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
This commit is contained in:
parent
765b7627dc
commit
d619711ea4
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.9-beta1" date="2012-??-??">
|
<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">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="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>
|
<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>
|
||||||
|
@ -2003,4 +2003,71 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
|
|||||||
return new HSSFAutoFilter(this);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ import org.apache.commons.codec.digest.DigestUtils;
|
|||||||
public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook {
|
public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook {
|
||||||
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
||||||
private static final int MAX_ROW = 0xFFFF;
|
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.
|
* 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++) {
|
for(int defNameIndex =0; defNameIndex<names.size(); defNameIndex++) {
|
||||||
NameRecord r = workbook.getNameRecord(defNameIndex);
|
NameRecord r = workbook.getNameRecord(defNameIndex);
|
||||||
if (r == null) {
|
if (r == null) {
|
||||||
|
@ -927,4 +927,48 @@ public interface Sheet extends Iterable<Row> {
|
|||||||
*/
|
*/
|
||||||
SheetConditionalFormatting getSheetConditionalFormatting();
|
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();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,10 @@ public class CellRangeAddress extends CellRangeAddressBase {
|
|||||||
sb.append(cellRefFrom.formatAsString());
|
sb.append(cellRefFrom.formatAsString());
|
||||||
|
|
||||||
//for a single-cell reference return A1 instead of A1:A1
|
//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(':');
|
||||||
sb.append(cellRefTo.formatAsString());
|
sb.append(cellRefTo.formatAsString());
|
||||||
}
|
}
|
||||||
|
@ -76,11 +76,13 @@ public abstract class CellRangeAddressBase {
|
|||||||
|
|
||||||
//TODO use the correct SpreadsheetVersion
|
//TODO use the correct SpreadsheetVersion
|
||||||
public final boolean isFullColumnRange() {
|
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
|
//TODO use the correct SpreadsheetVersion
|
||||||
public final boolean isFullRowRange() {
|
public final boolean isFullRowRange() {
|
||||||
return _firstCol == 0 && _lastCol == SpreadsheetVersion.EXCEL97.getLastColumnIndex();
|
return (_firstCol == 0 && _lastCol == SpreadsheetVersion.EXCEL97.getLastColumnIndex())
|
||||||
|
|| (_firstCol == -1 && _lastCol == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,25 +91,28 @@ public class CellReference {
|
|||||||
|
|
||||||
String[] parts = separateRefParts(cellRef);
|
String[] parts = separateRefParts(cellRef);
|
||||||
_sheetName = parts[0];
|
_sheetName = parts[0];
|
||||||
|
|
||||||
String colRef = parts[1];
|
String colRef = parts[1];
|
||||||
if (colRef.length() < 1) {
|
_isColAbs = (colRef.length() > 0) && colRef.charAt(0) == '$';
|
||||||
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
|
|
||||||
}
|
|
||||||
_isColAbs = colRef.charAt(0) == '$';
|
|
||||||
if (_isColAbs) {
|
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];
|
String rowRef=parts[2];
|
||||||
if (rowRef.length() < 1) {
|
_isRowAbs = (rowRef.length() > 0) && rowRef.charAt(0) == '$';
|
||||||
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'");
|
|
||||||
}
|
|
||||||
_isRowAbs = rowRef.charAt(0) == '$';
|
|
||||||
if (_isRowAbs) {
|
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) {
|
public CellReference(int pRow, int pCol) {
|
||||||
@ -482,14 +485,18 @@ public class CellReference {
|
|||||||
* Sheet name is not included.
|
* Sheet name is not included.
|
||||||
*/
|
*/
|
||||||
/* package */ void appendCellReference(StringBuffer sb) {
|
/* package */ void appendCellReference(StringBuffer sb) {
|
||||||
if(_isColAbs) {
|
if (_colIndex != -1) {
|
||||||
sb.append(ABSOLUTE_REFERENCE_MARKER);
|
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( convertNumToColString(_colIndex));
|
|
||||||
if(_isRowAbs) {
|
|
||||||
sb.append(ABSOLUTE_REFERENCE_MARKER);
|
|
||||||
}
|
|
||||||
sb.append(_rowIndex+1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,6 +25,7 @@ import java.util.Map;
|
|||||||
import org.apache.poi.ss.SpreadsheetVersion;
|
import org.apache.poi.ss.SpreadsheetVersion;
|
||||||
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.util.AreaReference;
|
||||||
import org.apache.poi.ss.util.SheetUtil;
|
import org.apache.poi.ss.util.SheetUtil;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
|
|
||||||
@ -1263,7 +1264,20 @@ public class SXSSFSheet implements Sheet, Cloneable
|
|||||||
public SheetConditionalFormatting getSheetConditionalFormatting(){
|
public SheetConditionalFormatting getSheetConditionalFormatting(){
|
||||||
return _sh.getSheetConditionalFormatting();
|
return _sh.getSheetConditionalFormatting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CellRangeAddress getRepeatingRows() {
|
||||||
|
return _sh.getRepeatingRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CellRangeAddress getRepeatingColumns() {
|
||||||
|
return _sh.getRepeatingColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//end of interface implementation
|
//end of interface implementation
|
||||||
/**
|
/**
|
||||||
* Specifies how many rows can be accessed at most via getRow().
|
* Specifies how many rows can be accessed at most via getRow().
|
||||||
|
@ -3185,4 +3185,54 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||||||
color.setIndexed(colorIndex);
|
color.setIndexed(colorIndex);
|
||||||
pr.setTabColor(color);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -359,14 +359,40 @@ public abstract class BaseTestWorkbook extends TestCase {
|
|||||||
assertSame(row, cell.getRow());
|
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(){
|
public void testSetRepeatingRowsAnsColumns(){
|
||||||
Workbook wb = _testDataProvider.createWorkbook();
|
Workbook wb = _testDataProvider.createWorkbook();
|
||||||
Sheet sheet1 = wb.createSheet();
|
Sheet sheet1 = wb.createSheet();
|
||||||
wb.setRepeatingRowsAndColumns(wb.getSheetIndex(sheet1), 0, 0, 0, 3);
|
wb.setRepeatingRowsAndColumns(wb.getSheetIndex(sheet1), 0, 0, 0, 3);
|
||||||
|
assertEquals("1:4", sheet1.getRepeatingRows().formatAsString());
|
||||||
|
|
||||||
//must handle sheets with quotas, see Bugzilla #47294
|
//must handle sheets with quotas, see Bugzilla #47294
|
||||||
Sheet sheet2 = wb.createSheet("My' Sheet");
|
Sheet sheet2 = wb.createSheet("My' Sheet");
|
||||||
wb.setRepeatingRowsAndColumns(wb.getSheetIndex(sheet2), 0, 0, 0, 3);
|
wb.setRepeatingRowsAndColumns(wb.getSheetIndex(sheet2), 0, 0, 0, 3);
|
||||||
|
assertEquals("1:4", sheet2.getRepeatingRows().formatAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
BIN
test-data/spreadsheet/RepeatingRowsCols.xls
Normal file
BIN
test-data/spreadsheet/RepeatingRowsCols.xls
Normal file
Binary file not shown.
BIN
test-data/spreadsheet/RepeatingRowsCols.xlsx
Normal file
BIN
test-data/spreadsheet/RepeatingRowsCols.xlsx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user