Author: fanningpj
Date: Sun Aug 14 09:47:16 2022
New Revision: 1903409

URL: http://svn.apache.org/viewvc?rev=1903409&view=rev
Log:
[bug-66213] hack clone table code to avoid failing with edge cases

Modified:
    
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
    
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java
    
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java

Modified: 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java?rev=1903409&r1=1903408&r2=1903409&view=diff
==============================================================================
--- 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java 
(original)
+++ 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java 
Sun Aug 14 09:47:16 2022
@@ -4302,6 +4302,7 @@ public class XSSFSheet extends POIXMLDoc
      * @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 POIXMLDoc
             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 POIXMLDoc
 
     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 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().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 table; XSSFTable.setArea fails and throws exception for 
too small tables
+            XSSFTable clonedTable = null;
+            if (table.supportsAreaReference(table.getArea())) {
+                clonedTable = sheet.createTable(table.getArea());
+            }
+
+            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 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);
         }
     }

Modified: 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java?rev=1903409&r1=1903408&r2=1903409&view=diff
==============================================================================
--- 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java 
(original)
+++ 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java 
Sun Aug 14 09:47:16 2022
@@ -508,13 +508,14 @@ public class XSSFTable extends POIXMLDoc
 
     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.

Modified: 
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java?rev=1903409&r1=1903408&r2=1903409&view=diff
==============================================================================
--- 
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java
 (original)
+++ 
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java
 Sun Aug 14 09:47:16 2022
@@ -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());
                 }
             }
         }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to