2011-05-17 06:46:35 -04: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.streaming ;
2014-06-11 10:38:32 -04:00
import java.io.File ;
import java.io.FileOutputStream ;
2011-05-17 06:46:35 -04:00
import java.io.IOException ;
import java.io.InputStream ;
import java.io.InputStreamReader ;
import java.io.OutputStream ;
import java.io.OutputStreamWriter ;
2014-06-11 10:38:32 -04:00
import java.util.Enumeration ;
import java.util.HashMap ;
2015-09-17 07:10:11 -04:00
import java.util.Iterator ;
2014-06-11 10:38:32 -04:00
import java.util.List ;
2016-01-16 17:58:25 -05:00
import java.util.Map ;
2015-09-17 07:10:11 -04:00
import java.util.NoSuchElementException ;
2014-06-11 10:38:32 -04:00
import java.util.zip.ZipEntry ;
2011-05-17 06:46:35 -04:00
import java.util.zip.ZipFile ;
import java.util.zip.ZipOutputStream ;
2014-06-11 10:38:32 -04:00
import org.apache.poi.openxml4j.opc.OPCPackage ;
2016-10-09 00:43:14 -04:00
import org.apache.poi.openxml4j.util.ZipEntrySource ;
import org.apache.poi.openxml4j.util.ZipFileZipEntrySource ;
2016-01-16 17:01:33 -05:00
import org.apache.poi.ss.SpreadsheetVersion ;
2011-05-17 06:46:35 -04:00
import org.apache.poi.ss.formula.udf.UDFFinder ;
2014-06-11 10:38:32 -04:00
import org.apache.poi.ss.usermodel.CellStyle ;
import org.apache.poi.ss.usermodel.CreationHelper ;
import org.apache.poi.ss.usermodel.DataFormat ;
import org.apache.poi.ss.usermodel.Font ;
import org.apache.poi.ss.usermodel.Name ;
import org.apache.poi.ss.usermodel.PictureData ;
2011-05-17 06:46:35 -04:00
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy ;
2014-06-11 10:38:32 -04:00
import org.apache.poi.ss.usermodel.Sheet ;
2017-01-19 23:23:42 -05:00
import org.apache.poi.ss.usermodel.SheetVisibility ;
2014-06-11 10:38:32 -04:00
import org.apache.poi.ss.usermodel.Workbook ;
2017-01-07 19:38:41 -05:00
import org.apache.poi.util.IOUtils ;
2016-10-09 00:43:14 -04:00
import org.apache.poi.util.Internal ;
2016-04-10 05:40:40 -04:00
import org.apache.poi.util.NotImplemented ;
2015-07-31 15:19:33 -04:00
import org.apache.poi.util.POILogFactory ;
import org.apache.poi.util.POILogger ;
2017-01-07 19:38:41 -05:00
import org.apache.poi.util.Removal ;
2014-07-24 14:58:27 -04:00
import org.apache.poi.util.TempFile ;
2014-02-14 17:45:05 -05:00
import org.apache.poi.xssf.model.SharedStringsTable ;
2014-06-11 10:38:32 -04:00
import org.apache.poi.xssf.usermodel.XSSFSheet ;
import org.apache.poi.xssf.usermodel.XSSFWorkbook ;
2011-05-17 06:46:35 -04:00
/ * *
* Streaming version of XSSFWorkbook implementing the " BigGridDemo " strategy .
*
2016-03-29 13:27:20 -04:00
* This allows to write very large files without running out of memory as only
* a configurable portion of the rows are kept in memory at any one time .
*
* You can provide a template workbook which is used as basis for the written
* data .
*
* See https : //poi.apache.org/spreadsheet/how-to.html#sxssf for details.
*
* Please note that there are still things that still may consume a large
* amount of memory based on which features you are using , e . g . merged regions ,
* comments , . . . are still only stored in memory and thus may require a lot of
* memory if used extensively .
*
2014-02-14 17:45:05 -05:00
* SXSSFWorkbook defaults to using inline strings instead of a shared strings
* table . This is very efficient , since no document content needs to be kept in
* memory , but is also known to produce documents that are incompatible with
* some clients . With shared strings enabled all unique strings in the document
* has to be kept in memory . Depending on your document content this could use
* a lot more resources than with shared strings disabled .
*
* Carefully review your memory budget and compatibility needs before deciding
* whether to enable shared strings or not .
* /
2015-07-31 15:19:33 -04:00
public class SXSSFWorkbook implements Workbook {
2011-06-08 08:38:07 -04:00
/ * *
2016-07-15 02:35:21 -04:00
* Specifies how many rows can be accessed at most via { @link SXSSFSheet # getRow } .
* When a new node is created via { @link SXSSFSheet # createRow } and the total number
2016-01-16 17:58:25 -05:00
* of unflushed records would exceed the specified value , then the
2011-06-08 08:38:07 -04:00
* row with the lowest index value is flushed and cannot be accessed
2016-07-15 02:35:21 -04:00
* via { @link SXSSFSheet # getRow } anymore .
2011-06-08 08:38:07 -04:00
* /
public static final int DEFAULT_WINDOW_SIZE = 100 ;
2016-01-16 17:58:25 -05:00
private static final POILogger logger = POILogFactory . getLogger ( SXSSFWorkbook . class ) ;
2011-06-08 08:38:07 -04:00
2016-01-16 17:58:25 -05:00
private final XSSFWorkbook _wb ;
2011-05-17 06:46:35 -04:00
2016-01-16 17:58:25 -05:00
private final Map < SXSSFSheet , XSSFSheet > _sxFromXHash = new HashMap < SXSSFSheet , XSSFSheet > ( ) ;
private final Map < XSSFSheet , SXSSFSheet > _xFromSxHash = new HashMap < XSSFSheet , SXSSFSheet > ( ) ;
2011-05-17 06:46:35 -04:00
2011-08-11 04:54:11 -04:00
private int _randomAccessWindowSize = DEFAULT_WINDOW_SIZE ;
2011-06-08 08:38:07 -04:00
2011-12-09 06:04:22 -05:00
/ * *
2016-01-16 17:58:25 -05:00
* whether temp files should be compressed .
2011-12-09 06:04:22 -05:00
* /
private boolean _compressTmpFiles = false ;
2014-02-14 17:45:05 -05:00
/ * *
* shared string table - a cache of strings in this workbook
* /
2016-01-16 17:58:25 -05:00
private final SharedStringsTable _sharedStringSource ;
2014-02-14 17:45:05 -05:00
2011-06-08 08:38:07 -04:00
/ * *
2016-03-29 13:27:20 -04:00
* Construct a new workbook with default row window size
2011-06-08 08:38:07 -04:00
* /
public SXSSFWorkbook ( ) {
2011-08-11 04:54:11 -04:00
this ( null /*workbook*/ ) ;
}
2012-02-07 03:17:21 -05:00
/ * *
2016-07-15 02:35:21 -04:00
* < p > Construct a workbook from a template . < / p >
*
2012-02-07 03:17:21 -05:00
* There are three use - cases to use SXSSFWorkbook ( XSSFWorkbook ) :
* < ol >
* < li >
* Append new sheets to existing workbooks . You can open existing
* workbook from a file or create on the fly with XSSF .
* < / li >
* < li >
* Append rows to existing sheets . The row number MUST be greater
2016-07-15 02:35:21 -04:00
* than { @code max ( rownum ) } in the template sheet .
2012-02-07 03:17:21 -05:00
* < / li >
* < li >
* Use existing workbook as a template and re - use global objects such
* as cell styles , formats , images , etc .
* < / li >
* < / ol >
* All three use cases can work in a combination .
2016-07-15 02:35:21 -04:00
*
2012-02-07 03:17:21 -05:00
* What is not supported :
* < ul >
* < li >
* Access initial cells and rows in the template . After constructing
2016-07-15 02:35:21 -04:00
* { @link # SXSSFWorkbook ( XSSFWorkbook ) } all internal windows are empty and
* { @link SXSSFSheet # getRow } and { @link SXSSFRow # getCell } return < code > null < / code > .
2012-02-07 03:17:21 -05:00
* < / li >
* < li >
* Override existing cells and rows . The API silently allows that but
* the output file is invalid and Excel cannot read it .
* < / li >
* < / ul >
*
* @param workbook the template workbook
* /
2011-08-11 04:54:11 -04:00
public SXSSFWorkbook ( XSSFWorkbook workbook ) {
this ( workbook , DEFAULT_WINDOW_SIZE ) ;
}
2011-06-08 08:38:07 -04:00
2011-08-11 04:54:11 -04:00
/ * *
* Constructs an workbook from an existing workbook .
* < p >
2016-07-15 02:35:21 -04:00
* When a new node is created via { @link SXSSFSheet # createRow } and the total number
2011-08-11 04:54:11 -04:00
* of unflushed records would exceed the specified value , then the
* row with the lowest index value is flushed and cannot be accessed
2016-07-15 02:35:21 -04:00
* via { @link SXSSFSheet # getRow } anymore .
2011-08-11 04:54:11 -04:00
* < / p >
* < p >
2016-07-15 02:35:21 -04:00
* A value of < code > - 1 < / code > indicates unlimited access . In this case all
* records that have not been flushed by a call to < code > flush ( ) < / code > are available
2011-08-11 04:54:11 -04:00
* for random access .
2016-07-15 02:35:21 -04:00
* < / p >
2011-08-11 04:54:11 -04:00
* < p >
2016-07-15 02:35:21 -04:00
* A value of < code > 0 < / code > is not allowed because it would flush any newly created row
2011-08-11 04:54:11 -04:00
* without having a chance to specify any cells .
* < / p >
*
2016-03-29 13:27:20 -04:00
* @param rowAccessWindowSize the number of rows that are kept in memory until flushed out , see above .
2011-08-11 04:54:11 -04:00
* /
public SXSSFWorkbook ( XSSFWorkbook workbook , int rowAccessWindowSize ) {
2011-12-16 05:11:45 -05:00
this ( workbook , rowAccessWindowSize , false ) ;
}
/ * *
* Constructs an workbook from an existing workbook .
* < p >
2016-07-15 02:35:21 -04:00
* When a new node is created via { @link SXSSFSheet # createRow } and the total number
2011-12-16 05:11:45 -05:00
* of unflushed records would exceed the specified value , then the
* row with the lowest index value is flushed and cannot be accessed
2016-07-15 02:35:21 -04:00
* via { @link SXSSFSheet # getRow } anymore .
2011-12-16 05:11:45 -05:00
* < / p >
* < p >
2016-07-15 02:35:21 -04:00
* A value of < code > - 1 < / code > indicates unlimited access . In this case all
* records that have not been flushed by a call to < code > flush ( ) < / code > are available
2011-12-16 05:11:45 -05:00
* for random access .
2016-07-15 02:35:21 -04:00
* < / p >
2011-12-16 05:11:45 -05:00
* < p >
2016-07-15 02:35:21 -04:00
* A value of < code > 0 < / code > is not allowed because it would flush any newly created row
2011-12-16 05:11:45 -05:00
* without having a chance to specify any cells .
* < / p >
*
2016-03-29 13:27:20 -04:00
* @param rowAccessWindowSize the number of rows that are kept in memory until flushed out , see above .
2011-12-16 05:11:45 -05:00
* @param compressTmpFiles whether to use gzip compression for temporary files
* /
public SXSSFWorkbook ( XSSFWorkbook workbook , int rowAccessWindowSize , boolean compressTmpFiles ) {
2014-02-14 17:45:05 -05:00
this ( workbook , rowAccessWindowSize , compressTmpFiles , false ) ;
}
/ * *
* Constructs an workbook from an existing workbook .
* < p >
2016-07-15 02:35:21 -04:00
* When a new node is created via { @link SXSSFSheet # createRow } and the total number
2014-02-14 17:45:05 -05:00
* of unflushed records would exceed the specified value , then the
* row with the lowest index value is flushed and cannot be accessed
2016-07-15 02:35:21 -04:00
* via { @link SXSSFSheet # getRow } anymore .
2014-02-14 17:45:05 -05:00
* < / p >
* < p >
2016-07-15 02:35:21 -04:00
* A value of < code > - 1 < / code > indicates unlimited access . In this case all
* records that have not been flushed by a call to < code > flush ( ) < / code > are available
2014-02-14 17:45:05 -05:00
* for random access .
2016-07-15 02:35:21 -04:00
* < / p >
2014-02-14 17:45:05 -05:00
* < p >
2016-07-15 02:35:21 -04:00
* A value of < code > 0 < / code > is not allowed because it would flush any newly created row
2014-02-14 17:45:05 -05:00
* without having a chance to specify any cells .
* < / p >
*
* @param workbook the template workbook
2016-03-29 13:27:20 -04:00
* @param rowAccessWindowSize the number of rows that are kept in memory until flushed out , see above .
2014-02-14 17:45:05 -05:00
* @param compressTmpFiles whether to use gzip compression for temporary files
* @param useSharedStringsTable whether to use a shared strings table
* /
public SXSSFWorkbook ( XSSFWorkbook workbook , int rowAccessWindowSize , boolean compressTmpFiles , boolean useSharedStringsTable ) {
2014-06-11 11:38:26 -04:00
setRandomAccessWindowSize ( rowAccessWindowSize ) ;
setCompressTempFiles ( compressTmpFiles ) ;
2017-01-07 19:38:41 -05:00
if ( workbook = = null ) {
2014-06-11 11:38:26 -04:00
_wb = new XSSFWorkbook ( ) ;
2016-01-16 17:58:25 -05:00
_sharedStringSource = useSharedStringsTable ? _wb . getSharedStringSource ( ) : null ;
2017-01-07 19:38:41 -05:00
} else {
2014-06-11 11:38:26 -04:00
_wb = workbook ;
2016-01-16 17:58:25 -05:00
_sharedStringSource = useSharedStringsTable ? _wb . getSharedStringSource ( ) : null ;
2017-01-07 19:38:41 -05:00
for ( Sheet sheet : _wb ) {
createAndRegisterSXSSFSheet ( ( XSSFSheet ) sheet ) ;
2011-08-11 04:54:11 -04:00
}
2014-06-11 11:38:26 -04:00
}
2011-06-08 08:38:07 -04:00
}
/ * *
* Construct an empty workbook and specify the window for row access .
* < p >
2016-07-15 02:35:21 -04:00
* When a new node is created via { @link SXSSFSheet # createRow } and the total number
2011-08-11 04:54:11 -04:00
* of unflushed records would exceed the specified value , then the
2011-06-08 08:38:07 -04:00
* row with the lowest index value is flushed and cannot be accessed
2016-07-15 02:35:21 -04:00
* via { @link SXSSFSheet # getRow } anymore .
2011-06-08 08:38:07 -04:00
* < / p >
* < p >
2016-07-15 02:35:21 -04:00
* A value of < code > - 1 < / code > indicates unlimited access . In this case all
* records that have not been flushed by a call to < code > flush ( ) < / code > are available
2011-06-08 08:38:07 -04:00
* for random access .
2016-07-15 02:35:21 -04:00
* < / p >
2011-06-08 08:38:07 -04:00
* < p >
2016-07-15 02:35:21 -04:00
* A value of < code > 0 < / code > is not allowed because it would flush any newly created row
2011-06-08 08:38:07 -04:00
* without having a chance to specify any cells .
* < / p >
*
2016-03-29 13:27:20 -04:00
* @param rowAccessWindowSize the number of rows that are kept in memory until flushed out , see above .
2011-06-08 08:38:07 -04:00
* /
public SXSSFWorkbook ( int rowAccessWindowSize ) {
2011-08-11 04:54:11 -04:00
this ( null /*workbook*/ , rowAccessWindowSize ) ;
}
2016-03-29 13:27:20 -04:00
/ * *
* See the constructors for a more detailed description of the sliding window of rows .
*
* @return The number of rows that are kept in memory at once before flushing them out .
* /
public int getRandomAccessWindowSize ( ) {
2011-08-11 04:54:11 -04:00
return _randomAccessWindowSize ;
}
2016-03-29 13:27:20 -04:00
private void setRandomAccessWindowSize ( int rowAccessWindowSize ) {
2011-06-08 08:38:07 -04:00
if ( rowAccessWindowSize = = 0 | | rowAccessWindowSize < - 1 ) {
throw new IllegalArgumentException ( " rowAccessWindowSize must be greater than 0 or -1 " ) ;
}
_randomAccessWindowSize = rowAccessWindowSize ;
}
2016-10-09 00:43:14 -04:00
/ * *
* Get whether temp files should be compressed .
*
* @return whether to compress temp files
* /
public boolean isCompressTempFiles ( ) {
return _compressTmpFiles ;
}
2011-12-09 06:04:22 -05:00
/ * *
* Set whether temp files should be compressed .
* < p >
* SXSSF writes sheet data in temporary files ( a temp file per - sheet )
* and the size of these temp files can grow to to a very large size ,
* e . g . for a 20 MB csv data the size of the temp xml file become few GB large .
* If the " compress " flag is set to < code > true < / code > then the temporary XML is gzipped .
* < / p >
* < p >
* Please note the the " compress " option may cause performance penalty .
* < / p >
* @param compress whether to compress temp files
* /
2016-10-09 00:43:14 -04:00
public void setCompressTempFiles ( boolean compress ) {
2011-12-09 06:04:22 -05:00
_compressTmpFiles = compress ;
}
2016-10-09 00:43:14 -04:00
@Internal
protected SharedStringsTable getSharedStringSource ( ) {
return _sharedStringSource ;
}
2011-12-09 06:04:22 -05:00
2016-10-09 00:43:14 -04:00
protected SheetDataWriter createSheetDataWriter ( ) throws IOException {
2011-12-09 06:04:22 -05:00
if ( _compressTmpFiles ) {
2014-02-14 17:45:05 -05:00
return new GZIPSheetDataWriter ( _sharedStringSource ) ;
2011-12-09 06:04:22 -05:00
}
2014-10-06 09:20:12 -04:00
return new SheetDataWriter ( _sharedStringSource ) ;
2011-12-09 06:04:22 -05:00
}
2011-05-17 06:46:35 -04:00
XSSFSheet getXSSFSheet ( SXSSFSheet sheet )
{
2016-03-29 13:27:20 -04:00
return _sxFromXHash . get ( sheet ) ;
2011-05-17 06:46:35 -04:00
}
SXSSFSheet getSXSSFSheet ( XSSFSheet sheet )
{
2016-03-29 13:27:20 -04:00
return _xFromSxHash . get ( sheet ) ;
2011-05-17 06:46:35 -04:00
}
void registerSheetMapping ( SXSSFSheet sxSheet , XSSFSheet xSheet )
{
_sxFromXHash . put ( sxSheet , xSheet ) ;
_xFromSxHash . put ( xSheet , sxSheet ) ;
}
2016-03-29 13:27:20 -04:00
2011-05-17 06:46:35 -04:00
void deregisterSheetMapping ( XSSFSheet xSheet )
{
SXSSFSheet sxSheet = getSXSSFSheet ( xSheet ) ;
2014-12-28 04:16:57 -05:00
// ensure that the writer is closed in all cases to not have lingering writers
try {
sxSheet . getSheetDataWriter ( ) . close ( ) ;
} catch ( IOException e ) {
// ignore exception here
}
2011-05-17 06:46:35 -04:00
_sxFromXHash . remove ( sxSheet ) ;
2014-12-28 04:16:57 -05:00
2011-05-17 06:46:35 -04:00
_xFromSxHash . remove ( xSheet ) ;
}
2016-03-29 13:27:20 -04:00
2011-05-17 06:46:35 -04:00
private XSSFSheet getSheetFromZipEntryName ( String sheetRef )
{
2011-05-18 06:37:31 -04:00
for ( XSSFSheet sheet : _sxFromXHash . values ( ) )
2011-05-17 06:46:35 -04:00
{
2017-01-07 19:38:41 -05:00
if ( sheetRef . equals ( sheet . getPackagePart ( ) . getPartName ( ) . getName ( ) . substring ( 1 ) ) ) {
return sheet ;
}
2011-05-17 06:46:35 -04:00
}
return null ;
}
2016-03-29 13:27:20 -04:00
2017-01-07 19:38:41 -05:00
protected void injectData ( ZipEntrySource zipEntrySource , OutputStream out ) throws IOException {
try {
2011-11-07 05:25:35 -05:00
ZipOutputStream zos = new ZipOutputStream ( out ) ;
2017-01-07 19:38:41 -05:00
try {
2016-10-09 00:43:14 -04:00
Enumeration < ? extends ZipEntry > en = zipEntrySource . getEntries ( ) ;
2017-01-07 19:38:41 -05:00
while ( en . hasMoreElements ( ) ) {
2011-11-07 05:25:35 -05:00
ZipEntry ze = en . nextElement ( ) ;
zos . putNextEntry ( new ZipEntry ( ze . getName ( ) ) ) ;
2016-10-09 00:43:14 -04:00
InputStream is = zipEntrySource . getInputStream ( ze ) ;
2011-11-07 05:25:35 -05:00
XSSFSheet xSheet = getSheetFromZipEntryName ( ze . getName ( ) ) ;
2017-01-07 19:38:41 -05:00
if ( xSheet ! = null ) {
2011-11-07 05:25:35 -05:00
SXSSFSheet sxSheet = getSXSSFSheet ( xSheet ) ;
InputStream xis = sxSheet . getWorksheetXMLInputStream ( ) ;
2017-01-07 19:38:41 -05:00
try {
2011-11-07 05:25:35 -05:00
copyStreamAndInjectWorksheet ( is , zos , xis ) ;
2017-01-07 19:38:41 -05:00
} finally {
2011-11-07 05:25:35 -05:00
xis . close ( ) ;
}
2017-01-07 19:38:41 -05:00
} else {
IOUtils . copy ( is , zos ) ;
2011-11-07 05:25:35 -05:00
}
is . close ( ) ;
}
2017-01-07 19:38:41 -05:00
} finally {
2011-11-07 05:25:35 -05:00
zos . close ( ) ;
2011-05-17 06:46:35 -04:00
}
2017-01-07 19:38:41 -05:00
} finally {
2016-10-09 00:43:14 -04:00
zipEntrySource . close ( ) ;
2011-11-07 05:25:35 -05:00
}
2011-05-17 06:46:35 -04:00
}
2017-01-07 19:38:41 -05:00
2011-08-11 04:54:11 -04:00
private static void copyStreamAndInjectWorksheet ( InputStream in , OutputStream out , InputStream worksheetData ) throws IOException {
2011-05-17 06:46:35 -04:00
InputStreamReader inReader = new InputStreamReader ( in , " UTF-8 " ) ; //TODO: Is it always UTF-8 or do we need to read the xml encoding declaration in the file? If not, we should perhaps use a SAX reader instead.
OutputStreamWriter outWriter = new OutputStreamWriter ( out , " UTF-8 " ) ;
2011-08-11 04:54:11 -04:00
boolean needsStartTag = true ;
2011-05-17 06:46:35 -04:00
int c ;
int pos = 0 ;
2011-08-11 04:54:11 -04:00
String s = " <sheetData " ;
2011-05-17 06:46:35 -04:00
int n = s . length ( ) ;
2017-01-07 19:38:41 -05:00
//Copy from "in" to "out" up to the string "<sheetData/>" or "</sheetData>" (excluding).
2011-05-17 06:46:35 -04:00
while ( ( ( c = inReader . read ( ) ) ! = - 1 ) )
{
if ( c = = s . charAt ( pos ) )
{
pos + + ;
2011-08-11 04:54:11 -04:00
if ( pos = = n )
{
if ( " <sheetData " . equals ( s ) )
{
c = inReader . read ( ) ;
if ( c = = - 1 )
{
outWriter . write ( s ) ;
break ;
}
if ( c = = '>' )
{
// Found <sheetData>
outWriter . write ( s ) ;
outWriter . write ( c ) ;
s = " </sheetData> " ;
n = s . length ( ) ;
pos = 0 ;
needsStartTag = false ;
continue ;
}
if ( c = = '/' )
{
// Found <sheetData/
c = inReader . read ( ) ;
if ( c = = - 1 )
{
outWriter . write ( s ) ;
break ;
}
if ( c = = '>' )
{
// Found <sheetData/>
break ;
}
outWriter . write ( s ) ;
outWriter . write ( '/' ) ;
outWriter . write ( c ) ;
pos = 0 ;
continue ;
}
outWriter . write ( s ) ;
outWriter . write ( '/' ) ;
outWriter . write ( c ) ;
pos = 0 ;
continue ;
}
else
{
// Found </sheetData>
break ;
}
}
2011-05-17 06:46:35 -04:00
}
else
{
2017-01-07 19:38:41 -05:00
if ( pos > 0 ) {
outWriter . write ( s , 0 , pos ) ;
}
2011-05-17 06:46:35 -04:00
if ( c = = s . charAt ( 0 ) )
{
pos = 1 ;
}
else
{
outWriter . write ( c ) ;
pos = 0 ;
}
}
}
outWriter . flush ( ) ;
2011-08-11 04:54:11 -04:00
if ( needsStartTag )
{
outWriter . write ( " <sheetData> \ n " ) ;
outWriter . flush ( ) ;
}
2017-01-07 19:38:41 -05:00
//Copy the worksheet data to "out".
IOUtils . copy ( worksheetData , out ) ;
2011-08-11 04:54:11 -04:00
outWriter . write ( " </sheetData> " ) ;
outWriter . flush ( ) ;
2017-01-07 19:38:41 -05:00
//Copy the rest of "in" to "out".
while ( ( ( c = inReader . read ( ) ) ! = - 1 ) ) {
2011-05-17 06:46:35 -04:00
outWriter . write ( c ) ;
2017-01-07 19:38:41 -05:00
}
2011-05-17 06:46:35 -04:00
outWriter . flush ( ) ;
}
public XSSFWorkbook getXSSFWorkbook ( )
{
return _wb ;
}
//start of interface implementation
/ * *
* 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 .
*
* @return the index of the active sheet ( 0 - based )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public int getActiveSheetIndex ( )
{
return _wb . getActiveSheetIndex ( ) ;
}
/ * *
* 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 .
*
* @param sheetIndex index of the active sheet ( 0 - based )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setActiveSheet ( int sheetIndex )
{
_wb . setActiveSheet ( sheetIndex ) ;
}
/ * *
* Gets the first tab that is displayed in the list of tabs in excel .
*
* @return the first tab that to display in the list of tabs ( 0 - based ) .
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public int getFirstVisibleTab ( )
{
return _wb . getFirstVisibleTab ( ) ;
}
/ * *
* Sets the first tab that is displayed in the list of tabs in excel .
*
* @param sheetIndex the first tab that to display in the list of tabs ( 0 - based )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setFirstVisibleTab ( int sheetIndex )
{
_wb . setFirstVisibleTab ( sheetIndex ) ;
}
/ * *
* 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 )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setSheetOrder ( String sheetname , int pos )
{
_wb . setSheetOrder ( sheetname , pos ) ;
}
/ * *
* Sets the tab whose data is actually seen when the sheet is opened .
* This may be different from the " selected sheet " since excel seems to
* allow you to show the data of one sheet when another is seen " selected "
* in the tabs ( at the bottom ) .
*
* @see Sheet # setSelected ( boolean )
* @param index the index of the sheet to select ( 0 based )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setSelectedTab ( int index )
{
_wb . setSelectedTab ( index ) ;
}
/ * *
* Set the sheet name .
*
* @param sheet number ( 0 based )
* @throws IllegalArgumentException if the name is greater than 31 chars or contains < code > / \ ? * [ ] < / code >
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setSheetName ( int sheet , String name )
{
_wb . setSheetName ( sheet , name ) ;
}
/ * *
* Set the sheet name
*
* @param sheet sheet number ( 0 based )
* @return Sheet name
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public String getSheetName ( int sheet )
{
return _wb . getSheetName ( sheet ) ;
}
/ * *
* Returns the index of the sheet by his name
*
* @param name the sheet name
* @return index of the sheet ( 0 based )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public int getSheetIndex ( String name )
{
return _wb . getSheetIndex ( name ) ;
}
/ * *
* Returns the index of the given sheet
*
* @param sheet the sheet to look up
* @return index of the sheet ( 0 based )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public int getSheetIndex ( Sheet sheet )
{
return _wb . getSheetIndex ( getXSSFSheet ( ( SXSSFSheet ) sheet ) ) ;
}
/ * *
* Sreate an Sheet for this Workbook , adds it to the sheets and returns
* the high level representation . Use this to create new sheets .
*
* @return Sheet representing the new sheet .
* /
2014-10-06 09:20:12 -04:00
@Override
2015-07-31 13:23:01 -04:00
public SXSSFSheet createSheet ( )
2011-05-17 06:46:35 -04:00
{
return createAndRegisterSXSSFSheet ( _wb . createSheet ( ) ) ;
}
2016-04-10 05:40:40 -04:00
2011-05-17 06:46:35 -04:00
SXSSFSheet createAndRegisterSXSSFSheet ( XSSFSheet xSheet )
{
2016-03-29 13:27:20 -04:00
final SXSSFSheet sxSheet ;
2011-05-17 06:46:35 -04:00
try
{
sxSheet = new SXSSFSheet ( this , xSheet ) ;
}
catch ( IOException ioe )
{
throw new RuntimeException ( ioe ) ;
}
registerSheetMapping ( sxSheet , xSheet ) ;
return sxSheet ;
}
/ * *
* Create an Sheet 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 .
* @return Sheet representing the new sheet .
* @throws IllegalArgumentException if the name is greater than 31 chars or contains < code > / \ ? * [ ] < / code >
* /
2014-10-06 09:20:12 -04:00
@Override
2015-07-31 15:19:33 -04:00
public SXSSFSheet createSheet ( String sheetname )
2011-05-17 06:46:35 -04:00
{
return createAndRegisterSXSSFSheet ( _wb . createSheet ( sheetname ) ) ;
}
/ * *
2016-04-10 05:40:40 -04:00
* < i > Not implemented for SXSSFWorkbook < / i >
*
2011-05-17 06:46:35 -04:00
* Create an Sheet from an existing sheet in the Workbook .
*
* @return Sheet representing the cloned sheet .
* /
2014-10-06 09:20:12 -04:00
@Override
2016-04-10 05:40:40 -04:00
@NotImplemented
2011-05-17 06:46:35 -04:00
public Sheet cloneSheet ( int sheetNum )
{
2011-05-19 08:00:10 -04:00
throw new RuntimeException ( " NotImplemented " ) ;
2011-05-17 06:46:35 -04:00
}
/ * *
* Get the number of spreadsheets in the workbook
*
* @return the number of sheets
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public int getNumberOfSheets ( )
{
return _wb . getNumberOfSheets ( ) ;
}
2015-09-17 07:10:11 -04:00
/ * *
* Returns an iterator of the sheets in the workbook
* in sheet order . Includes hidden and very hidden sheets .
*
* @return an iterator of the sheets .
* /
@Override
public Iterator < Sheet > sheetIterator ( ) {
return new SheetIterator < Sheet > ( ) ;
}
private final class SheetIterator < T extends Sheet > implements Iterator < T > {
final private Iterator < XSSFSheet > it ;
@SuppressWarnings ( " unchecked " )
public SheetIterator ( ) {
it = ( Iterator < XSSFSheet > ) ( Iterator < ? extends Sheet > ) _wb . iterator ( ) ;
}
@Override
public boolean hasNext ( ) {
return it . hasNext ( ) ;
}
@Override
@SuppressWarnings ( " unchecked " )
public T next ( ) throws NoSuchElementException {
final XSSFSheet xssfSheet = it . next ( ) ;
2016-03-29 13:27:20 -04:00
return ( T ) getSXSSFSheet ( xssfSheet ) ;
2015-09-17 07:10:11 -04:00
}
/ * *
* Unexpected behavior may occur if sheets are reordered after iterator
* has been created . Support for the remove method may be added in the future
* if someone can figure out a reliable implementation .
* /
@Override
public void remove ( ) throws IllegalStateException {
throw new UnsupportedOperationException ( " remove method not supported on XSSFWorkbook.iterator(). " +
" Use Sheet.removeSheetAt(int) instead. " ) ;
}
}
/ * *
* Alias for { @link # sheetIterator ( ) } to allow
* foreach loops
* /
@Override
public Iterator < Sheet > iterator ( ) {
return sheetIterator ( ) ;
}
2011-05-17 06:46:35 -04:00
/ * *
* Get the Sheet object at the given index .
*
2016-07-15 02:35:21 -04:00
* @param index of the sheet number ( 0 - based physical and logical )
2011-05-17 06:46:35 -04:00
* @return Sheet at the provided index
* /
2014-10-06 09:20:12 -04:00
@Override
2015-07-31 15:19:33 -04:00
public SXSSFSheet getSheetAt ( int index )
2011-05-17 06:46:35 -04:00
{
return getSXSSFSheet ( _wb . getSheetAt ( index ) ) ;
}
/ * *
* Get sheet with the given name
*
* @param name of the sheet
* @return Sheet with the name provided or < code > null < / code > if it does not exist
* /
2014-10-06 09:20:12 -04:00
@Override
2015-07-31 15:19:33 -04:00
public SXSSFSheet getSheet ( String name )
2011-05-17 06:46:35 -04:00
{
return getSXSSFSheet ( _wb . getSheet ( name ) ) ;
}
/ * *
* Removes sheet at the given index
*
* @param index of the sheet to remove ( 0 - based )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void removeSheetAt ( int index )
{
2015-04-29 15:28:26 -04:00
// Get the sheet to be removed
XSSFSheet xSheet = _wb . getSheetAt ( index ) ;
SXSSFSheet sxSheet = getSXSSFSheet ( xSheet ) ;
// De-register it
2011-05-17 06:46:35 -04:00
_wb . removeSheetAt ( index ) ;
deregisterSheetMapping ( xSheet ) ;
2015-04-29 15:28:26 -04:00
// Clean up temporary resources
2015-07-31 15:19:33 -04:00
try {
sxSheet . dispose ( ) ;
} catch ( IOException e ) {
logger . log ( POILogger . WARN , e ) ;
}
2011-05-17 06:46:35 -04:00
}
/ * *
* Create a new Font and add it to the workbook ' s font table
*
* @return new font object
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public Font createFont ( )
{
return _wb . createFont ( ) ;
}
/ * *
* Finds a font that matches the one with the supplied attributes
*
* @return the font with the matched attributes or < code > null < / code >
2016-06-17 21:21:08 -04:00
* @deprecated POI 3 . 15 beta 2 . Use { @link # findFont ( boolean , short , short , String , boolean , boolean , short , byte ) } instead .
2011-05-17 06:46:35 -04:00
* /
2017-01-07 19:38:41 -05:00
@Deprecated
2014-10-06 09:20:12 -04:00
@Override
2017-01-07 19:38:41 -05:00
@Removal ( version = " 3.17 " )
2011-05-17 06:46:35 -04:00
public Font findFont ( short boldWeight , short color , short fontHeight , String name , boolean italic , boolean strikeout , short typeOffset , byte underline )
{
return _wb . findFont ( boldWeight , color , fontHeight , name , italic , strikeout , typeOffset , underline ) ;
}
2016-06-17 21:21:08 -04:00
/ * *
* Finds a font that matches the one with the supplied attributes
*
* @return the font with the matched attributes or < code > null < / code >
* /
@Override
public Font findFont ( boolean bold , short color , short fontHeight , String name , boolean italic , boolean strikeout , short typeOffset , byte underline )
{
return _wb . findFont ( bold , color , fontHeight , name , italic , strikeout , typeOffset , underline ) ;
}
2011-05-17 06:46:35 -04:00
/ * *
* Get the number of fonts in the font table
*
* @return number of fonts
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public short getNumberOfFonts ( )
{
return _wb . getNumberOfFonts ( ) ;
}
/ * *
* Get the font at the given index number
*
* @param idx index number ( 0 - based )
* @return font at the index
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public Font getFontAt ( short idx )
{
return _wb . getFontAt ( idx ) ;
}
/ * *
* Create a new Cell style and add it to the workbook ' s style table
*
* @return the new Cell Style object
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public CellStyle createCellStyle ( )
{
return _wb . createCellStyle ( ) ;
}
/ * *
* Get the number of styles the workbook contains
*
* @return count of cell styles
* /
2014-10-06 09:20:12 -04:00
@Override
2015-12-28 09:50:54 -05:00
public int getNumCellStyles ( )
2011-05-17 06:46:35 -04:00
{
return _wb . getNumCellStyles ( ) ;
}
/ * *
* Get the cell style object at the given index
*
* @param idx index within the set of styles ( 0 - based )
* @return CellStyle object at the index
* /
2014-10-06 09:20:12 -04:00
@Override
2015-12-28 09:50:54 -05:00
public CellStyle getCellStyleAt ( int idx )
2011-05-17 06:46:35 -04:00
{
return _wb . getCellStyleAt ( idx ) ;
}
2014-06-11 10:38:32 -04:00
/ * *
* Closes the underlying { @link XSSFWorkbook } and { @link OPCPackage }
2016-07-24 07:38:50 -04:00
* on which this Workbook is based , if any .
*
* < p > Once this has been called , no further
* operations , updates or reads should be performed on the
* Workbook .
2014-06-11 10:38:32 -04:00
* /
@Override
public void close ( ) throws IOException {
2014-12-28 04:16:57 -05:00
// ensure that any lingering writer is closed
for ( SXSSFSheet sheet : _xFromSxHash . values ( ) )
{
try {
sheet . getSheetDataWriter ( ) . close ( ) ;
} catch ( IOException e ) {
2016-09-20 23:31:15 -04:00
logger . log ( POILogger . WARN ,
" An exception occurred while closing sheet data writer for sheet "
+ sheet . getSheetName ( ) + " . " , e ) ;
2014-12-28 04:16:57 -05:00
}
}
2014-06-11 10:38:32 -04:00
// Tell the base workbook to close, does nothing if
// it's a newly created one
_wb . close ( ) ;
}
2011-05-17 06:46:35 -04:00
/ * *
2017-01-07 19:38:41 -05:00
* Write out this workbook to an OutputStream .
2011-05-17 06:46:35 -04:00
*
* @param stream - the java OutputStream you wish to write to
* @exception IOException if anything can ' t be written .
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void write ( OutputStream stream ) throws IOException
{
2016-09-20 23:31:15 -04:00
flushSheets ( ) ;
2011-05-17 06:46:35 -04:00
//Save the template
2014-07-24 14:58:27 -04:00
File tmplFile = TempFile . createTempFile ( " poi-sxssf-template " , " .xlsx " ) ;
2017-01-07 19:38:41 -05:00
boolean deleted ;
try {
2012-09-14 09:45:09 -04:00
FileOutputStream os = new FileOutputStream ( tmplFile ) ;
2017-01-07 19:38:41 -05:00
try {
2012-09-14 09:45:09 -04:00
_wb . write ( os ) ;
2017-01-07 19:38:41 -05:00
} finally {
2012-09-14 09:45:09 -04:00
os . close ( ) ;
}
//Substitute the template entries with the generated sheet data files
2016-10-09 00:43:14 -04:00
final ZipEntrySource source = new ZipFileZipEntrySource ( new ZipFile ( tmplFile ) ) ;
injectData ( source , stream ) ;
2017-01-07 19:38:41 -05:00
} finally {
deleted = tmplFile . delete ( ) ;
2012-09-14 09:45:09 -04:00
}
2017-01-07 19:38:41 -05:00
if ( ! deleted ) {
throw new IOException ( " Could not delete temporary file after processing: " + tmplFile ) ;
2012-09-14 09:45:09 -04:00
}
}
2016-09-20 23:31:15 -04:00
protected void flushSheets ( ) throws IOException {
for ( SXSSFSheet sheet : _xFromSxHash . values ( ) )
{
sheet . flushRows ( ) ;
}
}
2012-09-14 09:45:09 -04:00
/ * *
* Dispose of temporary files backing this workbook on disk .
* Calling this method will render the workbook unusable .
* @return true if all temporary files were deleted successfully .
* /
public boolean dispose ( )
{
boolean success = true ;
for ( SXSSFSheet sheet : _sxFromXHash . keySet ( ) )
{
2015-07-31 15:19:33 -04:00
try {
success = sheet . dispose ( ) & & success ;
} catch ( IOException e ) {
logger . log ( POILogger . WARN , e ) ;
success = false ;
}
2012-09-14 09:45:09 -04:00
}
return success ;
2011-05-17 06:46:35 -04:00
}
/ * *
* @return the total number of defined names in this workbook
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public int getNumberOfNames ( )
{
return _wb . getNumberOfNames ( ) ;
}
/ * *
* @param name the name of the defined name
* @return the defined name with the specified name . < code > null < / code > if not found .
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public Name getName ( String name )
{
return _wb . getName ( name ) ;
}
2016-03-13 17:30:38 -04:00
/ * *
* Returns all defined names with the given name .
*
* @param name the name of the defined name
* @return a list of the defined names with the specified name . An empty list is returned if none is found .
* /
@Override
public List < ? extends Name > getNames ( String name ) {
return _wb . getNames ( name ) ;
}
2016-07-29 09:24:00 -04:00
/ * *
* Returns all defined names
*
* @return all defined names
* /
@Override
public List < ? extends Name > getAllNames ( )
{
return _wb . getAllNames ( ) ;
}
2011-05-17 06:46:35 -04:00
/ * *
* @param nameIndex position of the named range ( 0 - based )
* @return the defined name at the specified index
* @throws IllegalArgumentException if the supplied index is invalid
2016-07-29 09:24:00 -04:00
* @deprecated 3 . 16 . New projects should avoid accessing named ranges by index .
2011-05-17 06:46:35 -04:00
* /
2014-10-06 09:20:12 -04:00
@Override
2016-07-29 09:24:00 -04:00
@Deprecated
2017-01-07 19:38:41 -05:00
@Removal ( version = " 3.18 " )
2011-05-17 06:46:35 -04:00
public Name getNameAt ( int nameIndex )
{
return _wb . getNameAt ( nameIndex ) ;
}
/ * *
* Creates a new ( uninitialised ) defined name in this workbook
*
* @return new defined name object
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public Name createName ( )
{
return _wb . createName ( ) ;
}
/ * *
2016-07-15 02:35:21 -04:00
* Gets the defined name index by name
*
2011-05-17 06:46:35 -04:00
* < i > Note : < / i > Excel defined names are case - insensitive and
* this method performs a case - insensitive search .
*
* @param name the name of the defined name
2016-07-15 02:35:21 -04:00
* @return zero based index of the defined name . < code > - 1 < / code > if not found .
2016-07-29 09:24:00 -04:00
*
* @deprecated 3 . 16 . New projects should avoid accessing named ranges by index .
* Use { @link # getName ( String ) } instead .
2011-05-17 06:46:35 -04:00
* /
2014-10-06 09:20:12 -04:00
@Override
2016-07-29 09:24:00 -04:00
@Deprecated
2017-01-07 19:38:41 -05:00
@Removal ( version = " 3.18 " )
2011-05-17 06:46:35 -04:00
public int getNameIndex ( String name )
{
return _wb . getNameIndex ( name ) ;
}
/ * *
* Remove the defined name at the specified index
*
* @param index named range index ( 0 based )
2016-07-29 09:24:00 -04:00
*
* @deprecated 3 . 16 . New projects should use { @link # removeName ( Name ) } .
2011-05-17 06:46:35 -04:00
* /
2014-10-06 09:20:12 -04:00
@Override
2016-07-29 09:24:00 -04:00
@Deprecated
2017-01-07 19:38:41 -05:00
@Removal ( version = " 3.18 " )
2011-05-17 06:46:35 -04:00
public void removeName ( int index )
{
_wb . removeName ( index ) ;
}
/ * *
* Remove a defined name by name
*
2016-07-29 09:24:00 -04:00
* @param name the name of the defined name
*
* @deprecated 3 . 16 . New projects should use { @link # removeName ( Name ) } .
2011-05-17 06:46:35 -04:00
* /
2014-10-06 09:20:12 -04:00
@Override
2016-07-29 09:24:00 -04:00
@Deprecated
2017-01-07 19:38:41 -05:00
@Removal ( version = " 3.18 " )
2011-05-17 06:46:35 -04:00
public void removeName ( String name )
2016-07-29 09:24:00 -04:00
{
_wb . removeName ( name ) ;
}
/ * *
* Remove the given defined name
*
* @param name the name to remove
* /
@Override
public void removeName ( Name name )
2011-05-17 06:46:35 -04:00
{
_wb . removeName ( name ) ;
}
/ * *
* 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
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setPrintArea ( int sheetIndex , String reference )
{
_wb . setPrintArea ( sheetIndex , reference ) ;
}
/ * *
* 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
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setPrintArea ( int sheetIndex , int startColumn , int endColumn , int startRow , int endRow )
{
_wb . setPrintArea ( sheetIndex , startColumn , endColumn , startRow , endRow ) ;
}
/ * *
* 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
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public String getPrintArea ( int sheetIndex )
{
return _wb . getPrintArea ( sheetIndex ) ;
}
/ * *
* Delete the printarea for the sheet specified
*
* @param sheetIndex Zero - based sheet index ( 0 = First Sheet )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void removePrintArea ( int sheetIndex )
{
_wb . removePrintArea ( sheetIndex ) ;
}
/ * *
* Retrieves the current policy on what to do when
* getting missing or blank cells from a row .
* < p >
* The default is to return blank and null cells .
* { @link MissingCellPolicy }
* < / p >
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public MissingCellPolicy getMissingCellPolicy ( )
{
return _wb . getMissingCellPolicy ( ) ;
}
/ * *
* 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 org . apache . poi . ss . usermodel . Row # getCell ( int ) } . See
* { @link MissingCellPolicy }
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setMissingCellPolicy ( MissingCellPolicy missingCellPolicy )
{
_wb . setMissingCellPolicy ( missingCellPolicy ) ;
}
/ * *
* Returns the instance of DataFormat for this workbook .
*
* @return the DataFormat object
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public DataFormat createDataFormat ( )
{
return _wb . createDataFormat ( ) ;
}
/ * *
* 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 ( 1 based ) .
* @see # PICTURE_TYPE_EMF
* @see # PICTURE_TYPE_WMF
* @see # PICTURE_TYPE_PICT
* @see # PICTURE_TYPE_JPEG
* @see # PICTURE_TYPE_PNG
* @see # PICTURE_TYPE_DIB
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public int addPicture ( byte [ ] pictureData , int format )
{
return _wb . addPicture ( pictureData , format ) ;
}
/ * *
* Gets all pictures from the Workbook .
*
* @return the list of pictures ( a list of { @link PictureData } objects . )
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public List < ? extends PictureData > getAllPictures ( )
{
return _wb . getAllPictures ( ) ;
}
/ * *
* Returns an object that handles instantiating concrete
2015-07-31 15:19:33 -04:00
* classes of the various instances one needs for HSSF , XSSF
* and SXSSF .
2011-05-17 06:46:35 -04:00
* /
2014-10-06 09:20:12 -04:00
@Override
2015-07-31 15:19:33 -04:00
public CreationHelper getCreationHelper ( ) {
return new SXSSFCreationHelper ( this ) ;
2011-05-17 06:46:35 -04:00
}
2015-07-31 13:23:01 -04:00
protected boolean isDate1904 ( ) {
return _wb . isDate1904 ( ) ;
}
2014-10-06 09:20:12 -04:00
@Override
2017-01-19 23:23:42 -05:00
@NotImplemented ( " XSSFWorkbook#isHidden is not implemented " )
2011-05-17 06:46:35 -04:00
public boolean isHidden ( )
{
return _wb . isHidden ( ) ;
}
2014-10-06 09:20:12 -04:00
@Override
2017-01-19 23:23:42 -05:00
@NotImplemented ( " XSSFWorkbook#setHidden is not implemented " )
2011-05-17 06:46:35 -04:00
public void setHidden ( boolean hiddenFlag )
{
_wb . setHidden ( hiddenFlag ) ;
}
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public boolean isSheetHidden ( int sheetIx )
{
return _wb . isSheetHidden ( sheetIx ) ;
}
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public boolean isSheetVeryHidden ( int sheetIx )
{
return _wb . isSheetVeryHidden ( sheetIx ) ;
}
2017-01-19 23:23:42 -05:00
@Override
public SheetVisibility getSheetVisibility ( int sheetIx ) {
return _wb . getSheetVisibility ( sheetIx ) ;
}
2011-05-17 06:46:35 -04:00
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setSheetHidden ( int sheetIx , boolean hidden )
{
_wb . setSheetHidden ( sheetIx , hidden ) ;
}
2017-01-19 23:23:42 -05:00
@Removal ( version = " 3.18 " )
@Deprecated
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void setSheetHidden ( int sheetIx , int hidden )
{
_wb . setSheetHidden ( sheetIx , hidden ) ;
}
2014-11-04 16:35:01 -05:00
2017-01-19 23:23:42 -05:00
@Override
public void setSheetVisibility ( int sheetIx , SheetVisibility visibility ) {
_wb . setSheetVisibility ( sheetIx , visibility ) ;
}
2014-11-04 16:35:01 -05:00
/ * *
2016-04-10 05:40:40 -04:00
* < i > Not implemented for SXSSFWorkbook < / i >
*
2014-11-04 16:35:01 -05:00
* Adds the LinkTable records required to allow formulas referencing
* the specified external workbook to be added to this one . Allows
* formulas such as " [MyOtherWorkbook]Sheet3!$A$5 " to be added to the
* file , for workbooks not already referenced .
*
* @param name The name the workbook will be referenced as in formulas
* @param workbook The open workbook to fetch the link required information from
* /
2016-04-10 05:40:40 -04:00
@Override
@NotImplemented
2014-11-04 16:35:01 -05:00
public int linkExternalWorkbook ( String name , Workbook workbook ) {
throw new RuntimeException ( " NotImplemented " ) ;
}
2011-05-17 06:46:35 -04:00
/ * *
* Register a new toolpack in this workbook .
*
* @param toopack the toolpack to register
* /
2014-10-06 09:20:12 -04:00
@Override
2011-05-17 06:46:35 -04:00
public void addToolPack ( UDFFinder toopack )
{
_wb . addToolPack ( toopack ) ;
}
2011-06-27 11:40:48 -04:00
/ * *
* Whether the application shall perform a full recalculation when the workbook is opened .
* < p >
* Typically you want to force formula recalculation when you modify cell formulas or values
* of a workbook previously created by Excel . When set to 0 , this flag will tell Excel
* that it needs to recalculate all formulas in the workbook the next time the file is opened .
* < / p >
*
* @param value true if the application will perform a full recalculation of
* workbook values when the workbook is opened
* @since 3 . 8
* /
2014-10-06 09:20:12 -04:00
@Override
2011-06-27 11:40:48 -04:00
public void setForceFormulaRecalculation ( boolean value ) {
_wb . setForceFormulaRecalculation ( value ) ;
}
2011-06-30 11:54:04 -04:00
/ * *
* Whether Excel will be asked to recalculate all formulas when the workbook is opened .
* /
2014-10-06 09:20:12 -04:00
@Override
2011-06-30 11:54:04 -04:00
public boolean getForceFormulaRecalculation ( ) {
return _wb . getForceFormulaRecalculation ( ) ;
}
2016-01-16 17:01:33 -05:00
/ * *
* Returns the spreadsheet version ( EXCLE2007 ) of this workbook
*
* @return EXCEL2007 SpreadsheetVersion enum
* @since 3 . 14 beta 2
* /
@Override
2016-01-16 17:58:25 -05:00
public SpreadsheetVersion getSpreadsheetVersion ( ) {
2016-01-16 17:01:33 -05:00
return SpreadsheetVersion . EXCEL2007 ;
}
2017-01-14 21:04:57 -05:00
@Override
public int addOlePackage ( byte [ ] oleData , String label , String fileName , String command ) throws IOException {
return _wb . addOlePackage ( oleData , label , fileName , command ) ;
}
2011-05-17 06:46:35 -04:00
//end of interface implementation
}