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;
|
|
|
|
|
2008-11-18 21:01:58 -05:00
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.OutputStream;
|
2009-11-03 18:02:06 -05:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
2008-11-18 21:01:58 -05:00
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
2008-01-16 11:08:22 -05:00
|
|
|
import javax.xml.namespace.QName;
|
2008-11-18 21:01:58 -05:00
|
|
|
|
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;
|
2008-11-18 21:01:58 -05:00
|
|
|
import org.apache.poi.POIXMLException;
|
2009-07-24 03:29:22 -04:00
|
|
|
import org.apache.poi.POIXMLProperties;
|
2010-11-21 06:52:32 -05:00
|
|
|
import org.apache.poi.ss.formula.SheetNameFormatter;
|
2009-03-18 14:54:01 -04:00
|
|
|
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
|
|
|
import org.apache.poi.openxml4j.opc.OPCPackage;
|
|
|
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
|
|
|
import org.apache.poi.openxml4j.opc.PackagePartName;
|
|
|
|
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
|
|
|
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
|
|
|
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
|
|
|
import org.apache.poi.openxml4j.opc.TargetMode;
|
2010-11-28 07:03:52 -05:00
|
|
|
import org.apache.poi.ss.formula.udf.UDFFinder;
|
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;
|
2010-09-04 11:56:29 -04:00
|
|
|
import org.apache.poi.ss.util.WorkbookUtil;
|
2009-12-03 11:50:34 -05:00
|
|
|
import org.apache.poi.util.*;
|
2010-11-28 07:03:52 -05:00
|
|
|
import org.apache.poi.xssf.model.*;
|
2011-03-04 06:15:01 -05:00
|
|
|
import org.apache.poi.xssf.usermodel.helpers.XSSFFormulaUtils;
|
2008-11-18 21:01:58 -05:00
|
|
|
import org.apache.xmlbeans.XmlException;
|
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-10-10 10:54:32 -04:00
|
|
|
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
|
2009-11-03 18:02:06 -05:00
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookView;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookViews;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheets;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookProtection;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STSheetState;
|
|
|
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument;
|
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-11-18 21:01:58 -05:00
|
|
|
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
2008-09-30 09:57:36 -04:00
|
|
|
|
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;
|
|
|
|
|
2010-09-07 03:09:49 -04:00
|
|
|
/**
|
|
|
|
* Excel silently truncates long sheet names to 31 chars.
|
|
|
|
* This constant is used to ensure uniqueness in the first 31 chars
|
|
|
|
*/
|
|
|
|
private static final int MAX_SENSITIVE_SHEET_NAME_LEN = 31;
|
|
|
|
|
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
|
|
|
|
2010-05-19 07:55:17 -04:00
|
|
|
private ThemesTable theme;
|
|
|
|
|
2010-11-28 07:03:52 -05:00
|
|
|
/**
|
|
|
|
* The locator of user-defined functions.
|
|
|
|
* By default includes functions from the Excel Analysis Toolpack
|
|
|
|
*/
|
|
|
|
private IndexedUDFFinder _udfFinder = new IndexedUDFFinder(UDFFinder.DEFAULT);
|
|
|
|
|
2009-02-08 07:45:55 -05:00
|
|
|
/**
|
|
|
|
* TODO
|
|
|
|
*/
|
|
|
|
private CalculationChain calcChain;
|
|
|
|
|
2009-07-16 01:46:14 -04:00
|
|
|
/**
|
|
|
|
* A collection of custom XML mappings
|
|
|
|
*/
|
|
|
|
private MapInfo mapInfo;
|
|
|
|
|
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}
|
|
|
|
*/
|
2009-02-13 16:46:44 -05:00
|
|
|
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-28 06:03:51 -04:00
|
|
|
private static POILogger logger = POILogFactory.getLogger(XSSFWorkbook.class);
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2009-11-30 09:09:03 -05:00
|
|
|
/**
|
|
|
|
* cached instance of XSSFCreationHelper for this workbook
|
|
|
|
* @see {@link #getCreationHelper()}
|
|
|
|
*/
|
|
|
|
private XSSFCreationHelper _creationHelper;
|
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Create a new SpreadsheetML workbook.
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFWorkbook() {
|
2008-10-25 07:48:50 -04:00
|
|
|
super(newPackage());
|
|
|
|
onWorkbookCreate();
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
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.
|
|
|
|
*/
|
2009-03-18 14:54:01 -04:00
|
|
|
public XSSFWorkbook(OPCPackage pkg) throws IOException {
|
2010-01-13 15:24:15 -05:00
|
|
|
super(pkg);
|
2008-10-25 07:48:50 -04:00
|
|
|
|
|
|
|
//build a tree of POIXMLDocumentParts, this workbook being the root
|
2009-08-12 14:59:34 -04:00
|
|
|
load(XSSFFactory.getInstance());
|
|
|
|
}
|
|
|
|
|
|
|
|
public XSSFWorkbook(InputStream is) throws IOException {
|
|
|
|
super(PackageHelper.open(is));
|
2010-01-13 15:24:15 -05:00
|
|
|
|
2009-08-12 14:59:34 -04:00
|
|
|
//build a tree of POIXMLDocumentParts, this workbook being the root
|
|
|
|
load(XSSFFactory.getInstance());
|
2008-10-19 11:31:28 -04:00
|
|
|
}
|
|
|
|
|
2008-10-25 07:48:50 -04:00
|
|
|
/**
|
|
|
|
* Constructs a XSSFWorkbook object given a file name.
|
|
|
|
*
|
|
|
|
* @param path the file name.
|
|
|
|
*/
|
|
|
|
public XSSFWorkbook(String path) throws IOException {
|
|
|
|
this(openPackage(path));
|
|
|
|
}
|
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
@Override
|
2010-10-14 04:40:06 -04:00
|
|
|
@SuppressWarnings("deprecation") // getXYZArray() array accessors are deprecated
|
2008-10-25 07:48:50 -04:00
|
|
|
protected void onDocumentRead() throws IOException {
|
2008-10-01 13:15:02 -04:00
|
|
|
try {
|
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-10-25 07:48:50 -04:00
|
|
|
Map<String, XSSFSheet> shIdMap = new HashMap<String, XSSFSheet>();
|
2008-09-30 09:57:36 -04:00
|
|
|
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;
|
2010-05-19 07:55:17 -04:00
|
|
|
else if(p instanceof ThemesTable) theme = (ThemesTable)p;
|
2009-02-08 07:45:55 -05:00
|
|
|
else if(p instanceof CalculationChain) calcChain = (CalculationChain)p;
|
2009-07-16 01:46:14 -04:00
|
|
|
else if(p instanceof MapInfo) mapInfo = (MapInfo)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
|
|
|
}
|
|
|
|
}
|
2010-05-19 07:55:17 -04:00
|
|
|
stylesSource.setTheme(theme);
|
2008-10-19 11:31:28 -04:00
|
|
|
|
2009-04-17 14:02:01 -04:00
|
|
|
if(sharedStringSource == null) {
|
|
|
|
//Create SST if it is missing
|
|
|
|
sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance());
|
|
|
|
}
|
|
|
|
|
2008-10-29 15:12:47 -04:00
|
|
|
// Load individual sheets. The order of sheets is defined by the order of CTSheet elements in the workbook
|
2008-10-25 07:48:50 -04:00
|
|
|
sheets = new ArrayList<XSSFSheet>(shIdMap.size());
|
2010-10-14 04:40:06 -04:00
|
|
|
for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
|
2008-10-25 07:48:50 -04:00
|
|
|
XSSFSheet sh = shIdMap.get(ctSheet.getId());
|
2008-09-30 09:57:36 -04:00
|
|
|
if(sh == null) {
|
2008-10-28 06:03:51 -04:00
|
|
|
logger.log(POILogger.WARN, "Sheet with name " + ctSheet.getName() + " and r:id " + ctSheet.getId()+ " was defined, but didn't exist in package, skipping");
|
2008-10-01 13:15:02 -04:00
|
|
|
continue;
|
|
|
|
}
|
2008-10-25 07:48:50 -04:00
|
|
|
sh.sheet = ctSheet;
|
|
|
|
sh.onDocumentRead();
|
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
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
// Process the named ranges
|
2008-10-25 07:48:50 -04:00
|
|
|
namedRanges = new ArrayList<XSSFName>();
|
2008-10-29 15:12:47 -04:00
|
|
|
if(workbook.isSetDefinedNames()) {
|
2010-10-14 04:40:06 -04:00
|
|
|
for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameArray()) {
|
2008-09-30 09:57:36 -04:00
|
|
|
namedRanges.add(new XSSFName(ctName, this));
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
2008-10-25 07:48:50 -04:00
|
|
|
} catch (XmlException e) {
|
2008-09-30 09:57:36 -04:00
|
|
|
throw new POIXMLException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-25 07:48:50 -04:00
|
|
|
/**
|
|
|
|
* Create a new CTWorkbook with all values set to default
|
|
|
|
*/
|
|
|
|
private void onWorkbookCreate() {
|
2008-09-30 09:57:36 -04:00
|
|
|
workbook = CTWorkbook.Factory.newInstance();
|
2009-06-27 07:21:26 -04:00
|
|
|
|
|
|
|
// don't EVER use the 1904 date system
|
|
|
|
CTWorkbookPr workbookPr = workbook.addNewWorkbookPr();
|
|
|
|
workbookPr.setDate1904(false);
|
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
CTBookViews bvs = workbook.addNewBookViews();
|
|
|
|
CTBookView bv = bvs.addNewWorkbookView();
|
|
|
|
bv.setActiveTab(0);
|
|
|
|
workbook.addNewSheets();
|
|
|
|
|
2009-07-24 03:29:22 -04:00
|
|
|
POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
|
2009-08-09 09:08:59 -04:00
|
|
|
expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR);
|
2009-07-24 03:29:22 -04:00
|
|
|
|
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
|
|
|
|
2008-10-25 07:48:50 -04:00
|
|
|
namedRanges = new ArrayList<XSSFName>();
|
|
|
|
sheets = new ArrayList<XSSFSheet>();
|
2008-10-19 11:31:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new SpreadsheetML package and setup the default minimal content
|
|
|
|
*/
|
2009-03-18 14:54:01 -04:00
|
|
|
protected static OPCPackage newPackage() {
|
2008-10-19 11:31:28 -04:00
|
|
|
try {
|
2010-01-14 14:23:13 -05:00
|
|
|
OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream());
|
2008-10-19 11:31:28 -04:00
|
|
|
// 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());
|
|
|
|
|
2009-08-09 09:08:59 -04:00
|
|
|
pkg.getPackageProperties().setCreatorProperty(DOCUMENT_CREATOR);
|
2008-10-19 11:31:28 -04:00
|
|
|
|
|
|
|
return pkg;
|
2008-10-25 07:48:50 -04:00
|
|
|
} catch (Exception e){
|
2008-10-19 11:31:28 -04:00
|
|
|
throw new POIXMLException(e);
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the underlying XML bean
|
|
|
|
*
|
|
|
|
* @return the underlying CTWorkbook bean
|
|
|
|
*/
|
2009-12-03 11:50:34 -05:00
|
|
|
@Internal
|
2008-10-25 07:48:50 -04:00
|
|
|
public CTWorkbook getCTWorkbook() {
|
2008-10-01 13:15:02 -04:00
|
|
|
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()} .
|
2008-11-07 11:57:23 -05:00
|
|
|
* @see Workbook#PICTURE_TYPE_EMF
|
|
|
|
* @see Workbook#PICTURE_TYPE_WMF
|
|
|
|
* @see Workbook#PICTURE_TYPE_PICT
|
|
|
|
* @see Workbook#PICTURE_TYPE_JPEG
|
|
|
|
* @see Workbook#PICTURE_TYPE_PNG
|
|
|
|
* @see Workbook#PICTURE_TYPE_DIB
|
2008-10-10 10:54:32 -04:00
|
|
|
* @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()} .
|
2008-11-07 11:57:23 -05:00
|
|
|
* @see Workbook#PICTURE_TYPE_EMF
|
|
|
|
* @see Workbook#PICTURE_TYPE_WMF
|
|
|
|
* @see Workbook#PICTURE_TYPE_PICT
|
|
|
|
* @see Workbook#PICTURE_TYPE_JPEG
|
|
|
|
* @see Workbook#PICTURE_TYPE_PNG
|
|
|
|
* @see Workbook#PICTURE_TYPE_DIB
|
2008-10-17 11:14:00 -04:00
|
|
|
* @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-28 06:03:51 -04:00
|
|
|
/**
|
|
|
|
* Create an XSSFSheet from an existing sheet in the XSSFWorkbook.
|
|
|
|
* The cloned sheet is a deep copy of the original.
|
|
|
|
*
|
|
|
|
* @return XSSFSheet representing the cloned sheet.
|
|
|
|
* @throws IllegalArgumentException if the sheet index in invalid
|
|
|
|
* @throws POIXMLException if there were errors when cloning
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFSheet cloneSheet(int sheetNum) {
|
2008-10-28 06:03:51 -04:00
|
|
|
validateSheetIndex(sheetNum);
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
XSSFSheet srcSheet = sheets.get(sheetNum);
|
2008-10-28 06:03:51 -04:00
|
|
|
String srcName = srcSheet.getSheetName();
|
|
|
|
String clonedName = getUniqueSheetName(srcName);
|
|
|
|
|
|
|
|
XSSFSheet clonedSheet = createSheet(clonedName);
|
|
|
|
try {
|
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
|
srcSheet.write(out);
|
|
|
|
clonedSheet.read(new ByteArrayInputStream(out.toByteArray()));
|
|
|
|
} catch (IOException e){
|
|
|
|
throw new POIXMLException("Failed to clone sheet", e);
|
|
|
|
}
|
|
|
|
CTWorksheet ct = clonedSheet.getCTWorksheet();
|
|
|
|
if(ct.isSetDrawing()) {
|
|
|
|
logger.log(POILogger.WARN, "Cloning sheets with drawings is not yet supported.");
|
|
|
|
ct.unsetDrawing();
|
|
|
|
}
|
|
|
|
if(ct.isSetLegacyDrawing()) {
|
|
|
|
logger.log(POILogger.WARN, "Cloning sheets with comments is not yet supported.");
|
|
|
|
ct.unsetLegacyDrawing();
|
|
|
|
}
|
|
|
|
|
|
|
|
clonedSheet.setSelected(false);
|
|
|
|
return clonedSheet;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate a valid sheet name based on the existing one. Used when cloning sheets.
|
|
|
|
*
|
|
|
|
* @param srcName the original sheet name to
|
|
|
|
* @return clone sheet name
|
|
|
|
*/
|
|
|
|
private String getUniqueSheetName(String srcName) {
|
|
|
|
int uniqueIndex = 2;
|
|
|
|
String baseName = srcName;
|
|
|
|
int bracketPos = srcName.lastIndexOf('(');
|
|
|
|
if (bracketPos > 0 && srcName.endsWith(")")) {
|
|
|
|
String suffix = srcName.substring(bracketPos + 1, srcName.length() - ")".length());
|
|
|
|
try {
|
|
|
|
uniqueIndex = Integer.parseInt(suffix.trim());
|
|
|
|
uniqueIndex++;
|
|
|
|
baseName = srcName.substring(0, bracketPos).trim();
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
// contents of brackets not numeric
|
|
|
|
}
|
|
|
|
}
|
2008-10-19 08:54:40 -04:00
|
|
|
while (true) {
|
2008-10-28 06:03:51 -04:00
|
|
|
// Try and find the next sheet name that is unique
|
|
|
|
String index = Integer.toString(uniqueIndex++);
|
|
|
|
String name;
|
|
|
|
if (baseName.length() + index.length() + 2 < 31) {
|
|
|
|
name = baseName + " (" + index + ")";
|
2008-10-19 08:54:40 -04:00
|
|
|
} else {
|
2008-10-28 06:03:51 -04:00
|
|
|
name = baseName.substring(0, 31 - index.length() - 2) + "(" + index + ")";
|
2008-10-19 08:54:40 -04:00
|
|
|
}
|
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) {
|
2008-10-28 06:03:51 -04:00
|
|
|
return name;
|
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() {
|
2008-10-29 15:12:47 -04:00
|
|
|
return stylesSource.createCellStyle();
|
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 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-10-25 07:48:50 -04:00
|
|
|
* Create a new Font and add it to the workbook's font table
|
2008-09-30 09:57:36 -04:00
|
|
|
*
|
|
|
|
* @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();
|
2010-05-28 09:44:45 -04:00
|
|
|
font.registerTo(stylesSource);
|
2008-10-01 13:15:02 -04:00
|
|
|
return font;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFName createName() {
|
2010-09-11 08:45:59 -04:00
|
|
|
CTDefinedName ctName = CTDefinedName.Factory.newInstance();
|
|
|
|
ctName.setName("");
|
|
|
|
XSSFName name = new XSSFName(ctName, this);
|
2008-10-01 13:15:02 -04:00
|
|
|
namedRanges.add(name);
|
|
|
|
return name;
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
2008-10-25 07:48:50 -04:00
|
|
|
* Create an XSSFSheet for this workbook, adds it to the sheets and returns
|
2008-09-30 09:57:36 -04:00
|
|
|
* 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() {
|
2009-03-27 07:50:52 -04:00
|
|
|
String sheetname = "Sheet" + (sheets.size());
|
2009-03-29 12:10:40 -04:00
|
|
|
int idx = 0;
|
|
|
|
while(getSheet(sheetname) != null) {
|
|
|
|
sheetname = "Sheet" + idx;
|
|
|
|
idx++;
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
return createSheet(sheetname);
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
2011-06-23 06:49:11 -04:00
|
|
|
* Create a new sheet for this Workbook and return the high level representation.
|
|
|
|
* Use this to create new sheets.
|
2008-09-30 09:57:36 -04:00
|
|
|
*
|
2011-06-23 06:49:11 -04:00
|
|
|
* <p>
|
|
|
|
* Note that Excel allows sheet names up to 31 chars in length but other applications
|
|
|
|
* (such as OpenOffice) allow more. Some versions of Excel crash with names longer than 31 chars,
|
|
|
|
* others - truncate such names to 31 character.
|
|
|
|
* </p>
|
|
|
|
* <p>
|
|
|
|
* POI's SpreadsheetAPI silently truncates the input argument to 31 characters.
|
|
|
|
* Example:
|
|
|
|
*
|
|
|
|
* <pre><code>
|
|
|
|
* Sheet sheet = workbook.createSheet("My very long sheet name which is longer than 31 chars"); // will be truncated
|
|
|
|
* assert 31 == sheet.getSheetName().length();
|
|
|
|
* assert "My very long sheet name which i" == sheet.getSheetName();
|
|
|
|
* </code></pre>
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* Except the 31-character constraint, Excel applies some other rules:
|
|
|
|
* <p>
|
|
|
|
* Sheet name MUST be unique in the workbook and 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 sheetname to set for the sheet.
|
|
|
|
* @return Sheet representing the new sheet.
|
|
|
|
* @throws IllegalArgumentException if the name is null or invalid
|
|
|
|
* or workbook already contains a sheet with this name
|
|
|
|
* @see {@link org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)}
|
|
|
|
* for a safe way to create valid names
|
2008-09-30 09:57:36 -04:00
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFSheet createSheet(String sheetname) {
|
2011-06-23 06:49:11 -04:00
|
|
|
if (sheetname == null) {
|
|
|
|
throw new IllegalArgumentException("sheetName must not be null");
|
|
|
|
}
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
if (containsSheet( sheetname, sheets.size() ))
|
2008-10-29 15:12:47 -04:00
|
|
|
throw new IllegalArgumentException( "The workbook already contains a sheet of this name");
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2011-06-23 06:49:11 -04:00
|
|
|
// YK: Mimic Excel and silently truncate sheet names longer than 31 characters
|
|
|
|
if(sheetname.length() > 31) sheetname = sheetname.substring(0, 31);
|
|
|
|
WorkbookUtil.validateSheetName(sheetname);
|
|
|
|
|
2008-10-25 07:48:50 -04:00
|
|
|
CTSheet sheet = addSheet(sheetname);
|
|
|
|
|
2009-04-24 14:25:19 -04:00
|
|
|
int sheetNumber = 1;
|
|
|
|
for(XSSFSheet sh : sheets) sheetNumber = (int)Math.max(sh.sheet.getSheetId() + 1, sheetNumber);
|
|
|
|
|
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
|
|
|
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-25 07:48:50 -04:00
|
|
|
sheets.add(wrapper);
|
2008-10-01 13:15:02 -04:00
|
|
|
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) {
|
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-29 15:12:47 -04:00
|
|
|
return stylesSource.findFont(boldWeight, color, fontHeight, name, italic, strikeout, typeOffset, underline);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
2008-10-25 07:48:50 -04:00
|
|
|
return (int)workbook.getBookViews().getWorkbookViewArray(0).getActiveTab();
|
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-25 07:48:50 -04:00
|
|
|
* @see #addPicture(byte[], int)
|
2008-09-30 09:57:36 -04:00
|
|
|
*/
|
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
|
2009-02-13 16:46:44 -05:00
|
|
|
pictures = new ArrayList<XSSFPictureData>();
|
2008-10-10 10:54:32 -04:00
|
|
|
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-27 16:28:44 -04:00
|
|
|
/**
|
|
|
|
* gGet the cell style object at the given index
|
|
|
|
*
|
|
|
|
* @param idx index within the set of styles
|
|
|
|
* @return XSSFCellStyle object at the index
|
|
|
|
*/
|
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
|
|
|
|
2009-04-16 16:34:13 -04:00
|
|
|
public XSSFName getName(String name) {
|
|
|
|
int nameIndex = getNameIndex(name);
|
|
|
|
if (nameIndex < 0) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return namedRanges.get(nameIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
public XSSFName getNameAt(int nameIndex) {
|
|
|
|
int nNames = namedRanges.size();
|
|
|
|
if (nNames < 1) {
|
|
|
|
throw new IllegalStateException("There are no defined names in this workbook");
|
|
|
|
}
|
|
|
|
if (nameIndex < 0 || nameIndex > nNames) {
|
2009-08-17 22:41:45 -04:00
|
|
|
throw new IllegalArgumentException("Specified name index " + nameIndex
|
2009-04-16 16:34:13 -04:00
|
|
|
+ " is outside the allowable range (0.." + (nNames-1) + ").");
|
|
|
|
}
|
|
|
|
return namedRanges.get(nameIndex);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
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-29 15:12:47 -04:00
|
|
|
return (short)stylesSource.getFonts().size();
|
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-10-29 15:12:47 -04:00
|
|
|
return 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
|
|
|
|
*/
|
2009-08-17 22:41:45 -04:00
|
|
|
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
|
2008-11-21 04:22:07 -05:00
|
|
|
return name.getRefersToFormula();
|
2008-10-25 09:39:43 -04:00
|
|
|
|
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 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) {
|
2008-10-29 15:12:47 -04:00
|
|
|
for (XSSFSheet sheet : sheets) {
|
|
|
|
if (name.equalsIgnoreCase(sheet.getSheetName())) {
|
|
|
|
return sheet;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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-25 07:48:50 -04:00
|
|
|
* @throws IllegalArgumentException if the index is out of range (index
|
|
|
|
* < 0 || index >= getNumberOfSheets()).
|
2008-09-30 09:57:36 -04:00
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public XSSFSheet getSheetAt(int index) {
|
|
|
|
validateSheetIndex(index);
|
2008-10-25 07:48:50 -04:00
|
|
|
return sheets.get(index);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
2008-10-25 07:48:50 -04:00
|
|
|
* Returns the index of the sheet by his name (case insensitive match)
|
2008-09-30 09:57:36 -04:00
|
|
|
*
|
|
|
|
* @param name the sheet name
|
2008-10-25 07:48:50 -04:00
|
|
|
* @return index of the sheet (0 based) or <tt>-1</tt if not found
|
2008-09-30 09:57:36 -04:00
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public int getSheetIndex(String name) {
|
2008-10-29 15:12:47 -04:00
|
|
|
for (int i = 0 ; i < sheets.size() ; ++i) {
|
|
|
|
XSSFSheet sheet = sheets.get(i);
|
|
|
|
if (name.equalsIgnoreCase(sheet.getSheetName())) {
|
2008-10-01 13:15:02 -04:00
|
|
|
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;
|
2008-10-29 15:12:47 -04:00
|
|
|
for(XSSFSheet sh : sheets){
|
2008-09-30 09:57:36 -04:00
|
|
|
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-29 15:12:47 -04:00
|
|
|
return sheets.get(sheetIx).getSheetName();
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
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-25 09:39:43 -04:00
|
|
|
public void removeName(int nameIndex) {
|
2008-10-27 16:28:44 -04:00
|
|
|
namedRanges.remove(nameIndex);
|
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) {
|
2008-10-27 16:28:44 -04:00
|
|
|
for (int i = 0; i < namedRanges.size(); i++) {
|
|
|
|
XSSFName nm = namedRanges.get(i);
|
|
|
|
if(nm.getNameName().equalsIgnoreCase(name)) {
|
|
|
|
removeName(i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw new IllegalArgumentException("Named range was not found: " + name);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
2008-01-16 11:08:22 -05:00
|
|
|
|
2008-10-25 09:39:43 -04:00
|
|
|
/**
|
|
|
|
* Delete the printarea for the sheet specified
|
|
|
|
*
|
|
|
|
* @param sheetIndex 0-based sheet index (0 = First Sheet)
|
|
|
|
*/
|
2008-10-01 13:15:02 -04:00
|
|
|
public void removePrintArea(int sheetIndex) {
|
2008-10-25 09:39:43 -04:00
|
|
|
int cont = 0;
|
|
|
|
for (XSSFName name : namedRanges) {
|
2008-12-04 13:38:00 -05:00
|
|
|
if (name.getNameName().equals(XSSFName.BUILTIN_PRINT_AREA) && name.getSheetIndex() == sheetIndex) {
|
2008-10-25 09:39:43 -04:00
|
|
|
namedRanges.remove(cont);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cont++;
|
|
|
|
}
|
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
|
|
|
|
2009-09-12 12:01:18 -04:00
|
|
|
onSheetDelete(index);
|
|
|
|
|
2009-03-27 07:50:52 -04:00
|
|
|
XSSFSheet sheet = getSheetAt(index);
|
|
|
|
removeRelation(sheet);
|
2009-09-12 12:01:18 -04:00
|
|
|
sheets.remove(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gracefully remove references to the sheet being deleted
|
|
|
|
*
|
|
|
|
* @param index the 0-based index of the sheet to delete
|
|
|
|
*/
|
|
|
|
private void onSheetDelete(int index) {
|
|
|
|
//delete the CTSheet reference from workbook.xml
|
|
|
|
workbook.getSheets().removeSheet(index);
|
|
|
|
|
2010-09-21 07:16:12 -04:00
|
|
|
//calculation chain is auxiliary, remove it as it may contain orphan references to deleted cells
|
2009-09-12 12:01:18 -04:00
|
|
|
if(calcChain != null) {
|
|
|
|
removeRelation(calcChain);
|
|
|
|
calcChain = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
//adjust indices of names ranges
|
|
|
|
for (Iterator<XSSFName> it = namedRanges.iterator(); it.hasNext();) {
|
|
|
|
XSSFName nm = it.next();
|
|
|
|
CTDefinedName ct = nm.getCTName();
|
|
|
|
if(!ct.isSetLocalSheetId()) continue;
|
|
|
|
if (ct.getLocalSheetId() == index) {
|
|
|
|
it.remove();
|
|
|
|
} else if (ct.getLocalSheetId() > index){
|
|
|
|
// Bump down by one, so still points at the same sheet
|
|
|
|
ct.setLocalSheetId(ct.getLocalSheetId()-1);
|
|
|
|
}
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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() {
|
2009-02-13 16:46:44 -05:00
|
|
|
return _missingCellPolicy;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* 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) {
|
2009-02-13 16:46:44 -05:00
|
|
|
_missingCellPolicy = missingCellPolicy;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2010-10-14 06:06:16 -04:00
|
|
|
@SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are deprecated in xmlbeans with JDK 1.5 support
|
2008-10-01 13:15:02 -04:00
|
|
|
public void setActiveSheet(int index) {
|
|
|
|
|
|
|
|
validateSheetIndex(index);
|
2010-10-14 04:40:06 -04:00
|
|
|
|
|
|
|
for (CTBookView arrayBook : workbook.getBookViews().getWorkbookViewArray()) {
|
|
|
|
arrayBook.setActiveTab(index);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 ("
|
2009-04-16 16:34:13 -04:00
|
|
|
+ index +") is out of range (0.." + lastSheetIx + ")");
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
2008-10-27 16:28:44 -04:00
|
|
|
//short externSheetIndex = getWorkbook().checkExternSheet(sheetIndex);
|
|
|
|
//name.setExternSheetNumber(externSheetIndex);
|
2008-11-18 21:01:58 -05:00
|
|
|
String[] parts = COMMA_PATTERN.split(reference);
|
|
|
|
StringBuffer sb = new StringBuffer(32);
|
|
|
|
for (int i = 0; i < parts.length; i++) {
|
|
|
|
if(i>0) {
|
|
|
|
sb.append(",");
|
|
|
|
}
|
|
|
|
SheetNameFormatter.appendFormat(sb, getSheetName(sheetIndex));
|
|
|
|
sb.append("!");
|
|
|
|
sb.append(parts[i]);
|
|
|
|
}
|
2008-11-21 04:22:07 -05:00
|
|
|
name.setRefersToFormula(sb.toString());
|
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-25 09:39:43 -04:00
|
|
|
|
2008-10-17 14:43:37 -04:00
|
|
|
/**
|
|
|
|
* Sets the repeating rows and columns for a sheet.
|
2008-10-25 09:39:43 -04:00
|
|
|
* <p/>
|
2008-10-17 14:43:37 -04:00
|
|
|
* 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>
|
|
|
|
*
|
2008-10-25 09:39:43 -04:00
|
|
|
* @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.
|
2008-10-17 14:43:37 -04:00
|
|
|
*/
|
|
|
|
public void setRepeatingRowsAndColumns(int sheetIndex,
|
|
|
|
int startColumn, int endColumn,
|
|
|
|
int startRow, int endRow) {
|
2009-04-16 16:34:13 -04:00
|
|
|
// Check arguments
|
2008-10-25 09:39:43 -04:00
|
|
|
if ((startColumn == -1 && endColumn != -1) || startColumn < -1 || endColumn < -1 || startColumn > endColumn)
|
|
|
|
throw new IllegalArgumentException("Invalid column range specification");
|
|
|
|
if ((startRow == -1 && endRow != -1) || startRow < -1 || endRow < -1 || startRow > endRow)
|
|
|
|
throw new IllegalArgumentException("Invalid row range specification");
|
|
|
|
|
|
|
|
XSSFSheet sheet = getSheetAt(sheetIndex);
|
|
|
|
boolean removingRange = startColumn == -1 && endColumn == -1 && startRow == -1 && endRow == -1;
|
|
|
|
|
|
|
|
XSSFName name = getBuiltInName(XSSFName.BUILTIN_PRINT_TITLE, sheetIndex);
|
2009-08-05 13:54:56 -04:00
|
|
|
if (removingRange) {
|
|
|
|
if(name != null)namedRanges.remove(name);
|
2008-10-25 09:39:43 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (name == null) {
|
|
|
|
name = createBuiltInName(XSSFName.BUILTIN_PRINT_TITLE, sheetIndex);
|
|
|
|
}
|
|
|
|
|
2009-08-05 13:54:56 -04:00
|
|
|
String reference = getReferenceBuiltInRecord(name.getSheetName(), startColumn, endColumn, startRow, endRow);
|
|
|
|
name.setRefersToFormula(reference);
|
|
|
|
|
2011-03-18 12:06:10 -04:00
|
|
|
// If the print setup isn't currently defined, then add it
|
|
|
|
// in but without printer defaults
|
|
|
|
// If it's already there, leave it as-is!
|
|
|
|
CTWorksheet ctSheet = sheet.getCTWorksheet();
|
|
|
|
if(ctSheet.isSetPageSetup() && ctSheet.isSetPageMargins()) {
|
|
|
|
// Everything we need is already there
|
|
|
|
} else {
|
|
|
|
// Have initial ones put in place
|
|
|
|
XSSFPrintSetup printSetup = sheet.getPrintSetup();
|
|
|
|
printSetup.setValidSettings(false);
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
|
|
|
|
2008-10-25 09:39:43 -04:00
|
|
|
private static String getReferenceBuiltInRecord(String sheetName, int startC, int endC, int startR, int endR) {
|
|
|
|
//windows excel example for built-in title: 'second sheet'!$E:$F,'second sheet'!$2:$3
|
|
|
|
CellReference colRef = new CellReference(sheetName, 0, startC, true, true);
|
|
|
|
CellReference colRef2 = new CellReference(sheetName, 0, endC, true, true);
|
|
|
|
|
2009-06-10 14:44:53 -04:00
|
|
|
String escapedName = SheetNameFormatter.format(sheetName);
|
|
|
|
|
2009-08-05 13:54:56 -04:00
|
|
|
String c;
|
|
|
|
if(startC == -1 && endC == -1) c= "";
|
|
|
|
else c = escapedName + "!$" + colRef.getCellRefParts()[2] + ":$" + colRef2.getCellRefParts()[2];
|
2008-10-25 09:39:43 -04:00
|
|
|
|
|
|
|
CellReference rowRef = new CellReference(sheetName, startR, 0, true, true);
|
|
|
|
CellReference rowRef2 = new CellReference(sheetName, endR, 0, true, true);
|
2008-10-01 13:15:02 -04:00
|
|
|
|
2008-10-25 09:39:43 -04:00
|
|
|
String r = "";
|
2009-08-05 13:54:56 -04:00
|
|
|
if(startR == -1 && endR == -1) r = "";
|
|
|
|
else {
|
|
|
|
if (!rowRef.getCellRefParts()[1].equals("0") && !rowRef2.getCellRefParts()[1].equals("0")) {
|
|
|
|
r = escapedName + "!$" + rowRef.getCellRefParts()[1] + ":$" + rowRef2.getCellRefParts()[1];
|
|
|
|
}
|
2008-10-25 09:39:43 -04:00
|
|
|
}
|
2009-08-17 22:41:45 -04:00
|
|
|
|
2009-08-05 13:54:56 -04:00
|
|
|
StringBuffer rng = new StringBuffer();
|
|
|
|
rng.append(c);
|
|
|
|
if(rng.length() > 0 && r.length() > 0) rng.append(',');
|
|
|
|
rng.append(r);
|
|
|
|
return rng.toString();
|
2008-10-25 09:39:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private static String getReferencePrintArea(String sheetName, int startC, int endC, int startR, int endR) {
|
2008-10-17 14:43:37 -04:00
|
|
|
//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);
|
|
|
|
|
2008-11-18 21:01:58 -05:00
|
|
|
return "$" + colRef.getCellRefParts()[2] + "$" + colRef.getCellRefParts()[1] + ":$" + colRef2.getCellRefParts()[2] + "$" + colRef2.getCellRefParts()[1];
|
2008-10-17 14:43:37 -04:00
|
|
|
}
|
|
|
|
|
2010-12-02 10:23:35 -05:00
|
|
|
XSSFName getBuiltInName(String builtInCode, int sheetNumber) {
|
2008-10-17 14:43:37 -04:00
|
|
|
for (XSSFName name : namedRanges) {
|
2008-12-04 13:38:00 -05:00
|
|
|
if (name.getNameName().equalsIgnoreCase(builtInCode) && name.getSheetIndex() == sheetNumber) {
|
2008-10-17 14:43:37 -04:00
|
|
|
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
|
2008-10-25 09:39:43 -04:00
|
|
|
*
|
2008-10-17 14:43:37 -04:00
|
|
|
* @return a new NameRecord
|
2008-10-29 15:12:47 -04:00
|
|
|
* @throws IllegalArgumentException if sheetNumber is invalid
|
|
|
|
* @throws POIXMLException if such a name already exists in the workbook
|
2008-10-17 14:43:37 -04:00
|
|
|
*/
|
2010-12-02 10:23:35 -05:00
|
|
|
XSSFName createBuiltInName(String builtInName, int sheetNumber) {
|
2008-10-29 15:12:47 -04:00
|
|
|
validateSheetIndex(sheetNumber);
|
2008-10-25 09:39:43 -04:00
|
|
|
|
2008-10-27 16:28:44 -04:00
|
|
|
CTDefinedNames names = workbook.getDefinedNames() == null ? workbook.addNewDefinedNames() : workbook.getDefinedNames();
|
|
|
|
CTDefinedName nameRecord = names.addNewDefinedName();
|
2008-10-17 14:43:37 -04:00
|
|
|
nameRecord.setName(builtInName);
|
|
|
|
nameRecord.setLocalSheetId(sheetNumber);
|
2008-10-25 09:39:43 -04:00
|
|
|
|
|
|
|
XSSFName name = new XSSFName(nameRecord, this);
|
|
|
|
for (XSSFName nr : namedRanges) {
|
|
|
|
if (nr.equals(name))
|
2008-10-29 15:12:47 -04:00
|
|
|
throw new POIXMLException("Builtin (" + builtInName
|
2008-10-25 09:39:43 -04:00
|
|
|
+ ") already exists for sheet (" + sheetNumber + ")");
|
|
|
|
}
|
2008-10-17 14:43:37 -04:00
|
|
|
|
2010-12-02 10:23:35 -05:00
|
|
|
namedRanges.add(name);
|
2008-10-17 14:43:37 -04:00
|
|
|
return name;
|
|
|
|
}
|
2008-10-25 09:39:43 -04:00
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
/**
|
|
|
|
* We only set one sheet as selected for compatibility with HSSF.
|
|
|
|
*/
|
2009-03-27 07:50:52 -04:00
|
|
|
public void setSelectedTab(int index) {
|
2008-10-29 15:12:47 -04:00
|
|
|
for (int i = 0 ; i < sheets.size() ; ++i) {
|
|
|
|
XSSFSheet sheet = sheets.get(i);
|
2008-10-01 13:15:02 -04:00
|
|
|
sheet.setSelected(i == index);
|
|
|
|
}
|
|
|
|
}
|
2008-09-29 01:40:48 -04:00
|
|
|
|
2008-09-30 09:57:36 -04:00
|
|
|
/**
|
|
|
|
* Set the sheet name.
|
2008-10-01 13:15:02 -04:00
|
|
|
*
|
2011-06-23 06:49:11 -04:00
|
|
|
* @param sheetIndex sheet number (0 based)
|
|
|
|
* @param sheetname the new sheet name
|
|
|
|
* @throws IllegalArgumentException if the name is null or invalid
|
|
|
|
* or workbook already contains a sheet with this name
|
|
|
|
* @see {@link #createSheet(String)}
|
|
|
|
* @see {@link org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)}
|
|
|
|
* for a safe way to create valid names
|
2008-10-01 13:15:02 -04:00
|
|
|
*/
|
2011-06-23 06:49:11 -04:00
|
|
|
public void setSheetName(int sheetIndex, String sheetname) {
|
2011-03-04 06:15:01 -05:00
|
|
|
validateSheetIndex(sheetIndex);
|
2011-06-23 06:49:11 -04:00
|
|
|
|
|
|
|
// YK: Mimic Excel and silently truncate sheet names longer than 31 characters
|
|
|
|
if(sheetname != null && sheetname.length() > 31) sheetname = sheetname.substring(0, 31);
|
|
|
|
WorkbookUtil.validateSheetName(sheetname);
|
|
|
|
|
|
|
|
if (containsSheet(sheetname, sheetIndex ))
|
2008-10-01 13:15:02 -04:00
|
|
|
throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
|
2011-03-04 06:15:01 -05:00
|
|
|
|
|
|
|
XSSFFormulaUtils utils = new XSSFFormulaUtils(this);
|
2011-06-23 06:49:11 -04:00
|
|
|
utils.updateSheetName(sheetIndex, sheetname);
|
2011-03-04 06:15:01 -05:00
|
|
|
|
2011-06-23 06:49:11 -04:00
|
|
|
workbook.getSheets().getSheetArray(sheetIndex).setName(sheetname);
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
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
|
2009-03-27 07:50:52 -04:00
|
|
|
CTSheets ct = workbook.getSheets();
|
|
|
|
XmlObject cts = ct.getSheetArray(idx).copy();
|
2008-10-29 15:12:47 -04:00
|
|
|
workbook.getSheets().removeSheet(idx);
|
2009-03-27 07:50:52 -04:00
|
|
|
CTSheet newcts = ct.insertNewSheet(pos);
|
2008-10-01 13:15:02 -04:00
|
|
|
newcts.set(cts);
|
2009-03-27 07:50:52 -04:00
|
|
|
|
|
|
|
//notify sheets
|
|
|
|
for(int i=0; i < sheets.size(); i++) {
|
|
|
|
sheets.get(i).sheet = ct.getSheetArray(i);
|
|
|
|
}
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
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();
|
|
|
|
}
|
|
|
|
}
|
2009-02-15 15:47:36 -05:00
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
2009-02-15 15:47:36 -05:00
|
|
|
private void saveCalculationChain(){
|
|
|
|
if(calcChain != null){
|
2010-10-14 04:40:06 -04:00
|
|
|
int count = calcChain.getCTCalcChain().sizeOfCArray();
|
2009-02-15 15:47:36 -05:00
|
|
|
if(count == 0){
|
|
|
|
removeRelation(calcChain);
|
|
|
|
calcChain = null;
|
|
|
|
}
|
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void commit() throws IOException {
|
|
|
|
saveNamedRanges();
|
2009-02-15 15:47:36 -05:00
|
|
|
saveCalculationChain();
|
2008-09-30 09:57:36 -04:00
|
|
|
|
|
|
|
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
|
|
|
|
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorkbook.type.getName().getNamespaceURI(), "workbook"));
|
2009-02-13 16:46:44 -05:00
|
|
|
Map<String, String> map = new HashMap<String, String>();
|
2008-10-10 10:54:32 -04:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns SharedStringsTable - tha cache of string for this workbook
|
|
|
|
*
|
|
|
|
* @return the shared string table
|
|
|
|
*/
|
2009-12-03 11:50:34 -05:00
|
|
|
@Internal
|
2008-09-30 09:57:36 -04:00
|
|
|
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
|
|
|
|
2010-05-19 07:55:17 -04:00
|
|
|
/**
|
|
|
|
* Returns the Theme of current workbook.
|
|
|
|
*/
|
|
|
|
public ThemesTable getTheme() {
|
|
|
|
return theme;
|
|
|
|
}
|
|
|
|
|
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() {
|
2009-11-30 09:09:03 -05:00
|
|
|
if(_creationHelper == null) _creationHelper = new XSSFCreationHelper(this);
|
|
|
|
return _creationHelper;
|
2008-10-01 13:15:02 -04:00
|
|
|
}
|
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.
|
2010-09-07 03:09:49 -04:00
|
|
|
* For the purpose of comparison, long names are truncated to 31 chars.
|
2008-09-30 09:57:36 -04:00
|
|
|
*
|
|
|
|
* @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.
|
|
|
|
*/
|
2010-10-14 04:40:06 -04:00
|
|
|
@SuppressWarnings("deprecation") // getXYZArray() array accessors are deprecated
|
2008-10-01 13:15:02 -04:00
|
|
|
private boolean containsSheet(String name, int excludeSheetIdx) {
|
2010-10-14 04:40:06 -04:00
|
|
|
CTSheet[] ctSheetArray = workbook.getSheets().getSheetArray();
|
|
|
|
|
2010-09-07 03:09:49 -04:00
|
|
|
if (name.length() > MAX_SENSITIVE_SHEET_NAME_LEN) {
|
|
|
|
name = name.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN);
|
|
|
|
}
|
|
|
|
|
2008-10-01 13:15:02 -04:00
|
|
|
for (int i = 0; i < ctSheetArray.length; i++) {
|
2010-09-07 03:09:49 -04:00
|
|
|
String ctName = ctSheetArray[i].getName();
|
|
|
|
if (ctName.length() > MAX_SENSITIVE_SHEET_NAME_LEN) {
|
|
|
|
ctName = ctName.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (excludeSheetIdx != i && name.equalsIgnoreCase(ctName))
|
2008-10-01 13:15:02 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2008-09-30 09:57:36 -04:00
|
|
|
|
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 {
|
2008-10-25 07:48:50 -04:00
|
|
|
List<PackagePart> embedds = new LinkedList<PackagePart>();
|
|
|
|
|
|
|
|
for(XSSFSheet sheet : sheets){
|
|
|
|
// Get the embeddings for the workbook
|
|
|
|
for(PackageRelationship rel : sheet.getPackagePart().getRelationshipsByType(XSSFRelation.OLEEMBEDDINGS.getRelation()))
|
|
|
|
embedds.add(getTargetPart(rel));
|
|
|
|
|
|
|
|
for(PackageRelationship rel : sheet.getPackagePart().getRelationshipsByType(XSSFRelation.PACKEMBEDDINGS.getRelation()))
|
|
|
|
embedds.add(getTargetPart(rel));
|
|
|
|
|
|
|
|
}
|
2008-10-19 11:31:28 -04:00
|
|
|
return embedds;
|
|
|
|
}
|
2009-08-17 22:41:45 -04:00
|
|
|
|
2009-02-13 16:46:44 -05:00
|
|
|
public boolean isHidden() {
|
2009-04-16 16:34:13 -04:00
|
|
|
throw new RuntimeException("Not implemented yet");
|
2009-02-13 16:46:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setHidden(boolean hiddenFlag) {
|
2009-04-16 16:34:13 -04:00
|
|
|
throw new RuntimeException("Not implemented yet");
|
2009-02-13 16:46:44 -05:00
|
|
|
}
|
2008-10-29 15:12:47 -04:00
|
|
|
|
2010-09-05 08:53:07 -04:00
|
|
|
/**
|
|
|
|
* Check whether a sheet is hidden.
|
|
|
|
* <p>
|
|
|
|
* Note that a sheet could instead be set to be very hidden, which is different
|
|
|
|
* ({@link #isSheetVeryHidden(int)})
|
|
|
|
* </p>
|
|
|
|
* @param sheetIx Number
|
|
|
|
* @return <code>true</code> if sheet is hidden
|
|
|
|
*/
|
2008-10-29 15:12:47 -04:00
|
|
|
public boolean isSheetHidden(int sheetIx) {
|
|
|
|
validateSheetIndex(sheetIx);
|
|
|
|
CTSheet ctSheet = sheets.get(sheetIx).sheet;
|
|
|
|
return ctSheet.getState() == STSheetState.HIDDEN;
|
|
|
|
}
|
|
|
|
|
2010-09-05 08:53:07 -04:00
|
|
|
/**
|
|
|
|
* Check whether a sheet is very hidden.
|
|
|
|
* <p>
|
|
|
|
* This is different from the normal hidden status
|
|
|
|
* ({@link #isSheetHidden(int)})
|
|
|
|
* </p>
|
|
|
|
* @param sheetIx sheet index to check
|
|
|
|
* @return <code>true</code> if sheet is very hidden
|
|
|
|
*/
|
2008-10-29 15:12:47 -04:00
|
|
|
public boolean isSheetVeryHidden(int sheetIx) {
|
|
|
|
validateSheetIndex(sheetIx);
|
|
|
|
CTSheet ctSheet = sheets.get(sheetIx).sheet;
|
|
|
|
return ctSheet.getState() == STSheetState.VERY_HIDDEN;
|
|
|
|
}
|
|
|
|
|
2010-09-05 08:53:07 -04:00
|
|
|
/**
|
|
|
|
* Sets the visible state of this sheet.
|
|
|
|
* <p>
|
|
|
|
* Calling <code>setSheetHidden(sheetIndex, true)</code> is equivalent to
|
|
|
|
* <code>setSheetHidden(sheetIndex, Workbook.SHEET_STATE_HIDDEN)</code>.
|
|
|
|
* <br/>
|
|
|
|
* Calling <code>setSheetHidden(sheetIndex, false)</code> is equivalent to
|
|
|
|
* <code>setSheetHidden(sheetIndex, Workbook.SHEET_STATE_VISIBLE)</code>.
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @param sheetIx the 0-based index of the sheet
|
|
|
|
* @param hidden whether this sheet is hidden
|
|
|
|
* @see #setSheetHidden(int, int)
|
|
|
|
*/
|
2008-10-29 15:12:47 -04:00
|
|
|
public void setSheetHidden(int sheetIx, boolean hidden) {
|
2010-09-05 08:53:07 -04:00
|
|
|
setSheetHidden(sheetIx, hidden ? SHEET_STATE_HIDDEN : SHEET_STATE_VISIBLE);
|
2008-10-29 15:12:47 -04:00
|
|
|
}
|
|
|
|
|
2010-09-05 08:53:07 -04:00
|
|
|
/**
|
|
|
|
* Hide or unhide a sheet.
|
|
|
|
*
|
|
|
|
* <ul>
|
|
|
|
* <li>0 - visible. </li>
|
|
|
|
* <li>1 - hidden. </li>
|
|
|
|
* <li>2 - very hidden.</li>
|
|
|
|
* </ul>
|
|
|
|
* @param sheetIx the sheet index (0-based)
|
|
|
|
* @param state one of the following <code>Workbook</code> constants:
|
|
|
|
* <code>Workbook.SHEET_STATE_VISIBLE</code>,
|
|
|
|
* <code>Workbook.SHEET_STATE_HIDDEN</code>, or
|
|
|
|
* <code>Workbook.SHEET_STATE_VERY_HIDDEN</code>.
|
|
|
|
* @throws IllegalArgumentException if the supplied sheet index or state is invalid
|
|
|
|
*/
|
|
|
|
public void setSheetHidden(int sheetIx, int state) {
|
2008-10-29 15:12:47 -04:00
|
|
|
validateSheetIndex(sheetIx);
|
2010-09-05 08:53:07 -04:00
|
|
|
WorkbookUtil.validateSheetState(state);
|
2008-10-29 15:12:47 -04:00
|
|
|
CTSheet ctSheet = sheets.get(sheetIx).sheet;
|
2010-09-05 08:53:07 -04:00
|
|
|
ctSheet.setState(STSheetState.Enum.forInt(state + 1));
|
2008-10-29 15:12:47 -04:00
|
|
|
}
|
|
|
|
|
2009-02-08 07:45:55 -05:00
|
|
|
/**
|
|
|
|
* Fired when a formula is deleted from this workbook,
|
|
|
|
* for example when calling cell.setCellFormula(null)
|
|
|
|
*
|
2009-08-17 22:41:45 -04:00
|
|
|
* @see XSSFCell#setCellFormula(String)
|
2009-02-08 07:45:55 -05:00
|
|
|
*/
|
|
|
|
protected void onDeleteFormula(XSSFCell cell){
|
|
|
|
if(calcChain != null) {
|
|
|
|
int sheetId = (int)cell.getSheet().sheet.getSheetId();
|
|
|
|
calcChain.removeItem(sheetId, cell.getReference());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the CalculationChain object for this workbook
|
|
|
|
* <p>
|
|
|
|
* The calculation chain object specifies the order in which the cells in a workbook were last calculated
|
|
|
|
* </p>
|
2009-08-17 22:41:45 -04:00
|
|
|
*
|
2009-02-08 07:45:55 -05:00
|
|
|
* @return the <code>CalculationChain</code> object or <code>null</code> if not defined
|
|
|
|
*/
|
2009-12-03 11:50:34 -05:00
|
|
|
@Internal
|
2009-02-08 07:45:55 -05:00
|
|
|
public CalculationChain getCalculationChain(){
|
|
|
|
return calcChain;
|
|
|
|
}
|
|
|
|
|
2009-07-16 01:46:14 -04:00
|
|
|
/**
|
2009-08-17 22:41:45 -04:00
|
|
|
*
|
2009-07-16 01:46:14 -04:00
|
|
|
* @return a collection of custom XML mappings defined in this workbook
|
|
|
|
*/
|
|
|
|
public Collection<XSSFMap> getCustomXMLMappings(){
|
|
|
|
return mapInfo == null ? new ArrayList<XSSFMap>() : mapInfo.getAllXSSFMaps();
|
|
|
|
}
|
2009-08-17 22:41:45 -04:00
|
|
|
|
2009-07-30 09:24:57 -04:00
|
|
|
/**
|
2009-08-17 22:41:45 -04:00
|
|
|
*
|
2009-07-30 09:24:57 -04:00
|
|
|
* @return the helper class used to query the custom XML mapping defined in this workbook
|
|
|
|
*/
|
2009-12-03 11:50:34 -05:00
|
|
|
@Internal
|
2009-07-30 09:24:57 -04:00
|
|
|
public MapInfo getMapInfo(){
|
|
|
|
return mapInfo;
|
|
|
|
}
|
2009-10-28 12:05:39 -04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Specifies a boolean value that indicates whether structure of workbook is locked. <br/>
|
|
|
|
* A value true indicates the structure of the workbook is locked. Worksheets in the workbook can't be moved,
|
|
|
|
* deleted, hidden, unhidden, or renamed, and new worksheets can't be inserted.<br/>
|
|
|
|
* A value of false indicates the structure of the workbook is not locked.<br/>
|
|
|
|
*
|
|
|
|
* @return true if structure of workbook is locked
|
|
|
|
*/
|
|
|
|
public boolean isStructureLocked() {
|
|
|
|
return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockStructure();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Specifies a boolean value that indicates whether the windows that comprise the workbook are locked. <br/>
|
|
|
|
* A value of true indicates the workbook windows are locked. Windows are the same size and position each time the
|
|
|
|
* workbook is opened.<br/>
|
|
|
|
* A value of false indicates the workbook windows are not locked.
|
|
|
|
*
|
|
|
|
* @return true if windows that comprise the workbook are locked
|
|
|
|
*/
|
|
|
|
public boolean isWindowsLocked() {
|
|
|
|
return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockWindows();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Specifies a boolean value that indicates whether the workbook is locked for revisions.
|
|
|
|
*
|
|
|
|
* @return true if the workbook is locked for revisions.
|
|
|
|
*/
|
|
|
|
public boolean isRevisionLocked() {
|
|
|
|
return workbookProtectionPresent() && workbook.getWorkbookProtection().getLockRevision();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Locks the structure of workbook.
|
|
|
|
*/
|
|
|
|
public void lockStructure() {
|
|
|
|
createProtectionFieldIfNotPresent();
|
|
|
|
workbook.getWorkbookProtection().setLockStructure(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unlocks the structure of workbook.
|
|
|
|
*/
|
|
|
|
public void unLockStructure() {
|
|
|
|
createProtectionFieldIfNotPresent();
|
|
|
|
workbook.getWorkbookProtection().setLockStructure(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Locks the windows that comprise the workbook.
|
|
|
|
*/
|
|
|
|
public void lockWindows() {
|
|
|
|
createProtectionFieldIfNotPresent();
|
|
|
|
workbook.getWorkbookProtection().setLockWindows(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unlocks the windows that comprise the workbook.
|
|
|
|
*/
|
|
|
|
public void unLockWindows() {
|
|
|
|
createProtectionFieldIfNotPresent();
|
|
|
|
workbook.getWorkbookProtection().setLockWindows(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Locks the workbook for revisions.
|
|
|
|
*/
|
|
|
|
public void lockRevision() {
|
|
|
|
createProtectionFieldIfNotPresent();
|
|
|
|
workbook.getWorkbookProtection().setLockRevision(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unlocks the workbook for revisions.
|
|
|
|
*/
|
|
|
|
public void unLockRevision() {
|
|
|
|
createProtectionFieldIfNotPresent();
|
|
|
|
workbook.getWorkbookProtection().setLockRevision(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean workbookProtectionPresent() {
|
|
|
|
return workbook.getWorkbookProtection() != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void createProtectionFieldIfNotPresent() {
|
|
|
|
if (workbook.getWorkbookProtection() == null){
|
|
|
|
workbook.setWorkbookProtection(CTWorkbookProtection.Factory.newInstance());
|
|
|
|
}
|
|
|
|
}
|
2010-11-28 07:03:52 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Returns the locator of user-defined functions.
|
|
|
|
* <p>
|
|
|
|
* The default instance extends the built-in functions with the Excel Analysis Tool Pack.
|
|
|
|
* To set / evaluate custom functions you need to register them as follows:
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* </p>
|
|
|
|
* @return wrapped instance of UDFFinder that allows seeking functions both by index and name
|
|
|
|
*/
|
|
|
|
/*package*/ UDFFinder getUDFFinder() {
|
|
|
|
return _udfFinder;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register a new toolpack in this workbook.
|
|
|
|
*
|
|
|
|
* @param toopack the toolpack to register
|
|
|
|
*/
|
|
|
|
public void addToolPack(UDFFinder toopack){
|
|
|
|
_udfFinder.add(toopack);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-16 11:08:22 -05:00
|
|
|
}
|