Browse Source

[bug-66213] hack clone table code to avoid failing with edge cases

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1903409 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_5_2_3
PJ Fanning 1 year ago
parent
commit
711ab033f3

+ 73
- 66
poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java View File

@@ -4302,6 +4302,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
* @param t table to remove
*/
public void removeTable(XSSFTable t) {
String rId = getRelationId(t);
long id = t.getCTTable().getId();
Map.Entry<String, XSSFTable> toDelete = null;

@@ -4314,10 +4315,12 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
toDelete.getValue().onTableDelete();
CTTableParts tblParts = worksheet.getTableParts();
int matchedPos = -1;
for (int i = 0; i < tblParts.sizeOfTablePartArray(); i++) {
if (toDelete.getKey().equals(tblParts.getTablePartArray(i).getId())) {
matchedPos = i;
break;
if (rId != null) {
for (int i = 0; i < tblParts.sizeOfTablePartArray(); i++) {
if (rId.equals(tblParts.getTablePartArray(i).getId())) {
matchedPos = i;
break;
}
}
}
if (matchedPos != -1) {
@@ -4875,82 +4878,86 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx

static void cloneTables(XSSFSheet sheet) {
for (XSSFTable table : sheet.getTables()) {
// clone table
XSSFTable clonedTable = sheet.createTable(table.getArea());
clonedTable.updateHeaders();

// clone style
clonedTable.setStyleName(table.getStyleName());
XSSFTableStyleInfo style = (XSSFTableStyleInfo)table.getStyle();
XSSFTableStyleInfo clonedStyle = (XSSFTableStyleInfo)clonedTable.getStyle();
if (style != null && clonedStyle != null) {
clonedStyle.setShowColumnStripes(style.isShowColumnStripes());
clonedStyle.setShowRowStripes(style.isShowRowStripes());
clonedStyle.setFirstColumn(style.isShowFirstColumn());
clonedStyle.setLastColumn(style.isShowLastColumn());

// clone table; XSSFTable.setArea fails and throws exception for too small tables
XSSFTable clonedTable = null;
if (table.supportsAreaReference(table.getArea())) {
clonedTable = sheet.createTable(table.getArea());
}

//clone autofilter
clonedTable.getCTTable().setAutoFilter(table.getCTTable().getAutoFilter());
if (clonedTable != null) {
clonedTable.updateHeaders();

// clone style
clonedTable.setStyleName(table.getStyleName());
XSSFTableStyleInfo style = (XSSFTableStyleInfo)table.getStyle();
XSSFTableStyleInfo clonedStyle = (XSSFTableStyleInfo)clonedTable.getStyle();
if (style != null && clonedStyle != null) {
clonedStyle.setShowColumnStripes(style.isShowColumnStripes());
clonedStyle.setShowRowStripes(style.isShowRowStripes());
clonedStyle.setFirstColumn(style.isShowFirstColumn());
clonedStyle.setLastColumn(style.isShowLastColumn());
}

//clone totalsrow
int totalsRowCount = table.getTotalsRowCount();
if (totalsRowCount == 1) { // never seen more than one totals row
XSSFRow totalsRow = sheet.getRow(clonedTable.getEndCellReference().getRow());
if (clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);
CTTableColumn clonedTableCol = clonedTable.getCTTable().getTableColumns().getTableColumnList().get(i);
clonedTableCol.setTotalsRowFunction(tableCol.getTotalsRowFunction());
int intTotalsRowFunction = clonedTableCol.getTotalsRowFunction().intValue();
sheet.getWorkbook().setCellFormulaValidation(false);
if (intTotalsRowFunction == 10) { //custom
CTTableFormula totalsRowFormula = tableCol.getTotalsRowFormula();
clonedTableCol.setTotalsRowFormula(totalsRowFormula);
totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setCellFormula(totalsRowFormula.getStringValue());
} else if (intTotalsRowFunction == 1) { //none
//totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setBlank();
} else {
String subtotalFormulaStart = getSubtotalFormulaStartFromTotalsRowFunction(intTotalsRowFunction);
if (subtotalFormulaStart != null)
totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setCellFormula(subtotalFormulaStart + "," + clonedTable.getName() +"[" + clonedTableCol.getName()+ "])");
//clone autofilter
clonedTable.getCTTable().setAutoFilter(table.getCTTable().getAutoFilter());

//clone totalsrow
int totalsRowCount = table.getTotalsRowCount();
if (totalsRowCount == 1) { // never seen more than one totals row
XSSFRow totalsRow = sheet.getRow(clonedTable.getEndCellReference().getRow());
if (clonedTable.getCTTable().getTableColumns() != null
&& clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);
CTTableColumn clonedTableCol = clonedTable.getCTTable().getTableColumns().getTableColumnList().get(i);
clonedTableCol.setTotalsRowFunction(tableCol.getTotalsRowFunction());
int intTotalsRowFunction = clonedTableCol.getTotalsRowFunction().intValue();
sheet.getWorkbook().setCellFormulaValidation(false);
if (intTotalsRowFunction == 10) { //custom
CTTableFormula totalsRowFormula = tableCol.getTotalsRowFormula();
clonedTableCol.setTotalsRowFormula(totalsRowFormula);
totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setCellFormula(totalsRowFormula.getStringValue());
} else if (intTotalsRowFunction == 1) { //none
//totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setBlank();
} else {
String subtotalFormulaStart = getSubtotalFormulaStartFromTotalsRowFunction(intTotalsRowFunction);
if (subtotalFormulaStart != null)
totalsRow.getCell(clonedTable.getStartCellReference().getCol()+i).setCellFormula(subtotalFormulaStart + "," + clonedTable.getName() +"[" + clonedTableCol.getName()+ "])");
}
}
}
}
}

// clone calculated column formulas
if (clonedTable.getCTTable().getTableColumns() != null
&& clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);
CTTableColumn clonedTableCol = clonedTable.getCTTable().getTableColumns().getTableColumnList().get(i);
if (tableCol.getCalculatedColumnFormula() != null) {
clonedTableCol.setCalculatedColumnFormula(tableCol.getCalculatedColumnFormula());
CTTableFormula calculatedColumnFormula = clonedTableCol.getCalculatedColumnFormula();
String formula = tableCol.getCalculatedColumnFormula().getStringValue();
String clonedFormula = formula.replace(table.getName(), clonedTable.getName());
calculatedColumnFormula.setStringValue(clonedFormula);
int rFirst = clonedTable.getStartCellReference().getRow() + clonedTable.getHeaderRowCount();
int rLast = clonedTable.getEndCellReference().getRow() - clonedTable.getTotalsRowCount();
int c = clonedTable.getStartCellReference().getCol() + i;
sheet.getWorkbook().setCellFormulaValidation(false);
for (int r = rFirst; r <= rLast; r++) {
XSSFRow row = sheet.getRow(r);
if (row == null) {
row = sheet.createRow(r);
// clone calculated column formulas
if (clonedTable.getCTTable().getTableColumns() != null
&& clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);
CTTableColumn clonedTableCol = clonedTable.getCTTable().getTableColumns().getTableColumnList().get(i);
if (tableCol.getCalculatedColumnFormula() != null) {
clonedTableCol.setCalculatedColumnFormula(tableCol.getCalculatedColumnFormula());
CTTableFormula calculatedColumnFormula = clonedTableCol.getCalculatedColumnFormula();
String formula = tableCol.getCalculatedColumnFormula().getStringValue();
String clonedFormula = formula.replace(table.getName(), clonedTable.getName());
calculatedColumnFormula.setStringValue(clonedFormula);
int rFirst = clonedTable.getStartCellReference().getRow() + clonedTable.getHeaderRowCount();
int rLast = clonedTable.getEndCellReference().getRow() - clonedTable.getTotalsRowCount();
int c = clonedTable.getStartCellReference().getCol() + i;
sheet.getWorkbook().setCellFormulaValidation(false);
for (int r = rFirst; r <= rLast; r++) {
XSSFRow row = sheet.getRow(r); if (row == null) row = sheet.createRow(r);
XSSFCell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellFormula(clonedFormula);
}
XSSFCell cell = row.getCell(c, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell.setCellFormula(clonedFormula);
}
}
}
}

// remove old table
String rId = sheet.getRelationId(table);
sheet.removeTable(table);
}
}

+ 3
- 2
poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java View File

@@ -508,13 +508,14 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {

boolean supportsAreaReference(final AreaReference tableArea) {
int rowCount = (tableArea.getLastCell().getRow() - tableArea.getFirstCell().getRow()) + 1;
int minimumRowCount = 1 + getHeaderRowCount() + getTotalsRowCount();
int headerRowCount = Math.max(1, getHeaderRowCount());
int minimumRowCount = 1 + headerRowCount + getTotalsRowCount();
return rowCount >= minimumRowCount;
}

/**
* Set the area reference for the cells which this table covers. The area
* includes includes header rows and totals rows.
* includes header rows and totals rows.
*
* Updating the area with this method will create new column as necessary to
* the right side of the table but will not modify any cell values.

+ 1
- 1
poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java View File

@@ -779,7 +779,7 @@ public final class TestXSSFTable {
XSSFSheet sheet0 = wb2.getSheetAt(0);
XSSFSheet sheet1 = wb2.getSheetAt(1);
assertEquals(1, sheet0.getTables().size());
assertEquals(1, sheet1.getTables().size());
assertEquals(0, sheet1.getTables().size());
}
}
}

Loading…
Cancel
Save