From 1de04ad5f80caf921f35a6fed21f4f954937580d Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Sat, 21 Jul 2012 10:33:00 +0000 Subject: [PATCH] Bugzilla 53500 - Getter for repeating rows and columns git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1364061 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../apache/poi/hssf/usermodel/HSSFSheet.java | 67 ++++++++++++++++++ .../poi/hssf/usermodel/HSSFWorkbook.java | 4 +- .../org/apache/poi/ss/usermodel/Sheet.java | 44 ++++++++++++ .../apache/poi/ss/util/CellRangeAddress.java | 5 +- .../poi/ss/util/CellRangeAddressBase.java | 6 +- .../org/apache/poi/ss/util/CellReference.java | 45 +++++++----- .../apache/poi/xssf/streaming/SXSSFSheet.java | 16 ++++- .../apache/poi/xssf/usermodel/XSSFSheet.java | 50 +++++++++++++ .../poi/ss/usermodel/BaseTestWorkbook.java | 26 +++++++ test-data/spreadsheet/RepeatingRowsCols.xls | Bin 0 -> 58368 bytes test-data/spreadsheet/RepeatingRowsCols.xlsx | Bin 0 -> 20758 bytes 12 files changed, 239 insertions(+), 25 deletions(-) create mode 100644 test-data/spreadsheet/RepeatingRowsCols.xls create mode 100644 test-data/spreadsheet/RepeatingRowsCols.xlsx diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 092abdbfc6..4d84732c4d 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 53500 - Getter for repeating rows and columns 53369 - Fixed tests failing on JDK 1.7 53360 - Fixed SXSSF to correctly write text before escaped Unicode control character Change HSMF Types to have full data on ID, Name and Length, rather than just being a simple ID diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index fe332eb83e..9ca6a9552a 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -2003,4 +2003,71 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { 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); + } + + } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index afd0bce10f..a92f4bbff6 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -76,7 +76,7 @@ import org.apache.commons.codec.digest.DigestUtils; 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. @@ -1034,7 +1034,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss } - private int findExistingBuiltinNameRecordIdx(int sheetIndex, byte builtinCode) { + int findExistingBuiltinNameRecordIdx(int sheetIndex, byte builtinCode) { for(int defNameIndex =0; defNameIndex { */ SheetConditionalFormatting getSheetConditionalFormatting(); + + /** + * Gets the repeating rows used when printing the sheet, as found in + * File->PageSetup->Sheet. + *

+ * Repeating rows cover a range of contiguous rows, e.g.: + *

+     * Sheet1!$1:$1
+     * Sheet2!$5:$8
+     * 
+ * The {@link CellRangeAddress} returned contains a column part which spans + * all columns, and a row part which specifies the contiguous range of + * repeating rows. + *

+ * 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. + *

+ * Repeating columns cover a range of contiguous columns, e.g.: + *

+     * Sheet1!$A:$A
+     * Sheet2!$C:$F
+     * 
+ * The {@link CellRangeAddress} returned contains a row part which spans all + * rows, and a column part which specifies the contiguous range of + * repeating columns. + *

+ * 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(); + + } diff --git a/src/java/org/apache/poi/ss/util/CellRangeAddress.java b/src/java/org/apache/poi/ss/util/CellRangeAddress.java index 4a44a6c8a5..418161d752 100644 --- a/src/java/org/apache/poi/ss/util/CellRangeAddress.java +++ b/src/java/org/apache/poi/ss/util/CellRangeAddress.java @@ -100,7 +100,10 @@ public class CellRangeAddress extends CellRangeAddressBase { 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()); } diff --git a/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java b/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java index e8d9c9100a..12aaa6f629 100644 --- a/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java +++ b/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java @@ -76,11 +76,13 @@ public abstract class CellRangeAddressBase { //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); } /** diff --git a/src/java/org/apache/poi/ss/util/CellReference.java b/src/java/org/apache/poi/ss/util/CellReference.java index 12120b7489..f7c37e3005 100644 --- a/src/java/org/apache/poi/ss/util/CellReference.java +++ b/src/java/org/apache/poi/ss/util/CellReference.java @@ -91,25 +91,28 @@ public class CellReference { 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) { @@ -482,14 +485,18 @@ public class CellReference { * 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); } /** diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java index 5eb3338afb..9c6890f184 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java @@ -25,6 +25,7 @@ import java.util.Map; 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; @@ -1263,7 +1264,20 @@ public class SXSSFSheet implements Sheet, Cloneable 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(). diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index fbed5b06dd..1da83b22d7 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -3185,4 +3185,54 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { 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; + } + + } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java index 347eded973..fca31de5f7 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java @@ -359,14 +359,40 @@ public abstract class BaseTestWorkbook extends TestCase { 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()); } /** diff --git a/test-data/spreadsheet/RepeatingRowsCols.xls b/test-data/spreadsheet/RepeatingRowsCols.xls new file mode 100644 index 0000000000000000000000000000000000000000..95f4e50192b9c822d2eeb0a18a7a8dfa625e4dc0 GIT binary patch literal 58368 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 M0W0CLq`trVUpy@6F8}}l literal 0 HcmV?d00001 -- 2.39.5