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>
|
||||
<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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
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( 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.usermodel.*;
|
||||
|
||||
import org.apache.poi.ss.util.AreaReference;
|
||||
import org.apache.poi.ss.util.SheetUtil;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
|
||||
@ -1264,6 +1265,19 @@ public class SXSSFSheet implements Sheet, Cloneable
|
||||
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().
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
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