| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| |
| package org.apache.poi.xssf.streaming; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.TreeMap; |
| |
| import org.apache.poi.ss.SpreadsheetVersion; |
| import org.apache.poi.ss.usermodel.AutoFilter; |
| import org.apache.poi.ss.usermodel.Cell; |
| import org.apache.poi.ss.usermodel.CellRange; |
| import org.apache.poi.ss.usermodel.CellStyle; |
| import org.apache.poi.ss.usermodel.DataValidation; |
| import org.apache.poi.ss.usermodel.DataValidationHelper; |
| import org.apache.poi.ss.usermodel.Footer; |
| import org.apache.poi.ss.usermodel.Header; |
| import org.apache.poi.ss.usermodel.PrintSetup; |
| import org.apache.poi.ss.usermodel.Row; |
| import org.apache.poi.ss.usermodel.Sheet; |
| import org.apache.poi.ss.usermodel.SheetConditionalFormatting; |
| import org.apache.poi.ss.usermodel.Workbook; |
| import org.apache.poi.ss.util.CellAddress; |
| import org.apache.poi.ss.util.CellRangeAddress; |
| import org.apache.poi.ss.util.PaneInformation; |
| import org.apache.poi.ss.util.SheetUtil; |
| import org.apache.poi.util.Internal; |
| import org.apache.poi.util.NotImplemented; |
| import org.apache.poi.util.Removal; |
| import org.apache.poi.xssf.usermodel.XSSFColor; |
| import org.apache.poi.xssf.usermodel.XSSFComment; |
| import org.apache.poi.xssf.usermodel.XSSFDataValidation; |
| import org.apache.poi.xssf.usermodel.XSSFDrawing; |
| import org.apache.poi.xssf.usermodel.XSSFHyperlink; |
| import org.apache.poi.xssf.usermodel.XSSFSheet; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; |
| |
| /** |
| * Streaming version of XSSFSheet implementing the "BigGridDemo" strategy. |
| */ |
| public class SXSSFSheet implements Sheet |
| { |
| /*package*/ final XSSFSheet _sh; |
| private final SXSSFWorkbook _workbook; |
| private final TreeMap<Integer,SXSSFRow> _rows=new TreeMap<Integer,SXSSFRow>(); |
| private final SheetDataWriter _writer; |
| private int _randomAccessWindowSize = SXSSFWorkbook.DEFAULT_WINDOW_SIZE; |
| private final AutoSizeColumnTracker _autoSizeColumnTracker; |
| private int outlineLevelRow = 0; |
| private int lastFlushedRowNumber = -1; |
| private boolean allFlushed = false; |
| |
| public SXSSFSheet(SXSSFWorkbook workbook, XSSFSheet xSheet) throws IOException { |
| _workbook = workbook; |
| _sh = xSheet; |
| _writer = workbook.createSheetDataWriter(); |
| setRandomAccessWindowSize(_workbook.getRandomAccessWindowSize()); |
| _autoSizeColumnTracker = new AutoSizeColumnTracker(this); |
| } |
| |
| /** |
| * for testing purposes only |
| */ |
| @Internal |
| SheetDataWriter getSheetDataWriter(){ |
| return _writer; |
| } |
| |
| /* Gets "<sheetData>" document fragment*/ |
| public InputStream getWorksheetXMLInputStream() throws IOException |
| { |
| // flush all remaining data and close the temp file writer |
| flushRows(0); |
| _writer.close(); |
| return _writer.getWorksheetXMLInputStream(); |
| } |
| |
| //start of interface implementation |
| @Override |
| public Iterator<Row> iterator() |
| { |
| return rowIterator(); |
| } |
| |
| /** |
| * Create a new row within the sheet and return the high level representation |
| * |
| * @param rownum row number |
| * @return high level Row object representing a row in the sheet |
| * @throws IllegalArgumentException If the max. number of rows is exceeded or |
| * a rownum is provided where the row is already flushed to disk. |
| * @see #removeRow(Row) |
| */ |
| @Override |
| public SXSSFRow createRow(int rownum) |
| { |
| int maxrow = SpreadsheetVersion.EXCEL2007.getLastRowIndex(); |
| if (rownum < 0 || rownum > maxrow) { |
| throw new IllegalArgumentException("Invalid row number (" + rownum |
| + ") outside allowable range (0.." + maxrow + ")"); |
| } |
| |
| // attempt to overwrite a row that is already flushed to disk |
| if(rownum <= _writer.getLastFlushedRow() ) { |
| throw new IllegalArgumentException( |
| "Attempting to write a row["+rownum+"] " + |
| "in the range [0," + _writer.getLastFlushedRow() + "] that is already written to disk."); |
| } |
| |
| // attempt to overwrite a existing row in the input template |
| if(_sh.getPhysicalNumberOfRows() > 0 && rownum <= _sh.getLastRowNum() ) { |
| throw new IllegalArgumentException( |
| "Attempting to write a row["+rownum+"] " + |
| "in the range [0," + _sh.getLastRowNum() + "] that is already written to disk."); |
| } |
| |
| SXSSFRow newRow=new SXSSFRow(this); |
| _rows.put(rownum,newRow); |
| allFlushed = false; |
| if(_randomAccessWindowSize>=0&&_rows.size()>_randomAccessWindowSize) |
| { |
| try |
| { |
| flushRows(_randomAccessWindowSize); |
| } |
| catch (IOException ioe) |
| { |
| throw new RuntimeException(ioe); |
| } |
| } |
| return newRow; |
| } |
| |
| /** |
| * Remove a row from this sheet. All cells contained in the row are removed as well |
| * |
| * @param row representing a row to remove. |
| */ |
| @Override |
| public void removeRow(Row row) |
| { |
| if (row.getSheet() != this) { |
| throw new IllegalArgumentException("Specified row does not belong to this sheet"); |
| } |
| |
| for(Iterator<Map.Entry<Integer,SXSSFRow>> iter=_rows.entrySet().iterator();iter.hasNext();) |
| { |
| Map.Entry<Integer,SXSSFRow> entry=iter.next(); |
| if(entry.getValue()==row) |
| { |
| iter.remove(); |
| return; |
| } |
| } |
| } |
| |
| /** |
| * Returns the logical row (not physical) 0-based. If you ask for a row that is not |
| * defined you get a null. This is to say row 4 represents the fifth row on a sheet. |
| * |
| * @param rownum row to get (0-based) |
| * @return Row representing the rownumber or null if its not defined on the sheet |
| */ |
| @Override |
| public SXSSFRow getRow(int rownum) |
| { |
| return _rows.get(rownum); |
| } |
| |
| /** |
| * Returns the number of physically defined rows (NOT the number of rows in the sheet) |
| * |
| * @return the number of physically defined rows in this sheet |
| */ |
| @Override |
| public int getPhysicalNumberOfRows() |
| { |
| return _rows.size()+_writer.getNumberOfFlushedRows(); |
| } |
| |
| /** |
| * Gets the first row on the sheet |
| * |
| * @return the number of the first logical row on the sheet (0-based) |
| */ |
| @Override |
| public int getFirstRowNum() |
| { |
| if(_writer.getNumberOfFlushedRows() > 0) { |
| return _writer.getLowestIndexOfFlushedRows(); |
| } |
| return _rows.size() == 0 ? 0 : _rows.firstKey(); |
| } |
| |
| /** |
| * Gets the last row on the sheet |
| * |
| * @return last row contained n this sheet (0-based) |
| */ |
| @Override |
| public int getLastRowNum() |
| { |
| return _rows.size() == 0 ? 0 : _rows.lastKey(); |
| } |
| |
| /** |
| * Get the visibility state for a given column |
| * |
| * @param columnIndex - the column to get (0-based) |
| * @param hidden - the visiblity state of the column |
| */ |
| @Override |
| public void setColumnHidden(int columnIndex, boolean hidden) |
| { |
| _sh.setColumnHidden(columnIndex,hidden); |
| } |
| |
| /** |
| * Get the hidden state for a given column |
| * |
| * @param columnIndex - the column to set (0-based) |
| * @return hidden - <code>false</code> if the column is visible |
| */ |
| @Override |
| public boolean isColumnHidden(int columnIndex) |
| { |
| return _sh.isColumnHidden(columnIndex); |
| } |
| |
| /** |
| * Set the width (in units of 1/256th of a character width) |
| * <p> |
| * The maximum column width for an individual cell is 255 characters. |
| * This value represents the number of characters that can be displayed |
| * in a cell that is formatted with the standard font. |
| * </p> |
| * |
| * @param columnIndex - the column to set (0-based) |
| * @param width - the width in units of 1/256th of a character width |
| */ |
| @Override |
| public void setColumnWidth(int columnIndex, int width) |
| { |
| _sh.setColumnWidth(columnIndex,width); |
| } |
| |
| /** |
| * get the width (in units of 1/256th of a character width ) |
| * @param columnIndex - the column to set (0-based) |
| * @return width - the width in units of 1/256th of a character width |
| */ |
| @Override |
| public int getColumnWidth(int columnIndex) |
| { |
| return _sh.getColumnWidth(columnIndex); |
| } |
| |
| /** |
| * Get the actual column width in pixels |
| * |
| * <p> |
| * Please note, that this method works correctly only for workbooks |
| * with the default font size (Calibri 11pt for .xlsx). |
| * </p> |
| */ |
| @Override |
| public float getColumnWidthInPixels(int columnIndex) { |
| return _sh.getColumnWidthInPixels(columnIndex); |
| } |
| |
| /** |
| * Set the default column width for the sheet (if the columns do not define their own width) |
| * in characters |
| * |
| * @param width default column width measured in characters |
| */ |
| @Override |
| public void setDefaultColumnWidth(int width) |
| { |
| _sh.setDefaultColumnWidth(width); |
| } |
| |
| /** |
| * Get the default column width for the sheet (if the columns do not define their own width) |
| * in characters |
| * |
| * @return default column width measured in characters |
| */ |
| @Override |
| public int getDefaultColumnWidth() |
| { |
| return _sh.getDefaultColumnWidth(); |
| } |
| |
| |
| /** |
| * Get the default row height for the sheet (if the rows do not define their own height) in |
| * twips (1/20 of a point) |
| * |
| * @return default row height measured in twips (1/20 of a point) |
| */ |
| @Override |
| public short getDefaultRowHeight() |
| { |
| return _sh.getDefaultRowHeight(); |
| } |
| |
| /** |
| * Get the default row height for the sheet (if the rows do not define their own height) in |
| * points. |
| * |
| * @return default row height in points |
| */ |
| @Override |
| public float getDefaultRowHeightInPoints() |
| { |
| return _sh.getDefaultRowHeightInPoints(); |
| } |
| |
| /** |
| * Set the default row height for the sheet (if the rows do not define their own height) in |
| * twips (1/20 of a point) |
| * |
| * @param height default row height measured in twips (1/20 of a point) |
| */ |
| @Override |
| public void setDefaultRowHeight(short height) |
| { |
| _sh.setDefaultRowHeight(height); |
| } |
| |
| /** |
| * Set the default row height for the sheet (if the rows do not define their own height) in |
| * points |
| * @param height default row height |
| */ |
| @Override |
| public void setDefaultRowHeightInPoints(float height) |
| { |
| _sh.setDefaultRowHeightInPoints(height); |
| } |
| |
| |
| /** |
| * Returns the CellStyle that applies to the given |
| * (0 based) column, or null if no style has been |
| * set for that column |
| */ |
| @Override |
| public CellStyle getColumnStyle(int column) |
| { |
| return _sh.getColumnStyle(column); |
| } |
| |
| /** |
| * Sets the CellStyle that applies to the given |
| * (0 based) column. |
| */ |
| // public CellStyle setColumnStyle(int column, CellStyle style); |
| |
| /** |
| * Adds a merged region of cells (hence those cells form one) |
| * |
| * @param region (rowfrom/colfrom-rowto/colto) to merge |
| * @return index of this region |
| */ |
| @Override |
| public int addMergedRegion(CellRangeAddress region) |
| { |
| return _sh.addMergedRegion(region); |
| } |
| |
| /** |
| * Adds a merged region of cells (hence those cells form one) |
| * |
| * @param region (rowfrom/colfrom-rowto/colto) to merge |
| * @return index of this region |
| */ |
| @Override |
| public int addMergedRegionUnsafe(CellRangeAddress region) |
| { |
| return _sh.addMergedRegionUnsafe(region); |
| } |
| |
| /** |
| * Verify that merged regions do not intersect multi-cell array formulas and |
| * no merged regions intersect another merged region in this sheet. |
| * |
| * @throws IllegalStateException if region intersects with a multi-cell array formula |
| * @throws IllegalStateException if at least one region intersects with another merged region in this sheet |
| */ |
| @Override |
| public void validateMergedRegions() { |
| _sh.validateMergedRegions(); |
| } |
| |
| /** |
| * Determines whether the output is vertically centered on the page. |
| * |
| * @param value true to vertically center, false otherwise. |
| */ |
| @Override |
| public void setVerticallyCenter(boolean value) |
| { |
| _sh.setVerticallyCenter(value); |
| } |
| |
| /** |
| * Determines whether the output is horizontally centered on the page. |
| * |
| * @param value true to horizontally center, false otherwise. |
| */ |
| @Override |
| public void setHorizontallyCenter(boolean value) |
| { |
| _sh.setHorizontallyCenter(value); |
| } |
| |
| /** |
| * Determine whether printed output for this sheet will be horizontally centered. |
| */ |
| @Override |
| public boolean getHorizontallyCenter() |
| { |
| return _sh.getHorizontallyCenter(); |
| } |
| |
| /** |
| * Determine whether printed output for this sheet will be vertically centered. |
| */ |
| @Override |
| public boolean getVerticallyCenter() |
| { |
| return _sh.getVerticallyCenter(); |
| } |
| |
| /** |
| * Removes a merged region of cells (hence letting them free) |
| * |
| * @param index of the region to unmerge |
| */ |
| @Override |
| public void removeMergedRegion(int index) |
| { |
| _sh.removeMergedRegion(index); |
| } |
| |
| /** |
| * Removes a merged region of cells (hence letting them free) |
| * |
| * @param indices of the regions to unmerge |
| */ |
| @Override |
| public void removeMergedRegions(Collection<Integer> indices) |
| { |
| _sh.removeMergedRegions(indices); |
| } |
| |
| /** |
| * Returns the number of merged regions |
| * |
| * @return number of merged regions |
| */ |
| @Override |
| public int getNumMergedRegions() |
| { |
| return _sh.getNumMergedRegions(); |
| } |
| |
| /** |
| * Returns the merged region at the specified index. If you want multiple |
| * regions, it is faster to call {@link #getMergedRegions()} than to call |
| * this each time. |
| * |
| * @return the merged region at the specified index |
| */ |
| @Override |
| public CellRangeAddress getMergedRegion(int index) |
| { |
| return _sh.getMergedRegion(index); |
| } |
| |
| /** |
| * Returns the list of merged regions. If you want multiple regions, this is |
| * faster than calling {@link #getMergedRegion(int)} each time. |
| * |
| * @return the list of merged regions |
| */ |
| @Override |
| public List<CellRangeAddress> getMergedRegions() { |
| return _sh.getMergedRegions(); |
| } |
| |
| /** |
| * Returns an iterator of the physical rows |
| * |
| * @return an iterator of the PHYSICAL rows. Meaning the 3rd element may not |
| * be the third row if say for instance the second row is undefined. |
| */ |
| @Override |
| public Iterator<Row> rowIterator() |
| { |
| @SuppressWarnings("unchecked") |
| Iterator<Row> result = (Iterator<Row>)(Iterator<? extends Row>)_rows.values().iterator(); |
| return result; |
| } |
| |
| /** |
| * Flag indicating whether the sheet displays Automatic Page Breaks. |
| * |
| * @param value <code>true</code> if the sheet displays Automatic Page Breaks. |
| */ |
| @Override |
| public void setAutobreaks(boolean value) |
| { |
| _sh.setAutobreaks(value); |
| } |
| |
| /** |
| * Set whether to display the guts or not |
| * |
| * @param value - guts or no guts |
| */ |
| @Override |
| public void setDisplayGuts(boolean value) |
| { |
| _sh.setDisplayGuts(value); |
| } |
| |
| /** |
| * Set whether the window should show 0 (zero) in cells containing zero value. |
| * When false, cells with zero value appear blank instead of showing the number zero. |
| * |
| * @param value whether to display or hide all zero values on the worksheet |
| */ |
| @Override |
| public void setDisplayZeros(boolean value) |
| { |
| _sh.setDisplayZeros(value); |
| } |
| |
| |
| /** |
| * Gets the flag indicating whether the window should show 0 (zero) in cells containing zero value. |
| * When false, cells with zero value appear blank instead of showing the number zero. |
| * |
| * @return whether all zero values on the worksheet are displayed |
| */ |
| @Override |
| public boolean isDisplayZeros() |
| { |
| return _sh.isDisplayZeros(); |
| } |
| |
| /** |
| * Sets whether the worksheet is displayed from right to left instead of from left to right. |
| * |
| * @param value true for right to left, false otherwise. |
| */ |
| @Override |
| public void setRightToLeft(boolean value) |
| { |
| _sh.setRightToLeft(value); |
| } |
| |
| /** |
| * Whether the text is displayed in right-to-left mode in the window |
| * |
| * @return whether the text is displayed in right-to-left mode in the window |
| */ |
| @Override |
| public boolean isRightToLeft() |
| { |
| return _sh.isRightToLeft(); |
| } |
| |
| /** |
| * Flag indicating whether the Fit to Page print option is enabled. |
| * |
| * @param value <code>true</code> if the Fit to Page print option is enabled. |
| */ |
| @Override |
| public void setFitToPage(boolean value) |
| { |
| _sh.setFitToPage(value); |
| } |
| |
| /** |
| * Flag indicating whether summary rows appear below detail in an outline, when applying an outline. |
| * |
| * <p> |
| * When true a summary row is inserted below the detailed data being summarized and a |
| * new outline level is established on that row. |
| * </p> |
| * <p> |
| * When false a summary row is inserted above the detailed data being summarized and a new outline level |
| * is established on that row. |
| * </p> |
| * @param value <code>true</code> if row summaries appear below detail in the outline |
| */ |
| @Override |
| public void setRowSumsBelow(boolean value) |
| { |
| _sh.setRowSumsBelow(value); |
| } |
| |
| /** |
| * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline. |
| * |
| * <p> |
| * When true a summary column is inserted to the right of the detailed data being summarized |
| * and a new outline level is established on that column. |
| * </p> |
| * <p> |
| * When false a summary column is inserted to the left of the detailed data being |
| * summarized and a new outline level is established on that column. |
| * </p> |
| * @param value <code>true</code> if col summaries appear right of the detail in the outline |
| */ |
| @Override |
| public void setRowSumsRight(boolean value) |
| { |
| _sh.setRowSumsRight(value); |
| } |
| |
| /** |
| * Flag indicating whether the sheet displays Automatic Page Breaks. |
| * |
| * @return <code>true</code> if the sheet displays Automatic Page Breaks. |
| */ |
| @Override |
| public boolean getAutobreaks() |
| { |
| return _sh.getAutobreaks(); |
| } |
| |
| /** |
| * Get whether to display the guts or not, |
| * default value is true |
| * |
| * @return boolean - guts or no guts |
| */ |
| @Override |
| public boolean getDisplayGuts() |
| { |
| return _sh.getDisplayGuts(); |
| } |
| |
| /** |
| * Flag indicating whether the Fit to Page print option is enabled. |
| * |
| * @return <code>true</code> if the Fit to Page print option is enabled. |
| */ |
| @Override |
| public boolean getFitToPage() |
| { |
| return _sh.getFitToPage(); |
| } |
| |
| /** |
| * Flag indicating whether summary rows appear below detail in an outline, when applying an outline. |
| * |
| * <p> |
| * When true a summary row is inserted below the detailed data being summarized and a |
| * new outline level is established on that row. |
| * </p> |
| * <p> |
| * When false a summary row is inserted above the detailed data being summarized and a new outline level |
| * is established on that row. |
| * </p> |
| * @return <code>true</code> if row summaries appear below detail in the outline |
| */ |
| @Override |
| public boolean getRowSumsBelow() |
| { |
| return _sh.getRowSumsBelow(); |
| } |
| |
| /** |
| * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline. |
| * |
| * <p> |
| * When true a summary column is inserted to the right of the detailed data being summarized |
| * and a new outline level is established on that column. |
| * </p> |
| * <p> |
| * When false a summary column is inserted to the left of the detailed data being |
| * summarized and a new outline level is established on that column. |
| * </p> |
| * @return <code>true</code> if col summaries appear right of the detail in the outline |
| */ |
| @Override |
| public boolean getRowSumsRight() |
| { |
| return _sh.getRowSumsRight(); |
| } |
| |
| /** |
| * Returns whether gridlines are printed. |
| * |
| * @return whether gridlines are printed |
| */ |
| @Override |
| public boolean isPrintGridlines() |
| { |
| return _sh.isPrintGridlines(); |
| } |
| |
| /** |
| * Turns on or off the printing of gridlines. |
| * |
| * @param show boolean to turn on or off the printing of gridlines |
| */ |
| @Override |
| public void setPrintGridlines(boolean show) |
| { |
| _sh.setPrintGridlines(show); |
| } |
| |
| /** |
| * Returns whether row and column headings are printed. |
| * |
| * @return whether row and column headings are printed |
| */ |
| @Override |
| public boolean isPrintRowAndColumnHeadings() |
| { |
| return _sh.isPrintRowAndColumnHeadings(); |
| } |
| |
| /** |
| * Turns on or off the printing of row and column headings. |
| * |
| * @param show boolean to turn on or off the printing of row and column headings |
| */ |
| @Override |
| public void setPrintRowAndColumnHeadings(boolean show) |
| { |
| _sh.setPrintRowAndColumnHeadings(show); |
| } |
| |
| /** |
| * Gets the print setup object. |
| * |
| * @return The user model for the print setup object. |
| */ |
| @Override |
| public PrintSetup getPrintSetup() |
| { |
| return _sh.getPrintSetup(); |
| } |
| |
| /** |
| * Gets the user model for the default document header. |
| * <p> |
| * Note that XSSF offers more kinds of document headers than HSSF does |
| * </p> |
| * @return the document header. Never <code>null</code> |
| */ |
| @Override |
| public Header getHeader() |
| { |
| return _sh.getHeader(); |
| } |
| |
| /** |
| * Gets the user model for the default document footer. |
| * <p> |
| * Note that XSSF offers more kinds of document footers than HSSF does. |
| * </p> |
| * @return the document footer. Never <code>null</code> |
| */ |
| @Override |
| public Footer getFooter() |
| { |
| return _sh.getFooter(); |
| } |
| |
| /** |
| * Sets a flag indicating whether this sheet is selected. |
| * <p> |
| * Note: multiple sheets can be selected, but only one sheet can be active at one time. |
| * </p> |
| * @param value <code>true</code> if this sheet is selected |
| * @see Workbook#setActiveSheet(int) |
| */ |
| @Override |
| public void setSelected(boolean value) |
| { |
| _sh.setSelected(value); |
| } |
| |
| /** |
| * Gets the size of the margin in inches. |
| * |
| * @param margin which margin to get |
| * @return the size of the margin |
| */ |
| @Override |
| public double getMargin(short margin) |
| { |
| return _sh.getMargin(margin); |
| } |
| |
| /** |
| * Sets the size of the margin in inches. |
| * |
| * @param margin which margin to get |
| * @param size the size of the margin |
| */ |
| @Override |
| public void setMargin(short margin, double size) |
| { |
| _sh.setMargin(margin,size); |
| } |
| |
| /** |
| * Answer whether protection is enabled or disabled |
| * |
| * @return true means protection enabled; false means protection disabled |
| */ |
| @Override |
| public boolean getProtect() |
| { |
| return _sh.getProtect(); |
| } |
| |
| /** |
| * Sets the protection enabled as well as the password |
| * @param password to set for protection. Pass <code>null</code> to remove protection |
| */ |
| @Override |
| public void protectSheet(String password) |
| { |
| _sh.protectSheet(password); |
| } |
| |
| /** |
| * Answer whether scenario protection is enabled or disabled |
| * |
| * @return true means protection enabled; false means protection disabled |
| */ |
| @Override |
| public boolean getScenarioProtect() |
| { |
| return _sh.getScenarioProtect(); |
| } |
| |
| /** |
| * Sets the zoom magnification for the sheet. The zoom is expressed as a |
| * fraction. For example to express a zoom of 75% use 3 for the numerator |
| * and 4 for the denominator. |
| * |
| * @param numerator The numerator for the zoom magnification. |
| * @param denominator The denominator for the zoom magnification. |
| * @deprecated 2015-11-23 (circa POI 3.14beta1). Use {@link #setZoom(int)} instead. |
| */ |
| @Deprecated |
| @Removal(version="3.16") |
| @Override |
| public void setZoom(int numerator, int denominator) |
| { |
| _sh.setZoom(numerator,denominator); |
| } |
| |
| /** |
| * Window zoom magnification for current view representing percent values. |
| * Valid values range from 10 to 400. Horizontal and Vertical scale together. |
| * |
| * For example: |
| * <pre> |
| * 10 - 10% |
| * 20 - 20% |
| * ... |
| * 100 - 100% |
| * ... |
| * 400 - 400% |
| * </pre> |
| * |
| * Current view can be Normal, Page Layout, or Page Break Preview. |
| * |
| * @param scale window zoom magnification |
| * @throws IllegalArgumentException if scale is invalid |
| */ |
| @Override |
| public void setZoom(int scale) { |
| _sh.setZoom(scale); |
| } |
| |
| /** |
| * The top row in the visible view when the sheet is |
| * first viewed after opening it in a viewer |
| * |
| * @return short indicating the rownum (0 based) of the top row |
| */ |
| @Override |
| public short getTopRow() |
| { |
| return _sh.getTopRow(); |
| } |
| |
| /** |
| * The left col in the visible view when the sheet is |
| * first viewed after opening it in a viewer |
| * |
| * @return short indicating the rownum (0 based) of the top row |
| */ |
| @Override |
| public short getLeftCol() |
| { |
| return _sh.getLeftCol(); |
| } |
| |
| /** |
| * Sets desktop window pane display area, when the |
| * file is first opened in a viewer. |
| * |
| * @param toprow the top row to show in desktop window pane |
| * @param leftcol the left column to show in desktop window pane |
| */ |
| @Override |
| public void showInPane(int toprow, int leftcol) |
| { |
| _sh.showInPane(toprow, leftcol); |
| } |
| |
| /** |
| * Control if Excel should be asked to recalculate all formulas when the |
| * workbook is opened, via the "sheetCalcPr fullCalcOnLoad" option. |
| * Calculating the formula values with {@link org.apache.poi.ss.usermodel.FormulaEvaluator} is the |
| * recommended solution, but this may be used for certain cases where |
| * evaluation in POI is not possible. |
| */ |
| @Override |
| public void setForceFormulaRecalculation(boolean value) { |
| _sh.setForceFormulaRecalculation(value); |
| } |
| |
| /** |
| * Whether Excel will be asked to recalculate all formulas when the |
| * workbook is opened. |
| */ |
| @Override |
| public boolean getForceFormulaRecalculation() { |
| return _sh.getForceFormulaRecalculation(); |
| } |
| |
| /** |
| * <i>Not implemented for SXSSFSheets</i> |
| * |
| * Shifts rows between startRow and endRow n number of rows. |
| * If you use a negative number, it will shift rows up. |
| * Code ensures that rows don't wrap around. |
| * |
| * Calls shiftRows(startRow, endRow, n, false, false); |
| * |
| * <p> |
| * Additionally shifts merged regions that are completely defined in these |
| * rows (ie. merged 2 cells on a row to be shifted). |
| * @param startRow the row to start shifting |
| * @param endRow the row to end shifting |
| * @param n the number of rows to shift |
| */ |
| @NotImplemented |
| @Override |
| public void shiftRows(int startRow, int endRow, int n) |
| { |
| throw new RuntimeException("NotImplemented"); |
| } |
| |
| /** |
| * <i>Not implemented for SXSSFSheets</i> |
| * |
| * Shifts rows between startRow and endRow n number of rows. |
| * If you use a negative number, it will shift rows up. |
| * Code ensures that rows don't wrap around |
| * |
| * <p> |
| * Additionally shifts merged regions that are completely defined in these |
| * rows (ie. merged 2 cells on a row to be shifted). All merged regions that are |
| * completely overlaid by shifting will be deleted. |
| * <p> |
| * @param startRow the row to start shifting |
| * @param endRow the row to end shifting |
| * @param n the number of rows to shift |
| * @param copyRowHeight whether to copy the row height during the shift |
| * @param resetOriginalRowHeight whether to set the original row's height to the default |
| */ |
| @NotImplemented |
| @Override |
| public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) |
| { |
| throw new RuntimeException("NotImplemented"); |
| } |
| |
| /** |
| * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. |
| * @param colSplit Horizonatal position of split. |
| * @param rowSplit Vertical position of split. |
| * @param leftmostColumn Left column visible in right pane. |
| * @param topRow Top row visible in bottom pane |
| */ |
| @Override |
| public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) |
| { |
| _sh.createFreezePane(colSplit, rowSplit, leftmostColumn, topRow); |
| } |
| |
| /** |
| * Creates a split (freezepane). Any existing freezepane or split pane is overwritten. |
| * @param colSplit Horizonatal position of split. |
| * @param rowSplit Vertical position of split. |
| */ |
| @Override |
| public void createFreezePane(int colSplit, int rowSplit) |
| { |
| _sh.createFreezePane(colSplit,rowSplit); |
| } |
| |
| /** |
| * Creates a split pane. Any existing freezepane or split pane is overwritten. |
| * @param xSplitPos Horizonatal position of split (in 1/20th of a point). |
| * @param ySplitPos Vertical position of split (in 1/20th of a point). |
| * @param topRow Top row visible in bottom pane |
| * @param leftmostColumn Left column visible in right pane. |
| * @param activePane Active pane. One of: PANE_LOWER_RIGHT, |
| * PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT |
| * @see #PANE_LOWER_LEFT |
| * @see #PANE_LOWER_RIGHT |
| * @see #PANE_UPPER_LEFT |
| * @see #PANE_UPPER_RIGHT |
| */ |
| @Override |
| public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) |
| { |
| _sh.createSplitPane(xSplitPos, ySplitPos, leftmostColumn, topRow, activePane); |
| } |
| |
| /** |
| * Returns the information regarding the currently configured pane (split or freeze) |
| * |
| * @return null if no pane configured, or the pane information. |
| */ |
| @Override |
| public PaneInformation getPaneInformation() |
| { |
| return _sh.getPaneInformation(); |
| } |
| |
| /** |
| * Sets whether the gridlines are shown in a viewer |
| * |
| * @param show whether to show gridlines or not |
| */ |
| @Override |
| public void setDisplayGridlines(boolean show) |
| { |
| _sh.setDisplayGridlines(show); |
| } |
| |
| /** |
| * Returns if gridlines are displayed |
| * |
| * @return whether gridlines are displayed |
| */ |
| @Override |
| public boolean isDisplayGridlines() |
| { |
| return _sh.isDisplayGridlines(); |
| } |
| |
| /** |
| * Sets whether the formulas are shown in a viewer |
| * |
| * @param show whether to show formulas or not |
| */ |
| @Override |
| public void setDisplayFormulas(boolean show) |
| { |
| _sh.setDisplayFormulas(show); |
| } |
| |
| /** |
| * Returns if formulas are displayed |
| * |
| * @return whether formulas are displayed |
| */ |
| @Override |
| public boolean isDisplayFormulas() |
| { |
| return _sh.isDisplayFormulas(); |
| } |
| |
| /** |
| * Sets whether the RowColHeadings are shown in a viewer |
| * |
| * @param show whether to show RowColHeadings or not |
| */ |
| @Override |
| public void setDisplayRowColHeadings(boolean show) |
| { |
| _sh.setDisplayRowColHeadings(show); |
| } |
| |
| /** |
| * Returns if RowColHeadings are displayed. |
| * @return whether RowColHeadings are displayed |
| */ |
| @Override |
| public boolean isDisplayRowColHeadings() |
| { |
| return _sh.isDisplayRowColHeadings(); |
| } |
| |
| /** |
| * Sets a page break at the indicated row |
| * @param row FIXME: Document this! |
| */ |
| @Override |
| public void setRowBreak(int row) |
| { |
| _sh.setRowBreak(row); |
| } |
| |
| /** |
| * Determines if there is a page break at the indicated row |
| * @param row FIXME: Document this! |
| * @return FIXME: Document this! |
| */ |
| @Override |
| public boolean isRowBroken(int row) |
| { |
| return _sh.isRowBroken(row); |
| } |
| |
| /** |
| * Removes the page break at the indicated row |
| * @param row |
| */ |
| @Override |
| public void removeRowBreak(int row) |
| { |
| _sh.removeRowBreak(row); |
| } |
| |
| /** |
| * Retrieves all the horizontal page breaks |
| * @return all the horizontal page breaks, or null if there are no row page breaks |
| */ |
| @Override |
| public int[] getRowBreaks() |
| { |
| return _sh.getRowBreaks(); |
| } |
| |
| /** |
| * Retrieves all the vertical page breaks |
| * @return all the vertical page breaks, or null if there are no column page breaks |
| */ |
| @Override |
| public int[] getColumnBreaks() |
| { |
| return _sh.getColumnBreaks(); |
| } |
| |
| /** |
| * Sets a page break at the indicated column |
| * @param column |
| */ |
| @Override |
| public void setColumnBreak(int column) |
| { |
| _sh.setColumnBreak(column); |
| } |
| |
| /** |
| * Determines if there is a page break at the indicated column |
| * @param column FIXME: Document this! |
| * @return FIXME: Document this! |
| */ |
| @Override |
| public boolean isColumnBroken(int column) |
| { |
| return _sh.isColumnBroken(column); |
| } |
| |
| /** |
| * Removes a page break at the indicated column |
| * @param column |
| */ |
| @Override |
| public void removeColumnBreak(int column) |
| { |
| _sh.removeColumnBreak(column); |
| } |
| |
| /** |
| * Expands or collapses a column group. |
| * |
| * @param columnNumber One of the columns in the group. |
| * @param collapsed true = collapse group, false = expand group. |
| */ |
| @Override |
| public void setColumnGroupCollapsed(int columnNumber, boolean collapsed) |
| { |
| _sh.setColumnGroupCollapsed(columnNumber, collapsed); |
| } |
| |
| /** |
| * Create an outline for the provided column range. |
| * |
| * @param fromColumn beginning of the column range. |
| * @param toColumn end of the column range. |
| */ |
| @Override |
| public void groupColumn(int fromColumn, int toColumn) |
| { |
| _sh.groupColumn(fromColumn,toColumn); |
| } |
| |
| /** |
| * Ungroup a range of columns that were previously groupped |
| * |
| * @param fromColumn start column (0-based) |
| * @param toColumn end column (0-based) |
| */ |
| @Override |
| public void ungroupColumn(int fromColumn, int toColumn) |
| { |
| _sh.ungroupColumn(fromColumn, toColumn); |
| } |
| |
| /** |
| * Tie a range of rows together so that they can be collapsed or expanded |
| * |
| * <p> |
| * Please note the rows being grouped <em>must</em> be in the current window, |
| * if the rows are already flushed then groupRow has no effect. |
| * </p> |
| * |
| * Correct code: |
| * <pre><code> |
| * Workbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory |
| * Sheet sh = wb.createSheet(); |
| * for (int rownum = 0; rownum < 1000; rownum++) { |
| * Row row = sh.createRow(rownum); |
| * if(rownum == 200) { |
| * sh.groupRow(100, 200); |
| * } |
| * } |
| * |
| * </code></pre> |
| * |
| * |
| * Incorrect code: |
| * <pre><code> |
| * Workbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory |
| * Sheet sh = wb.createSheet(); |
| * for (int rownum = 0; rownum < 1000; rownum++) { |
| * Row row = sh.createRow(rownum); |
| * } |
| * sh.groupRow(100, 200); // the rows in the range [100, 200] are already flushed and groupRows has no effect |
| * |
| * </code></pre> |
| * |
| * |
| * @param fromRow start row (0-based) |
| * @param toRow end row (0-based) |
| */ |
| @Override |
| public void groupRow(int fromRow, int toRow) |
| { |
| for(SXSSFRow row : _rows.subMap(fromRow, toRow + 1).values()){ |
| int level = row.getOutlineLevel() + 1; |
| row.setOutlineLevel(level); |
| |
| if(level > outlineLevelRow) { |
| outlineLevelRow = level; |
| } |
| } |
| |
| setWorksheetOutlineLevelRow(); |
| } |
| |
| /** |
| * Set row groupings (like groupRow) in a stream-friendly manner |
| * |
| * <p> |
| * groupRows requires all rows in the group to be in the current window. |
| * This is not always practical. Instead use setRowOutlineLevel to |
| * explicitly set the group level. Level 1 is the top level group, |
| * followed by 2, etc. It is up to the user to ensure that level 2 |
| * groups are correctly nested under level 1, etc. |
| * </p> |
| * |
| * @param rownum index of row to update (0-based) |
| * @param level outline level (greater than 0) |
| */ |
| public void setRowOutlineLevel(int rownum, int level) |
| { |
| SXSSFRow row = _rows.get(rownum); |
| row.setOutlineLevel(level); |
| if(level > 0 && level > outlineLevelRow) { |
| outlineLevelRow = level; |
| setWorksheetOutlineLevelRow(); |
| } |
| } |
| |
| private void setWorksheetOutlineLevelRow() { |
| CTWorksheet ct = _sh.getCTWorksheet(); |
| CTSheetFormatPr pr = ct.isSetSheetFormatPr() ? |
| ct.getSheetFormatPr() : |
| ct.addNewSheetFormatPr(); |
| if(outlineLevelRow > 0) { |
| pr.setOutlineLevelRow((short)outlineLevelRow); |
| } |
| } |
| |
| /** |
| * Ungroup a range of rows that were previously groupped |
| * |
| * @param fromRow start row (0-based) |
| * @param toRow end row (0-based) |
| */ |
| @Override |
| public void ungroupRow(int fromRow, int toRow) |
| { |
| _sh.ungroupRow(fromRow, toRow); |
| } |
| |
| /** |
| * Set view state of a grouped range of rows. |
| * |
| * <i>Not implemented for expanding (i.e. collapse == false)</i> |
| * |
| * @param row start row of a groupped range of rows (0-based) |
| * @param collapse whether to expand/collapse the detail rows |
| * @throws RuntimeException if collapse is false as this is not implemented for SXSSF. |
| */ |
| @Override |
| public void setRowGroupCollapsed(int row, boolean collapse) |
| { |
| if (collapse) { |
| collapseRow(row); |
| } else { |
| //expandRow(rowIndex); |
| throw new RuntimeException("Unable to expand row: Not Implemented"); |
| } |
| } |
| |
| /** |
| * @param rowIndex the zero based row index to collapse |
| */ |
| private void collapseRow(int rowIndex) { |
| SXSSFRow row = getRow(rowIndex); |
| if(row == null) { |
| throw new IllegalArgumentException("Invalid row number("+ rowIndex + "). Row does not exist."); |
| } else { |
| int startRow = findStartOfRowOutlineGroup(rowIndex); |
| |
| // Hide all the columns until the end of the group |
| int lastRow = writeHidden(row, startRow, true); |
| SXSSFRow lastRowObj = getRow(lastRow); |
| if (lastRowObj != null) { |
| lastRowObj.setCollapsed(true); |
| } else { |
| SXSSFRow newRow = createRow(lastRow); |
| newRow.setCollapsed(true); |
| } |
| } |
| } |
| |
| /** |
| * @param rowIndex the zero based row index to find from |
| */ |
| private int findStartOfRowOutlineGroup(int rowIndex) { |
| // Find the start of the group. |
| Row row = getRow(rowIndex); |
| int level = ((SXSSFRow) row).getOutlineLevel(); |
| if(level == 0) { |
| throw new IllegalArgumentException("Outline level is zero for the row (" + rowIndex + ")."); |
| } |
| int currentRow = rowIndex; |
| while (getRow(currentRow) != null) { |
| if (getRow(currentRow).getOutlineLevel() < level) { |
| return currentRow + 1; |
| } |
| currentRow--; |
| } |
| return currentRow + 1; |
| } |
| |
| private int writeHidden(SXSSFRow xRow, int rowIndex, boolean hidden) { |
| int level = xRow.getOutlineLevel(); |
| SXSSFRow currRow = getRow(rowIndex); |
| |
| while (currRow != null && currRow.getOutlineLevel() >= level) { |
| currRow.setHidden(hidden); |
| rowIndex++; |
| currRow = getRow(rowIndex); |
| } |
| return rowIndex; |
| } |
| |
| /** |
| * Sets the default column style for a given column. POI will only apply this style to new cells added to the sheet. |
| * |
| * @param column the column index |
| * @param style the style to set |
| */ |
| @Override |
| public void setDefaultColumnStyle(int column, CellStyle style) |
| { |
| _sh.setDefaultColumnStyle(column, style); |
| } |
| |
| |
| /** |
| * Track a column in the sheet for auto-sizing. |
| * Note this has undefined behavior if a column is tracked after one or more rows are written to the sheet. |
| * If <code>column</code> is already tracked, this call does nothing. |
| * |
| * @param column the column to track for auto-sizing |
| * @since 3.14beta1 |
| * @see #trackColumnsForAutoSizing(Collection) |
| * @see #trackAllColumnsForAutoSizing() |
| */ |
| public void trackColumnForAutoSizing(int column) |
| { |
| _autoSizeColumnTracker.trackColumn(column); |
| } |
| |
| /** |
| * Track several columns in the sheet for auto-sizing. |
| * Note this has undefined behavior if columns are tracked after one or more rows are written to the sheet. |
| * Any column in <code>columns</code> that are already tracked are ignored by this call. |
| * |
| * @param columns the columns to track for auto-sizing |
| * @since 3.14beta1 |
| */ |
| public void trackColumnsForAutoSizing(Collection<Integer> columns) |
| { |
| _autoSizeColumnTracker.trackColumns(columns); |
| } |
| |
| /** |
| * Tracks all columns in the sheet for auto-sizing. If this is called, individual columns do not need to be tracked. |
| * Because determining the best-fit width for a cell is expensive, this may affect the performance. |
| * @since 3.14beta1 |
| */ |
| public void trackAllColumnsForAutoSizing() |
| { |
| _autoSizeColumnTracker.trackAllColumns(); |
| } |
| |
| /** |
| * Removes a column that was previously marked for inclusion in auto-size column tracking. |
| * When a column is untracked, the best-fit width is forgotten. |
| * If <code>column</code> is not tracked, it will be ignored by this call. |
| * |
| * @param column the index of the column to track for auto-sizing |
| * @return true if column was tracked prior to this call, false if no action was taken |
| * @since 3.14beta1 |
| * @see #untrackColumnsForAutoSizing(Collection) |
| * @see #untrackAllColumnsForAutoSizing() |
| */ |
| public boolean untrackColumnForAutoSizing(int column) |
| { |
| return _autoSizeColumnTracker.untrackColumn(column); |
| } |
| |
| /** |
| * Untracks several columns in the sheet for auto-sizing. |
| * When a column is untracked, the best-fit width is forgotten. |
| * Any column in <code>columns</code> that is not tracked will be ignored by this call. |
| * |
| * @param columns the indices of the columns to track for auto-sizing |
| * @return true if one or more columns were untracked as a result of this call |
| * @since 3.14beta1 |
| */ |
| public boolean untrackColumnsForAutoSizing(Collection<Integer> columns) |
| { |
| return _autoSizeColumnTracker.untrackColumns(columns); |
| } |
| |
| /** |
| * Untracks all columns in the sheet for auto-sizing. Best-fit column widths are forgotten. |
| * If this is called, individual columns do not need to be untracked. |
| * @since 3.14beta1 |
| */ |
| public void untrackAllColumnsForAutoSizing() |
| { |
| _autoSizeColumnTracker.untrackAllColumns(); |
| } |
| |
| /** |
| * Returns true if column is currently tracked for auto-sizing. |
| * |
| * @param column the index of the column to check |
| * @return true if column is tracked |
| * @since 3.14beta1 |
| */ |
| public boolean isColumnTrackedForAutoSizing(int column) |
| { |
| return _autoSizeColumnTracker.isColumnTracked(column); |
| } |
| |
| /** |
| * Get the currently tracked columns for auto-sizing. |
| * Note if all columns are tracked, this will only return the columns that have been explicitly or implicitly tracked, |
| * which is probably only columns containing 1 or more non-blank values |
| * |
| * @return a set of the indices of all tracked columns |
| * @since 3.14beta1 |
| */ |
| public Set<Integer> getTrackedColumnsForAutoSizing() |
| { |
| return _autoSizeColumnTracker.getTrackedColumns(); |
| } |
| |
| /** |
| * Adjusts the column width to fit the contents. |
| * |
| * <p> |
| * This process can be relatively slow on large sheets, so this should |
| * normally only be called once per column, at the end of your |
| * processing. |
| * </p> |
| * You can specify whether the content of merged cells should be considered or ignored. |
| * Default is to ignore merged cells. |
| * |
| * <p> |
| * Special note about SXSSF implementation: You must register the columns you wish to track with |
| * the SXSSFSheet using {@link #trackColumnForAutoSizing(int)} or {@link #trackAllColumnsForAutoSizing()}. |
| * This is needed because the rows needed to compute the column width may have fallen outside the |
| * random access window and been flushed to disk. |
| * Tracking columns is required even if all rows are in the random access window. |
| * </p> |
| * <p><i>New in POI 3.14 beta 1: auto-sizes columns using cells from current and flushed rows.</i></p> |
| * |
| * @param column the column index to auto-size |
| */ |
| @Override |
| public void autoSizeColumn(int column) |
| { |
| autoSizeColumn(column, false); |
| } |
| |
| /** |
| * Adjusts the column width to fit the contents. |
| * <p> |
| * This process can be relatively slow on large sheets, so this should |
| * normally only be called once per column, at the end of your |
| * processing. |
| * </p> |
| * You can specify whether the content of merged cells should be considered or ignored. |
| * Default is to ignore merged cells. |
| * |
| * <p> |
| * Special note about SXSSF implementation: You must register the columns you wish to track with |
| * the SXSSFSheet using {@link #trackColumnForAutoSizing(int)} or {@link #trackAllColumnsForAutoSizing()}. |
| * This is needed because the rows needed to compute the column width may have fallen outside the |
| * random access window and been flushed to disk. |
| * Tracking columns is required even if all rows are in the random access window. |
| * </p> |
| * <p><i>New in POI 3.14 beta 1: auto-sizes columns using cells from current and flushed rows.</i></p> |
| * |
| * @param column the column index to auto-size |
| * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column |
| */ |
| @Override |
| public void autoSizeColumn(int column, boolean useMergedCells) |
| { |
| // Multiple calls to autoSizeColumn need to look up the best-fit width |
| // of rows already flushed to disk plus re-calculate the best-fit width |
| // of rows in the current window. It isn't safe to update the column |
| // widths before flushing to disk because columns in the random access |
| // window rows may change in best-fit width. The best-fit width of a cell |
| // is only fixed when it becomes inaccessible for modification. |
| // Changes to the shared strings table, styles table, or formulas might |
| // be able to invalidate the auto-size width without the opportunity |
| // to recalculate the best-fit width for the flushed rows. This is an |
| // inherent limitation of SXSSF. If having correct auto-sizing is |
| // critical, the flushed rows would need to be re-read by the read-only |
| // XSSF eventmodel (SAX) or the memory-heavy XSSF usermodel (DOM). |
| final int flushedWidth; |
| try { |
| // get the best fit width of rows already flushed to disk |
| flushedWidth = _autoSizeColumnTracker.getBestFitColumnWidth(column, useMergedCells); |
| } |
| catch (final IllegalStateException e) { |
| throw new IllegalStateException("Could not auto-size column. Make sure the column was tracked prior to auto-sizing the column.", e); |
| } |
| |
| // get the best-fit width of rows currently in the random access window |
| final int activeWidth = (int) (256 * SheetUtil.getColumnWidth(this, column, useMergedCells)); |
| |
| // the best-fit width for both flushed rows and random access window rows |
| // flushedWidth or activeWidth may be negative if column contains only blank cells |
| final int bestFitWidth = Math.max(flushedWidth, activeWidth); |
| |
| if (bestFitWidth > 0) { |
| final int maxColumnWidth = 255*256; // The maximum column width for an individual cell is 255 characters |
| final int width = Math.min(bestFitWidth, maxColumnWidth); |
| setColumnWidth(column, width); |
| } |
| } |
| |
| /** |
| * Returns cell comment for the specified row and column |
| * |
| * @return cell comment or <code>null</code> if not found |
| * @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellAddress)} instead. |
| */ |
| @Deprecated |
| @Removal(version="3.16") |
| @Override |
| public XSSFComment getCellComment(int row, int column) |
| { |
| return getCellComment(new CellAddress(row, column)); |
| } |
| |
| /** |
| * Returns cell comment for the specified row and column |
| * |
| * @return cell comment or <code>null</code> if not found |
| */ |
| @Override |
| public XSSFComment getCellComment(CellAddress ref) |
| { |
| return _sh.getCellComment(ref); |
| } |
| |
| /** |
| * Returns all cell comments on this sheet. |
| * @return A map of each Comment in the sheet, keyed on the cell address where |
| * the comment is located. |
| */ |
| @Override |
| public Map<CellAddress, XSSFComment> getCellComments() { |
| return _sh.getCellComments(); |
| } |
| |
| /** |
| * Get a Hyperlink in this sheet anchored at row, column |
| * |
| * @param row |
| * @param column |
| * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null |
| */ |
| @Override |
| public XSSFHyperlink getHyperlink(int row, int column) { |
| return _sh.getHyperlink(row, column); |
| } |
| |
| /** |
| * Get a Hyperlink in this sheet located in a cell specified by {code addr} |
| * |
| * @param addr The address of the cell containing the hyperlink |
| * @return hyperlink if there is a hyperlink anchored at {@code addr}; otherwise returns {@code null} |
| * @since POI 3.15 beta 3 |
| */ |
| @Override |
| public XSSFHyperlink getHyperlink(CellAddress addr) { |
| return _sh.getHyperlink(addr); |
| } |
| |
| /** |
| * Get a list of Hyperlinks in this sheet |
| * |
| * @return Hyperlinks for the sheet |
| */ |
| @Override |
| public List<XSSFHyperlink> getHyperlinkList() { |
| return _sh.getHyperlinkList(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public XSSFDrawing getDrawingPatriarch() |
| { |
| return _sh.getDrawingPatriarch(); |
| } |
| |
| /** |
| * Creates the top-level drawing patriarch. |
| * |
| * @return The new drawing patriarch. |
| */ |
| @Override |
| public SXSSFDrawing createDrawingPatriarch() |
| { |
| return new SXSSFDrawing(getWorkbook(), _sh.createDrawingPatriarch()); |
| } |
| |
| |
| /** |
| * Return the parent workbook |
| * |
| * @return the parent workbook |
| */ |
| @Override |
| public SXSSFWorkbook getWorkbook() |
| { |
| return _workbook; |
| } |
| |
| /** |
| * Returns the name of this sheet |
| * |
| * @return the name of this sheet |
| */ |
| @Override |
| public String getSheetName() |
| { |
| return _sh.getSheetName(); |
| } |
| |
| /** |
| * Note - this is not the same as whether the sheet is focused (isActive) |
| * @return <code>true</code> if this sheet is currently selected |
| */ |
| @Override |
| public boolean isSelected() |
| { |
| return _sh.isSelected(); |
| } |
| |
| |
| /** |
| * Sets array formula to specified region for result. |
| * |
| * @param formula text representation of the formula |
| * @param range Region of array formula for result. |
| * @return the {@link CellRange} of cells affected by this change |
| */ |
| @Override |
| public CellRange<? extends Cell> setArrayFormula(String formula, CellRangeAddress range) |
| { |
| return _sh.setArrayFormula(formula, range); |
| } |
| |
| /** |
| * Remove a Array Formula from this sheet. All cells contained in the Array Formula range are removed as well |
| * |
| * @param cell any cell within Array Formula range |
| * @return the {@link CellRange} of cells affected by this change |
| */ |
| @Override |
| public CellRange<? extends Cell> removeArrayFormula(Cell cell) |
| { |
| return _sh.removeArrayFormula(cell); |
| } |
| |
| @Override |
| public DataValidationHelper getDataValidationHelper() |
| { |
| return _sh.getDataValidationHelper(); |
| } |
| |
| @Override |
| public List<XSSFDataValidation> getDataValidations() |
| { |
| return _sh.getDataValidations(); |
| } |
| |
| /** |
| * Creates a data validation object |
| * @param dataValidation The Data validation object settings |
| */ |
| @Override |
| public void addValidationData(DataValidation dataValidation) |
| { |
| _sh.addValidationData(dataValidation); |
| } |
| |
| /** |
| * Enable filtering for a range of cells |
| * |
| * @param range the range of cells to filter |
| */ |
| @Override |
| public AutoFilter setAutoFilter(CellRangeAddress range) |
| { |
| return _sh.setAutoFilter(range); |
| } |
| |
| @Override |
| public SheetConditionalFormatting getSheetConditionalFormatting(){ |
| return _sh.getSheetConditionalFormatting(); |
| } |
| |
| |
| @Override |
| public CellRangeAddress getRepeatingRows() { |
| return _sh.getRepeatingRows(); |
| } |
| |
| @Override |
| public CellRangeAddress getRepeatingColumns() { |
| return _sh.getRepeatingColumns(); |
| } |
| |
| @Override |
| public void setRepeatingRows(CellRangeAddress rowRangeRef) { |
| _sh.setRepeatingRows(rowRangeRef); |
| } |
| |
| @Override |
| public void setRepeatingColumns(CellRangeAddress columnRangeRef) { |
| _sh.setRepeatingColumns(columnRangeRef); |
| } |
| |
| |
| |
| //end of interface implementation |
| /** |
| * Specifies how many rows can be accessed at most via getRow(). |
| * When a new node is created via createRow() and the total number |
| * of unflushed records would exeed the specified value, then the |
| * row with the lowest index value is flushed and cannot be accessed |
| * via getRow() anymore. |
| * A value of -1 indicates unlimited access. In this case all |
| * records that have not been flushed by a call to flush() are available |
| * for random access. |
| * A value of 0 is not allowed because it would flush any newly created row |
| * without having a chance to specify any cells. |
| */ |
| public void setRandomAccessWindowSize(int value) |
| { |
| if(value == 0 || value < -1) { |
| throw new IllegalArgumentException("RandomAccessWindowSize must be either -1 or a positive integer"); |
| } |
| _randomAccessWindowSize=value; |
| } |
| |
| /** |
| * Are all rows flushed to disk? |
| */ |
| public boolean areAllRowsFlushed() { |
| return allFlushed; |
| } |
| /** |
| * @return Last row number to be flushed to disk, or -1 if none flushed yet |
| */ |
| public int getLastFlushedRowNum() { |
| return lastFlushedRowNumber; |
| } |
| |
| /** |
| * Specifies how many rows can be accessed at most via getRow(). |
| * The exeeding rows (if any) are flushed to the disk while rows |
| * with lower index values are flushed first. |
| */ |
| public void flushRows(int remaining) throws IOException |
| { |
| while(_rows.size() > remaining) { |
| flushOneRow(); |
| } |
| if (remaining == 0) { |
| allFlushed = true; |
| } |
| } |
| |
| /** |
| * Flush all rows to disk. After this call no rows can be accessed via getRow() |
| * |
| * @throws IOException |
| */ |
| public void flushRows() throws IOException |
| { |
| this.flushRows(0); |
| } |
| |
| private void flushOneRow() throws IOException |
| { |
| Integer firstRowNum = _rows.firstKey(); |
| if (firstRowNum!=null) { |
| int rowIndex = firstRowNum.intValue(); |
| SXSSFRow row = _rows.get(firstRowNum); |
| // Update the best fit column widths for auto-sizing just before the rows are flushed |
| _autoSizeColumnTracker.updateColumnWidths(row); |
| _writer.writeRow(rowIndex, row); |
| _rows.remove(firstRowNum); |
| lastFlushedRowNumber = rowIndex; |
| } |
| } |
| public void changeRowNum(SXSSFRow row, int newRowNum) |
| { |
| |
| removeRow(row); |
| _rows.put(newRowNum,row); |
| } |
| |
| public int getRowNum(SXSSFRow row) |
| { |
| for(Iterator<Map.Entry<Integer,SXSSFRow>> iter=_rows.entrySet().iterator();iter.hasNext();) |
| { |
| Map.Entry<Integer,SXSSFRow> entry=iter.next(); |
| if(entry.getValue()==row) { |
| return entry.getKey().intValue(); |
| } |
| } |
| return -1; |
| } |
| |
| /** |
| * Deletes the temporary file that backed this sheet on disk. |
| * @return true if the file was deleted, false if it wasn't. |
| */ |
| boolean dispose() throws IOException { |
| if (!allFlushed) { |
| flushRows(); |
| } |
| return _writer.dispose(); |
| } |
| |
| @Override |
| public int getColumnOutlineLevel(int columnIndex) { |
| return _sh.getColumnOutlineLevel(columnIndex); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public CellAddress getActiveCell() { |
| return _sh.getActiveCell(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void setActiveCell(CellAddress address) { |
| _sh.setActiveCell(address); |
| } |
| |
| public XSSFColor getTabColor() { |
| return _sh.getTabColor(); |
| } |
| |
| public void setTabColor(XSSFColor color) { |
| _sh.setTabColor(color); |
| } |
| } |