]> source.dussan.org Git - poi.git/commitdiff
Cell Style optimisations too
authorNick Burch <nick@apache.org>
Tue, 15 Jul 2008 21:38:38 +0000 (21:38 +0000)
committerNick Burch <nick@apache.org>
Tue, 15 Jul 2008 21:38:38 +0000 (21:38 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@677057 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/model/Workbook.java
src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
src/java/org/apache/poi/hssf/usermodel/HSSFOptimiser.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFOptimiser.java

index c9b4a0ee1af6dd092849fb8e7da159db8ece92e8..36510eb8352e1ff52fbd0d9b2042812f8e5bd9fc 100644 (file)
@@ -713,6 +713,18 @@ public class Workbook implements Model
 
         return retval;
     }
+    
+    /**
+     * Removes the given ExtendedFormatRecord record from the
+     *  file's list. This will make all 
+     *  subsequent font indicies drop by one,
+     *  so you'll need to update those yourself!
+     */
+    public void removeExFormatRecord(ExtendedFormatRecord rec) {
+       records.remove(rec); // this updates XfPos for us
+        numxfs--;
+    }
+
 
     /**
      * creates a new Cell-type Extneded Format Record and adds it to the end of
index 636c5406fda7726790ec26af80969a0f3ad85996..21335a8dd8bd8d9175f5d90b2262561ab1425621 100644 (file)
@@ -927,14 +927,13 @@ public class HSSFCell
      * object.
      * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
      */
-
     public HSSFCellStyle getCellStyle()
     {
       short styleIndex=record.getXFIndex();
       ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(styleIndex);
       return new HSSFCellStyle(styleIndex, xf, book);
     }
-
+    
     /**
      * used for internationalization, currently -1 for unchanged, 0 for compressed unicode or 1 for 16-bit
      *
index c01037ae491ea2630b6ccbc1063b9075794aee8b..f2c7acc414acb564277bf3fec930060d6317cf8f 100644 (file)
@@ -173,6 +173,89 @@ public class HSSFOptimiser {
         * @param workbook The workbook in which to optimise the cell styles
         */
        public static void optimiseCellStyles(HSSFWorkbook workbook) {
+               // Where each style has ended up, and if we need to
+               //  delete the record for it. Start off with no change
+               short[] newPos = 
+                       new short[workbook.getWorkbook().getNumExFormats()];
+               boolean[] zapRecords = new boolean[newPos.length];
+               for(int i=0; i<newPos.length; i++) {
+                       newPos[i] = (short)i;
+                       zapRecords[i] = false;
+               }
+               
+               // Get each style record, so we can do deletes
+               //  without getting confused
+               ExtendedFormatRecord[] xfrs = new ExtendedFormatRecord[newPos.length]; 
+               for(int i=0; i<newPos.length; i++) {
+                       xfrs[i] = workbook.getWorkbook().getExFormatAt(i);
+               }
+               
+               // Loop over each style, seeing if it is the same
+               //  as an earlier one. If it is, point users of the
+               //  later duplicate copy to the earlier one, and 
+               //  mark the later one as needing deleting
+               // Only work on user added ones, which come after 20
+               for(int i=21; i<newPos.length; i++) {
+                       // Check this one for being a duplicate
+                       //  of an earlier one
+                       int earlierDuplicate = -1;
+                       for(int j=0; j<i && earlierDuplicate == -1; j++) {
+                               ExtendedFormatRecord xfCheck = workbook.getWorkbook().getExFormatAt(j);
+                               if(xfCheck.equals(xfrs[i])) {
+                                       earlierDuplicate = j;
+                               }
+                       }
+                       
+                       // If we got a duplicate, mark it as such
+                       if(earlierDuplicate != -1) {
+                               newPos[i] = (short)earlierDuplicate;
+                               zapRecords[i] = true;
+                       }
+               }
+               
+               // Update the new positions based on
+               //  deletes that have occurred between
+               //  the start and them
+               // Only work on user added ones, which come after 20
+               for(int i=21; i<newPos.length; i++) {
+                       // Find the number deleted to that
+                       //  point, and adjust
+                       short preDeletePos = newPos[i];
+                       short newPosition = preDeletePos;
+                       for(int j=0; j<preDeletePos; j++) {
+                               if(zapRecords[j]) newPosition--;
+                       }
+                       
+                       // Update the new position
+                       newPos[i] = newPosition;
+               }
+               
+               // Zap the un-needed user style records
+               for(int i=21; i<newPos.length; i++) {
+                       if(zapRecords[i]) {
+                               workbook.getWorkbook().removeExFormatRecord(
+                                               xfrs[i]
+                               );
+                       }
+               }
                
+               // Finally, update the cells to point at
+               //  their new extended format records
+               for(int sheetNum=0; sheetNum<workbook.getNumberOfSheets(); sheetNum++) {
+                       HSSFSheet s = workbook.getSheetAt(sheetNum);
+                       Iterator rIt = s.rowIterator();
+                       while(rIt.hasNext()) {
+                               HSSFRow row = (HSSFRow)rIt.next();
+                               Iterator cIt = row.cellIterator();
+                               while(cIt.hasNext()) {
+                                       HSSFCell cell = (HSSFCell)cIt.next();
+                                       short oldXf = cell.getCellValueRecord().getXFIndex();
+                                       HSSFCellStyle newStyle = workbook.getCellStyleAt(
+                                                       newPos[oldXf]
+                                       );
+                                       cell.setCellStyle(newStyle);
+                               }
+                       }
+               }
        }
 }
index 7ba55e76fab5908dc4db590b508ca723c8ac9d25..b998fdd5191702df0cd5840e6a5719f8460a561a 100644 (file)
@@ -15,6 +15,8 @@
 ==================================================================== */
 package org.apache.poi.hssf.usermodel;
 
+import org.apache.poi.hssf.model.Workbook;
+
 import junit.framework.TestCase;
 
 public class TestHSSFOptimiser extends TestCase {
@@ -38,7 +40,7 @@ public class TestHSSFOptimiser extends TestCase {
                assertEquals(f, s.getFont(wb));
                
                // Optimise styles
-//             HSSFOptimiser.optimiseCellStyles(wb);
+               HSSFOptimiser.optimiseCellStyles(wb);
                
                assertEquals(5, wb.getNumberOfFonts());
                assertEquals(22, wb.getNumCellStyles());
@@ -77,6 +79,8 @@ public class TestHSSFOptimiser extends TestCase {
                
                
                // Use all three of the four in cell styles
+               assertEquals(21, wb.getNumCellStyles());
+               
                HSSFCellStyle cs1 = wb.createCellStyle();
                cs1.setFont(f1);
                assertEquals(5, cs1.getFontIndex());
@@ -93,6 +97,8 @@ public class TestHSSFOptimiser extends TestCase {
                cs4.setFont(f6);
                assertEquals(10, cs4.getFontIndex());
                
+               assertEquals(25, wb.getNumCellStyles());
+               
                
                // And three in rich text
                HSSFSheet s = wb.createSheet();
@@ -144,4 +150,91 @@ public class TestHSSFOptimiser extends TestCase {
                assertEquals(8, r.getCell(1).getRichStringCellValue().getFontAtIndex(6));
                assertEquals(8, r.getCell(1).getRichStringCellValue().getFontAtIndex(7));
        }
+       
+       public void testOptimiseStyles() throws Exception {
+               HSSFWorkbook wb = new HSSFWorkbook();
+
+               // Two fonts
+               assertEquals(4, wb.getNumberOfFonts());
+               
+               HSSFFont f1 = wb.createFont();
+               f1.setFontHeight((short)11);
+               f1.setFontName("Testing");
+               
+               HSSFFont f2 = wb.createFont();
+               f2.setFontHeight((short)22);
+               f2.setFontName("Also Testing");
+
+               assertEquals(6, wb.getNumberOfFonts());
+       
+               
+               // Several styles
+               assertEquals(21, wb.getNumCellStyles());
+               
+               HSSFCellStyle cs1 = wb.createCellStyle();
+               cs1.setFont(f1);
+               
+               HSSFCellStyle cs2 = wb.createCellStyle();
+               cs2.setFont(f2);
+               
+               HSSFCellStyle cs3 = wb.createCellStyle();
+               cs3.setFont(f1);
+               
+               HSSFCellStyle cs4 = wb.createCellStyle();
+               cs4.setFont(f1);
+               cs4.setAlignment((short)22);
+               
+               HSSFCellStyle cs5 = wb.createCellStyle();
+               cs5.setFont(f2);
+               cs5.setAlignment((short)111);
+               
+               HSSFCellStyle cs6 = wb.createCellStyle();
+               cs6.setFont(f2);
+               
+               assertEquals(27, wb.getNumCellStyles());
+               
+               
+               // Use them
+               HSSFSheet s = wb.createSheet();
+               HSSFRow r = s.createRow(0);
+               
+               r.createCell((short)0).setCellStyle(cs1);
+               r.createCell((short)1).setCellStyle(cs2);
+               r.createCell((short)2).setCellStyle(cs3);
+               r.createCell((short)3).setCellStyle(cs4);
+               r.createCell((short)4).setCellStyle(cs5);
+               r.createCell((short)5).setCellStyle(cs6);
+               r.createCell((short)6).setCellStyle(cs1);
+               r.createCell((short)7).setCellStyle(cs2);
+               
+               assertEquals(21, r.getCell(0).getCellValueRecord().getXFIndex());
+               assertEquals(26, r.getCell(5).getCellValueRecord().getXFIndex());
+               assertEquals(21, r.getCell(6).getCellValueRecord().getXFIndex());
+               
+               
+               // Optimise
+               HSSFOptimiser.optimiseCellStyles(wb);
+               
+               
+               // Check
+               assertEquals(6, wb.getNumberOfFonts());
+               assertEquals(25, wb.getNumCellStyles());
+               
+               // cs1 -> 21
+               assertEquals(21, r.getCell(0).getCellValueRecord().getXFIndex());
+               // cs2 -> 22
+               assertEquals(22, r.getCell(1).getCellValueRecord().getXFIndex());
+               // cs3 = cs1 -> 21
+               assertEquals(21, r.getCell(2).getCellValueRecord().getXFIndex());
+               // cs4 --> 24 -> 23
+               assertEquals(23, r.getCell(3).getCellValueRecord().getXFIndex());
+               // cs5 --> 25 -> 24
+               assertEquals(24, r.getCell(4).getCellValueRecord().getXFIndex());
+               // cs6 = cs2 -> 22
+               assertEquals(22, r.getCell(5).getCellValueRecord().getXFIndex());
+               // cs1 -> 21
+               assertEquals(21, r.getCell(6).getCellValueRecord().getXFIndex());
+               // cs2 -> 22
+               assertEquals(22, r.getCell(7).getCellValueRecord().getXFIndex());
+       }
 }