]> source.dussan.org Git - poi.git/commitdiff
[bug-66213] hack clone table code to avoid failing with edge cases
authorPJ Fanning <fanningpj@apache.org>
Sat, 13 Aug 2022 18:11:16 +0000 (18:11 +0000)
committerPJ Fanning <fanningpj@apache.org>
Sat, 13 Aug 2022 18:11:16 +0000 (18:11 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1903398 13f79535-47bb-0310-9956-ffa450edef68

poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java
poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java
src/resources/ooxml-lite-report.clazz

index 6cb0a79096a8ed62255a0251f5413885e46f0460..f3a91566094f30ec42f503b1e1ca312231d9a834 100644 (file)
@@ -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);
index 54f8752b91ab789697394b99a798fc1a491603d2..66d6898e456354945fa6f9eedc8ebdcd78b3d557 100644 (file)
@@ -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<XSSFXmlColumnPr> xmlColumnPrs;
     private transient List<XSSFTableColumn> 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");
         }
index e7f6f571737c8fd0330eb6f77093d319c52bf68c..4e716c55779d5144dbb6fbeb8320f281c8a36c65 100644 (file)
@@ -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());
+                }
+            }
+        }
+    }
 }
index 811deff38aa650178b3527dd8bfcea8cf6895757..b9916cc5cf4c9ee5c575e6d9cc32afc729f7225f 100644 (file)
@@ -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