#58200 Prepare for evaluating SXSSF cell formulas in limited cases
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1693641 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fcbd93a768
commit
66d370a978
@ -0,0 +1,48 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCreationHelper;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
|
||||
|
||||
/**
|
||||
* Streaming Creation Helper, which performs some actions
|
||||
* based on the Streaming Workbook, and some on the related
|
||||
* regular XSSF Workbook
|
||||
*/
|
||||
public class SXSSFCreationHelper extends XSSFCreationHelper {
|
||||
private static POILogger logger = POILogFactory.getLogger(SXSSFCreationHelper.class);
|
||||
|
||||
private SXSSFWorkbook wb;
|
||||
|
||||
public SXSSFCreationHelper(SXSSFWorkbook workbook) {
|
||||
super(workbook.getXSSFWorkbook());
|
||||
this.wb = workbook;
|
||||
}
|
||||
|
||||
public XSSFRichTextString createRichTextString(String text) {
|
||||
logger.log(POILogger.INFO, "SXSSF doesn't support Rich Text Strings, any formatting information will be lost");
|
||||
return new XSSFRichTextString(text);
|
||||
}
|
||||
|
||||
public SXSSFFormulaEvaluator createFormulaEvaluator() {
|
||||
return new SXSSFFormulaEvaluator(wb);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
|
||||
|
||||
/**
|
||||
* Streaming-specific Formula Evaluator, which is able to
|
||||
* lookup cells within the current Window.
|
||||
*/
|
||||
public class SXSSFFormulaEvaluator extends XSSFFormulaEvaluator {
|
||||
private static POILogger logger = POILogFactory.getLogger(SXSSFFormulaEvaluator.class);
|
||||
|
||||
private SXSSFWorkbook wb;
|
||||
|
||||
public SXSSFFormulaEvaluator(SXSSFWorkbook workbook) {
|
||||
super(workbook.getXSSFWorkbook());
|
||||
this.wb = workbook;
|
||||
}
|
||||
|
||||
/**
|
||||
* For active worksheets only, will loop over rows and
|
||||
* cells, evaluating formula cells there.
|
||||
* If formula cells are outside the window for that sheet,
|
||||
* it can either skip them silently, or give an exception
|
||||
*/
|
||||
public static void evaluateAllFormulaCells(SXSSFWorkbook wb, boolean skipOutOfWindow) {
|
||||
// Check they're all available
|
||||
for (int i=0; i<wb.getNumberOfSheets(); i++) {
|
||||
SXSSFSheet s = wb.getSheetAt(i);
|
||||
if (s.isFlushed()) {
|
||||
throw new SheetsFlushedException();
|
||||
}
|
||||
}
|
||||
|
||||
// Process the sheets as best we can
|
||||
for (int i=0; i<wb.getNumberOfSheets(); i++) {
|
||||
SXSSFSheet s = wb.getSheetAt(i);
|
||||
// TODO Detect if rows have been flushed
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops over rows and cells, evaluating formula cells there.
|
||||
* If any sheets are inactive, or any cells outside of the window,
|
||||
* will give an Exception.
|
||||
* For SXSSF, you generally don't want to use this method, instead
|
||||
* evaluate your formulas as you go before they leave the window.
|
||||
*/
|
||||
public void evaluateAll() {
|
||||
// Have the evaluation done, with exceptions
|
||||
evaluateAllFormulaCells(wb, false);
|
||||
}
|
||||
|
||||
public static class SheetsFlushedException extends IllegalStateException {
|
||||
protected SheetsFlushedException() {
|
||||
super("One or more sheets have been flushed, cannot evaluate all cells");
|
||||
}
|
||||
}
|
||||
}
|
@ -50,25 +50,22 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
|
||||
|
||||
/**
|
||||
* Streaming version of XSSFSheet implementing the "BigGridDemo" strategy.
|
||||
*
|
||||
* @author Alex Geller, Four J's Development Tools
|
||||
*/
|
||||
public class SXSSFSheet implements Sheet, Cloneable
|
||||
{
|
||||
SXSSFWorkbook _workbook;
|
||||
XSSFSheet _sh;
|
||||
TreeMap<Integer,SXSSFRow> _rows=new TreeMap<Integer,SXSSFRow>();
|
||||
SheetDataWriter _writer;
|
||||
int _randomAccessWindowSize = SXSSFWorkbook.DEFAULT_WINDOW_SIZE;
|
||||
int outlineLevelRow = 0;
|
||||
private SXSSFWorkbook _workbook;
|
||||
private TreeMap<Integer,SXSSFRow> _rows=new TreeMap<Integer,SXSSFRow>();
|
||||
private SheetDataWriter _writer;
|
||||
private int _randomAccessWindowSize = SXSSFWorkbook.DEFAULT_WINDOW_SIZE;
|
||||
private int outlineLevelRow = 0;
|
||||
private boolean flushed = false;
|
||||
|
||||
public SXSSFSheet(SXSSFWorkbook workbook, XSSFSheet xSheet) throws IOException
|
||||
{
|
||||
_workbook=workbook;
|
||||
_sh=xSheet;
|
||||
public SXSSFSheet(SXSSFWorkbook workbook, XSSFSheet xSheet) throws IOException {
|
||||
_workbook = workbook;
|
||||
_sh = xSheet;
|
||||
_writer = workbook.createSheetDataWriter();
|
||||
setRandomAccessWindowSize(_workbook.getRandomAccessWindowSize());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,6 +135,7 @@ public class SXSSFSheet implements Sheet, Cloneable
|
||||
initialAllocationSize=10;
|
||||
SXSSFRow newRow=new SXSSFRow(this,initialAllocationSize);
|
||||
_rows.put(new Integer(rownum),newRow);
|
||||
flushed = false;
|
||||
if(_randomAccessWindowSize>=0&&_rows.size()>_randomAccessWindowSize)
|
||||
{
|
||||
try
|
||||
@ -1464,6 +1462,13 @@ public class SXSSFSheet implements Sheet, Cloneable
|
||||
}
|
||||
_randomAccessWindowSize=value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are all rows flushed to disk?
|
||||
*/
|
||||
public boolean isFlushed() {
|
||||
return flushed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies how many rows can be accessed at most via getRow().
|
||||
@ -1473,6 +1478,7 @@ public class SXSSFSheet implements Sheet, Cloneable
|
||||
public void flushRows(int remaining) throws IOException
|
||||
{
|
||||
while(_rows.size() > remaining) flushOneRow();
|
||||
if (remaining == 0) flushed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1517,7 +1523,8 @@ public class SXSSFSheet implements Sheet, Cloneable
|
||||
* Deletes the temporary file that backed this sheet on disk.
|
||||
* @return true if the file was deleted, false if it wasn't.
|
||||
*/
|
||||
boolean dispose() {
|
||||
boolean dispose() throws IOException {
|
||||
if (!flushed) flushRows();
|
||||
return _writer.dispose();
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,8 @@ import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.TempFile;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
@ -62,8 +64,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
* Carefully review your memory budget and compatibility needs before deciding
|
||||
* whether to enable shared strings or not.
|
||||
*/
|
||||
public class SXSSFWorkbook implements Workbook
|
||||
{
|
||||
public class SXSSFWorkbook implements Workbook {
|
||||
/**
|
||||
* Specifies how many rows can be accessed at most via getRow().
|
||||
* When a new node is created via createRow() and the total number
|
||||
@ -72,6 +73,7 @@ public class SXSSFWorkbook implements Workbook
|
||||
* via getRow() anymore.
|
||||
*/
|
||||
public static final int DEFAULT_WINDOW_SIZE = 100;
|
||||
private static POILogger logger = POILogFactory.getLogger(SXSSFWorkbook.class);
|
||||
|
||||
XSSFWorkbook _wb;
|
||||
|
||||
@ -650,7 +652,7 @@ public class SXSSFWorkbook implements Workbook
|
||||
* @throws IllegalArgumentException if the name is greater than 31 chars or contains <code>/\?*[]</code>
|
||||
*/
|
||||
@Override
|
||||
public Sheet createSheet(String sheetname)
|
||||
public SXSSFSheet createSheet(String sheetname)
|
||||
{
|
||||
return createAndRegisterSXSSFSheet(_wb.createSheet(sheetname));
|
||||
}
|
||||
@ -685,7 +687,7 @@ public class SXSSFWorkbook implements Workbook
|
||||
* @return Sheet at the provided index
|
||||
*/
|
||||
@Override
|
||||
public Sheet getSheetAt(int index)
|
||||
public SXSSFSheet getSheetAt(int index)
|
||||
{
|
||||
return getSXSSFSheet(_wb.getSheetAt(index));
|
||||
}
|
||||
@ -697,7 +699,7 @@ public class SXSSFWorkbook implements Workbook
|
||||
* @return Sheet with the name provided or <code>null</code> if it does not exist
|
||||
*/
|
||||
@Override
|
||||
public Sheet getSheet(String name)
|
||||
public SXSSFSheet getSheet(String name)
|
||||
{
|
||||
return getSXSSFSheet(_wb.getSheet(name));
|
||||
}
|
||||
@ -719,7 +721,11 @@ public class SXSSFWorkbook implements Workbook
|
||||
deregisterSheetMapping(xSheet);
|
||||
|
||||
// Clean up temporary resources
|
||||
sxSheet.dispose();
|
||||
try {
|
||||
sxSheet.dispose();
|
||||
} catch (IOException e) {
|
||||
logger.log(POILogger.WARN, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -909,7 +915,12 @@ public class SXSSFWorkbook implements Workbook
|
||||
boolean success = true;
|
||||
for (SXSSFSheet sheet : _sxFromXHash.keySet())
|
||||
{
|
||||
success = sheet.dispose() && success;
|
||||
try {
|
||||
success = sheet.dispose() && success;
|
||||
} catch (IOException e) {
|
||||
logger.log(POILogger.WARN, e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@ -1114,12 +1125,12 @@ public class SXSSFWorkbook implements Workbook
|
||||
|
||||
/**
|
||||
* Returns an object that handles instantiating concrete
|
||||
* classes of the various instances one needs for HSSF and XSSF.
|
||||
* classes of the various instances one needs for HSSF, XSSF
|
||||
* and SXSSF.
|
||||
*/
|
||||
@Override
|
||||
public CreationHelper getCreationHelper()
|
||||
{
|
||||
return _wb.getCreationHelper();
|
||||
public CreationHelper getCreationHelper() {
|
||||
return new SXSSFCreationHelper(this);
|
||||
}
|
||||
|
||||
protected boolean isDate1904() {
|
||||
|
@ -367,12 +367,8 @@ public class SheetDataWriter {
|
||||
* Deletes the temporary file that backed this sheet on disk.
|
||||
* @return true if the file was deleted, false if it wasn't.
|
||||
*/
|
||||
boolean dispose() {
|
||||
try {
|
||||
_out.close();
|
||||
return _fd.delete();
|
||||
} catch (IOException e){
|
||||
return false;
|
||||
}
|
||||
boolean dispose() throws IOException {
|
||||
_out.close();
|
||||
return _fd.delete();
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,13 @@ package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import org.apache.poi.ss.usermodel.CreationHelper;
|
||||
import org.apache.poi.ss.usermodel.Hyperlink;
|
||||
import org.apache.poi.util.Internal;
|
||||
|
||||
public class XSSFCreationHelper implements CreationHelper {
|
||||
private XSSFWorkbook workbook;
|
||||
|
||||
XSSFCreationHelper(XSSFWorkbook wb) {
|
||||
@Internal
|
||||
public XSSFCreationHelper(XSSFWorkbook wb) {
|
||||
workbook = wb;
|
||||
}
|
||||
|
||||
|
@ -235,22 +235,22 @@ public class XSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluator
|
||||
* cells, and calling evaluateFormulaCell on each one.
|
||||
*/
|
||||
public static void evaluateAllFormulaCells(XSSFWorkbook wb) {
|
||||
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
|
||||
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
|
||||
}
|
||||
/**
|
||||
* Loops over all cells in all sheets of the supplied
|
||||
* workbook.
|
||||
* For cells that contain formulas, their formulas are
|
||||
* evaluated, and the results are saved. These cells
|
||||
* remain as formula cells.
|
||||
* For cells that do not contain formulas, no changes
|
||||
* are made.
|
||||
* This is a helpful wrapper around looping over all
|
||||
* cells, and calling evaluateFormulaCell on each one.
|
||||
*/
|
||||
public void evaluateAll() {
|
||||
HSSFFormulaEvaluator.evaluateAllFormulaCells(_book);
|
||||
}
|
||||
/**
|
||||
* Loops over all cells in all sheets of the supplied
|
||||
* workbook.
|
||||
* For cells that contain formulas, their formulas are
|
||||
* evaluated, and the results are saved. These cells
|
||||
* remain as formula cells.
|
||||
* For cells that do not contain formulas, no changes
|
||||
* are made.
|
||||
* This is a helpful wrapper around looping over all
|
||||
* cells, and calling evaluateFormulaCell on each one.
|
||||
*/
|
||||
public void evaluateAll() {
|
||||
HSSFFormulaEvaluator.evaluateAllFormulaCells(_book);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a CellValue wrapper around the supplied ValueEval instance.
|
||||
|
Loading…
Reference in New Issue
Block a user