]> source.dussan.org Git - poi.git/commitdiff
Bug 50474 - Example demonstrating how to update workbook embedded in a Wordprocessing...
authorYegor Kozlov <yegor@apache.org>
Sat, 25 Jun 2011 13:46:00 +0000 (13:46 +0000)
committerYegor Kozlov <yegor@apache.org>
Sat, 25 Jun 2011 13:46:00 +0000 (13:46 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1139541 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/examples/src/org/apache/poi/xwpf/usermodel/UpdateEmbeddedDoc.java [new file with mode: 0644]
test-data/document/EmbeddedDocument.docx [new file with mode: 0644]

index 61e2425f33bc67b3565f1bccb53787a0c6beef36..55edae324e388011ba4f3a5f5bf3cfae83dac2c3 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta4" date="2011-??-??">
+           <action dev="poi-developers" type="add">50474 - Example demonstrating how to update Excel workbook embedded in a WordprocessingML document </action>
            <action dev="poi-developers" type="fix">51431 - Avoid IndexOutOfBoundException when removing freeze panes in XSSF </action>
            <action dev="poi-developers" type="fix">48877 - Fixed XSSFRichTextString to respect leading and trailing line breaks </action>
            <action dev="poi-developers" type="fix">49564 - Fixed default behaviour of XSSFCellStyle.getLocked() </action>
diff --git a/src/examples/src/org/apache/poi/xwpf/usermodel/UpdateEmbeddedDoc.java b/src/examples/src/org/apache/poi/xwpf/usermodel/UpdateEmbeddedDoc.java
new file mode 100644 (file)
index 0000000..ffdb7e2
--- /dev/null
@@ -0,0 +1,219 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.xwpf.usermodel;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.util.List;\r
+import java.util.Iterator;\r
+\r
+import junit.framework.Assert;\r
+import org.apache.poi.openxml4j.opc.PackagePart;\r
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
+import org.apache.poi.ss.usermodel.WorkbookFactory;\r
+import org.apache.poi.ss.usermodel.Workbook;\r
+import org.apache.poi.ss.usermodel.Sheet;\r
+import org.apache.poi.ss.usermodel.Row;\r
+import org.apache.poi.ss.usermodel.Cell;\r
+\r
+/**\r
+ * Tests whether it is possible to successfully update an Excel workbook that is\r
+ * embedded into a WordprocessingML document. Note that the test has currently\r
+ * only been conducted with a binary Excel workbook and NOT yet with a\r
+ * SpreadsheetML workbook embedded into the document.\r
+ *\r
+ * <p>\r
+ *     This code was successfully tested with the following file from the POI test collection:\r
+ *     http://svn.apache.org/repos/asf/poi/trunk/test-data/document/EmbeddedDocument.docx\r
+ * </p>\r
+ *\r
+ * @author Mark B\r
+ */\r
+public class UpdateEmbeddedDoc {\r
+\r
+    private XWPFDocument doc = null;\r
+    private File docFile = null;\r
+\r
+    private static final int SHEET_NUM = 0;\r
+    private static final int ROW_NUM = 0;\r
+    private static final int CELL_NUM = 0;\r
+    private static final double NEW_VALUE = 100.98D;\r
+    private static final String BINARY_EXTENSION = "xls";\r
+    private static final String OPENXML_EXTENSION = "xlsx";\r
+\r
+    /**\r
+     * Create a new instance of the UpdateEmbeddedDoc class using the following\r
+     * parameters;\r
+     *\r
+     * @param filename An instance of the String class that encapsulates the name\r
+     *                 of and path to a WordprocessingML Word document that contains an\r
+     *                 embedded binary Excel workbook.\r
+     * @throws java.io.FileNotFoundException Thrown if the file cannot be found\r
+     *                                       on the underlying file system.\r
+     * @throws java.io.IOException           Thrown if a problem occurs in the underlying\r
+     *                                       file system.\r
+     */\r
+    public UpdateEmbeddedDoc(String filename) throws FileNotFoundException, IOException {\r
+        this.docFile = new File(filename);\r
+        FileInputStream fis = null;\r
+        if (!this.docFile.exists()) {\r
+            throw new FileNotFoundException("The Word dcoument " +\r
+                    filename +\r
+                    " does not exist.");\r
+        }\r
+        try {\r
+\r
+            // Open the Word document file and instantiate the XWPFDocument\r
+            // class.\r
+            fis = new FileInputStream(this.docFile);\r
+            this.doc = new XWPFDocument(fis);\r
+        } finally {\r
+            if (fis != null) {\r
+                try {\r
+                    fis.close();\r
+                    fis = null;\r
+                } catch (IOException ioEx) {\r
+                    System.out.println("IOException caught trying to close " +\r
+                            "FileInputStream in the constructor of " +\r
+                            "UpdateEmbeddedDoc.");\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Called to update the embedded Excel workbook. As the format and structire\r
+     * of the workbook are known in advance, all this code attempts to do is\r
+     * write a new value into the first cell on the first row of the first\r
+     * worksheet. Prior to executing this method, that cell will contain the\r
+     * value 1.\r
+     *\r
+     * @throws org.apache.poi.openxml4j.exceptions.OpenXML4JException\r
+     *                             Rather\r
+     *                             than use the specific classes (HSSF/XSSF) to handle the embedded\r
+     *                             workbook this method uses those defeined in the SS stream. As\r
+     *                             a result, it might be the case that a SpreadsheetML file is\r
+     *                             opened for processing, throwing this exception if that file is\r
+     *                             invalid.\r
+     * @throws java.io.IOException Thrown if a problem occurs in the underlying\r
+     *                             file system.\r
+     */\r
+    public void updateEmbeddedDoc() throws OpenXML4JException, IOException {\r
+        Workbook workbook = null;\r
+        Sheet sheet = null;\r
+        Row row = null;\r
+        Cell cell = null;\r
+        PackagePart pPart = null;\r
+        Iterator<PackagePart> pIter = null;\r
+        List<PackagePart> embeddedDocs = this.doc.getAllEmbedds();\r
+        if (embeddedDocs != null && !embeddedDocs.isEmpty()) {\r
+            pIter = embeddedDocs.iterator();\r
+            while (pIter.hasNext()) {\r
+                pPart = pIter.next();\r
+                if (pPart.getPartName().getExtension().equals(BINARY_EXTENSION) ||\r
+                        pPart.getPartName().getExtension().equals(OPENXML_EXTENSION)) {\r
+\r
+                    // Get an InputStream from the pacage part and pass that\r
+                    // to the create method of the WorkbookFactory class. Update\r
+                    // the resulting Workbook and then stream that out again\r
+                    // using an OutputStream obtained from the same PackagePart.\r
+                    workbook = WorkbookFactory.create(pPart.getInputStream());\r
+                    sheet = workbook.getSheetAt(SHEET_NUM);\r
+                    row = sheet.getRow(ROW_NUM);\r
+                    cell = row.getCell(CELL_NUM);\r
+                    cell.setCellValue(NEW_VALUE);\r
+                    workbook.write(pPart.getOutputStream());\r
+                }\r
+            }\r
+\r
+            // Finally, write the newly modified Word document out to file.\r
+            this.doc.write(new FileOutputStream(this.docFile));\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Called to test whether or not the embedded workbook was correctly\r
+     * updated. This method simply recovers the first cell from the first row\r
+     * of the first workbook and tests the value it contains.\r
+     * <p/>\r
+     * Note that execution will not continue up to the assertion as the\r
+     * embedded workbook is now corrupted and causes an IllegalArgumentException\r
+     * with the following message\r
+     * <p/>\r
+     * <em>java.lang.IllegalArgumentException: Your InputStream was neither an\r
+     * OLE2 stream, nor an OOXML stream</em>\r
+     * <p/>\r
+     * to be thrown when the WorkbookFactory.createWorkbook(InputStream) method\r
+     * is executed.\r
+     *\r
+     * @throws org.apache.poi.openxml4j.exceptions.OpenXML4JException\r
+     *                             Rather\r
+     *                             than use the specific classes (HSSF/XSSF) to handle the embedded\r
+     *                             workbook this method uses those defeined in the SS stream. As\r
+     *                             a result, it might be the case that a SpreadsheetML file is\r
+     *                             opened for processing, throwing this exception if that file is\r
+     *                             invalid.\r
+     * @throws java.io.IOException Thrown if a problem occurs in the underlying\r
+     *                             file system.\r
+     */\r
+    public void checkUpdatedDoc() throws OpenXML4JException, IOException {\r
+        Workbook workbook = null;\r
+        Sheet sheet = null;\r
+        Row row = null;\r
+        Cell cell = null;\r
+        PackagePart pPart = null;\r
+        Iterator<PackagePart> pIter = null;\r
+        List<PackagePart> embeddedDocs = this.doc.getAllEmbedds();\r
+        if (embeddedDocs != null && !embeddedDocs.isEmpty()) {\r
+            pIter = embeddedDocs.iterator();\r
+            while (pIter.hasNext()) {\r
+                pPart = pIter.next();\r
+                if (pPart.getPartName().getExtension().equals(BINARY_EXTENSION) ||\r
+                        pPart.getPartName().getExtension().equals(OPENXML_EXTENSION)) {\r
+                    workbook = WorkbookFactory.create(pPart.getInputStream());\r
+                    sheet = workbook.getSheetAt(SHEET_NUM);\r
+                    row = sheet.getRow(ROW_NUM);\r
+                    cell = row.getCell(CELL_NUM);\r
+                    Assert.assertEquals(cell.getNumericCellValue(), NEW_VALUE);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Code to test updating of the embedded Excel workbook.\r
+     *\r
+     * @param args\r
+     */\r
+    public static void main(String[] args) {\r
+        try {\r
+            UpdateEmbeddedDoc ued = new UpdateEmbeddedDoc(args[0]);\r
+            ued.updateEmbeddedDoc();\r
+            ued.checkUpdatedDoc();\r
+        } catch (Exception ex) {\r
+            System.out.println(ex.getClass().getName());\r
+            System.out.println(ex.getMessage());\r
+            ex.printStackTrace(System.out);\r
+        }\r
+    }\r
+}\r
diff --git a/test-data/document/EmbeddedDocument.docx b/test-data/document/EmbeddedDocument.docx
new file mode 100644 (file)
index 0000000..1cb35a5
Binary files /dev/null and b/test-data/document/EmbeddedDocument.docx differ