* @return The 0-based position of the newly added string.
*/
public int putSharedString(String s);
-
- /**
- * Write back out
- */
- public void save() throws IOException;
}
==================================================================== */
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);
}
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;
/**
* 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();
}
/**
*/
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());
}
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.
*
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;;
/**
* 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 {
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();
}
/**
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
}
// Find a spare key, and add that
- long newKey = 1;
+ long newKey = FIRST_CUSTOM_STYLE_ID;
while(numberFormats.containsKey(newKey)) {
newKey++;
}
return newKey;
}
+ public Font getFontAt(long idx) {
+ // TODO
+ return null;
+ }
+ public synchronized long putFont(Font font) {
+ // TODO
+ return -1;
+ }
+
/**
* For unit testing only
*/
}
- /**
- * 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.
*
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
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;
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",
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>();
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());
// 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
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");
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();
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
}
}