/********************************************************************* * * Copyright (C) 2006 Andrew Khan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***************************************************************************/ package jxl.write.biff; import java.util.Arrays; import java.util.ArrayList; import java.util.HashMap; import java.util.TreeSet; import java.util.Iterator; import common.Assert; import common.Logger; import jxl.BooleanCell; import jxl.Cell; import jxl.CellType; import jxl.CellView; import jxl.DateCell; import jxl.HeaderFooter; import jxl.Hyperlink; import jxl.Image; import jxl.LabelCell; import jxl.NumberCell; import jxl.Range; import jxl.Sheet; import jxl.SheetSettings; import jxl.WorkbookSettings; import jxl.biff.AutoFilter; import jxl.biff.CellReferenceHelper; import jxl.biff.ConditionalFormat; import jxl.biff.DataValidation; import jxl.biff.FormattingRecords; import jxl.biff.FormulaData; import jxl.biff.IndexMapping; import jxl.biff.NumFormatRecordsException; import jxl.biff.SheetRangeImpl; import jxl.biff.XFRecord; import jxl.biff.drawing.Chart; import jxl.biff.drawing.ComboBox; import jxl.biff.drawing.Drawing; import jxl.biff.drawing.DrawingGroupObject; import jxl.format.CellFormat; import jxl.biff.formula.FormulaException; import jxl.read.biff.SheetImpl; import jxl.read.biff.NameRecord; import jxl.read.biff.WorkbookParser; import jxl.write.Blank; import jxl.write.Boolean; import jxl.write.DateTime; import jxl.write.Formula; import jxl.write.Label; import jxl.write.Number; import jxl.write.WritableCell; import jxl.write.WritableCellFormat; import jxl.write.WritableFont; import jxl.write.WritableHyperlink; import jxl.write.WritableImage; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; import jxl.write.WriteException; /** * A transient utility object used to copy sheets. This * functionality has been farmed out to a different class * in order to reduce the bloat of the WritableSheetImpl */ class SheetCopier { private static Logger logger = Logger.getLogger(SheetCopier.class); private SheetImpl fromSheet; private WritableSheetImpl toSheet; private WorkbookSettings workbookSettings; // Objects used by the sheet private TreeSet columnFormats; private FormattingRecords formatRecords; private ArrayList hyperlinks; private MergedCells mergedCells; private ArrayList rowBreaks; private ArrayList columnBreaks; private SheetWriter sheetWriter; private ArrayList drawings; private ArrayList images; private ArrayList conditionalFormats; private AutoFilter autoFilter; private DataValidation dataValidation; private ComboBox comboBox; private PLSRecord plsRecord; private boolean chartOnly; private ButtonPropertySetRecord buttonPropertySet; private int numRows; private int maxRowOutlineLevel; private int maxColumnOutlineLevel; // Objects used to maintain state during the copy process private HashMap xfRecords; private HashMap fonts; private HashMap formats; public SheetCopier(Sheet f, WritableSheet t) { fromSheet = (SheetImpl) f; toSheet = (WritableSheetImpl) t; workbookSettings = toSheet.getWorkbook().getSettings(); chartOnly = false; } void setColumnFormats(TreeSet cf) { columnFormats = cf; } void setFormatRecords(FormattingRecords fr) { formatRecords = fr; } void setHyperlinks(ArrayList h) { hyperlinks = h; } void setMergedCells(MergedCells mc) { mergedCells = mc; } void setRowBreaks(ArrayList rb) { rowBreaks = rb; } void setColumnBreaks(ArrayList cb) { columnBreaks = cb; } void setSheetWriter(SheetWriter sw) { sheetWriter = sw; } void setDrawings(ArrayList d) { drawings = d; } void setImages(ArrayList i) { images = i; } void setConditionalFormats(ArrayList cf) { conditionalFormats = cf; } AutoFilter getAutoFilter() { return autoFilter; } DataValidation getDataValidation() { return dataValidation; } ComboBox getComboBox() { return comboBox; } PLSRecord getPLSRecord() { return plsRecord; } boolean isChartOnly() { return chartOnly; } ButtonPropertySetRecord getButtonPropertySet() { return buttonPropertySet; } /** * Copies a sheet from a read-only version to the writable version. * Performs shallow copies */ public void copySheet() { shallowCopyCells(); // Copy the column info records jxl.read.biff.ColumnInfoRecord[] readCirs = fromSheet.getColumnInfos(); for (int i = 0 ; i < readCirs.length; i++) { 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 { 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 = 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(new Integer(rowbreaks[i])); } } int[] columnbreaks = fromSheet.getColumnPageBreaks(); if (columnbreaks != null) { for (int i = 0; i < columnbreaks.length; i++) { columnBreaks.add(new Integer(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] instanceof jxl.biff.drawing.Drawing) { WritableImage wi = new WritableImage (dr[i], toSheet.getWorkbook().getDrawingGroup()); drawings.add(wi); images.add(wi); } else if (dr[i] instanceof jxl.biff.drawing.Comment) { jxl.biff.drawing.Comment c = new 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] instanceof jxl.biff.drawing.Button) { jxl.biff.drawing.Button b = new jxl.biff.drawing.Button (dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.add(b); } else if (dr[i] instanceof jxl.biff.drawing.ComboBox) { jxl.biff.drawing.ComboBox cb = new 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); int objid = dataValidation.getComboBoxObjectId(); if (objid != 0) { comboBox = (ComboBox) drawings.get(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(); } /** * Copies a sheet from a read-only version to the writable version. * Performs shallow copies */ public void copyWritableSheet() { shallowCopyCells(); /* // Copy the column formats Iterator cfit = fromWritableSheet.columnFormats.iterator(); while (cfit.hasNext()) { ColumnInfoRecord cv = new ColumnInfoRecord ((ColumnInfoRecord) cfit.next()); columnFormats.add(cv); } // Copy the merged cells Range[] merged = fromWritableSheet.getMergedCells(); for (int i = 0; i < merged.length; i++) { mergedCells.add(new SheetRangeImpl((SheetRangeImpl)merged[i], this)); } // Copy the row properties try { RowRecord[] copyRows = fromWritableSheet.rows; RowRecord row = null; for (int i = 0; i < copyRows.length ; i++) { row = copyRows[i]; if (row != null && (!row.isDefaultHeight() || row.isCollapsed())) { RowRecord rr = getRowRecord(i); rr.setRowDetails(row.getRowHeight(), row.matchesDefaultFontHeight(), row.isCollapsed(), row.getStyle()); } } } 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 horizontal page breaks rowBreaks = new ArrayList(fromWritableSheet.rowBreaks); // Copy the vertical page breaks columnBreaks = new ArrayList(fromWritableSheet.columnBreaks); // Copy the data validations DataValidation rdv = fromWritableSheet.dataValidation; if (rdv != null) { dataValidation = new DataValidation(rdv, workbook, workbook, workbookSettings); } // Copy the charts sheetWriter.setCharts(fromWritableSheet.getCharts()); // Copy the drawings DrawingGroupObject[] dr = si.getDrawings(); for (int i = 0 ; i < dr.length ; i++) { if (dr[i] instanceof jxl.biff.drawing.Drawing) { WritableImage wi = new WritableImage(dr[i], workbook.getDrawingGroup()); drawings.add(wi); images.add(wi); } // Not necessary to copy the comments, as they will be handled by // the deep copy of the individual cells } // Copy the workspace options sheetWriter.setWorkspaceOptions(fromWritableSheet.getWorkspaceOptions()); // Copy the environment specific print record if (fromWritableSheet.plsRecord != null) { plsRecord = new PLSRecord(fromWritableSheet.plsRecord); } // Copy the button property set if (fromWritableSheet.buttonPropertySet != null) { buttonPropertySet = new ButtonPropertySetRecord (fromWritableSheet.buttonPropertySet); } */ } /** * Imports a sheet from a different workbook, doing a deep copy */ public void importSheet() { xfRecords = new HashMap(); fonts = new HashMap(); formats = new HashMap(); deepCopyCells(); // Copy the column info records jxl.read.biff.ColumnInfoRecord[] readCirs = fromSheet.getColumnInfos(); for (int i = 0 ; i < readCirs.length; i++) { 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 = (WritableCellFormat) xfRecords.get(new Integer(xfIndex)); if (cf == null) { CellFormat readFormat = fromSheet.getColumnView(j).getFormat(); WritableCellFormat wcf = copyCellFormat(readFormat); } 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 { 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; jxl.read.biff.RowRecord rowrec = rowprops[i]; if (rowrec.hasDefaultFormat()) { format = (WritableCellFormat) xfRecords.get(new Integer(rowrec.getXFIndex())); if (format == null) { int rownum = rowrec.getRowNumber(); CellFormat readFormat = fromSheet.getRowView(rownum).getFormat(); WritableCellFormat wcf = copyCellFormat(readFormat); } } rr.setRowDetails(rowrec.getRowHeight(), rowrec.matchesDefaultFontHeight(), rowrec.isCollapsed(), rowrec.getOutlineLevel(), rowrec.getGroupStart(), format); numRows = 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(new Integer(rowbreaks[i])); } } int[] columnbreaks = fromSheet.getColumnPageBreaks(); if (columnbreaks != null) { for (int i = 0; i < columnbreaks.length; i++) { columnBreaks.add(new Integer(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.get(key); xfMapping.setMapping(key.intValue(), xfmapping.getXFIndex()); } IndexMapping fontMapping = new IndexMapping(200); for (Iterator i = fonts.keySet().iterator(); i.hasNext();) { Integer key = (Integer) i.next(); Integer fontmap = (Integer) fonts.get(key); fontMapping.setMapping(key.intValue(), fontmap.intValue()); } IndexMapping formatMapping = new IndexMapping(200); for (Iterator i = formats.keySet().iterator(); i.hasNext();) { Integer key = (Integer) i.next(); Integer formatmap = (Integer) formats.get(key); formatMapping.setMapping(key.intValue(), formatmap.intValue()); } // 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] instanceof 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] instanceof jxl.biff.drawing.Comment) { jxl.biff.drawing.Comment c = new 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] instanceof jxl.biff.drawing.Button) { jxl.biff.drawing.Button b = new jxl.biff.drawing.Button (dr[i], toSheet.getWorkbook().getDrawingGroup(), workbookSettings); drawings.add(b); } else if (dr[i] instanceof jxl.biff.drawing.ComboBox) { jxl.biff.drawing.ComboBox cb = new 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); int objid = dataValidation.getComboBoxObjectId(); if (objid != 0) { comboBox = (ComboBox) drawings.get(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(); } /** * Performs a shallow copy of the specified cell */ private WritableCell shallowCopyCell(Cell cell) { CellType ct = cell.getType(); WritableCell newCell = null; if (ct == CellType.LABEL) { newCell = new Label((LabelCell) cell); } else if (ct == CellType.NUMBER) { newCell = new Number((NumberCell) cell); } else if (ct == CellType.DATE) { newCell = new DateTime((DateCell) cell); } else if (ct == CellType.BOOLEAN) { newCell = new Boolean((BooleanCell) cell); } else if (ct == CellType.NUMBER_FORMULA) { newCell = new ReadNumberFormulaRecord((FormulaData) cell); } else if (ct == CellType.STRING_FORMULA) { newCell = new ReadStringFormulaRecord((FormulaData) cell); } else if( ct == CellType.BOOLEAN_FORMULA) { newCell = new ReadBooleanFormulaRecord((FormulaData) cell); } else if (ct == CellType.DATE_FORMULA) { newCell = new ReadDateFormulaRecord((FormulaData) cell); } else if(ct == CellType.FORMULA_ERROR) { newCell = new ReadErrorFormulaRecord((FormulaData) cell); } else if (ct == CellType.EMPTY) { if (cell.getCellFormat() != null) { // It is a blank cell, rather than an empty cell, so // it may have formatting information, so // it must be copied newCell = new Blank(cell); } } return newCell; } /** * Performs a deep copy of the specified cell, handling the cell format * * @param cell the cell to copy */ private WritableCell deepCopyCell(Cell cell) { WritableCell c = shallowCopyCell(cell); if (c == null) { return c; } if (c instanceof ReadFormulaRecord) { ReadFormulaRecord rfr = (ReadFormulaRecord) c; boolean crossSheetReference = !rfr.handleImportedCellReferences (fromSheet.getWorkbook(), fromSheet.getWorkbook(), workbookSettings); if (crossSheetReference) { try { logger.warn("Formula " + rfr.getFormula() + " in cell " + CellReferenceHelper.getCellReference(cell.getColumn(), cell.getRow()) + " cannot be imported because it references another " + " sheet from the source workbook"); } catch (FormulaException e) { logger.warn("Formula in cell " + CellReferenceHelper.getCellReference(cell.getColumn(), cell.getRow()) + " cannot be imported: " + e.getMessage()); } // Create a new error formula and add it instead c = new Formula(cell.getColumn(), cell.getRow(), "\"ERROR\""); } } // Copy the cell format CellFormat cf = c.getCellFormat(); int index = ( (XFRecord) cf).getXFIndex(); WritableCellFormat wcf = (WritableCellFormat) xfRecords.get(new Integer(index)); if (wcf == null) { wcf = copyCellFormat(cf); } c.setCellFormat(wcf); return c; } /** * Perform a shallow copy of the cells from the specified sheet into this one */ void shallowCopyCells() { // Copy the cells int cells = fromSheet.getRows(); Cell[] row = null; Cell cell = null; for (int i = 0; i < cells; i++) { row = fromSheet.getRow(i); for (int j = 0; j < row.length; j++) { cell = row[j]; WritableCell c = shallowCopyCell(cell); // Encase the calls to addCell in a try-catch block // These should not generate any errors, because we are // copying from an existing spreadsheet. In the event of // errors, catch the exception and then bomb out with an // assertion try { if (c != null) { toSheet.addCell(c); } } catch (WriteException e) { Assert.verify(false); } } } numRows = toSheet.getRows(); } /** * Perform a deep copy of the cells from the specified sheet into this one */ void deepCopyCells() { // Copy the cells int cells = fromSheet.getRows(); Cell[] row = null; Cell cell = null; for (int i = 0; i < cells; i++) { row = fromSheet.getRow(i); for (int j = 0; j < row.length; j++) { cell = row[j]; WritableCell c = deepCopyCell(cell); // Encase the calls to addCell in a try-catch block // These should not generate any errors, because we are // copying from an existing spreadsheet. In the event of // errors, catch the exception and then bomb out with an // assertion try { if (c != null) { toSheet.addCell(c); } } catch (WriteException e) { Assert.verify(false); } } } } /** * 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.put(new Integer(xfIndex), f); int fontIndex = xfr.getFontIndex(); fonts.put(new Integer(fontIndex), new Integer(f.getFontIndex())); int formatIndex = xfr.getFormatRecord(); formats.put(new Integer(formatIndex), new Integer(f.getFormatRecord())); return f; } catch (NumFormatRecordsException e) { logger.warn("Maximum number of format records exceeded. Using " + "default format."); return WritableWorkbook.NORMAL_STYLE; } } /** * Imports any names defined on the source sheet to the destination workbook */ private void importNames() { WorkbookParser fromWorkbook = (WorkbookParser) fromSheet.getWorkbook(); WritableWorkbook toWorkbook = toSheet.getWorkbook(); int fromSheetIndex = fromWorkbook.getIndex(fromSheet); NameRecord[] nameRecords = fromWorkbook.getNameRecords(); String[] names = toWorkbook.getRangeNames(); for (int i = 0 ; i < nameRecords.length ;i++) { NameRecord.NameRange[] nameRanges = nameRecords[i].getRanges(); for (int j = 0; j < nameRanges.length; j++) { int nameSheetIndex = fromWorkbook.getExternalSheetIndex (nameRanges[j].getExternalSheet()); if (fromSheetIndex == nameSheetIndex) { String name = nameRecords[i].getName(); if (Arrays.binarySearch(names, name) < 0) { toWorkbook.addNameArea(name, toSheet, nameRanges[j].getFirstColumn(), nameRanges[j].getFirstRow(), nameRanges[j].getLastColumn(), nameRanges[j].getLastRow()); } else { logger.warn("Named range " + name + " is already present in the destination workbook"); } } } } } /** * Gets the number of rows - allows for the case where formatting has * been applied to rows, even though the row has no data * * @return the number of rows */ int getRows() { return numRows; } /** * Accessor for the maximum column outline level * * @return the maximum column outline level, or 0 if no outlines/groups */ public int getMaxColumnOutlineLevel() { return maxColumnOutlineLevel; } /** * Accessor for the maximum row outline level * * @return the maximum row outline level, or 0 if no outlines/groups */ public int getMaxRowOutlineLevel() { return maxRowOutlineLevel; } }