]> source.dussan.org Git - poi.git/commitdiff
optimized serialization of XSSFRow - avoid re-ordering of CTCell beans if they are...
authorYegor Kozlov <yegor@apache.org>
Sat, 29 May 2010 10:28:04 +0000 (10:28 +0000)
committerYegor Kozlov <yegor@apache.org>
Sat, 29 May 2010 10:28:04 +0000 (10:28 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@949375 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java

index 61535c5cd3bbc9c162ced7091a0d98255df9d1c8..f43a05fadf0b9f42a24810dfe15116d5de649d5e 100644 (file)
@@ -18,6 +18,7 @@
 package org.apache.poi.xssf.usermodel;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.TreeMap;
 
@@ -384,20 +385,37 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
 
     /**
      * Fired when the document is written to an output stream.
-     * <p>
-     * Attaches CTCell beans to the underlying CTRow bean
-     * </p>
-     * @see org.apache.poi.xssf.usermodel.XSSFSheet#commit()
+     *
+     * @see org.apache.poi.xssf.usermodel.XSSFSheet#write(java.io.OutputStream) ()
      */
     protected void onDocumentWrite(){
-        ArrayList<CTCell> cArray = new ArrayList<CTCell>(_cells.size());
-        //create array of CTCell objects.
-        //TreeMap's value iterator ensures that the cells are ordered by columnIndex in the ascending order
-        for (Cell cell : _cells.values()) {
-            XSSFCell c = (XSSFCell)cell;
-            cArray.add(c.getCTCell());
+        // check if cells in the CTRow are ordered
+        boolean isOrdered = true;
+        if(_row.sizeOfCArray() != _cells.size()) isOrdered = false;
+        else {
+            int i = 0;
+            CTCell[] xcell = _row.getCArray();
+            for (XSSFCell cell : _cells.values()) {
+                CTCell c1 = cell.getCTCell();
+                CTCell c2 = xcell[i++];
+
+                String r1 = c1.getR();
+                String r2 = c2.getR();
+                if (!(r1==null ? r2==null : r1.equals(r2))){
+                    isOrdered = false;
+                    break;
+                }
+            }
+        }
+
+        if(!isOrdered){
+            CTCell[] cArray = new CTCell[_cells.size()];
+            int i = 0;
+            for (XSSFCell c : _cells.values()) {
+                cArray[i++] = c.getCTCell();
+            }
+            _row.setCArray(cArray);
         }
-        _row.setCArray(cArray.toArray(new CTCell[cArray.size()]));
     }
 
     /**
index 460055369053824c53f53d5c691c33a7e6b411c5..34db7c403e41f5c4b91e36ec41c7c99e5ec3c4e3 100644 (file)
@@ -2464,20 +2464,28 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         // rows in the internal model (_rows) are always ordered while
         // CTRow beans held by CTSheetData may be not, for example, user can
         // insert rows in random order, shift rows after insertion, etc.
-        Integer [] curRows = new Integer[sheetData.sizeOfRowArray()];
-        int i = 0;
-        for(CTRow ctrow : sheetData.getRowArray()){
-            curRows[i++] = (int)(ctrow.getR() - 1);
-        }
-        Integer [] ordRows = _rows.keySet().toArray(new Integer[_rows.size()]);
-        if(!Arrays.equals(curRows, ordRows)){
-            // The order of rows in CTSheetData and internal model does not match 
-            CTRow[] orderedCTRows = new CTRow[_rows.size()];
-            i = 0;
+        boolean isOrdered = true;
+        if(sheetData.sizeOfRowArray() != _rows.size()) isOrdered = false;
+        else {
+            int i = 0;
+            CTRow[] xrow = sheetData.getRowArray();
+            for (XSSFRow row : _rows.values()) {
+                CTRow c1 = row.getCTRow();
+                CTRow c2 = xrow[i++];
+                if (c1.getR() != c2.getR()){
+                    isOrdered = false;
+                    break;
+                }
+            }
+        }
+        
+        if(!isOrdered){
+            CTRow[] cArray = new CTRow[_rows.size()];
+            int i = 0;
             for(XSSFRow row : _rows.values()){
-                orderedCTRows[i++] = row.getCTRow();
+                cArray[i++] = row.getCTRow();
             }
-            sheetData.setRowArray(orderedCTRows);
+            sheetData.setRowArray(cArray);
         }
     }
 
index c1302812ed4af2568ff08dc1de28eec06ee54d01..db4a26c493809e3f33462f737090e52a20a596b0 100644 (file)
@@ -24,13 +24,7 @@ import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.model.CommentsTable;
 import org.apache.poi.xssf.model.StylesTable;
 import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
 
 
 public final class TestXSSFSheet extends BaseTestSheet {
@@ -894,21 +888,84 @@ public final class TestXSSFSheet extends BaseTestSheet {
         assertSame(comment1, sheet1.getCommentsTable(true));
     }
 
+    /**
+     * Rows and cells can be created in random order,
+     * but serialization forces strict ascending order of the CTRow and CTCell xml beans
+     */
     public void testCreateRow() {
         XSSFWorkbook workbook = new XSSFWorkbook();
         XSSFSheet sheet = workbook.createSheet();
         CTWorksheet wsh = sheet.getCTWorksheet();
-        assertEquals(0, wsh.getSheetData().sizeOfRowArray());
-        XSSFRow row1 = sheet.createRow(1);
-        row1.createCell(1);
+        CTSheetData sheetData = wsh.getSheetData();
+        assertEquals(0, sheetData.sizeOfRowArray());
+
+        XSSFRow row1 = sheet.createRow(2);
         row1.createCell(2);
-        assertEquals(1, wsh.getSheetData().sizeOfRowArray());
-        assertEquals(2, wsh.getSheetData().getRowArray(0).sizeOfCArray());
+        row1.createCell(1);
+
+        XSSFRow row2 = sheet.createRow(1);
+        row2.createCell(2);
+        row2.createCell(1);
+        row2.createCell(0);
+
+        XSSFRow row3 = sheet.createRow(0);
+        row3.createCell(3);
+        row3.createCell(0);
+        row3.createCell(2);
+        row3.createCell(5);
+
+
+        CTRow[] xrow = sheetData.getRowArray();
+        assertEquals(3, xrow.length);
+
+        //rows are unsorted: {2, 1, 0}
+        assertEquals(2, xrow[0].sizeOfCArray());
+        assertEquals(3, xrow[0].getR());
+        assertTrue(xrow[0].equals(row1.getCTRow()));
+
+        assertEquals(3, xrow[1].sizeOfCArray());
+        assertEquals(2, xrow[1].getR());
+        assertTrue(xrow[1].equals(row2.getCTRow()));
+
+        assertEquals(4, xrow[2].sizeOfCArray());
+        assertEquals(1, xrow[2].getR());
+        assertTrue(xrow[2].equals(row3.getCTRow()));
+
+        CTCell[] xcell = xrow[2].getCArray();
+        assertEquals("D1", xcell[0].getR());
+        assertEquals("A1", xcell[1].getR());
+        assertEquals("C1", xcell[2].getR());
+        assertEquals("F1", xcell[3].getR());
 
         //re-creating a row does NOT add extra data to the parent
-        sheet.createRow(1);
-        assertEquals(1, wsh.getSheetData().sizeOfRowArray());
+        row2 = sheet.createRow(1);
+        assertEquals(3, sheetData.sizeOfRowArray());
         //existing cells are invalidated
-        assertEquals(0, wsh.getSheetData().getRowArray(0).sizeOfCArray());
+        assertEquals(0, sheetData.getRowArray(1).sizeOfCArray());
+        assertEquals(0, row2.getPhysicalNumberOfCells());
+
+        workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook);
+        sheet = workbook.getSheetAt(0);
+        wsh = sheet.getCTWorksheet();
+        xrow = sheetData.getRowArray();
+        assertEquals(3, xrow.length);
+
+        //rows are sorted: {0, 1, 2}
+        assertEquals(4, xrow[0].sizeOfCArray());
+        assertEquals(1, xrow[0].getR());
+        //cells are now sorted
+        xcell = xrow[0].getCArray();
+        assertEquals("A1", xcell[0].getR());
+        assertEquals("C1", xcell[1].getR());
+        assertEquals("D1", xcell[2].getR());
+        assertEquals("F1", xcell[3].getR());
+
+
+        assertEquals(0, xrow[1].sizeOfCArray());
+        assertEquals(2, xrow[1].getR());
+
+        assertEquals(2, xrow[2].sizeOfCArray());
+        assertEquals(3, xrow[2].getR());
+
     }
 }