diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index c21877588..f3076d3cc 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -193,7 +193,8 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss */ private static final String[] WORKBOOK_DIR_ENTRY_NAMES = { "Workbook", // as per BIFF8 spec - "WORKBOOK", + "WORKBOOK", // Typically from third party programs + "BOOK", // Typically odd Crystal Reports exports }; @@ -1180,9 +1181,11 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss if (preserveNodes) { // Don't write out the old Workbook, we'll be doing our new one excepts.add("Workbook"); - // If the file had WORKBOOK instead of Workbook, we'll write it - // out correctly shortly, so don't include the old one - excepts.add("WORKBOOK"); + // If the file had an "incorrect" name for the workbook stream, + // don't write the old one as we'll use the correct name shortly + for (String wrongName : WORKBOOK_DIR_ENTRY_NAMES) { + excepts.add(wrongName); + } // Copy over all the other nodes to our new poifs copyNodes(this.directory, fs.getRoot(), excepts); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java b/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java index bf4343561..e71289c14 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java @@ -75,7 +75,7 @@ public class AllUserModelTests { result.addTestSuite(TestUnfixedBugs.class); } result.addTestSuite(TestUnicodeWorkbook.class); - result.addTestSuite(TestUppercaseWorkbook.class); + result.addTestSuite(TestNonStandardWorkbookStreamNames.class); result.addTestSuite(TestWorkbook.class); return result; diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestUppercaseWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestNonStandardWorkbookStreamNames.java similarity index 59% rename from src/testcases/org/apache/poi/hssf/usermodel/TestUppercaseWorkbook.java rename to src/testcases/org/apache/poi/hssf/usermodel/TestNonStandardWorkbookStreamNames.java index ad7ae65a0..1a28cb421 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestUppercaseWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestNonStandardWorkbookStreamNames.java @@ -29,17 +29,17 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem; /** * Tests for how HSSFWorkbook behaves with XLS files - * with a WORKBOOK directory entry (instead of the more - * usual, Workbook) + * with a WORKBOOK or BOOK directory entry (instead of + * the more usual, Workbook) */ -public final class TestUppercaseWorkbook extends TestCase { - +public final class TestNonStandardWorkbookStreamNames extends TestCase { private String xlsA = "WORKBOOK_in_capitals.xls"; + private String xlsB = "BOOK_in_capitals.xls"; /** * Test that we can open a file with WORKBOOK */ - public void testOpen() throws Exception { + public void testOpenWORKBOOK() throws Exception { InputStream is = HSSFTestDataSamples.openSampleFileStream(xlsA); POIFSFileSystem fs = new POIFSFileSystem(is); @@ -60,31 +60,64 @@ public final class TestUppercaseWorkbook extends TestCase { HSSFWorkbook wb = new HSSFWorkbook(fs); } + /** + * Test that we can open a file with BOOK + */ + public void testOpenBOOK() throws Exception { + InputStream is = HSSFTestDataSamples.openSampleFileStream(xlsB); + + POIFSFileSystem fs = new POIFSFileSystem(is); + + // Ensure that we have a BOOK entry + fs.getRoot().getEntry("BOOK"); + assertTrue(true); + + // But not a Workbook one + try { + fs.getRoot().getEntry("Workbook"); + fail(); + } catch(FileNotFoundException e) {} + // And not a Summary one + try { + fs.getRoot().getEntry("\005SummaryInformation"); + fail(); + } catch(FileNotFoundException e) {} + + // Try to open the workbook + HSSFWorkbook wb = new HSSFWorkbook(fs); + } + /** * Test that when we write out, we go back to the correct case */ public void testWrite() throws Exception { - InputStream is = HSSFTestDataSamples.openSampleFileStream(xlsA); - POIFSFileSystem fs = new POIFSFileSystem(is); - - // Open the workbook, not preserving nodes - HSSFWorkbook wb = new HSSFWorkbook(fs); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - wb.write(out); - - // Check now - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - POIFSFileSystem fs2 = new POIFSFileSystem(in); - - // Check that we have the new entries - fs2.getRoot().getEntry("Workbook"); - try { - fs2.getRoot().getEntry("WORKBOOK"); - fail(); - } catch(FileNotFoundException e) {} - - // And it can be opened - HSSFWorkbook wb2 = new HSSFWorkbook(fs2); + for (String file : new String[] {xlsA, xlsB}) { + InputStream is = HSSFTestDataSamples.openSampleFileStream(file); + POIFSFileSystem fs = new POIFSFileSystem(is); + + // Open the workbook, not preserving nodes + HSSFWorkbook wb = new HSSFWorkbook(fs); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + wb.write(out); + + // Check now + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + POIFSFileSystem fs2 = new POIFSFileSystem(in); + + // Check that we have the new entries + fs2.getRoot().getEntry("Workbook"); + try { + fs2.getRoot().getEntry("BOOK"); + fail(); + } catch(FileNotFoundException e) {} + try { + fs2.getRoot().getEntry("WORKBOOK"); + fail(); + } catch(FileNotFoundException e) {} + + // And it can be opened + HSSFWorkbook wb2 = new HSSFWorkbook(fs2); + } } /** diff --git a/test-data/spreadsheet/BOOK_in_capitals.xls b/test-data/spreadsheet/BOOK_in_capitals.xls new file mode 100644 index 000000000..002d0cac2 Binary files /dev/null and b/test-data/spreadsheet/BOOK_in_capitals.xls differ