<changes>
<release version="3.9-beta1" date="2012-??-??">
+ <action dev="poi-developers" type="add">53500 - Getter for repeating rows and columns</action>
<action dev="poi-developers" type="fix">53369 - Fixed tests failing on JDK 1.7</action>
<action dev="poi-developers" type="fix">53360 - Fixed SXSSF to correctly write text before escaped Unicode control character</action>
<action dev="poi-developers" type="add">Change HSMF Types to have full data on ID, Name and Length, rather than just being a simple ID</action>
return new HSSFAutoFilter(this);
}
+
+ @Override
+ public CellRangeAddress getRepeatingRows() {
+ return getRepeatingRowsOrColums(true);
+ }
+
+
+ @Override
+ public CellRangeAddress getRepeatingColumns() {
+ return getRepeatingRowsOrColums(false);
+ }
+
+
+ private CellRangeAddress getRepeatingRowsOrColums(boolean rows) {
+ NameRecord rec = getBuiltinNameRecord(NameRecord.BUILTIN_PRINT_TITLE);
+ if (rec == null) {
+ return null;
+ }
+
+ Ptg[] nameDefinition = rec.getNameDefinition();
+ if (rec.getNameDefinition() == null) {
+ return null;
+ }
+
+ int maxRowIndex = SpreadsheetVersion.EXCEL97.getLastRowIndex();
+ int maxColIndex = SpreadsheetVersion.EXCEL97.getLastColumnIndex();
+
+ for (Ptg ptg :nameDefinition) {
+
+ if (ptg instanceof Area3DPtg) {
+ Area3DPtg areaPtg = (Area3DPtg) ptg;
+
+ if (areaPtg.getFirstColumn() == 0
+ && areaPtg.getLastColumn() == maxColIndex) {
+ if (rows) {
+ CellRangeAddress rowRange = new CellRangeAddress(
+ areaPtg.getFirstRow(), areaPtg.getLastRow(), -1, -1);
+ return rowRange;
+ }
+ } else if (areaPtg.getFirstRow() == 0
+ && areaPtg.getLastRow() == maxRowIndex) {
+ if (!rows) {
+ CellRangeAddress columnRange = new CellRangeAddress(-1, -1,
+ areaPtg.getFirstColumn(), areaPtg.getLastColumn());
+ return columnRange;
+ }
+ }
+
+ }
+
+ }
+
+ return null;
+ }
+
+
+ private NameRecord getBuiltinNameRecord(byte builtinCode) {
+ int sheetIndex = _workbook.getSheetIndex(this);
+ int recIndex =
+ _workbook.findExistingBuiltinNameRecordIdx(sheetIndex, builtinCode);
+ if (recIndex == -1) {
+ return null;
+ }
+ return _workbook.getNameRecord(recIndex);
+ }
+
+
}
public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook {
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
private static final int MAX_ROW = 0xFFFF;
- private static final short MAX_COLUMN = (short)0x00FF;
+ private static final int MAX_COLUMN = (short)0x00FF;
/**
* The maximum number of cell styles in a .xls workbook.
}
- private int findExistingBuiltinNameRecordIdx(int sheetIndex, byte builtinCode) {
+ int findExistingBuiltinNameRecordIdx(int sheetIndex, byte builtinCode) {
for(int defNameIndex =0; defNameIndex<names.size(); defNameIndex++) {
NameRecord r = workbook.getNameRecord(defNameIndex);
if (r == null) {
*/
SheetConditionalFormatting getSheetConditionalFormatting();
+
+ /**
+ * Gets the repeating rows used when printing the sheet, as found in
+ * File->PageSetup->Sheet.
+ * <p/>
+ * Repeating rows cover a range of contiguous rows, e.g.:
+ * <pre>
+ * Sheet1!$1:$1
+ * Sheet2!$5:$8
+ * </pre>
+ * The {@link CellRangeAddress} returned contains a column part which spans
+ * all columns, and a row part which specifies the contiguous range of
+ * repeating rows.
+ * <p/>
+ * If the Sheet does not have any repeating rows defined, null is returned.
+ *
+ * @return an {@link CellRangeAddress} containing the repeating rows for the
+ * Sheet, or null.
+ */
+ CellRangeAddress getRepeatingRows();
+
+
+ /**
+ * Gets the repeating columns used when printing the sheet, as found in
+ * File->PageSetup->Sheet.
+ * <p/>
+ * Repeating columns cover a range of contiguous columns, e.g.:
+ * <pre>
+ * Sheet1!$A:$A
+ * Sheet2!$C:$F
+ * </pre>
+ * The {@link CellRangeAddress} returned contains a row part which spans all
+ * rows, and a column part which specifies the contiguous range of
+ * repeating columns.
+ * <p/>
+ * If the Sheet does not have any repeating columns defined, null is
+ * returned.
+ *
+ * @return an {@link CellRangeAddress} containing the repeating columns for the
+ * Sheet, or null.
+ */
+ CellRangeAddress getRepeatingColumns();
+
+
}
sb.append(cellRefFrom.formatAsString());
//for a single-cell reference return A1 instead of A1:A1
- if(!cellRefFrom.equals(cellRefTo)){
+ //for full-column ranges or full-row ranges return A:A instead of A,
+ //and 1:1 instead of 1
+ if(!cellRefFrom.equals(cellRefTo)
+ || isFullColumnRange() || isFullRowRange()){
sb.append(':');
sb.append(cellRefTo.formatAsString());
}
//TODO use the correct SpreadsheetVersion
public final boolean isFullColumnRange() {
- return _firstRow == 0 && _lastRow == SpreadsheetVersion.EXCEL97.getLastRowIndex();
+ return (_firstRow == 0 && _lastRow == SpreadsheetVersion.EXCEL97.getLastRowIndex())
+ || (_firstRow == -1 && _lastRow == -1);
}
//TODO use the correct SpreadsheetVersion
public final boolean isFullRowRange() {
- return _firstCol == 0 && _lastCol == SpreadsheetVersion.EXCEL97.getLastColumnIndex();
+ return (_firstCol == 0 && _lastCol == SpreadsheetVersion.EXCEL97.getLastColumnIndex())
+ || (_firstCol == -1 && _lastCol == -1);
}
/**
String[] parts = separateRefParts(cellRef);
_sheetName = parts[0];
+
String colRef = parts[1];
- if (colRef.length() < 1) {
- throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
- }
- _isColAbs = colRef.charAt(0) == '$';
+ _isColAbs = (colRef.length() > 0) && colRef.charAt(0) == '$';
if (_isColAbs) {
- colRef=colRef.substring(1);
+ colRef = colRef.substring(1);
+ }
+ if (colRef.length() == 0) {
+ _colIndex = -1;
+ } else {
+ _colIndex = convertColStringToIndex(colRef);
}
- _colIndex = convertColStringToIndex(colRef);
String rowRef=parts[2];
- if (rowRef.length() < 1) {
- throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
- }
- _isRowAbs = rowRef.charAt(0) == '$';
+ _isRowAbs = (rowRef.length() > 0) && rowRef.charAt(0) == '$';
if (_isRowAbs) {
- rowRef=rowRef.substring(1);
+ rowRef = rowRef.substring(1);
+ }
+ if (rowRef.length() == 0) {
+ _rowIndex = -1;
+ } else {
+ _rowIndex = Integer.parseInt(rowRef)-1; // -1 to convert 1-based to zero-based
}
- _rowIndex = Integer.parseInt(rowRef)-1; // -1 to convert 1-based to zero-based
}
public CellReference(int pRow, int pCol) {
* Sheet name is not included.
*/
/* package */ void appendCellReference(StringBuffer sb) {
- if(_isColAbs) {
- sb.append(ABSOLUTE_REFERENCE_MARKER);
- }
- sb.append( convertNumToColString(_colIndex));
- if(_isRowAbs) {
- sb.append(ABSOLUTE_REFERENCE_MARKER);
+ if (_colIndex != -1) {
+ if(_isColAbs) {
+ sb.append(ABSOLUTE_REFERENCE_MARKER);
+ }
+ sb.append( convertNumToColString(_colIndex));
+ }
+ if (_rowIndex != -1) {
+ if(_isRowAbs) {
+ sb.append(ABSOLUTE_REFERENCE_MARKER);
+ }
+ sb.append(_rowIndex+1);
}
- sb.append(_rowIndex+1);
}
/**
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.SheetUtil;
import org.apache.poi.xssf.usermodel.XSSFSheet;
public SheetConditionalFormatting getSheetConditionalFormatting(){
return _sh.getSheetConditionalFormatting();
}
-
+
+
+ @Override
+ public CellRangeAddress getRepeatingRows() {
+ return _sh.getRepeatingRows();
+ }
+
+
+ @Override
+ public CellRangeAddress getRepeatingColumns() {
+ return _sh.getRepeatingColumns();
+ }
+
+
//end of interface implementation
/**
* Specifies how many rows can be accessed at most via getRow().
color.setIndexed(colorIndex);
pr.setTabColor(color);
}
+
+
+ @Override
+ public CellRangeAddress getRepeatingRows() {
+ return getRepeatingRowsOrColums(true);
+ }
+
+
+ @Override
+ public CellRangeAddress getRepeatingColumns() {
+ return getRepeatingRowsOrColums(false);
+ }
+
+
+ private CellRangeAddress getRepeatingRowsOrColums(boolean rows) {
+ int sheetIndex = getWorkbook().getSheetIndex(this);
+ XSSFName name = getWorkbook().getBuiltInName(
+ XSSFName.BUILTIN_PRINT_TITLE, sheetIndex);
+ if (name == null ) {
+ return null;
+ }
+ String refStr = name.getRefersToFormula();
+ if (refStr == null) {
+ return null;
+ }
+ String[] parts = refStr.split(",");
+ int maxRowIndex = SpreadsheetVersion.EXCEL2007.getLastRowIndex();
+ int maxColIndex = SpreadsheetVersion.EXCEL2007.getLastColumnIndex();
+ for (String part : parts) {
+ CellRangeAddress range = CellRangeAddress.valueOf(part);
+ if ((range.getFirstColumn() == 0
+ && range.getLastColumn() == maxColIndex)
+ || (range.getFirstColumn() == -1
+ && range.getLastColumn() == -1)) {
+ if (rows) {
+ return range;
+ }
+ } else if (range.getFirstRow() == 0
+ && range.getLastRow() == maxRowIndex
+ || (range.getFirstRow() == -1
+ && range.getLastRow() == -1)) {
+ if (!rows) {
+ return range;
+ }
+ }
+ }
+ return null;
+ }
+
+
}
assertSame(row, cell.getRow());
}
+
+ public void testGetRepeatingRowsAnsColumns(){
+ Workbook wb = _testDataProvider.openSampleWorkbook(
+ "RepeatingRowsCols."
+ + _testDataProvider.getStandardFileNameExtension());
+
+ Sheet sheet0 = wb.getSheetAt(0);
+ assertNull(sheet0.getRepeatingRows());
+ assertNull(sheet0.getRepeatingColumns());
+
+ Sheet sheet1 = wb.getSheetAt(1);
+ assertEquals("1:1", sheet1.getRepeatingRows().formatAsString());
+ assertNull(sheet1.getRepeatingColumns());
+
+ Sheet sheet2 = wb.getSheetAt(2);
+ assertNull(sheet2.getRepeatingRows());
+ assertEquals("A:A", sheet2.getRepeatingColumns().formatAsString());
+
+ Sheet sheet3 = wb.getSheetAt(3);
+ assertEquals("2:3", sheet3.getRepeatingRows().formatAsString());
+ assertEquals("A:B", sheet3.getRepeatingColumns().formatAsString());
+ }
+
+
public void testSetRepeatingRowsAnsColumns(){
Workbook wb = _testDataProvider.createWorkbook();
Sheet sheet1 = wb.createSheet();
wb.setRepeatingRowsAndColumns(wb.getSheetIndex(sheet1), 0, 0, 0, 3);
+ assertEquals("1:4", sheet1.getRepeatingRows().formatAsString());
//must handle sheets with quotas, see Bugzilla #47294
Sheet sheet2 = wb.createSheet("My' Sheet");
wb.setRepeatingRowsAndColumns(wb.getSheetIndex(sheet2), 0, 0, 0, 3);
+ assertEquals("1:4", sheet2.getRepeatingRows().formatAsString());
}
/**