2026-02-16 20:14:18 +01:00

2075 lines
86 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>The New Halloween Document</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> &gt; <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 &ndash; 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">&nbsp;
<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">
&nbsp;
</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="menupage">
<div class="menupagetitle">HOWTO</div>
</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="menuitem">
<a href="../../components/spreadsheet/eval.html">Formula Evaluation</a>
</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>The New Halloween Document</h1>
<div id="front-matter"></div>
<a name="How+to+use+the+HSSF+API"></a>
<h2 class="boxed">How to use the HSSF API</h2>
<div class="section">
<a name="Capabilities"></a>
<h3 class="boxed">Capabilities</h3>
<p>This release of the how-to outlines functionality for the
current svn trunk.
Those looking for information on previous releases should
look in the documentation distributed with that release.</p>
<p>
HSSF allows numeric, string, date or formula cell values to be written to
or read from an XLS file. Also
in this release is row and column sizing, cell styling (bold,
italics, borders,etc), and support for both built-in and user
defined data formats. Also available is
an event-based API for reading XLS files.
It differs greatly from the read/write API
and is intended for intermediate developers who need a smaller
memory footprint.
</p>
<a name="Different+APIs"></a>
<h3 class="boxed">Different APIs</h3>
<p>There are a few different ways to access the HSSF API. These
have different characteristics, so you should read up on
all to select the best for you.</p>
<ul>
<li>
<a href="#user_api">User API (HSSF and XSSF)</a>
</li>
<li>
<a href="#event_api">Event API (HSSF Only)</a>
</li>
<li>
<a href="#record_aware_event_api">Event API with extensions to be Record Aware (HSSF Only)</a>
</li>
<li>
<a href="#xssf_sax_api">XSSF and SAX (Event API)</a>
</li>
<li>
<a href="#sxssf">SXSSF (Streaming User API)</a>
</li>
<li>
<a href="#low_level_api">Low Level API</a>
</li>
</ul>
</div>
<a name="General+Use"></a>
<h2 class="boxed">General Use</h2>
<div class="section">
<a name="user_api" id="user_api"></a><a name="User+API+%28HSSF+and+XSSF%29"></a>
<h3 class="boxed">User API (HSSF and XSSF)</h3>
<a name="Writing+a+new+file"></a>
<h4>Writing a new file</h4>
<p>The high level API (package: org.apache.poi.ss.usermodel)
is what most people should use. Usage is very simple.
</p>
<p>Workbooks are created by creating an instance of
org.apache.poi.ss.usermodel.Workbook. Either create
a concrete class directly
(org.apache.poi.hssf.usermodel.HSSFWorkbook or
org.apache.poi.xssf.usermodel.XSSFWorkbook), or use
the handy factory class
org.apache.poi.ss.usermodel.WorkbookFactory.
</p>
<p>Sheets are created by calling createSheet() from an existing
instance of Workbook, the created sheet is automatically added in
sequence to the workbook. Sheets do not in themselves have a sheet
name (the tab at the bottom); you set
the name associated with a sheet by calling
Workbook.setSheetName(sheetindex,"SheetName",encoding).
For HSSF, the name may be in 8bit format
(HSSFWorkbook.ENCODING_COMPRESSED_UNICODE)
or Unicode (HSSFWorkbook.ENCODING_UTF_16). Default
encoding for HSSF is 8bit per char. For XSSF, the name
is automatically handled as unicode.
</p>
<p>Rows are created by calling createRow(rowNumber) from an existing
instance of Sheet. Only rows that have cell values should be
added to the sheet. To set the row's height, you just call
setRowHeight(height) on the row object. The height must be given in
twips, or 1/20th of a point. If you prefer, there is also a
setRowHeightInPoints method.
</p>
<p>Cells are created by calling createCell(column, type) from an
existing Row. Only cells that have values should be added to the
row. Cells should have their cell type set to either
Cell.CELL_TYPE_NUMERIC or Cell.CELL_TYPE_STRING depending on
whether they contain a numeric or textual value. Cells must also have
a value set. Set the value by calling setCellValue with either a
String or double as a parameter. Individual cells do not have a
width; you must call setColumnWidth(colindex, width) (use units of
1/256th of a character) on the Sheet object. (You can't do it on
an individual basis in the GUI either).</p>
<p>Cells are styled with CellStyle objects which in turn contain
a reference to an Font object. These are created via the
Workbook object by calling createCellStyle() and createFont().
Once you create the object you must set its parameters (colors,
borders, etc). To set a font for an CellStyle call
setFont(fontobj).
</p>
<p>Once you have generated your workbook, you can write it out by
calling write(outputStream) from your instance of Workbook, passing
it an OutputStream (for instance, a FileOutputStream or
ServletOutputStream). You must close the OutputStream yourself. HSSF
does not close it for you.
</p>
<p>Here is some example code (excerpted and adapted from
org.apache.poi.hssf.dev.HSSF test class):</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">short rownum;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// create a new file</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">FileOutputStream out = new FileOutputStream("workbook.xls");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// create a new workbook</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">Workbook wb = new HSSFWorkbook();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// create a new sheet</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">Sheet s = wb.createSheet();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// declare a row object reference</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">Row r = null;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// declare a cell object reference</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">Cell c = null;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// create 3 cell styles</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">CellStyle cs = wb.createCellStyle();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">CellStyle cs2 = wb.createCellStyle();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">CellStyle cs3 = wb.createCellStyle();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">DataFormat df = wb.createDataFormat();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// create 2 fonts objects</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">Font f = wb.createFont();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">Font f2 = wb.createFont();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//set font 1 to 12 point type</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">f.setFontHeightInPoints((short) 12);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//make it blue</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">f.setColor( (short)0xc );</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// make it bold</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//arial is the default font</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">f.setBoldweight(Font.BOLDWEIGHT_BOLD);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//set font 2 to 10 point type</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">f2.setFontHeightInPoints((short) 10);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//make it red</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">f2.setColor( (short)Font.COLOR_RED );</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//make it bold</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">f2.setBoldweight(Font.BOLDWEIGHT_BOLD);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">f2.setStrikeout( true );</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//set cell stlye</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">cs.setFont(f);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//set the cell format</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">cs.setDataFormat(df.getFormat("#,##0.0"));</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//set a thin border</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">cs2.setBorderBottom(cs2.BORDER_THIN);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//fill w fg fill color</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">cs2.setFillPattern((short) CellStyle.SOLID_FOREGROUND);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//set the cell format to text see DataFormat for a full list</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">cs2.setDataFormat(HSSFDataFormat.getBuiltinFormat("text"));</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// set the font</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">cs2.setFont(f2);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// set the sheet name in Unicode</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">wb.setSheetName(0, "\u0422\u0435\u0441\u0442\u043E\u0432\u0430\u044F " +</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> "\u0421\u0442\u0440\u0430\u043D\u0438\u0447\u043A\u0430" );</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// in case of plain ascii</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// wb.setSheetName(0, "HSSF Test");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// create a sheet with 30 rows (0-29)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">int rownum;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">for (rownum = (short) 0; rownum &lt; 30; rownum++)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">{</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // create a row</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> r = s.createRow(rownum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // on every other row</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> if ((rownum % 2) == 0)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // make the row height bigger (in twips - 1/20 of a point)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> r.setHeight((short) 0x249);</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"> //r.setRowNum(( short ) rownum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // create 10 cells (0-9) (the += 2 becomes apparent later</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> for (short cellnum = (short) 0; cellnum &lt; 10; cellnum += 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"> // create a numeric cell</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c = r.createCell(cellnum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // do some goofy math to demonstrate decimals</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c.setCellValue(rownum * 10000 + cellnum</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> + (((double) rownum / 1000)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> + ((double) cellnum / 10000)));</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> String cellValue;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // create a string cell (see why += 2 in the</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c = r.createCell((short) (cellnum + 1));</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // on every other row</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> if ((rownum % 2) == 0)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // set this cell to the first cell style we defined</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c.setCellStyle(cs);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // set the cell's string value to "Test"</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c.setCellValue( "Test" );</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> }</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> else</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c.setCellStyle(cs2);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // set the cell's string value to "\u0422\u0435\u0441\u0442"</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c.setCellValue( "\u0422\u0435\u0441\u0442" );</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"> // make this column a bit wider</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> s.setColumnWidth((short) (cellnum + 1), (short) ((50 * 8) / ((double) 1 / 20)));</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">//draw a thick black border on the row at the bottom using BLANKS</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// advance 2 rows</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">rownum++;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">rownum++;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">r = s.createRow(rownum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// define the third style to be the default</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// except with a thick black border at the bottom</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">cs3.setBorderBottom(cs3.BORDER_THICK);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//create 50 cells</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">for (short cellnum = (short) 0; cellnum &lt; 50; cellnum++)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">{</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> //create a blank type cell (no value)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c = r.createCell(cellnum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // set it to the thick black border style</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> c.setCellStyle(cs3);</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">//end draw thick black border</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">// demonstrate adding/naming and deleting a sheet</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// create a sheet, set its title then delete it</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">s = wb.createSheet();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">wb.setSheetName(1, "DeletedSheet");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">wb.removeSheetAt(1);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">//end deleted sheet</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// write the workbook to the output stream</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">// close our file (don't blow out our file handles</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>
<a name="Reading+or+modifying+an+existing+file"></a>
<h4>Reading or modifying an existing file</h4>
<p>Reading in a file is equally simple. To read in a file, create a
new instance of org.apache.poi.poifs.Filesystem, passing in an open InputStream, such as a FileInputStream
for your XLS, to the constructor. Construct a new instance of
org.apache.poi.hssf.usermodel.HSSFWorkbook passing the
Filesystem instance to the constructor. From there you have access to
all of the high level model objects through their assessor methods
(workbook.getSheet(sheetNum), sheet.getRow(rownum), etc).
</p>
<p>Modifying the file you have read in is simple. You retrieve the
object via an assessor method, remove it via a parent object's remove
method (sheet.removeRow(hssfrow)) and create objects just as you
would if creating a new xls. When you are done modifying cells just
call workbook.write(outputstream) just as you did above.</p>
<p>An example of this can be seen in
<a href="https://github.com/apache/poi/tree/trunk/poi-examples/src/main/java/org/apache/poi/examples/hssf/usermodel/HSSFReadWrite.java">org.apache.poi.hssf.usermodel.examples.HSSFReadWrite</a>.</p>
<a name="event_api" id="event_api"></a><a name="Event+API+%28HSSF+Only%29"></a>
<h3 class="boxed">Event API (HSSF Only)</h3>
<p>The event API is newer than the User API. It is intended for intermediate
developers who are willing to learn a little bit of the low level API
structures. Its relatively simple to use, but requires a basic
understanding of the parts of an Excel file (or willingness to
learn). The advantage provided is that you can read an XLS with a
relatively small memory footprint.
</p>
<p>One important thing to note with the basic Event API is that it
triggers events only for things actually stored within the file.
With the XLS file format, it is quite common for things that
have yet to be edited to simply not exist in the file. This means
there may well be apparent "gaps" in the record stream, which
you either need to work around, or use the
<a href="#record_aware_event_api">Record Aware</a> extension
to the Event API.</p>
<p>To use this API you construct an instance of
org.apache.poi.hssf.eventmodel.HSSFRequest. Register a class you
create that supports the
org.apache.poi.hssf.eventmodel.HSSFListener interface using the
HSSFRequest.addListener(yourlistener, recordsid). The recordsid
should be a static reference number (such as BOFRecord.sid) contained
in the classes in org.apache.poi.hssf.record. The trick is you
have to know what these records are. Alternatively you can call
HSSFRequest.addListenerForAllRecords(mylistener). In order to learn
about these records you can either read all of the javadoc in the
org.apache.poi.hssf.record package or you can just hack up a
copy of org.apache.poi.hssf.dev.EFHSSF and adapt it to your
needs. TODO: better documentation on records.</p>
<p>Once you've registered your listeners in the HSSFRequest object
you can construct an instance of
org.apache.poi.poifs.filesystem.FileSystem (see POIFS howto) and
pass it your XLS file inputstream. You can either pass this, along
with the request you constructed, to an instance of HSSFEventFactory
via the HSSFEventFactory.processWorkbookEvents(request, Filesystem)
method, or you can get an instance of DocumentInputStream from
Filesystem.createDocumentInputStream("Workbook") and pass
it to HSSFEventFactory.processEvents(request, inputStream). Once you
make this call, the listeners that you constructed receive calls to
their processRecord(Record) methods with each Record they are
registered to listen for until the file has been completely read.
</p>
<p>A code excerpt from org.apache.poi.hssf.dev.EFHSSF (which is
in CVS or the source distribution) is reprinted below with excessive
comments:</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">/**</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> * This example shows how to use the event API for reading a file.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> */</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">public class EventExample</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> implements HSSFListener</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">{</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> private SSTRecord sstrec;</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"> * This method listens for incoming records and handles them as required.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> * @param record The record that was found while reading.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> */</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> public void processRecord(Record record)</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 (record.getSid())</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // the BOFRecord can represent either the beginning of a sheet or the workbook</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> case BOFRecord.sid:</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> BOFRecord bof = (BOFRecord) record;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> if (bof.getType() == bof.TYPE_WORKBOOK)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("Encountered workbook");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // assigned to the class level member</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> } else if (bof.getType() == bof.TYPE_WORKSHEET)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("Encountered sheet reference");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> }</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 BoundSheetRecord.sid:</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> BoundSheetRecord bsr = (BoundSheetRecord) record;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("New sheet named: " + bsr.getSheetname());</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 RowRecord.sid:</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> RowRecord rowrec = (RowRecord) record;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("Row found, first column at "</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> + rowrec.getFirstCol() + " last column at " + rowrec.getLastCol());</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 NumberRecord.sid:</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> NumberRecord numrec = (NumberRecord) record;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("Cell found with value " + numrec.getValue()</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> + " at row " + numrec.getRow() + " and column " + numrec.getColumn());</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"> // SSTRecords store an array of unique strings used in Excel.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> case SSTRecord.sid:</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> sstrec = (SSTRecord) record;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> for (int k = 0; k &lt; sstrec.getNumUniqueStrings(); k++)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("String table value " + k + " = " + sstrec.getString(k));</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> }</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 LabelSSTRecord.sid:</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> LabelSSTRecord lrec = (LabelSSTRecord) record;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("String cell found with value "</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> + sstrec.getString(lrec.getSSTIndex()));</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 class="codeline">
<span class="lineno"></span><span class="codebody"> * Read an excel file and spit out what we find.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> *</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> * @param args Expect one argument that is the file to read.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> * @throws IOException When there is an error processing the file.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> */</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> public static void main(String[] args) throws IOException</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // create a new file input stream with the input file specified</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // at the command line</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> FileInputStream fin = new FileInputStream(args[0]);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // create a new org.apache.poi.poifs.filesystem.Filesystem</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> POIFSFileSystem poifs = new POIFSFileSystem(fin);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // get the Workbook (excel part) stream in a InputStream</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> InputStream din = poifs.createDocumentInputStream("Workbook");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // construct out HSSFRequest object</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> HSSFRequest req = new HSSFRequest();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // lazy listen for ALL records with the listener shown above</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> req.addListenerForAllRecords(new EventExample());</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // create our event factory</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> HSSFEventFactory factory = new HSSFEventFactory();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // process our events based on the document input stream</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> factory.processEvents(req, din);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // once all the events are processed close our file input stream</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> fin.close();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // and our document input stream (don't want to leak these!)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> din.close();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("done.");</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="record_aware_event_api" id="record_aware_event_api"></a><a name="Record+Aware+Event+API+%28HSSF+Only%29"></a>
<h3 class="boxed">Record Aware Event API (HSSF Only)</h3>
<p>
This is an extension to the normal
<a href="#event_api">Event API</a>. With this, your listener
will be called with extra, dummy records. These dummy records should
alert you to records which aren't present in the file (eg cells that have
yet to be edited), and allow you to handle these.
</p>
<p>
There are three dummy records that your HSSFListener will be called with:
</p>
<ul>
<li>org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord
<br>
This is called during the row record phase (which typically occurs before
the cell records), and indicates that the row record for the given
row is not present in the file.</li>
<li>org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord
<br>
This is called during the cell record phase. It is called when a cell
record is encountered which leaves a gap between it an the previous one.
You can get multiple of these, before the real cell record.</li>
<li>org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord
<br>
This is called after the last cell of a given row. It indicates that there
are no more cells for the row, and also tells you how many cells you have
had. For a row with no cells, this will be the only record you get.</li>
</ul>
<p>
To use the Record Aware Event API, you should create an
org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener, and pass
it your HSSFListener. Then, register the MissingRecordAwareHSSFListener
to the event model, and start that as normal.
</p>
<p>
One example use for this API is to write a CSV outputter, which always
outputs a minimum number of columns, even where the file doesn't contain
some of the rows or cells. It can be found at
<span class="codefrag">/poi-examples/src/main/java/org/apache/poi/examples/hssf/eventusermodel/XLS2CSVmra.java</span>,
and may be called on the command line, or from within your own code.
The latest version is always available from
<a href="https://github.com/apache/poi/tree/trunk/poi-examples/src/main/java/org/apache/poi/examples/hssf/eventusermodel/">git</a>.
</p>
<p>
<em>In POI versions before 3.0.3, this code lived in the scratchpad section.
If you're using one of these older versions of POI, you will either
need to include the scratchpad jar on your classpath, or build from a</em>
<a href="../../devel/git.html">git checkout</a>.
</p>
<a name="xssf_sax_api" id="xssf_sax_api"></a><a name="XSSF+and+SAX+%28Event+API%29"></a>
<h3 class="boxed">XSSF and SAX (Event API)</h3>
<p>If memory footprint is an issue, then for XSSF, you can get at
the underlying XML data, and process it yourself. This is intended
for intermediate developers who are willing to learn a little bit of
low level structure of .xlsx files, and who are happy processing
XML in java. Its relatively simple to use, but requires a basic
understanding of the file structure. The advantage provided is that
you can read a XLSX file with a relatively small memory footprint.
</p>
<p>One important thing to note with the basic Event API is that it
triggers events only for things actually stored within the file.
With the XLSX file format, it is quite common for things that
have yet to be edited to simply not exist in the file. This means
there may well be apparent "gaps" in the record stream, which
you need to work around.</p>
<p>To use this API you construct an instance of
org.apache.poi.xssf.eventmodel.XSSFReader. This will optionally
provide a nice interface on the shared strings table, and the styles.
It provides methods to get the raw xml data from the rest of the
file, which you will then pass to SAX.</p>
<p>This example shows how to get at a single known sheet, or at
all sheets in the file. It is based on the example in
<a href="https://github.com/apache/poi/tree/trunk/poi-examples/src/main/java/org/apache/poi/examples/xssf/eventusermodel/FromHowTo.java">svn
poi-examples/src/main/java/org/apache/poi/examples/xssf/eventusermodel/FromHowTo.java</a>
</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">import java.io.InputStream;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import java.util.Iterator;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.util.XMLHelper;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.openxml4j.opc.OPCPackage;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.xssf.eventusermodel.XSSFReader;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.xssf.model.SharedStringsTable;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.xml.sax.Attributes;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.xml.sax.ContentHandler;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.xml.sax.InputSource;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.xml.sax.SAXException;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.xml.sax.XMLReader;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.xml.sax.helpers.DefaultHandler;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import javax.xml.parsers.ParserConfigurationException;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">public class ExampleEventUserModel {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> public void processOneSheet(String filename) throws Exception {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> OPCPackage pkg = OPCPackage.open(filename);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> XSSFReader r = new XSSFReader( pkg );</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> SharedStringsTable sst = r.getSharedStringsTable();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> XMLReader parser = fetchSheetParser(sst);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // To look up the Sheet Name / Sheet Order / rID,</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // you need to process the core Workbook stream.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // Normally it's of the form rId# or rSheet#</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> InputStream sheet2 = r.getSheet("rId2");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> InputSource sheetSource = new InputSource(sheet2);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> parser.parse(sheetSource);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> sheet2.close();</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"> public void processAllSheets(String filename) throws Exception {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> OPCPackage pkg = OPCPackage.open(filename);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> XSSFReader r = new XSSFReader( pkg );</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> SharedStringsTable sst = r.getSharedStringsTable();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> XMLReader parser = fetchSheetParser(sst);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Iterator&lt;InputStream&gt; sheets = r.getSheetsData();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> while(sheets.hasNext()) {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("Processing new sheet:\n");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> InputStream sheet = sheets.next();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> InputSource sheetSource = new InputSource(sheet);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> parser.parse(sheetSource);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> sheet.close();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println("");</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"> public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException, ParserConfigurationException {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> XMLReader parser = XMLHelper.newXMLReader();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> ContentHandler handler = new SheetHandler(sst);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> parser.setContentHandler(handler);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> return parser;</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"> * See org.xml.sax.helpers.DefaultHandler javadocs</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> */</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> private static class SheetHandler extends DefaultHandler {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> private SharedStringsTable sst;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> private String lastContents;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> private boolean nextIsString;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> private SheetHandler(SharedStringsTable sst) {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> this.sst = sst;</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"> public void startElement(String uri, String localName, String name,</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Attributes attributes) throws SAXException {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // c =&gt; cell</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> if(name.equals("c")) {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // Print the cell reference</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.print(attributes.getValue("r") + " - ");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // Figure out if the value is an index in the SST</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> String cellType = attributes.getValue("t");</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> if(cellType != null &amp;&amp; cellType.equals("s")) {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> nextIsString = true;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> } else {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> nextIsString = false;</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"> // Clear contents cache</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> lastContents = "";</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"> public void endElement(String uri, String localName, String name)</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> throws SAXException {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // Process the last contents as required.</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // Do now, as characters() may be called more than once</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> if(nextIsString) {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> int idx = Integer.parseInt(lastContents);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> lastContents = sst.getItemAt(idx).getString();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> nextIsString = false;</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"> // v =&gt; contents of a cell</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // Output after we've seen the string contents</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> if(name.equals("v")) {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> System.out.println(lastContents);</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"> public void characters(char[] ch, int start, int length) {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> lastContents += new String(ch, start, length);</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"> public static void main(String[] args) throws Exception {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> ExampleEventUserModel example = new ExampleEventUserModel();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> example.processOneSheet(args[0]);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> example.processAllSheets(args[0]);</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>
For a fuller example, including support for fetching number formatting
information and applying it to numeric cells (eg to format dates or
percentages), please see
<a href="https://github.com/apache/poi/tree/trunk/poi-examples/src/main/java/org/apache/poi/examples/xssf/eventusermodel/XLSX2CSV.java">the XLSX2CSV example in svn</a>
</p>
<p>An example is also <a href="https://github.com/apache/poi/tree/trunk/poi-examples/src/main/java/org/apache/poi/examples/xssf/streaming/HybridStreaming.java">provided</a>
showing how to combine the user API and the SAX API by doing a streaming parse
of larger worksheets and a traditional user-model parse of the rest of a workbook.</p>
<a name="sxssf" id="sxssf"></a><a name="SXSSF+%28Streaming+Usermodel+API%29"></a>
<h3 class="boxed">SXSSF (Streaming Usermodel API)</h3>
<p>
SXSSF (package: org.apache.poi.xssf.streaming) is an API-compatible streaming extension of XSSF to be used when
very large spreadsheets have to be produced, and heap space is limited.
SXSSF achieves its low memory footprint by limiting access to the rows that
are within a sliding window, while XSSF gives access to all rows in the
document. Older rows that are no longer in the window become inaccessible,
as they are written to the disk.
</p>
<p>
You can specify the window size at workbook construction time via <em>new SXSSFWorkbook(int windowSize)</em>
or you can set it per-sheet via <em>SXSSFSheet#setRandomAccessWindowSize(int windowSize)</em>
</p>
<p>
When a new row is created via createRow() and the total number
of unflushed records would exceed the specified window size, then the
row with the lowest index value is flushed and cannot be accessed
via getRow() anymore.
</p>
<p>
The default window size is <em>100</em> and defined by SXSSFWorkbook.DEFAULT_WINDOW_SIZE.
</p>
<p>
A windowSize of -1 indicates unlimited access. In this case all
records that have not been flushed by a call to flushRows() are available
for random access.
</p>
<p>
Note that SXSSF allocates temporary files that you <strong>must</strong> always clean up explicitly, by calling the dispose method.
</p>
<p>
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.
</p>
<p>
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,
hyperlinks, comments, ... are still only stored in memory and thus may require a lot of
memory if used extensively.
</p>
<p>
Carefully review your memory budget and compatibility needs before deciding
whether to enable shared strings or not.
</p>
<p> The example below writes a sheet with a window of 100 rows. When the row count reaches 101,
the row with rownum=0 is flushed to disk and removed from memory, when rownum reaches 102 then the row with rownum=1 is flushed, etc.
</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">import junit.framework.Assert;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.usermodel.Cell;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.usermodel.Row;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.usermodel.Sheet;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.usermodel.Workbook;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.util.CellReference;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.xssf.streaming.SXSSFWorkbook;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> public static void main(String[] args) throws Throwable {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Sheet sh = wb.createSheet();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> for(int rownum = 0; rownum &lt; 1000; rownum++){</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Row row = sh.createRow(rownum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> for(int cellnum = 0; cellnum &lt; 10; cellnum++){</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Cell cell = row.createCell(cellnum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> String address = new CellReference(cell).formatAsString();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> cell.setCellValue(address);</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"> // Rows with rownum &lt; 900 are flushed and not accessible</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> for(int rownum = 0; rownum &lt; 900; rownum++){</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Assert.assertNull(sh.getRow(rownum));</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"> // ther last 100 rows are still in memory</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> for(int rownum = 900; rownum &lt; 1000; rownum++){</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Assert.assertNotNull(sh.getRow(rownum));</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"> FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");</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 class="codeline">
<span class="lineno"></span><span class="codebody"> // dispose of temporary files backing this workbook on disk</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> wb.dispose();</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>The next example turns off auto-flushing (windowSize=-1) and the code manually controls how portions of data are written to disk</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">import org.apache.poi.ss.usermodel.Cell;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.usermodel.Row;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.usermodel.Sheet;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.usermodel.Workbook;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.ss.util.CellReference;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">import org.apache.poi.xssf.streaming.SXSSFWorkbook;</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> public static void main(String[] args) throws Throwable {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> SXSSFWorkbook wb = new SXSSFWorkbook(-1); // turn off auto-flushing and accumulate all rows in memory</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Sheet sh = wb.createSheet();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> for(int rownum = 0; rownum &lt; 1000; rownum++){</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Row row = sh.createRow(rownum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> for(int cellnum = 0; cellnum &lt; 10; cellnum++){</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> Cell cell = row.createCell(cellnum);</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> String address = new CellReference(cell).formatAsString();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> cell.setCellValue(address);</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"> // manually control how rows are flushed to disk</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> if(rownum % 100 == 0) {</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> ((SXSSFSheet)sh).flushRows(100); // retain 100 last rows and flush all others</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // ((SXSSFSheet)sh).flushRows() is a shortcut for ((SXSSFSheet)sh).flushRows(0),</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> // this method flushes all rows</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"> FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");</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 class="codeline">
<span class="lineno"></span><span class="codebody"> // dispose of temporary files backing this workbook on disk</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"> wb.dispose();</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>SXSSF flushes sheet data in temporary files (a temp file per sheet) and the size of these temporary files
can grow to a very large value. For example, for a 20 MB csv data the size of the temp xml becomes more than a gigabyte.
If the size of the temp files is an issue, you can tell SXSSF to use gzip compression:
</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">SXSSFWorkbook wb = new SXSSFWorkbook();</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody">wb.setCompressTempFiles(true); // temp files will be gzipped</span>
</div>
<div class="codeline">
<span class="lineno"></span><span class="codebody"></span>
</div>
</div>
<a name="low_level_api" id="low_level_api"></a><a name="Low+Level+APIs"></a>
<h3 class="boxed">Low Level APIs</h3>
<p>The low level API is not much to look at. It consists of lots of
"Records" in the org.apache.poi.hssf.record.* package,
and set of helper classes in org.apache.poi.hssf.model.*. The
record classes are consistent with the low level binary structures
inside a BIFF8 file (which is embedded in a POIFS file system). You
probably need the book: "Microsoft Excel 97 Developer's Kit"
from Microsoft Press in order to understand how these fit together
(out of print but easily obtainable from Amazon's used books). In
order to gain a good understanding of how to use the low level APIs
should view the source in org.apache.poi.hssf.usermodel.* and
the classes in org.apache.poi.hssf.model.*. You should read the
documentation for the POIFS libraries as well.</p>
<a name="Generating+XLS+from+XML"></a>
<h3 class="boxed">Generating XLS from XML</h3>
<p>If you wish to generate an XLS file from some XML, it is possible to
write your own XML processing code, then use the User API to write out
the document.</p>
<p>The other option is to use <a href="https://cocoon.apache.org/">Cocoon</a>.
In Cocoon, there is the <a href="https://cocoon.apache.org/2.1/userdocs/xls-serializer.html">HSSF Serializer</a>,
which takes in XML (in the gnumeric format), and outputs an XLS file for you.</p>
<a name="HSSF+Class%2FTest+Application"></a>
<h3 class="boxed">HSSF Class/Test Application</h3>
<p>The HSSF application is nothing more than a test for the high
level API (and indirectly the low level support). The main body of
its code is repeated above. To run it:
</p>
<ul>
<li>download the poi-alpha build and untar it (tar xvzf
tarball.tar.gz)
</li>
<li>set up your classpath as follows:
<span class="codefrag">export HSSFDIR={wherever you put HSSF's jar files}
export LOG4JDIR={wherever you put LOG4J's jar files}
export CLASSPATH=$CLASSPATH:$HSSFDIR/hssf.jar:$HSSFDIR/poi-poifs.jar:$HSSFDIR/poi-util.jar:$LOG4JDIR/log4j.jar</span>
</li>
<li>type:
<span class="codefrag">java org.apache.poi.hssf.dev.HSSF ~/myxls.xls write</span>
</li>
</ul>
<p></p>
<p>This should generate a test sheet in your home directory called <span class="codefrag">"myxls.xls"</span>. </p>
<ul>
<li>Type:
<span class="codefrag">java org.apache.poi.hssf.dev.HSSF ~/input.xls output.xls</span>
<br>
<br>
This is the read/write/modify test. It reads in the spreadsheet, modifies a cell, and writes it back out.
Failing this test is not necessarily a bad thing. If HSSF tries to modify a non-existant sheet then this will
most likely fail. No big deal. </li>
</ul>
<a name="HSSF+Developer%27s+Tools"></a>
<h3 class="boxed">HSSF Developer's Tools</h3>
<p>HSSF has a number of tools useful for developers to debug/develop
stuff using HSSF (and more generally XLS files). We've already
discussed the app for testing HSSF read/write/modify capabilities;
now we'll talk a bit about BiffViewer. Early on in the development of
HSSF, it was decided that knowing what was in a record, what was
wrong with it, etc. was virtually impossible with the available
tools. So we developed BiffViewer. You can find it at
org.apache.poi.hssf.dev.BiffViewer. It performs two basic
functions and a derivative.
</p>
<p>The first is "biffview". To do this you run it (assumes
you have everything setup in your classpath and that you know what
you're doing enough to be thinking about this) with an xls file as a
parameter. It will give you a listing of all understood records with
their data and a list of not-yet-understood records with no data
(because it doesn't know how to interpret them). This listing is
useful for several things. First, you can look at the values and SEE
what is wrong in quasi-English. Second, you can send the output to a
file and compare it.
</p>
<p>The second function is "big freakin dump", just pass a
file and a second argument matching "bfd" exactly. This
will just make a big hexdump of the file.
</p>
<p>Lastly, there is "mixed" mode which does the same as
regular biffview, only it includes hex dumps of certain records
intertwined. To use that just pass a file with a second argument
matching "on" exactly.</p>
<p>In the next release cycle we'll also have something called a
FormulaViewer. The class is already there, but its not very useful
yet. When it does something, we'll document it.</p>
<a name="What%27s+Next%3F"></a>
<h3 class="boxed">What's Next?</h3>
<p>Further effort on HSSF is going to focus on the following major areas: </p>
<ul>
<li>Performance: POI currently uses a lot of memory for large sheets.</li>
<li>Charts: This is a hard problem, with very little documentation.</li>
</ul>
<p>
<a href="../../devel/guidelines.html"> So jump in! </a>
</p>
</div>
<p align="right">
<font size="-2">by&nbsp;Andrew C. Oliver,&nbsp;Glen Stampoultzis,&nbsp;Nick Burch,&nbsp;Sergei Kozello</font>
</p>
</div>
<!--+
|end content
+-->
<div class="clearboth">&nbsp;</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 &copy;
2001-2026 <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/how-to.html">dev@poi.apache.org</a>
</div>
<!--+
|end bottomstrip
+-->
</div>
</body>
</html>