/** * Gets the thread safe version of the cell format passed in. If the * format is already thread safe (ie. it doesn't use a statically initialized * format or font) then the same object is simply returned * This object is already tied to a workbook instance, so no synchronisation * is necesasry * * @param wf a format to verify * @return the thread safe format */ public XFRecord getFormat(XFRecord wf) { XFRecord format = wf; // Check to see if the format is one of the shared Workbook defaults. If // so, then get hold of the Workbook's specific instance if (format == WritableWorkbook.NORMAL_STYLE) { format = getNormalStyle(); } else if (format == WritableWorkbook.HYPERLINK_STYLE) { format = getHyperlinkStyle(); } else if (format == WritableWorkbook.HIDDEN_STYLE) { format = getHiddenStyle(); } else if (format == DateRecord.defaultDateFormat) { format = getDefaultDateFormat(); } // Do the same with the statically shared fonts if (format.getFont() == WritableWorkbook.ARIAL_10_PT) { format.setFont(getArial10Pt()); } else if (format.getFont() == WritableWorkbook.HYPERLINK_FONT) { format.setFont(getHyperlinkFont()); } return(format); }
/** * Returns an initialized copy of the cell format * * @param cf the cell format to copy * @return a deep copy of the cell format */ private WritableCellFormat copyCellFormat(CellFormat cf) { try { // just do a deep copy of the cell format for now. This will create // a copy of the format and font also - in the future this may // need to be sorted out XFRecord xfr = (XFRecord)cf; WritableCellFormat f = new WritableCellFormat(xfr); formatRecords.addStyle(f); // Maintain the local list of formats int xfIndex = xfr.getXFIndex(); xfRecords.Add(xfIndex, f); int fontIndex = xfr.getFontIndex(); fonts.Add(fontIndex, f.getFontIndex()); int formatIndex = xfr.getFormatRecord(); formats.Add(formatIndex, f.getFormatRecord()); return(f); } catch (NumFormatRecordsException e) { //logger.warn("Maximum number of format records exceeded. Using default format."); return(WritableWorkbook.NORMAL_STYLE); } }
/** * Overloaded constructor used when building writable cells from the * Java API which also takes a format * * @param c the column * @param t the cell type * @param r the row * @param st the format to apply to this cell */ protected CellValue(Type t, int c, int r, CellFormat st) : base(t) { row = r; column = c; format = (XFRecord)st; referenced = false; copied = false; }
/** * Constructor used when setting column information from the user * API * * @param w the width of the column in characters * @param col the column to format * @param xf the style for the column */ public ColumnInfoRecord(int col, int w, XFRecord xf) : base(Type.COLINFO) { column = col; width = w; style = xf; xfIndex = style.getXFIndex(); hidden = false; }
/** * Constructor used when copying an existing spreadsheet * * @param col the column number * @param cir the column info record read in * @param fr the format records */ public ColumnInfoRecord(CSharpJExcel.Jxl.Read.Biff.ColumnInfoRecord cir, int col, FormattingRecords fr) : base(Type.COLINFO) { column = col; width = cir.getWidth(); xfIndex = cir.getXFIndex(); style = fr.getXFRecord(xfIndex); outlineLevel = cir.getOutlineLevel(); collapsed = cir.getCollapsed(); }
/** * Gets the CellFormat object for this cell. Used by the WritableWorkbook * API * * @return the CellFormat used for this cell */ public CellFormat getCellFormat() { if (!initialized) { format = formattingRecords.getXFRecord(xfIndex); initialized = true; } return(format); }
/** * Copy constructor used when copying from sheet to sheet within the * same workbook * * @param the record to copy */ public ColumnInfoRecord(ColumnInfoRecord cir) : base(Type.COLINFO) { column = cir.column; width = cir.width; style = cir.style; xfIndex = cir.xfIndex; hidden = cir.hidden; outlineLevel = cir.outlineLevel; collapsed = cir.collapsed; }
/** * Constructor used when creating a writable cell from a read-only cell * (when copying a workbook) * * @param c the cell to clone * @param t the type of this cell */ protected CellValue(Type t, Cell c) : this(t, c.getColumn(), c.getRow()) { copied = true; format = (XFRecord)c.getCellFormat(); if (c.getCellFeatures() != null) { features = new WritableCellFeatures(c.getCellFeatures()); features.setWritableCell(this); } }
/** * Copy constructor * * @param c the column * @param t the cell type * @param r the row * @param cv the value to copy */ protected CellValue(Type t, int c, int r, CellValue cv) : base(t) { row = r; column = c; format = cv.format; referenced = false; copied = false; // used during a deep copy, so the cell features need // to be added again if (cv.features != null) { features = new WritableCellFeatures(cv.features); features.setWritableCell(this); } }
/** * An API function which sets the format to apply to this cell * * @param cf the format to apply to this cell */ public void setCellFormat(CellFormat cf) { format = (XFRecord)cf; // If the referenced flag has not been set, this cell has not // been added to the spreadsheet, so we don't need to perform // any further logic if (!referenced) { return; } // The cell has already been added to the spreadsheet, so the // formattingRecords reference must be initialized Assert.verify(formattingRecords != null); addCellFormat(); }
/** * Adds an extended formatting record to the list. If the XF record passed * in has not been initialized, its index is determined based on the * xfRecords list, and * this position is passed to the XF records initialize method * * @param xf the xf record to add * @exception NumFormatRecordsException */ public void addStyle(XFRecord xf) { if (!xf.isInitialized()) { int pos = xfRecords.Count; xf.initialize(pos, this, fonts); xfRecords.Add(xf); } else { // The XF record has probably been read in. If the index is greater // Than the size of the list, then it is not a preset format, // so add it if (xf.getXFIndex() >= xfRecords.Count) { xfRecords.Add(xf); } } }
/** * Sets the row details based upon the readable row record passed in * Called when copying spreadsheets * * @param height the height of the row record in 1/20ths of a point * @param mdfh matches the default font height * @param col the collapsed status of the row * @param ol the outline level * @param gs the group start * @param xf the xfrecord for the row (NULL if no default is set) */ public void setRowDetails(int height, bool mdfh, bool col, int ol, bool gs, XFRecord xfr) { rowHeight = height; collapsed = col; matchesDefFontHeight = mdfh; outlineLevel = ol; groupStart = gs; if (xfr != null) { defaultFormat = true; style = xfr; xfIndex = style.getXFIndex(); } }
/** * Adds the format information to the shared records. Performs the necessary * checks (and clones) to ensure that the formats are not shared. * Called from setCellDetails and setCellFormat */ private void addCellFormat() { // Check to see if the format is one of the shared Workbook defaults. If // so, then get hold of the Workbook's specific instance Styles styles = sheet.getWorkbook().getStyles(); format = styles.getFormat(format); try { if (!format.isInitialized()) { formattingRecords.addStyle(format); } } catch (NumFormatRecordsException e) { //logger.warn("Maximum number of format records exceeded. Using default format."); format = styles.getNormalStyle(); } }
/** * Sees if the extended formatting record at the specified position * represents a date. First checks against the built in formats, and * then checks against the hash map of FormatRecords * * @param pos the xf format index * @return TRUE if this format index is formatted as a Date */ public bool isDate(int pos) { XFRecord xfr = (XFRecord)xfRecords[pos]; if (xfr.isDate()) { return(true); } if (!formats.ContainsKey(xfr.getFormatRecord())) { return(false); } FormatRecord fmt = formats[xfr.getFormatRecord()] as FormatRecord; if (fmt == null) { return(false); } return(fmt.isDate()); }
/** * Gets the NumberFormat used to format the cell. * * @param pos the xf format index * @return the DateFormat object used to format the date in the original * excel cell */ public CSharpJExcel.Interop.NumberFormat getNumberFormat(int pos) { XFRecord xfr = (XFRecord)xfRecords[pos]; if (xfr.isNumber()) { return(xfr.getNumberFormat()); } if (!formats.ContainsKey(xfr.getFormatRecord())) { return(null); } FormatRecord fr = formats[xfr.getFormatRecord()] as FormatRecord; if (fr == null) { return(null); } return(fr.isNumber() ? fr.getNumberFormat() : null); }
/// <summary> Does the hard work of building up the object graph from the excel bytes /// /// </summary> /// <exception cref=""> BiffException /// </exception> /// <exception cref=""> PasswordException if the workbook is password protected /// </exception> protected internal 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(); nameTable = new ArrayList(); // Skip to the first worksheet while (bofs == 1) { r = excelFile.next(); if (r.Type == NExcel.Biff.Type.SST) { continueRecords.Clear(); Record nextrec = excelFile.peek(); while (nextrec.Type == NExcel.Biff.Type.CONTINUE) { continueRecords.Add(excelFile.next()); nextrec = excelFile.peek(); } // cast the array System.Object[] rec = continueRecords.ToArray(); Record[] records = new Record[rec.Length]; Array.Copy(rec, 0, records, 0, rec.Length); sharedStrings = new SSTRecord(r, records, settings); } else if (r.Type == NExcel.Biff.Type.FILEPASS) { throw new PasswordException(); } else if (r.Type == NExcel.Biff.Type.NAME) { NameRecord nr = null; if (bof.isBiff8()) { nr = new NameRecord(r, settings, namedRecords.Count); } else { nr = new NameRecord(r, settings, namedRecords.Count, NameRecord.biff7); } namedRecords[nr.Name] = nr; nameTable.Add(nr); } else if (r.Type == NExcel.Biff.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.Type == NExcel.Biff.Type.PALETTE) { NExcel.Biff.PaletteRecord palette = new NExcel.Biff.PaletteRecord(r); formattingRecords.Palette = palette; } else if (r.Type == NExcel.Biff.Type.NINETEENFOUR) { NineteenFourRecord nr = new NineteenFourRecord(r); nineteenFour = nr.is1904(); } else if (r.Type == NExcel.Biff.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.getMessage()); Assert.verify(false, "This should not happen. 64"); } } else if (r.Type == NExcel.Biff.Type.XF) { XFRecord xfr = null; if (bof.isBiff8()) { xfr = new XFRecord(r, XFRecord.biff8); } else { xfr = new XFRecord(r, XFRecord.biff7); } try { formattingRecords.addStyle(xfr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out // Assert.verify(false, e.getMessage()); Assert.verify(false, "This should not happen. 59"); } } else if (r.Type == NExcel.Biff.Type.BOUNDSHEET) { BoundsheetRecord br = null; if (bof.isBiff8()) { br = new BoundsheetRecord(r); } else { br = new BoundsheetRecord(r, BoundsheetRecord.biff7); } if (br.isSheet() || br.Chart) { boundsheets.Add(br); } } else if (r.Type == NExcel.Biff.Type.EXTERNSHEET) { if (bof.isBiff8()) { externSheet = new ExternalSheetRecord(r, settings); } else { externSheet = new ExternalSheetRecord(r, settings, ExternalSheetRecord.biff7); } } else if (r.Type == NExcel.Biff.Type.CODEPAGE) { CodepageRecord cr = new CodepageRecord(r); settings.CharacterSet = cr.CharacterSet; } else if (r.Type == NExcel.Biff.Type.SUPBOOK) { SupbookRecord sr = new SupbookRecord(r, settings); supbooks.Add(sr); } else if (r.Type == NExcel.Biff.Type.PROTECT) { ProtectRecord pr = new ProtectRecord(r); wbProtected = pr.IsProtected(); } else if (r.Type == NExcel.Biff.Type.MSODRAWINGGROUP) { msoDrawingGroup = new MsoDrawingGroupRecord(r); if (drawingGroup == null) { drawingGroup = new DrawingGroup(DrawingGroup.READ); } drawingGroup.add(msoDrawingGroup); Record nextrec = excelFile.peek(); while (nextrec.Type == NExcel.Biff.Type.CONTINUE) { drawingGroup.add(excelFile.next()); nextrec = excelFile.peek(); } } else if (r.Type == NExcel.Biff.Type.EOF) { bofs--; } } bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.Type == NExcel.Biff.Type.BOF) { bof = new BOFRecord(r); } } // Only get sheets for which there is a corresponding Boundsheet record while (bof != null && NumberOfSheets < 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[NumberOfSheets]; s.setName(br.Name); s.Hidden = 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[NumberOfSheets]; s.setName(br.Name); s.Hidden = br.isHidden(); addSheet(s); } else { logger.warn("BOF is unrecognized"); while (excelFile.hasNext() && r.Type != NExcel.Biff.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.Type == NExcel.Biff.Type.BOF) { bof = new BOFRecord(r); } } } }
/** * Writes out this sheet. First writes out the standard sheet * information then writes out each row in turn. * Once all the rows have been written out, it retrospectively adjusts * the offset references in the file * * @exception IOException */ public void write() { Assert.verify(rows != null); // This worksheet consists of just one chart, so write it and return if (chartOnly) { drawingWriter.write(outputFile); return; } BOFRecord bof = new BOFRecord(BOFRecord.sheet); outputFile.write(bof); // Compute the number of blocks of 32 rows that will be needed int numBlocks = numRows / 32; if (numRows - numBlocks * 32 != 0) { numBlocks++; } int indexPos = outputFile.getPos(); // Write the index record out now in order to serve as a place holder // The bof passed in is the bof of the workbook, not this sheet IndexRecord indexRecord = new IndexRecord(0, numRows, numBlocks); outputFile.write(indexRecord); if (settings.getAutomaticFormulaCalculation()) { CalcModeRecord cmr = new CalcModeRecord(CalcModeRecord.automatic); outputFile.write(cmr); } else { CalcModeRecord cmr = new CalcModeRecord(CalcModeRecord.manual); outputFile.write(cmr); } CalcCountRecord ccr = new CalcCountRecord(0x64); outputFile.write(ccr); RefModeRecord rmr = new RefModeRecord(); outputFile.write(rmr); IterationRecord itr = new IterationRecord(false); outputFile.write(itr); DeltaRecord dtr = new DeltaRecord(0.001); outputFile.write(dtr); SaveRecalcRecord srr = new SaveRecalcRecord(settings.getRecalculateFormulasBeforeSave()); outputFile.write(srr); PrintHeadersRecord phr = new PrintHeadersRecord(settings.getPrintHeaders()); outputFile.write(phr); PrintGridLinesRecord pglr = new PrintGridLinesRecord(settings.getPrintGridLines()); outputFile.write(pglr); GridSetRecord gsr = new GridSetRecord(true); outputFile.write(gsr); GuttersRecord gutr = new GuttersRecord(); gutr.setMaxColumnOutline(maxColumnOutlineLevel + 1); gutr.setMaxRowOutline(maxRowOutlineLevel + 1); outputFile.write(gutr); DefaultRowHeightRecord drhr = new DefaultRowHeightRecord (settings.getDefaultRowHeight(), settings.getDefaultRowHeight() != SheetSettings.DEFAULT_DEFAULT_ROW_HEIGHT); outputFile.write(drhr); if (maxRowOutlineLevel > 0) { workspaceOptions.setRowOutlines(true); } if (maxColumnOutlineLevel > 0) { workspaceOptions.setColumnOutlines(true); } workspaceOptions.setFitToPages(settings.getFitToPages()); outputFile.write(workspaceOptions); if (rowBreaks.Count > 0) { int[] rb = new int[rowBreaks.Count]; for (int i = 0; i < rb.Length; i++) { rb[i] = (int)rowBreaks[i]; } HorizontalPageBreaksRecord hpbr = new HorizontalPageBreaksRecord(rb); outputFile.write(hpbr); } if (columnBreaks.Count > 0) { int[] rb = new int[columnBreaks.Count]; for (int i = 0; i < rb.Length; i++) { rb[i] = (int)columnBreaks[i]; } VerticalPageBreaksRecord hpbr = new VerticalPageBreaksRecord(rb); outputFile.write(hpbr); } HeaderRecord header = new HeaderRecord(settings.getHeader().ToString()); outputFile.write(header); FooterRecord footer = new FooterRecord(settings.getFooter().ToString()); outputFile.write(footer); HorizontalCentreRecord hcr = new HorizontalCentreRecord(settings.isHorizontalCentre()); outputFile.write(hcr); VerticalCentreRecord vcr = new VerticalCentreRecord(settings.isVerticalCentre()); outputFile.write(vcr); // Write out the margins if they don't equal the default if (settings.getLeftMargin() != settings.getDefaultWidthMargin()) { MarginRecord mr = new LeftMarginRecord(settings.getLeftMargin()); outputFile.write(mr); } if (settings.getRightMargin() != settings.getDefaultWidthMargin()) { MarginRecord mr = new RightMarginRecord(settings.getRightMargin()); outputFile.write(mr); } if (settings.getTopMargin() != settings.getDefaultHeightMargin()) { MarginRecord mr = new TopMarginRecord(settings.getTopMargin()); outputFile.write(mr); } if (settings.getBottomMargin() != settings.getDefaultHeightMargin()) { MarginRecord mr = new BottomMarginRecord(settings.getBottomMargin()); outputFile.write(mr); } if (plsRecord != null) { outputFile.write(plsRecord); } SetupRecord setup = new SetupRecord(settings); outputFile.write(setup); if (settings.isProtected()) { ProtectRecord pr = new ProtectRecord(settings.isProtected()); outputFile.write(pr); ScenarioProtectRecord spr = new ScenarioProtectRecord(settings.isProtected()); outputFile.write(spr); ObjectProtectRecord opr = new ObjectProtectRecord(settings.isProtected()); outputFile.write(opr); if (settings.getPassword() != null) { PasswordRecord pw = new PasswordRecord(settings.getPassword()); outputFile.write(pw); } else if (settings.getPasswordHash() != 0) { PasswordRecord pw = new PasswordRecord(settings.getPasswordHash()); outputFile.write(pw); } } indexRecord.setDataStartPosition(outputFile.getPos()); DefaultColumnWidth dcw = new DefaultColumnWidth(settings.getDefaultColumnWidth()); outputFile.write(dcw); // Get a handle to the normal styles WritableCellFormat normalStyle = sheet.getWorkbook().getStyles().getNormalStyle(); WritableCellFormat defaultDateFormat = sheet.getWorkbook().getStyles().getDefaultDateFormat(); // Write out all the column formats foreach (ColumnInfoRecord cir in columnFormats) { // Writing out the column info with index 0x100 causes excel to crash if (cir.getColumn() < 0x100) { outputFile.write(cir); } XFRecord xfr = cir.getCellFormat(); if (xfr != normalStyle && cir.getColumn() < 0x100) { // Make this the format for every cell in the column Cell[] cells = getColumn(cir.getColumn()); for (int i = 0; i < cells.Length; i++) { if (cells[i] != null && (cells[i].getCellFormat() == normalStyle || cells[i].getCellFormat() == defaultDateFormat)) { // The cell has no overriding format specified, so // set it to the column default ((WritableCell)cells[i]).setCellFormat(xfr); } } } } // Write out the auto filter if (autoFilter != null) { autoFilter.write(outputFile); } DimensionRecord dr = new DimensionRecord(numRows, numCols); outputFile.write(dr); // Write out all the rows, in blocks of 32 for (int block = 0; block < numBlocks; block++) { DBCellRecord dbcell = new DBCellRecord(outputFile.getPos()); int blockRows = System.Math.Min(32, numRows - block * 32); bool firstRow = true; // First write out all the row records for (int i = block * 32; i < block * 32 + blockRows; i++) { if (rows[i] != null) { rows[i].write(outputFile); if (firstRow) { dbcell.setCellOffset(outputFile.getPos()); firstRow = false; } } } // Now write out all the cells for (int i = block * 32; i < block * 32 + blockRows; i++) { if (rows[i] != null) { dbcell.addCellRowPosition(outputFile.getPos()); rows[i].writeCells(outputFile); } } // Now set the current file position in the index record indexRecord.addBlockPosition(outputFile.getPos()); // Set the position of the file pointer and write out the DBCell // record dbcell.setPosition(outputFile.getPos()); outputFile.write(dbcell); } // Do the drawings and charts if enabled if (!workbookSettings.getDrawingsDisabled()) { drawingWriter.write(outputFile); } Window2Record w2r = new Window2Record(settings); outputFile.write(w2r); // Handle the frozen panes if (settings.getHorizontalFreeze() != 0 || settings.getVerticalFreeze() != 0) { PaneRecord pr = new PaneRecord(settings.getHorizontalFreeze(), settings.getVerticalFreeze()); outputFile.write(pr); // Handle the selection record. First, there will always be a top left SelectionRecord sr = new SelectionRecord(SelectionRecord.upperLeft, 0, 0); outputFile.write(sr); // Top right if (settings.getHorizontalFreeze() != 0) { sr = new SelectionRecord(SelectionRecord.upperRight, settings.getHorizontalFreeze(), 0); outputFile.write(sr); } // Bottom left if (settings.getVerticalFreeze() != 0) { sr = new SelectionRecord(SelectionRecord.lowerLeft, 0, settings.getVerticalFreeze()); outputFile.write(sr); } // Bottom right if (settings.getHorizontalFreeze() != 0 && settings.getVerticalFreeze() != 0) { sr = new SelectionRecord(SelectionRecord.lowerRight, settings.getHorizontalFreeze(), settings.getVerticalFreeze()); outputFile.write(sr); } Weird1Record w1r = new Weird1Record(); outputFile.write(w1r); } else { // No frozen panes - just write out the selection record for the // whole sheet SelectionRecord sr = new SelectionRecord(SelectionRecord.upperLeft, 0, 0); outputFile.write(sr); } // Handle the zoom factor if (settings.getZoomFactor() != 100) { SCLRecord sclr = new SCLRecord(settings.getZoomFactor()); outputFile.write(sclr); } // Now write out all the merged cells mergedCells.write(outputFile); // Write out all the hyperlinks foreach (WritableHyperlink hlr in hyperlinks) { outputFile.write(hlr); } if (buttonPropertySet != null) { outputFile.write(buttonPropertySet); } // Write out the data validations if (dataValidation != null || validatedCells.Count > 0) { writeDataValidation(); } // Write out the conditional formats if (conditionalFormats != null && conditionalFormats.Count > 0) { foreach (ConditionalFormat cf in conditionalFormats) { cf.write(outputFile); } } EOFRecord eof = new EOFRecord(); outputFile.write(eof); // Now the various cross reference offsets have been calculated, // retrospectively set the values in the output file outputFile.setData(indexRecord.getData(), indexPos + 4); }
/** * Check all the merged cells for borders. If the merge record has * borders, then we need to rejig the cell formats to take account of this. * This is called by the write method of the WritableWorkbookImpl, so that * any new XFRecords that are created may be written out with the others */ public void checkMergedBorders() { Range[] mcells = mergedCells.getMergedCells(); ArrayList borderFormats = new ArrayList(); for (int mci = 0; mci < mcells.Length; mci++) { Range range = mcells[mci]; Cell topLeft = range.getTopLeft(); XFRecord tlformat = (XFRecord)topLeft.getCellFormat(); if (tlformat != null && tlformat.hasBorders() == true && !tlformat.isRead()) { try { CellXFRecord cf1 = new CellXFRecord(tlformat); Cell bottomRight = range.getBottomRight(); cf1.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK); cf1.setBorder(Border.LEFT, tlformat.getBorderLine(Border.LEFT), tlformat.getBorderColour(Border.LEFT)); cf1.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP)); if (topLeft.getRow() == bottomRight.getRow()) { cf1.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM)); } if (topLeft.getColumn() == bottomRight.getColumn()) { cf1.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT)); } int index = borderFormats.IndexOf(cf1); if (index != -1) { cf1 = (CellXFRecord)borderFormats[index]; } else { borderFormats.Add(cf1); } ((WritableCell)topLeft).setCellFormat(cf1); // Handle the bottom left corner if (bottomRight.getRow() > topLeft.getRow()) { // Handle the corner cell if (bottomRight.getColumn() != topLeft.getColumn()) { CellXFRecord cf2 = new CellXFRecord(tlformat); cf2.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK); cf2.setBorder(Border.LEFT, tlformat.getBorderLine(Border.LEFT), tlformat.getBorderColour(Border.LEFT)); cf2.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM)); index = borderFormats.IndexOf(cf2); if (index != -1) { cf2 = (CellXFRecord)borderFormats[index]; } else { borderFormats.Add(cf2); } sheet.addCell(new Blank(topLeft.getColumn(), bottomRight.getRow(), cf2)); } // Handle the cells down the left hand side (and along the // right too, if necessary) for (int i = topLeft.getRow() + 1; i < bottomRight.getRow(); i++) { CellXFRecord cf3 = new CellXFRecord(tlformat); cf3.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK); cf3.setBorder(Border.LEFT, tlformat.getBorderLine(Border.LEFT), tlformat.getBorderColour(Border.LEFT)); if (topLeft.getColumn() == bottomRight.getColumn()) { cf3.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT)); } index = borderFormats.IndexOf(cf3); if (index != -1) { cf3 = (CellXFRecord)borderFormats[index]; } else { borderFormats.Add(cf3); } sheet.addCell(new Blank(topLeft.getColumn(), i, cf3)); } } // Handle the top right corner if (bottomRight.getColumn() > topLeft.getColumn()) { if (bottomRight.getRow() != topLeft.getRow()) { // Handle the corner cell CellXFRecord cf6 = new CellXFRecord(tlformat); cf6.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK); cf6.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT)); cf6.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP)); index = borderFormats.IndexOf(cf6); if (index != -1) { cf6 = (CellXFRecord)borderFormats[index]; } else { borderFormats.Add(cf6); } sheet.addCell(new Blank(bottomRight.getColumn(), topLeft.getRow(), cf6)); } // Handle the cells along the right for (int i = topLeft.getRow() + 1; i < bottomRight.getRow(); i++) { CellXFRecord cf7 = new CellXFRecord(tlformat); cf7.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK); cf7.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT)); index = borderFormats.IndexOf(cf7); if (index != -1) { cf7 = (CellXFRecord)borderFormats[index]; } else { borderFormats.Add(cf7); } sheet.addCell(new Blank(bottomRight.getColumn(), i, cf7)); } // Handle the cells along the top, and along the bottom too for (int i = topLeft.getColumn() + 1; i < bottomRight.getColumn(); i++) { CellXFRecord cf8 = new CellXFRecord(tlformat); cf8.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK); cf8.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP)); if (topLeft.getRow() == bottomRight.getRow()) { cf8.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM)); } index = borderFormats.IndexOf(cf8); if (index != -1) { cf8 = (CellXFRecord)borderFormats[index]; } else { borderFormats.Add(cf8); } sheet.addCell(new Blank(i, topLeft.getRow(), cf8)); } } // Handle the bottom right corner if (bottomRight.getColumn() > topLeft.getColumn() || bottomRight.getRow() > topLeft.getRow()) { // Handle the corner cell CellXFRecord cf4 = new CellXFRecord(tlformat); cf4.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK); cf4.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT)); cf4.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM)); if (bottomRight.getRow() == topLeft.getRow()) { cf4.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP)); } if (bottomRight.getColumn() == topLeft.getColumn()) { cf4.setBorder(Border.LEFT, tlformat.getBorderLine(Border.LEFT), tlformat.getBorderColour(Border.LEFT)); } index = borderFormats.IndexOf(cf4); if (index != -1) { cf4 = (CellXFRecord)borderFormats[index]; } else { borderFormats.Add(cf4); } sheet.addCell(new Blank(bottomRight.getColumn(), bottomRight.getRow(), cf4)); // Handle the cells along the bottom (and along the top // as well, if appropriate) for (int i = topLeft.getColumn() + 1; i < bottomRight.getColumn(); i++) { CellXFRecord cf5 = new CellXFRecord(tlformat); cf5.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK); cf5.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM)); if (topLeft.getRow() == bottomRight.getRow()) { cf5.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP)); } index = borderFormats.IndexOf(cf5); if (index != -1) { cf5 = (CellXFRecord)borderFormats[index]; } else { borderFormats.Add(cf5); } sheet.addCell(new Blank(i, bottomRight.getRow(), cf5)); } } } catch (WriteException e) { // just log e.ToString(), not the whole stack trace //logger.warn(e.ToString()); } } } }
/** * Copy constructor. Invoked when copying formats to handle cell merging * * @param fmt the format to copy */ public CellXFRecord(XFRecord fmt) : base(fmt) { setXFDetails(XFRecord.cell, 0); }
/** * Sets the cell format. Used when importing spreadsheets * * @param xfr the xf record */ public void setCellFormat(XFRecord xfr) { style = xfr; }
/** * Rationalizes the cell formats. Duplicate * formats are removed and the format indexed of the cells * adjusted accordingly * * @param fontMapping the font mapping index numbers * @param formatMapping the format mapping index numbers * @return the list of new font index number */ public IndexMapping rationalize(IndexMapping fontMapping, IndexMapping formatMapping) { // Update the index codes for the XF records using the format // mapping and the font mapping // at the same time // XFRecord xfr = null; foreach (XFRecord xfr in xfRecords) { if (xfr.getFormatRecord() >= customFormatStartIndex) { xfr.setFormatIndex(formatMapping.getNewIndex(xfr.getFormatRecord())); } xfr.setFontIndex(fontMapping.getNewIndex(xfr.getFontIndex())); } ArrayList newrecords = new ArrayList(minXFRecords); IndexMapping mapping = new IndexMapping(xfRecords.Count); int numremoved = 0; int numXFRecords = System.Math.Min(minXFRecords, xfRecords.Count); // Copy across the fundamental styles for (int i = 0; i < numXFRecords; i++) { newrecords.Add(xfRecords[i]); mapping.setMapping(i, i); } if (numXFRecords < minXFRecords) { //logger.warn("There are less than the expected minimum number of XF records"); return(mapping); } // Iterate through the old list for (int i = minXFRecords; i < xfRecords.Count; i++) { XFRecord xf = (XFRecord)xfRecords[i]; // Compare against formats already on the list bool duplicate = false; foreach (XFRecord xf2 in newrecords) { if (xf2.Equals(xf)) { duplicate = true; mapping.setMapping(i, mapping.getNewIndex(xf2.getXFIndex())); numremoved++; break; } } // If this format is not a duplicate then add it to the new list if (!duplicate) { newrecords.Add(xf); mapping.setMapping(i, i - numremoved); } } // It is sufficient to merely change the xf index field on all XFRecords // In this case, CellValues which refer to defunct format records // will nevertheless be written out with the correct index number foreach (XFRecord xf in xfRecords) { xf.rationalize(mapping); } // Set the new list xfRecords = newrecords; return(mapping); }
/** * Imports a sheet from a different workbook, doing a deep copy */ public void importSheet() { xfRecords = new Dictionary <int, WritableCellFormat>(); fonts = new Dictionary <int, int>(); formats = new Dictionary <int, int>(); deepCopyCells(); // Copy the column info records CSharpJExcel.Jxl.Read.Biff.ColumnInfoRecord[] readCirs = fromSheet.getColumnInfos(); for (int i = 0; i < readCirs.Length; i++) { CSharpJExcel.Jxl.Read.Biff.ColumnInfoRecord rcir = readCirs[i]; for (int j = rcir.getStartColumn(); j <= rcir.getEndColumn(); j++) { ColumnInfoRecord cir = new ColumnInfoRecord(rcir, j); int xfIndex = cir.getXfIndex(); XFRecord cf = null; if (!xfRecords.ContainsKey(xfIndex)) { // TODO: CML -- what does THIS actually achieve unless it has side-effects? CellFormat readFormat = fromSheet.getColumnView(j).getFormat(); WritableCellFormat wcf = copyCellFormat(readFormat); } else { cf = xfRecords[xfIndex]; } cir.setCellFormat(cf); cir.setHidden(rcir.getHidden()); columnFormats.Add(cir); } } // Copy the hyperlinks Hyperlink[] hls = fromSheet.getHyperlinks(); for (int i = 0; i < hls.Length; i++) { WritableHyperlink hr = new WritableHyperlink(hls[i], toSheet); hyperlinks.Add(hr); } // Copy the merged cells Range[] merged = fromSheet.getMergedCells(); for (int i = 0; i < merged.Length; i++) { mergedCells.add(new SheetRangeImpl((SheetRangeImpl)merged[i], toSheet)); } // Copy the row properties try { CSharpJExcel.Jxl.Read.Biff.RowRecord[] rowprops = fromSheet.getRowProperties(); for (int i = 0; i < rowprops.Length; i++) { RowRecord rr = toSheet.getRowRecord(rowprops[i].getRowNumber()); XFRecord format = null; CSharpJExcel.Jxl.Read.Biff.RowRecord rowrec = rowprops[i]; if (rowrec.hasDefaultFormat()) { if (!xfRecords.ContainsKey(rowrec.getXFIndex())) { int rownum = rowrec.getRowNumber(); CellFormat readFormat = fromSheet.getRowView(rownum).getFormat(); WritableCellFormat wcf = copyCellFormat(readFormat); } else { format = xfRecords[rowrec.getXFIndex()]; } } rr.setRowDetails(rowrec.getRowHeight(), rowrec.matchesDefaultFontHeight(), rowrec.isCollapsed(), rowrec.getOutlineLevel(), rowrec.getGroupStart(), format); numRows = System.Math.Max(numRows, rowprops[i].getRowNumber() + 1); } } catch (RowsExceededException e) { // Handle the rows exceeded exception - this cannot occur since // the sheet we are copying from will have a valid number of rows Assert.verify(false); } // Copy the headers and footers // sheetWriter.setHeader(new HeaderRecord(si.getHeader())); // sheetWriter.setFooter(new FooterRecord(si.getFooter())); // Copy the page breaks int[] rowbreaks = fromSheet.getRowPageBreaks(); if (rowbreaks != null) { for (int i = 0; i < rowbreaks.Length; i++) { rowBreaks.Add(rowbreaks[i]); } } int[] columnbreaks = fromSheet.getColumnPageBreaks(); if (columnbreaks != null) { for (int i = 0; i < columnbreaks.Length; i++) { columnBreaks.Add(columnbreaks[i]); } } // Copy the charts Chart[] fromCharts = fromSheet.getCharts(); if (fromCharts != null && fromCharts.Length > 0) { //logger.warn("Importing of charts is not supported"); /* * sheetWriter.setCharts(fromSheet.getCharts()); * IndexMapping xfMapping = new IndexMapping(200); * for (Iterator i = xfRecords.keySet().iterator(); i.hasNext();) * { * Integer key = (Integer) i.next(); * XFRecord xfmapping = (XFRecord) xfRecords[key); * xfMapping.setMapping(key, xfmapping.getXFIndex()); * } * * IndexMapping fontMapping = new IndexMapping(200); * for (Iterator i = fonts.keySet().iterator(); i.hasNext();) * { * Integer key = (Integer) i.next(); * Integer fontmap = (Integer) fonts[key); * fontMapping.setMapping(key, fontmap); * } * * IndexMapping formatMapping = new IndexMapping(200); * for (Iterator i = formats.keySet().iterator(); i.hasNext();) * { * Integer key = (Integer) i.next(); * Integer formatmap = (Integer) formats[key); * formatMapping.setMapping(key, formatmap); * } * * // Now reuse the rationalization feature on each chart to * // handle the new fonts * for (int i = 0; i < fromCharts.Length ; i++) * { * fromCharts[i].rationalize(xfMapping, fontMapping, formatMapping); * } */ } // Copy the drawings DrawingGroupObject[] dr = fromSheet.getDrawings(); // Make sure the destination workbook has a drawing group // created in it if (dr.Length > 0 && toSheet.getWorkbook().getDrawingGroup() == null) { toSheet.getWorkbook().createDrawingGroup(); } for (int i = 0; i < dr.Length; i++) { if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.Drawing) { WritableImage wi = new WritableImage (dr[i].getX(), dr[i].getY(), dr[i].getWidth(), dr[i].getHeight(), dr[i].getImageData()); toSheet.getWorkbook().addDrawing(wi); drawings.Add(wi); images.Add(wi); } else if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.Comment) { CSharpJExcel.Jxl.Biff.Drawing.Comment c = new CSharpJExcel.Jxl.Biff.Drawing.Comment(dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.Add(c); // Set up the reference on the cell value CellValue cv = (CellValue)toSheet.getWritableCell(c.getColumn(), c.getRow()); Assert.verify(cv.getCellFeatures() != null); cv.getWritableCellFeatures().setCommentDrawing(c); } else if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.Button) { CSharpJExcel.Jxl.Biff.Drawing.Button b = new CSharpJExcel.Jxl.Biff.Drawing.Button(dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.Add(b); } else if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.ComboBox) { CSharpJExcel.Jxl.Biff.Drawing.ComboBox cb = new CSharpJExcel.Jxl.Biff.Drawing.ComboBox(dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.Add(cb); } } // Copy the data validations DataValidation rdv = fromSheet.getDataValidation(); if (rdv != null) { dataValidation = new DataValidation(rdv, toSheet.getWorkbook(), toSheet.getWorkbook(), workbookSettings); uint objid = dataValidation.getComboBoxObjectId(); if (objid != 0) { comboBox = (ComboBox)drawings[(int)objid]; } } // Copy the workspace options sheetWriter.setWorkspaceOptions(fromSheet.getWorkspaceOptions()); // Set a flag to indicate if it contains a chart only if (fromSheet.getSheetBof().isChart()) { chartOnly = true; sheetWriter.setChartOnly(); } // Copy the environment specific print record if (fromSheet.getPLS() != null) { if (fromSheet.getWorkbookBof().isBiff7()) { //logger.warn("Cannot copy Biff7 print settings record - ignoring"); } else { plsRecord = new PLSRecord(fromSheet.getPLS()); } } // Copy the button property set if (fromSheet.getButtonPropertySet() != null) { buttonPropertySet = new ButtonPropertySetRecord (fromSheet.getButtonPropertySet()); } importNames(); // Copy the outline levels maxRowOutlineLevel = fromSheet.getMaxRowOutlineLevel(); maxColumnOutlineLevel = fromSheet.getMaxColumnOutlineLevel(); }
/** * 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); } } }
/** * Copies a sheet from a read-only version to the writable version. * Performs shallow copies */ public void copySheet() { shallowCopyCells(); // Copy the column info records CSharpJExcel.Jxl.Read.Biff.ColumnInfoRecord[] readCirs = fromSheet.getColumnInfos(); for (int i = 0; i < readCirs.Length; i++) { CSharpJExcel.Jxl.Read.Biff.ColumnInfoRecord rcir = readCirs[i]; for (int j = rcir.getStartColumn(); j <= rcir.getEndColumn(); j++) { ColumnInfoRecord cir = new ColumnInfoRecord(rcir, j, formatRecords); cir.setHidden(rcir.getHidden()); columnFormats.Add(cir); } } // Copy the hyperlinks Hyperlink[] hls = fromSheet.getHyperlinks(); for (int i = 0; i < hls.Length; i++) { WritableHyperlink hr = new WritableHyperlink (hls[i], toSheet); hyperlinks.Add(hr); } // Copy the merged cells Range[] merged = fromSheet.getMergedCells(); for (int i = 0; i < merged.Length; i++) { mergedCells.add(new SheetRangeImpl((SheetRangeImpl)merged[i], toSheet)); } // Copy the row properties try { CSharpJExcel.Jxl.Read.Biff.RowRecord[] rowprops = fromSheet.getRowProperties(); for (int i = 0; i < rowprops.Length; i++) { RowRecord rr = toSheet.getRowRecord(rowprops[i].getRowNumber()); XFRecord format = rowprops[i].hasDefaultFormat() ? formatRecords.getXFRecord(rowprops[i].getXFIndex()) : null; rr.setRowDetails(rowprops[i].getRowHeight(), rowprops[i].matchesDefaultFontHeight(), rowprops[i].isCollapsed(), rowprops[i].getOutlineLevel(), rowprops[i].getGroupStart(), format); numRows = System.Math.Max(numRows, rowprops[i].getRowNumber() + 1); } } catch (RowsExceededException e) { // Handle the rows exceeded exception - this cannot occur since // the sheet we are copying from will have a valid number of rows Assert.verify(false); } // Copy the headers and footers // sheetWriter.setHeader(new HeaderRecord(si.getHeader())); // sheetWriter.setFooter(new FooterRecord(si.getFooter())); // Copy the page breaks int[] rowbreaks = fromSheet.getRowPageBreaks(); if (rowbreaks != null) { for (int i = 0; i < rowbreaks.Length; i++) { rowBreaks.Add(rowbreaks[i]); } } int[] columnbreaks = fromSheet.getColumnPageBreaks(); if (columnbreaks != null) { for (int i = 0; i < columnbreaks.Length; i++) { columnBreaks.Add(columnbreaks[i]); } } // Copy the charts sheetWriter.setCharts(fromSheet.getCharts()); // Copy the drawings DrawingGroupObject[] dr = fromSheet.getDrawings(); for (int i = 0; i < dr.Length; i++) { if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.Drawing) { WritableImage wi = new WritableImage (dr[i], toSheet.getWorkbook().getDrawingGroup()); drawings.Add(wi); images.Add(wi); } else if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.Comment) { CSharpJExcel.Jxl.Biff.Drawing.Comment c = new CSharpJExcel.Jxl.Biff.Drawing.Comment(dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.Add(c); // Set up the reference on the cell value CellValue cv = (CellValue)toSheet.getWritableCell(c.getColumn(), c.getRow()); Assert.verify(cv.getCellFeatures() != null); cv.getWritableCellFeatures().setCommentDrawing(c); } else if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.Button) { CSharpJExcel.Jxl.Biff.Drawing.Button b = new CSharpJExcel.Jxl.Biff.Drawing.Button (dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.Add(b); } else if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.ComboBox) { CSharpJExcel.Jxl.Biff.Drawing.ComboBox cb = new CSharpJExcel.Jxl.Biff.Drawing.ComboBox (dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.Add(cb); } else if (dr[i] is CSharpJExcel.Jxl.Biff.Drawing.CheckBox) { CSharpJExcel.Jxl.Biff.Drawing.CheckBox cb = new CSharpJExcel.Jxl.Biff.Drawing.CheckBox (dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.Add(cb); } } // Copy the data validations DataValidation rdv = fromSheet.getDataValidation(); if (rdv != null) { dataValidation = new DataValidation(rdv, toSheet.getWorkbook(), toSheet.getWorkbook(), workbookSettings); uint objid = dataValidation.getComboBoxObjectId(); if (objid != 0) { comboBox = (ComboBox)drawings[(int)objid]; } } // Copy the conditional formats ConditionalFormat[] cf = fromSheet.getConditionalFormats(); if (cf.Length > 0) { for (int i = 0; i < cf.Length; i++) { conditionalFormats.Add(cf[i]); } } // Get the autofilter autoFilter = fromSheet.getAutoFilter(); // Copy the workspace options sheetWriter.setWorkspaceOptions(fromSheet.getWorkspaceOptions()); // Set a flag to indicate if it contains a chart only if (fromSheet.getSheetBof().isChart()) { chartOnly = true; sheetWriter.setChartOnly(); } // Copy the environment specific print record if (fromSheet.getPLS() != null) { if (fromSheet.getWorkbookBof().isBiff7()) { //logger.warn("Cannot copy Biff7 print settings record - ignoring"); } else { plsRecord = new PLSRecord(fromSheet.getPLS()); } } // Copy the button property set if (fromSheet.getButtonPropertySet() != null) { buttonPropertySet = new ButtonPropertySetRecord (fromSheet.getButtonPropertySet()); } // Copy the outline levels maxRowOutlineLevel = fromSheet.getMaxRowOutlineLevel(); maxColumnOutlineLevel = fromSheet.getMaxColumnOutlineLevel(); }