aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYegor Kozlov <yegor@apache.org>2012-07-21 10:33:00 +0000
committerYegor Kozlov <yegor@apache.org>2012-07-21 10:33:00 +0000
commit1de04ad5f80caf921f35a6fed21f4f954937580d (patch)
tree306900765d9b698320a15c09371c1e87ae3bd53e /src
parent00831d3c5b3dd286236a545e418a8c3e0bf73964 (diff)
downloadpoi-1de04ad5f80caf921f35a6fed21f4f954937580d.tar.gz
poi-1de04ad5f80caf921f35a6fed21f4f954937580d.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/documentation/content/xdocs/status.xml1
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java67
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java4
-rw-r--r--src/java/org/apache/poi/ss/usermodel/Sheet.java44
-rw-r--r--src/java/org/apache/poi/ss/util/CellRangeAddress.java5
-rw-r--r--src/java/org/apache/poi/ss/util/CellRangeAddressBase.java6
-rw-r--r--src/java/org/apache/poi/ss/util/CellReference.java45
-rw-r--r--src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java16
-rw-r--r--src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java50
-rw-r--r--src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java26
10 files changed, 239 insertions, 25 deletions
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 @@
<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>
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<names.size(); defNameIndex++) {
NameRecord r = workbook.getNameRecord(defNameIndex);
if (r == null) {
diff --git a/src/java/org/apache/poi/ss/usermodel/Sheet.java b/src/java/org/apache/poi/ss/usermodel/Sheet.java
index 5be4f1f5e6..4ef8842609 100644
--- a/src/java/org/apache/poi/ss/usermodel/Sheet.java
+++ b/src/java/org/apache/poi/ss/usermodel/Sheet.java
@@ -927,4 +927,48 @@ public interface Sheet extends Iterable<Row> {
*/
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();
+
+
}
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());
}
/**