1 19 20 package jxl.write.biff; 21 22 import java.util.ArrayList ; 23 import java.util.Iterator ; 24 import java.io.IOException ; 25 26 import common.Logger; 27 import jxl.CellType; 28 import jxl.write.Number; 29 import jxl.biff.Type; 30 import jxl.biff.WritableRecordData; 31 import jxl.biff.IntegerHelper; 32 import jxl.biff.XFRecord; 33 import jxl.biff.IndexMapping; 34 import jxl.biff.CellReferenceHelper; 35 36 39 class RowRecord extends WritableRecordData 40 { 41 44 private static final Logger logger = Logger.getLogger(RowRecord.class); 45 46 49 private byte[] data; 50 53 private CellValue[] cells; 54 57 private int rowHeight; 58 61 private boolean collapsed; 62 65 private int rowNumber; 66 69 private int numColumns; 70 73 private int xfIndex; 74 77 private XFRecord style; 78 81 private boolean defaultFormat; 82 85 private boolean matchesDefFontHeight; 86 89 private static final int growSize = 10; 90 91 94 private static final int maxRKValue = 0x1fffffff; 95 96 99 private static final int minRKValue = -0x20000000; 100 101 104 private static int defaultHeightIndicator = 0xff; 105 106 109 private static int maxColumns = 256; 110 111 112 117 public RowRecord(int rn) 118 { 119 super(Type.ROW); 120 rowNumber = rn; 121 cells = new CellValue[0]; 122 numColumns = 0; 123 rowHeight = defaultHeightIndicator; 124 collapsed = false; 125 matchesDefFontHeight = true; 126 } 127 128 133 public void setRowHeight(int h) 134 { 135 if (h == 0) 136 { 137 setCollapsed(true); 138 matchesDefFontHeight = false; 139 } 140 else 141 { 142 rowHeight = h; 143 matchesDefFontHeight = false; 144 } 145 } 146 147 156 void setRowDetails(int height, boolean mdfh, boolean col, XFRecord xfr) 157 { 158 rowHeight = height; 159 collapsed = col; 160 matchesDefFontHeight = mdfh; 161 162 if (xfr != null) 163 { 164 defaultFormat = true; 165 style = xfr; 166 xfIndex = style.getXFIndex(); 167 } 168 } 169 170 175 public void setCollapsed(boolean c) 176 { 177 collapsed = c; 178 } 179 180 185 public int getRowNumber() 186 { 187 return rowNumber; 188 } 189 190 195 public void addCell(CellValue cv) 196 { 197 int col = cv.getColumn(); 198 199 if (col >= maxColumns) 200 { 201 logger.warn("Could not add cell at " + 202 CellReferenceHelper.getCellReference(cv.getRow(), 203 cv.getColumn()) + 204 " because it exceeds the maximum column limit"); 205 return; 206 } 207 208 if (col >= cells.length) 212 { 213 CellValue[] oldCells = cells; 214 cells = new CellValue[Math.max(oldCells.length + growSize, col+1)]; 215 System.arraycopy(oldCells, 0, cells, 0, oldCells.length); 216 oldCells = null; 217 } 218 219 cells[col] = cv; 220 221 numColumns = Math.max(col+1, numColumns); 222 } 223 224 229 public void removeCell(int col) 230 { 231 if (col >= numColumns) 233 { 234 return; 235 } 236 237 cells[col] = null; 238 } 239 240 246 public void write(File outputFile) throws IOException 247 { 248 outputFile.write(this); 249 } 250 251 259 public void writeCells(File outputFile) 260 throws IOException 261 { 262 ArrayList integerValues = new ArrayList (); 264 boolean integerValue = false; 265 266 for (int i = 0; i < numColumns; i++) 268 { 269 integerValue = false; 270 if (cells[i] != null) 271 { 272 if (cells[i].getType() == CellType.NUMBER) 275 { 276 Number nc = (Number ) cells[i]; 277 if (nc.getValue() == (int) nc.getValue() && 278 nc.getValue() < maxRKValue && 279 nc.getValue() > minRKValue && 280 nc.getCellFeatures() == null) 281 { 282 integerValue = true; 283 } 284 } 285 286 if (integerValue) 287 { 288 integerValues.add(cells[i]); 290 } 291 else 292 { 293 writeIntegerValues(integerValues, outputFile); 296 outputFile.write(cells[i]); 297 298 if (cells[i].getType() == CellType.STRING_FORMULA) 301 { 302 StringRecord sr = new StringRecord(cells[i].getContents()); 303 outputFile.write(sr); 304 } 305 } 306 } 307 else 308 { 309 writeIntegerValues(integerValues, outputFile); 312 } 313 } 314 315 writeIntegerValues(integerValues, outputFile); 317 } 318 319 327 private void writeIntegerValues(ArrayList integerValues, File outputFile) 328 throws IOException 329 { 330 if (integerValues.size() == 0) 331 { 332 return; 333 } 334 335 if (integerValues.size() >= 3 ) 336 { 337 MulRKRecord mulrk = new MulRKRecord(integerValues); 339 outputFile.write(mulrk); 340 } 341 else 342 { 343 Iterator i = integerValues.iterator(); 345 while (i.hasNext()) 346 { 347 outputFile.write((CellValue) i.next()); 348 } 349 } 350 351 integerValues.clear(); 353 } 354 355 360 public byte[] getData() 361 { 362 byte[] data = new byte[16]; 364 IntegerHelper.getTwoBytes(rowNumber, data, 0); 365 IntegerHelper.getTwoBytes(numColumns, data, 4); 366 IntegerHelper.getTwoBytes(rowHeight, data, 6); 367 368 int options = 0x100; 369 370 if (collapsed) 371 { 372 options |= 0x20; 373 } 374 375 if (!matchesDefFontHeight) 376 { 377 options |= 0x40; 378 } 379 380 if (defaultFormat) 381 { 382 options |= 0x80; 383 options |= (xfIndex << 16); 384 } 385 386 IntegerHelper.getFourBytes(options, data, 12); 387 388 return data; 389 } 390 391 396 public int getMaxColumn() 397 { 398 return numColumns; 399 } 400 401 408 public CellValue getCell(int col) 409 { 410 return (col >= 0 && col < numColumns) ? cells[col] : null; 411 } 412 413 417 void incrementRow() 418 { 419 rowNumber++; 420 421 for (int i = 0; i < cells.length; i++) 422 { 423 if (cells[i] != null) 424 { 425 cells[i].incrementRow(); 426 } 427 } 428 } 429 430 434 void decrementRow() 435 { 436 rowNumber--; 437 for (int i = 0; i < cells.length; i++) 438 { 439 if (cells[i] != null) 440 { 441 cells[i].decrementRow(); 442 } 443 } 444 } 445 446 451 void insertColumn(int col) 452 { 453 if (col >= numColumns) 456 { 457 return; 458 } 459 460 if (numColumns >= maxColumns) 461 { 462 logger.warn("Could not insert column because maximum column limit has "+ 463 "been reached"); 464 return; 465 } 466 467 CellValue[] oldCells = cells; 469 470 if (numColumns >= cells.length - 1) 471 { 472 cells = new CellValue[oldCells.length + growSize]; 473 } 474 else 475 { 476 cells = new CellValue[oldCells.length]; 477 } 478 479 System.arraycopy(oldCells, 0, cells, 0, col); 481 482 System.arraycopy(oldCells, col, cells, col+1, numColumns - col); 484 485 for (int i = col+1; i <= numColumns; i++) 487 { 488 if (cells[i] != null) 489 { 490 cells[i].incrementColumn(); 491 } 492 } 493 494 numColumns++; 496 } 497 498 503 void removeColumn(int col) 504 { 505 if (col >= numColumns) 508 { 509 return; 510 } 511 512 CellValue[] oldCells = cells; 514 515 cells = new CellValue[oldCells.length]; 516 517 System.arraycopy(oldCells, 0, cells, 0, col); 519 520 System.arraycopy(oldCells, col + 1, cells, col, numColumns - (col+1)); 522 523 for (int i = col; i < numColumns; i++) 525 { 526 if (cells[i] != null) 527 { 528 cells[i].decrementColumn(); 529 } 530 } 531 532 numColumns--; 534 } 535 536 541 public boolean isDefaultHeight() 542 { 543 return rowHeight == defaultHeightIndicator; 544 } 545 546 551 public int getRowHeight() 552 { 553 return rowHeight; 554 } 555 556 561 public boolean isCollapsed() 562 { 563 return collapsed; 564 } 565 566 570 void rationalize(IndexMapping xfmapping) 571 { 572 if (defaultFormat) 573 { 574 xfIndex = xfmapping.getNewIndex(xfIndex); 575 } 576 } 577 578 584 XFRecord getStyle() 585 { 586 return style; 587 } 588 589 594 boolean hasDefaultFormat() 595 { 596 return defaultFormat; 597 } 598 599 604 boolean matchesDefaultFontHeight() 605 { 606 return matchesDefFontHeight; 607 } 608 } 609 610 611 612 613 614 615 616 617 618 619 | Popular Tags |