misc ooxml improvements:"

1. preserve themes across read-write
2. properly set default properties of a new worksheet


git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@698838 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2008-09-25 06:51:18 +00:00
parent dca93e084f
commit 36e20d8073
10 changed files with 230 additions and 143 deletions

View File

@ -178,7 +178,7 @@ public class StylesTable implements StylesSource, XSSFModel {
return putFont((XSSFFont)font, fonts);
}
public CellStyle getStyleAt(long idx) {
public XSSFCellStyle getStyleAt(long idx) {
int styleXfId = 0;
// 0 is the empty default
@ -378,15 +378,16 @@ public class StylesTable implements StylesSource, XSSFModel {
}
private void initialize() {
//CTFont ctFont = createDefaultFont();
XSSFFont xssfFont = createDefaultFont();
fonts.add(xssfFont.getCTFont());
CTFill[] ctFill = createDefaultFills();
fills.add(ctFill[0]);
/*
fills.add(ctFill[1]);
*/
CTBorder ctBorder = createDefaultBorder();
borders.add(ctBorder);
@ -415,6 +416,7 @@ public class StylesTable implements StylesSource, XSSFModel {
return ctBorder;
}
private CTFill[] createDefaultFills() {
CTFill[] ctFill = new CTFill[]{CTFill.Factory.newInstance(),CTFill.Factory.newInstance()};
ctFill[0].addNewPatternFill().setPatternType(STPatternType.NONE);

View File

@ -0,0 +1,67 @@
package org.apache.poi.xssf.model;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
/**
* An instance of this part type contains information about a document's theme, which is a combination of color
* scheme, font scheme, and format scheme (the latter also being referred to as effects).
* For a SpreadsheetML document, the choice of theme affects the color and style of cell contents and charts,
* among other things.
*
* @author Yegor Kozlov
*/
public class ThemeTable implements XSSFModel {
private ThemeDocument doc;
private String originalId;
public ThemeTable(InputStream is, String originalId) throws IOException {
readFrom(is);
this.originalId = originalId;
}
public String getOriginalId() {
return this.originalId;
}
public ThemeTable() {
this.doc = ThemeDocument.Factory.newInstance();
}
public void readFrom(InputStream is) throws IOException {
try {
doc = ThemeDocument.Factory.parse(is);
} catch (XmlException e) {
throw new IOException(e.getLocalizedMessage());
}
}
public void writeTo(OutputStream out) throws IOException {
XmlOptions options = new XmlOptions();
options.setSaveOuter();
options.setUseDefaultNamespace();
doc.save(out, options);
}
}

View File

@ -110,7 +110,7 @@ public final class XSSFCell implements Cell {
return row.getRowNum();
}
public CellStyle getCellStyle() {
public XSSFCellStyle getCellStyle() {
// Zero is the empty default
if(this.cell.getS() > 0) {
return stylesSource.getStyleAt(this.cell.getS());

View File

@ -19,89 +19,80 @@ package org.apache.poi.xssf.usermodel;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
public class XSSFDialogsheet extends XSSFSheet implements Sheet{
public XSSFDialogsheet(CTSheet sheet, CTDialogsheet dialogsheet,
XSSFWorkbook workbook) {
super(sheet, null, workbook);
this.worksheet = null;
this.dialogsheet = dialogsheet;
if (this.dialogsheet == null) {
this.dialogsheet = CTDialogsheet.Factory.newInstance();
}
}
public XSSFRow createRow(int rowNum) {
return null;
}
public XSSFDialogsheet(CTSheet sheet, CTDialogsheet dialogsheet,
XSSFWorkbook workbook) {
super(sheet, CTWorksheet.Factory.newInstance(), workbook);
this.worksheet = null;
this.dialogsheet = dialogsheet;
if (this.dialogsheet == null) {
this.dialogsheet = CTDialogsheet.Factory.newInstance();
}
}
protected CTHeaderFooter getSheetTypeHeaderFooter() {
if (dialogsheet.getHeaderFooter() == null) {
dialogsheet.setHeaderFooter(CTHeaderFooter.Factory.newInstance());
}
return dialogsheet.getHeaderFooter();
}
public XSSFRow createRow(int rowNum) {
return null;
}
protected CTSheetPr getSheetTypeSheetPr() {
if (dialogsheet.getSheetPr() == null) {
dialogsheet.setSheetPr(CTSheetPr.Factory.newInstance());
}
return dialogsheet.getSheetPr();
}
protected CTHeaderFooter getSheetTypeHeaderFooter() {
if (dialogsheet.getHeaderFooter() == null) {
dialogsheet.setHeaderFooter(CTHeaderFooter.Factory.newInstance());
}
return dialogsheet.getHeaderFooter();
}
protected CTPageBreak getSheetTypeColumnBreaks() {
return null;
}
protected CTSheetPr getSheetTypeSheetPr() {
if (dialogsheet.getSheetPr() == null) {
dialogsheet.setSheetPr(CTSheetPr.Factory.newInstance());
}
return dialogsheet.getSheetPr();
}
protected CTSheetFormatPr getSheetTypeSheetFormatPr() {
if (dialogsheet.getSheetFormatPr() == null) {
dialogsheet.setSheetFormatPr(CTSheetFormatPr.Factory.newInstance());
}
return dialogsheet.getSheetFormatPr();
}
protected CTPageBreak getSheetTypeColumnBreaks() {
return null;
}
protected CTPageMargins getSheetTypePageMargins() {
if (dialogsheet.getPageMargins() == null) {
dialogsheet.setPageMargins(CTPageMargins.Factory.newInstance());
}
return dialogsheet.getPageMargins();
}
protected CTSheetFormatPr getSheetTypeSheetFormatPr() {
if (dialogsheet.getSheetFormatPr() == null) {
dialogsheet.setSheetFormatPr(CTSheetFormatPr.Factory.newInstance());
}
return dialogsheet.getSheetFormatPr();
}
protected CTPageBreak getSheetTypeRowBreaks() {
return null;
}
protected CTPageMargins getSheetTypePageMargins() {
if (dialogsheet.getPageMargins() == null) {
dialogsheet.setPageMargins(CTPageMargins.Factory.newInstance());
}
return dialogsheet.getPageMargins();
}
protected CTSheetViews getSheetTypeSheetViews() {
if (dialogsheet.getSheetViews() == null) {
dialogsheet.setSheetViews(CTSheetViews.Factory.newInstance());
dialogsheet.getSheetViews().addNewSheetView();
}
return dialogsheet.getSheetViews();
}
protected CTPageBreak getSheetTypeRowBreaks() {
return null;
}
protected CTPrintOptions getSheetTypePrintOptions() {
if (dialogsheet.getPrintOptions() == null) {
dialogsheet.setPrintOptions(CTPrintOptions.Factory.newInstance());
}
return dialogsheet.getPrintOptions();
}
protected CTSheetViews getSheetTypeSheetViews() {
if (dialogsheet.getSheetViews() == null) {
dialogsheet.setSheetViews(CTSheetViews.Factory.newInstance());
dialogsheet.getSheetViews().addNewSheetView();
}
return dialogsheet.getSheetViews();
}
protected CTPrintOptions getSheetTypePrintOptions() {
if (dialogsheet.getPrintOptions() == null) {
dialogsheet.setPrintOptions(CTPrintOptions.Factory.newInstance());
}
return dialogsheet.getPrintOptions();
}
protected CTSheetProtection getSheetTypeProtection() {
if (dialogsheet.getSheetProtection() == null) {
dialogsheet.setSheetProtection(CTSheetProtection.Factory.newInstance());
}
return dialogsheet.getSheetProtection();
}
protected CTSheetProtection getSheetTypeProtection() {
if (dialogsheet.getSheetProtection() == null) {
dialogsheet.setSheetProtection(CTSheetProtection.Factory.newInstance());
}
return dialogsheet.getSheetProtection();
}
}

View File

@ -13,15 +13,7 @@ import java.util.Iterator;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.xssf.model.BinaryPart;
import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.Control;
import org.apache.poi.xssf.model.Drawing;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.XSSFChildContainingModel;
import org.apache.poi.xssf.model.XSSFModel;
import org.apache.poi.xssf.model.XSSFWritableModel;
import org.apache.poi.xssf.model.*;
import org.openxml4j.exceptions.InvalidFormatException;
import org.openxml4j.opc.PackagePart;
import org.openxml4j.opc.PackagePartName;
@ -122,6 +114,12 @@ public class XSSFRelation {
"/xl/activeX/activeX#.bin",
BinaryPart.class
);
public static final XSSFRelation THEME = new XSSFRelation(
"application/vnd.openxmlformats-officedocument.theme+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
"/xl/theme/theme#.xml",
ThemeTable.class
);
private static POILogger log = POILogFactory.getLogger(XSSFRelation.class);

View File

@ -129,12 +129,12 @@ public class XSSFRow implements Row {
return xcell;
}
private Cell retrieveCell(int cellnum) {
private XSSFCell retrieveCell(int cellnum) {
Iterator<Cell> it = cellIterator();
for ( ; it.hasNext() ; ) {
Cell cell = it.next();
if (cell.getCellNum() == cellnum) {
return cell;
return (XSSFCell)cell;
}
}
return null;
@ -145,7 +145,7 @@ public class XSSFRow implements Row {
* with the {@link MissingCellPolicy} from the
* parent Workbook.
*/
public Cell getCell(int cellnum) {
public XSSFCell getCell(int cellnum) {
return getCell(cellnum, sheet.getWorkbook().getMissingCellPolicy());
}
@ -153,8 +153,8 @@ public class XSSFRow implements Row {
* Returns the cell at the given (0 based) index,
* with the specified {@link MissingCellPolicy}
*/
public Cell getCell(int cellnum, MissingCellPolicy policy) {
Cell cell = retrieveCell(cellnum);
public XSSFCell getCell(int cellnum, MissingCellPolicy policy) {
XSSFCell cell = retrieveCell(cellnum);
if(policy == RETURN_NULL_AND_BLANK) {
return cell;
}

View File

@ -128,23 +128,20 @@ public class XSSFSheet implements Sheet {
this.workbook = workbook;
this.sheet = sheet;
this.worksheet = worksheet;
if (this.worksheet == null) {
this.worksheet = CTWorksheet.Factory.newInstance();
}
if (this.worksheet.getSheetData() == null) {
this.worksheet.addNewSheetData();
}
//CTSheetView sheetView = getSheetTypeSheetView();
//sheetView.setWorkbookViewId(0);
initRows(this.worksheet);
initColumns(this.worksheet);
hyperlinks = new ArrayList<XSSFHyperlink>();
}
public XSSFSheet(XSSFWorkbook workbook) {
this.workbook = workbook;
hyperlinks = new ArrayList<XSSFHyperlink>();
}
@ -152,6 +149,35 @@ public class XSSFSheet implements Sheet {
return this.workbook;
}
/**
* Create a new CTWorksheet instance and setup default values
*
* @return a new instance
*/
protected static CTWorksheet newSheetInstance(){
CTWorksheet worksheet = CTWorksheet.Factory.newInstance();
CTSheetFormatPr ctFormat = worksheet.addNewSheetFormatPr();
ctFormat.setDefaultRowHeight(15.0);
CTSheetView ctView = worksheet.addNewSheetViews().addNewSheetView();
ctView.setTabSelected(true);
ctView.setWorkbookViewId(0);
worksheet.addNewDimension().setRef("A1");
worksheet.addNewSheetData();
CTPageMargins ctMargins = worksheet.addNewPageMargins();
ctMargins.setBottom(0.75);
ctMargins.setFooter(0.3);
ctMargins.setHeader(0.3);
ctMargins.setLeft(0.7);
ctMargins.setRight(0.7);
ctMargins.setTop(0.75);
return worksheet;
}
/**
* Tweaks the CTWorksheet to fit with what Excel
* will accept without a massive huff, and write into
@ -591,11 +617,11 @@ public class XSSFSheet implements Sheet {
return false;
}
public Row getRow(int rownum) {
public XSSFRow getRow(int rownum) {
for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
Row row = it.next();
if (row.getRowNum() == rownum) {
return row;
return (XSSFRow)row;
}
}
return null;

View File

@ -40,13 +40,7 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.Control;
import org.apache.poi.xssf.model.Drawing;
import org.apache.poi.xssf.model.SharedStringSource;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.XSSFModel;
import org.apache.poi.xssf.model.*;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
@ -84,6 +78,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
private SharedStringSource sharedStringSource;
private StylesSource stylesSource;
private List<? extends XSSFModel> themes = new LinkedList<ThemeTable>();
private MissingCellPolicy missingCellPolicy = Row.RETURN_NULL_AND_BLANK;
private static POILogger log = POILogFactory.getLogger(XSSFWorkbook.class);
@ -132,6 +128,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
e.printStackTrace();
throw new IOException("Unable to load styles - " + e.toString());
}
try {
// Load shared strings
this.themes = XSSFRelation.THEME.loadAll(getCorePart());
} catch(Exception e) {
throw new IOException("Unable to load shared strings - " + e.toString());
}
// Load individual sheets
for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
@ -251,23 +253,17 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
public XSSFCellStyle createCellStyle() {
CTXf xf=CTXf.Factory.newInstance();
xf.setNumFmtId(0);
xf.setFontId(0);
xf.setFillId(0);
xf.setBorderId(0);
xf.setXfId(0);
int xfSize=((StylesTable)stylesSource)._getStyleXfsSize();
long indexXf=((StylesTable)stylesSource).putCellXf(xf);
XSSFCellStyle style = new XSSFCellStyle(new Long(indexXf-1).intValue(), xfSize-1, (StylesTable)stylesSource);
return style;
CTXf xf=CTXf.Factory.newInstance();
xf.setNumFmtId(0);
xf.setFontId(0);
xf.setFillId(0);
xf.setBorderId(0);
xf.setXfId(0);
int xfSize=((StylesTable)stylesSource)._getStyleXfsSize();
long indexXf=((StylesTable)stylesSource).putCellXf(xf);
XSSFCellStyle style = new XSSFCellStyle(new Long(indexXf-1).intValue(), xfSize-1, (StylesTable)stylesSource);
return style;
}
/*
public XSSFCellStyle createCellStyle() {
return new XSSFCellStyle(stylesSource);
}
*/
public DataFormat createDataFormat() {
return getCreationHelper().createDataFormat();
@ -291,12 +287,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
public XSSFSheet createSheet(String sheetname) {
return createSheet(sheetname, null);
return createSheet(sheetname, XSSFSheet.newSheetInstance());
}
public XSSFSheet createSheet(String sheetname, CTWorksheet worksheet) {
CTSheet sheet = addSheet(sheetname);
XSSFWorksheet wrapper = new XSSFWorksheet(sheet, worksheet, this);
XSSFSheet wrapper = new XSSFSheet(sheet, worksheet, this);
this.sheets.add(wrapper);
return wrapper;
}
@ -468,7 +464,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
return null;
}
public Sheet getSheetAt(int index) {
public XSSFSheet getSheetAt(int index) {
return this.sheets.get(index);
}
@ -623,7 +619,9 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
// Main part
PackagePartName corePartName = PackagingURIHelper.createPartName(workbookRelation.getDefaultFileName());
// Create main part relationship
pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT, "rId1");
int rId = 1;
pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT, "rId" + (rId++));
// Create main document part
PackagePart corePart = pkg.createPart(corePartName, workbookRelation.getContentType());
OutputStream out;
@ -636,13 +634,14 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
// Write out our sheets, updating the references
// to them in the main workbook as we go
int drawingIndex = 1;
for (int i=0 ; i < this.getNumberOfSheets(); i++) {
int sheetNumber = (i+1);
XSSFSheet sheet = (XSSFSheet) this.getSheetAt(i);
XSSFSheet sheet = this.getSheetAt(i);
PackagePartName partName = PackagingURIHelper.createPartName(
XSSFRelation.WORKSHEET.getFileName(sheetNumber));
PackageRelationship rel =
corePart.addRelationship(partName, TargetMode.INTERNAL, XSSFRelation.WORKSHEET.getRelation(), "rSheet" + sheetNumber);
corePart.addRelationship(partName, TargetMode.INTERNAL, XSSFRelation.WORKSHEET.getRelation(), "rId" + sheetNumber);
PackagePart part = pkg.createPart(partName, XSSFRelation.WORKSHEET.getContentType());
// XXX This should not be needed, but apparently the setSaveOuter call above does not work in XMLBeans 2.2
@ -653,15 +652,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
workbook.getSheets().getSheetArray(i).setId(rel.getId());
workbook.getSheets().getSheetArray(i).setSheetId(sheetNumber);
// If our sheet has comments, then write out those
if(sheet.hasComments()) {
CommentsTable ct = (CommentsTable)sheet.getCommentsSourceIfExists();
XSSFRelation.SHEET_COMMENTS.save(ct, part, sheetNumber);
}
// If our sheet has drawings, then write out those
if(sheet.getDrawings() != null) {
int drawingIndex = 1;
for(Drawing drawing : sheet.getDrawings()) {
XSSFRelation.VML_DRAWINGS.save(
drawing,
@ -672,6 +664,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
}
// If our sheet has comments, then write out those
if(sheet.hasComments()) {
CommentsTable ct = (CommentsTable)sheet.getCommentsSourceIfExists();
XSSFRelation.SHEET_COMMENTS.save(ct, part, sheetNumber);
}
// If our sheet has controls, then write out those
if(sheet.getControls() != null) {
int controlIndex = 1;
@ -695,6 +693,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
StylesTable st = (StylesTable)stylesSource;
XSSFRelation.STYLES.save(st, corePart);
}
if(themes.size() > 0) {
for(int i=0; i< themes.size(); i++) {
XSSFRelation.THEME.save(themes.get(i), corePart, i+1);
}
}
// Named ranges
if(namedRanges.size() > 0) {
@ -751,7 +754,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
protected void setSharedStringSource(SharedStringSource sharedStringSource) {
this.sharedStringSource = sharedStringSource;
}
public StylesSource getStylesSource() {
return this.stylesSource;
}

View File

@ -121,8 +121,8 @@ public class TestXSSFSheet extends TestCase {
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet 1");
// Test that default height set by the constructor
assertEquals((short) 0, sheet.getDefaultRowHeight());
assertEquals((float) 0, sheet.getDefaultRowHeightInPoints());
assertEquals((short) 300, sheet.getDefaultRowHeight());
assertEquals((float) 15, sheet.getDefaultRowHeightInPoints());
// Set a new default row height in twips and test getting the value in points
sheet.setDefaultRowHeight((short) 360);
assertEquals((float) 18, sheet.getDefaultRowHeightInPoints());
@ -244,7 +244,7 @@ public class TestXSSFSheet extends TestCase {
public void testGetSetMargin() {
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet 1");
assertEquals((double) 0, sheet.getMargin((short) 0));
assertEquals(0.7, sheet.getMargin((short) 0));
sheet.setMargin((short) 0, 10);
assertEquals((double) 10, sheet.getMargin((short) 0));
assertEquals((double) 10, sheet.getMargin((short) 1));
@ -465,9 +465,9 @@ public class TestXSSFSheet extends TestCase {
public void testGetDialog() {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = (XSSFSheet) workbook.createSheet("Sheet 1");
XSSFSheet sheet = workbook.createSheet("Sheet 1");
assertFalse(sheet.getDialog());
XSSFSheet dialogsheet = (XSSFSheet) workbook.createDialogsheet("Dialogsheet 1", null);
XSSFSheet dialogsheet = workbook.createDialogsheet("Dialogsheet 1", null);
assertTrue(dialogsheet.getDialog());
}

View File

@ -88,7 +88,7 @@ public class TestXSSFWorkbook extends TestCase {
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet1 = workbook.createSheet("sheet1");
Sheet sheet2 = workbook.createSheet("sheet2");
assertEquals(-1, workbook.getSelectedTab());
assertEquals(0, workbook.getSelectedTab());
workbook.setSelectedTab((short) 0);
assertEquals(0, workbook.getSelectedTab());
workbook.setSelectedTab((short) 1);