2008-01-16 11:08:22 -05:00
|
|
|
/* ====================================================================
|
|
|
|
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.
|
|
|
|
==================================================================== */
|
|
|
|
|
|
|
|
package org.apache.poi.xssf.usermodel;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
2008-09-24 13:53:29 -04:00
|
|
|
import java.io.OutputStream;
|
2008-10-17 11:14:00 -04:00
|
|
|
import java.io.InputStream;
|
2008-10-10 10:54:32 -04:00
|
|
|
import java.util.*;
|
2008-01-16 11:08:22 -05:00
|
|
|
import javax.xml.namespace.QName;
|
2008-02-04 11:34:44 -05:00
|
|
|
import org.apache.poi.POIXMLDocument;
|
2008-09-30 09:57:36 -04:00
|
|
|
import org.apache.poi.POIXMLDocumentPart;
|
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647711,647714-647737,647739-647823,647825-648155,648157-648202,648204-648273,648275,648277-648302,648304-648333,648335-648588,648590-648622,648625-648673,648675-649141,649144,649146-649556,649558-649795,649799,649801-649910,649912-649913,649915-650128,650131-650132,650134-650137,650140-650914,650916-651991,651993-652284,652286-652287,652289,652291,652293-652297,652299-652328,652330-652425,652427-652445,652447-652560,652562-652933,652935,652937-652993,652995-653116,653118-653124,653126-653483,653487-653519,653522-653550,653552-653607,653609-653667,653669-653674,653676-653814,653817-653830,653832-653891,653893-653944,653946-654055,654057-654355,654357-654365,654367-654648,654651-655215,655217-655277,655279-655281,655283-655911,655913-656212,656214,656216-656251,656253-656698,656700-656756,656758-656892,656894-657135,657137-657165,657168-657179,657181-657354,657356-657357,657359-657701,657703-657874,657876-658032,658034-658284,658286,658288-658301,658303-658307,658309-658321,658323-658335,658337-658348,658351,658353-658832,658834-658983,658985,658987-659066,659068-659402,659404-659428,659430-659451,659453-659454,659456-659461,659463-659477,659479-659525 via svnmerge from
https://svn.apache.org:443/repos/asf/poi/trunk
........
r659525 | nick | 2008-05-23 13:58:56 +0100 (Fri, 23 May 2008) | 1 line
Extend the support for specifying a policy to HSSF on missing / blank cells when fetching, to be able to specify the policy at the HSSFWorkbook level
........
Also, port this to XSSF
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@659533 13f79535-47bb-0310-9956-ffa450edef68
2008-05-23 09:12:43 -04:00
|
|
|
import org.apache.poi.ss.usermodel.Row;
|
2008-01-16 11:08:22 -05:00
|
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
import org.apache.poi.ss.usermodel.Workbook;
|
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647711,647714-647737,647739-647823,647825-648155,648157-648202,648204-648273,648275,648277-648302,648304-648333,648335-648588,648590-648622,648625-648673,648675-649141,649144,649146-649556,649558-649795,649799,649801-649910,649912-649913,649915-650128,650131-650132,650134-650137,650140-650914,650916-651991,651993-652284,652286-652287,652289,652291,652293-652297,652299-652328,652330-652425,652427-652445,652447-652560,652562-652933,652935,652937-652993,652995-653116,653118-653124,653126-653483,653487-653519,653522-653550,653552-653607,653609-653667,653669-653674,653676-653814,653817-653830,653832-653891,653893-653944,653946-654055,654057-654355,654357-654365,654367-654648,654651-655215,655217-655277,655279-655281,655283-655911,655913-656212,656214,656216-656251,656253-656698,656700-656756,656758-656892,656894-657135,657137-657165,657168-657179,657181-657354,657356-657357,657359-657701,657703-657874,657876-658032,658034-658284,658286,658288-658301,658303-658307,658309-658321,658323-658335,658337-658348,658351,658353-658832,658834-658983,658985,658987-659066,659068-659402,659404-659428,659430-659451,659453-659454,659456-659461,659463-659477,659479-659525 via svnmerge from
https://svn.apache.org:443/repos/asf/poi/trunk
........
r659525 | nick | 2008-05-23 13:58:56 +0100 (Fri, 23 May 2008) | 1 line
Extend the support for specifying a policy to HSSF on missing / blank cells when fetching, to be able to specify the policy at the HSSFWorkbook level
........
Also, port this to XSSF
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@659533 13f79535-47bb-0310-9956-ffa450edef68
2008-05-23 09:12:43 -04:00
|
|
|
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
|
2008-10-17 14:43:37 -04:00
|
|
|
import org.apache.poi.ss.util.CellReference;
|
2008-02-19 07:56:51 -05:00
|
|
|
import org.apache.poi.util.POILogFactory;
|
|
|
|
import org.apache.poi.util.POILogger;
|
2008-09-30 09:57:36 -04:00
|
|
|
import org.apache.poi.util.PackageHelper;
|
2008-10-17 11:14:00 -04:00
|
|
|
import org.apache.poi.util.IOUtils;
|
2008-09-25 02:51:18 -04:00
|
|
|
import org.apache.poi.xssf.model.*;
|
2008-09-30 09:57:36 -04:00
|
|
|
import org.apache.poi.POIXMLException;
|
2008-01-22 08:28:48 -05:00
|
|
|
import org.apache.xmlbeans.XmlObject;
|
2008-01-16 11:08:22 -05:00
|
|
|
import org.apache.xmlbeans.XmlOptions;
|
2008-09-30 09:57:36 -04:00
|
|
|
import org.openxml4j.exceptions.OpenXML4JException;
|
2008-10-19 11:31:28 -04:00
|
|
|
import org.openxml4j.exceptions.InvalidFormatException;
|
2008-09-30 09:57:36 -04:00
|
|
|
import org.openxml4j.opc.*;
|
2008-01-16 11:08:22 -05:00
|
|
|
import org.openxml4j.opc.Package;
|
2008-10-01 13:15:02 -04:00
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
|
2008-10-10 10:54:32 -04:00
|
|
|
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* High level representation of a SpreadsheetML workbook. This is the first object most users
|
|
|
|
* will construct whether they are reading or writing a workbook. It is also the
|
|
|
|
* top level object for creating new sheets/etc.
|
|
|
|
*/
|
|
|
|
public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<XSSFSheet> {
|
|
|
|
|
2008-10-21 13:56:34 -04:00
|
|
|
/**
|
|
|
|
* Width of one character of the default font in pixels. Same for Calibry and Arial.
|
|
|
|
*/
|
|
|
|
public static final float DEFAULT_CHARACTER_WIDTH = 7.0017f;
|
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* The underlying XML bean
|
|
|
|
*/
|
|
|
|
private CTWorkbook workbook;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this holds the XSSFSheet objects attached to this workbook
|
|
|
|
*/
|
|
|
|
private List<XSSFSheet> sheets;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this holds the XSSFName objects attached to this workbook
|
|
|
|
*/
|
|
|
|
private List<XSSFName> namedRanges;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* shared string table - a cache of strings in this workbook
|
|
|
|
*/
|
|
|
|
private SharedStringsTable sharedStringSource;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A collection of shared objects used for styling content,
|
|
|
|
* e.g. fonts, cell styles, colors, etc.
|
|
|
|
*/
|
2008-10-05 09:56:28 -04:00
|
|
|
private StylesTable stylesSource;
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to keep track of the data formatter so that all
|
|
|
|
* createDataFormatter calls return the same one for a given
|
|
|
|
* book. This ensures that updates from one places is visible
|
|
|
|
* someplace else.
|
|
|
|
*/
|
|
|
|
private XSSFDataFormat formatter;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The policy to apply in the event of missing or
|
|
|
|
* blank cells when fetching from a row.
|
|
|
|
* See {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy}
|
|
|
|
*/
|
|
|
|
private MissingCellPolicy missingCellPolicy = Row.RETURN_NULL_AND_BLANK;
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-10-10 10:54:32 -04:00
|
|
|
/**
|
|
|
|
* array of pictures for this workbook
|
|
|
|
*/
|
|
|
|
private List<XSSFPictureData> pictures;
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
private static POILogger log = POILogFactory.getLogger(XSSFWorkbook.class);
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-10-19 11:31:28 -04:00
|
|
|
/**
|
|
|
|
* The embedded OLE2 files in the OPC package
|
|
|
|
*/
|
|
|
|
private List<PackagePart> embedds;
|
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Create a new SpreadsheetML workbook.
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFWorkbook() {
|
2008-09-30 09:57:36 -04:00
|
|
|
super();
|
2008-10-19 11:31:28 -04:00
|
|
|
onDocumentCreate();
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructs a XSSFWorkbook object given a file name.
|
|
|
|
*
|
|
|
|
* @param path the file name.
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFWorkbook(String path) throws IOException {
|
|
|
|
this(openPackage(path));
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Constructs a XSSFWorkbook object given a OpenXML4J <code>Package</code> object,
|
|
|
|
* see <a href="http://openxml4j.org/">www.openxml4j.org</a>.
|
|
|
|
*
|
|
|
|
* @param pkg the OpenXML4J <code>Package</code> object.
|
|
|
|
*/
|
|
|
|
public XSSFWorkbook(Package pkg) throws IOException {
|
2008-10-19 11:31:28 -04:00
|
|
|
super(ensureWriteAccess(pkg));
|
|
|
|
onDocumentRead();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* YK: current implementation of OpenXML4J is funny.
|
|
|
|
* Packages opened by Package.open(InputStream is) are read-only,
|
|
|
|
* there is no way to change or even save such an instance in a OutputStream.
|
|
|
|
* The workaround is to create a copy via a temp file
|
|
|
|
*/
|
|
|
|
private static Package ensureWriteAccess(Package pkg) throws IOException {
|
2008-09-30 09:57:36 -04:00
|
|
|
if(pkg.getPackageAccess() == PackageAccess.READ){
|
|
|
|
try {
|
2008-10-19 11:31:28 -04:00
|
|
|
return PackageHelper.clone(pkg);
|
2008-09-30 09:57:36 -04:00
|
|
|
} catch (OpenXML4JException e){
|
|
|
|
throw new POIXMLException(e);
|
|
|
|
}
|
|
|
|
}
|
2008-10-19 11:31:28 -04:00
|
|
|
return pkg;
|
2008-09-30 09:57:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize this workbook from the specified Package
|
|
|
|
*/
|
|
|
|
@Override
|
2008-10-19 11:31:28 -04:00
|
|
|
protected void onDocumentRead() {
|
2008-10-01 13:15:02 -04:00
|
|
|
try {
|
2008-09-30 09:57:36 -04:00
|
|
|
//build the POIXMLDocumentPart tree, this workbook is the root
|
2008-10-12 09:10:30 -04:00
|
|
|
read(XSSFFactory.getInstance());
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-10-19 11:31:28 -04:00
|
|
|
WorkbookDocument doc = WorkbookDocument.Factory.parse(getPackagePart().getInputStream());
|
2008-10-01 13:15:02 -04:00
|
|
|
this.workbook = doc.getWorkbook();
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
HashMap<String, XSSFSheet> shIdMap = new HashMap<String, XSSFSheet>();
|
|
|
|
for(POIXMLDocumentPart p : getRelations()){
|
|
|
|
if(p instanceof SharedStringsTable) sharedStringSource = (SharedStringsTable)p;
|
2008-10-05 09:56:28 -04:00
|
|
|
else if(p instanceof StylesTable) stylesSource = (StylesTable)p;
|
2008-09-30 09:57:36 -04:00
|
|
|
else if (p instanceof XSSFSheet) {
|
|
|
|
shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
}
|
2008-10-19 11:31:28 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
// Load individual sheets
|
2008-09-30 09:57:36 -04:00
|
|
|
sheets = new LinkedList<XSSFSheet>();
|
2008-10-19 11:31:28 -04:00
|
|
|
embedds = new LinkedList<PackagePart>();
|
2008-10-01 13:15:02 -04:00
|
|
|
for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
|
2008-09-30 09:57:36 -04:00
|
|
|
String id = ctSheet.getId();
|
|
|
|
XSSFSheet sh = shIdMap.get(id);
|
|
|
|
sh.sheet = ctSheet;
|
|
|
|
if(sh == null) {
|
2008-10-01 13:15:02 -04:00
|
|
|
log.log(POILogger.WARN, "Sheet with name " + ctSheet.getName() + " and r:id " + ctSheet.getId()+ " was defined, but didn't exist in package, skipping");
|
|
|
|
continue;
|
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
//initialize internal arrays of rows and columns
|
|
|
|
sh.initialize();
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
PackagePart sheetPart = sh.getPackagePart();
|
2008-10-01 13:15:02 -04:00
|
|
|
// Process external hyperlinks for the sheet,
|
|
|
|
// if there are any
|
|
|
|
PackageRelationshipCollection hyperlinkRels =
|
|
|
|
sheetPart.getRelationshipsByType(XSSFRelation.SHEET_HYPERLINKS.getRelation());
|
2008-09-30 09:57:36 -04:00
|
|
|
sh.initHyperlinks(hyperlinkRels);
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
// Get the embeddings for the workbook
|
2008-09-30 09:57:36 -04:00
|
|
|
for(PackageRelationship rel : sheetPart.getRelationshipsByType(XSSFRelation.OLEEMBEDDINGS.getRelation()))
|
2008-10-01 13:15:02 -04:00
|
|
|
embedds.add(getTargetPart(rel)); // TODO: Add this reference to each sheet as well
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
for(PackageRelationship rel : sheetPart.getRelationshipsByType(XSSFRelation.PACKEMBEDDINGS.getRelation()))
|
2008-10-01 13:15:02 -04:00
|
|
|
embedds.add(getTargetPart(rel));
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
sheets.add(sh);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
if(sharedStringSource == null) {
|
|
|
|
//Create SST if it is missing
|
2008-10-12 09:10:30 -04:00
|
|
|
sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance());
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
// Process the named ranges
|
2008-09-30 09:57:36 -04:00
|
|
|
namedRanges = new LinkedList<XSSFName>();
|
|
|
|
if(workbook.getDefinedNames() != null) {
|
|
|
|
for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameArray()) {
|
|
|
|
namedRanges.add(new XSSFName(ctName, this));
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
throw new POIXMLException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-19 11:31:28 -04:00
|
|
|
@Override
|
|
|
|
protected void onDocumentCreate() {
|
2008-09-30 09:57:36 -04:00
|
|
|
workbook = CTWorkbook.Factory.newInstance();
|
|
|
|
CTBookViews bvs = workbook.addNewBookViews();
|
|
|
|
CTBookView bv = bvs.addNewWorkbookView();
|
|
|
|
bv.setActiveTab(0);
|
|
|
|
workbook.addNewSheets();
|
|
|
|
|
2008-10-12 09:10:30 -04:00
|
|
|
sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance());
|
|
|
|
stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance());
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
namedRanges = new LinkedList<XSSFName>();
|
|
|
|
sheets = new LinkedList<XSSFSheet>();
|
2008-10-19 11:31:28 -04:00
|
|
|
embedds = new LinkedList<PackagePart>();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new SpreadsheetML package and setup the default minimal content
|
|
|
|
*/
|
|
|
|
protected Package newPackage() throws IOException {
|
|
|
|
try {
|
|
|
|
Package pkg = Package.create(PackageHelper.createTempFile());
|
|
|
|
// Main part
|
|
|
|
PackagePartName corePartName = PackagingURIHelper.createPartName(XSSFRelation.WORKBOOK.getDefaultFileName());
|
|
|
|
// Create main part relationship
|
|
|
|
pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT);
|
|
|
|
// Create main document part
|
|
|
|
pkg.createPart(corePartName, XSSFRelation.WORKBOOK.getContentType());
|
|
|
|
|
|
|
|
pkg.getPackageProperties().setCreatorProperty("Apache POI");
|
|
|
|
|
|
|
|
return pkg;
|
|
|
|
} catch (InvalidFormatException e){
|
|
|
|
throw new POIXMLException(e);
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the underlying XML bean
|
|
|
|
*
|
|
|
|
* @return the underlying CTWorkbook bean
|
|
|
|
*/
|
|
|
|
public CTWorkbook getWorkbook() {
|
|
|
|
return this.workbook;
|
|
|
|
}
|
|
|
|
|
2008-10-10 10:54:32 -04:00
|
|
|
/**
|
|
|
|
* Adds a picture to the workbook.
|
|
|
|
*
|
|
|
|
* @param pictureData The bytes of the picture
|
|
|
|
* @param format The format of the picture.
|
|
|
|
*
|
|
|
|
* @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
|
|
|
|
* @see #PICTURE_TYPE_EMF
|
|
|
|
* @see #PICTURE_TYPE_WMF
|
|
|
|
* @see #PICTURE_TYPE_PICT
|
|
|
|
* @see #PICTURE_TYPE_JPEG
|
|
|
|
* @see #PICTURE_TYPE_PNG
|
|
|
|
* @see #PICTURE_TYPE_DIB
|
|
|
|
* @see #getAllPictures()
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public int addPicture(byte[] pictureData, int format) {
|
2008-10-10 10:54:32 -04:00
|
|
|
int imageNumber = getAllPictures().size() + 1;
|
2008-10-12 09:10:30 -04:00
|
|
|
XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true);
|
2008-10-10 10:54:32 -04:00
|
|
|
try {
|
|
|
|
OutputStream out = img.getPackagePart().getOutputStream();
|
|
|
|
out.write(pictureData);
|
|
|
|
out.close();
|
|
|
|
} catch (IOException e){
|
|
|
|
throw new POIXMLException(e);
|
|
|
|
}
|
|
|
|
pictures.add(img);
|
|
|
|
return imageNumber - 1;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
2008-10-17 11:14:00 -04:00
|
|
|
/**
|
|
|
|
* Adds a picture to the workbook.
|
|
|
|
*
|
|
|
|
* @param is The sream to read image from
|
|
|
|
* @param format The format of the picture.
|
|
|
|
*
|
|
|
|
* @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
|
|
|
|
* @see #PICTURE_TYPE_EMF
|
|
|
|
* @see #PICTURE_TYPE_WMF
|
|
|
|
* @see #PICTURE_TYPE_PICT
|
|
|
|
* @see #PICTURE_TYPE_JPEG
|
|
|
|
* @see #PICTURE_TYPE_PNG
|
|
|
|
* @see #PICTURE_TYPE_DIB
|
|
|
|
* @see #getAllPictures()
|
|
|
|
*/
|
|
|
|
public int addPicture(InputStream is, int format) throws IOException {
|
|
|
|
int imageNumber = getAllPictures().size() + 1;
|
|
|
|
XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true);
|
|
|
|
OutputStream out = img.getPackagePart().getOutputStream();
|
|
|
|
IOUtils.copy(is, out);
|
|
|
|
out.close();
|
|
|
|
pictures.add(img);
|
|
|
|
return imageNumber - 1;
|
|
|
|
}
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFSheet cloneSheet(int sheetNum) {
|
|
|
|
XSSFSheet srcSheet = sheets.get(sheetNum);
|
|
|
|
String srcName = getSheetName(sheetNum);
|
2008-10-19 08:54:40 -04:00
|
|
|
int i = 1;
|
|
|
|
String name = srcName;
|
|
|
|
while (true) {
|
|
|
|
//Try and find the next sheet name that is unique
|
|
|
|
String index = Integer.toString(i++);
|
|
|
|
if (name.length() + index.length() + 2 < 31) {
|
|
|
|
name = name + "("+index+")";
|
|
|
|
} else {
|
|
|
|
name = name.substring(0, 31 - index.length() - 2) + "(" +index + ")";
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
|
2008-10-19 08:54:40 -04:00
|
|
|
//If the sheet name is unique, then set it otherwise move on to the next number.
|
|
|
|
if (getSheetIndex(name) == -1) {
|
|
|
|
break;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
}
|
2008-10-19 08:54:40 -04:00
|
|
|
|
|
|
|
XSSFSheet clonedSheet = createSheet(name);
|
|
|
|
clonedSheet.worksheet.set(srcSheet.worksheet);
|
|
|
|
return clonedSheet;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Create a new XSSFCellStyle and add it to the workbook's style table
|
|
|
|
*
|
|
|
|
* @return the new XSSFCellStyle object
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFCellStyle createCellStyle() {
|
|
|
|
CTXf xf=CTXf.Factory.newInstance();
|
|
|
|
xf.setNumFmtId(0);
|
|
|
|
xf.setFontId(0);
|
|
|
|
xf.setFillId(0);
|
|
|
|
xf.setBorderId(0);
|
|
|
|
xf.setXfId(0);
|
2008-10-05 09:56:28 -04:00
|
|
|
int xfSize=(stylesSource)._getStyleXfsSize();
|
2008-10-21 13:56:34 -04:00
|
|
|
int indexXf=(stylesSource).putCellXf(xf);
|
|
|
|
XSSFCellStyle style = new XSSFCellStyle(indexXf-1, xfSize-1, stylesSource);
|
2008-10-01 13:15:02 -04:00
|
|
|
return style;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Returns the instance of XSSFDataFormat for this workbook.
|
|
|
|
*
|
|
|
|
* @return the XSSFDataFormat object
|
|
|
|
* @see org.apache.poi.ss.usermodel.DataFormat
|
|
|
|
*/
|
|
|
|
public XSSFDataFormat createDataFormat() {
|
|
|
|
if (formatter == null)
|
|
|
|
formatter = new XSSFDataFormat(stylesSource);
|
|
|
|
return formatter;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* create a new Font and add it to the workbook's font table
|
|
|
|
*
|
|
|
|
* @return new font object
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFFont createFont() {
|
2008-10-05 09:56:28 -04:00
|
|
|
XSSFFont font = new XSSFFont();
|
|
|
|
font.putFont(stylesSource);
|
2008-10-01 13:15:02 -04:00
|
|
|
return font;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Creates a new named range and add it to the model
|
|
|
|
*
|
|
|
|
* @return named range high level
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFName createName() {
|
|
|
|
XSSFName name = new XSSFName(this);
|
|
|
|
namedRanges.add(name);
|
|
|
|
return name;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* create an XSSFSheet for this workbook, adds it to the sheets and returns
|
|
|
|
* the high level representation. Use this to create new sheets.
|
|
|
|
*
|
|
|
|
* @return XSSFSheet representing the new sheet.
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFSheet createSheet() {
|
|
|
|
String sheetname = "Sheet" + (sheets.size() + 1);
|
|
|
|
return createSheet(sheetname);
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* create an XSSFSheet for this workbook, adds it to the sheets and returns
|
|
|
|
* the high level representation. Use this to create new sheets.
|
|
|
|
*
|
|
|
|
* @param sheetname sheetname to set for the sheet, can't be duplicate, greater than 31 chars or contain /\?*[]
|
|
|
|
* @return XSSFSheet representing the new sheet.
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFSheet createSheet(String sheetname) {
|
|
|
|
if (containsSheet( sheetname, sheets.size() ))
|
|
|
|
throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
int sheetNumber = getNumberOfSheets() + 1;
|
2008-10-12 09:10:30 -04:00
|
|
|
XSSFSheet wrapper = (XSSFSheet)createRelationship(XSSFRelation.WORKSHEET, XSSFFactory.getInstance(), sheetNumber);
|
2008-09-30 09:57:36 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
CTSheet sheet = addSheet(sheetname);
|
2008-09-30 09:57:36 -04:00
|
|
|
wrapper.sheet = sheet;
|
|
|
|
sheet.setId(wrapper.getPackageRelationship().getId());
|
|
|
|
sheet.setSheetId(sheetNumber);
|
2008-10-10 10:54:32 -04:00
|
|
|
if(sheets.size() == 0) wrapper.setSelected(true);
|
2008-10-01 13:15:02 -04:00
|
|
|
this.sheets.add(wrapper);
|
|
|
|
return wrapper;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-10-19 08:54:40 -04:00
|
|
|
protected XSSFDialogsheet createDialogsheet(String sheetname, CTDialogsheet dialogsheet) {
|
|
|
|
XSSFSheet sheet = createSheet(sheetname);
|
|
|
|
return new XSSFDialogsheet(sheet);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-02-29 09:18:06 -05:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
private CTSheet addSheet(String sheetname) {
|
|
|
|
validateSheetName(sheetname);
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
CTSheet sheet = workbook.getSheets().addNewSheet();
|
2008-10-01 13:15:02 -04:00
|
|
|
sheet.setName(sheetname);
|
|
|
|
return sheet;
|
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Finds a font that matches the one with the supplied attributes
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFFont findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) {
|
2008-10-05 09:56:28 -04:00
|
|
|
short fontNum = getNumberOfFonts();
|
2008-10-01 13:15:02 -04:00
|
|
|
for (short i = 0; i < fontNum; i++) {
|
|
|
|
XSSFFont xssfFont = getFontAt(i);
|
|
|
|
|
|
|
|
if ( (xssfFont.getBold() == (boldWeight == XSSFFont.BOLDWEIGHT_BOLD))
|
|
|
|
&& xssfFont.getColor() == color
|
|
|
|
&& xssfFont.getFontHeightInPoints() == fontHeight
|
|
|
|
&& xssfFont.getFontName().equals(name)
|
|
|
|
&& xssfFont.getItalic() == italic
|
|
|
|
&& xssfFont.getStrikeout() == strikeout
|
|
|
|
&& xssfFont.getTypeOffset() == typeOffset
|
|
|
|
&& xssfFont.getUnderline() == underline)
|
|
|
|
{
|
|
|
|
return xssfFont;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience method to get the active sheet. The active sheet is is the sheet
|
|
|
|
* which is currently displayed when the workbook is viewed in Excel.
|
|
|
|
* 'Selected' sheet(s) is a distinct concept.
|
|
|
|
*/
|
|
|
|
public int getActiveSheetIndex() {
|
|
|
|
//activeTab (Active Sheet Index) Specifies an unsignedInt
|
|
|
|
//that contains the index to the active sheet in this book view.
|
|
|
|
Long index = workbook.getBookViews().getWorkbookViewArray(0).getActiveTab();
|
|
|
|
return index.intValue();
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Gets all embedded OLE2 objects from the Workbook.
|
|
|
|
*
|
|
|
|
* @return the list of embedded objects (a list of {@link org.openxml4j.opc.PackagePart} objects.)
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public List getAllEmbeddedObjects() {
|
2008-09-30 09:57:36 -04:00
|
|
|
return embedds;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Gets all pictures from the Workbook.
|
|
|
|
*
|
|
|
|
* @return the list of pictures (a list of {@link XSSFPictureData} objects.)
|
|
|
|
*/
|
2008-10-10 10:54:32 -04:00
|
|
|
public List<XSSFPictureData> getAllPictures() {
|
|
|
|
if(pictures == null) {
|
|
|
|
//In OOXML pictures are referred to in sheets,
|
|
|
|
//dive into sheet's relations, select drawings and their images
|
|
|
|
pictures = new ArrayList();
|
|
|
|
for(XSSFSheet sh : sheets){
|
|
|
|
for(POIXMLDocumentPart dr : sh.getRelations()){
|
|
|
|
if(dr instanceof XSSFDrawing){
|
|
|
|
for(POIXMLDocumentPart img : dr.getRelations()){
|
|
|
|
if(img instanceof XSSFPictureData){
|
|
|
|
pictures.add((XSSFPictureData)img);
|
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
return pictures;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFCellStyle getCellStyleAt(short idx) {
|
2008-10-05 09:56:28 -04:00
|
|
|
return stylesSource.getStyleAt(idx);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Get the font at the given index number
|
|
|
|
*
|
|
|
|
* @param idx index number
|
|
|
|
* @return XSSFFont at the index
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFFont getFontAt(short idx) {
|
2008-10-12 09:10:30 -04:00
|
|
|
return stylesSource.getFontAt(idx);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Gets the Named range at the given index number
|
|
|
|
*
|
|
|
|
* @param index position of the named range
|
|
|
|
* @return XSSFName at the index
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFName getNameAt(int index) {
|
|
|
|
return namedRanges.get(index);
|
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the Named range name at the given index number,
|
|
|
|
* this method is equivalent to <code>getNameAt(index).getName()</code>
|
|
|
|
*
|
|
|
|
* @param index the named range index (0 based)
|
|
|
|
* @return named range name
|
|
|
|
* @see #getNameAt(int)
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public String getNameName(int index) {
|
|
|
|
return getNameAt(index).getNameName();
|
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the named range index by his name
|
|
|
|
* <i>Note:</i>Excel named ranges are case-insensitive and
|
|
|
|
* this method performs a case-insensitive search.
|
|
|
|
*
|
|
|
|
* @param name named range name
|
|
|
|
* @return named range index
|
|
|
|
*/
|
|
|
|
public int getNameIndex(String name) {
|
|
|
|
int i = 0;
|
|
|
|
for(XSSFName nr : namedRanges) {
|
|
|
|
if(nr.getNameName().equals(name)) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
return -1;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Get the number of styles the workbook contains
|
|
|
|
*
|
|
|
|
* @return count of cell styles
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public short getNumCellStyles() {
|
2008-10-05 09:56:28 -04:00
|
|
|
return (short) (stylesSource).getNumCellStyles();
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Get the number of fonts in the this workbook
|
|
|
|
*
|
|
|
|
* @return number of fonts
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public short getNumberOfFonts() {
|
2008-10-05 09:56:28 -04:00
|
|
|
return (short)(stylesSource).getNumberOfFonts();
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Get the number of named ranges in the this workbook
|
|
|
|
*
|
|
|
|
* @return number of named ranges
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public int getNumberOfNames() {
|
|
|
|
return namedRanges.size();
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Get the number of worksheets in the this workbook
|
|
|
|
*
|
|
|
|
* @return number of worksheets
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public int getNumberOfSheets() {
|
2008-09-30 09:57:36 -04:00
|
|
|
return this.sheets.size();
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-10-17 14:43:37 -04:00
|
|
|
/**
|
|
|
|
* Retrieves the reference for the printarea of the specified sheet, the sheet name is appended to the reference even if it was not specified.
|
|
|
|
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
|
|
|
|
* @return String Null if no print area has been defined
|
|
|
|
*/
|
|
|
|
public String getPrintArea(int sheetIndex) {
|
2008-10-21 13:56:34 -04:00
|
|
|
XSSFName name = getBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex);
|
2008-10-17 14:43:37 -04:00
|
|
|
if (name == null) return null;
|
|
|
|
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
|
|
|
|
return name.getReference();
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* deprecated May 2008
|
|
|
|
* @deprecated - Misleading name - use getActiveSheetIndex()
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public short getSelectedTab() {
|
|
|
|
short i = 0;
|
|
|
|
for (XSSFSheet sheet : this.sheets) {
|
|
|
|
if (sheet.isSelected()) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2008-09-16 08:25:54 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Get sheet with the given name (case insensitive match)
|
|
|
|
*
|
|
|
|
* @param name of the sheet
|
|
|
|
* @return XSSFSheet with the name provided or <code>null</code> if it does not exist
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFSheet getSheet(String name) {
|
|
|
|
CTSheet[] sheets = this.workbook.getSheets().getSheetArray();
|
|
|
|
for (int i = 0 ; i < sheets.length ; ++i) {
|
|
|
|
if (name.equals(sheets[i].getName())) {
|
|
|
|
return this.sheets.get(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Get the XSSFSheet object at the given index.
|
|
|
|
*
|
|
|
|
* @param index of the sheet number (0-based physical & logical)
|
|
|
|
* @return XSSFSheet at the provided index
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFSheet getSheetAt(int index) {
|
|
|
|
validateSheetIndex(index);
|
|
|
|
return this.sheets.get(index);
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Returns the index of the sheet by his name
|
|
|
|
*
|
|
|
|
* @param name the sheet name
|
|
|
|
* @return index of the sheet (0 based)
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public int getSheetIndex(String name) {
|
|
|
|
CTSheet[] sheets = this.workbook.getSheets().getSheetArray();
|
|
|
|
for (int i = 0 ; i < sheets.length ; ++i) {
|
|
|
|
if (name.equals(sheets[i].getName())) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Returns the index of the given sheet
|
|
|
|
*
|
|
|
|
* @param sheet the sheet to look up
|
|
|
|
* @return index of the sheet (0 based). <tt>-1</tt> if not found
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public int getSheetIndex(Sheet sheet) {
|
2008-09-30 09:57:36 -04:00
|
|
|
int idx = 0;
|
|
|
|
for(XSSFSheet sh : this){
|
|
|
|
if(sh == sheet) return idx;
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
return -1;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the sheet name
|
|
|
|
*
|
|
|
|
* @param sheetIx Number
|
|
|
|
* @return Sheet name
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public String getSheetName(int sheetIx) {
|
2008-09-30 09:57:36 -04:00
|
|
|
validateSheetIndex(sheetIx);
|
2008-10-01 13:15:02 -04:00
|
|
|
return this.workbook.getSheets().getSheetArray(sheetIx).getName();
|
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
/**
|
2008-10-01 13:15:02 -04:00
|
|
|
* Allows foreach loops:
|
2008-09-30 09:57:36 -04:00
|
|
|
* <pre><code>
|
|
|
|
* XSSFWorkbook wb = new XSSFWorkbook(package);
|
|
|
|
* for(XSSFSheet sheet : wb){
|
|
|
|
*
|
|
|
|
* }
|
|
|
|
* </code></pre>
|
|
|
|
*/
|
|
|
|
public Iterator<XSSFSheet> iterator() {
|
|
|
|
return sheets.iterator();
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
/**
|
|
|
|
* Are we a normal workbook (.xlsx), or a
|
|
|
|
* macro enabled workbook (.xlsm)?
|
|
|
|
*/
|
|
|
|
public boolean isMacroEnabled() {
|
2008-10-19 11:31:28 -04:00
|
|
|
return getPackagePart().getContentType().equals(XSSFRelation.MACROS_WORKBOOK.getContentType());
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
public void removeName(int index) {
|
|
|
|
// TODO Auto-generated method stub
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
public void removeName(String name) {
|
|
|
|
// TODO Auto-generated method stub
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
public void removePrintArea(int sheetIndex) {
|
|
|
|
// TODO Auto-generated method stub
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Removes sheet at the given index.<p/>
|
|
|
|
*
|
|
|
|
* Care must be taken if the removed sheet is the currently active or only selected sheet in
|
|
|
|
* the workbook. There are a few situations when Excel must have a selection and/or active
|
|
|
|
* sheet. (For example when printing - see Bug 40414).<br/>
|
|
|
|
*
|
|
|
|
* This method makes sure that if the removed sheet was active, another sheet will become
|
|
|
|
* active in its place. Furthermore, if the removed sheet was the only selected sheet, another
|
|
|
|
* sheet will become selected. The newly active/selected sheet will have the same index, or
|
|
|
|
* one less if the removed sheet was the last in the workbook.
|
|
|
|
*
|
|
|
|
* @param index of the sheet (0-based)
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public void removeSheetAt(int index) {
|
|
|
|
validateSheetIndex(index);
|
2008-10-10 10:54:32 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
this.sheets.remove(index);
|
|
|
|
this.workbook.getSheets().removeSheet(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the current policy on what to do when
|
|
|
|
* getting missing or blank cells from a row.
|
|
|
|
* The default is to return blank and null cells.
|
|
|
|
* {@link MissingCellPolicy}
|
|
|
|
*/
|
|
|
|
public MissingCellPolicy getMissingCellPolicy() {
|
|
|
|
return missingCellPolicy;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Sets the policy on what to do when
|
|
|
|
* getting missing or blank cells from a row.
|
|
|
|
* This will then apply to all calls to
|
|
|
|
* {@link Row#getCell(int)}}. See
|
|
|
|
* {@link MissingCellPolicy}
|
|
|
|
*/
|
|
|
|
public void setMissingCellPolicy(MissingCellPolicy missingCellPolicy) {
|
|
|
|
this.missingCellPolicy = missingCellPolicy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience method to set the active sheet. The active sheet is is the sheet
|
|
|
|
* which is currently displayed when the workbook is viewed in Excel.
|
|
|
|
* 'Selected' sheet(s) is a distinct concept.
|
|
|
|
*/
|
|
|
|
public void setActiveSheet(int index) {
|
|
|
|
|
|
|
|
validateSheetIndex(index);
|
|
|
|
//activeTab (Active Sheet Index) Specifies an unsignedInt that contains the index to the active sheet in this book view.
|
|
|
|
CTBookView[] arrayBook = workbook.getBookViews().getWorkbookViewArray();
|
|
|
|
for (int i = 0; i < arrayBook.length; i++) {
|
|
|
|
workbook.getBookViews().getWorkbookViewArray(i).setActiveTab(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate sheet index
|
|
|
|
*
|
|
|
|
* @param index the index to validate
|
|
|
|
* @throws IllegalArgumentException if the index is out of range (index
|
|
|
|
* < 0 || index >= getNumberOfSheets()).
|
|
|
|
*/
|
|
|
|
private void validateSheetIndex(int index) {
|
|
|
|
int lastSheetIx = sheets.size() - 1;
|
|
|
|
if (index < 0 || index > lastSheetIx) {
|
|
|
|
throw new IllegalArgumentException("Sheet index ("
|
|
|
|
+ index +") is out of range (0.." + lastSheetIx + ")");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the first tab that is displayed in the list of tabs in excel.
|
|
|
|
*
|
|
|
|
* @return integer that contains the index to the active sheet in this book view.
|
|
|
|
*/
|
|
|
|
public int getFirstVisibleTab() {
|
|
|
|
CTBookViews bookViews = workbook.getBookViews();
|
|
|
|
CTBookView bookView = bookViews.getWorkbookViewArray(0);
|
|
|
|
return (short) bookView.getActiveTab();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the first tab that is displayed in the list of tabs in excel.
|
|
|
|
*
|
|
|
|
* @param index integer that contains the index to the active sheet in this book view.
|
|
|
|
*/
|
|
|
|
public void setFirstVisibleTab(int index) {
|
|
|
|
CTBookViews bookViews = workbook.getBookViews();
|
|
|
|
CTBookView bookView= bookViews.getWorkbookViewArray(0);
|
|
|
|
bookView.setActiveTab(index);
|
|
|
|
}
|
|
|
|
|
2008-10-17 14:43:37 -04:00
|
|
|
/**
|
|
|
|
* Sets the printarea for the sheet provided
|
|
|
|
* <p>
|
|
|
|
* i.e. Reference = $A$1:$B$2
|
|
|
|
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
|
|
|
|
* @param reference Valid name Reference for the Print Area
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public void setPrintArea(int sheetIndex, String reference) {
|
2008-10-21 13:56:34 -04:00
|
|
|
XSSFName name = getBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex);
|
2008-10-17 14:43:37 -04:00
|
|
|
if (name == null) {
|
|
|
|
name = createBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex);
|
|
|
|
namedRanges.add(name);
|
|
|
|
}
|
|
|
|
name.setReference(reference);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
2008-10-17 14:43:37 -04:00
|
|
|
/**
|
|
|
|
* For the Convenience of Java Programmers maintaining pointers.
|
|
|
|
* @see #setPrintArea(int, String)
|
|
|
|
* @param sheetIndex Zero-based sheet index (0 = First Sheet)
|
|
|
|
* @param startColumn Column to begin printarea
|
|
|
|
* @param endColumn Column to end the printarea
|
|
|
|
* @param startRow Row to begin the printarea
|
|
|
|
* @param endRow Row to end the printarea
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public void setPrintArea(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) {
|
2008-10-17 14:43:37 -04:00
|
|
|
String reference=getReferencePrintArea(getSheetName(sheetIndex), startColumn, endColumn, startRow, endRow);
|
|
|
|
setPrintArea(sheetIndex, reference);
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
|
2008-10-17 14:43:37 -04:00
|
|
|
/**
|
|
|
|
* Sets the repeating rows and columns for a sheet.
|
|
|
|
* This is function is included in the workbook
|
|
|
|
* because it creates/modifies name records which are stored at the
|
|
|
|
* workbook level.
|
|
|
|
* <p>
|
|
|
|
* To set just repeating columns:
|
|
|
|
* <pre>
|
|
|
|
* workbook.setRepeatingRowsAndColumns(0,0,1,-1,-1);
|
|
|
|
* </pre>
|
|
|
|
* To set just repeating rows:
|
|
|
|
* <pre>
|
|
|
|
* workbook.setRepeatingRowsAndColumns(0,-1,-1,0,4);
|
|
|
|
* </pre>
|
|
|
|
* To remove all repeating rows and columns for a sheet.
|
|
|
|
* <pre>
|
|
|
|
* workbook.setRepeatingRowsAndColumns(0,-1,-1,-1,-1);
|
|
|
|
* </pre>
|
|
|
|
*
|
|
|
|
* @param sheetIndex 0 based index to sheet.
|
|
|
|
* @param startColumn 0 based start of repeating columns.
|
|
|
|
* @param endColumn 0 based end of repeating columns.
|
|
|
|
* @param startRow 0 based start of repeating rows.
|
|
|
|
* @param endRow 0 based end of repeating rows.
|
|
|
|
*/
|
|
|
|
public void setRepeatingRowsAndColumns(int sheetIndex,
|
|
|
|
int startColumn, int endColumn,
|
|
|
|
int startRow, int endRow) {
|
|
|
|
//TODO
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-17 14:43:37 -04:00
|
|
|
private String getReferencePrintArea(String sheetName, int startC, int endC, int startR, int endR) {
|
|
|
|
//windows excel example: Sheet1!$C$3:$E$4
|
|
|
|
CellReference colRef = new CellReference(sheetName, startR, startC, true, true);
|
|
|
|
CellReference colRef2 = new CellReference(sheetName, endR, endC, true, true);
|
|
|
|
|
|
|
|
String c = "'" + sheetName + "'!$" + colRef.getCellRefParts()[2] + "$" + colRef.getCellRefParts()[1] + ":$" + colRef2.getCellRefParts()[2] + "$" + colRef2.getCellRefParts()[1];
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
//****************** NAME RANGE *************************
|
|
|
|
|
|
|
|
private CTDefinedNames getDefinedNames() {
|
|
|
|
return workbook.getDefinedNames() == null ? workbook.addNewDefinedNames() : workbook.getDefinedNames();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-21 13:56:34 -04:00
|
|
|
private XSSFName getBuiltInName(String builtInCode, int sheetNumber) {
|
2008-10-17 14:43:37 -04:00
|
|
|
for (XSSFName name : namedRanges) {
|
|
|
|
if (name.getNameName().equalsIgnoreCase(builtInCode) && name.getLocalSheetId() == sheetNumber) {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
2008-10-17 14:43:37 -04:00
|
|
|
/**
|
|
|
|
* Generates a NameRecord to represent a built-in region
|
|
|
|
* @return a new NameRecord
|
|
|
|
*/
|
2008-10-21 13:56:34 -04:00
|
|
|
private XSSFName createBuiltInName(String builtInName, int sheetNumber) {
|
2008-10-17 14:43:37 -04:00
|
|
|
if (sheetNumber < 0 || sheetNumber+1 > Short.MAX_VALUE) {
|
|
|
|
throw new IllegalArgumentException("Sheet number ["+sheetNumber+"]is not valid ");
|
|
|
|
}
|
|
|
|
|
|
|
|
CTDefinedName nameRecord=getDefinedNames().addNewDefinedName();
|
|
|
|
nameRecord.setName(builtInName);
|
|
|
|
nameRecord.setLocalSheetId(sheetNumber);
|
|
|
|
|
|
|
|
XSSFName name=new XSSFName(nameRecord,this);
|
|
|
|
for(XSSFName nr : namedRanges){
|
|
|
|
if(nr.equals(name))
|
|
|
|
throw new RuntimeException("Builtin (" + builtInName
|
|
|
|
+ ") already exists for sheet (" + sheetNumber + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*******************************************
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
/**
|
|
|
|
* We only set one sheet as selected for compatibility with HSSF.
|
|
|
|
*/
|
|
|
|
public void setSelectedTab(short index) {
|
|
|
|
for (int i = 0 ; i < this.sheets.size() ; ++i) {
|
|
|
|
XSSFSheet sheet = this.sheets.get(i);
|
|
|
|
sheet.setSelected(i == index);
|
|
|
|
}
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Set the sheet name.
|
|
|
|
* Will throw IllegalArgumentException if the name is greater than 31 chars
|
|
|
|
* or contains /\?*[]
|
2008-10-01 13:15:02 -04:00
|
|
|
*
|
2008-09-30 09:57:36 -04:00
|
|
|
* @param sheet number (0 based)
|
2008-10-01 13:15:02 -04:00
|
|
|
* @see #validateSheetName(String)
|
|
|
|
*/
|
|
|
|
public void setSheetName(int sheet, String name) {
|
|
|
|
validateSheetIndex(sheet);
|
|
|
|
validateSheetName(name);
|
|
|
|
if (containsSheet(name, sheet ))
|
|
|
|
throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
|
|
|
|
this.workbook.getSheets().getSheetArray(sheet).setName(name);
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* sets the order of appearance for a given sheet.
|
|
|
|
*
|
|
|
|
* @param sheetname the name of the sheet to reorder
|
|
|
|
* @param pos the position that we want to insert the sheet into (0 based)
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public void setSheetOrder(String sheetname, int pos) {
|
|
|
|
int idx = getSheetIndex(sheetname);
|
|
|
|
sheets.add(pos, sheets.remove(idx));
|
|
|
|
// Reorder CTSheets
|
|
|
|
XmlObject cts = this.workbook.getSheets().getSheetArray(idx).copy();
|
|
|
|
this.workbook.getSheets().removeSheet(idx);
|
|
|
|
CTSheet newcts = this.workbook.getSheets().insertNewSheet(pos);
|
|
|
|
newcts.set(cts);
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* marshal named ranges from the {@link #namedRanges} collection to the underlying CTWorkbook bean
|
|
|
|
*/
|
|
|
|
private void saveNamedRanges(){
|
|
|
|
// Named ranges
|
|
|
|
if(namedRanges.size() > 0) {
|
|
|
|
CTDefinedNames names = CTDefinedNames.Factory.newInstance();
|
|
|
|
CTDefinedName[] nr = new CTDefinedName[namedRanges.size()];
|
|
|
|
int i = 0;
|
|
|
|
for(XSSFName name : namedRanges) {
|
|
|
|
nr[i] = name.getCTName();
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
names.setDefinedNameArray(nr);
|
|
|
|
workbook.setDefinedNames(names);
|
|
|
|
} else {
|
|
|
|
if(workbook.isSetDefinedNames()) {
|
|
|
|
workbook.unsetDefinedNames();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void commit() throws IOException {
|
|
|
|
saveNamedRanges();
|
|
|
|
|
|
|
|
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
|
|
|
|
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorkbook.type.getName().getNamespaceURI(), "workbook"));
|
2008-10-10 10:54:32 -04:00
|
|
|
Map map = new HashMap();
|
|
|
|
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
|
|
|
|
xmlOptions.setSaveSuggestedPrefixes(map);
|
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
PackagePart part = getPackagePart();
|
|
|
|
OutputStream out = part.getOutputStream();
|
|
|
|
workbook.save(out, xmlOptions);
|
|
|
|
out.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Method write - write out this workbook to an Outputstream.
|
|
|
|
*
|
|
|
|
* @param stream - the java OutputStream you wish to write the XLS to
|
|
|
|
*
|
|
|
|
* @exception IOException if anything can't be written.
|
|
|
|
*/
|
|
|
|
public void write(OutputStream stream) throws IOException {
|
|
|
|
//force all children to commit their changes into the underlying OOXML Package
|
|
|
|
save();
|
|
|
|
|
|
|
|
getPackage().save(stream);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Returns SharedStringsTable - tha cache of string for this workbook
|
|
|
|
*
|
|
|
|
* @return the shared string table
|
|
|
|
*/
|
|
|
|
public SharedStringsTable getSharedStringSource() {
|
2008-10-01 13:15:02 -04:00
|
|
|
return this.sharedStringSource;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Return a object representing a collection of shared objects used for styling content,
|
|
|
|
* e.g. fonts, cell styles, colors, etc.
|
|
|
|
*/
|
2008-10-05 09:56:28 -04:00
|
|
|
public StylesTable getStylesSource() {
|
2008-10-01 13:15:02 -04:00
|
|
|
return this.stylesSource;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Returns an object that handles instantiating concrete
|
|
|
|
* classes of the various instances for XSSF.
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFCreationHelper getCreationHelper() {
|
|
|
|
return new XSSFCreationHelper(this);
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Determines whether a workbook contains the provided sheet name.
|
|
|
|
*
|
|
|
|
* @param name the name to test (case insensitive match)
|
|
|
|
* @param excludeSheetIdx the sheet to exclude from the check or -1 to include all sheets in the check.
|
|
|
|
* @return true if the sheet contains the name, false otherwise.
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
private boolean containsSheet(String name, int excludeSheetIdx) {
|
|
|
|
CTSheet[] ctSheetArray = workbook.getSheets().getSheetArray();
|
|
|
|
for (int i = 0; i < ctSheetArray.length; i++) {
|
|
|
|
if (excludeSheetIdx != i && name.equalsIgnoreCase(ctSheetArray[i].getName()))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
/**
|
|
|
|
* Validates sheet name.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* The character count <tt>MUST</tt> be greater than or equal to 1 and less than or equal to 31.
|
|
|
|
* The string MUST NOT contain the any of the following characters:
|
|
|
|
* <ul>
|
|
|
|
* <li> 0x0000 </li>
|
|
|
|
* <li> 0x0003 </li>
|
|
|
|
* <li> colon (:) </li>
|
|
|
|
* <li> backslash (\) </li>
|
|
|
|
* <li> asterisk (*) </li>
|
|
|
|
* <li> question mark (?) </li>
|
|
|
|
* <li> forward slash (/) </li>
|
|
|
|
* <li> opening square bracket ([) </li>
|
|
|
|
* <li> closing square bracket (]) </li>
|
|
|
|
* </ul>
|
|
|
|
* The string MUST NOT begin or end with the single quote (') character.
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @param sheetName the name to validate
|
|
|
|
*/
|
2008-09-30 09:57:36 -04:00
|
|
|
private static void validateSheetName(String sheetName) {
|
|
|
|
if (sheetName == null) {
|
|
|
|
throw new IllegalArgumentException("sheetName must not be null");
|
|
|
|
}
|
|
|
|
int len = sheetName.length();
|
|
|
|
if (len < 1 || len > 31) {
|
|
|
|
throw new IllegalArgumentException("sheetName '" + sheetName
|
|
|
|
+ "' is invalid - must be 1-30 characters long");
|
|
|
|
}
|
|
|
|
for (int i=0; i<len; i++) {
|
|
|
|
char ch = sheetName.charAt(i);
|
|
|
|
switch (ch) {
|
|
|
|
case '/':
|
|
|
|
case '\\':
|
|
|
|
case '?':
|
|
|
|
case '*':
|
|
|
|
case ']':
|
|
|
|
case '[':
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// all other chars OK
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
throw new IllegalArgumentException("Invalid char (" + ch
|
|
|
|
+ ") found at index (" + i + ") in sheet name '" + sheetName + "'");
|
|
|
|
}
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a boolean value that indicates whether the date systems used in the workbook starts in 1904.
|
|
|
|
* <p>
|
|
|
|
* The default value is false, meaning that the workbook uses the 1900 date system,
|
|
|
|
* where 1/1/1900 is the first day in the system..
|
|
|
|
* </p>
|
|
|
|
* @return true if the date systems used in the workbook starts in 1904
|
|
|
|
*/
|
|
|
|
protected boolean isDate1904(){
|
|
|
|
CTWorkbookPr workbookPr = workbook.getWorkbookPr();
|
|
|
|
return workbookPr != null && workbookPr.getDate1904();
|
|
|
|
}
|
2008-10-19 11:31:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the document's embedded files.
|
|
|
|
*/
|
|
|
|
public List<PackagePart> getAllEmbedds() throws OpenXML4JException {
|
|
|
|
return embedds;
|
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|