]> source.dussan.org Git - poi.git/commitdiff
#57919 Start on support for writing to a new File (faster than OutputStream)
authorNick Burch <nick@apache.org>
Wed, 20 Jul 2016 11:07:29 +0000 (11:07 +0000)
committerNick Burch <nick@apache.org>
Wed, 20 Jul 2016 11:07:29 +0000 (11:07 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1753486 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java

index 5c2e5df3307e692863155fb5925c3691b8c6f5b8..b17e70e8680b63c5f1e9c41f61a19c899d540269 100644 (file)
@@ -1291,7 +1291,6 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
         super.close();
     }
 
-    //@Override // TODO Not yet on POIDocument
     /**
      * Write out this workbook to the currently open {@link File} via the
      *  writeable {@link POIFSFileSystem} it was opened as. 
@@ -1300,6 +1299,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
      *   instead of a File, or if this is not the root document. For those cases, 
      *   you must use {@link #write(OutputStream)} to write to a brand new stream.
      */
+    //@Override // TODO Not yet on POIDocument
     public void write() throws IOException {
         // TODO Push much of this logic down to POIDocument, as will be common for most formats
         if (directory == null) {
@@ -1323,6 +1323,34 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
         directory.getFileSystem().writeFilesystem();
     }
     
+    /**
+     * Method write - write out this workbook to a new {@link File}.  Constructs
+     * a new POI POIFSFileSystem, passes in the workbook binary representation  and
+     * writes it out. If the file exists, it will be replaced, otherwise a new one
+     * will be created.
+     * 
+     * Note that you cannot write to the currently open File using this method.
+     * If you opened your Workbook from a File, you <i>must</i> use the {@link #write()}
+     * method instead!
+     * 
+     * TODO Finish Implementing
+     * 
+     * @param newFile - the new File you wish to write the XLS to
+     *
+     * @exception IOException if anything can't be written.
+     * @see org.apache.poi.poifs.filesystem.POIFSFileSystem
+     */
+    //@Override // TODO Not yet on POIDocument
+    public void write(File newFile) throws IOException {
+        POIFSFileSystem fs = POIFSFileSystem.create(newFile);
+        try {
+            write(fs);
+            fs.writeFilesystem();
+        } finally {
+            fs.close();
+        }
+    }
+    
     /**
      * Method write - write out this workbook to an {@link OutputStream}.  Constructs
      * a new POI POIFSFileSystem, passes in the workbook binary representation  and
@@ -1339,42 +1367,45 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
      * @see org.apache.poi.poifs.filesystem.POIFSFileSystem
      */
     @Override
-       public void write(OutputStream stream)
-            throws IOException
-    {
+       public void write(OutputStream stream) throws IOException {
         NPOIFSFileSystem fs = new NPOIFSFileSystem();
         try {
-            // For tracking what we've written out, used if we're
-            //  going to be preserving nodes
-            List<String> excepts = new ArrayList<String>(1);
-    
-            // Write out the Workbook stream
-            fs.createDocument(new ByteArrayInputStream(getBytes()), "Workbook");
-    
-            // Write out our HPFS properties, if we have them
-            writeProperties(fs, excepts);
-    
-            if (preserveNodes) {
-                // Don't write out the old Workbook, we'll be doing our new one
-                // 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
-               excepts.addAll(Arrays.asList(WORKBOOK_DIR_ENTRY_NAMES));
-    
-                // Copy over all the other nodes to our new poifs
-                EntryUtils.copyNodes(
-                        new FilteringDirectoryNode(this.directory, excepts)
-                        , new FilteringDirectoryNode(fs.getRoot(), excepts)
-                );
-    
-                // YK: preserve StorageClsid, it is important for embedded workbooks,
-                // see Bugzilla 47920
-                fs.getRoot().setStorageClsid(this.directory.getStorageClsid());
-            }
+            write(fs);
             fs.writeFilesystem(stream);
         } finally {
             fs.close();
         }
     }
+    
+    /** Writes the workbook out to a brand new, empty POIFS */
+    private void write(NPOIFSFileSystem fs) throws IOException {
+        // For tracking what we've written out, used if we're
+        //  going to be preserving nodes
+        List<String> excepts = new ArrayList<String>(1);
+
+        // Write out the Workbook stream
+        fs.createDocument(new ByteArrayInputStream(getBytes()), "Workbook");
+
+        // Write out our HPFS properties, if we have them
+        writeProperties(fs, excepts);
+
+        if (preserveNodes) {
+            // Don't write out the old Workbook, we'll be doing our new one
+            // 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
+            excepts.addAll(Arrays.asList(WORKBOOK_DIR_ENTRY_NAMES));
+
+            // Copy over all the other nodes to our new poifs
+            EntryUtils.copyNodes(
+                    new FilteringDirectoryNode(this.directory, excepts)
+                    , new FilteringDirectoryNode(fs.getRoot(), excepts)
+                    );
+
+            // YK: preserve StorageClsid, it is important for embedded workbooks,
+            // see Bugzilla 47920
+            fs.getRoot().setStorageClsid(this.directory.getStorageClsid());
+        }
+    }
 
     /**
      * Totals the sizes of all sheet records and eventually serializes them
index 48d75ab940e9dfcd1307fdc3c1cbc03e0b16276f..e78f18f9f1275695393c3d658efeb063dfc3304d 100644 (file)
@@ -20,6 +20,7 @@
 package org.apache.poi.poifs.filesystem;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -121,6 +122,27 @@ public class POIFSFileSystem
     public static boolean hasPOIFSHeader(byte[] header8Bytes) {
         return NPOIFSFileSystem.hasPOIFSHeader(header8Bytes);
     }
+    
+    /**
+     * Creates a new {@link POIFSFileSystem} in a new {@link File}.
+     * Use {@link #POIFSFileSystem(File)} to open an existing File,
+     *  this should only be used to create a new empty filesystem.
+     *
+     * @param file The file to create and open
+     * @return The created and opened {@link POIFSFileSystem}
+     */
+    public static POIFSFileSystem create(File file) throws IOException {
+        // TODO Make this nicer!
+        // Create a new empty POIFS in the file
+        POIFSFileSystem tmp = new POIFSFileSystem();
+        FileOutputStream fout = new FileOutputStream(file);
+        tmp.writeFilesystem(fout);
+        fout.close();
+        tmp.close();
+        
+        // Open it up again backed by the file
+        return new POIFSFileSystem(file);
+    }
 
     /**
      * read in a file and write it back out again