/** * Does the hard work of building up the object graph from the excel bytes * * @exception BiffException * @exception PasswordException if the workbook is password protected */ protected override void parse() { Record r = null; BOFRecord bof = new BOFRecord(excelFile.next()); workbookBof = bof; bofs++; if (!bof.isBiff8() && !bof.isBiff7()) { throw new BiffException(BiffException.unrecognizedBiffVersion); } if (!bof.isWorkbookGlobals()) { throw new BiffException(BiffException.expectedGlobals); } ArrayList continueRecords = new ArrayList(); ArrayList localNames = new ArrayList(); nameTable = new ArrayList(); addInFunctions = new ArrayList(); // Skip to the first worksheet while (bofs == 1) { r = excelFile.next(); if (r.getType() == Type.SST) { continueRecords.Clear(); Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { continueRecords.Add(excelFile.next()); nextrec = excelFile.peek(); } // cast the array Record[] records = new Record[continueRecords.Count]; int pos = 0; foreach (Record record in continueRecords) records[pos++] = record; sharedStrings = new SSTRecord(r,records,settings); } else if (r.getType() == Type.FILEPASS) { throw new PasswordException(); } else if (r.getType() == Type.NAME) { NameRecord nr = null; if (bof.isBiff8()) { nr = new NameRecord(r,settings,nameTable.Count); } else { nr = new NameRecord(r,settings,nameTable.Count, NameRecord.biff7); } // Add all local and global names to the name table in order to // preserve the indexing nameTable.Add(nr); if (nr.isGlobal()) namedRecords.Add(nr.getName(),nr); else localNames.Add(nr); } else if (r.getType() == Type.FONT) { FontRecord fr = null; if (bof.isBiff8()) fr = new FontRecord(r,settings); else fr = new FontRecord(r,settings,FontRecord.biff7); fonts.addFont(fr); } else if (r.getType() == Type.PALETTE) { CSharpJExcel.Jxl.Biff.PaletteRecord palette = new CSharpJExcel.Jxl.Biff.PaletteRecord(r); formattingRecords.setPalette(palette); } else if (r.getType() == Type.NINETEENFOUR) { NineteenFourRecord nr = new NineteenFourRecord(r); nineteenFour = nr.is1904(); } else if (r.getType() == Type.FORMAT) { FormatRecord fr = null; if (bof.isBiff8()) fr = new FormatRecord(r,settings,FormatRecord.biff8); else fr = new FormatRecord(r,settings,FormatRecord.biff7); try { formattingRecords.addFormat(fr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out Assert.verify(false,e.Message); } } else if (r.getType() == Type.XF) { XFRecord xfr = null; if (bof.isBiff8()) xfr = new XFRecord(r,settings,XFRecord.biff8); else xfr = new XFRecord(r,settings,XFRecord.biff7); try { formattingRecords.addStyle(xfr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out Assert.verify(false,e.Message); } } else if (r.getType() == Type.BOUNDSHEET) { BoundsheetRecord br = null; if (bof.isBiff8()) br = new BoundsheetRecord(r,settings); else br = new BoundsheetRecord(r,BoundsheetRecord.biff7); if (br.isSheet()) boundsheets.Add(br); else if (br.isChart() && !settings.getDrawingsDisabled()) boundsheets.Add(br); } else if (r.getType() == Type.EXTERNSHEET) { if (bof.isBiff8()) externSheet = new ExternalSheetRecord(r,settings); else externSheet = new ExternalSheetRecord(r,settings,ExternalSheetRecord.biff7); } else if (r.getType() == Type.XCT) { XCTRecord xctr = new XCTRecord(r); xctRecords.Add(xctr); } else if (r.getType() == Type.CODEPAGE) { CodepageRecord cr = new CodepageRecord(r); settings.setCharacterSet(cr.getCharacterSet()); } else if (r.getType() == Type.SUPBOOK) { Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { r.addContinueRecord(excelFile.next()); nextrec = excelFile.peek(); } SupbookRecord sr = new SupbookRecord(r,settings); supbooks.Add(sr); } else if (r.getType() == Type.EXTERNNAME) { ExternalNameRecord enr = new ExternalNameRecord(r,settings); if (enr.isAddInFunction()) { addInFunctions.Add(enr.getName()); } } else if (r.getType() == Type.PROTECT) { ProtectRecord pr = new ProtectRecord(r); wbProtected = pr.isProtected(); } else if (r.getType() == Type.OBJPROJ) { doesContainMacros = true; } else if (r.getType() == Type.COUNTRY) { countryRecord = new CountryRecord(r); } else if (r.getType() == Type.MSODRAWINGGROUP) { if (!settings.getDrawingsDisabled()) { msoDrawingGroup = new MsoDrawingGroupRecord(r); if (drawingGroup == null) { drawingGroup = new DrawingGroup(Origin.READ); } drawingGroup.add(msoDrawingGroup); Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { drawingGroup.add(excelFile.next()); nextrec = excelFile.peek(); } } } else if (r.getType() == Type.BUTTONPROPERTYSET) buttonPropertySet = new ButtonPropertySetRecord(r); else if (r.getType() == Type.EOF) bofs--; else if (r.getType() == Type.REFRESHALL) { RefreshAllRecord rfm = new RefreshAllRecord(r); settings.setRefreshAll(rfm.getRefreshAll()); } else if (r.getType() == Type.TEMPLATE) { TemplateRecord rfm = new TemplateRecord(r); settings.setTemplate(rfm.getTemplate()); } else if (r.getType() == Type.EXCEL9FILE) { Excel9FileRecord e9f = new Excel9FileRecord(r); settings.setExcel9File(e9f.getExcel9File()); } else if (r.getType() == Type.WINDOWPROTECT) { WindowProtectedRecord winp = new WindowProtectedRecord(r); settings.setWindowProtected(winp.getWindowProtected()); } else if (r.getType() == Type.HIDEOBJ) { HideobjRecord hobj = new HideobjRecord(r); settings.setHideobj(hobj.getHideMode()); } else if (r.getType() == Type.WRITEACCESS) { WriteAccessRecord war = new WriteAccessRecord(r,bof.isBiff8(),settings); settings.setWriteAccess(war.getWriteAccess()); } else { // logger.info("Unsupported record type: " + // Integer.toHexString(r.getCode())+"h"); } } bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.getType() == Type.BOF) bof = new BOFRecord(r); } // Only get sheets for which there is a corresponding Boundsheet record while (bof != null && getNumberOfSheets() < boundsheets.Count) { if (!bof.isBiff8() && !bof.isBiff7()) throw new BiffException(BiffException.unrecognizedBiffVersion); if (bof.isWorksheet()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[getNumberOfSheets()]; s.setName(br.getName()); s.setHidden(br.isHidden()); addSheet(s); } else if (bof.isChart()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[getNumberOfSheets()]; s.setName(br.getName()); s.setHidden(br.isHidden()); addSheet(s); } else { //logger.warn("BOF is unrecognized"); while (excelFile.hasNext() && r.getType() != Type.EOF) r = excelFile.next(); } // The next record will normally be a BOF or empty padding until // the end of the block is reached. In exceptionally unlucky cases, // the last EOF will coincide with a block division, so we have to // check there is more data to retrieve. // Thanks to liamg for spotting this bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.getType() == Type.BOF) bof = new BOFRecord(r); } } // Add all the local names to the specific sheets foreach (NameRecord nr in localNames) { if (nr.getBuiltInName() == null) { //logger.warn("Usage of a local non-builtin name"); } else if (nr.getBuiltInName() == BuiltInName.PRINT_AREA || nr.getBuiltInName() == BuiltInName.PRINT_TITLES) { // appears to use the internal tab number rather than the // external sheet index SheetImpl s = (SheetImpl)sheets[nr.getSheetRef() - 1]; s.addLocalName(nr); } } }
/** * Does the hard work of building up the object graph from the excel bytes * * @exception BiffException * @exception PasswordException if the workbook is password protected */ protected override void parse() { Record r = null; BOFRecord bof = new BOFRecord(excelFile.next()); workbookBof = bof; bofs++; if (!bof.isBiff8() && !bof.isBiff7()) { throw new BiffException(BiffException.unrecognizedBiffVersion); } if (!bof.isWorkbookGlobals()) { throw new BiffException(BiffException.expectedGlobals); } ArrayList continueRecords = new ArrayList(); ArrayList localNames = new ArrayList(); nameTable = new ArrayList(); addInFunctions = new ArrayList(); // Skip to the first worksheet while (bofs == 1) { r = excelFile.next(); if (r.getType() == Type.SST) { continueRecords.Clear(); Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { continueRecords.Add(excelFile.next()); nextrec = excelFile.peek(); } // cast the array Record[] records = new Record[continueRecords.Count]; int pos = 0; foreach (Record record in continueRecords) { records[pos++] = record; } sharedStrings = new SSTRecord(r, records, settings); } else if (r.getType() == Type.FILEPASS) { throw new PasswordException(); } else if (r.getType() == Type.NAME) { NameRecord nr = null; if (bof.isBiff8()) { nr = new NameRecord(r, settings, nameTable.Count); } else { nr = new NameRecord(r, settings, nameTable.Count, NameRecord.biff7); } // Add all local and global names to the name table in order to // preserve the indexing nameTable.Add(nr); if (nr.isGlobal()) { namedRecords.Add(nr.getName(), nr); } else { localNames.Add(nr); } } else if (r.getType() == Type.FONT) { FontRecord fr = null; if (bof.isBiff8()) { fr = new FontRecord(r, settings); } else { fr = new FontRecord(r, settings, FontRecord.biff7); } fonts.addFont(fr); } else if (r.getType() == Type.PALETTE) { CSharpJExcel.Jxl.Biff.PaletteRecord palette = new CSharpJExcel.Jxl.Biff.PaletteRecord(r); formattingRecords.setPalette(palette); } else if (r.getType() == Type.NINETEENFOUR) { NineteenFourRecord nr = new NineteenFourRecord(r); nineteenFour = nr.is1904(); } else if (r.getType() == Type.FORMAT) { FormatRecord fr = null; if (bof.isBiff8()) { fr = new FormatRecord(r, settings, FormatRecord.biff8); } else { fr = new FormatRecord(r, settings, FormatRecord.biff7); } try { formattingRecords.addFormat(fr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out Assert.verify(false, e.Message); } } else if (r.getType() == Type.XF) { XFRecord xfr = null; if (bof.isBiff8()) { xfr = new XFRecord(r, settings, XFRecord.biff8); } else { xfr = new XFRecord(r, settings, XFRecord.biff7); } try { formattingRecords.addStyle(xfr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out Assert.verify(false, e.Message); } } else if (r.getType() == Type.BOUNDSHEET) { BoundsheetRecord br = null; if (bof.isBiff8()) { br = new BoundsheetRecord(r, settings); } else { br = new BoundsheetRecord(r, BoundsheetRecord.biff7); } if (br.isSheet()) { boundsheets.Add(br); } else if (br.isChart() && !settings.getDrawingsDisabled()) { boundsheets.Add(br); } } else if (r.getType() == Type.EXTERNSHEET) { if (bof.isBiff8()) { externSheet = new ExternalSheetRecord(r, settings); } else { externSheet = new ExternalSheetRecord(r, settings, ExternalSheetRecord.biff7); } } else if (r.getType() == Type.XCT) { XCTRecord xctr = new XCTRecord(r); xctRecords.Add(xctr); } else if (r.getType() == Type.CODEPAGE) { CodepageRecord cr = new CodepageRecord(r); settings.setCharacterSet(cr.getCharacterSet()); } else if (r.getType() == Type.SUPBOOK) { Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { r.addContinueRecord(excelFile.next()); nextrec = excelFile.peek(); } SupbookRecord sr = new SupbookRecord(r, settings); supbooks.Add(sr); } else if (r.getType() == Type.EXTERNNAME) { ExternalNameRecord enr = new ExternalNameRecord(r, settings); if (enr.isAddInFunction()) { addInFunctions.Add(enr.getName()); } } else if (r.getType() == Type.PROTECT) { ProtectRecord pr = new ProtectRecord(r); wbProtected = pr.isProtected(); } else if (r.getType() == Type.OBJPROJ) { doesContainMacros = true; } else if (r.getType() == Type.COUNTRY) { countryRecord = new CountryRecord(r); } else if (r.getType() == Type.MSODRAWINGGROUP) { if (!settings.getDrawingsDisabled()) { msoDrawingGroup = new MsoDrawingGroupRecord(r); if (drawingGroup == null) { drawingGroup = new DrawingGroup(Origin.READ); } drawingGroup.add(msoDrawingGroup); Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { drawingGroup.add(excelFile.next()); nextrec = excelFile.peek(); } } } else if (r.getType() == Type.BUTTONPROPERTYSET) { buttonPropertySet = new ButtonPropertySetRecord(r); } else if (r.getType() == Type.EOF) { bofs--; } else if (r.getType() == Type.REFRESHALL) { RefreshAllRecord rfm = new RefreshAllRecord(r); settings.setRefreshAll(rfm.getRefreshAll()); } else if (r.getType() == Type.TEMPLATE) { TemplateRecord rfm = new TemplateRecord(r); settings.setTemplate(rfm.getTemplate()); } else if (r.getType() == Type.EXCEL9FILE) { Excel9FileRecord e9f = new Excel9FileRecord(r); settings.setExcel9File(e9f.getExcel9File()); } else if (r.getType() == Type.WINDOWPROTECT) { WindowProtectedRecord winp = new WindowProtectedRecord(r); settings.setWindowProtected(winp.getWindowProtected()); } else if (r.getType() == Type.HIDEOBJ) { HideobjRecord hobj = new HideobjRecord(r); settings.setHideobj(hobj.getHideMode()); } else if (r.getType() == Type.WRITEACCESS) { WriteAccessRecord war = new WriteAccessRecord(r, bof.isBiff8(), settings); settings.setWriteAccess(war.getWriteAccess()); } else { // logger.info("Unsupported record type: " + // Integer.toHexString(r.getCode())+"h"); } } bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.getType() == Type.BOF) { bof = new BOFRecord(r); } } // Only get sheets for which there is a corresponding Boundsheet record while (bof != null && getNumberOfSheets() < boundsheets.Count) { if (!bof.isBiff8() && !bof.isBiff7()) { throw new BiffException(BiffException.unrecognizedBiffVersion); } if (bof.isWorksheet()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[getNumberOfSheets()]; s.setName(br.getName()); s.setHidden(br.isHidden()); addSheet(s); } else if (bof.isChart()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[getNumberOfSheets()]; s.setName(br.getName()); s.setHidden(br.isHidden()); addSheet(s); } else { //logger.warn("BOF is unrecognized"); while (excelFile.hasNext() && r.getType() != Type.EOF) { r = excelFile.next(); } } // The next record will normally be a BOF or empty padding until // the end of the block is reached. In exceptionally unlucky cases, // the last EOF will coincide with a block division, so we have to // check there is more data to retrieve. // Thanks to liamg for spotting this bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.getType() == Type.BOF) { bof = new BOFRecord(r); } } } // Add all the local names to the specific sheets foreach (NameRecord nr in localNames) { if (nr.getBuiltInName() == null) { //logger.warn("Usage of a local non-builtin name"); } else if (nr.getBuiltInName() == BuiltInName.PRINT_AREA || nr.getBuiltInName() == BuiltInName.PRINT_TITLES) { // appears to use the internal tab number rather than the // external sheet index SheetImpl s = (SheetImpl)sheets[nr.getSheetRef() - 1]; s.addLocalName(nr); } } }
/** * Reads in the contents of this sheet */ public void read() { Record r = null; BaseSharedFormulaRecord sharedFormula = null; bool sharedFormulaAdded = false; bool cont = true; // Set the position within the file excelFile.setPos(startPosition); // Handles to the last drawing and obj records MsoDrawingRecord msoRecord = null; ObjRecord objRecord = null; bool firstMsoRecord = true; // Handle to the last conditional format record ConditionalFormat condFormat = null; // Handle to the autofilter records FilterModeRecord filterMode = null; AutoFilterInfoRecord autoFilterInfo = null; // A handle to window2 record Window2Record window2Record = null; // A handle to printgridlines record PrintGridLinesRecord printGridLinesRecord = null; // A handle to printheaders record PrintHeadersRecord printHeadersRecord = null; // Hash map of comments, indexed on objectId. As each corresponding // note record is encountered, these are removed from the array Dictionary<uint,Comment> comments = new Dictionary<uint,Comment>(); // A list of object ids - used for cross referencing ArrayList objectIds = new ArrayList(); // A handle to a continue record read in ContinueRecord continueRecord = null; while (cont) { r = excelFile.next(); Type type = r.getType(); if (type == Type.UNKNOWN && r.getCode() == 0) { //logger.warn("Biff code zero found"); // Try a dimension record if (r.getLength() == 0xa) { //logger.warn("Biff code zero found - trying a dimension record."); r.setType(Type.DIMENSION); } else { //logger.warn("Biff code zero found - Ignoring."); } } if (type == Type.DIMENSION) { DimensionRecord dr = null; if (workbookBof.isBiff8()) { dr = new DimensionRecord(r); } else { dr = new DimensionRecord(r, DimensionRecord.biff7); } numRows = dr.getNumberOfRows(); numCols = dr.getNumberOfColumns(); cells = new Cell[numRows, numCols]; } else if (type == Type.LABELSST) { LabelSSTRecord label = new LabelSSTRecord(r, sharedStrings, formattingRecords, sheet); addCell(label); } else if (type == Type.RK || type == Type.RK2) { RKRecord rkr = new RKRecord(r, formattingRecords, sheet); if (formattingRecords.isDate(rkr.getXFIndex())) { DateCell dc = new DateRecord (rkr, rkr.getXFIndex(), formattingRecords, nineteenFour, sheet); addCell(dc); } else { addCell(rkr); } } else if (type == Type.HLINK) { HyperlinkRecord hr = new HyperlinkRecord(r, sheet, workbookSettings); hyperlinks.Add(hr); } else if (type == Type.MERGEDCELLS) { MergedCellsRecord mc = new MergedCellsRecord(r, sheet); if (mergedCells == null) { mergedCells = mc.getRanges(); } else { Range[] newMergedCells = new Range[mergedCells.Length + mc.getRanges().Length]; System.Array.Copy(mergedCells, 0, newMergedCells, 0, mergedCells.Length); System.Array.Copy(mc.getRanges(), 0, newMergedCells, mergedCells.Length, mc.getRanges().Length); mergedCells = newMergedCells; } } else if (type == Type.MULRK) { MulRKRecord mulrk = new MulRKRecord(r); // Get the individual cell records from the multiple record int num = mulrk.getNumberOfColumns(); int ixf = 0; for (int i = 0; i < num; i++) { ixf = mulrk.getXFIndex(i); NumberValue nv = new NumberValue (mulrk.getRow(), mulrk.getFirstColumn() + i, RKHelper.getDouble(mulrk.getRKNumber(i)), ixf, formattingRecords, sheet); if (formattingRecords.isDate(ixf)) { DateCell dc = new DateRecord(nv, ixf, formattingRecords, nineteenFour, sheet); addCell(dc); } else { nv.setNumberFormat(formattingRecords.getNumberFormat(ixf)); addCell(nv); } } } else if (type == Type.NUMBER) { NumberRecord nr = new NumberRecord(r, formattingRecords, sheet); if (formattingRecords.isDate(nr.getXFIndex())) { DateCell dc = new DateRecord(nr,nr.getXFIndex(),formattingRecords,nineteenFour, sheet); addCell(dc); } else addCell(nr); } else if (type == Type.BOOLERR) { BooleanRecord br = new BooleanRecord(r, formattingRecords, sheet); if (br.isError()) { ErrorRecord er = new ErrorRecord(br.getRecord(), formattingRecords, sheet); addCell(er); } else { addCell(br); } } else if (type == Type.PRINTGRIDLINES) { printGridLinesRecord = new PrintGridLinesRecord(r); settings.setPrintGridLines(printGridLinesRecord.getPrintGridLines()); } else if (type == Type.PRINTHEADERS) { printHeadersRecord = new PrintHeadersRecord(r); settings.setPrintHeaders(printHeadersRecord.getPrintHeaders()); } else if (type == Type.WINDOW2) { window2Record = null; if (workbookBof.isBiff8()) { window2Record = new Window2Record(r); } else { window2Record = new Window2Record(r, Window2Record.biff7); } settings.setShowGridLines(window2Record.getShowGridLines()); settings.setDisplayZeroValues(window2Record.getDisplayZeroValues()); settings.setSelected(true); settings.setPageBreakPreviewMode(window2Record.isPageBreakPreview()); } else if (type == Type.PANE) { PaneRecord pr = new PaneRecord(r); if (window2Record != null && window2Record.getFrozen()) { settings.setVerticalFreeze(pr.getRowsVisible()); settings.setHorizontalFreeze(pr.getColumnsVisible()); } } else if (type == Type.CONTINUE) { // don't know what this is for, but keep hold of it anyway continueRecord = new ContinueRecord(r); } else if (type == Type.NOTE) { if (!workbookSettings.getDrawingsDisabled()) { NoteRecord nr = new NoteRecord(r); // Get the comment for the object id if (!comments.ContainsKey(nr.getObjectId())) { //logger.warn(" cannot find comment for note id " + nr.getObjectId() + "...ignoring"); } else { Comment comment = comments[nr.getObjectId()]; comments.Remove(nr.getObjectId()); comment.setNote(nr); drawings.Add(comment); addCellComment(comment.getColumn(), comment.getRow(), comment.getText(), comment.getWidth(), comment.getHeight()); } } } else if (type == Type.ARRAY) { ; } else if (type == Type.PROTECT) { ProtectRecord pr = new ProtectRecord(r); settings.setProtected(pr.isProtected()); } else if (type == Type.SHAREDFORMULA) { if (sharedFormula == null) { //logger.warn("Shared template formula is null - " + // "trying most recent formula template"); SharedFormulaRecord lastSharedFormula = (SharedFormulaRecord)sharedFormulas[sharedFormulas.Count - 1]; if (lastSharedFormula != null) sharedFormula = lastSharedFormula.getTemplateFormula(); } SharedFormulaRecord sfr = new SharedFormulaRecord(r, sharedFormula, workbook, workbook, sheet); sharedFormulas.Add(sfr); sharedFormula = null; } else if (type == Type.FORMULA || type == Type.FORMULA2) { FormulaRecord fr = new FormulaRecord(r, excelFile, formattingRecords, workbook, workbook, sheet, workbookSettings); if (fr.isShared()) { BaseSharedFormulaRecord prevSharedFormula = sharedFormula; sharedFormula = (BaseSharedFormulaRecord)fr.getFormula(); // See if it fits in any of the shared formulas sharedFormulaAdded = addToSharedFormulas(sharedFormula); if (sharedFormulaAdded) { sharedFormula = prevSharedFormula; } // If we still haven't added the previous base shared formula, // revert it to an ordinary formula and add it to the cell if (!sharedFormulaAdded && prevSharedFormula != null) { // Do nothing. It's possible for the biff file to contain the // record sequence // FORMULA-SHRFMLA-FORMULA-SHRFMLA-FORMULA-FORMULA-FORMULA // ie. it first lists all the formula templates, then it // lists all the individual formulas addCell(revertSharedFormula(prevSharedFormula)); } } else { Cell cell = fr.getFormula(); try { // See if the formula evaluates to date if (fr.getFormula().getType() == CellType.NUMBER_FORMULA) { NumberFormulaRecord nfr = (NumberFormulaRecord)fr.getFormula(); if (formattingRecords.isDate(nfr.getXFIndex())) { cell = new DateFormulaRecord(nfr, formattingRecords, workbook, workbook, nineteenFour, sheet); } } addCell(cell); } catch (FormulaException e) { // Something has gone wrong trying to read the formula data eg. it // might be unsupported biff7 data //logger.warn(CellReferenceHelper.getCellReference(cell.getColumn(), cell.getRow()) + " " + e.Message); } } } else if (type == Type.LABEL) { LabelRecord lr = null; if (workbookBof.isBiff8()) { lr = new LabelRecord(r, formattingRecords, sheet, workbookSettings); } else { lr = new LabelRecord(r, formattingRecords, sheet, workbookSettings, LabelRecord.biff7); } addCell(lr); } else if (type == Type.RSTRING) { RStringRecord lr = null; // RString records are obsolete in biff 8 Assert.verify(!workbookBof.isBiff8()); lr = new RStringRecord(r, formattingRecords, sheet, workbookSettings, RStringRecord.biff7); addCell(lr); } else if (type == Type.NAME) { ; } else if (type == Type.PASSWORD) { PasswordRecord pr = new PasswordRecord(r); settings.setPasswordHash(pr.getPasswordHash()); } else if (type == Type.ROW) { RowRecord rr = new RowRecord(r); // See if the row has anything funny about it if (!rr.isDefaultHeight() || !rr.matchesDefaultFontHeight() || rr.isCollapsed() || rr.hasDefaultFormat() || rr.getOutlineLevel() != 0) { rowProperties.Add(rr); } } else if (type == Type.BLANK) { if (!workbookSettings.getIgnoreBlanks()) { BlankCell bc = new BlankCell(r, formattingRecords, sheet); addCell(bc); } } else if (type == Type.MULBLANK) { if (!workbookSettings.getIgnoreBlanks()) { MulBlankRecord mulblank = new MulBlankRecord(r); // Get the individual cell records from the multiple record int num = mulblank.getNumberOfColumns(); for (int i = 0; i < num; i++) { int ixf = mulblank.getXFIndex(i); MulBlankCell mbc = new MulBlankCell (mulblank.getRow(), mulblank.getFirstColumn() + i, ixf, formattingRecords, sheet); addCell(mbc); } } } else if (type == Type.SCL) { SCLRecord scl = new SCLRecord(r); settings.setZoomFactor(scl.getZoomFactor()); } else if (type == Type.COLINFO) { ColumnInfoRecord cir = new ColumnInfoRecord(r); columnInfosArray.Add(cir); } else if (type == Type.HEADER) { HeaderRecord hr = null; if (workbookBof.isBiff8()) hr = new HeaderRecord(r, workbookSettings); else hr = new HeaderRecord(r, workbookSettings, HeaderRecord.biff7); HeaderFooter header = new HeaderFooter(hr.getHeader()); settings.setHeader(header); } else if (type == Type.FOOTER) { FooterRecord fr = null; if (workbookBof.isBiff8()) { fr = new FooterRecord(r, workbookSettings); } else { fr = new FooterRecord(r, workbookSettings, FooterRecord.biff7); } HeaderFooter footer = new HeaderFooter(fr.getFooter()); settings.setFooter(footer); } else if (type == Type.SETUP) { SetupRecord sr = new SetupRecord(r); // If the setup record has its not initialized bit set, then // use the sheet settings default values if (sr.getInitialized()) { if (sr.isPortrait()) { settings.setOrientation(PageOrientation.PORTRAIT); } else { settings.setOrientation(PageOrientation.LANDSCAPE); } if (sr.isRightDown()) { settings.setPageOrder(PageOrder.RIGHT_THEN_DOWN); } else { settings.setPageOrder(PageOrder.DOWN_THEN_RIGHT); } settings.setPaperSize(PaperSize.getPaperSize(sr.getPaperSize())); settings.setHeaderMargin(sr.getHeaderMargin()); settings.setFooterMargin(sr.getFooterMargin()); settings.setScaleFactor(sr.getScaleFactor()); settings.setPageStart(sr.getPageStart()); settings.setFitWidth(sr.getFitWidth()); settings.setFitHeight(sr.getFitHeight()); settings.setHorizontalPrintResolution (sr.getHorizontalPrintResolution()); settings.setVerticalPrintResolution(sr.getVerticalPrintResolution()); settings.setCopies(sr.getCopies()); if (workspaceOptions != null) { settings.setFitToPages(workspaceOptions.getFitToPages()); } } } else if (type == Type.WSBOOL) { workspaceOptions = new WorkspaceInformationRecord(r); } else if (type == Type.DEFCOLWIDTH) { DefaultColumnWidthRecord dcwr = new DefaultColumnWidthRecord(r); settings.setDefaultColumnWidth(dcwr.getWidth()); } else if (type == Type.DEFAULTROWHEIGHT) { DefaultRowHeightRecord drhr = new DefaultRowHeightRecord(r); if (drhr.getHeight() != 0) { settings.setDefaultRowHeight(drhr.getHeight()); } } else if (type == Type.CONDFMT) { ConditionalFormatRangeRecord cfrr = new ConditionalFormatRangeRecord(r); condFormat = new ConditionalFormat(cfrr); conditionalFormats.Add(condFormat); } else if (type == Type.CF) { ConditionalFormatRecord cfr = new ConditionalFormatRecord(r); condFormat.addCondition(cfr); } else if (type == Type.FILTERMODE) { filterMode = new FilterModeRecord(r); } else if (type == Type.AUTOFILTERINFO) { autoFilterInfo = new AutoFilterInfoRecord(r); } else if (type == Type.AUTOFILTER) { if (!workbookSettings.getAutoFilterDisabled()) { AutoFilterRecord af = new AutoFilterRecord(r); if (autoFilter == null) { autoFilter = new AutoFilter(filterMode, autoFilterInfo); filterMode = null; autoFilterInfo = null; } autoFilter.add(af); } } else if (type == Type.LEFTMARGIN) { MarginRecord m = new LeftMarginRecord(r); settings.setLeftMargin(m.getMargin()); } else if (type == Type.RIGHTMARGIN) { MarginRecord m = new RightMarginRecord(r); settings.setRightMargin(m.getMargin()); } else if (type == Type.TOPMARGIN) { MarginRecord m = new TopMarginRecord(r); settings.setTopMargin(m.getMargin()); } else if (type == Type.BOTTOMMARGIN) { MarginRecord m = new BottomMarginRecord(r); settings.setBottomMargin(m.getMargin()); } else if (type == Type.HORIZONTALPAGEBREAKS) { HorizontalPageBreaksRecord dr = null; if (workbookBof.isBiff8()) { dr = new HorizontalPageBreaksRecord(r); } else { dr = new HorizontalPageBreaksRecord (r, HorizontalPageBreaksRecord.biff7); } rowBreaks = dr.getRowBreaks(); } else if (type == Type.VERTICALPAGEBREAKS) { VerticalPageBreaksRecord dr = null; if (workbookBof.isBiff8()) { dr = new VerticalPageBreaksRecord(r); } else { dr = new VerticalPageBreaksRecord (r, VerticalPageBreaksRecord.biff7); } columnBreaks = dr.getColumnBreaks(); } else if (type == Type.PLS) { plsRecord = new PLSRecord(r); // Check for Continue records while (excelFile.peek().getType() == Type.CONTINUE) { r.addContinueRecord(excelFile.next()); } } else if (type == Type.DVAL) { if (!workbookSettings.getCellValidationDisabled()) { DataValidityListRecord dvlr = new DataValidityListRecord(r); if (dvlr.getObjectId() == DataValidation.DEFAULT_OBJECT_ID) { if (msoRecord != null && objRecord == null) { // there is a drop down associated with this data validation if (drawingData == null) drawingData = new DrawingData(); Drawing2 d2 = new Drawing2(msoRecord, drawingData, workbook.getDrawingGroup()); drawings.Add(d2); msoRecord = null; dataValidation = new DataValidation(dvlr); } else { // no drop down dataValidation = new DataValidation(dvlr); } } else if (objectIds.Contains(dvlr.getObjectId())) dataValidation = new DataValidation(dvlr); else { //logger.warn("object id " + dvlr.getObjectId() + " referenced " + // " by data validity list record not found - ignoring"); } } } else if (type == Type.HCENTER) { CentreRecord hr = new CentreRecord(r); settings.setHorizontalCentre(hr.isCentre()); } else if (type == Type.VCENTER) { CentreRecord vc = new CentreRecord(r); settings.setVerticalCentre(vc.isCentre()); } else if (type == Type.DV) { if (!workbookSettings.getCellValidationDisabled()) { DataValiditySettingsRecord dvsr = new DataValiditySettingsRecord(r, workbook, workbook, workbook.getSettings()); if (dataValidation != null) { dataValidation.add(dvsr); addCellValidation(dvsr.getFirstColumn(), dvsr.getFirstRow(), dvsr.getLastColumn(), dvsr.getLastRow(), dvsr); } else { //logger.warn("cannot add data validity settings"); } } } else if (type == Type.OBJ) { objRecord = new ObjRecord(r); if (!workbookSettings.getDrawingsDisabled()) { // sometimes excel writes out continue records instead of drawing // records, so forcibly hack the stashed continue record into // a drawing record if (msoRecord == null && continueRecord != null) { //logger.warn("Cannot find drawing record - using continue record"); msoRecord = new MsoDrawingRecord(continueRecord.getRecord()); continueRecord = null; } handleobjectRecord(objRecord, msoRecord, comments); objectIds.Add((objRecord.getObjectId())); } // Save chart handling until the chart BOF record appears if (objRecord.getType() != ObjRecord.CHART) { objRecord = null; msoRecord = null; } } else if (type == Type.MSODRAWING) { if (!workbookSettings.getDrawingsDisabled()) { if (msoRecord != null) { // For form controls, a rogue MSODRAWING record can crop up // after the main one. Add these into the drawing data drawingData.addRawData(msoRecord.getData()); } msoRecord = new MsoDrawingRecord(r); if (firstMsoRecord) { msoRecord.setFirst(); firstMsoRecord = false; } } } else if (type == Type.BUTTONPROPERTYSET) { buttonPropertySet = new ButtonPropertySetRecord(r); } else if (type == Type.CALCMODE) { CalcModeRecord cmr = new CalcModeRecord(r); settings.setAutomaticFormulaCalculation(cmr.isAutomatic()); } else if (type == Type.SAVERECALC) { SaveRecalcRecord cmr = new SaveRecalcRecord(r); settings.setRecalculateFormulasBeforeSave(cmr.getRecalculateOnSave()); } else if (type == Type.GUTS) { GuttersRecord gr = new GuttersRecord(r); maxRowOutlineLevel = gr.getRowOutlineLevel() > 0 ? gr.getRowOutlineLevel() - 1 : 0; maxColumnOutlineLevel = gr.getColumnOutlineLevel() > 0 ? gr.getRowOutlineLevel() - 1 : 0; } else if (type == Type.BOF) { BOFRecord br = new BOFRecord(r); Assert.verify(!br.isWorksheet()); int startpos = excelFile.getPos() - r.getLength() - 4; // Skip to the end of the nested bof // Thanks to Rohit for spotting this Record r2 = excelFile.next(); while (r2.getCode() != Type.EOF.value) r2 = excelFile.next(); if (br.isChart()) { if (!workbook.getWorkbookBof().isBiff8()) { //logger.warn("only biff8 charts are supported"); } else { if (drawingData == null) drawingData = new DrawingData(); if (!workbookSettings.getDrawingsDisabled()) { Chart chart = new Chart(msoRecord, objRecord, drawingData, startpos, excelFile.getPos(), excelFile, workbookSettings); charts.Add(chart); if (workbook.getDrawingGroup() != null) workbook.getDrawingGroup().add(chart); } } // Reset the drawing records msoRecord = null; objRecord = null; } // If this worksheet is just a chart, then the EOF reached // represents the end of the sheet as well as the end of the chart if (sheetBof.isChart()) cont = false; } else if (type == Type.EOF) cont = false; } // Restore the file to its accurate position excelFile.restorePos(); // Add any out of bounds cells if (outOfBoundsCells.Count > 0) handleOutOfBoundsCells(); // Add all the shared formulas to the sheet as individual formulas foreach (SharedFormulaRecord sfr in sharedFormulas) { Cell[] sfnr = sfr.getFormulas(formattingRecords, nineteenFour); for (int sf = 0; sf < sfnr.Length; sf++) addCell(sfnr[sf]); } // If the last base shared formula wasn't added to the sheet, then // revert it to an ordinary formula and add it if (!sharedFormulaAdded && sharedFormula != null) addCell(revertSharedFormula(sharedFormula)); // If there is a stray msoDrawing record, then flag to the drawing group // that one has been omitted if (msoRecord != null && workbook.getDrawingGroup() != null) workbook.getDrawingGroup().setDrawingsOmitted(msoRecord, objRecord); // Check that the comments hash is empty if (comments.Count != 0) { //logger.warn("Not all comments have a corresponding Note record"); } }