--- /dev/null
+/*\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