1 19 20 package jxl.read.biff; 21 22 import java.util.ArrayList ; 23 import java.util.Iterator ; 24 import java.util.HashMap ; 25 26 import common.Assert; 27 import common.Logger; 28 29 import jxl.Workbook; 30 import jxl.Sheet; 31 import jxl.Cell; 32 import jxl.Range; 33 import jxl.WorkbookSettings; 34 import jxl.biff.RangeImpl; 35 import jxl.biff.Type; 36 import jxl.biff.FormatRecord; 37 import jxl.biff.Fonts; 38 import jxl.biff.FontRecord; 39 import jxl.biff.XFRecord; 40 import jxl.biff.FormattingRecords; 41 import jxl.biff.NumFormatRecordsException; 42 import jxl.biff.PaletteRecord; 43 import jxl.biff.WorkbookMethods; 44 import jxl.biff.formula.ExternalSheet; 45 import jxl.biff.drawing.DrawingGroup; 46 import jxl.biff.drawing.Origin; 47 import jxl.biff.drawing.MsoDrawingGroupRecord; 48 49 53 public class WorkbookParser extends Workbook 54 implements ExternalSheet, WorkbookMethods 55 { 56 59 private static Logger logger = Logger.getLogger(WorkbookParser.class); 60 61 64 private File excelFile; 65 68 private int bofs; 69 72 private boolean nineteenFour; 73 76 private SSTRecord sharedStrings; 77 80 private ArrayList boundsheets; 81 84 private FormattingRecords formattingRecords; 85 88 private Fonts fonts; 89 90 93 private ArrayList sheets; 94 95 98 private SheetImpl lastSheet; 99 100 103 private int lastSheetIndex; 104 105 108 private HashMap namedRecords; 109 110 113 private ArrayList nameTable; 114 115 118 private ExternalSheetRecord externSheet; 119 120 123 private ArrayList supbooks; 124 125 128 private BOFRecord workbookBof; 129 130 133 private MsoDrawingGroupRecord msoDrawingGroup; 134 135 138 private ButtonPropertySetRecord buttonPropertySet; 139 140 143 private boolean wbProtected; 144 145 148 private boolean containsMacros; 149 150 153 private WorkbookSettings settings; 154 155 158 private DrawingGroup drawingGroup; 159 160 164 private CountryRecord countryRecord; 165 166 172 public WorkbookParser(File f, WorkbookSettings s) 173 { 174 super(); 175 excelFile = f; 176 boundsheets = new ArrayList (10); 177 fonts = new Fonts(); 178 formattingRecords = new FormattingRecords(fonts); 179 sheets = new ArrayList (10); 180 supbooks = new ArrayList (10); 181 namedRecords = new HashMap (); 182 lastSheetIndex = -1; 183 wbProtected = false; 184 containsMacros = false; 185 settings = s; 186 } 187 188 196 public Sheet[] getSheets() 197 { 198 Sheet[] sheetArray = new Sheet[getNumberOfSheets()]; 199 return (Sheet[]) sheets.toArray(sheetArray); 200 } 201 202 209 public Sheet getReadSheet(int index) 210 { 211 return getSheet(index); 212 } 213 214 220 public Sheet getSheet(int index) 221 { 222 if ((lastSheet != null) && lastSheetIndex == index) 226 { 227 return lastSheet; 228 } 229 230 if (lastSheet != null) 232 { 233 lastSheet.clear(); 234 235 if (!settings.getGCDisabled()) 236 { 237 System.gc(); 238 } 239 } 240 241 lastSheet = (SheetImpl) sheets.get(index); 242 lastSheetIndex = index; 243 lastSheet.readSheet(); 244 245 return lastSheet; 246 } 247 248 254 public Sheet getSheet(String name) 255 { 256 int pos = 0; 258 boolean found = false; 259 Iterator i = boundsheets.iterator(); 260 BoundsheetRecord br = null; 261 262 while (i.hasNext() && !found) 263 { 264 br = (BoundsheetRecord) i.next(); 265 266 if (br.getName().equals(name)) 267 { 268 found = true; 269 } 270 else 271 { 272 pos++; 273 } 274 } 275 276 return found ? getSheet(pos) : null; 277 } 278 279 284 public String [] getSheetNames() 285 { 286 String [] names = new String [boundsheets.size()]; 287 288 BoundsheetRecord br = null; 289 for (int i = 0; i < names.length; i++) 290 { 291 br = (BoundsheetRecord) boundsheets.get(i); 292 names[i] = br.getName(); 293 } 294 295 return names; 296 } 297 298 299 307 public int getExternalSheetIndex(int index) 308 { 309 if (workbookBof.isBiff7()) 312 { 313 return index; 314 } 315 316 Assert.verify(externSheet != null); 317 318 int firstTab = externSheet.getFirstTabIndex(index); 319 320 return firstTab; 321 } 322 323 331 public int getLastExternalSheetIndex(int index) 332 { 333 if (workbookBof.isBiff7()) 336 { 337 return index; 338 } 339 340 Assert.verify(externSheet != null); 341 342 int lastTab = externSheet.getLastTabIndex(index); 343 344 return lastTab; 345 } 346 347 353 public String getExternalSheetName(int index) 354 { 355 if (workbookBof.isBiff7()) 358 { 359 BoundsheetRecord br = (BoundsheetRecord) boundsheets.get(index); 360 361 return br.getName(); 362 } 363 364 int supbookIndex = externSheet.getSupbookIndex(index); 365 SupbookRecord sr = (SupbookRecord) supbooks.get(supbookIndex); 366 367 int firstTab = externSheet.getFirstTabIndex(index); 368 369 if (sr.getType() == SupbookRecord.INTERNAL) 370 { 371 BoundsheetRecord br = (BoundsheetRecord) boundsheets.get(firstTab); 373 374 return br.getName(); 375 } 376 else if (sr.getType() == SupbookRecord.EXTERNAL) 377 { 378 StringBuffer sb = new StringBuffer (); 380 sb.append('['); 381 sb.append(sr.getFileName()); 382 sb.append(']'); 383 sb.append(sr.getSheetName(firstTab)); 384 return sb.toString(); 385 } 386 387 return "[UNKNOWN]"; 389 } 390 391 397 public String getLastExternalSheetName(int index) 398 { 399 if (workbookBof.isBiff7()) 402 { 403 BoundsheetRecord br = (BoundsheetRecord) boundsheets.get(index); 404 405 return br.getName(); 406 } 407 408 int supbookIndex = externSheet.getSupbookIndex(index); 409 SupbookRecord sr = (SupbookRecord) supbooks.get(supbookIndex); 410 411 int lastTab = externSheet.getLastTabIndex(index); 412 413 if (sr.getType() == SupbookRecord.INTERNAL) 414 { 415 BoundsheetRecord br = (BoundsheetRecord) boundsheets.get(lastTab); 417 418 return br.getName(); 419 } 420 else if (sr.getType() == SupbookRecord.EXTERNAL) 421 { 422 StringBuffer sb = new StringBuffer (); 424 sb.append('['); 425 sb.append(sr.getFileName()); 426 sb.append(']'); 427 sb.append(sr.getSheetName(lastTab)); 428 return sb.toString(); 429 } 430 431 return "[UNKNOWN]"; 433 } 434 435 440 public int getNumberOfSheets() 441 { 442 return sheets.size(); 443 } 444 445 449 public void close() 450 { 451 if (lastSheet != null) 452 { 453 lastSheet.clear(); 454 } 455 excelFile.clear(); 456 457 if (!settings.getGCDisabled()) 458 { 459 System.gc(); 460 } 461 } 462 463 468 final void addSheet(Sheet s) 469 { 470 sheets.add(s); 471 } 472 473 479 protected void parse() throws BiffException, PasswordException 480 { 481 Record r = null; 482 483 BOFRecord bof = new BOFRecord(excelFile.next()); 484 workbookBof = bof; 485 bofs++; 486 487 if (!bof.isBiff8() && !bof.isBiff7()) 488 { 489 throw new BiffException(BiffException.unrecognizedBiffVersion); 490 } 491 492 if (!bof.isWorkbookGlobals()) 493 { 494 throw new BiffException(BiffException.expectedGlobals); 495 } 496 ArrayList continueRecords = new ArrayList (); 497 nameTable = new ArrayList (); 498 499 while (bofs == 1) 501 { 502 r = excelFile.next(); 503 504 if (r.getType() == Type.SST) 505 { 506 continueRecords.clear(); 507 Record nextrec = excelFile.peek(); 508 while (nextrec.getType() == Type.CONTINUE) 509 { 510 continueRecords.add(excelFile.next()); 511 nextrec = excelFile.peek(); 512 } 513 514 Record[] records = new Record[continueRecords.size()]; 516 records = (Record[]) continueRecords.toArray(records); 517 518 sharedStrings = new SSTRecord(r, records, settings); 519 } 520 else if (r.getType() == Type.FILEPASS) 521 { 522 throw new PasswordException(); 523 } 524 else if (r.getType() == Type.NAME) 525 { 526 NameRecord nr = null; 527 528 if (bof.isBiff8()) 529 { 530 nr = new NameRecord(r, settings, namedRecords.size()); 531 532 } 533 else 534 { 535 nr = new NameRecord(r, settings, namedRecords.size(), 536 NameRecord.biff7); 537 } 538 namedRecords.put(nr.getName(), nr); 539 nameTable.add(nr); 540 } 541 else if (r.getType() == Type.FONT) 542 { 543 FontRecord fr = null; 544 545 if (bof.isBiff8()) 546 { 547 fr = new FontRecord(r, settings); 548 } 549 else 550 { 551 fr = new FontRecord(r, settings, FontRecord.biff7); 552 } 553 fonts.addFont(fr); 554 } 555 else if (r.getType() == Type.PALETTE) 556 { 557 PaletteRecord palette = new PaletteRecord(r); 558 formattingRecords.setPalette(palette); 559 } 560 else if (r.getType() == Type.NINETEENFOUR) 561 { 562 NineteenFourRecord nr = new NineteenFourRecord(r); 563 nineteenFour = nr.is1904(); 564 } 565 else if (r.getType() == Type.FORMAT) 566 { 567 FormatRecord fr = null; 568 if (bof.isBiff8()) 569 { 570 fr = new FormatRecord(r, settings, FormatRecord.biff8); 571 } 572 else 573 { 574 fr = new FormatRecord(r, settings, FormatRecord.biff7); 575 } 576 try 577 { 578 formattingRecords.addFormat(fr); 579 } 580 catch (NumFormatRecordsException e) 581 { 582 e.printStackTrace(); 583 Assert.verify(false, e.getMessage()); 585 } 586 } 587 else if (r.getType() == Type.XF) 588 { 589 XFRecord xfr = null; 590 if (bof.isBiff8()) 591 { 592 xfr = new XFRecord(r, settings, XFRecord.biff8); 593 } 594 else 595 { 596 xfr = new XFRecord(r, settings, XFRecord.biff7); 597 } 598 599 try 600 { 601 formattingRecords.addStyle(xfr); 602 } 603 catch (NumFormatRecordsException e) 604 { 605 Assert.verify(false, e.getMessage()); 607 } 608 } 609 else if (r.getType() == Type.BOUNDSHEET) 610 { 611 BoundsheetRecord br = null; 612 613 if (bof.isBiff8()) 614 { 615 br = new BoundsheetRecord(r); 616 } 617 else 618 { 619 br = new BoundsheetRecord(r, BoundsheetRecord.biff7); 620 } 621 622 if (br.isSheet()) 623 { 624 boundsheets.add(br); 625 } 626 else if (br.isChart() && !settings.getDrawingsDisabled()) 627 { 628 boundsheets.add(br); 629 } 630 } 631 else if (r.getType() == Type.EXTERNSHEET) 632 { 633 if (bof.isBiff8()) 634 { 635 externSheet = new ExternalSheetRecord(r, settings); 636 } 637 else 638 { 639 externSheet = new ExternalSheetRecord(r, settings, 640 ExternalSheetRecord.biff7); 641 } 642 } 643 else if (r.getType() == Type.CODEPAGE) 644 { 645 CodepageRecord cr = new CodepageRecord(r); 646 settings.setCharacterSet(cr.getCharacterSet()); 647 } 648 else if (r.getType() == Type.SUPBOOK) 649 { 650 Record nextrec = excelFile.peek(); 651 while (nextrec.getType() == Type.CONTINUE) 652 { 653 r.addContinueRecord(excelFile.next()); 654 nextrec = excelFile.peek(); 655 } 656 657 SupbookRecord sr = new SupbookRecord(r, settings); 658 supbooks.add(sr); 659 } 660 else if (r.getType() == Type.PROTECT) 661 { 662 ProtectRecord pr = new ProtectRecord(r); 663 wbProtected = pr.isProtected(); 664 } 665 else if (r.getType() == Type.OBJPROJ) 666 { 667 containsMacros = true; 668 } 669 else if (r.getType() == Type.COUNTRY) 670 { 671 countryRecord = new CountryRecord(r); 672 } 673 else if (r.getType() == Type.MSODRAWINGGROUP) 674 { 675 if (!settings.getDrawingsDisabled()) 676 { 677 msoDrawingGroup = new MsoDrawingGroupRecord(r); 678 679 if (drawingGroup == null) 680 { 681 drawingGroup = new DrawingGroup(Origin.READ); 682 } 683 684 drawingGroup.add(msoDrawingGroup); 685 686 Record nextrec = excelFile.peek(); 687 while (nextrec.getType() == Type.CONTINUE) 688 { 689 drawingGroup.add(excelFile.next()); 690 nextrec = excelFile.peek(); 691 } 692 } 693 } 694 else if (r.getType() == Type.BUTTONPROPERTYSET) 695 { 696 buttonPropertySet = new ButtonPropertySetRecord(r); 697 } 698 else if (r.getType() == Type.EOF) 699 { 700 bofs--; 701 } 702 } 703 704 bof = null; 705 if (excelFile.hasNext()) 706 { 707 r = excelFile.next(); 708 709 if (r.getType() == Type.BOF) 710 { 711 bof = new BOFRecord(r); 712 } 713 } 714 715 while (bof != null && getNumberOfSheets() < boundsheets.size()) 717 { 718 if (!bof.isBiff8() && !bof.isBiff7()) 719 { 720 throw new BiffException(BiffException.unrecognizedBiffVersion); 721 } 722 723 if (bof.isWorksheet()) 724 { 725 SheetImpl s = new SheetImpl(excelFile, 727 sharedStrings, 728 formattingRecords, 729 bof, 730 workbookBof, 731 nineteenFour, 732 this); 733 734 BoundsheetRecord br = (BoundsheetRecord) boundsheets.get 735 (getNumberOfSheets()); 736 s.setName(br.getName()); 737 s.setHidden(br.isHidden()); 738 addSheet(s); 739 } 740 else if (bof.isChart()) 741 { 742 SheetImpl s = new SheetImpl(excelFile, 744 sharedStrings, 745 formattingRecords, 746 bof, 747 workbookBof, 748 nineteenFour, 749 this); 750 751 BoundsheetRecord br = (BoundsheetRecord) boundsheets.get 752 (getNumberOfSheets()); 753 s.setName(br.getName()); 754 s.setHidden(br.isHidden()); 755 addSheet(s); 756 } 757 else 758 { 759 logger.warn("BOF is unrecognized"); 760 761 762 while (excelFile.hasNext() && r.getType() != Type.EOF) 763 { 764 r = excelFile.next(); 765 } 766 } 767 768 bof = null; 774 if (excelFile.hasNext()) 775 { 776 r = excelFile.next(); 777 778 if (r.getType() == Type.BOF) 779 { 780 bof = new BOFRecord(r); 781 } 782 } 783 } 784 } 785 786 792 public FormattingRecords getFormattingRecords() 793 { 794 return formattingRecords; 795 } 796 797 803 public ExternalSheetRecord getExternalSheetRecord() 804 { 805 return externSheet; 806 } 807 808 814 public MsoDrawingGroupRecord getMsoDrawingGroupRecord() 815 { 816 return msoDrawingGroup; 817 } 818 819 825 public SupbookRecord[] getSupbookRecords() 826 { 827 SupbookRecord[] sr = new SupbookRecord[supbooks.size()]; 828 return (SupbookRecord[]) supbooks.toArray(sr); 829 } 830 831 837 public NameRecord[] getNameRecords() 838 { 839 NameRecord[] na = new NameRecord[nameTable.size()]; 840 return (NameRecord[]) nameTable.toArray(na); 841 } 842 843 848 public Fonts getFonts() 849 { 850 return fonts; 851 } 852 853 862 public Cell findCellByName(String name) 863 { 864 NameRecord nr = (NameRecord) namedRecords.get(name); 865 866 if (nr == null) 867 { 868 return null; 869 } 870 871 NameRecord.NameRange[] ranges = nr.getRanges(); 872 873 Sheet s = getSheet(ranges[0].getExternalSheet()); 875 Cell cell = s.getCell(ranges[0].getFirstColumn(), ranges[0].getFirstRow()); 876 877 return cell; 878 } 879 880 894 public Range[] findByName(String name) 895 { 896 NameRecord nr = (NameRecord) namedRecords.get(name); 897 898 if (nr == null) 899 { 900 return null; 901 } 902 903 NameRecord.NameRange[] ranges = nr.getRanges(); 904 905 Range[] cellRanges = new Range[ranges.length]; 906 907 for (int i = 0; i < ranges.length; i++) 908 { 909 cellRanges[i] = new RangeImpl 910 (this, 911 getExternalSheetIndex(ranges[i].getExternalSheet()), 912 ranges[i].getFirstColumn(), 913 ranges[i].getFirstRow(), 914 getLastExternalSheetIndex(ranges[i].getExternalSheet()), 915 ranges[i].getLastColumn(), 916 ranges[i].getLastRow()); 917 } 918 919 return cellRanges; 920 } 921 922 927 public String [] getRangeNames() 928 { 929 Object [] keys = namedRecords.keySet().toArray(); 930 String [] names = new String [keys.length]; 931 System.arraycopy(keys, 0, names, 0, keys.length); 932 933 return names; 934 } 935 936 942 public BOFRecord getWorkbookBof() 943 { 944 return workbookBof; 945 } 946 947 952 public boolean isProtected() 953 { 954 return wbProtected; 955 } 956 957 962 public WorkbookSettings getSettings() 963 { 964 return settings; 965 } 966 967 973 public int getExternalSheetIndex(String sheetName) 974 { 975 return 0; 976 } 977 978 984 public int getLastExternalSheetIndex(String sheetName) 985 { 986 return 0; 987 } 988 989 995 public String getName(int index) 996 { 997 Assert.verify(index >= 0 && index < nameTable.size()); 998 return ((NameRecord) nameTable.get(index)).getName(); 999 } 1000 1001 1007 public int getNameIndex(String name) 1008 { 1009 NameRecord nr = (NameRecord) namedRecords.get(name); 1010 1011 return nr != null ? nr.getIndex() : 0; 1012 } 1013 1014 1019 public DrawingGroup getDrawingGroup() 1020 { 1021 return drawingGroup; 1022 } 1023 1024 1033 public CompoundFile getCompoundFile() 1034 { 1035 return excelFile.getCompoundFile(); 1036 } 1037 1038 1043 public boolean containsMacros() 1044 { 1045 return containsMacros; 1046 } 1047 1048 1053 public ButtonPropertySetRecord getButtonPropertySet() 1054 { 1055 return buttonPropertySet; 1056 } 1057 1058 1063 public CountryRecord getCountryRecord() 1064 { 1065 return countryRecord; 1066 } 1067} 1068 1069 1070 1071 1072 1073 1074 1075 | Popular Tags |