From: PJ Fanning Date: Sat, 13 Aug 2022 18:11:16 +0000 (+0000) Subject: [bug-66213] hack clone table code to avoid failing with edge cases X-Git-Tag: REL_5_2_3~71 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6d2853d9bd5041b2e2938d5bc4cf4657cb33e86e;p=poi.git [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 --- diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 6cb0a79096..f3a9156609 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -4271,7 +4271,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx tables.put(tbl.getId(), table); - if(tableArea != null) { + if(tableArea != null && table.supportsAreaReference(tableArea)) { table.setArea(tableArea); } @@ -4921,7 +4921,8 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx } // 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); for (int i = 0; i < clonedTable.getCTTable().getTableColumns().getTableColumnList().size(); i++) { CTTableColumn tableCol = table.getCTTable().getTableColumns().getTableColumnList().get(i); diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java index 54f8752b91..66d6898e45 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java @@ -28,6 +28,8 @@ import java.util.Collections; import java.util.List; 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.openxml4j.opc.PackagePart; import org.apache.poi.ss.SpreadsheetVersion; @@ -56,6 +58,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.TableDocument; */ public class XSSFTable extends POIXMLDocumentPart implements Table { + private static final Logger LOG = LogManager.getLogger(XSSFTable.class); + private CTTable ctTable; private transient List xmlColumnPrs; private transient List tableColumns; @@ -399,7 +403,11 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { public void setStyleName(String newStyleName) { if (newStyleName == null) { if (ctTable.isSetTableStyleInfo()) { - ctTable.getTableStyleInfo().unsetName(); + try { + ctTable.getTableStyleInfo().unsetName(); + } catch (Exception e) { + LOG.atDebug().log("Failed to unset style name", e); + } } styleName = null; return; @@ -498,6 +506,12 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { 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 * includes includes header rows and totals rows. @@ -525,9 +539,8 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { "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 + " rows, to cover at least one data row and all header rows and totals rows"); } diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java index e7f6f57173..4e716c5577 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java @@ -752,4 +752,36 @@ public final class TestXSSFTable { } } } + + @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()); + } + } + } + } } diff --git a/src/resources/ooxml-lite-report.clazz b/src/resources/ooxml-lite-report.clazz index 811deff38a..b9916cc5cf 100644 --- a/src/resources/ooxml-lite-report.clazz +++ b/src/resources/ooxml-lite-report.clazz @@ -2513,3 +2513,7 @@ org/openxmlformats/schemas/drawingml/x2006/chart/CTDLblPos org/openxmlformats/schemas/drawingml/x2006/chart/STDLblPos$Enum org/openxmlformats/schemas/drawingml/x2006/chart/impl/STDLblPosImpl 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