diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 815bbb095..c9b7f86fb 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,7 @@ + Include the sheet name in the output of examples.XLS2CSVmra 45784 - Support long chart titles in SeriesTextRecords 45777 - Throw an exception if HSSF Footer or Header is attemped to be set too long, rather than having it break during writing out 45844 - Addtional diagnostics for HSLF SlideShowRecordDumper diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 338849914..ae6a90ae0 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + Include the sheet name in the output of examples.XLS2CSVmra 45784 - Support long chart titles in SeriesTextRecords 45777 - Throw an exception if HSSF Footer or Header is attemped to be set too long, rather than having it break during writing out 45844 - Addtional diagnostics for HSLF SlideShowRecordDumper diff --git a/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java b/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java index 27b432067..2bf618749 100644 --- a/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java +++ b/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java @@ -21,6 +21,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; +import java.util.ArrayList; import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; @@ -34,6 +35,7 @@ import org.apache.poi.hssf.model.HSSFFormulaParser; import org.apache.poi.hssf.record.BOFRecord; import org.apache.poi.hssf.record.BlankRecord; import org.apache.poi.hssf.record.BoolErrRecord; +import org.apache.poi.hssf.record.BoundSheetRecord; import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.LabelRecord; import org.apache.poi.hssf.record.LabelSSTRecord; @@ -69,6 +71,11 @@ public class XLS2CSVmra implements HSSFListener { // Records we pick up as we process private SSTRecord sstRecord; private FormatTrackingHSSFListener formatListener; + + /** So we known which sheet we're on */ + private int sheetIndex = -1; + private BoundSheetRecord[] orderedBSRs; + private ArrayList boundSheetRecords = new ArrayList(); // For handling formulas with string results private int nextRow; @@ -132,6 +139,9 @@ public class XLS2CSVmra implements HSSFListener { switch (record.getSid()) { + case BoundSheetRecord.sid: + boundSheetRecords.add(record); + break; case BOFRecord.sid: BOFRecord br = (BOFRecord)record; if(br.getType() == BOFRecord.TYPE_WORKSHEET) { @@ -139,6 +149,17 @@ public class XLS2CSVmra implements HSSFListener { if(workbookBuildingListener != null && stubWorkbook == null) { stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook(); } + + // Output the worksheet name + // Works by ordering the BSRs by the location of + // their BOFRecords, and then knowing that we + // process BOFRecords in byte offset order + sheetIndex++; + if(orderedBSRs == null) { + orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords); + } + output.println(); + output.println(orderedBSRs[sheetIndex].getSheetname() + ":"); } break; diff --git a/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java b/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java index 1f7106ad7..412e991d2 100644 --- a/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java +++ b/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java @@ -17,6 +17,10 @@ package org.apache.poi.hssf.record; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + import org.apache.poi.util.BitField; import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.LittleEndian; @@ -329,4 +333,31 @@ public final class BoundSheetRecord extends Record { public void setVeryHidden(boolean veryHidden) { field_2_option_flags = veryHiddenFlag.setShortBoolean(field_2_option_flags, veryHidden); } + + /** + * Takes a list of BoundSheetRecords, and returns the all + * ordered by the position of their BOFs. + */ + public static BoundSheetRecord[] orderByBofPosition(List boundSheetRecords) { + BoundSheetRecord[] bsrs = (BoundSheetRecord[])boundSheetRecords.toArray( + new BoundSheetRecord[boundSheetRecords.size()]); + + // Sort + Arrays.sort(bsrs, new BOFComparator()); + + // All done + return bsrs; + } + private static class BOFComparator implements Comparator { + public int compare(Object bsr1, Object bsr2) { + return compare((BoundSheetRecord)bsr1, (BoundSheetRecord)bsr2); + } + public int compare(BoundSheetRecord bsr1, BoundSheetRecord bsr2) { + if(bsr1.field_1_position_of_BOF < bsr2.field_1_position_of_BOF) + return -1; + if(bsr1.field_1_position_of_BOF == bsr2.field_1_position_of_BOF) + return 0; + return 1; + } + } } diff --git a/src/testcases/org/apache/poi/hssf/record/TestBOFRecord.java b/src/testcases/org/apache/poi/hssf/record/TestBOFRecord.java index 843e17d2a..99a004b73 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestBOFRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestBOFRecord.java @@ -18,6 +18,7 @@ package org.apache.poi.hssf.record; import java.io.InputStream; +import java.util.ArrayList; import junit.framework.AssertionFailedError; import junit.framework.TestCase; @@ -38,4 +39,24 @@ public final class TestBOFRecord extends TestCase { throw new AssertionFailedError("Identified bug 42794"); } } + + public void testOrdering() throws Exception { + BoundSheetRecord bs1 = new BoundSheetRecord(); + BoundSheetRecord bs2 = new BoundSheetRecord(); + BoundSheetRecord bs3 = new BoundSheetRecord(); + bs1.setPositionOfBof(11); + bs2.setPositionOfBof(33); + bs3.setPositionOfBof(22); + + ArrayList l = new ArrayList(); + l.add(bs1); + l.add(bs2); + l.add(bs3); + + BoundSheetRecord[] r = BoundSheetRecord.orderByBofPosition(l); + assertEquals(3, r.length); + assertEquals(bs1, r[0]); + assertEquals(bs3, r[1]); + assertEquals(bs2, r[2]); + } }