1 2 17 18 19 package org.apache.poi.hssf.record.aggregates; 20 21 import org.apache.poi.hssf.record.DBCellRecord; 22 import org.apache.poi.hssf.record.Record; 23 import org.apache.poi.hssf.record.RowRecord; 24 25 import java.util.Iterator ; 26 import java.util.Map ; 27 import java.util.TreeMap ; 28 29 34 35 public class RowRecordsAggregate 36 extends Record 37 { 38 int firstrow = -1; 39 int lastrow = -1; 40 Map records = null; 41 int size = 0; 42 43 44 45 public RowRecordsAggregate() 46 { 47 records = new TreeMap (); 48 } 49 50 public void insertRow(RowRecord row) 51 { 52 size += row.getRecordSize(); 53 54 records.put(row, row); 56 if ((row.getRowNumber() < firstrow) || (firstrow == -1)) 57 { 58 firstrow = row.getRowNumber(); 59 } 60 if ((row.getRowNumber() > lastrow) || (lastrow == -1)) 61 { 62 lastrow = row.getRowNumber(); 63 } 64 } 65 66 public void removeRow(RowRecord row) 67 { 68 size -= row.getRecordSize(); 69 70 records.remove(row); 72 } 73 74 public RowRecord getRow(int rownum) 75 { 76 77 RowRecord row = new RowRecord(); 79 80 row.setRowNumber(( short ) rownum); 81 return ( RowRecord ) records.get(row); 82 } 83 84 public int getPhysicalNumberOfRows() 85 { 86 return records.size(); 87 } 88 89 public int getFirstRowNum() 90 { 91 return firstrow; 92 } 93 94 public int getLastRowNum() 95 { 96 return lastrow; 97 } 98 99 103 public int getRowBlockCount() { 104 int size = records.size()/DBCellRecord.BLOCK_SIZE; 105 if ((records.size() % DBCellRecord.BLOCK_SIZE) != 0) 106 size++; 107 return size; 108 } 109 110 public int getRowBlockSize(int block) { 111 return 20 * getRowCountForBlock(block); 112 } 113 114 115 public int getRowCountForBlock(int block) { 116 int startIndex = block * DBCellRecord.BLOCK_SIZE; 117 int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1; 118 if (endIndex >= records.size()) 119 endIndex = records.size()-1; 120 121 return endIndex-startIndex+1; 122 } 123 124 125 public int getStartRowNumberForBlock(int block) { 126 int startIndex = block * DBCellRecord.BLOCK_SIZE; 131 Iterator rowIter = records.values().iterator(); 132 RowRecord row = null; 133 for (int i=0; i<=startIndex;i++) { 135 row = (RowRecord)rowIter.next(); 136 } 137 138 return row.getRowNumber(); 139 } 140 141 142 public int getEndRowNumberForBlock(int block) { 143 int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1; 144 if (endIndex >= records.size()) 145 endIndex = records.size()-1; 146 147 Iterator rowIter = records.values().iterator(); 148 RowRecord row = null; 149 for (int i=0; i<=endIndex;i++) { 150 row = (RowRecord)rowIter.next(); 151 } 152 return row.getRowNumber(); 153 } 154 155 156 157 private int serializeRowBlock(final int block, final int offset, byte[] data) { 158 final int startIndex = block*DBCellRecord.BLOCK_SIZE; 159 final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE; 160 161 Iterator rowIterator = records.values().iterator(); 162 int pos = offset; 163 164 int i=0; 169 for (;i<startIndex;i++) 170 rowIterator.next(); 171 while(rowIterator.hasNext() && (i++ < endIndex)) { 172 RowRecord row = (RowRecord)rowIterator.next(); 173 pos += row.serialize(pos, data); 174 } 175 return pos - offset; 176 } 177 178 public int serialize(int offset, byte [] data) { 179 throw new RuntimeException ("The serialize method that passes in cells should be used"); 180 } 181 182 183 192 193 public int serialize(int offset, byte [] data, ValueRecordsAggregate cells) 194 { 195 int pos = offset; 196 197 final int blockCount = getRowBlockCount(); 199 for (int block=0;block<blockCount;block++) { 200 final int rowStartPos = pos; 203 final int rowBlockSize = serializeRowBlock(block, pos, data); 205 pos += rowBlockSize; 206 final int startRowNumber = getStartRowNumberForBlock(block); 208 final int endRowNumber = getEndRowNumberForBlock(block); 209 DBCellRecord cellRecord = new DBCellRecord(); 210 int cellRefOffset = (rowBlockSize-20); 212 for (int row=startRowNumber;row<=endRowNumber;row++) { 213 if (cells.rowHasCells(row)) { 214 final int rowCellSize = cells.serializeCellRow(row, pos, data); 215 pos += rowCellSize; 216 cellRecord.addCellOffset((short)cellRefOffset); 218 cellRefOffset = rowCellSize; 219 } 220 } 221 cellRecord.setRowOffset(pos - rowStartPos); 223 pos += cellRecord.serialize(pos, data); 224 225 } 226 return pos - offset; 227 } 228 229 237 238 protected void fillFields(byte [] data, short size, int offset) 239 { 240 } 241 242 248 249 protected void validateSid(short id) 250 { 251 } 252 253 256 257 public short getSid() 258 { 259 return -1000; 260 } 261 262 public int getRecordSize() 263 { 264 return size; 265 } 266 267 public Iterator getIterator() 268 { 269 return records.values().iterator(); 270 } 271 272 275 public Object clone() 276 { 277 RowRecordsAggregate rec = new RowRecordsAggregate(); 278 for ( Iterator rowIter = getIterator(); rowIter.hasNext(); ) 279 { 280 RowRecord row = (RowRecord) ( (RowRecord) rowIter.next() ).clone(); 282 rec.insertRow( row ); 283 } 284 return rec; 285 } 286 287 288 public int findStartOfRowOutlineGroup(int row) 289 { 290 RowRecord rowRecord = this.getRow( row ); 292 int level = rowRecord.getOutlineLevel(); 293 int currentRow = row; 294 while (this.getRow( currentRow ) != null) 295 { 296 rowRecord = this.getRow( currentRow ); 297 if (rowRecord.getOutlineLevel() < level) 298 return currentRow + 1; 299 currentRow--; 300 } 301 302 return currentRow + 1; 303 } 304 305 public int findEndOfRowOutlineGroup( int row ) 306 { 307 int level = getRow( row ).getOutlineLevel(); 308 int currentRow; 309 for (currentRow = row; currentRow < this.getLastRowNum(); currentRow++) 310 { 311 if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level) 312 { 313 break; 314 } 315 } 316 317 return currentRow-1; 318 } 319 320 public int writeHidden( RowRecord rowRecord, int row, boolean hidden ) 321 { 322 int level = rowRecord.getOutlineLevel(); 323 while (rowRecord != null && this.getRow(row).getOutlineLevel() >= level) 324 { 325 rowRecord.setZeroHeight( hidden ); 326 row++; 327 rowRecord = this.getRow( row ); 328 } 329 return row - 1; 330 } 331 332 public void collapseRow( int rowNumber ) 333 { 334 335 int startRow = findStartOfRowOutlineGroup( rowNumber ); 337 RowRecord rowRecord = (RowRecord) getRow( startRow ); 338 339 int lastRow = writeHidden( rowRecord, startRow, true ); 341 342 if (getRow(lastRow + 1) != null) 344 { 345 getRow(lastRow + 1).setColapsed( true ); 346 } 347 else 348 { 349 RowRecord row = createRow( lastRow + 1); 350 row.setColapsed( true ); 351 insertRow( row ); 352 } 353 } 354 355 362 public static RowRecord createRow(int row) 363 { 364 RowRecord rowrec = new RowRecord(); 365 366 rowrec.setRowNumber(row); 368 rowrec.setHeight(( short ) 0xff); 369 rowrec.setOptimize(( short ) 0x0); 370 rowrec.setOptionFlags(( short ) 0x100); rowrec.setXFIndex(( short ) 0xf); 372 return rowrec; 373 } 374 375 public boolean isRowGroupCollapsed( int row ) 376 { 377 int collapseRow = findEndOfRowOutlineGroup( row ) + 1; 378 379 if (getRow(collapseRow) == null) 380 return false; 381 else 382 return getRow( collapseRow ).getColapsed(); 383 } 384 385 public void expandRow( int rowNumber ) 386 { 387 int idx = rowNumber; 388 if (idx == -1) 389 return; 390 391 if (!isRowGroupCollapsed(idx)) 393 return; 394 395 int startIdx = findStartOfRowOutlineGroup( idx ); 397 RowRecord row = getRow( startIdx ); 398 399 int endIdx = findEndOfRowOutlineGroup( idx ); 401 402 if ( !isRowGroupHiddenByParent( idx ) ) 410 { 411 for ( int i = startIdx; i <= endIdx; i++ ) 412 { 413 if ( row.getOutlineLevel() == getRow( i ).getOutlineLevel() ) 414 getRow( i ).setZeroHeight( false ); 415 else if (!isRowGroupCollapsed(i)) 416 getRow( i ).setZeroHeight( false ); 417 } 418 } 419 420 getRow( endIdx + 1 ).setColapsed( false ); 422 } 423 424 public boolean isRowGroupHiddenByParent( int row ) 425 { 426 int endLevel; 428 boolean endHidden; 429 int endOfOutlineGroupIdx = findEndOfRowOutlineGroup( row ); 430 if (getRow( endOfOutlineGroupIdx + 1 ) == null) 431 { 432 endLevel = 0; 433 endHidden = false; 434 } 435 else 436 { 437 endLevel = getRow( endOfOutlineGroupIdx + 1).getOutlineLevel(); 438 endHidden = getRow( endOfOutlineGroupIdx + 1).getZeroHeight(); 439 } 440 441 int startLevel; 443 boolean startHidden; 444 int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row ); 445 if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) 446 { 447 startLevel = 0; 448 startHidden = false; 449 } 450 else 451 { 452 startLevel = getRow( startOfOutlineGroupIdx - 1).getOutlineLevel(); 453 startHidden = getRow( startOfOutlineGroupIdx - 1 ).getZeroHeight(); 454 } 455 456 if (endLevel > startLevel) 457 { 458 return endHidden; 459 } 460 else 461 { 462 return startHidden; 463 } 464 } 465 466 } 467 468 | Popular Tags |