| 1 19 20 21 package jxl.biff; 22 23 import java.text.DateFormat ; 24 import java.text.SimpleDateFormat ; 25 import java.text.NumberFormat ; 26 import java.text.DecimalFormat ; 27 import java.text.DecimalFormatSymbols ; 28 29 import common.Assert; 30 import common.Logger; 31 32 import jxl.WorkbookSettings; 33 import jxl.format.CellFormat; 34 import jxl.format.Format; 35 import jxl.format.Font; 36 import jxl.format.Alignment; 37 import jxl.format.VerticalAlignment; 38 import jxl.format.BorderLineStyle; 39 import jxl.format.Border; 40 import jxl.format.Colour; 41 import jxl.format.Pattern; 42 import jxl.format.Orientation; 43 import jxl.read.biff.Record; 44 45 48 public class XFRecord extends WritableRecordData implements CellFormat 49 { 50 53 private static Logger logger = Logger.getLogger(XFRecord.class); 54 55 58 public int formatIndex; 59 60 63 private int parentFormat; 64 65 68 private XFType xfFormatType; 69 70 73 private boolean date; 74 75 78 private boolean number; 79 80 84 private DateFormat dateFormat; 85 86 90 private NumberFormat numberFormat; 91 92 96 private byte usedAttributes; 97 100 private int fontIndex; 101 104 private boolean locked; 105 108 private boolean hidden; 109 112 private Alignment align; 113 116 private VerticalAlignment valign; 117 120 private Orientation orientation; 121 125 private boolean wrap; 126 127 130 private int indentation; 131 132 135 private boolean shrinkToFit; 136 137 140 private BorderLineStyle leftBorder; 141 144 private BorderLineStyle rightBorder; 145 148 private BorderLineStyle topBorder; 149 152 private BorderLineStyle bottomBorder; 153 154 157 private Colour leftBorderColour; 158 161 private Colour rightBorderColour; 162 165 private Colour topBorderColour; 166 169 private Colour bottomBorderColour; 170 171 174 private Colour backgroundColour; 175 178 private Pattern pattern; 179 183 private int options; 184 187 private int xfIndex; 188 191 private FontRecord font; 192 196 private DisplayFormat format; 197 200 private boolean initialized; 201 202 206 private boolean read; 207 208 213 private Format excelFormat; 214 215 220 private boolean formatInfoInitialized; 221 222 227 private boolean copied; 228 229 234 private FormattingRecords formattingRecords; 235 236 239 private static final int[] dateFormats = new int[] 240 {0xe, 241 0xf, 242 0x10, 243 0x11, 244 0x12, 245 0x13, 246 0x14, 247 0x15, 248 0x16, 249 0x2d, 250 0x2e, 251 0x2f}; 252 253 256 private static final DateFormat [] javaDateFormats = new DateFormat [] 257 {new SimpleDateFormat ("dd/MM/yyyy"), 258 new SimpleDateFormat ("d-MMM-yy"), 259 new SimpleDateFormat ("d-MMM"), 260 new SimpleDateFormat ("MMM-yy"), 261 new SimpleDateFormat ("h:mm a"), 262 new SimpleDateFormat ("h:mm:ss a"), 263 new SimpleDateFormat ("H:mm"), 264 new SimpleDateFormat ("H:mm:ss"), 265 new SimpleDateFormat ("M/d/yy H:mm"), 266 new SimpleDateFormat ("mm:ss"), 267 new SimpleDateFormat ("H:mm:ss"), 268 new SimpleDateFormat ("mm:ss.S")}; 269 270 273 private static int[] numberFormats = new int[] 274 {0x1, 275 0x2, 276 0x3, 277 0x4, 278 0x5, 279 0x6, 280 0x7, 281 0x8, 282 0x9, 283 0xa, 284 0xb, 285 0x25, 286 0x26, 287 0x27, 288 0x28, 289 0x29, 290 0x2a, 291 0x2b, 292 0x2c, 293 0x30}; 294 295 298 private static NumberFormat [] javaNumberFormats = new NumberFormat [] 299 {new DecimalFormat ("0"), 300 new DecimalFormat ("0.00"), 301 new DecimalFormat ("#,##0"), 302 new DecimalFormat ("#,##0.00"), 303 new DecimalFormat ("$#,##0;($#,##0)"), 304 new DecimalFormat ("$#,##0;($#,##0)"), 305 new DecimalFormat ("$#,##0.00;($#,##0.00)"), 306 new DecimalFormat ("$#,##0.00;($#,##0.00)"), 307 new DecimalFormat ("0%"), 308 new DecimalFormat ("0.00%"), 309 new DecimalFormat ("0.00E00"), 310 new DecimalFormat ("#,##0;(#,##0)"), 311 new DecimalFormat ("#,##0;(#,##0)"), 312 new DecimalFormat ("#,##0.00;(#,##0.00)"), 313 new DecimalFormat ("#,##0.00;(#,##0.00)"), 314 new DecimalFormat ("#,##0;(#,##0)"), 315 new DecimalFormat ("$#,##0;($#,##0)"), 316 new DecimalFormat ("#,##0.00;(#,##0.00)"), 317 new DecimalFormat ("$#,##0.00;($#,##0.00)"), 318 new DecimalFormat ("##0.0E0")}; 319 320 private static class BiffType {}; 322 323 public static final BiffType biff8 = new BiffType(); 324 public static final BiffType biff7 = new BiffType(); 325 326 329 private BiffType biffType; 330 331 private static class XFType 333 { 334 } 335 protected static final XFType cell = new XFType(); 336 protected static final XFType style = new XFType(); 337 338 344 public XFRecord(Record t, WorkbookSettings ws, BiffType bt) 345 { 346 super(t); 347 348 biffType = bt; 349 350 byte[] data = getRecord().getData(); 351 352 fontIndex = IntegerHelper.getInt(data[0], data[1]); 353 formatIndex = IntegerHelper.getInt(data[2], data[3]); 354 date = false; 355 number = false; 356 357 358 for (int i = 0; i < dateFormats.length && date == false; i++) 360 { 361 if (formatIndex == dateFormats[i]) 362 { 363 date = true; 364 dateFormat = javaDateFormats[i]; 365 } 366 } 367 368 for (int i = 0; i < numberFormats.length && number == false; i++) 370 { 371 if (formatIndex == numberFormats[i]) 372 { 373 number = true; 374 DecimalFormat df = (DecimalFormat ) javaNumberFormats[i].clone(); 375 DecimalFormatSymbols symbols = 376 new DecimalFormatSymbols (ws.getLocale()); 377 df.setDecimalFormatSymbols(symbols); 378 numberFormat = df; 379 } 381 } 382 383 int cellAttributes = IntegerHelper.getInt(data[4], data[5]); 385 parentFormat = (cellAttributes & 0xfff0) >> 4; 386 387 int formatType = cellAttributes & 0x4; 388 xfFormatType = formatType == 0 ? cell : style; 389 locked = ((cellAttributes & 0x1) != 0); 390 hidden = ((cellAttributes & 0x2) != 0); 391 392 if (xfFormatType == cell && 393 (parentFormat & 0xfff) == 0xfff) 394 { 395 parentFormat = 0; 397 logger.warn("Invalid parent format found - ignoring"); 398 } 399 400 initialized = false; 401 read = true; 402 formatInfoInitialized = false; 403 copied = false; 404 } 405 406 412 public XFRecord(FontRecord fnt, DisplayFormat form) 413 { 414 super(Type.XF); 415 416 initialized = false; 417 locked = true; 418 hidden = false; 419 align = Alignment.GENERAL; 420 valign = VerticalAlignment.BOTTOM; 421 orientation = Orientation.HORIZONTAL; 422 wrap = false; 423 leftBorder = BorderLineStyle.NONE; 424 rightBorder = BorderLineStyle.NONE; 425 topBorder = BorderLineStyle.NONE; 426 bottomBorder = BorderLineStyle.NONE; 427 leftBorderColour = Colour.AUTOMATIC; 428 rightBorderColour = Colour.AUTOMATIC; 429 topBorderColour = Colour.AUTOMATIC; 430 bottomBorderColour = Colour.AUTOMATIC; 431 pattern = Pattern.NONE; 432 backgroundColour = Colour.DEFAULT_BACKGROUND; 433 indentation = 0; 434 shrinkToFit = false; 435 436 parentFormat = 0; 438 xfFormatType = null; 439 440 font = fnt; 441 format = form; 442 biffType = biff8; 443 read = false; 444 copied = false; 445 formatInfoInitialized = true; 446 447 Assert.verify(font != null); 448 Assert.verify(format != null); 449 } 450 451 457 protected XFRecord(XFRecord fmt) 458 { 459 super(Type.XF); 460 461 initialized = false; 462 locked = fmt.locked; 463 hidden = fmt.hidden; 464 align = fmt.align; 465 valign = fmt.valign; 466 orientation = fmt.orientation; 467 wrap = fmt.wrap; 468 leftBorder = fmt.leftBorder; 469 rightBorder = fmt.rightBorder; 470 topBorder = fmt.topBorder; 471 bottomBorder = fmt.bottomBorder; 472 leftBorderColour = fmt.leftBorderColour; 473 rightBorderColour = fmt.rightBorderColour; 474 topBorderColour = fmt.topBorderColour; 475 bottomBorderColour = fmt.bottomBorderColour; 476 pattern = fmt.pattern; 477 xfFormatType = fmt.xfFormatType; 478 indentation = fmt.indentation; 479 shrinkToFit = fmt.shrinkToFit; 480 parentFormat = fmt.parentFormat; 481 backgroundColour = fmt.backgroundColour; 482 483 font = fmt.font; 485 format = fmt.format; 486 487 fontIndex = fmt.fontIndex; 488 formatIndex = fmt.formatIndex; 489 490 formatInfoInitialized = fmt.formatInfoInitialized; 491 492 biffType = biff8; 493 read = false; 494 copied = true; 495 } 496 497 504 protected XFRecord(CellFormat cellFormat) 505 { 506 super(Type.XF); 507 508 Assert.verify(cellFormat != null); 509 Assert.verify(cellFormat instanceof XFRecord); 510 XFRecord fmt = (XFRecord) cellFormat; 511 512 if (!fmt.formatInfoInitialized) 513 { 514 fmt.initializeFormatInformation(); 515 } 516 517 locked = fmt.locked; 518 hidden = fmt.hidden; 519 align = fmt.align; 520 valign = fmt.valign; 521 orientation = fmt.orientation; 522 wrap = fmt.wrap; 523 leftBorder = fmt.leftBorder; 524 rightBorder = fmt.rightBorder; 525 topBorder = fmt.topBorder; 526 bottomBorder = fmt.bottomBorder; 527 leftBorderColour = fmt.leftBorderColour; 528 rightBorderColour = fmt.rightBorderColour; 529 topBorderColour = fmt.topBorderColour; 530 bottomBorderColour = fmt.bottomBorderColour; 531 pattern = fmt.pattern; 532 xfFormatType = fmt.xfFormatType; 533 parentFormat = fmt.parentFormat; 534 indentation = fmt.indentation; 535 shrinkToFit = fmt.shrinkToFit; 536 backgroundColour = fmt.backgroundColour; 537 538 font = new FontRecord(fmt.getFont()); 540 541 if (fmt.getFormat() == null) 543 { 544 if (fmt.format.isBuiltIn()) 546 { 547 format = fmt.format; 548 } 549 else 550 { 551 format = new FormatRecord((FormatRecord) fmt.format); 553 } 554 } 555 else if (fmt.getFormat() instanceof BuiltInFormat) 556 { 557 excelFormat = (BuiltInFormat) fmt.excelFormat; 559 format = (BuiltInFormat) fmt.excelFormat; 560 } 561 else 562 { 563 Assert.verify(fmt.formatInfoInitialized); 565 566 Assert.verify(fmt.excelFormat instanceof FormatRecord); 569 570 FormatRecord fr = new FormatRecord((FormatRecord) fmt.excelFormat); 572 573 excelFormat = fr; 576 format = fr; 577 } 578 579 biffType = biff8; 580 581 formatInfoInitialized = true; 583 584 585 read = false; 587 588 copied = false; 590 591 initialized = false; 593 } 594 595 600 public DateFormat getDateFormat() 601 { 602 return dateFormat; 603 } 604 605 610 public NumberFormat getNumberFormat() 611 { 612 return numberFormat; 613 } 614 615 620 public int getFormatRecord() 621 { 622 return formatIndex; 623 } 624 625 630 public boolean isDate() 631 { 632 return date; 633 } 634 635 640 public boolean isNumber() 641 { 642 return number; 643 } 644 645 653 public byte[] getData() 654 { 655 if (!formatInfoInitialized) 659 { 660 initializeFormatInformation(); 661 } 662 663 byte[] data = new byte[20]; 664 665 IntegerHelper.getTwoBytes(fontIndex, data, 0); 666 IntegerHelper.getTwoBytes(formatIndex, data, 2); 667 668 int cellAttributes = 0; 670 671 if (getLocked()) 672 { 673 cellAttributes |= 0x01; 674 } 675 676 if (getHidden()) 677 { 678 cellAttributes |= 0x02; 679 } 680 681 if (xfFormatType == style) 682 { 683 cellAttributes |= 0x04; 684 parentFormat = 0xffff; 685 } 686 687 cellAttributes |= (parentFormat << 4); 688 689 IntegerHelper.getTwoBytes(cellAttributes, data, 4); 690 691 int alignMask = align.getValue(); 692 693 if (wrap) 694 { 695 alignMask |= 0x08; 696 } 697 698 alignMask |= (valign.getValue() << 4); 699 700 alignMask |= (orientation.getValue() << 8); 701 702 IntegerHelper.getTwoBytes(alignMask, data, 6); 703 704 data[9] = (byte) 0x10; 705 706 int borderMask = leftBorder.getValue(); 708 borderMask |= (rightBorder.getValue() << 4); 709 borderMask |= (topBorder.getValue() << 8); 710 borderMask |= (bottomBorder.getValue() << 12); 711 712 IntegerHelper.getTwoBytes(borderMask, data, 10); 713 714 if (borderMask != 0) 717 { 718 byte lc = (byte)leftBorderColour.getValue(); 719 byte rc = (byte)rightBorderColour.getValue(); 720 byte tc = (byte)topBorderColour.getValue(); 721 byte bc = (byte)bottomBorderColour.getValue(); 722 723 int sideColourMask = (lc & 0x7f) | ((rc & 0x7f) << 7); 724 int topColourMask = (tc & 0x7f) | ((bc & 0x7f) << 7); 725 726 IntegerHelper.getTwoBytes(sideColourMask, data, 12); 727 IntegerHelper.getTwoBytes(topColourMask, data, 14); 728 } 729 730 int patternVal = pattern.getValue() << 10; 732 IntegerHelper.getTwoBytes(patternVal, data, 16); 733 734 int colourPaletteMask = backgroundColour.getValue(); 736 colourPaletteMask |= (0x40 << 7); 737 IntegerHelper.getTwoBytes(colourPaletteMask, data, 18); 738 739 options |= indentation & 0x0f; 741 742 if (shrinkToFit) 743 { 744 options |= 0x10; 745 } 746 else 747 { 748 options &= 0xef; 749 } 750 751 data[8] = (byte) options; 752 753 if (biffType == biff8) 754 { 755 data[9] = usedAttributes; 757 } 758 759 return data; 760 } 761 762 767 protected final boolean getLocked() 768 { 769 return locked; 770 } 771 772 777 protected final boolean getHidden() 778 { 779 return hidden; 780 } 781 782 787 protected final void setXFLocked(boolean l) 788 { 789 locked = l; 790 } 791 792 797 protected final void setXFCellOptions(int opt) 798 { 799 options |= opt; 800 } 801 802 809 protected void setXFAlignment(Alignment a) 810 { 811 Assert.verify(!initialized); 812 align = a; 813 } 814 815 820 protected void setXFIndentation(int i) 821 { 822 Assert.verify(!initialized); 823 indentation = i; 824 } 825 826 831 protected void setXFShrinkToFit(boolean s) 832 { 833 Assert.verify(!initialized); 834 shrinkToFit = s; 835 } 836 837 842 public Alignment getAlignment() 843 { 844 if (!formatInfoInitialized) 845 { 846 initializeFormatInformation(); 847 } 848 849 return align; 850 } 851 852 857 public int getIndentation() 858 { 859 if (!formatInfoInitialized) 860 { 861 initializeFormatInformation(); 862 } 863 864 return indentation; 865 } 866 867 872 public boolean isShrinkToFit() 873 { 874 if (!formatInfoInitialized) 875 { 876 initializeFormatInformation(); 877 } 878 879 return shrinkToFit; 880 } 881 882 887 public boolean isLocked() 888 { 889 if (!formatInfoInitialized) 890 { 891 initializeFormatInformation(); 892 } 893 894 return locked; 895 } 896 897 898 903 public VerticalAlignment getVerticalAlignment() 904 { 905 if (!formatInfoInitialized) 906 { 907 initializeFormatInformation(); 908 } 909 910 return valign; 911 } 912 913 918 public Orientation getOrientation() 919 { 920 if (!formatInfoInitialized) 921 { 922 initializeFormatInformation(); 923 } 924 925 return orientation; 926 } 927 928 936 protected void setXFBackground(Colour c, Pattern p) 937 { 938 Assert.verify(!initialized); 939 backgroundColour = c; 940 pattern = p; 941 } 942 943 948 public Colour getBackgroundColour() 949 { 950 if (!formatInfoInitialized) 951 { 952 initializeFormatInformation(); 953 } 954 955 return backgroundColour; 956 } 957 958 963 public Pattern getPattern() 964 { 965 if (!formatInfoInitialized) 966 { 967 initializeFormatInformation(); 968 } 969 970 return pattern; 971 } 972 973 981 protected void setXFVerticalAlignment(VerticalAlignment va) 982 { 983 Assert.verify(!initialized); 984 valign = va; 985 } 986 987 995 protected void setXFOrientation(Orientation o) 996 { 997 Assert.verify(!initialized); 998 orientation = o; 999 } 1000 1001 1008 protected void setXFWrap(boolean w) 1009 { 1010 Assert.verify(!initialized); 1011 wrap = w; 1012 } 1013 1014 1019 public boolean getWrap() 1020 { 1021 if (!formatInfoInitialized) 1022 { 1023 initializeFormatInformation(); 1024 } 1025 1026 return wrap; 1027 } 1028 1029 1037 protected void setXFBorder(Border b, BorderLineStyle ls, Colour c) 1038 { 1039 Assert.verify(!initialized); 1040 1041 if (c==Colour.BLACK) 1042 { 1043 c = Colour.PALETTE_BLACK; 1044 } 1045 1046 if (b == Border.LEFT) 1047 { 1048 leftBorder = ls; 1049 leftBorderColour = c; 1050 } 1051 else if (b == Border.RIGHT) 1052 { 1053 rightBorder = ls; 1054 rightBorderColour = c; 1055 } 1056 else if (b == Border.TOP) 1057 { 1058 topBorder = ls; 1059 topBorderColour = c; 1060 } 1061 else if (b == Border.BOTTOM) 1062 { 1063 bottomBorder = ls; 1064 bottomBorderColour = c; 1065 } 1066 return; 1067 } 1068 1069 1070 1078 public BorderLineStyle getBorder(Border border) 1079 { 1080 return getBorderLine(border); 1081 } 1082 1083 1091 public BorderLineStyle getBorderLine(Border border) 1092 { 1093 if (border == Border.NONE || 1095 border == Border.ALL) 1096 { 1097 return BorderLineStyle.NONE; 1098 } 1099 1100 if (!formatInfoInitialized) 1101 { 1102 initializeFormatInformation(); 1103 } 1104 1105 if (border == Border.LEFT) 1106 { 1107 return leftBorder; 1108 } 1109 else if (border == Border.RIGHT) 1110 { 1111 return rightBorder; 1112 } 1113 else if (border == Border.TOP) 1114 { 1115 return topBorder; 1116 } 1117 else if (border == Border.BOTTOM) 1118 { 1119 return bottomBorder; 1120 } 1121 1122 return BorderLineStyle.NONE; 1123 } 1124 1125 1133 public Colour getBorderColour(Border border) 1134 { 1135 if (border == Border.NONE || 1137 border == Border.ALL) 1138 { 1139 return Colour.PALETTE_BLACK; 1140 } 1141 1142 if (!formatInfoInitialized) 1143 { 1144 initializeFormatInformation(); 1145 } 1146 1147 if (border == Border.LEFT) 1148 { 1149 return leftBorderColour; 1150 } 1151 else if (border == Border.RIGHT) 1152 { 1153 return rightBorderColour; 1154 } 1155 else if (border == Border.TOP) 1156 { 1157 return topBorderColour; 1158 } 1159 else if (border == Border.BOTTOM) 1160 { 1161 return bottomBorderColour; 1162 } 1163 1164 return Colour.BLACK; 1165 } 1166 1167 1168 1174 public final boolean hasBorders() 1175 { 1176 if (!formatInfoInitialized) 1177 { 1178 initializeFormatInformation();
|