From 77bf6ef42bb212897d9b8691c39825cb0b70c9d8 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sun, 30 Nov 2014 15:54:34 +0000 Subject: [PATCH] Track what Biff version we are working on, and use that to work around Biff 2 and 5 having the same formula record sid for different layouts git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1642556 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hssf/extractor/OldExcelExtractor.java | 37 +++++++++++++++++-- .../org/apache/poi/hssf/record/BOFRecord.java | 9 ++++- .../hssf/extractor/TestOldExcelExtractor.java | 7 +++- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java b/src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java index 619b12a53..f1a28479e 100644 --- a/src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java +++ b/src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java @@ -24,6 +24,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import org.apache.poi.hssf.record.BOFRecord; +import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.NumberRecord; import org.apache.poi.hssf.record.OldFormulaRecord; import org.apache.poi.hssf.record.OldLabelRecord; @@ -48,6 +50,7 @@ import org.apache.poi.ss.usermodel.Cell; public class OldExcelExtractor { private RecordInputStream ris; private Closeable input; + private int biffVersion; public OldExcelExtractor(InputStream input) throws IOException { BufferedInputStream bstream = new BufferedInputStream(input, 8); @@ -107,8 +110,26 @@ public class OldExcelExtractor { * for these old file formats */ public String getText() { - StringBuffer text = new StringBuffer(); + // Work out what version we're dealing with + int bofSid = ris.getNextSid(); + switch (bofSid) { + case BOFRecord.biff2_sid: + biffVersion = 2; + break; + case BOFRecord.biff3_sid: + biffVersion = 3; + break; + case BOFRecord.biff4_sid: + biffVersion = 4; + break; + case BOFRecord.biff5_sid: + biffVersion = 5; + break; + default: + throw new IllegalArgumentException("File does not begin with a BOF, found sid of " + bofSid); + } + StringBuffer text = new StringBuffer(); while (ris.hasNextRecord()) { int sid = ris.getNextSid(); ris.nextRecord(); @@ -136,9 +157,17 @@ public class OldExcelExtractor { case OldFormulaRecord.biff2_sid: case OldFormulaRecord.biff3_sid: case OldFormulaRecord.biff4_sid: - OldFormulaRecord fr = new OldFormulaRecord(ris); - if (fr.getCachedResultType() == Cell.CELL_TYPE_NUMERIC) { - handleNumericCell(text, fr.getValue()); + // Biff 2 and 5+ share the same SID, due to a bug... + if (biffVersion == 5) { + FormulaRecord fr = new FormulaRecord(ris); + if (fr.getCachedResultType() == Cell.CELL_TYPE_NUMERIC) { + handleNumericCell(text, fr.getValue()); + } + } else { + OldFormulaRecord fr = new OldFormulaRecord(ris); + if (fr.getCachedResultType() == Cell.CELL_TYPE_NUMERIC) { + handleNumericCell(text, fr.getValue()); + } } break; case RKRecord.sid: diff --git a/src/java/org/apache/poi/hssf/record/BOFRecord.java b/src/java/org/apache/poi/hssf/record/BOFRecord.java index 0e415c9c0..f6a36bf7f 100644 --- a/src/java/org/apache/poi/hssf/record/BOFRecord.java +++ b/src/java/org/apache/poi/hssf/record/BOFRecord.java @@ -31,9 +31,16 @@ import org.apache.poi.util.LittleEndianOutput; */ public final class BOFRecord extends StandardRecord { /** - * for BIFF8 files the BOF is 0x809. For earlier versions it was 0x09 or 0x(biffversion)09 + * for BIFF8 files the BOF is 0x809. For earlier versions see + * {@link #biff2_sid} {@link #biff3_sid} {@link #biff4_sid} + * {@link #biff5_sid} */ public final static short sid = 0x809; + // SIDs from earlier BIFF versions + public final static short biff2_sid = 0x009; + public final static short biff3_sid = 0x209; + public final static short biff4_sid = 0x409; + public final static short biff5_sid = 0x809; /** suggested default (0x0600 - BIFF8) */ public final static int VERSION = 0x0600; diff --git a/src/testcases/org/apache/poi/hssf/extractor/TestOldExcelExtractor.java b/src/testcases/org/apache/poi/hssf/extractor/TestOldExcelExtractor.java index 1558a50e0..d3589b730 100644 --- a/src/testcases/org/apache/poi/hssf/extractor/TestOldExcelExtractor.java +++ b/src/testcases/org/apache/poi/hssf/extractor/TestOldExcelExtractor.java @@ -52,7 +52,7 @@ public final class TestOldExcelExtractor extends POITestCase { assertContains(text, "11"); assertContains(text, "784"); } - public void DISABLEDtestSimpleExcel5() { + public void testSimpleExcel5() { for (String ver : new String[] {"5", "95"}) { OldExcelExtractor extractor = createExtractor("testEXCEL_"+ver+".xls"); @@ -105,7 +105,7 @@ public final class TestOldExcelExtractor extends POITestCase { // assertContains(text, "55,624"); // assertContains(text, "11,743,477"); } - public void DISABLEDtestFormattedNumbersExcel5() { + public void testFormattedNumbersExcel5() { for (String ver : new String[] {"5", "95"}) { OldExcelExtractor extractor = createExtractor("testEXCEL_"+ver+".xls"); String text = extractor.getText(); @@ -116,6 +116,9 @@ public final class TestOldExcelExtractor extends POITestCase { // Numbers which come from formulas assertContains(text, "13"); assertContains(text, "169"); + + // Formatted numbers + // TODO } }