]> source.dussan.org Git - poi.git/commitdiff
Hopefully fix #45672 properly - improve handling by MissingRecordAwareHSSFListener...
authorNick Burch <nick@apache.org>
Tue, 3 Nov 2009 22:45:39 +0000 (22:45 +0000)
committerNick Burch <nick@apache.org>
Tue, 3 Nov 2009 22:45:39 +0000 (22:45 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@832584 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java
src/java/org/apache/poi/hssf/record/MulBlankRecord.java
src/java/org/apache/poi/hssf/record/RecordFactory.java
src/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java
test-data/spreadsheet/45672.xls [new file with mode: 0644]

index 0cd747f15d7fb1594e9e8542879aa748c5efc788..2d9fe5a3dd2445556928640e71c2f8e20f35ba23 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.6-beta1" date="2009-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45672 - improve handling by MissingRecordAwareHSSFListener of records that cover multiple cells (MulBlankRecord and MulRKRecord)</action>
            <action dev="POI-DEVELOPERS" type="fix">48096 - relaxed validation check in RecalcIdRecord</action>
            <action dev="POI-DEVELOPERS" type="fix">48085 - improved error checking in BlockAllocationTableReader to trap unreasonable field values</action>
            <action dev="POI-DEVELOPERS" type="fix">47924 - fixed logic for matching cells and comments in HSSFCell.getCellComment()</action>
index e41b0b92aea08917802ef8a48e43a3dcc03b58e9..7da8ee5e20b0397223ace38fbe41cbea1b0bd29d 100644 (file)
@@ -21,9 +21,14 @@ import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
 import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
 import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord;
 import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.BlankRecord;
 import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.MulBlankRecord;
+import org.apache.poi.hssf.record.MulRKRecord;
 import org.apache.poi.hssf.record.NoteRecord;
+import org.apache.poi.hssf.record.NumberRecord;
 import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordFactory;
 import org.apache.poi.hssf.record.RowRecord;
 import org.apache.poi.hssf.record.SharedFormulaRecord;
 
@@ -62,7 +67,7 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener {
        public void processRecord(Record record) {
                int thisRow;
                int thisColumn;
-
+               CellValueRecordInterface[] expandedRecords = null;
 
                if (record instanceof CellValueRecordInterface) {
                        CellValueRecordInterface valueRec = (CellValueRecordInterface) record;
@@ -105,6 +110,19 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener {
                                        // - so don't fire off the LastCellOfRowDummyRecord yet
                                        childListener.processRecord(record);
                                        return;
+                               case MulBlankRecord.sid:
+                                       // These appear in the middle of the cell records, to
+                                       //  specify that the next bunch are empty but styled
+                                       // Expand this out into multiple blank cells
+                                       MulBlankRecord mbr = (MulBlankRecord)record;
+                                       expandedRecords = RecordFactory.convertBlankRecords(mbr);
+                                       break;
+                               case MulRKRecord.sid:
+                                       // This is multiple consecutive number cells in one record
+                                       // Exand this out into multiple regular number cells
+                                       MulRKRecord mrk = (MulRKRecord)record;
+                                       expandedRecords = RecordFactory.convertRKRecords(mrk);
+                                       break;
                                case NoteRecord.sid:
                                        NoteRecord nrec = (NoteRecord) record;
                                        thisRow = nrec.getRow();
@@ -112,6 +130,13 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener {
                                        break;
                        }
                }
+               
+               // First part of expanded record handling
+               if(expandedRecords != null && expandedRecords.length > 0) {
+                       thisRow = expandedRecords[0].getRow();
+                       thisColumn = expandedRecords[0].getColumn();
+               }
+               
                // If we're on cells, and this cell isn't in the same
                //  row as the last one, then fire the 
                //  dummy end-of-row records
@@ -148,13 +173,26 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener {
                        }
                }
                
+               // Next part of expanded record handling
+               if(expandedRecords != null && expandedRecords.length > 0) {
+                       thisColumn = expandedRecords[expandedRecords.length-1].getColumn();
+               }
+
+               
                // Update cell and row counts as needed
                if(thisColumn != -1) {
                        lastCellColumn = thisColumn;
                        lastCellRow = thisRow;
                }
 
-               childListener.processRecord(record);
+               // Pass along the record(s)
+               if(expandedRecords != null && expandedRecords.length > 0) {
+                       for(CellValueRecordInterface r : expandedRecords) {
+                               childListener.processRecord((Record)r);
+                       }
+               } else {
+                       childListener.processRecord(record);
+               }
        }
 
        private void resetCounts() {
index 87d4eafeacca6f94c08bf087378923576d1a01b6..695c55c877c148876d7bf939ba85a3b7ce6177e5 100644 (file)
@@ -56,6 +56,13 @@ public final class MulBlankRecord extends StandardRecord {
        public int getFirstColumn() {
                return _firstCol;
        }
+       
+       /**
+        * @return ending column (last cell this holds in the row). Zero based
+        */
+       public int getLastColumn() {
+               return _lastCol;
+       }
 
        /**
         * get the number of columns this contains (last-first +1)
index 3d200e7ef4ec945503a976a248cb8b68c30e7e07..85f3a082e4f6d73b716b6d85d22cec39131cc532 100644 (file)
@@ -281,7 +281,6 @@ public final class RecordFactory {
         * Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord}s
         */
        public static NumberRecord[] convertRKRecords(MulRKRecord mrk) {
-
                NumberRecord[] mulRecs = new NumberRecord[mrk.getNumColumns()];
                for (int k = 0; k < mrk.getNumColumns(); k++) {
                        NumberRecord nr = new NumberRecord();
@@ -295,6 +294,22 @@ public final class RecordFactory {
                return mulRecs;
        }
 
+       /**
+        * Converts a {@link MulBlankRecord} into an equivalent array of {@link BlankRecord}s
+        */
+       public static BlankRecord[] convertBlankRecords(MulBlankRecord mbk) {
+               BlankRecord[] mulRecs = new BlankRecord[mbk.getNumColumns()];
+               for (int k = 0; k < mbk.getNumColumns(); k++) {
+                       BlankRecord br = new BlankRecord();
+
+                       br.setColumn((short) (k + mbk.getFirstColumn()));
+                       br.setRow(mbk.getRow());
+                       br.setXFIndex(mbk.getXFAt(k));
+                       mulRecs[k] = br;
+               }
+               return mulRecs;
+       }
+
        /**
         * @return an array of all the SIDS for all known records
         */
index aa4bbcc6f0e37597d4b32103435e9395e07278a7..e632cbbbb1091107802b5b1889593c029de1e39d 100644 (file)
@@ -29,7 +29,9 @@ import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
 import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
 import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord;
 import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.BlankRecord;
 import org.apache.poi.hssf.record.LabelSSTRecord;
+import org.apache.poi.hssf.record.MulBlankRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RowRecord;
 import org.apache.poi.hssf.record.SharedFormulaRecord;
@@ -422,4 +424,41 @@ public final class TestMissingRecordAwareHSSFListener extends TestCase {
                assertEquals(1, eorCount);
                assertEquals(1, sfrCount);
        }
+       
+       /**
+        * MulBlank records hold multiple blank cells. Check we
+        *  can handle them correctly.
+        */
+       public void testMulBlankHandling() {
+               readRecords("45672.xls");
+               
+               // Check that we don't have any MulBlankRecords, but do
+               //  have lots of BlankRecords
+               Record[] rr = r;
+               int eorCount=0;
+               int mbrCount=0;
+               int brCount=0;
+               for (int i = 0; i < rr.length; i++) {
+                       Record record = rr[i];
+                       if (record instanceof MulBlankRecord) {
+                               mbrCount++;
+                       }
+                       if (record instanceof BlankRecord) {
+                               brCount++;
+                       }
+                       if (record instanceof LastCellOfRowDummyRecord) {
+                               eorCount++;
+                       }
+               }
+               if (mbrCount > 0) {
+                       throw new AssertionFailedError("Identified bug 45672");
+               }
+               if (brCount < 20) {
+                       throw new AssertionFailedError("Identified bug 45672");
+               }
+               if (eorCount != 2) {
+                       throw new AssertionFailedError("Identified bug 45672");
+               }
+               assertEquals(2, eorCount);
+       }
 }
diff --git a/test-data/spreadsheet/45672.xls b/test-data/spreadsheet/45672.xls
new file mode 100644 (file)
index 0000000..752ce5d
Binary files /dev/null and b/test-data/spreadsheet/45672.xls differ