]> source.dussan.org Git - poi.git/commitdiff
Tidy up the xssf models stuff, by pushing more of the logic onto XSSFWorkbook
authorNick Burch <nick@apache.org>
Sun, 16 Mar 2008 23:30:51 +0000 (23:30 +0000)
committerNick Burch <nick@apache.org>
Sun, 16 Mar 2008 23:30:51 +0000 (23:30 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@637688 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/SharedStringSource.java
src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/StylesSource.java
src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java
src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java

index 6979a7c7e03d2429e7acd978ad4cb0330c615f77..3a2794caf28f55f5932b63fc2fa48acae06933fc 100644 (file)
@@ -39,9 +39,4 @@ public interface SharedStringSource {
      * @return The 0-based position of the newly added string.
      */
     public int putSharedString(String s);
-    
-    /**
-     * Write back out
-     */
-    public void save() throws IOException;
 }
index dc328ff104167379dc97d8d5ef1fc9320a6c81ae..45a11a46a3674d6fb1c7e1ac09c5acf519106f5f 100644 (file)
 ==================================================================== */
 package org.apache.poi.ss.usermodel;
 
-import java.io.IOException;
-
 public interface StylesSource {
     public String getNumberFormatAt(long idx);
     public long putNumberFormat(String fmt);
     
-    /**
-     * Write back out
-     */
-    public void save() throws IOException;
+    public Font getFontAt(long idx);
+    public long putFont(Font font);
 }
index 33e5bfe817f873a3fec2d242c404f495bda63d97..c6d8d2a862f63d318fe3aeabd4415b7bafaf731d 100644 (file)
@@ -25,7 +25,6 @@ import java.util.LinkedList;
 import org.apache.poi.ss.usermodel.SharedStringSource;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlOptions;
-import org.openxml4j.opc.PackagePart;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSst;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.SstDocument;
@@ -34,32 +33,28 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.SstDocument;
 /**
  * Table of strings shared across all sheets in a workbook.
  * 
- * FIXME: I don't like having a dependency on PackagePart (from OpenXML4J) in model classes.
- * I'd rather let Workbook keep track of all part-document relationships and keep all other
- * classes clean. -- Ugo
- * 
  * @version $Id$
  */
 public class SharedStringsTable implements SharedStringSource, XSSFModel {
 
     private final LinkedList<String> strings = new LinkedList<String>();
+    private SstDocument doc;
     
-    private PackagePart part;
-   
     /**
-     * Create a new SharedStringsTable by reading it from a PackagePart.
+     * Create a new SharedStringsTable, by reading it 
+     *  from the InputStream of a PackagePart.
      * 
-     * @param part The PackagePart to read.
+     * @param is The input stream containing the XML document.
      * @throws IOException if an error occurs while reading.
      */
-    public SharedStringsTable(PackagePart part) throws IOException {
-        this.part = part;
-        InputStream is = part.getInputStream();
-        try {
-            readFrom(is);
-        } finally {
-            if (is != null) is.close();
-        }
+    public SharedStringsTable(InputStream is) throws IOException {
+        readFrom(is);
+    }
+    /**
+     * Create a new, empty SharedStringsTable
+     */
+    public SharedStringsTable() {
+       doc = SstDocument.Factory.newInstance();
     }
 
     /**
@@ -70,7 +65,7 @@ public class SharedStringsTable implements SharedStringSource, XSSFModel {
      */
     public void readFrom(InputStream is) throws IOException {
         try {
-            SstDocument doc = SstDocument.Factory.parse(is);
+            doc = SstDocument.Factory.parse(is);
             for (CTRst rst : doc.getSst().getSiArray()) {
                 strings.add(rst.getT());
             }
@@ -91,20 +86,6 @@ public class SharedStringsTable implements SharedStringSource, XSSFModel {
         return strings.size() - 1;
     }
 
-    /**
-     * Save this table to its own PackagePart.
-     * 
-     * @throws IOException if an error occurs while writing.
-     */
-    public void save() throws IOException {
-        OutputStream out = this.part.getOutputStream();
-        try {
-            writeTo(out);
-        } finally {
-            out.close();
-        }
-    }
-
     /**
      * Write this table out as XML.
      * 
index 122a1b4401a3e55789ec1a16387672e3b0b41bb9..c5227c1c1cac9a07152a137002e3043373ee699b 100644 (file)
@@ -25,13 +25,14 @@ import java.util.Hashtable;
 import java.util.LinkedList;
 import java.util.Map.Entry;
 
+import org.apache.poi.ss.usermodel.Font;
 import org.apache.poi.ss.usermodel.StylesSource;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlOptions;
-import org.openxml4j.opc.PackagePart;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFonts;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmt;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmts;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument;;
@@ -40,10 +41,6 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument;;
 /**
  * Table of styles shared across all sheets in a workbook.
  * 
- * FIXME: I don't like having a dependency on PackagePart (from OpenXML4J) in model classes.
- * I'd rather let Workbook keep track of all part-document relationships and keep all other
- * classes clean. -- Ugo
- * 
  * @version $Id: SharedStringsTable.java 612495 2008-01-16 16:08:22Z ugo $
  */
 public class StylesTable implements StylesSource, XSSFModel {
@@ -52,23 +49,28 @@ public class StylesTable implements StylesSource, XSSFModel {
     private final LinkedList<CTFill> fills = new LinkedList<CTFill>();
     private final LinkedList<CTBorder> borders = new LinkedList<CTBorder>();
     
-    private PackagePart part;
+    /**
+     * The first style id available for use as a custom style
+     */
+    public static final long FIRST_CUSTOM_STYLE_ID = 165;
+    
     private StyleSheetDocument doc;
    
     /**
-     * Create a new StylesTable by reading it from a PackagePart.
+     * Create a new StylesTable, by reading it from 
+     *  the InputStream of a a PackagePart.
      * 
-     * @param part The PackagePart to read.
+     * @param is The input stream containing the XML document.
      * @throws IOException if an error occurs while reading.
      */
-    public StylesTable(PackagePart part) throws IOException {
-        this.part = part;
-        InputStream is = part.getInputStream();
-        try {
-            readFrom(is);
-        } finally {
-            if (is != null) is.close();
-        }
+    public StylesTable(InputStream is) throws IOException {
+        readFrom(is);
+    }
+    /**
+     * Create a new, empty StylesTable
+     */
+    public StylesTable() {
+       doc = StyleSheetDocument.Factory.newInstance();
     }
 
     /**
@@ -106,7 +108,6 @@ public class StylesTable implements StylesSource, XSSFModel {
     public String getNumberFormatAt(long idx) {
         return numberFormats.get(idx);
     }
-
     public synchronized long putNumberFormat(String fmt) {
         if (numberFormats.containsValue(fmt)) {
                // Find the key, and return that
@@ -120,7 +121,7 @@ public class StylesTable implements StylesSource, XSSFModel {
         }
         
         // Find a spare key, and add that
-        long newKey = 1;
+        long newKey = FIRST_CUSTOM_STYLE_ID;
         while(numberFormats.containsKey(newKey)) {
                newKey++;
         }
@@ -128,6 +129,15 @@ public class StylesTable implements StylesSource, XSSFModel {
         return newKey;
     }
     
+    public Font getFontAt(long idx) {
+       // TODO
+       return null;
+    }
+    public synchronized long putFont(Font font) {
+       // TODO
+       return -1;
+    }
+    
     /**
      * For unit testing only
      */
@@ -154,20 +164,6 @@ public class StylesTable implements StylesSource, XSSFModel {
     }
     
 
-    /**
-     * Save this table to its own PackagePart.
-     * 
-     * @throws IOException if an error occurs while writing.
-     */
-    public void save() throws IOException {
-        OutputStream out = this.part.getOutputStream();
-        try {
-            writeTo(out);
-        } finally {
-            out.close();
-        }
-    }
-
     /**
      * Write this table out as XML.
      * 
@@ -193,7 +189,12 @@ public class StylesTable implements StylesSource, XSSFModel {
        doc.getStyleSheet().setNumFmts(formats);
        
        // Fonts
-       // TODO
+       CTFonts fnts = CTFonts.Factory.newInstance();
+       fnts.setCount(fonts.size());
+       fnts.setFontArray(
+                       fonts.toArray(new CTFont[fonts.size()])
+       );
+       doc.getStyleSheet().setFonts(fnts);
        
        // Fills
        // TODO
index 57d37a4049b2bd15e7e456294119b41348131090..62d6878fd2b58b79c3a476477bf057b847773c81 100644 (file)
@@ -18,7 +18,9 @@
 package org.apache.poi.xssf.usermodel;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.reflect.Constructor;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -65,22 +67,6 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
 
 
 public class XSSFWorkbook extends POIXMLDocument implements Workbook {
-       public static class XSSFRelation {
-               private String TYPE;
-               private String REL;
-               private String DEFAULT_NAME;
-               private Class<? extends XSSFModel> CLASS;
-               private XSSFRelation(String TYPE, String REL, String DEFAULT_NAME, Class<? extends XSSFModel> CLASS) {
-                       this.TYPE = TYPE;
-                       this.REL = REL;
-                       this.DEFAULT_NAME = DEFAULT_NAME;
-                       this.CLASS = CLASS;
-               }
-               public String getContentType() { return TYPE; }
-               public String getRelation() { return REL; }
-               public String getDefaultFileName() { return DEFAULT_NAME; }
-       }
-       
        public static final XSSFRelation WORKSHEET = new XSSFRelation(
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
                        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
@@ -112,6 +98,70 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
                null
     );
     
+       public static class XSSFRelation {
+               private String TYPE;
+               private String REL;
+               private String DEFAULT_NAME;
+               private Class<? extends XSSFModel> CLASS;
+               private XSSFRelation(String TYPE, String REL, String DEFAULT_NAME, Class<? extends XSSFModel> CLASS) {
+                       this.TYPE = TYPE;
+                       this.REL = REL;
+                       this.DEFAULT_NAME = DEFAULT_NAME;
+                       this.CLASS = CLASS;
+               }
+               public String getContentType() { return TYPE; }
+               public String getRelation() { return REL; }
+               public String getDefaultFileName() { return DEFAULT_NAME; }
+
+               /**
+                * Load, off the specified core part
+                */
+               private XSSFModel load(PackagePart corePart) throws Exception {
+                       Constructor<? extends XSSFModel> c = CLASS.getConstructor(InputStream.class);
+                       XSSFModel model = null;
+                       
+            PackageRelationshipCollection prc =
+               corePart.getRelationshipsByType(REL);
+            Iterator<PackageRelationship> it = prc.iterator();
+            if(it.hasNext()) {
+                PackageRelationship rel = it.next();
+                PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
+                PackagePart part = corePart.getPackage().getPart(relName);
+                InputStream is = part.getInputStream();
+                try {
+                       model = c.newInstance(is);
+                } finally {
+                       is.close();
+                }
+            } else {
+               log.log(POILogger.WARN, "No part " + DEFAULT_NAME + " found");
+            }
+            return model;
+               }
+               /**
+                * Save, with the default name
+                */
+               private void save(XSSFModel model, PackagePart corePart) throws IOException {
+                       save(model, corePart, DEFAULT_NAME);
+               }
+               /**
+                * Save, with the specified name
+                */
+               private void save(XSSFModel model, PackagePart corePart, String name) throws IOException {
+            PackagePartName ppName = null;
+            try {
+               ppName = PackagingURIHelper.createPartName(name);
+            } catch(InvalidFormatException e) {
+               throw new IllegalStateException(e);
+            }
+            corePart.addRelationship(ppName, TargetMode.INTERNAL, REL);
+            PackagePart part = corePart.getPackage().createPart(ppName, TYPE);
+            OutputStream out = part.getOutputStream();
+            model.writeTo(out);
+            out.close();
+               }
+       }
+       
     private CTWorkbook workbook;
     
     private List<XSSFSheet> sheets = new LinkedList<XSSFSheet>();
@@ -138,34 +188,22 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
             WorkbookDocument doc = WorkbookDocument.Factory.parse(getCorePart().getInputStream());
             this.workbook = doc.getWorkbook();
             
-            PackageRelationshipCollection prc;
-            Iterator<PackageRelationship> it;
-            
-            // Load shared strings
-            prc = getCorePart().getRelationshipsByType(SHARED_STRINGS.getRelation());
-            it = prc.iterator();
-            if (it.hasNext()) { 
-                PackageRelationship rel = it.next();
-                PackagePart part = getTargetPart(rel);
-                this.sharedStringSource = new SharedStringsTable(part);
-            } else {
-               log.log(POILogger.WARN, "No shared strings part found");
-            }
-            // Load styles source
-            prc = getCorePart().getRelationshipsByType(STYLES.getRelation());
-            it = prc.iterator();
-            if (it.hasNext()) { 
-                PackageRelationship rel = it.next();
-                PackagePart part = getTargetPart(rel);
-                this.stylesSource = new StylesTable(part);
-            } else {
-               log.log(POILogger.WARN, "No styles part found");
+            try {
+                   // Load shared strings
+                   this.sharedStringSource = (SharedStringSource)
+                       SHARED_STRINGS.load(getCorePart());
+                   // Load styles source
+                   this.stylesSource = (StylesSource)
+                       STYLES.load(getCorePart());
+            } catch(Exception e) {
+               throw new IOException(e.getMessage());
             }
             
             // Load individual sheets
             for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
                 PackagePart part = getPackagePart(ctSheet);
                 if (part == null) {
+                       log.log(POILogger.WARN, "Sheet with name " + ctSheet.getName() + " was defined, but didn't exist, skipping");
                     continue;
                 }
                 WorksheetDocument worksheetDoc = WorksheetDocument.Factory.parse(part.getInputStream());
@@ -572,21 +610,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
              // Write shared strings and styles
              if(sharedStringSource != null) {
                     SharedStringsTable sst = (SharedStringsTable)sharedStringSource;
-                    PackagePartName sstName = PackagingURIHelper.createPartName(SHARED_STRINGS.getDefaultFileName());
-                    corePart.addRelationship(sstName, TargetMode.INTERNAL, SHARED_STRINGS.getRelation());
-                    PackagePart sstPart = pkg.createPart(sstName, SHARED_STRINGS.getContentType());
-                    out = sstPart.getOutputStream();
-                    sst.writeTo(out);
-                    out.close();
+                    SHARED_STRINGS.save(sst, corePart);
              }
              if(stylesSource != null) {
                     StylesTable st = (StylesTable)stylesSource;
-                    PackagePartName stName = PackagingURIHelper.createPartName(STYLES.getDefaultFileName());
-                    corePart.addRelationship(stName, TargetMode.INTERNAL, STYLES.getRelation());
-                    PackagePart stPart = pkg.createPart(stName, STYLES.getContentType());
-                    out = stPart.getOutputStream();
-                    st.writeTo(out);
-                    out.close();
+                    STYLES.save(st, corePart);
              }
 
              //  All done
index 89a066107e6cec89186e883993e09ac80c9d8254..f99dbebacc8a210390f457d4c39a545af687d2af 100644 (file)
@@ -31,8 +31,17 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
 
 
 public class TestXSSFWorkbook extends TestCase {
-    
-    public void testGetSheetIndex() {
+    public TestXSSFWorkbook(String name) {
+               super(name);
+               
+               // Use system out logger
+           System.setProperty(
+                   "org.apache.poi.util.POILogger",
+                   "org.apache.poi.util.SystemOutLogger"
+           );
+       }
+
+       public void testGetSheetIndex() {
         XSSFWorkbook workbook = new XSSFWorkbook();
         Sheet sheet1 = workbook.createSheet("sheet1");
         Sheet sheet2 = workbook.createSheet("sheet2");
@@ -127,7 +136,7 @@ public class TestXSSFWorkbook extends TestCase {
         Sheet sheet2 = workbook.createSheet("sheet2");
         Sheet sheet3 = workbook.createSheet("sheet3");
         File file = File.createTempFile("poi-", ".xlsx");
-        System.out.println("Saving to " + file.getAbsolutePath());
+        System.out.println("Saving newly created file to " + file.getAbsolutePath());
         OutputStream out = new FileOutputStream(file);
         workbook.write(out);
         out.close();
@@ -194,5 +203,17 @@ public class TestXSSFWorkbook extends TestCase {
                assertEquals(2, st._getFillsSize());
                // Has 1 border
                assertEquals(1, st._getBordersSize());
+               
+               // Add two more styles
+               assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8, 
+                               st.putNumberFormat("testFORMAT"));
+               assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 8, 
+                               st.putNumberFormat("testFORMAT"));
+               assertEquals(StylesTable.FIRST_CUSTOM_STYLE_ID + 9, 
+                               st.putNumberFormat("testFORMAT2"));
+               assertEquals(10, st._getNumberFormatSize());
+               
+               // Save, load back in again, and check
+               // TODO
     }
 }