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:
parent
dca93e084f
commit
36e20d8073
@ -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);
|
||||
|
67
src/ooxml/java/org/apache/poi/xssf/model/ThemeTable.java
Executable file
67
src/ooxml/java/org/apache/poi/xssf/model/ThemeTable.java
Executable 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);
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
|
@ -19,22 +19,13 @@ 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);
|
||||
super(sheet, CTWorksheet.Factory.newInstance(), workbook);
|
||||
this.worksheet = null;
|
||||
this.dialogsheet = dialogsheet;
|
||||
if (this.dialogsheet == null) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -128,14 +128,11 @@ 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);
|
||||
|
||||
@ -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;
|
||||
|
@ -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()) {
|
||||
@ -263,12 +265,6 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
|
||||
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) {
|
||||
|
@ -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());
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user