consolidate limits specific to Excel version(Excel97, Excel2007) in SpreadsheetVersion enum, allow merged regions with columns greater than 255 or rows bigger than 65536 in XSSF

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@762372 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2009-04-06 15:06:23 +00:00
parent e859a684f3
commit 6ceeb39a45
25 changed files with 159 additions and 99 deletions

View File

@ -37,6 +37,7 @@
<!-- Don't forget to update status.xml too! --> <!-- Don't forget to update status.xml too! -->
<release version="3.5-beta6" date="2009-??-??"> <release version="3.5-beta6" date="2009-??-??">
<action dev="POI-DEVELOPERS" type="fix">46832 - Allow merged regions with columns greater than 255 or rows bigger than 65536 in XSSF</action>
<action dev="POI-DEVELOPERS" type="fix">46951 - Fixed formula parser to better handle range operators and whole row/column refs.</action> <action dev="POI-DEVELOPERS" type="fix">46951 - Fixed formula parser to better handle range operators and whole row/column refs.</action>
<action dev="POI-DEVELOPERS" type="fix">46948 - Fixed evaluation of range operator to allow for area-ref operands</action> <action dev="POI-DEVELOPERS" type="fix">46948 - Fixed evaluation of range operator to allow for area-ref operands</action>
<action dev="POI-DEVELOPERS" type="fix">46918 - Fixed ExtendedPivotTableViewFieldsRecord(SXVDEX) to allow shorter format</action> <action dev="POI-DEVELOPERS" type="fix">46918 - Fixed ExtendedPivotTableViewFieldsRecord(SXVDEX) to allow shorter format</action>

View File

@ -34,6 +34,7 @@
<!-- Don't forget to update changes.xml too! --> <!-- Don't forget to update changes.xml too! -->
<changes> <changes>
<release version="3.5-beta6" date="2009-??-??"> <release version="3.5-beta6" date="2009-??-??">
<action dev="POI-DEVELOPERS" type="fix">46832 - Allow merged regions with columns greater than 255 or rows bigger than 65536 in XSSF</action>
<action dev="POI-DEVELOPERS" type="fix">46951 - Fixed formula parser to better handle range operators and whole row/column refs.</action> <action dev="POI-DEVELOPERS" type="fix">46951 - Fixed formula parser to better handle range operators and whole row/column refs.</action>
<action dev="POI-DEVELOPERS" type="fix">46948 - Fixed evaluation of range operator to allow for area-ref operands</action> <action dev="POI-DEVELOPERS" type="fix">46948 - Fixed evaluation of range operator to allow for area-ref operands</action>
<action dev="POI-DEVELOPERS" type="fix">46918 - Fixed ExtendedPivotTableViewFieldsRecord(SXVDEX) to allow shorter format</action> <action dev="POI-DEVELOPERS" type="fix">46918 - Fixed ExtendedPivotTableViewFieldsRecord(SXVDEX) to allow shorter format</action>

View File

@ -38,11 +38,6 @@ public final class RowRecord extends StandardRecord {
private static final int OPTION_BITS_ALWAYS_SET = 0x0100; private static final int OPTION_BITS_ALWAYS_SET = 0x0100;
private static final int DEFAULT_HEIGHT_BIT = 0x8000; private static final int DEFAULT_HEIGHT_BIT = 0x8000;
/** The maximum row number that excel can handle (zero based) ie 65536 rows is
* max number of rows.
*/
public final static int MAX_ROW_NUMBER = 65535;
private int field_1_row_number; private int field_1_row_number;
private int field_2_first_col; private int field_2_first_col;
private int field_3_last_col; // plus 1 private int field_3_last_col; // plus 1

View File

@ -39,6 +39,7 @@ import org.apache.poi.hssf.record.SharedFormulaRecord;
import org.apache.poi.hssf.record.TableRecord; import org.apache.poi.hssf.record.TableRecord;
import org.apache.poi.hssf.record.UnknownRecord; import org.apache.poi.hssf.record.UnknownRecord;
import org.apache.poi.hssf.record.formula.FormulaShifter; import org.apache.poi.hssf.record.formula.FormulaShifter;
import org.apache.poi.ss.SpreadsheetVersion;
/** /**
* *
@ -138,8 +139,9 @@ public final class RowRecordsAggregate extends RecordAggregate {
} }
public RowRecord getRow(int rowIndex) { public RowRecord getRow(int rowIndex) {
if (rowIndex < 0 || rowIndex > 65535) { int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex();
throw new IllegalArgumentException("The row number must be between 0 and 65535"); if (rowIndex < 0 || rowIndex > maxrow) {
throw new IllegalArgumentException("The row number must be between 0 and " + maxrow);
} }
return _rowRecords.get(new Integer(rowIndex)); return _rowRecords.get(new Integer(rowIndex));
} }

View File

@ -22,6 +22,7 @@ import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndianInput; import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput; import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.ss.SpreadsheetVersion;
/** /**
* ReferencePtgBase - handles references (such as A1, A2, IA4) * ReferencePtgBase - handles references (such as A1, A2, IA4)
@ -31,7 +32,7 @@ import org.apache.poi.util.LittleEndianOutput;
*/ */
public abstract class RefPtgBase extends OperandPtg { public abstract class RefPtgBase extends OperandPtg {
private final static int MAX_ROW_NUMBER = 65536; private final static int MAX_ROW_NUMBER = SpreadsheetVersion.EXCEL97.getMaxRows();
/** The row index - zero based unsigned 16 bit value */ /** The row index - zero based unsigned 16 bit value */
private int field_1_row; private int field_1_row;
@ -73,7 +74,7 @@ public abstract class RefPtgBase extends OperandPtg {
} }
/** /**
* @return the row number as an int, between 0 and 65535 * @return the row number as an int
*/ */
public final int getRow() { public final int getRow() {
return field_1_row; return field_1_row;

View File

@ -55,6 +55,7 @@ import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.SpreadsheetVersion;
/** /**
* High level representation of a cell in a row of a spreadsheet. * High level representation of a cell in a row of a spreadsheet.
@ -79,8 +80,8 @@ public class HSSFCell implements Cell {
/** /**
* The maximum number of columns in BIFF8 * The maximum number of columns in BIFF8
*/ */
public static final int LAST_COLUMN_NUMBER = 255; // 2^8 - 1 public static final int LAST_COLUMN_NUMBER = SpreadsheetVersion.EXCEL97.getLastColumnIndex(); // 2^8 - 1
private static final String LAST_COLUMN_NAME = "IV"; private static final String LAST_COLUMN_NAME = SpreadsheetVersion.EXCEL97.getLastColumnName();
public final static short ENCODING_UNCHANGED = -1; public final static short ENCODING_UNCHANGED = -1;
public final static short ENCODING_COMPRESSED_UNICODE = 0; public final static short ENCODING_COMPRESSED_UNICODE = 0;

View File

@ -25,6 +25,7 @@ import org.apache.poi.hssf.record.ExtendedFormatRecord;
import org.apache.poi.hssf.record.RowRecord; import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.SpreadsheetVersion;
/** /**
* High level representation of a row of a spreadsheet. * High level representation of a row of a spreadsheet.
@ -222,9 +223,10 @@ public final class HSSFRow implements Row {
* @throws IndexOutOfBoundsException if the row number is not within the range 0-65535. * @throws IndexOutOfBoundsException if the row number is not within the range 0-65535.
*/ */
public void setRowNum(int rowIndex) { public void setRowNum(int rowIndex) {
if ((rowIndex < 0) || (rowIndex > RowRecord.MAX_ROW_NUMBER)) { int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex();
if ((rowIndex < 0) || (rowIndex > maxrow)) {
throw new IllegalArgumentException("Invalid row number (" + rowIndex throw new IllegalArgumentException("Invalid row number (" + rowIndex
+ ") outside allowable range (0.." + RowRecord.MAX_ROW_NUMBER + ")"); + ") outside allowable range (0.." + maxrow + ")");
} }
rowNum = rowIndex; rowNum = rowIndex;
if (row != null) { if (row != null) {

View File

@ -51,6 +51,7 @@ import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -558,6 +559,7 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
*/ */
public int addMergedRegion(CellRangeAddress region) public int addMergedRegion(CellRangeAddress region)
{ {
region.validate(SpreadsheetVersion.EXCEL97);
return _sheet.addMergedRegion( region.getFirstRow(), return _sheet.addMergedRegion( region.getFirstRow(),
region.getFirstColumn(), region.getFirstColumn(),
region.getLastRow(), region.getLastRow(),
@ -1256,7 +1258,7 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
} }
} }
} }
if ( endRow == _lastrow || endRow + n > _lastrow ) _lastrow = Math.min( endRow + n, 65535 ); if ( endRow == _lastrow || endRow + n > _lastrow ) _lastrow = Math.min( endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex() );
if ( startRow == _firstrow || startRow + n < _firstrow ) _firstrow = Math.max( startRow + n, 0 ); if ( startRow == _firstrow || startRow + n < _firstrow ) _firstrow = Math.max( startRow + n, 0 );
// Update any formulas on this sheet that point to // Update any formulas on this sheet that point to
@ -1291,8 +1293,8 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
* @param leftmostColumn Left column visible in right pane. * @param leftmostColumn Left column visible in right pane.
*/ */
public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) { public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) {
if (colSplit < 0 || colSplit > 255) throw new IllegalArgumentException("Column must be between 0 and 255"); validateColumn(colSplit);
if (rowSplit < 0 || rowSplit > 65535) throw new IllegalArgumentException("Row must be between 0 and 65535"); validateRow(rowSplit);
if (leftmostColumn < colSplit) throw new IllegalArgumentException("leftmostColumn parameter must not be less than colSplit parameter"); if (leftmostColumn < colSplit) throw new IllegalArgumentException("leftmostColumn parameter must not be less than colSplit parameter");
if (topRow < rowSplit) throw new IllegalArgumentException("topRow parameter must not be less than leftmostColumn parameter"); if (topRow < rowSplit) throw new IllegalArgumentException("topRow parameter must not be less than leftmostColumn parameter");
getSheet().createFreezePane( colSplit, rowSplit, topRow, leftmostColumn ); getSheet().createFreezePane( colSplit, rowSplit, topRow, leftmostColumn );
@ -1426,7 +1428,7 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
*/ */
public void setColumnBreak(int column) { public void setColumnBreak(int column) {
validateColumn((short)column); validateColumn((short)column);
_sheet.getPageSettings().setColumnBreak((short)column, (short)0, (short)65535); _sheet.getPageSettings().setColumnBreak((short)column, (short)0, (short) SpreadsheetVersion.EXCEL97.getLastRowIndex());
} }
/** /**
@ -1451,7 +1453,8 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
* @param row * @param row
*/ */
protected void validateRow(int row) { protected void validateRow(int row) {
if (row > 65535) throw new IllegalArgumentException("Maximum row number is 65535"); int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex();
if (row > maxrow) throw new IllegalArgumentException("Maximum row number is " + maxrow);
if (row < 0) throw new IllegalArgumentException("Minumum row number is 0"); if (row < 0) throw new IllegalArgumentException("Minumum row number is 0");
} }
@ -1459,8 +1462,9 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
* Runs a bounds check for column numbers * Runs a bounds check for column numbers
* @param column * @param column
*/ */
protected void validateColumn(short column) { protected void validateColumn(int column) {
if (column > 255) throw new IllegalArgumentException("Maximum column number is 255"); int maxcol = SpreadsheetVersion.EXCEL97.getLastColumnIndex();
if (column > maxcol) throw new IllegalArgumentException("Maximum column number is " + maxcol);
if (column < 0) throw new IllegalArgumentException("Minimum column number is 0"); if (column < 0) throw new IllegalArgumentException("Minimum column number is 0");
} }

View File

@ -23,6 +23,7 @@ import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable; import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
import org.apache.poi.ss.util.Region; import org.apache.poi.ss.util.Region;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.SpreadsheetVersion;
/** /**
* The 'Conditional Formatting' facet of <tt>HSSFSheet</tt> * The 'Conditional Formatting' facet of <tt>HSSFSheet</tt>
@ -120,6 +121,8 @@ public final class HSSFSheetConditionalFormatting {
if (regions == null) { if (regions == null) {
throw new IllegalArgumentException("regions must not be null"); throw new IllegalArgumentException("regions must not be null");
} }
for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL97);
if (cfRules == null) { if (cfRules == null) {
throw new IllegalArgumentException("cfRules must not be null"); throw new IllegalArgumentException("cfRules must not be null");
} }

View File

@ -28,23 +28,11 @@ import org.apache.poi.hssf.record.SelectionRecord;
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro) * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
*/ */
public class CellRangeAddress extends org.apache.poi.ss.util.CellRangeAddress { public class CellRangeAddress extends org.apache.poi.ss.util.CellRangeAddress {
/*
* TODO - replace org.apache.poi.hssf.util.Region
*/
public static final int ENCODED_SIZE = 8;
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) { public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
super(firstRow, lastRow, firstCol, lastCol); super(firstRow, lastRow, firstCol, lastCol);
} }
public CellRangeAddress(RecordInputStream in) { public CellRangeAddress(RecordInputStream in) {
super(readUShortAndCheck(in), in.readUShort(), in.readUShort(), in.readUShort()); super(in);
}
private static int readUShortAndCheck(RecordInputStream in) {
if (in.remaining() < ENCODED_SIZE) {
// Ran out of data
throw new RuntimeException("Ran out of data reading CellRangeAddress");
}
return in.readUShort();
} }
} }

View File

@ -25,8 +25,6 @@ import org.apache.poi.ss.util.CellReference;
* discernable to the user. It is not intended to deal with low-level issues like file formats. * discernable to the user. It is not intended to deal with low-level issues like file formats.
* <p/> * <p/>
* *
* For internal POI use only
*
* @author Josh Micich * @author Josh Micich
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */

View File

@ -17,6 +17,8 @@
package org.apache.poi.ss.util; package org.apache.poi.ss.util;
import org.apache.poi.ss.SpreadsheetVersion;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -176,7 +178,7 @@ public class AreaReference {
// C$1:C$65535 or D$1:F$0 // C$1:C$65535 or D$1:F$0
// i.e. absolute from 1st row to 0th one // i.e. absolute from 1st row to 0th one
if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() && if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() &&
botRight.getRow() == 65535 && botRight.isRowAbsolute()) { botRight.getRow() == SpreadsheetVersion.EXCEL97.getLastRowIndex() && botRight.isRowAbsolute()) {
return true; return true;
} }
return false; return false;

View File

@ -17,6 +17,8 @@
package org.apache.poi.ss.util; package org.apache.poi.ss.util;
import org.apache.poi.ss.SpreadsheetVersion;
/** /**
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/> * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
@ -27,49 +29,58 @@ package org.apache.poi.ss.util;
*/ */
public abstract class CellRangeAddressBase { public abstract class CellRangeAddressBase {
/** max 65536 rows in BIFF8 */
private static final int LAST_ROW_INDEX = 0x00FFFF;
/** max 256 columns in BIFF8 */
private static final int LAST_COLUMN_INDEX = 0x00FF;
private int _firstRow; private int _firstRow;
private int _firstCol; private int _firstCol;
private int _lastRow; private int _lastRow;
private int _lastCol; private int _lastCol;
protected CellRangeAddressBase(int firstRow, int lastRow, int firstCol, int lastCol) { protected CellRangeAddressBase(int firstRow, int lastRow, int firstCol, int lastCol) {
if(!isValid(firstRow, lastRow, firstCol, lastCol)) {
throw new IllegalArgumentException("invalid cell range (" + firstRow + ", " + lastRow
+ ", " + firstCol + ", " + lastCol + ")");
}
_firstRow = firstRow; _firstRow = firstRow;
_lastRow =lastRow; _lastRow = lastRow;
_firstCol = firstCol; _firstCol = firstCol;
_lastCol = lastCol; _lastCol = lastCol;
} }
private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn) {
if(lastRow < 0 || lastRow > LAST_ROW_INDEX) { /**
return false; * Validate the range limits against the supplied version of Excel
*
* @param ssVersion the version of Excel to validate against
* @throws IllegalArgumentException if the range limits are outside of the allowed range
*/
public void validate(SpreadsheetVersion ssVersion) {
validateRow(_firstRow, ssVersion);
validateRow(_lastRow, ssVersion);
validateColumn(_firstCol, ssVersion);
validateColumn(_lastCol, ssVersion);
} }
if(firstRow < 0 || firstRow > LAST_ROW_INDEX) { /**
return false; * Runs a bounds check for row numbers
* @param row
*/
private static void validateRow(int row, SpreadsheetVersion ssVersion) {
int maxrow = ssVersion.getLastRowIndex();
if (row > maxrow) throw new IllegalArgumentException("Maximum row number is " + maxrow);
if (row < 0) throw new IllegalArgumentException("Minumum row number is 0");
} }
if(lastColumn < 0 || lastColumn > LAST_COLUMN_INDEX) { /**
return false; * Runs a bounds check for column numbers
} * @param column
if(firstColumn < 0 || firstColumn > LAST_COLUMN_INDEX) { */
return false; private static void validateColumn(int column, SpreadsheetVersion ssVersion) {
} int maxcol = ssVersion.getLastColumnIndex();
return true; if (column > maxcol) throw new IllegalArgumentException("Maximum column number is " + maxcol);
if (column < 0) throw new IllegalArgumentException("Minimum column number is 0");
} }
//TODO use the correct SpreadsheetVersion
public final boolean isFullColumnRange() { public final boolean isFullColumnRange() {
return _firstRow == 0 && _lastRow == LAST_ROW_INDEX; return _firstRow == 0 && _lastRow == SpreadsheetVersion.EXCEL97.getLastRowIndex();
} }
//TODO use the correct SpreadsheetVersion
public final boolean isFullRowRange() { public final boolean isFullRowRange() {
return _firstCol == 0 && _lastCol == LAST_COLUMN_INDEX; return _firstCol == 0 && _lastCol == SpreadsheetVersion.EXCEL97.getLastColumnIndex();
} }
/** /**

View File

@ -21,6 +21,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.poi.hssf.record.formula.SheetNameFormatter; import org.apache.poi.hssf.record.formula.SheetNameFormatter;
import org.apache.poi.ss.SpreadsheetVersion;
/** /**
* *
@ -61,9 +62,9 @@ public class CellReference {
* digits or dot. (They can even end in dot). * digits or dot. (They can even end in dot).
*/ */
private static final Pattern NAMED_RANGE_NAME_PATTERN = Pattern.compile("[_A-Za-z][_.A-Za-z0-9]*"); private static final Pattern NAMED_RANGE_NAME_PATTERN = Pattern.compile("[_A-Za-z][_.A-Za-z0-9]*");
private static final String BIFF8_LAST_COLUMN = "IV"; private static final String BIFF8_LAST_COLUMN = SpreadsheetVersion.EXCEL97.getLastColumnName();
private static final int BIFF8_LAST_COLUMN_TEXT_LEN = BIFF8_LAST_COLUMN.length(); private static final int BIFF8_LAST_COLUMN_TEXT_LEN = BIFF8_LAST_COLUMN.length();
private static final String BIFF8_LAST_ROW = String.valueOf(0x10000); private static final String BIFF8_LAST_ROW = String.valueOf(SpreadsheetVersion.EXCEL97.getMaxRows());
private static final int BIFF8_LAST_ROW_TEXT_LEN = BIFF8_LAST_ROW.length(); private static final int BIFF8_LAST_ROW_TEXT_LEN = BIFF8_LAST_ROW.length();
private final int _rowIndex; private final int _rowIndex;

View File

@ -30,6 +30,7 @@ import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.formula.FormulaParser; import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.FormulaRenderer; import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -56,13 +57,6 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
public final class XSSFCell implements Cell { public final class XSSFCell implements Cell {
private static POILogger logger = POILogFactory.getLogger(XSSFCell.class); private static POILogger logger = POILogFactory.getLogger(XSSFCell.class);
private static final String FILE_FORMAT_NAME = "BIFF12";
/**
* The maximum number of columns in SpreadsheetML
*/
public static final int LAST_COLUMN_NUMBER = 16384-1; //2^14-1
private static final String LAST_COLUMN_NAME = "XFD";
private static final String FALSE_AS_STRING = "0"; private static final String FALSE_AS_STRING = "0";
private static final String TRUE_AS_STRING = "1"; private static final String TRUE_AS_STRING = "1";
@ -791,10 +785,12 @@ public final class XSSFCell implements Cell {
* @throws RuntimeException if the bounds are exceeded. * @throws RuntimeException if the bounds are exceeded.
*/ */
private static void checkBounds(int cellIndex) { private static void checkBounds(int cellIndex) {
if (cellIndex < 0 || cellIndex > LAST_COLUMN_NUMBER) { SpreadsheetVersion v = SpreadsheetVersion.EXCEL2007;
int maxcol = SpreadsheetVersion.EXCEL2007.getLastColumnIndex();
if (cellIndex < 0 || cellIndex > maxcol) {
throw new IllegalArgumentException("Invalid column index (" + cellIndex throw new IllegalArgumentException("Invalid column index (" + cellIndex
+ "). Allowable column range for " + FILE_FORMAT_NAME + " is (0.." + "). Allowable column range for " + v.name() + " is (0.."
+ LAST_COLUMN_NUMBER + ") or ('A'..'" + LAST_COLUMN_NAME + "')"); + maxcol + ") or ('A'..'" + v.getLastColumnName() + "')");
} }
} }

View File

@ -25,6 +25,7 @@ import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.formula.FormulaParser; import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.FormulaRenderer; import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.xssf.model.CalculationChain; import org.apache.poi.xssf.model.CalculationChain;
import org.apache.poi.hssf.record.formula.Ptg; import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.FormulaShifter; import org.apache.poi.hssf.record.formula.FormulaShifter;
@ -41,12 +42,6 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
public class XSSFRow implements Row, Comparable<XSSFRow> { public class XSSFRow implements Row, Comparable<XSSFRow> {
private static final POILogger logger = POILogFactory.getLogger(XSSFRow.class); private static final POILogger logger = POILogFactory.getLogger(XSSFRow.class);
private static final String FILE_FORMAT_NAME = "BIFF12";
/**
* The maximum number of rows in SpreadsheetML
*/
public static final int MAX_ROW_NUMBER = 1048575; //2 ^ 20 - 1
/** /**
* the xml bean containing all cell definitions for this row * the xml bean containing all cell definitions for this row
*/ */
@ -328,12 +323,13 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
* Set the row number of this row. * Set the row number of this row.
* *
* @param rowIndex the row number (0-based) * @param rowIndex the row number (0-based)
* @throws IllegalArgumentException if rowNum < 0 or greater than {@link #MAX_ROW_NUMBER} * @throws IllegalArgumentException if rowNum < 0 or greater than 1048575
*/ */
public void setRowNum(int rowIndex) { public void setRowNum(int rowIndex) {
if (rowIndex < 0 || rowIndex > MAX_ROW_NUMBER) { int maxrow = SpreadsheetVersion.EXCEL2007.getLastRowIndex();
if (rowIndex < 0 || rowIndex > maxrow) {
throw new IllegalArgumentException("Invalid row number (" + rowIndex throw new IllegalArgumentException("Invalid row number (" + rowIndex
+ ") outside allowable range (0.." + MAX_ROW_NUMBER + ")"); + ") outside allowable range (0.." + maxrow + ")");
} }
row.setR(rowIndex + 1); row.setR(rowIndex + 1);
} }

View File

@ -34,6 +34,7 @@ import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.formula.FormulaParser; import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.FormulaRenderer; import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.xssf.model.CommentsTable; import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.CalculationChain; import org.apache.poi.xssf.model.CalculationChain;
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
@ -235,6 +236,8 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
* @return index of this region * @return index of this region
*/ */
public int addMergedRegion(CellRangeAddress cra) { public int addMergedRegion(CellRangeAddress cra) {
cra.validate(SpreadsheetVersion.EXCEL2007);
CTMergeCells ctMergeCells = worksheet.isSetMergeCells() ? worksheet.getMergeCells() : worksheet.addNewMergeCells(); CTMergeCells ctMergeCells = worksheet.isSetMergeCells() ? worksheet.getMergeCells() : worksheet.addNewMergeCells();
CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell(); CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell();
ctMergeCell.setRef(cra.formatAsString()); ctMergeCell.setRef(cra.formatAsString());
@ -764,9 +767,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
CTMergeCell ctMergeCell = ctMergeCells.getMergeCellArray(index); CTMergeCell ctMergeCell = ctMergeCells.getMergeCellArray(index);
String ref = ctMergeCell.getRef(); String ref = ctMergeCell.getRef();
CellReference cell1 = new CellReference(ref.substring(0, ref.indexOf(":"))); return CellRangeAddress.valueOf(ref);
CellReference cell2 = new CellReference(ref.substring(ref.indexOf(":") + 1));
return new CellRangeAddress(cell1.getRow(), cell2.getRow(), cell1.getCol(), cell2.getCol());
} }
/** /**

View File

@ -17,6 +17,7 @@
package org.apache.poi.xssf; package org.apache.poi.xssf;
import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.ITestDataProvider;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples;
@ -46,6 +47,10 @@ public final class XSSFITestDataProvider implements ITestDataProvider {
return HSSFTestDataSamples.getTestDataFileContent(fileName); return HSSFTestDataSamples.getTestDataFileContent(fileName);
} }
public SpreadsheetVersion getSpreadsheetVersion(){
return SpreadsheetVersion.EXCEL2007;
}
private XSSFITestDataProvider(){} private XSSFITestDataProvider(){}
private static XSSFITestDataProvider inst = new XSSFITestDataProvider(); private static XSSFITestDataProvider inst = new XSSFITestDataProvider();
public static XSSFITestDataProvider getInstance(){ public static XSSFITestDataProvider getInstance(){

View File

@ -24,6 +24,7 @@ import java.util.Iterator;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.XSSFITestDataProvider;
@ -43,10 +44,10 @@ public final class TestXSSFRow extends BaseTestRow {
} }
public void testRowBounds() { public void testRowBounds() {
baseTestRowBounds(XSSFRow.MAX_ROW_NUMBER); baseTestRowBounds(SpreadsheetVersion.EXCEL2007.getLastRowIndex());
} }
public void testCellBounds() { public void testCellBounds() {
baseTestCellBounds(XSSFCell.LAST_COLUMN_NUMBER); baseTestCellBounds(SpreadsheetVersion.EXCEL2007.getLastColumnIndex());
} }
} }

View File

@ -19,6 +19,7 @@ package org.apache.poi.hssf;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.ITestDataProvider;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
/** /**
@ -46,6 +47,10 @@ public final class HSSFITestDataProvider implements ITestDataProvider {
return HSSFTestDataSamples.getTestDataFileContent(fileName); return HSSFTestDataSamples.getTestDataFileContent(fileName);
} }
public SpreadsheetVersion getSpreadsheetVersion(){
return SpreadsheetVersion.EXCEL2007;
}
private HSSFITestDataProvider(){} private HSSFITestDataProvider(){}
private static HSSFITestDataProvider inst = new HSSFITestDataProvider(); private static HSSFITestDataProvider inst = new HSSFITestDataProvider();
public static HSSFITestDataProvider getInstance(){ public static HSSFITestDataProvider getInstance(){

View File

@ -25,6 +25,7 @@ import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.hssf.record.BlankRecord; import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.RowRecord; import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.ss.usermodel.BaseTestRow; import org.apache.poi.ss.usermodel.BaseTestRow;
import org.apache.poi.ss.SpreadsheetVersion;
/** /**
* Test HSSFRow is okay. * Test HSSFRow is okay.
@ -39,11 +40,11 @@ public final class TestHSSFRow extends BaseTestRow {
} }
public void testRowBounds() { public void testRowBounds() {
baseTestRowBounds(RowRecord.MAX_ROW_NUMBER); baseTestRowBounds(SpreadsheetVersion.EXCEL97.getLastRowIndex());
} }
public void testCellBounds() { public void testCellBounds() {
baseTestCellBounds(HSSFCell.LAST_COLUMN_NUMBER); baseTestCellBounds(SpreadsheetVersion.EXCEL97.getLastColumnIndex());
} }
public void testLastAndFirstColumns_bug46654() { public void testLastAndFirstColumns_bug46654() {

View File

@ -17,21 +17,17 @@
package org.apache.poi.hssf.usermodel; package org.apache.poi.hssf.usermodel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.HSSFITestDataProvider; import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.DrawingManager2; import org.apache.poi.hssf.model.DrawingManager2;
import org.apache.poi.hssf.record.*; import org.apache.poi.hssf.record.*;
import org.apache.poi.ss.util.Region;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.usermodel.BaseTestSheet; import org.apache.poi.ss.usermodel.BaseTestSheet;
import org.apache.poi.ddf.EscherDgRecord; import org.apache.poi.ddf.EscherDgRecord;

View File

@ -50,4 +50,6 @@ public interface ITestDataProvider {
* @return an open <tt>InputStream</tt> for the specified sample file * @return an open <tt>InputStream</tt> for the specified sample file
*/ */
byte[] getTestDataFileContent(String fileName); byte[] getTestDataFileContent(String fileName);
SpreadsheetVersion getSpreadsheetVersion();
} }

View File

@ -19,6 +19,7 @@ package org.apache.poi.ss.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.ITestDataProvider;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
import java.util.Iterator; import java.util.Iterator;
@ -195,6 +196,46 @@ public abstract class BaseTestSheet extends TestCase {
assertEquals(3, sheetP.getPrintSetup().getCopies()); assertEquals(3, sheetP.getPrintSetup().getCopies());
} }
/**
* Test adding merged regions. If the region's bounds are outside of the allowed range
* then an IllegalArgumentException should be thrown
*
*/
public void testAddMerged() {
Workbook wb = getTestDataProvider().createWorkbook();
Sheet sheet = wb.createSheet();
assertEquals(0, sheet.getNumMergedRegions());
SpreadsheetVersion ssVersion = getTestDataProvider().getSpreadsheetVersion();
CellRangeAddress region = new CellRangeAddress(0, 1, 0, 1);
sheet.addMergedRegion(region);
assertEquals(1, sheet.getNumMergedRegions());
try {
region = new CellRangeAddress(-1, -1, -1, -1);
sheet.addMergedRegion(region);
fail("Expected exception");
} catch (IllegalArgumentException e){
;
}
try {
region = new CellRangeAddress(0, 0, 0, ssVersion.getLastColumnIndex() + 1);
sheet.addMergedRegion(region);
fail("Expected exception");
} catch (IllegalArgumentException e){
;
}
try {
region = new CellRangeAddress(0, ssVersion.getLastRowIndex() + 1, 0, 1);
sheet.addMergedRegion(region);
fail("Expected exception");
} catch (IllegalArgumentException e){
;
}
assertEquals(1, sheet.getNumMergedRegions());
}
/** /**
* When removing one merged region, it would break * When removing one merged region, it would break
* *

View File

@ -108,6 +108,12 @@ public abstract class BaseTestWorkbook extends TestCase {
assertEquals("sheet3", workbook.getSheetName(0)); assertEquals("sheet3", workbook.getSheetName(0));
workbook.removeSheetAt(0); workbook.removeSheetAt(0);
assertEquals(0, workbook.getNumberOfSheets()); assertEquals(0, workbook.getNumberOfSheets());
//re-create the sheets
workbook.createSheet("sheet1");
workbook.createSheet("sheet2");
workbook.createSheet("sheet3");
assertEquals(3, workbook.getNumberOfSheets());
} }
public void testDefaultValues() { public void testDefaultValues() {