mirror of
https://github.com/apache/poi.git
synced 2026-02-27 20:40:08 +08:00
1115 lines
44 KiB
HTML
1115 lines
44 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<meta content="Apache Forrest" name="Generator">
|
|
<meta name="Forrest-version" content="0.9">
|
|
<meta name="Forrest-skin-name" content="pelt">
|
|
<title>Formula Evaluation</title>
|
|
<link type="text/css" href="../../skin/basic.css" rel="stylesheet">
|
|
<link media="screen" type="text/css" href="../../skin/screen.css" rel="stylesheet">
|
|
<link media="print" type="text/css" href="../../skin/print.css" rel="stylesheet">
|
|
<link type="text/css" href="../../skin/profile.css" rel="stylesheet">
|
|
<script src="../../skin/getBlank.js" language="javascript" type="text/javascript"></script><script src="../../skin/getMenu.js" language="javascript" type="text/javascript"></script><script src="../../skin/fontsize.js" language="javascript" type="text/javascript"></script>
|
|
<link rel="shortcut icon" href="../../images/favicon.ico">
|
|
</head>
|
|
<body onload="init()">
|
|
<script type="text/javascript">ndeSetTextSize();</script>
|
|
<div id="top">
|
|
<!--+
|
|
|breadtrail
|
|
+-->
|
|
<div class="breadtrail">
|
|
<a href="https://www.apache.org">Apache Software Foundation</a> > <a href="https://poi.apache.org">Apache POI</a><script src="../../skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
|
|
</div>
|
|
<!--+
|
|
|header
|
|
+-->
|
|
<div class="header">
|
|
<!--+
|
|
|start group logo
|
|
+-->
|
|
<div class="grouplogo">
|
|
<a href="https://www.apache.org"><img class="logoImage" alt="Apache Software Foundation" src="../../images/asflogo_horizontal_color.svg" title="The Apache Software Foundation is a cornerstone of the modern Open Source software ecosystem – supporting some of the most widely used and important software solutions powering today's Internet economy."></a>
|
|
</div>
|
|
<!--+
|
|
|end group logo
|
|
+-->
|
|
<!--+
|
|
|start Project Logo
|
|
+-->
|
|
<div class="projectlogo">
|
|
<a href="https://poi.apache.org"><img class="logoImage" alt="Apache POI" src="../../images/project-header.png" title="Apache POI is well-known in the Java field as a library for reading and writing Microsoft Office file formats, such as Excel, PowerPoint, Word, Visio, Publisher and Outlook. It supports both the older (OLE2) and new (OOXML - Office Open XML) formats."></a>
|
|
</div>
|
|
<!--+
|
|
|end Project Logo
|
|
+-->
|
|
<!--+
|
|
|start Search
|
|
+-->
|
|
<div class="searchbox">
|
|
<form action="https://www.google.com/search" method="get" class="roundtopsmall">
|
|
<input value="poi.apache.org" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" size="25" name="q" id="query" type="text" value="Search the site with google">
|
|
<input name="Search" value="Search" type="submit">
|
|
</form>
|
|
</div>
|
|
<!--+
|
|
|end search
|
|
+-->
|
|
<!--+
|
|
|start Tabs
|
|
+-->
|
|
<ul id="tabs">
|
|
<li>
|
|
<a class="unselected" href="../../index.html">Home</a>
|
|
</li>
|
|
<li>
|
|
<a class="unselected" href="../../help/index.html">Help</a>
|
|
</li>
|
|
<li class="current">
|
|
<a class="selected" href="../../components/index.html">Component APIs</a>
|
|
</li>
|
|
<li>
|
|
<a class="unselected" href="../../devel/index.html">Getting Involved</a>
|
|
</li>
|
|
</ul>
|
|
<!--+
|
|
|end Tabs
|
|
+-->
|
|
</div>
|
|
</div>
|
|
<div id="main">
|
|
<div id="publishedStrip">
|
|
<!--+
|
|
|start Subtabs
|
|
+-->
|
|
<div id="level2tabs"></div>
|
|
<!--+
|
|
|end Endtabs
|
|
+-->
|
|
<script type="text/javascript"><!--
|
|
document.write("Last Published: " + document.lastModified);
|
|
// --></script>
|
|
</div>
|
|
<!--+
|
|
|breadtrail
|
|
+-->
|
|
<div class="breadtrail">
|
|
|
|
|
|
</div>
|
|
<!--+
|
|
|start Menu, mainarea
|
|
+-->
|
|
<!--+
|
|
|start Menu
|
|
+-->
|
|
<div id="menu">
|
|
<div onclick="SwitchMenu('menu_selected_1.1', '../../skin/')" id="menu_selected_1.1Title" class="menutitle" style="background-image: url('../../skin/images/chapter_open.gif');">Component APIs</div>
|
|
<div id="menu_selected_1.1" class="selectedmenuitemgroup" style="display: block;">
|
|
<div class="menuitem">
|
|
<a href="../../components/index.html">Overview</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../apidocs/index.html">Javadocs</a>
|
|
</div>
|
|
<div onclick="SwitchMenu('menu_selected_1.1.3', '../../skin/')" id="menu_selected_1.1.3Title" class="menutitle" style="background-image: url('../../skin/images/chapter_open.gif');">Excel (HSSF/XSSF)</div>
|
|
<div id="menu_selected_1.1.3" class="selectedmenuitemgroup" style="display: block;">
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/index.html">Overview</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/quick-guide.html">Quick Guide</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/how-to.html">HOWTO</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/converting.html">HSSF to SS Converting</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/formula.html">Formula Support</a>
|
|
</div>
|
|
<div class="menupage">
|
|
<div class="menupagetitle">Formula Evaluation</div>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/eval-devguide.html">Eval Dev Guide</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/examples.html">Examples</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/use-case.html">Use Case</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/diagrams.html">Pictorial Docs</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/limitations.html">Limitations</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/user-defined-functions.html">User Defined Functions</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/excelant.html">ExcelAnt Tests</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/hacking-hssf.html">Hacking HSSF</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/record-generator.html">Record Generator</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/spreadsheet/chart.html">Charts</a>
|
|
</div>
|
|
</div>
|
|
<div onclick="SwitchMenu('menu_1.1.4', '../../skin/')" id="menu_1.1.4Title" class="menutitle">PowerPoint (HSLF/XSLF)</div>
|
|
<div id="menu_1.1.4" class="menuitemgroup">
|
|
<div class="menuitem">
|
|
<a href="../../components/slideshow/index.html">Overview</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/slideshow/quick-guide.html">Quick Guide</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/slideshow/how-to-shapes.html">HSLF Cookbook</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/slideshow/xslf-cookbook.html">XSLF Cookbook</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/slideshow/ppt-wmf-emf-renderer.html">Render SL/WMF/EMF</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/slideshow/ppt-file-format.html">PPT File Format</a>
|
|
</div>
|
|
</div>
|
|
<div onclick="SwitchMenu('menu_1.1.5', '../../skin/')" id="menu_1.1.5Title" class="menutitle">Word (HWPF/XWPF)</div>
|
|
<div id="menu_1.1.5" class="menuitemgroup">
|
|
<div class="menuitem">
|
|
<a href="../../components/document/index.html">Overview</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/document/quick-guide.html">HWPF Quick Guide</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/document/quick-guide-xwpf.html">XWPF Quick Guide</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/document/docoverview.html">HWPF Format</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/document/projectplan.html">HWPF Project plan</a>
|
|
</div>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/hsmf/index.html">Outlook (HSMF)</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/diagram/index.html">Visio (HDGF+XDGF)</a>
|
|
</div>
|
|
<div onclick="SwitchMenu('menu_1.1.8', '../../skin/')" id="menu_1.1.8Title" class="menutitle">Publisher (HPBF)</div>
|
|
<div id="menu_1.1.8" class="menuitemgroup">
|
|
<div class="menuitem">
|
|
<a href="../../components/hpbf/index.html">Overview</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/hpbf/file-format.html">File Format</a>
|
|
</div>
|
|
</div>
|
|
<div onclick="SwitchMenu('menu_1.1.9', '../../skin/')" id="menu_1.1.9Title" class="menutitle">OLE2 Filesystem (POIFS)</div>
|
|
<div id="menu_1.1.9" class="menuitemgroup">
|
|
<div class="menuitem">
|
|
<a href="../../components/poifs/index.html">Overview</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/poifs/how-to.html">How To</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/poifs/embeded.html">Embedded Documents</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/poifs/fileformat.html">File System Documentation</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/poifs/usecases.html">Use Cases</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/poifs/design.html">Design</a>
|
|
</div>
|
|
</div>
|
|
<div onclick="SwitchMenu('menu_1.1.10', '../../skin/')" id="menu_1.1.10Title" class="menutitle">OLE2 Document Props (HPSF)</div>
|
|
<div id="menu_1.1.10" class="menuitemgroup">
|
|
<div class="menuitem">
|
|
<a href="../../components/hpsf/index.html">Overview</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/hpsf/how-to.html">How To</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/hpsf/thumbnails.html">Thumbnails</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/hpsf/internals.html">Internals</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/hpsf/todo.html">To Do</a>
|
|
</div>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/hmef/index.html">TNEF (HMEF) for winmail.dat</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/oxml4j/index.html">OpenXML4J (OOXML)</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/logging.html">Logging framework</a>
|
|
</div>
|
|
<div class="menuitem">
|
|
<a href="../../components/configuration.html">Configuration</a>
|
|
</div>
|
|
</div>
|
|
<div id="credit"></div>
|
|
<div id="roundbottom">
|
|
<img style="display: none" class="corner" height="15" width="15" alt="" src="../../skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
|
|
<!--+
|
|
|alternative credits
|
|
+-->
|
|
<div id="credit2">
|
|
<a href="https://donate.apache.org/"><img border="0" title="Support Apache" alt="Support Apache - logo" src="../../images/support-asf.png" style="width: 125px;height: 125px;"></a><a href="https://www.apache.org/foundation/press/kit/#poweredby"><img border="0" title="powered by POI" alt="powered by POI - logo" src="../../images/poweredby-poi-logo.png" style="width: 125px;height: 125px;"></a>
|
|
</div>
|
|
</div>
|
|
<!--+
|
|
|end Menu
|
|
+-->
|
|
<!--+
|
|
|start content
|
|
+-->
|
|
<div id="content">
|
|
<h1>Formula Evaluation</h1>
|
|
<div id="front-matter"></div>
|
|
|
|
<a name="Introduction"></a>
|
|
<h2 class="boxed">Introduction</h2>
|
|
<div class="section">
|
|
<p>The POI formula evaluation code enables you to calculate the result of
|
|
formulas in Excels sheets read-in, or created in POI. This document explains
|
|
how to use the API to evaluate your formulas.
|
|
</p>
|
|
</div>
|
|
|
|
|
|
<a name="WhyEvaluate" id="WhyEvaluate"></a>
|
|
<a name="Why+do+I+need+to+evaluate+formulas%3F"></a>
|
|
<h2 class="boxed">Why do I need to evaluate formulas?</h2>
|
|
<div class="section">
|
|
<p>The Excel file format (both .xls and .xlsx) stores a "cached" result for
|
|
every formula along with the formula itself. This means that when the file
|
|
is opened, it can be quickly displayed, without needing to spend a long
|
|
time calculating all of the formula results. It also means that when reading
|
|
a file through Apache POI, the result is quickly available to you too!
|
|
</p>
|
|
<p>After making changes with Apache POI to either Formula Cells themselves,
|
|
or those that they depend on, you should normally perform a Formula
|
|
Evaluation to have these "cached" results updated. This is normally done
|
|
after all changes have been performed, but before you write the file out.
|
|
If you don't do this, there's a good chance that when you open the file in
|
|
Excel, until you go to the cell and hit enter or F9, you will either see
|
|
the old value or '#VALUE!' for the cell. (Sometimes Excel will notice
|
|
itself, and trigger a recalculation on load, but unless you know you are
|
|
using volatile functions it's generally best to trigger a <a href="#recalculation">Recalulation</a>
|
|
through POI)
|
|
</p>
|
|
</div>
|
|
|
|
|
|
<a name="Status" id="Status"></a>
|
|
<a name="Status-N1002D"></a>
|
|
<h2 class="boxed">Status</h2>
|
|
<div class="section">
|
|
<p>The code currently provides implementations for all the arithmatic operators.
|
|
It also provides implementations for approx. 140 built in
|
|
functions in Excel. The framework however makes it easy to add
|
|
implementation of new functions. See the <a href="eval-devguide.html"> Formula
|
|
evaluation development guide</a> and <a href="../../apidocs/dev/org/apache/poi/hssf/record/formula/functions/package-summary.html">javadocs</a>
|
|
for details. </p>
|
|
<p> Both HSSFWorkbook and XSSFWorkbook are supported, so you can
|
|
evaluate formulas on both .xls and .xlsx files.</p>
|
|
<p> User-defined functions are <a href="user-defined-functions.html">supported</a>,
|
|
but must be rewritten in Java and registered with the macro-enabled workbook in order to be evaluated.
|
|
</p>
|
|
</div>
|
|
|
|
<a name="User+API+How-TO"></a>
|
|
<h2 class="boxed">User API How-TO</h2>
|
|
<div class="section">
|
|
<p>The following code demonstrates how to use the FormulaEvaluator
|
|
in the context of other POI excel reading code.
|
|
</p>
|
|
<p>There are several ways in which you can use the FormulaEvalutator API.</p>
|
|
<a name="Evaluate" id="Evaluate"></a><a name="Using+FormulaEvaluator."></a>
|
|
<h3 class="boxed">Using FormulaEvaluator.evaluate(Cell cell)</h3>
|
|
<p>This evaluates a given cell, and returns the new value,
|
|
without affecting the cell</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FileInputStream fis = new FileInputStream("c:/temp/test.xls");</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("c:/temp/test.xls")</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Sheet sheet = wb.getSheetAt(0);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// suppose your formula is in B3</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">CellReference cellReference = new CellReference("B3"); </span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Row row = sheet.getRow(cellReference.getRow());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Cell cell = row.getCell(cellReference.getCol()); </span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">CellValue cellValue = evaluator.evaluate(cell);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">switch (cellValue.getCellType()) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_BOOLEAN:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cellValue.getBooleanValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_NUMERIC:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cellValue.getNumberValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_STRING:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cellValue.getStringValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_BLANK:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_ERROR:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> // CELL_TYPE_FORMULA will never happen</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_FORMULA: </span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">} </span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
<p>Thus using the retrieved value (of type
|
|
FormulaEvaluator.CellValue - a nested class) returned
|
|
by FormulaEvaluator is similar to using a Cell object
|
|
containing the value of the formula evaluation. CellValue is
|
|
a simple value object and does not maintain reference
|
|
to the original cell.
|
|
</p>
|
|
<a name="EvaluateFormulaCell" id="EvaluateFormulaCell"></a><a name="Using+FormulaEvaluator.-N1014D"></a>
|
|
<h3 class="boxed">Using FormulaEvaluator.evaluateFormulaCell(Cell cell)</h3>
|
|
<p>
|
|
<strong>evaluateFormulaCell</strong>(Cell cell)
|
|
will check to see if the supplied cell is a formula cell.
|
|
If it isn't, then no changes will be made to it. If it is,
|
|
then the formula is evaluated. The value for the formula
|
|
is saved alongside it, to be displayed in excel. The
|
|
formula remains in the cell, just with a new value</p>
|
|
<p>The return of the function is the type of the
|
|
formula result, such as Cell.CELL_TYPE_BOOLEAN</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FileInputStream fis = new FileInputStream("/somepath/test.xls");</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Sheet sheet = wb.getSheetAt(0);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// suppose your formula is in B3</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">CellReference cellReference = new CellReference("B3"); </span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Row row = sheet.getRow(cellReference.getRow());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Cell cell = row.getCell(cellReference.getCol()); </span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">if (cell!=null) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> switch (evaluator.evaluateFormulaCell(cell)) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_BOOLEAN:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cell.getBooleanCellValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_NUMERIC:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cell.getNumericCellValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_STRING:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cell.getStringCellValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_BLANK:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_ERROR:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cell.getErrorCellValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> // CELL_TYPE_FORMULA will never occur</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_FORMULA: </span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> }</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">}</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
<a name="EvaluateInCell" id="EvaluateInCell"></a><a name="Using+FormulaEvaluator.-N1024E"></a>
|
|
<h3 class="boxed">Using FormulaEvaluator.evaluateInCell(Cell cell)</h3>
|
|
<p>
|
|
<strong>evaluateInCell</strong>(Cell cell) will check to
|
|
see if the supplied cell is a formula cell. If it isn't,
|
|
then no changes will be made to it. If it is, then the
|
|
formula is evaluated, and the new value saved into the cell,
|
|
in place of the old formula.</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FileInputStream fis = new FileInputStream("/somepath/test.xls");</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Sheet sheet = wb.getSheetAt(0);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// suppose your formula is in B3</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">CellReference cellReference = new CellReference("B3");</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Row row = sheet.getRow(cellReference.getRow());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Cell cell = row.getCell(cellReference.getCol()); </span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">if (cell!=null) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> switch (evaluator.</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">evaluateInCell</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">(cell).getCellType()) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_BOOLEAN:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cell.getBooleanCellValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_NUMERIC:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cell.getNumericCellValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_STRING:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cell.getStringCellValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_BLANK:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_ERROR:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> System.out.println(cell.getErrorCellValue());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> // CELL_TYPE_FORMULA will never occur</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> case Cell.CELL_TYPE_FORMULA:</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> break;</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> }</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">}</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
<a name="EvaluateAll" id="EvaluateAll"></a><a name="Re-calculating+all+formulas+in+a+Workbook"></a>
|
|
<h3 class="boxed">Re-calculating all formulas in a Workbook</h3>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FileInputStream fis = new FileInputStream("/somepath/test.xls");</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">for (Sheet sheet : wb) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> for (Row r : sheet) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> for (Cell c : r) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> if (c.getCellType() == Cell.CELL_TYPE_FORMULA) {</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> evaluator.evaluateFormulaCell(c);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> }</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> }</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> }</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">}</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
<p>Alternately, if you know which of HSSF or XSSF you're working
|
|
with, then you can call the static
|
|
<strong>evaluateAllFormulaCells</strong> method on the appropriate
|
|
HSSFFormulaEvaluator or XSSFFormulaEvaluator class.</p>
|
|
</div>
|
|
|
|
|
|
<a name="recalculation" id="recalculation"></a>
|
|
<a name="Recalculation+of+Formulas"></a>
|
|
<h2 class="boxed">Recalculation of Formulas</h2>
|
|
<div class="section">
|
|
<p>
|
|
In certain cases you may want to force Excel to re-calculate formulas when the workbook is opened.
|
|
Consider the following example:
|
|
</p>
|
|
<p>
|
|
Open Excel and create a new workbook. On the first sheet set A1=1, B1=1, C1=A1+B1.
|
|
Excel automatically calculates formulas and the value in C1 is 2. So far so good.
|
|
</p>
|
|
<p>
|
|
Now modify the workbook with POI:
|
|
</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Workbook wb = WorkbookFactory.create(new FileInputStream("workbook.xls"));</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Sheet sh = wb.getSheetAt(0);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">sh.getRow(0).getCell(0).setCellValue(2); // set A1=2</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FileOutputStream out = new FileOutputStream("workbook2.xls");</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">wb.write(out);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">out.close();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
<p>
|
|
Now open workbook2.xls in Excel and the value in C1 is still 2 while you expected 3. Wrong? No!
|
|
The point is that Excel caches previously calculated results and you need to trigger recalculation to updated them.
|
|
It is not an issue when you are creating new workbooks from scratch, but important to remember when you are modifing
|
|
existing workbooks with formulas. This can be done in two ways:
|
|
</p>
|
|
<p>
|
|
1. Re-evaluate formulas with POI's FormulaEvaluator:
|
|
</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Workbook wb = WorkbookFactory.create(new FileInputStream("workbook.xls"));</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Sheet sh = wb.getSheetAt(0);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">sh.getRow(0).getCell(0).setCellValue(2); // set A1=2</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">wb.getCreationHelper().createFormulaEvaluator().evaluateAll();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
<p>
|
|
2. Delegate re-calculation to Excel. The application will perform a full recalculation when the workbook is opened:
|
|
</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Workbook wb = WorkbookFactory.create(new FileInputStream("workbook.xls"));</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Sheet sh = wb.getSheetAt(0);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">sh.getRow(0).getCell(0).setCellValue(2); // set A1=2</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">wb.setForceFormulaRecalculation(true);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<a name="external" id="external"></a>
|
|
<a name="External+%28Cross-Workbook%29+references"></a>
|
|
<h2 class="boxed">External (Cross-Workbook) references</h2>
|
|
<div class="section">
|
|
<p>It is possible for a formula in an Excel spreadsheet to
|
|
refer to a Named Range or Cell in a different workbook.
|
|
These cross-workbook references are normally called <em>External
|
|
References</em>. These are formulas which look something like:</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">=SUM([Finances.xlsx]Numbers!D10:D25)</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">=SUM('C:\Data\[Finances.xlsx]Numbers'!D10:D25)</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">=SUM([Finances.xlsx]Range20)</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
<p>If you don't have access to these other workbooks, then you
|
|
should call
|
|
<a href="../../apidocs/dev/org/apache/poi/ss/usermodel/FormulaEvaluator.html#setIgnoreMissingWorkbooks(boolean)">setIgnoreMissingWorkbooks(true)</a>
|
|
to tell the Formula Evaluator to skip evaluating any external
|
|
references it can't look up.</p>
|
|
<p>In order for POI to be able to evaluate external references, it
|
|
needs access to the workbooks in question. As these don't necessarily
|
|
have the same names on your system as in the workbook, you need to
|
|
give POI a map of external references to open workbooks, through
|
|
the
|
|
<a href="../../apidocs/dev/org/apache/poi/ss/usermodel/FormulaEvaluator.html#setupReferencedWorkbooks(java.util.Map)">setupReferencedWorkbooks(java.util.Map<java.lang.String,FormulaEvaluator> workbooks)</a>
|
|
method. You should normally do something like:</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// Create a FormulaEvaluator to use</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">FormulaEvaluator mainWorkbookEvaluator = workbook.getCreationHelper().createFormulaEvaluator();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// Track the workbook references</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Map<String,FormulaEvaluator> workbooks = new HashMap<String, FormulaEvaluator>();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// Add this workbook</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">workbooks.put("report.xlsx", mainWorkbookEvaluator);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// Add two others</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">workbooks.put("input.xls", WorkbookFactory.create("C:\\temp\\input22.xls").getCreationHelper().createFormulaEvaluator());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">workbooks.put("lookups.xlsx", WorkbookFactory.create("/home/poi/data/tmp-lookups.xlsx").getCreationHelper().createFormulaEvaluator());</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// Attach them</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">mainWorkbookEvaluator.setupReferencedWorkbooks(workbooks);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// Evaluate</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">mainWorkbookEvaluator.evaluateAll();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<a name="Performance" id="Performance"></a>
|
|
<a name="Performance+Notes"></a>
|
|
<h2 class="boxed">Performance Notes</h2>
|
|
<div class="section">
|
|
<ul>
|
|
|
|
<li>Generally you should have to create only one FormulaEvaluator
|
|
instance per Workbook. The FormulaEvaluator will cache
|
|
evaluations of dependent cells, so if you have multiple
|
|
formulas all depending on a cell then subsequent evaluations
|
|
will be faster.
|
|
</li>
|
|
|
|
<li>You should normally perform all of your updates to cells,
|
|
before triggering the evaluation, rather than doing one
|
|
cell at a time. By waiting until all the updates/sets are
|
|
performed, you'll be able to take best advantage of the caching
|
|
for complex formulas.
|
|
</li>
|
|
|
|
<li>If you do end up making changes to cells part way through
|
|
evaluation, you should call <em>notifySetFormula</em> or
|
|
<em>notifyUpdateCell</em> to trigger suitable cache clearance.
|
|
Alternately, you could instantiate a new FormulaEvaluator,
|
|
which will start with empty caches.
|
|
</li>
|
|
|
|
<li>Also note that FormulaEvaluator maintains a reference to
|
|
the sheet and workbook, so ensure that the evaluator instance
|
|
is available for garbage collection when you are done with it
|
|
(in other words don't maintain long lived reference to
|
|
FormulaEvaluator if you don't really need to - unless
|
|
all references to the sheet and workbook are removed, these
|
|
don't get garbage collected and continue to occupy potentially
|
|
large amounts of memory).
|
|
</li>
|
|
|
|
<li>CellValue instances however do not maintain reference to the
|
|
Cell or the sheet or workbook, so these can be long-lived
|
|
objects without any adverse effect on performance.
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
<a name="Formula+Evaluation+Debugging"></a>
|
|
<h2 class="boxed">Formula Evaluation Debugging</h2>
|
|
<div class="section">
|
|
<p>POI is not perfect and you may stumble across formula evaluation problems (Java exceptions
|
|
or just different results) in your special use case. To support an easy detailed analysis, a special
|
|
logging of the full evaluation is provided.</p>
|
|
<p>POI 5.1.0 and above uses <a href="https://logging.apache.org/log4j/2.x/">Log4J 2.x</a> as a logging framework. Try to set up a logging
|
|
configuration that lets you see the info and other log messages.</p>
|
|
<p>Example use:</p>
|
|
<div class="code">
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// open your file</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Workbook wb = new HSSFWorkbook(new FileInputStream("foobar.xls"));</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// get your cell</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">Cell cell = wb.getSheet(0).getRow(0).getCell(0); // just a dummy example</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"></span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">// perform debug output for the next evaluate-call only</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> evaluator.setDebugEvaluationOutputForNextEval(true);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">evaluator.evaluateFormulaCell(cell);</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody">evaluator.evaluateFormulaCell(cell); // no logging performed for this next evaluate-call</span>
|
|
</div>
|
|
<div class="codeline">
|
|
<span class="lineno"></span><span class="codebody"> </span>
|
|
</div>
|
|
</div>
|
|
<p>The special Logger called "POI.FormulaEval" is used (useful if you use the CommonsLogger and a detailed logging configuration).
|
|
The used log levels are WARN and INFO (for detailed parameter info and results) - the level are so high to allow this
|
|
special logging without being disturbed by the bunch of DEBUG log entries from other classes.</p>
|
|
</div>
|
|
|
|
|
|
<a name="sxssf" id="sxssf"></a>
|
|
<a name="Formula+Evaluation+and+SXSSF"></a>
|
|
<h2 class="boxed">Formula Evaluation and SXSSF</h2>
|
|
<div class="section">
|
|
<p>For versions before 3.13 final, no formula evaluation is possible with
|
|
SXSSF.</p>
|
|
<p>If you are using POI 3.13 final or newer, formula evaluation is possible with SXSSF,
|
|
but with some caveats.</p>
|
|
<p>The biggest restriction is that, since evaluating a cell needs that cell in memory
|
|
and any others it depends on, only pure-function formulas and formulas referencing
|
|
nearby cells can be evaluated with SXSSF. If a formula references a cell that hasn't
|
|
yet been written, or one which has already been flushed to disk, then it won't be
|
|
possible to evaluate it.</p>
|
|
<p>Because of this, a call to <em>wb.getCreationHelper().createFormulaEvaluator().evaluateAll();</em>
|
|
will very rarely work on SXSSF, as it's very rare that all the cells wil be available
|
|
and in memory at any time! Instead, it is suggested to evaluate formula cells just
|
|
after writing them, or shortly after when cells they depend on are added. Just make
|
|
sure that all cells needing or needed for evaluation are inside the window.</p>
|
|
</div>
|
|
|
|
</div>
|
|
<!--+
|
|
|end content
|
|
+-->
|
|
<div class="clearboth"> </div>
|
|
</div>
|
|
<div id="footer">
|
|
<!--+
|
|
|start bottomstrip
|
|
+-->
|
|
<div class="lastmodified">
|
|
<script type="text/javascript"><!--
|
|
document.write("Last Published: " + document.lastModified);
|
|
// --></script>
|
|
</div>
|
|
<div class="copyright">
|
|
Copyright ©
|
|
2001-2025 <a href="https://www.apache.org/">The Apache Software Foundation</a>
|
|
<br>
|
|
Apache POI, POI, Apache, the Apache logo, and the Apache
|
|
POI project logo are trademarks of The Apache Software Foundation.
|
|
</div>
|
|
<div id="feedback">
|
|
Send feedback about the website to:
|
|
<a id="feedbackto" href="mailto:dev@poi.apache.org?subject=Feedback%C2%A0components/spreadsheet/eval.html">dev@poi.apache.org</a>
|
|
</div>
|
|
<!--+
|
|
|end bottomstrip
|
|
+-->
|
|
</div>
|
|
</body>
|
|
</html>
|