git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1364061 13f79535-47bb-0310-9956-ffa450edef68tags/3.10-beta1
<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> |
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); | |||||
} | |||||
} | } |
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. | ||||
} | } | ||||
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) { |
*/ | */ | ||||
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(); | |||||
} | } |
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()); | ||||
} | } |
//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); | |||||
} | } | ||||
/** | /** |
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) { | |||||
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'"); | |||||
} | |||||
_isColAbs = colRef.charAt(0) == '$'; | |||||
_isColAbs = (colRef.length() > 0) && 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) { | |||||
throw new IllegalArgumentException("Invalid Formula cell reference: '"+cellRef+"'"); | |||||
} | |||||
_isRowAbs = rowRef.charAt(0) == '$'; | |||||
_isRowAbs = (rowRef.length() > 0) && 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) { | ||||
* Sheet name is not included. | * Sheet name is not included. | ||||
*/ | */ | ||||
/* package */ void appendCellReference(StringBuffer sb) { | /* 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.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; | ||||
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(). |
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; | |||||
} | |||||
} | } |
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()); | |||||
} | } | ||||
/** | /** |