Author: yegor
Date: Tue May 17 10:46:35 2011
New Revision: 1104120
URL: http://svn.apache.org/viewvc?rev=1104120&view=rev
Log:
Bugzilla 51160: Initial version of SXSSF, a low memory foortprint API to
produce xlsx files
Added:
poi/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java
poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/
poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java
poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
Modified:
poi/trunk/src/documentation/content/xdocs/status.xml
Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL:
http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=1104120&r1=1104119&r2=1104120&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Tue May 17 10:46:35
2011
@@ -34,7 +34,8 @@
<changes>
<release version="3.8-beta3" date="2011-??-??">
- <action dev="poi-developers" type="add">51171 - Improved
performance of opening large .xls files</action>
+ <action dev="poi-developers" type="add">51160 - Initial version of
SXSSF, a low memory foortprint API to produce xlsx files</action>
+ <action dev="poi-developers" type="fix">51171 - Improved
performance of opening large .xls files</action>
<action dev="poi-developers" type="add">51172 - Add XWPF support
for GIF pictures</action>
<action dev="poi-developers" type="add">NPOIFS Mini Streams now
support extending the underlying big block stream to fit more data</action>
<action dev="poi-developers" type="fix">51148 - XWPFDocument now
properly tracks paragraphs and tables when adding/removing them</action>
Added:
poi/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java?rev=1104120&view=auto
==============================================================================
---
poi/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java
(added)
+++
poi/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java
Tue May 17 10:46:35 2011
@@ -0,0 +1,204 @@
+/*
+ * ====================================================================
+ * 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.ss.examples;
+
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SSPerformanceTest {
+ public static void main(String[] args) {
+ if (args.length != 4) usage("need four command arguments");
+
+ String type = args[0];
+ long timeStarted = System.currentTimeMillis();
+ Workbook workBook = createWorkbook(type);
+ boolean isHType = workBook instanceof HSSFWorkbook;
+
+ int rows = parseInt(args[1], "Failed to parse rows value as integer");
+ int cols = parseInt(args[2], "Failed to parse cols value as integer");
+ boolean saveFile = parseInt(args[3], "Failed to parse saveFile value
as integer") != 0;
+
+ Map<String, CellStyle> styles = createStyles(workBook);
+
+ Sheet sheet = workBook.createSheet("Main Sheet");
+
+ Cell headerCell = sheet.createRow(0).createCell(0);
+ headerCell.setCellValue("Header text is spanned across multiple
cells");
+ headerCell.setCellStyle(styles.get("header"));
+ sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$F$1"));
+
+ int sheetNo = 0;
+ int rowIndexInSheet = 1;
+ double value = 0;
+ Calendar calendar = Calendar.getInstance();
+ for (int rowIndex = 0; rowIndex < rows; rowIndex++) {
+ if (isHType && sheetNo != rowIndex / 0x10000) {
+ sheet = workBook.createSheet("Spillover from sheet " +
(++sheetNo));
+ headerCell.setCellValue("Header text is spanned across
multiple cells");
+ headerCell.setCellStyle(styles.get("header"));
+ sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$F$1"));
+ rowIndexInSheet = 1;
+ }
+
+ Row row = sheet.createRow(rowIndexInSheet);
+ for (int colIndex = 0; colIndex < cols; colIndex++) {
+ Cell cell = row.createCell(colIndex);
+ String address = new CellReference(cell).formatAsString();
+ switch (colIndex){
+ case 0:
+ // column A: default number format
+ cell.setCellValue(value++);
+ break;
+ case 1:
+ // column B: #,##0
+ cell.setCellValue(value++);
+ cell.setCellStyle(styles.get("#,##0.00"));
+ break;
+ case 2:
+ // column C: $#,##0.00
+ cell.setCellValue(value++);
+ cell.setCellStyle(styles.get("$#,##0.00"));
+ break;
+ case 3:
+ // column D: red bold text on yellow background
+ cell.setCellValue(address);
+ cell.setCellStyle(styles.get("red-bold"));
+ break;
+ case 4:
+ // column E: boolean
+ // TODO booleans are shown as 1/0 instead of TRUE/FALSE
+ cell.setCellValue(rowIndex % 2 == 0);
+ break;
+ case 5:
+ // column F: date / time
+ cell.setCellValue(calendar);
+ cell.setCellStyle(styles.get("m/d/yyyy"));
+ calendar.roll(Calendar.DAY_OF_YEAR, -1);
+ break;
+ case 6:
+ // column F: formula
+ // TODO formulas are not yet supported in SXSSF
+ //cell.setCellFormula("SUM(A" + (rowIndex+1) + ":E" +
(rowIndex+1)+ ")");
+ //break;
+ default:
+ cell.setCellValue(value++);
+ break;
+ }
+ }
+ rowIndexInSheet++;
+ }
+ if (saveFile) {
+ String fileName = type + "_" + rows + "_" + cols + "." +
getFileSuffix(args[0]);
+ try {
+ FileOutputStream out = new FileOutputStream(fileName);
+ workBook.write(out);
+ out.close();
+ } catch (IOException ioe) {
+ System.err.println("Error: failed to write to file \"" +
fileName + "\", reason=" + ioe.getMessage());
+ }
+ }
+ long timeFinished = System.currentTimeMillis();
+ System.out.println("Elapsed " + (timeFinished-timeStarted)/1000 + "
seconds");
+ }
+
+ static Map<String, CellStyle> createStyles(Workbook wb) {
+ Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
+ CellStyle style;
+
+ Font headerFont = wb.createFont();
+ headerFont.setFontHeightInPoints((short) 14);
+ headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
+ style = wb.createCellStyle();
+ style.setAlignment(CellStyle.ALIGN_CENTER);
+ style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
+ style.setFont(headerFont);
+
style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());
+ style.setFillPattern(CellStyle.SOLID_FOREGROUND);
+ styles.put("header", style);
+
+ Font monthFont = wb.createFont();
+ monthFont.setFontHeightInPoints((short)12);
+ monthFont.setColor(IndexedColors.RED.getIndex());
+ monthFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
+ style = wb.createCellStyle();
+ style.setAlignment(CellStyle.ALIGN_CENTER);
+ style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
+ style.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
+ style.setFillPattern(CellStyle.SOLID_FOREGROUND);
+ style.setFont(monthFont);
+ styles.put("red-bold", style);
+
+ String[] nfmt = {"#,##0.00", "$#,##0.00", "m/d/yyyy"};
+ for(String fmt : nfmt){
+ style = wb.createCellStyle();
+ style.setDataFormat(wb.createDataFormat().getFormat(fmt));
+ styles.put(fmt, style);
+ }
+
+ return styles;
+ }
+
+
+ static void usage(String message) {
+ System.err.println(message);
+ System.err.println("usage: java SSPerformanceTest HSSF|XSSF|SXSSF rows
cols saveFile (0|1)? ");
+ System.exit(1);
+ }
+
+ static Workbook createWorkbook(String type) {
+ if ("HSSF".equals(type))
+ return new HSSFWorkbook();
+ else if ("XSSF".equals(type))
+ return new XSSFWorkbook();
+ else if ("SXSSF".equals(type))
+ return new SXSSFWorkbook();
+ else
+ usage("Unknown type \"" + type + "\"");
+ return null;
+ }
+
+ static String getFileSuffix(String type) {
+ if ("HSSF".equals(type))
+ return "xls";
+ else if ("XSSF".equals(type))
+ return "xlsx";
+ else if ("SXSSF".equals(type))
+ return "xlsx";
+ return null;
+ }
+
+ static int parseInt(String value, String msg) {
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ usage(msg);
+ }
+ return 0;
+ }
+}
Added: poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java?rev=1104120&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
(added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java Tue
May 17 10:46:35 2011
@@ -0,0 +1,1013 @@
+/* ====================================================================
+ 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.util.Calendar;
+import java.util.Date;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.RichTextString;
+import org.apache.poi.ss.usermodel.Comment;
+import org.apache.poi.ss.usermodel.Hyperlink;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.ss.formula.FormulaParseException;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+/**
+ * Streaming version of XSSFRow implementing the "BigGridDemo" strategy.
+ *
+ * @author Alex Geller, Four J's Development Tools
+*/
+public class SXSSFCell implements Cell
+{
+
+ SXSSFRow _row;
+ Value _value;
+ CellStyle _style;
+ Property _firstProperty;
+
+ public SXSSFCell(SXSSFRow row,int cellType)
+ {
+ _row=row;
+ setType(cellType);
+ }
+
+//start of interface implementation
+
+ /**
+ * Returns column index of this cell
+ *
+ * @return zero-based column index of a column in a sheet.
+ */
+ public int getColumnIndex()
+ {
+ return _row.getCellIndex(this);
+ }
+
+ /**
+ * Returns row index of a row in the sheet that contains this cell
+ *
+ * @return zero-based row index of a row in the sheet that contains this
cell
+ */
+ public int getRowIndex()
+ {
+ return _row.getRowNum();
+ }
+
+ /**
+ * Returns the sheet this cell belongs to
+ *
+ * @return the sheet this cell belongs to
+ */
+ public Sheet getSheet()
+ {
+ return _row.getSheet();
+ }
+
+ /**
+ * Returns the Row this cell belongs to
+ *
+ * @return the Row that owns this cell
+ */
+ public Row getRow()
+ {
+ return _row;
+ }
+
+ /**
+ * Set the cells type (numeric, formula or string)
+ *
+ * @throws IllegalArgumentException if the specified cell type is invalid
+ * @see #CELL_TYPE_NUMERIC
+ * @see #CELL_TYPE_STRING
+ * @see #CELL_TYPE_FORMULA
+ * @see #CELL_TYPE_BLANK
+ * @see #CELL_TYPE_BOOLEAN
+ * @see #CELL_TYPE_ERROR
+ */
+ public void setCellType(int cellType)
+ {
+ ensureType(cellType);
+ }
+
+ /**
+ * Return the cell type.
+ *
+ * @return the cell type
+ * @see Cell#CELL_TYPE_BLANK
+ * @see Cell#CELL_TYPE_NUMERIC
+ * @see Cell#CELL_TYPE_STRING
+ * @see Cell#CELL_TYPE_FORMULA
+ * @see Cell#CELL_TYPE_BOOLEAN
+ * @see Cell#CELL_TYPE_ERROR
+ */
+ public int getCellType()
+ {
+ return _value.getType();
+ }
+
+ /**
+ * Only valid for formula cells
+ * @return one of ({@link #CELL_TYPE_NUMERIC}, {@link #CELL_TYPE_STRING},
+ * {@link #CELL_TYPE_BOOLEAN}, {@link #CELL_TYPE_ERROR}) depending
+ * on the cached value of the formula
+ */
+ public int getCachedFormulaResultType()
+ {
+//TODO: Implement this correctly
+ assert false;
+ return CELL_TYPE_NUMERIC;
+ }
+
+ /**
+ * Set a numeric value for the cell
+ *
+ * @param value the numeric value to set this cell to. For formulas
we'll set the
+ * precalculated value, for numerics we'll set its value. For other
types we
+ * will change the cell to a numeric cell and set its value.
+ */
+ public void setCellValue(double value)
+ {
+ ensureTypeOrFormulaType(CELL_TYPE_NUMERIC);
+ if(_value.getType()==CELL_TYPE_FORMULA)
+ ((NumericFormulaValue)_value).setPreEvaluatedValue(value);
+ else
+ ((NumericValue)_value).setValue(value);
+ }
+
+ /**
+ * Converts the supplied date to its equivalent Excel numeric value and
sets
+ * that into the cell.
+ * <p/>
+ * <b>Note</b> - There is actually no 'DATE' cell type in Excel. In many
+ * cases (when entering date values), Excel automatically adjusts the
+ * <i>cell style</i> to some date format, creating the illusion that the
cell
+ * data type is now something besides {@link Cell#CELL_TYPE_NUMERIC}. POI
+ * does not attempt to replicate this behaviour. To make a numeric cell
+ * display as a date, use {@link #setCellStyle(CellStyle)} etc.
+ *
+ * @param value the numeric value to set this cell to. For formulas we'll
set the
+ * precalculated value, for numerics we'll set its value. For other
types we
+ * will change the cell to a numerics cell and set its value.
+ */
+ public void setCellValue(Date value)
+ {
+//TODO: activate this when compiling against 3.7.
+ //boolean date1904 = getSheet().getXSSFWorkbook().isDate1904();
+ boolean date1904 = false;
+ setCellValue(DateUtil.getExcelDate(value, date1904));
+ }
+
+ /**
+ * Set a date value for the cell. Excel treats dates as numeric so you
will need to format the cell as
+ * a date.
+ * <p>
+ * This will set the cell value based on the Calendar's timezone. As Excel
+ * does not support timezones this means that both 20:00+03:00 and
+ * 20:00-03:00 will be reported as the same value (20:00) even that there
+ * are 6 hours difference between the two times. This difference can be
+ * preserved by using <code>setCellValue(value.getTime())</code> which will
+ * automatically shift the times to the default timezone.
+ * </p>
+ *
+ * @param value the date value to set this cell to. For formulas we'll
set the
+ * precalculated value, for numerics we'll set its value. For
othertypes we
+ * will change the cell to a numeric cell and set its value.
+ */
+ public void setCellValue(Calendar value)
+ {
+//TODO: activate this when compiling against 3.7.
+ //boolean date1904 = getSheet().getXSSFWorkbook().isDate1904();
+ boolean date1904 = false;
+ setCellValue( DateUtil.getExcelDate(value, date1904 ));
+ }
+
+ /**
+ * Set a rich string value for the cell.
+ *
+ * @param value value to set the cell to. For formulas we'll set the
formula
+ * string, for String cells we'll set its value. For other types we will
+ * change the cell to a string cell and set its value.
+ * If value is null then we will change the cell to a Blank cell.
+ */
+ public void setCellValue(RichTextString value)
+ {
+ ensureRichTextStringType();
+ ((RichTextValue)_value).setValue(value);
+ }
+
+ /**
+ * Set a string value for the cell.
+ *
+ * @param value value to set the cell to. For formulas we'll set the
formula
+ * string, for String cells we'll set its value. For other types we will
+ * change the cell to a string cell and set its value.
+ * If value is null then we will change the cell to a Blank cell.
+ */
+ public void setCellValue(String value)
+ {
+ ensureTypeOrFormulaType(CELL_TYPE_STRING);
+ if(_value.getType()==CELL_TYPE_FORMULA)
+ ((StringFormulaValue)_value).setPreEvaluatedValue(value);
+ else
+ ((PlainStringValue)_value).setValue(value);
+ }
+
+ /**
+ * Sets formula for this cell.
+ * <p>
+ * Note, this method only sets the formula string and does not calculate
the formula value.
+ * To set the precalculated value use {@link #setCellValue(double)} or
{@link #setCellValue(String)}
+ * </p>
+ *
+ * @param formula the formula to set, e.g. <code>"SUM(C4:E4)"</code>.
+ * If the argument is <code>null</code> then the current formula is
removed.
+ * @throws FormulaParseException if the formula has incorrect syntax or is
otherwise invalid
+ */
+ public void setCellFormula(String formula) throws FormulaParseException
+ {
+ ensureFormulaType(computeTypeFromFormula(formula));
+ ((FormulaValue)_value).setValue(formula);
+ }
+ /**
+ * Return a formula for the cell, for example, <code>SUM(C4:E4)</code>
+ *
+ * @return a formula for the cell
+ * @throws IllegalStateException if the cell type returned by {@link
#getCellType()} is not CELL_TYPE_FORMULA
+ */
+ public String getCellFormula()
+ {
+ if(_value.getType()!=CELL_TYPE_FORMULA)
+ throw typeMismatch(CELL_TYPE_FORMULA,_value.getType(),false);
+ return ((FormulaValue)_value).getValue();
+ }
+
+ /**
+ * Get the value of the cell as a number.
+ * <p>
+ * For strings we throw an exception. For blank cells we return a 0.
+ * For formulas or error cells we return the precalculated value;
+ * </p>
+ * @return the value of the cell as a number
+ * @throws IllegalStateException if the cell type returned by {@link
#getCellType()} is CELL_TYPE_STRING
+ * @exception NumberFormatException if the cell value isn't a parsable
<code>double</code>.
+ * @see org.apache.poi.ss.usermodel.DataFormatter for turning this number
into a string similar to that which Excel would render this number as.
+ */
+ public double getNumericCellValue()
+ {
+ int cellType = getCellType();
+ switch(cellType)
+ {
+ case CELL_TYPE_BLANK:
+ return 0.0;
+ case CELL_TYPE_FORMULA:
+ {
+ FormulaValue fv=(FormulaValue)_value;
+ if(fv.getFormulaType()!=CELL_TYPE_NUMERIC)
+ throw typeMismatch(CELL_TYPE_NUMERIC, CELL_TYPE_FORMULA,
false);
+ return ((NumericFormulaValue)_value).getPreEvaluatedValue();
+ }
+ case CELL_TYPE_NUMERIC:
+ return ((NumericValue)_value).getValue();
+ default:
+ throw typeMismatch(CELL_TYPE_NUMERIC, cellType, false);
+ }
+ }
+
+ /**
+ * Get the value of the cell as a date.
+ * <p>
+ * For strings we throw an exception. For blank cells we return a null.
+ * </p>
+ * @return the value of the cell as a date
+ * @throws IllegalStateException if the cell type returned by {@link
#getCellType()} is CELL_TYPE_STRING
+ * @exception NumberFormatException if the cell value isn't a parsable
<code>double</code>.
+ * @see org.apache.poi.ss.usermodel.DataFormatter for formatting this
date into a string similar to how excel does.
+ */
+ public Date getDateCellValue()
+ {
+ int cellType = getCellType();
+ if (cellType == CELL_TYPE_BLANK)
+ {
+ return null;
+ }
+
+ double value = getNumericCellValue();
+//TODO: activate this when compiling against 3.7.
+ //boolean date1904 = getSheet().getXSSFWorkbook().isDate1904();
+ boolean date1904 = false;
+ return DateUtil.getJavaDate(value, date1904);
+ }
+
+ /**
+ * Get the value of the cell as a XSSFRichTextString
+ * <p>
+ * For numeric cells we throw an exception. For blank cells we return an
empty string.
+ * For formula cells we return the pre-calculated value if a string,
otherwise an exception.
+ * </p>
+ * @return the value of the cell as a XSSFRichTextString
+ */
+ public RichTextString getRichStringCellValue()
+ {
+ int cellType = getCellType();
+
if(!(getCellType()==CELL_TYPE_STRING&&((StringValue)_value).isRichText()))
+ throw typeMismatch(CELL_TYPE_STRING, cellType, false);
+ return ((RichTextValue)_value).getValue();
+ }
+
+
+ /**
+ * Get the value of the cell as a string
+ * <p>
+ * For numeric cells we throw an exception. For blank cells we return an
empty string.
+ * For formulaCells that are not string Formulas, we throw an exception.
+ * </p>
+ * @return the value of the cell as a string
+ */
+ public String getStringCellValue()
+ {
+ int cellType = getCellType();
+ switch(cellType)
+ {
+ case CELL_TYPE_BLANK:
+ return "";
+ case CELL_TYPE_FORMULA:
+ {
+ FormulaValue fv=(FormulaValue)_value;
+ if(fv.getFormulaType()!=CELL_TYPE_STRING)
+ throw typeMismatch(CELL_TYPE_STRING, CELL_TYPE_FORMULA,
false);
+ return ((StringFormulaValue)_value).getPreEvaluatedValue();
+ }
+ case CELL_TYPE_STRING:
+ {
+ if(((StringValue)_value).isRichText())
+ return ((RichTextValue)_value).getValue().getString();
+ else
+ return ((PlainStringValue)_value).getValue();
+ }
+ default:
+ throw typeMismatch(CELL_TYPE_STRING, cellType, false);
+ }
+ }
+
+ /**
+ * Set a boolean value for the cell
+ *
+ * @param value the boolean value to set this cell to. For formulas we'll
set the
+ * precalculated value, for booleans we'll set its value. For other
types we
+ * will change the cell to a boolean cell and set its value.
+ */
+ public void setCellValue(boolean value)
+ {
+ ensureTypeOrFormulaType(CELL_TYPE_BOOLEAN);
+ if(_value.getType()==CELL_TYPE_FORMULA)
+ ((BooleanFormulaValue)_value).setPreEvaluatedValue(value);
+ else
+ ((BooleanValue)_value).setValue(value);
+ }
+
+ /**
+ * Set a error value for the cell
+ *
+ * @param value the error value to set this cell to. For formulas we'll
set the
+ * precalculated value , for errors we'll set
+ * its value. For other types we will change the cell to an error
+ * cell and set its value.
+ * @see org.apache.poi.ss.usermodel.FormulaError
+ */
+ public void setCellErrorValue(byte value)
+ {
+ ensureType(CELL_TYPE_ERROR);
+ if(_value.getType()==CELL_TYPE_FORMULA)
+ ((ErrorFormulaValue)_value).setPreEvaluatedValue(value);
+ else
+ ((ErrorValue)_value).setValue(value);
+ }
+
+ /**
+ * Get the value of the cell as a boolean.
+ * <p>
+ * For strings, numbers, and errors, we throw an exception. For blank
cells we return a false.
+ * </p>
+ * @return the value of the cell as a boolean
+ * @throws IllegalStateException if the cell type returned by {@link
#getCellType()}
+ * is not CELL_TYPE_BOOLEAN, CELL_TYPE_BLANK or CELL_TYPE_FORMULA
+ */
+ public boolean getBooleanCellValue()
+ {
+ int cellType = getCellType();
+ switch(cellType)
+ {
+ case CELL_TYPE_BLANK:
+ return false;
+ case CELL_TYPE_FORMULA:
+ {
+ FormulaValue fv=(FormulaValue)_value;
+ if(fv.getFormulaType()!=CELL_TYPE_BOOLEAN)
+ throw typeMismatch(CELL_TYPE_BOOLEAN, CELL_TYPE_FORMULA,
false);
+ return ((BooleanFormulaValue)_value).getPreEvaluatedValue();
+ }
+ case CELL_TYPE_BOOLEAN:
+ {
+ return ((BooleanValue)_value).getValue();
+ }
+ default:
+ throw typeMismatch(CELL_TYPE_BOOLEAN, cellType, false);
+ }
+ }
+
+ /**
+ * Get the value of the cell as an error code.
+ * <p>
+ * For strings, numbers, and booleans, we throw an exception.
+ * For blank cells we return a 0.
+ * </p>
+ *
+ * @return the value of the cell as an error code
+ * @throws IllegalStateException if the cell type returned by {@link
#getCellType()} isn't CELL_TYPE_ERROR
+ * @see org.apache.poi.ss.usermodel.FormulaError for error codes
+ */
+ public byte getErrorCellValue()
+ {
+ int cellType = getCellType();
+ switch(cellType)
+ {
+ case CELL_TYPE_BLANK:
+ return 0;
+ case CELL_TYPE_FORMULA:
+ {
+ FormulaValue fv=(FormulaValue)_value;
+ if(fv.getFormulaType()!=CELL_TYPE_ERROR)
+ throw typeMismatch(CELL_TYPE_ERROR, CELL_TYPE_FORMULA,
false);
+ return ((ErrorFormulaValue)_value).getPreEvaluatedValue();
+ }
+ case CELL_TYPE_ERROR:
+ {
+ return ((ErrorValue)_value).getValue();
+ }
+ default:
+ throw typeMismatch(CELL_TYPE_ERROR, cellType, false);
+ }
+ }
+
+ /**
+ * Set the style for the cell. The style should be an CellStyle
created/retreived from
+ * the Workbook.
+ *
+ * @param style reference contained in the workbook.
+ * If the value is null then the style information is removed causing the
cell to used the default workbook style.
+ * @see org.apache.poi.ss.usermodel.Workbook#createCellStyle()
+ */
+ public void setCellStyle(CellStyle style)
+ {
+ _style=style;
+ }
+
+ /**
+ * Return the cell's style.
+ *
+ * @return the cell's style. Always not-null. Default cell style has zero
index and can be obtained as
+ * <code>workbook.getCellStyleAt(0)</code>
+ * @see org.apache.poi.ss.usermodel.Workbook#getCellStyleAt(short)
+ */
+ public CellStyle getCellStyle()
+ {
+ return _style;
+ }
+
+ /**
+ * Sets this cell as the active cell for the worksheet
+ */
+ public void setAsActiveCell()
+ {
+//TODO: What needs to be done here? Is there a "the active cell" at the sheet
or even the workbook level?
+ //getRow().setAsActiveCell(this);
+ }
+
+ /**
+ * Assign a comment to this cell
+ *
+ * @param comment comment associated with this cell
+ */
+ public void setCellComment(Comment comment)
+ {
+ setProperty(Property.COMMENT,comment);
+ }
+
+ /**
+ * Returns comment associated with this cell
+ *
+ * @return comment associated with this cell or <code>null</code> if not
found
+ */
+ public Comment getCellComment()
+ {
+ return (Comment)getPropertyValue(Property.COMMENT);
+ }
+
+ /**
+ * Removes the comment for this cell, if there is one.
+ */
+ public void removeCellComment()
+ {
+ removeProperty(Property.COMMENT);
+ }
+
+ /**
+ * @return hyperlink associated with this cell or <code>null</code> if not
found
+ */
+ public Hyperlink getHyperlink()
+ {
+ return (Hyperlink)getPropertyValue(Property.HYPERLINK);
+ }
+
+ /**
+ * Assign a hyperlink to this cell
+ *
+ * @param link hyperlink associated with this cell
+ */
+ public void setHyperlink(Hyperlink link)
+ {
+ setProperty(Property.HYPERLINK,link);
+ }
+
+ /**
+ * Only valid for array formula cells
+ *
+ * @return range of the array formula group that the cell belongs to.
+ */
+//TODO: What is this?
+ public CellRangeAddress getArrayFormulaRange()
+ {
+ return null;
+ }
+
+ /**
+ * @return <code>true</code> if this cell is part of group of cells having
a common array formula.
+ */
+//TODO: What is this?
+ public boolean isPartOfArrayFormulaGroup()
+ {
+ return false;
+ }
+//end of interface implementation
+
+ void removeProperty(int type)
+ {
+ Property current=_firstProperty;
+ Property previous=null;
+ while(current!=null&¤t.getType()!=type)
+ {
+ previous=current;
+ current=current._next;
+ }
+ if(current!=null)
+ {
+ if(previous!=null)
+ {
+ previous._next=current._next;
+ }
+ else
+ {
+ _firstProperty=current._next;
+ }
+ }
+ }
+ void setProperty(int type,Object value)
+ {
+ Property current=_firstProperty;
+ Property previous=null;
+ while(current!=null&¤t.getType()!=type)
+ {
+ previous=current;
+ current=current._next;
+ }
+ if(current!=null)
+ {
+ current.setValue(value);
+ }
+ else
+ {
+ switch(type)
+ {
+ case Property.COMMENT:
+ {
+ current=new CommentProperty(value);
+ break;
+ }
+ case Property.HYPERLINK:
+ {
+ current=new HyperlinkProperty(value);
+ break;
+ }
+ }
+ if(previous!=null)
+ {
+ previous._next=current;
+ }
+ else
+ {
+ _firstProperty=current;
+ }
+ }
+ }
+ Object getPropertyValue(int type)
+ {
+ return getPropertyValue(type,null);
+ }
+ Object getPropertyValue(int type,String defaultValue)
+ {
+ Property current=_firstProperty;
+ while(current!=null&¤t.getType()!=type) current=current._next;
+ return current==null?defaultValue:current.getValue();
+ }
+ void ensurePlainStringType()
+ {
+ if(_value.getType()!=CELL_TYPE_STRING
+ ||((StringValue)_value).isRichText())
+ _value=new PlainStringValue();
+ }
+ void ensureRichTextStringType()
+ {
+ if(_value.getType()!=CELL_TYPE_STRING
+ ||!((StringValue)_value).isRichText())
+ _value=new RichTextValue();
+ }
+ void ensureType(int type)
+ {
+ if(_value.getType()!=type)
+ setType(type);
+ }
+ void ensureFormulaType(int type)
+ {
+ if(_value.getType()!=CELL_TYPE_FORMULA
+ ||((FormulaValue)_value).getFormulaType()!=type)
+ setFormulaType(type);
+ }
+ void ensureTypeOrFormulaType(int type)
+ {
+ assert type==CELL_TYPE_NUMERIC||
+ type==CELL_TYPE_STRING||
+ type==CELL_TYPE_BOOLEAN||
+ type==CELL_TYPE_ERROR;
+ if(_value.getType()==type)
+ {
+ if(type==CELL_TYPE_STRING&&((StringValue)_value).isRichText())
+ setType(CELL_TYPE_STRING);
+ return;
+ }
+ if(_value.getType()==CELL_TYPE_FORMULA)
+ {
+ if(((FormulaValue)_value).getFormulaType()==type)
+ return;
+ setFormulaType(type); // once a formula, always a formula
+ return;
+ }
+ setType(type);
+ }
+ void setType(int type)
+ {
+ switch(type)
+ {
+ case CELL_TYPE_NUMERIC:
+ {
+ _value=new NumericValue();
+ break;
+ }
+ case CELL_TYPE_STRING:
+ {
+ _value=new PlainStringValue();
+ break;
+ }
+ case CELL_TYPE_FORMULA:
+ {
+ _value=new NumericFormulaValue();
+ break;
+ }
+ case CELL_TYPE_BLANK:
+ {
+ _value=new BlankValue();
+ break;
+ }
+ case CELL_TYPE_BOOLEAN:
+ {
+ _value=new BooleanValue();
+ break;
+ }
+ case CELL_TYPE_ERROR:
+ {
+ _value=new ErrorValue();
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("Illegal type " + type);
+ }
+ }
+ }
+ void setFormulaType(int type)
+ {
+ switch(type)
+ {
+ case CELL_TYPE_NUMERIC:
+ {
+ _value=new NumericFormulaValue();
+ break;
+ }
+ case CELL_TYPE_STRING:
+ {
+ _value=new StringFormulaValue();
+ break;
+ }
+ case CELL_TYPE_BOOLEAN:
+ {
+ _value=new BooleanFormulaValue();
+ break;
+ }
+ case CELL_TYPE_ERROR:
+ {
+ _value=new ErrorFormulaValue();
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("Illegal type " + type);
+ }
+ }
+ }
+//TODO: implement this correctly
+ int computeTypeFromFormula(String formula)
+ {
+ return CELL_TYPE_NUMERIC;
+ }
+//COPIED FROM
https://svn.apache.org/repos/asf/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
since the functions are declared private there
+ /**
+ * Used to help format error messages
+ */
+ private static RuntimeException typeMismatch(int expectedTypeCode, int
actualTypeCode, boolean isFormulaCell) {
+ String msg = "Cannot get a "
+ + getCellTypeName(expectedTypeCode) + " value from a "
+ + getCellTypeName(actualTypeCode) + " " + (isFormulaCell ?
"formula " : "") + "cell";
+ return new IllegalStateException(msg);
+ }
+/**
+ * Used to help format error messages
+ */
+ private static String getCellTypeName(int cellTypeCode) {
+ switch (cellTypeCode) {
+ case CELL_TYPE_BLANK: return "blank";
+ case CELL_TYPE_STRING: return "text";
+ case CELL_TYPE_BOOLEAN: return "boolean";
+ case CELL_TYPE_ERROR: return "error";
+ case CELL_TYPE_NUMERIC: return "numeric";
+ case CELL_TYPE_FORMULA: return "formula";
+ }
+ return "#unknown cell type (" + cellTypeCode + ")#";
+ }
+//END OF COPIED CODE
+
+ static abstract class Property
+ {
+ final static int COMMENT=1;
+ final static int HYPERLINK=2;
+ Object _value;
+ Property _next;
+ public Property(Object value)
+ {
+ _value=value;
+ }
+ abstract int getType();
+ void setValue(Object value)
+ {
+ _value=value;
+ }
+ Object getValue()
+ {
+ return _value;
+ }
+ }
+ static class CommentProperty extends Property
+ {
+ public CommentProperty(Object value)
+ {
+ super(value);
+ }
+ public int getType()
+ {
+ return COMMENT;
+ }
+ }
+ static class HyperlinkProperty extends Property
+ {
+ public HyperlinkProperty(Object value)
+ {
+ super(value);
+ }
+ public int getType()
+ {
+ return HYPERLINK;
+ }
+ }
+ interface Value
+ {
+ int getType();
+ }
+ static class NumericValue implements Value
+ {
+ double _value;
+ public int getType()
+ {
+ return CELL_TYPE_NUMERIC;
+ }
+ void setValue(double value)
+ {
+ _value=value;
+ }
+ double getValue()
+ {
+ return _value;
+ }
+ }
+ static abstract class StringValue implements Value
+ {
+ public int getType()
+ {
+ return CELL_TYPE_STRING;
+ }
+//We cannot introduce a new type CELL_TYPE_RICH_TEXT because the types are
public so we have to make rich text as a type of string
+ abstract boolean isRichText(); // using the POI style which seems to
avoid "instanceof".
+ }
+ static class PlainStringValue extends StringValue
+ {
+ String _value;
+ void setValue(String value)
+ {
+ _value=value;
+ }
+ String getValue()
+ {
+ return _value;
+ }
+ boolean isRichText()
+ {
+ return false;
+ }
+ }
+ static class RichTextValue implements Value
+ {
+ RichTextString _value;
+ public int getType()
+ {
+ return CELL_TYPE_STRING;
+ }
+ void setValue(RichTextString value)
+ {
+ _value=value;
+ }
+ RichTextString getValue()
+ {
+ return _value;
+ }
+ boolean isRichText()
+ {
+ return true;
+ }
+ }
+ static abstract class FormulaValue implements Value
+ {
+ String _value;
+ public int getType()
+ {
+ return CELL_TYPE_FORMULA;
+ }
+ void setValue(String value)
+ {
+ _value=value;
+ }
+ String getValue()
+ {
+ return _value;
+ }
+ abstract int getFormulaType();
+ }
+ static class NumericFormulaValue extends FormulaValue
+ {
+ double _preEvaluatedValue;
+ int getFormulaType()
+ {
+ return CELL_TYPE_NUMERIC;
+ }
+ void setPreEvaluatedValue(double value)
+ {
+ _preEvaluatedValue=value;
+ }
+ double getPreEvaluatedValue()
+ {
+ return _preEvaluatedValue;
+ }
+ }
+ static class StringFormulaValue extends FormulaValue
+ {
+ String _preEvaluatedValue;
+ int getFormulaType()
+ {
+ return CELL_TYPE_STRING;
+ }
+ void setPreEvaluatedValue(String value)
+ {
+ _preEvaluatedValue=value;
+ }
+ String getPreEvaluatedValue()
+ {
+ return _preEvaluatedValue;
+ }
+ }
+ static class BooleanFormulaValue extends FormulaValue
+ {
+ boolean _preEvaluatedValue;
+ int getFormulaType()
+ {
+ return CELL_TYPE_BOOLEAN;
+ }
+ void setPreEvaluatedValue(boolean value)
+ {
+ _preEvaluatedValue=value;
+ }
+ boolean getPreEvaluatedValue()
+ {
+ return _preEvaluatedValue;
+ }
+ }
+ static class ErrorFormulaValue extends FormulaValue
+ {
+ byte _preEvaluatedValue;
+ int getFormulaType()
+ {
+ return CELL_TYPE_ERROR;
+ }
+ void setPreEvaluatedValue(byte value)
+ {
+ _preEvaluatedValue=value;
+ }
+ byte getPreEvaluatedValue()
+ {
+ return _preEvaluatedValue;
+ }
+ }
+ static class BlankValue implements Value
+ {
+ public int getType()
+ {
+ return CELL_TYPE_BLANK;
+ }
+ }
+ static class BooleanValue implements Value
+ {
+ boolean _value;
+ public int getType()
+ {
+ return CELL_TYPE_BOOLEAN;
+ }
+ void setValue(boolean value)
+ {
+ _value=value;
+ }
+ boolean getValue()
+ {
+ return _value;
+ }
+ }
+ static class ErrorValue implements Value
+ {
+ byte _value;
+ public int getType()
+ {
+ return CELL_TYPE_ERROR;
+ }
+ void setValue(byte value)
+ {
+ _value=value;
+ }
+ byte getValue()
+ {
+ return _value;
+ }
+ }
+}
Added: poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java?rev=1104120&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java Tue
May 17 10:46:35 2011
@@ -0,0 +1,388 @@
+/* ====================================================================
+ 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 org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Streaming version of XSSFRow implementing the "BigGridDemo" strategy.
+ *
+ * @author Alex Geller, Four J's Development Tools
+*/
+public class SXSSFRow implements Row
+{
+ SXSSFSheet _sheet;
+ SXSSFCell[] _cells;
+ int _maxColumn=-1;
+ short _height=-1;
+//TODO: Need to set the correct default value for _zHeight
+ boolean _zHeight;
+
+ public SXSSFRow(SXSSFSheet sheet, int initialSize)
+ {
+ _sheet=sheet;
+ _cells=new SXSSFCell[initialSize];
+ }
+ public Iterator<Cell> allCellsIterator()
+ {
+ return new CellIterator();
+ }
+ public boolean hasCustomHeight()
+ {
+ return _height!=-1;
+ }
+//begin of interface implementation
+ public Iterator<Cell> iterator()
+ {
+ return new FilledCellIterator();
+ }
+
+ /**
+ * Use this to create new cells within the row and return it.
+ * <p>
+ * The cell that is returned is a {@link Cell#CELL_TYPE_BLANK}. The type
can be changed
+ * either through calling <code>setCellValue</code> or
<code>setCellType</code>.
+ *
+ * @param column - the column number this cell represents
+ * @return Cell a high level representation of the created cell.
+ * @throws IllegalArgumentException if columnIndex < 0 or greater than the
maximum number of supported columns
+ * (255 for *.xls, 1048576 for *.xlsx)
+ */
+ public Cell createCell(int column)
+ {
+ return createCell(column,Cell.CELL_TYPE_BLANK);
+ }
+
+ /**
+ * Use this to create new cells within the row and return it.
+ * <p>
+ * The cell that is returned is a {@link Cell#CELL_TYPE_BLANK}. The type
can be changed
+ * either through calling setCellValue or setCellType.
+ *
+ * @param column - the column number this cell represents
+ * @return Cell a high level representation of the created cell.
+ * @throws IllegalArgumentException if columnIndex < 0 or greate than a
maximum number of supported columns
+ * (255 for *.xls, 1048576 for *.xlsx)
+ */
+ public Cell createCell(int column, int type)
+ {
+ if(column>=_cells.length)
+ {
+ SXSSFCell[] newCells=new
SXSSFCell[Math.max(column+1,_cells.length*2)];
+ System.arraycopy(_cells,0,newCells,0,_cells.length);
+ _cells=newCells;
+ }
+ _cells[column]=new SXSSFCell(this,type);
+ if(column>_maxColumn) _maxColumn=column;
+ return _cells[column];
+ }
+
+ /**
+ * Remove the Cell from this row.
+ *
+ * @param cell the cell to remove
+ */
+ public void removeCell(Cell cell)
+ {
+ int index=getCellIndex(cell);
+ if(index>=0)
+ {
+ _cells[index]=null;
+ while(_maxColumn>=0&&_cells[_maxColumn]==null) _maxColumn--;
+ }
+ }
+
+ int getCellIndex(Cell cell)
+ {
+ for(int i=0;i<=_maxColumn;i++)
+ {
+ if(_cells[i]==cell) return i;
+ }
+ return -1;
+ }
+
+ /**
+ * Set the row number of this row.
+ *
+ * @param rowNum the row number (0-based)
+ * @throws IllegalArgumentException if rowNum < 0
+ */
+ public void setRowNum(int rowNum)
+ {
+ _sheet.changeRowNum(this,rowNum);
+ }
+
+ /**
+ * Get row number this row represents
+ *
+ * @return the row number (0 based)
+ */
+ public int getRowNum()
+ {
+ return _sheet.getRowNum(this);
+ }
+
+ /**
+ * Get the cell representing a given column (logical cell) 0-based. If you
+ * ask for a cell that is not defined....you get a null.
+ *
+ * @param cellnum 0 based column number
+ * @return Cell representing that column or null if undefined.
+ * @see #getCell(int, org.apache.poi.ss.usermodel.Row.MissingCellPolicy)
+ */
+ public Cell getCell(int cellnum)
+ {
+ return cellnum>_maxColumn?null:_cells[cellnum];
+ }
+
+ /**
+ * Returns the cell at the given (0 based) index, with the specified
{@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy}
+ *
+ * @return the cell at the given (0 based) index
+ * @throws IllegalArgumentException if cellnum < 0 or the specified
MissingCellPolicy is invalid
+ * @see Row#RETURN_NULL_AND_BLANK
+ * @see Row#RETURN_BLANK_AS_NULL
+ * @see Row#CREATE_NULL_AS_BLANK
+ */
+ public Cell getCell(int cellnum, MissingCellPolicy policy)
+ {
+ assert false;
+ Cell cell = getCell(cellnum);
+ if(policy == RETURN_NULL_AND_BLANK)
+ {
+ return cell;
+ }
+ if(policy == RETURN_BLANK_AS_NULL)
+ {
+ if(cell == null) return cell;
+ if(cell.getCellType() == Cell.CELL_TYPE_BLANK)
+ {
+ return null;
+ }
+ return cell;
+ }
+ if(policy == CREATE_NULL_AS_BLANK)
+ {
+ if(cell == null)
+ {
+ return createCell(cellnum, Cell.CELL_TYPE_BLANK);
+ }
+ return cell;
+ }
+ throw new IllegalArgumentException("Illegal policy " + policy + " (" +
policy.id + ")");
+ }
+
+ /**
+ * Get the number of the first cell contained in this row.
+ *
+ * @return short representing the first logical cell in the row,
+ * or -1 if the row does not contain any cells.
+ */
+ public short getFirstCellNum()
+ {
+ for(int i=0;i<=_maxColumn;i++)
+ if(_cells[i]!=null) return (short)i;
+ return -1;
+ }
+
+ /**
+ * Gets the index of the last cell contained in this row <b>PLUS ONE</b>.
The result also
+ * happens to be the 1-based column number of the last cell. This value
can be used as a
+ * standard upper bound when iterating over cells:
+ * <pre>
+ * short minColIx = row.getFirstCellNum();
+ * short maxColIx = row.getLastCellNum();
+ * for(short colIx=minColIx; colIx<maxColIx; colIx++) {
+ * Cell cell = row.getCell(colIx);
+ * if(cell == null) {
+ * continue;
+ * }
+ * //... do something with cell
+ * }
+ * </pre>
+ *
+ * @return short representing the last logical cell in the row <b>PLUS
ONE</b>,
+ * or -1 if the row does not contain any cells.
+ */
+ public short getLastCellNum()
+ {
+ return (short)(_maxColumn+1);
+ }
+
+ /**
+ * Gets the number of defined cells (NOT number of cells in the actual
row!).
+ * That is to say if only columns 0,4,5 have values then there would be 3.
+ *
+ * @return int representing the number of defined cells in the row.
+ */
+ public int getPhysicalNumberOfCells()
+ {
+ int count=0;
+ for(int i=0;i<=_maxColumn;i++)
+ {
+ if(_cells[i]!=null) count++;
+ }
+ return count;
+ }
+
+ /**
+ * Set the row's height or set to ff (-1) for undefined/default-height.
Set the height in "twips" or
+ * 1/20th of a point.
+ *
+ * @param height rowheight or 0xff for undefined (use sheet default)
+ */
+ public void setHeight(short height)
+ {
+ _height=height;
+ }
+
+ /**
+ * Set whether or not to display this row with 0 height
+ *
+ * @param zHeight height is zero or not.
+ */
+ public void setZeroHeight(boolean zHeight)
+ {
+ _zHeight=zHeight;
+ }
+
+ /**
+ * Get whether or not to display this row with 0 height
+ *
+ * @return - zHeight height is zero or not.
+ */
+ public boolean getZeroHeight()
+ {
+ return _zHeight;
+ }
+
+ /**
+ * Set the row's height in points.
+ *
+ * @param height the height in points. <code>-1</code> resets to the
default height
+ */
+ public void setHeightInPoints(float height)
+ {
+ if(height==-1)
+ _height=-1;
+ else
+ _height=(short)(height*20);
+ }
+
+ /**
+ * Get the row's height measured in twips (1/20th of a point). If the
height is not set, the default worksheet value is returned,
+ * See {@link Sheet#getDefaultRowHeightInPoints()}
+ *
+ * @return row height measured in twips (1/20th of a point)
+ */
+ public short getHeight()
+ {
+ return
(short)(_height==-1?getSheet().getDefaultRowHeightInPoints()*20:_height);
+ }
+
+ /**
+ * Returns row height measured in point size. If the height is not set,
the default worksheet value is returned,
+ * See {@link Sheet#getDefaultRowHeightInPoints()}
+ *
+ * @return row height measured in point size
+ * @see Sheet#getDefaultRowHeightInPoints()
+ */
+ public float getHeightInPoints()
+ {
+ return
(float)(_height==-1?getSheet().getDefaultRowHeightInPoints():(float)_height/20.0);
+ }
+
+ /**
+ * @return Cell iterator of the physically defined cells. Note element 4
may
+ * actually be row cell depending on how many are defined!
+ */
+ public Iterator<Cell> cellIterator()
+ {
+ return iterator();
+ }
+
+ /**
+ * Returns the Sheet this row belongs to
+ *
+ * @return the Sheet that owns this row
+ */
+ public Sheet getSheet()
+ {
+ return _sheet;
+ }
+//end of interface implementation
+
+
+/** returns all filled cells (created via Row.createCell())*/
+ public class FilledCellIterator implements Iterator<Cell>
+ {
+ int pos=0;
+ public boolean hasNext()
+ {
+ return pos <= _maxColumn;
+ }
+ void advanceToNext()
+ {
+ pos++;
+ while(pos<=_maxColumn&&_cells[pos]==null) pos++;
+ }
+ public Cell next() throws NoSuchElementException
+ {
+ if (hasNext())
+ {
+ Cell retval=_cells[pos];
+ advanceToNext();
+ return retval;
+ }
+ else
+ {
+ throw new NoSuchElementException();
+ }
+ }
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+/** returns all cells including empty cells in which case "null" is returned*/
+ public class CellIterator implements Iterator<Cell>
+ {
+ int pos=0;
+ public boolean hasNext()
+ {
+ return pos <= _maxColumn;
+ }
+ public Cell next() throws NoSuchElementException
+ {
+ if (hasNext())
+ return _cells[pos++];
+ else
+ throw new NoSuchElementException();
+ }
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
+
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]