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@1903398 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_5_2_3
PJ Fanning 1 year ago
parent
commit
6d2853d9bd

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



tables.put(tbl.getId(), table); tables.put(tbl.getId(), table);


if(tableArea != null) {
if(tableArea != null && table.supportsAreaReference(tableArea)) {
table.setArea(tableArea); table.setArea(tableArea);
} }


} }


// clone calculated column formulas // clone calculated column formulas
if (clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
if (clonedTable.getCTTable().getTableColumns() != null
&& clonedTable.getCTTable().getTableColumns().getTableColumnList().size() > 0) {
clonedTable.getCTTable().setTotalsRowCount(totalsRowCount); clonedTable.getCTTable().setTotalsRowCount(totalsRowCount);
for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) { for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) {
CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i); CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i);

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

import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListMap;


import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.ooxml.POIXMLDocumentPart; import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.SpreadsheetVersion;
*/ */
public class XSSFTable extends POIXMLDocumentPart implements Table { public class XSSFTable extends POIXMLDocumentPart implements Table {


private static final Logger LOG = LogManager.getLogger(XSSFTable.class);

private CTTable ctTable; private CTTable ctTable;
private transient List<XSSFXmlColumnPr> xmlColumnPrs; private transient List<XSSFXmlColumnPr> xmlColumnPrs;
private transient List<XSSFTableColumn> tableColumns; private transient List<XSSFTableColumn> tableColumns;
public void setStyleName(String newStyleName) { public void setStyleName(String newStyleName) {
if (newStyleName == null) { if (newStyleName == null) {
if (ctTable.isSetTableStyleInfo()) { if (ctTable.isSetTableStyleInfo()) {
ctTable.getTableStyleInfo().unsetName();
try {
ctTable.getTableStyleInfo().unsetName();
} catch (Exception e) {
LOG.atDebug().log("Failed to unset style name", e);
}
} }
styleName = null; styleName = null;
return; return;
updateHeaders(); updateHeaders();
} }


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

/** /**
* Set the area reference for the cells which this table covers. The area * Set the area reference for the cells which this table covers. The area
* includes includes header rows and totals rows. * includes includes header rows and totals rows.
"The AreaReference must not reference a different sheet"); "The AreaReference must not reference a different sheet");
} }


int rowCount = (tableArea.getLastCell().getRow() - tableArea.getFirstCell().getRow()) + 1;
int minimumRowCount = 1 + getHeaderRowCount() + getTotalsRowCount();
if (rowCount < minimumRowCount) {
if (!supportsAreaReference(tableArea)) {
int minimumRowCount = 1 + getHeaderRowCount() + getTotalsRowCount();
throw new IllegalArgumentException("AreaReference needs at least " + minimumRowCount throw new IllegalArgumentException("AreaReference needs at least " + minimumRowCount
+ " rows, to cover at least one data row and all header rows and totals rows"); + " rows, to cover at least one data row and all header rows and totals rows");
} }

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

} }
} }
} }

@Test
void testCloneConditionalFormattingSamples() throws IOException {
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("ConditionalFormattingSamples.xlsx")) {
wb.cloneSheet(0, "Test");
try (UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) {
wb.write(bos);
try (XSSFWorkbook wb2 = new XSSFWorkbook(bos.toInputStream())) {
XSSFSheet sheet0 = wb2.getSheetAt(0);
XSSFSheet sheet1 = wb2.getSheetAt(1);
assertEquals(0, sheet0.getTables().size());
assertEquals(0, sheet1.getTables().size());
}
}
}
}

@Test
void testCloneSingleCellTable() throws IOException {
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("SingleCellTable.xlsx")) {
wb.cloneSheet(0, "Test");
try (UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) {
wb.write(bos);
try (XSSFWorkbook wb2 = new XSSFWorkbook(bos.toInputStream())) {
XSSFSheet sheet0 = wb2.getSheetAt(0);
XSSFSheet sheet1 = wb2.getSheetAt(1);
assertEquals(1, sheet0.getTables().size());
assertEquals(1, sheet1.getTables().size());
}
}
}
}
} }

+ 4
- 0
src/resources/ooxml-lite-report.clazz View File

org/openxmlformats/schemas/drawingml/x2006/chart/STDLblPos$Enum org/openxmlformats/schemas/drawingml/x2006/chart/STDLblPos$Enum
org/openxmlformats/schemas/drawingml/x2006/chart/impl/STDLblPosImpl org/openxmlformats/schemas/drawingml/x2006/chart/impl/STDLblPosImpl
org/openxmlformats/schemas/drawingml/x2006/chart/STDLblPos org/openxmlformats/schemas/drawingml/x2006/chart/STDLblPos
org/openxmlformats/schemas/spreadsheetml/x2006/main/impl/STTotalsRowFunctionImpl
org/openxmlformats/schemas/spreadsheetml/x2006/main/STTotalsRowFunction
org/openxmlformats/schemas/spreadsheetml/x2006/main/impl/CTTableFormulaImpl
org/openxmlformats/schemas/spreadsheetml/x2006/main/CTTableFormula

Loading…
Cancel
Save