committed the hssf english versions to the spanish trans so that they can be patched.

PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352847 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew C. Oliver 2002-09-18 23:52:56 +00:00
parent 92fc3397c5
commit 7e8fb96f2c
12 changed files with 1648 additions and 0 deletions

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>HSSF</title>
<subtitle>Alternatives to HSSF</subtitle>
<authors>
<person name="Glen Stampoultzis" email="glens@apache.org"/>
</authors>
</header>
<body>
<section title="Alternatives">
<p>
Maybe it's unwise to advertise your competitors but we believe
competition is good and we have the best support reading and
write Excel workbooks currently available.
</p>
<table>
<tr>
<td><b>Product</b></td>
<td><b>URL</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td>Formula One</td>
<td>
<link href="http://www.tidestone.com/">www.tidestone.com</link>
</td>
<td>An alternative to this project is to
buy the $10,000 Formula 1 library
and accept its crude api and limitations.</td>
</tr>
<tr>
<td>Visual Basic</td>
<td>
<link href="http://www.microsoft.com/">www.microsoft.com</link>
</td>
<td>Give up XML and write Visual Basic code on a Microsoft Windows based
Environment or output in Microsoft's beta and primarily undocumented
XML for office format.</td>
</tr>
<tr>
<td>JExcel</td>
<td>http://stareyes.homeip.net:8888</td>
<td>Frequently unavailable. Little currently known about it's capabilities.</td>
</tr>
<tr>
<td>JWorkbook</td>
<td>http://www.object-refinery.com/jworkbook/index.html</td>
<td>This effort supports Gnumeric and Excel, however the Excel part is done using POI anyway.</td>
</tr>
<tr>
<td>xlReader</td>
<td><link href="http://www.sourceforge.net/projects/xlrd">http://www.sourceforge.net/projects/xlrd</link></td>
<td>Provides decent support for reading Excel.</td>
</tr>
<tr>
<td>Excel ODBC Driver</td>
<td><link href="http://www.nwlink.com/~leewal/content/exceljavasample.htm">http://www.nwlink.com/~leewal/content/exceljavasample.htm</link></td>
<td>ODBC offers a somewhat wierd method for using Excel.</td>
</tr>
<tr>
<td>ExtenXLS</td>
<td><link href="http://www.extentech.com/products/ExtenXLS/docs/intro3.jsp">http://www.extentech.com/products/ExtenXLS/docs/intro3.jsp</link></td>
<td>Commercial library for reading, modifying and writing Excel spreadsheets. Not cheap but
certainly a lot more affordable than Formula 1. No idea as to it's quality.</td>
</tr>
<tr>
<td>J-Integra Java-Excel Bridge</td>
<td><link href="http://www.intrinsyc.com/products/bridging/jintegra.asp">http://www.intrinsyc.com/products/bridging/jintegra.asp</link></td>
<td>Uses DCOM to an Excel instance on a windows machine.</td>
</tr>
<tr>
<td>Perl &amp; C</td>
<td>-</td>
<td>There are a number of perl and C libraries, however none of them are consistent.</td>
</tr>
<tr>
<td>VistaJDBC</td>
<td><link href="http://www.vistaportal.com/products/vistajdbc.htm">http://www.vistaportal.com/products/vistajdbc.htm</link></td>
<td>VistaJDBC driver works with both StarOffice and Excel spreadsheets and
can access data using standard SQL statements without any API programming.
VistaJDBC also implemented ability to choose by not just rows and columns but by
specific cells, ranges of cells, etc.
</td>
</tr>
<tr>
<td>Coldtags Excel Tag Library</td>
<td><link href="http://www.servletsuite.com/servlets/exceltag.htm">http://www.servletsuite.com/servlets/exceltag.htm</link></td>
<td>
This library outputs a simple CSV file, in which cells can
contain numbers or text. You could output a CSV file without its
help, but it gives a little more readability/structure to the code, and
could be extended to handle more complexity. When
you invoke one of these JSP pages from your browser, you open up an Excel
spreadsheet. There's no formatting, worksheets, or anything fancy like that.
So it's not strictly a competitor but it does the job.
</td>
</tr>
</table>
</section>
</body>
</document>

View File

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
<book software="Poi Project"
title="HSSF"
copyright="@year@ Poi Project">
<menu label="Navigation">
<menu-item label="Main" href="../index.html"/>
</menu>
<menu label="HSSF">
<menu-item label="Quick Guide" href="quick-guide.html"/>
<menu-item label="HOWTO" href="how-to.html"/>
<menu-item label="Formula Support" href="formula.html" />
<menu-item label="Use Case" href="use-case.html"/>
<menu-item label="Pictorial Docs" href="diagrams.html"/>
<menu-item label="Alternatives" href="alternatives.html"/>
<menu-item label="Limitations" href="limitations.html"/>
</menu>
<menu label="Contributer's Guide">
<menu-item label="Hacking HSSF" href="hacking-hssf.html"/>
<menu-item label="Record Generator" href="record-generator.html"/>
</menu>
</book>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>HSSF</title>
<subtitle>Overview</subtitle>
<authors>
<person name="Andrew C. Oliver" email="acoliver@apache.org"/>
<person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
</authors>
</header>
<body>
<section title="Usermodel Class Diagram by Matthew Young">
<img src="images/usermodel.gif"/>
</section>
</body>
</document>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>HSSF</title>
<subtitle>Overview</subtitle>
<authors>
<person name="Andrew C. Oliver" email="acoliver@apache.org"/>
<person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
</authors>
</header>
<body>
<section title="Overview">
<p>
This section is intended for diagrams (UML/etc) that help
explain HSSF.
</p>
<ul>
<li>
<link href="diagram1.html">HSSF usermodel class diagram</link> -
by Matthew Young (myoung at westernasset dot com)
</li>
</ul>
<p>
Have more? Add a new &quot;bug&quot; to the bug database with [DOCUMENTATION]
prefacing the description and a link to the file on an http server
somewhere. If you don't have your own webserver, then you can email it
to (acoliver at apache dot org) provided its &lt; 5MB. Diagrams should be
in some format that can be read at least on Linux and Windows. Diagrams
that can be edited are preferrable, but lets face it, there aren't too
many good affordable UML tools yet! And no they don't HAVE to be UML...
just useful.
</p>
</section>
</body>
</document>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Formula Support</title>
<authors>
<person email="avik@apache.org" name="Avik Sengupta" id="AS"/>
</authors>
</header>
<body>
<section title="Introduction">
<p>
This document describes the current state of formula support in POI.
The information in this document applies to the 2.0-dev version of POI (i.e. CVS HEAD).
Since this area is a work in progress, this document will be updated with new features as and
when they are added.
</p>
</section>
<section title="The basics">
<p>
In org.apache.poi.hssf.usermodel.HSSFCell
<strong> setCellFormula(&quot;formulaString&quot;) </strong> is used to add a formula to sheet and
<strong> getCellFormula() </strong> is used to retrieve the string representation of a formula.
</p>
<p>
We aim to support the complete excel grammer for formulas. Thus, the string that you pass in
to the <b> setCellFormula </b> call should be what you expect to type into excel. Also, note
that you should NOT add a "=" to the front of the string.
</p>
</section>
<section title="Supported Features">
<ul>
<li>Cell References</li>
<li>String, integer and floating point literals</li>
<li>Area references</li>
<li>Relative or absolute references</li>
<li>Arithmetic Operators</li>
<li>Sheet Functions</li>
</ul>
</section>
<section title="Partially supported">
<ul>
<li>
The formula parser now has the ability to parse formulas containing strings. However
formulas that return a string value are not yet supported.
</li>
<li>Formula tokens in Excel are stored in one of three possible <em> classes </em>:
Reference, Value and Array. Based on the location of a token, its class can change
in complicated and undocumented ways. While we have support for most cases, we
are not sure if we have covered all bases (since there is no documentation for this area.)
We would therefore like you to report any
occurence of #VALUE! in a cell upon opening a POI generated workbook in excel. (Check that
typing the formula into Excel directly gives a valid result.)
</li>
</ul>
</section>
<section title="Not yet supported">
<ul>
<li>Array formulas</li>
<li>Formulas with logical operations (IF) </li>
<li>Sheet References in formulas</li>
<li>Everything else :) </li>
</ul>
</section>
<section title="Internals">
<p>
Formulas in Excel are stored as sequences of tokens in Reverse Polish Notation order. The
<link href="http://sc.openoffice.org/excelfileformat.pdf">open office XLS spec</link> is the best
documentation you will find for the format.
</p>
<p>
The tokens used by excel are modelled as individual *Ptg classes in the <strong>
org.apache.poi.hssf.record.formula</strong> package.
</p>
<p>
The task of parsing a formula string into an array of RPN ordered tokens is done by the <strong>
org.apache.poi.hssf.record.formula.FormulaParser</strong> class. This class implements a hand
written recursive descent parser.
</p>
<p>Check out the <link href="http://jakarta.apache.org/poi/javadocs/">javadocs </link> for details.
</p>
</section>
</body>
</document>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Hacking HSSF</title>
<authors>
<person email="glens@apache.org" name="Glen Stampoultzis" id="GJS"/>
<person email="acoliver@apache.org" name="Andrew Oliver" id="AO"/>
</authors>
</header>
<body>
<section title="Where Can I Find Documentation on Feature X">
<p>
You might find the
'Excel 97 Developer's Kit' (out of print, Microsoft Press, no
restrictive covenants, available on Amazon.com) helpful for
understanding the file format.
</p>
<p>
Also useful is the <link href="http://sc.openoffice.org/excelfileformat.pdf">open office XLS spec</link>. We
are collaborating with the maintainer of the spec so if you think you can add something to their
document just send through your changes.
</p>
</section>
<section title="Help, I Can't Find Feature X Documented Anywhere">
<ol>
<li>
Look at OpenOffice.org or Gnumeric sources if its implemented there.
</li>
<li>
Use org.apache.poi.hssf.dev.BiffViewer to view the structure of the
file. Experiment by adding one criteria entry at a time. See what it
does to the structure, infer behavior and structure from it. Using the
unix diff command (or get cygwin from www.cygwin.com for windows) you
can figure out a lot very quickly. Unimplemented records show up as
'UNKNOWN' and prints a hex dump.
</li>
</ol>
</section>
<section title="Low-level Record Generation">
<p>
Low level records can be time consuming to created. We created a record
generator to help generate some of the simpler tasks.
</p>
<p>
We use XML
descriptors to generate the Java code (which sure beats the heck out of
the PERL scripts originally used ;-) for low level records. The
generator is kinda alpha-ish right now and could use some enhancement,
so you may find that to be about 1/2 of the work. Notice this is in
org.apache.poi.hssf.record.definitions.
</p>
</section>
<section title="Important Notice">
<p>One thing to note: If you are making a large code contribution we need to ensure
any participants in this process have never
signed a "Non Disclosure Agreement" with Microsoft, and have not
received any information covered by such an agreement. If they have
they'll not be able to participate in the POI project. For large contributions we
may ask you to sign an agreement.</p>
</section>
<section title="What Can I Work On?">
<p>Check our <link href="../todo.html">todo list</link> or simply look for missing functionality. Start small
and work your way up.</p>
</section>
<section title="What Else Should I Know?">
<p>Make sure you <link href="http://jakarta.apache.org/poi/contrib.html">read the contributing section</link>
as it contains more generation information about contributing to Poi in general.</p>
</section>
</body>
</document>

View File

@ -0,0 +1,498 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>The New Halloween Document</title>
<authors>
<person email="acoliver2@users.sourceforge.net" name="Andrew C. Oliver" id="AO"/>
<person email="glens@apache.org" name="Glen Stampoultzis" id="GJS"/>
<person email="sergeikozello@mail.ru" name="Sergei Kozello" id="SK"/>
</authors>
</header>
<body>
<section title="How to use the HSSF prototype API">
<section title="Capabilities">
<p>This release of the how-to outlines functionality for the CVS HEAD.
Those looking for information on previous releases should
look in the documentation distributed with that release.</p>
<p>
This release allows numeric and string cell values to be written to
or read from an XLS file as well as reading and writing dates. Also
in this release is row and column sizing, cell styling (bold,
italics, borders,etc), and support for built-in data formats. New
to this release 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. It will also serve as the basis for the HSSF
Generator.</p>
</section>
<section title="General Use">
<section title="User API">
<section title="Writing a new one">
<p>The high level API (package: org.apache.poi.hssf.usermodel)
is what most people should use. Usage is very simple.
</p>
<p>Workbooks are created by creating an instance of
org.apache.poi.hssf.usermodel.HSSFWorkbook.
</p>
<p>Sheets are created by calling createSheet() from an existing
instance of HSSFWorkbook, 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
HSSFWorkbook.setSheetName(sheetindex,&quot;SheetName&quot;,encoding).
The name may be in 8bit format (HSSFWorkbook.ENCODING_COMPRESSED_UNICODE)
or Unicode (HSSFWorkbook.ENCODING_UTF_16). Default encoding is 8bit per char.
</p>
<p>Rows are created by calling createRow(rowNumber) from an existing
instance of HSSFSheet. 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 HSSFRow. Only cells that have values should be added to the
row. Cells should have their cell type set to either
HSSFCell.CELL_TYPE_NUMERIC or HSSFCell.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 HSSFSheet object. (You can't do it on
an individual basis in the GUI either).</p>
<p>Cells are styled with HSSFCellStyle objects which in turn contain
a reference to an HSSFFont object. These are created via the
HSSFWorkbook 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 HSSFCellStyle 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>
<source><![CDATA[
short rownum;
// create a new file
FileOutputStream out = new FileOutputStream("workbook.xls");
// create a new workbook
HSSFWorkbook wb = new HSSFWorkbook();
// create a new sheet
HSSFSheet s = wb.createSheet();
// declare a row object reference
HSSFRow r = null;
// declare a cell object reference
HSSFCell c = null;
// create 3 cell styles
HSSFCellStyle cs = wb.createCellStyle();
HSSFCellStyle cs2 = wb.createCellStyle();
HSSFCellStyle cs3 = wb.createCellStyle();
// create 2 fonts objects
HSSFFont f = wb.createFont();
HSSFFont f2 = wb.createFont();
//set font 1 to 12 point type
f.setFontHeightInPoints((short) 12);
//make it blue
f.setColor( (short)0xc );
// make it bold
//arial is the default font
f.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
//set font 2 to 10 point type
f2.setFontHeightInPoints((short) 10);
//make it red
f2.setColor( (short)HSSFFont.COLOR_RED );
//make it bold
f2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
f2.setStrikeout( true );
//set cell stlye
cs.setFont(f);
//set the cell format see HSSFDataFromat for a full list
cs.setDataFormat(HSSFDataFormat.getFormat("($#,##0_);[Red]($#,##0)"));
//set a thin border
cs2.setBorderBottom(cs2.BORDER_THIN);
//fill w fg fill color
cs2.setFillPattern((short) HSSFCellStyle.SOLID_FOREGROUND);
// set the font
cs2.setFont(f2);
// set the sheet name in Unicode
wb.setSheetName(0, "\u0422\u0435\u0441\u0442\u043E\u0432\u0430\u044F " +
"\u0421\u0442\u0440\u0430\u043D\u0438\u0447\u043A\u0430",
HSSFWorkbook.ENCODING_UTF_16 );
// in case of compressed Unicode
// wb.setSheetName(0, "HSSF Test", HSSFWorkbook.ENCODING_COMPRESSED_UNICODE );
// create a sheet with 30 rows (0-29)
for (rownum = (short) 0; rownum < 30; rownum++)
{
// create a row
r = s.createRow(rownum);
// on every other row
if ((rownum % 2) == 0)
{
// make the row height bigger (in twips - 1/20 of a point)
r.setHeight((short) 0x249);
}
//r.setRowNum(( short ) rownum);
// create 10 cells (0-9) (the += 2 becomes apparent later
for (short cellnum = (short) 0; cellnum < 10; cellnum += 2)
{
// create a numeric cell
c = r.createCell(cellnum);
// do some goofy math to demonstrate decimals
c.setCellValue(rownum * 10000 + cellnum
+ (((double) rownum / 1000)
+ ((double) cellnum / 10000)));
String cellValue;
// create a string cell (see why += 2 in the
c = r.createCell((short) (cellnum + 1));
// on every other row
if ((rownum % 2) == 0)
{
// set this cell to the first cell style we defined
c.setCellStyle(cs);
// set the cell's string value to "Test"
c.setEncoding( HSSFCell.ENCODING_COMPRESSED_UNICODE );
c.setCellValue( "Test" );
}
else
{
c.setCellStyle(cs2);
// set the cell's string value to "\u0422\u0435\u0441\u0442"
c.setEncoding( HSSFCell.ENCODING_UTF_16 );
c.setCellValue( "\u0422\u0435\u0441\u0442" );
}
// make this column a bit wider
s.setColumnWidth((short) (cellnum + 1), (short) ((50 * 8) / ((double) 1 / 20)));
}
}
//draw a thick black border on the row at the bottom using BLANKS
// advance 2 rows
rownum++;
rownum++;
r = s.createRow(rownum);
// define the third style to be the default
// except with a thick black border at the bottom
cs3.setBorderBottom(cs3.BORDER_THICK);
//create 50 cells
for (short cellnum = (short) 0; cellnum < 50; cellnum++)
{
//create a blank type cell (no value)
c = r.createCell(cellnum);
// set it to the thick black border style
c.setCellStyle(cs3);
}
//end draw thick black border
// demonstrate adding/naming and deleting a sheet
// create a sheet, set its title then delete it
s = wb.createSheet();
wb.setSheetName(1, "DeletedSheet");
wb.removeSheetAt(1);
//end deleted sheet
// write the workbook to the output stream
// close our file (don't blow out our file handles
wb.write(out);
out.close();
]]></source>
</section>
<section title="Reading or modifying an existing file">
<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
<link href="http://cvs.apache.org/viewcvs/~checkout~/jakarta-poi/src/java/org/apache/poi/hssf/dev/HSSF.java?rev=1.1">org.apache.poi.hssf.dev.HSSF</link>.</p>
</section>
</section>
<section title="Event API">
<p>The event API is brand new. 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>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(&quot;Workbook&quot;) 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>
<source><![CDATA[
/**
* This example shows how to use the event API for reading a file.
*/
public class EventExample
implements HSSFListener
{
private SSTRecord sstrec;
/**
* This method listens for incoming records and handles them as required.
* @param record The record that was found while reading.
*/
public void processRecord(Record record)
{
switch (record.getSid())
{
// the BOFRecord can represent either the beginning of a sheet or the workbook
case BOFRecord.sid:
BOFRecord bof = (BOFRecord) record;
if (bof.getType() == bof.TYPE_WORKBOOK)
{
System.out.println("Encountered workbook");
// assigned to the class level member
} else if (bof.getType() == bof.TYPE_WORKSHEET)
{
System.out.println("Encountered sheet reference");
}
break;
case BoundSheetRecord.sid:
BoundSheetRecord bsr = (BoundSheetRecord) record;
System.out.println("New sheet named: " + bsr.getSheetname());
break;
case RowRecord.sid:
RowRecord rowrec = (RowRecord) record;
System.out.println("Row found, first column at "
+ rowrec.getFirstCol() + " last column at " + rowrec.getLastCol());
break;
case NumberRecord.sid:
NumberRecord numrec = (NumberRecord) record;
System.out.println("Cell found with value " + numrec.getValue()
+ " at row " + numrec.getRow() + " and column " + numrec.getColumn());
break;
// SSTRecords store a array of unique strings used in Excel.
case SSTRecord.sid:
sstrec = (SSTRecord) record;
for (int k = 0; k < sstrec.getNumUniqueStrings(); k++)
{
System.out.println("String table value " + k + " = " + sstrec.getString(k));
}
break;
case LabelSSTRecord.sid:
LabelSSTRecord lrec = (LabelSSTRecord) record;
System.out.println("String cell found with value "
+ sstrec.getString(lrec.getSSTIndex()));
break;
}
}
/**
* Read an excel file and spit out what we find.
*
* @param args Expect one argument that is the file to read.
* @throws IOException When there is an error processing the file.
*/
public static void main(String[] args) throws IOException
{
// create a new file input stream with the input file specified
// at the command line
FileInputStream fin = new FileInputStream(args[0]);
// create a new org.apache.poi.poifs.filesystem.Filesystem
POIFSFileSystem poifs = new POIFSFileSystem(fin);
// get the Workbook (excel part) stream in a InputStream
InputStream din = poifs.createDocumentInputStream("Workbook");
// construct out HSSFRequest object
HSSFRequest req = new HSSFRequest();
// lazy listen for ALL records with the listener shown above
req.addListenerForAllRecords(new EventExample());
// create our event factory
HSSFEventFactory factory = new HSSFEventFactory();
// process our events based on the document input stream
factory.processEvents(req, din);
// once all the events are processed close our file input stream
fin.close();
// and our document input stream (don't want to leak these!)
din.close();
System.out.println("done.");
}
}
]]></source>
</section>
<section title="Low Level APIs">
<p>The low level API is not much to look at. It consists of lots of
&quot;Records&quot; 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: &quot;Microsoft Excel 97 Developer's Kit&quot;
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>
</section>
<section title="HSSF Class/Test Application">
<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:
<code>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/jog4j.jar</code>
</li><li>type:
<code>java org.apache.poi.hssf.dev.HSSF ~/myxls.xls write</code></li>
</ul>
<p></p>
<p>This should generate a test sheet in your home directory called <code>&quot;myxls.xls&quot;</code>. </p>
<ul>
<li>Type:
<code>java org.apache.poi.hssf.dev.HSSF ~/input.xls output.xls</code>
<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>
</section>
<section title="Logging facility">
<p>Poi can dynamically select it's logging implementation. Poi trys to
create a logger using the System property named "org.apache.poi.util.POILogger".
Out of the box this can be set to one of three values:
</p>
<ul>
<li>org.apache.poi.util.CommonsLogger</li>
<li>org.apache.poi.util.NullLogger</li>
<li>org.apache.poi.util.SystemOutLogger</li>
</ul>
<p>
If the property is not defined or points to an invalid classthen the NullLogger is used.
</p>
<p>
Refer to the commons logging package level javadoc for more information concerning how to
<link href="http://jakarta.apache.org/commons/logging/api/index.html">configure commons logging.</link>
</p>
</section>
<section title="HSSF Developer's Tools">
<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 &quot;biffview&quot;. 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 &quot;big freakin dump&quot;, just pass a
file and a second argument matching &quot;bfd&quot; exactly. This
will just make a big hexdump of the file.
</p>
<p>Lastly, there is &quot;mixed&quot; 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 &quot;on&quot; 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>
</section>
<section title="What's Next?">
<p>This release contains code that supports &quot;internationalization&quot;
or more accurately non-US/UK languages; however, it has not been
tested with the new API changes (please help us with this). We've
shifted focus a bit for this release in recognition of the
international support we've gotten. We're going to focus on western
European languages for our first beta. We're more than happy to
accept help in supporting non-Western European languages if someone
who knows what they're doing in this area is willing to pitch in!
(There is next to no documentation on what is necessary to support
such a move and its really hard to support a language when you don't even
know the alphabet).</p>
<p>This release of HSSF does not yet support Formulas. I've been
focusing on the requests I've gotten in. That being said, if we get
more user feedback on what is most useful first we'll aim for that.
As a general principal, HSSF's goal is to support HSSF-Serializer
(meaning an emphasis on write). We would like to hear from you! How
are you using HSSF/POIFS? How would you like to use it? What features
are most important first?
</p>
</section>
</section>
</section>
</body>
</document>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>HSSF</title>
<subtitle>Overview</subtitle>
<authors>
<person name="Andrew C. Oliver" email="acoliver@apache.org"/>
<person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
</authors>
</header>
<body>
<section title="Overview">
<p>HSSF is the POI Project's pure Java implementation of the Excel '97(-2002) file format.</p>
<p>HSSF provides a way to read spreadsheets create, modify, read and write XLS spreadsheets
It provides:
</p>
<ul>
<li>low level structures for those with special needs</li>
<li>an eventmodel api for efficient read-only access</li>
<li>a full usermodel api for creating, reading and modifying XLS files</li>
</ul>
<p>
Truth be told there is probably a better way to generate your spreadsheet
generation (yet you'll still be using HSSF indirectly). At the time of
this writing we're in the process of moving the HSSF Serializer over to
the <link href="http://xml.apache.org/cocoon">Apache Cocoon
Project</link>. With Cocoon you can serialize any XML datasource (of
which might be a ESQL page outputting in SQL for instance) by simply
applying the stylesheet and designating the serializer.
</p>
<p>
If you're merely reading spreadsheet data, then use the eventmodel api
in the org.apache.poi.hssf.eventmodel package.
</p>
<p>
If you're modifying spreadsheet data then use the usermodel api. You
can also generate spreadsheets this way, but using Cocoon (which will do
it this way indirectly) is the best way...we promise.
</p>
</section>
</body>
</document>

View File

@ -0,0 +1,52 @@
<document>
<header>
<title>Limitations</title>
<authors>
<person email="glens@apache.org" name="Glen Stampoultzis" id="GJS"/>
</authors>
</header>
<body>
<section title="Version 1.5 limitations">
<p>
The intent of this document is to outline some of the known limitations of the
POI HSSF API's. It is not intended to be complete list of every bug or missing
feature of HSSF, rather it's purpose is to provide a broad feel for some of the
functionality that is missing or broken.
</p>
<ul>
<li>
Charts<br/><br/>
You can not currently create charts. This is planned for the 2.0 release. You can
however create a chart in Excel, modify the chart data values using HSSF and write
a new spreadsheet out. This is possible because POI attempts to keep existing records
intact as far as possible.<br/><br/>
</li>
<li>
Rich Text<br/><br/>
HSSF does not support rich text cells. Rich text cells are
cells that have multiple fonts and styles in the once cell. Any attempt to read
a spreadsheet that has rich text cells will throw an exception. This feature may
be supported in the future but it is not currently planned. Patches are welcome.<br/><br/>
</li>
<li>
Outlines<br/><br/>
It is not yet possible to create outlines. Reading a spreadsheet with outlines
may work correctly but has not been tested. Write support for outlines may
be added in the future but it is not currently planned. Patches are welcome.<br/><br/>
</li>
<li>
Macros<br/><br/>
Macros can not be created. The are currently no plans to support macros. Reading
workbooks containing macros is supported but attempting to write those workbooks
will fail. This is because macros are stored as extra file sytems within the
compound document, and these are not currently kept when the file is rewritten.<br/><br/>
</li>
<li>
Pivot Tables<br/><br/>
Generating pivot tables is not supported. Reading spreadsheets containing pivot tables
has not been tested.
</li>
</ul>
</section>
</body>
</document>

View File

@ -0,0 +1,404 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Busy Developers' Guide to HSSF Features</title>
<authors>
<person email="glens@apache.org" name="Glen Stampoultzis" id="CO"/>
</authors>
</header>
<body>
<section title="Busy Developers' Guide to Features">
<p>
Want to use HSSF read and write spreadsheets in a hurry? This guide is for you. If you're after
more in-depth coverage of the HSSF user-API please consult the <link href="how-to.html">HOWTO</link>
guide as it contains actual descriptions of how to use this stuff.
</p>
<section title="Index of Features">
<ul>
<li><link href="#NewWorkbook">How to create a new workbook</link></li>
<li><link href="#NewSheet">How to create a sheet</link></li>
<li><link href="#CreateCells">How to create cells</link></li>
<li><link href="#CreateDateCells">How to create date cells</link></li>
<li><link href="#CellTypes">Working with different types of cells</link></li>
<li><link href="#Alignment">Aligning cells</link></li>
<li><link href="#Borders">Working with borders</link></li>
<li><link href="#FrillsAndFills">Fills and color</link></li>
<li><link href="#MergedCells">Merging cells</link></li>
<li><link href="#WorkingWithFonts">Working with fonts</link></li>
<li><link href="#ReadWriteWorkbook">Reading and writing</link></li>
<li><link href="#NewLinesInCells">Use newlines in cells.</link></li>
<li><link href="#DataFormats">Create user defined data formats.</link></li>
<li><link href="#PrintArea">Set print area for a sheet.</link></li>
<li><link href="#FooterPageNumbers">Set page numbers on the footer of a sheet.</link></li>
</ul>
</section>
<section title="Features">
<anchor id="NewWorkbook"/>
<section title="New Workbook">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="NewSheet"/>
<section title="New Sheet">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
HSSFSheet sheet2 = wb.createSheet("second sheet");
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="CreateCells"/>
<section title="Creating Cells">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short)0);
// Create a cell and put a value in it.
HSSFCell cell = row.createCell((short)0);
cell.setCellValue(1);
// Or do it on one line.
row.createCell((short)1).setCellValue(1.2);
row.createCell((short)2).setCellValue("This is a string");
row.createCell((short)3).setCellValue(true);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="CreateDateCells"/>
<section title="Creating Date Cells">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short)0);
// Create a cell and put a date value in it. The first cell is not styled
// as a date.
HSSFCell cell = row.createCell((short)0);
cell.setCellValue(new Date());
// we style the second cell as a date (and time). It is important to
// create a new cell style from the workbook otherwise you can end up
// modifying the built in style and effecting not only this cell but other cells.
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(HSSFDataFormat.getFormat("m/d/yy h:mm"));
cell = row.createCell((short)1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="CellTypes"/>
<section title="Working with different types of cells">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFRow row = sheet.createRow((short)2);
row.createCell((short) 0).setCellValue(1.1);
row.createCell((short) 1).setCellValue(new Date());
row.createCell((short) 2).setCellValue("a string");
row.createCell((short) 3).setCellValue(true);
row.createCell((short) 4).setCellType(HSSFCell.CELL_TYPE_ERROR);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="Alignment"/>
<section title="Demonstrates various alignment options">
<source>
public static void main(String[] args)
throws IOException
{
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFRow row = sheet.createRow((short) 2);
createCell(wb, row, (short) 0, HSSFCellStyle.ALIGN_CENTER);
createCell(wb, row, (short) 1, HSSFCellStyle.ALIGN_CENTER_SELECTION);
createCell(wb, row, (short) 2, HSSFCellStyle.ALIGN_FILL);
createCell(wb, row, (short) 3, HSSFCellStyle.ALIGN_GENERAL);
createCell(wb, row, (short) 4, HSSFCellStyle.ALIGN_JUSTIFY);
createCell(wb, row, (short) 5, HSSFCellStyle.ALIGN_LEFT);
createCell(wb, row, (short) 6, HSSFCellStyle.ALIGN_RIGHT);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
}
/**
* Creates a cell and aligns it a certain way.
*
* @param wb the workbook
* @param row the row to create the cell in
* @param column the column number to create the cell in
* @param align the alignment for the cell.
*/
private static void createCell(HSSFWorkbook wb, HSSFRow row, short column, short align)
{
HSSFCell cell = row.createCell(column);
cell.setCellValue("Align It");
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setAlignment(align);
cell.setCellStyle(cellStyle);
}
</source>
</section>
<anchor id="Borders"/>
<section title="Working with borders">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short) 1);
// Create a cell and put a value in it.
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue(4);
// Style the cell with borders all around.
HSSFCellStyle style = wb.createCellStyle();
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBottomBorderColor(HSSFColor.BLACK.index);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setLeftBorderColor(HSSFColor.GREEN.index);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setRightBorderColor(HSSFColor.BLUE.index);
style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM_DASHED);
style.setTopBorderColor(HSSFColor.BLACK.index);
cell.setCellStyle(style);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="FillsAndFrills"/>
<section title="Fills and colors">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short) 1);
// Aqua background
HSSFCellStyle style = wb.createCellStyle();
style.setFillBackgroundColor(HSSFColor.AQUA.index);
style.setFillPattern(HSSFCellStyle.BIG_SPOTS);
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("X");
cell.setCellStyle(style);
// Orange "foreground", foreground being the fill foreground not the font color.
style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.ORANGE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
cell = row.createCell((short) 2);
cell.setCellValue("X");
cell.setCellStyle(style);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="MergedCells"/>
<section title="Merging cells">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFRow row = sheet.createRow((short) 1);
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("This is a test of merging");
sheet.addMergedRegion(new Region(1,(short)1,1,(short)2));
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="WorkingWithFonts"/>
<section title="Working with fonts">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short) 1);
// Create a new font and alter it.
HSSFFont font = wb.createFont();
font.setFontHeightInPoints((short)24);
font.setFontName("Courier New");
font.setItalic(true);
font.setStrikeout(true);
// Fonts are set into a style so create a new one to use.
HSSFCellStyle style = wb.createCellStyle();
style.setFont(font);
// Create a cell and put a value in it.
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("This is a test of fonts");
cell.setCellStyle(style);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="ReadWriteWorkbook"/>
<section title="Reading and Rewriting Workbooks">
<source>
POIFSFileSystem fs =
new POIFSFileSystem(new FileInputStream("workbook.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row = sheet.getRow(2);
HSSFCell cell = row.getCell((short)3);
if (cell == null)
cell = row.createCell((short)3);
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue("a test");
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="UseNewLinesInCells"/>
<section title="Using newlines in cells">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet();
HSSFRow r = null;
HSSFCell c = null;
HSSFCellStyle cs = wb.createCellStyle();
HSSFFont f = wb.createFont();
HSSFFont f2 = wb.createFont();
cs = wb.createCellStyle();
cs.setFont( f2 );
//Word Wrap MUST be turned on
cs.setWrapText( true );
r = s.createRow( (short) 2 );
r.setHeight( (short) 0x349 );
c = r.createCell( (short) 2 );
c.setCellType( HSSFCell.CELL_TYPE_STRING );
c.setCellValue( "Use \n with word wrap on to create a new line" );
c.setCellStyle( cs );
s.setColumnWidth( (short) 2, (short) ( ( 50 * 8 ) / ( (double) 1 / 20 ) ) );
FileOutputStream fileOut = new FileOutputStream( "workbook.xls" );
wb.write( fileOut );
fileOut.close();</source>
</section>
<anchor id="DataFormats"/>
<section title="Data Formats">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFCellStyle style;
HSSFDataFormat format = wb.createDataFormat();
HSSFRow row;
HSSFCell cell;
short rowNum = 0;
short colNum = 0;
row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(11111.25);
style = wb.createCellStyle();
style.setDataFormat(format.getFormat("0.0"));
cell.setCellStyle(style);
row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(11111.25);
style = wb.createCellStyle();
style.setDataFormat(format.getFormat("#,##0.0000"));
cell.setCellStyle(style);
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="PrintArea"/>
<section title="Set Print Area to One Page">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFPrintSetup ps = sheet.getPrintSetup()
sheet.setAutobreaks(true)
ps.setFitHeight((short)1);
ps.setFitWidth((short)1);
// Create various cells and rows for spreadsheet.
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="FooterPageNumbers"/>
<section title="Set Page Numbers on Footer">
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFFooter footer = sheet.getFooter()
footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() );
// Create various cells and rows for spreadsheet.
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
</section>
</section>
</body>
</document>

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Record Generator HOWTO</title>
<authors>
<person email="glens@apache.org" name="Glen Stampoultzis" id="glens"/>
<person email="acoliver@apache.org" name="Andrew C. Oliver" id="acoliver"/>
</authors>
</header>
<body>
<section title="How to Use the Record Generator">
<section title="History">
<p>
The record generator was born from frustration with translating
the Excel records to Java classes. Doing this manually is a time
consuming process. It's also very easy to make mistakes.
</p>
<p>
A utility was needed to take the defintition of what a
record looked like and do all the boring stuff. Thus the
record generator was born.
</p>
</section>
<section title="Capabilities">
<p>
The record generator takes XML as input and produced the following
output:
<ul>
<li>A Java file capabile of decoding and encoding the record.</li>
<li>A test class with provides a fill-in-the-blanks implementation of a test case
for ensuring the record operates as designed.</li>
</ul>
</p>
</section>
<section title="Usage">
<p>
The record generator is invoked as an Ant target (generate-records). It goes
through looking for all files in src/records/defintitions ending with _record.xml.
It then creates two files; the Java record definition and the Java test case template.
</p>
<p>
The records themselves have the following general layout:
</p>
<source><![CDATA[
<record id="0x1032" name="Frame" package="org.apache.poi.hssf.record">
<description>The frame record indicates whether there is a border
around the displayed text of a chart.</description>
<author>Glen Stampoultzis (glens at apache.org)</author>
<fields>
<field type="int" size="2" name="border type">
<const name="regular" value="0" description="regular rectangle or no border"/>
<const name="shadow" value="1" description="rectangle with shadow"/>
</field>
<field type="int" size="2" name="options">
<bit number="0" name="auto size"
description="excel calculates the size automatically if true"/>
<bit number="1" name="auto position"
description="excel calculates the position automatically"/>
</field>
</fields>
</record>
]]></source>
<p>
Currently the type can be of type int, float or string. The 'int'
type covers bytes, shorts and integers which is selected using a
size of 1, 2 or 4. An additional type called varword is used to
represent a array of word values where the first short is the length
of the array. The string type generation is only partially
implemented. If choosing string you must select a size of 'var'.
</p>
<p>
The Java records are regenerated each time the record generator is
run, however the test stubs are only created if the test stub does
not already exist. What this means is that you may change test
stubs but not the generated records.
</p>
</section>
<section title="How it Works">
<p>
The record generation works by taking an XML file and styling it
using XLST. Given that XSLT is a little limited in some ways it was
necessary to add a little Java code to the mix.
</p>
<p>
See record.xsl, record_test.xsl, FieldIterator.java,
RecordUtil.java, RecordGenerator.java
</p>
</section>
<section title="Limitations">
<p>
The record generator does not handle all possible record types and
is not ment to. Sometimes it's going to make more sense to generate
the records manually. The main point of this thing is to make the
easy stuff simple.
</p>
<p>
Currently the record generator is optimized to create Excel records.
It could be adapted to create Word records with a little poking
around.
</p>
<p>
Currently the the XSL file that generates the record calls out to
Java objects. This would have been better done as Javascript inside
the XSL file itself. The Java code for the record generation is
currently quite messy with minimal comments.
</p>
</section>
</section>
</body>
</document>

View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>HSSF Use Cases</title>
<authors>
<person email="marc.johnson@yahoo.com" name="Marc Johnson" id="MJ"/>
</authors>
</header>
<body>
<section title="HSSF Use Cases">
<section title="Use Case 1: Read existing HSSF">
<p><strong>Primary Actor:</strong> HSSF client</p>
<p><strong>Scope:</strong> HSSF</p>
<p><strong>Level:</strong> Summary</p>
<p><strong>Stakeholders and Interests:</strong></p>
<ul>
<li>HSSF client- wants to read content
of HSSF file</li>
<li>HSSF - understands HSSF file</li>
<li>POIFS - understands underlying POI
file system</li>
</ul>
<p><strong>Precondition:</strong> None</p>
<p><strong>Minimal Guarantee:</strong> None</p>
<p><strong>Main Success Guarantee:</strong></p>
<ol>
<li>HSSF client requests HSSF to read
a HSSF file, providing an InputStream
containing HSSF file in question.</li>
<li>HSSF requests POIFS to read the HSSF
file, passing the InputStream
object to POIFS (POIFS use case 1, read existing file system)</li>
<li>HSSF reads the &quot;Workbook&quot;
file (use case 4, read workbook entry)</li>
</ol>
<p><strong>Extensions:</strong></p>
<p>2a. Exceptions
thrown by POIFS will be passed on to the HSSF client.</p>
</section>
<section title="Use Case 2: Write HSSF file">
<p><strong>Primary Actor:</strong> HSSF client</p>
<p><strong>Scope:</strong> HSSF</p>
<p><strong>Level:</strong> Summary</p>
<p><strong>Stakeholders and Interests:</strong></p>
<ul>
<li>HSSF client- wants to write file
out.</li>
<li>HSSF - knows how to write file
out.</li>
<li>POIFS - knows how to write file
system out.</li>
</ul>
<p><strong>Precondition:</strong></p>
<ul>
<li>File has been
read (use case 1, read existing HSSF file) and subsequently modified
or file has been created (use case 3, create HSSF file)</li>
</ul>
<p><strong>Minimal Guarantee:</strong> None</p>
<p><strong>Main Success Guarantee:</strong></p>
<ol>
<li>HSSF client
provides an OutputStream to
write the file to.</li>
<li>HSSF writes
the &quot;Workbook&quot; to its associated POIFS file system (use case
5, write workbook entry)</li>
<li>HSSF
requests POIFS to write its file system out, using the OutputStream
obtained from the HSSF client (POIFS use case 2, write file system).</li>
</ol>
<p><strong>Extensions:</strong></p>
<p>3a. Exceptions
from POIFS are passed to the HSSF client.</p>
</section>
<section title="Use Case 3:Create HSSF file">
<p><strong>Primary Actor:</strong> HSSF client</p>
<p><strong>Scope:</strong> HSSF</p>
<p>
<strong>Level:</strong> Summary</p>
<p><strong>Stakeholders and Interests:</strong></p>
<ul>
<li>HSSF client- wants to create a new
file.</li>
<li>HSSF - knows how to create a new
file.</li>
<li>POIFS - knows how to creat a new
file system.</li>
</ul>
<p><strong>Precondition:</strong></p>
<p><strong>Minimal Guarantee:</strong> None</p>
<p><strong>Main Success Guarantee:</strong></p>
<ol>
<li>HSSF requests
POIFS to create a new file system (POIFS use case 3, create new file
system)</li>
</ol>
<p><strong>Extensions:</strong>
None</p>
</section>
<section title="Use Case 4: Read workbook entry">
<p><strong>Primary Actor:</strong> HSSF</p>
<p><strong>Scope:</strong> HSSF</p>
<p>
<strong>Level:</strong> Summary</p>
<p><strong>Stakeholders and Interests:</strong></p>
<ul>
<li>HSSF - knows how to read the
workbook entry</li>
<li>POIFS - knows how to manage the file
system.</li>
</ul>
<p><strong>Precondition:</strong></p>
<ul>
<li>The file
system has been read (use case 1, read existing HSSF file) or has
been created and written to (use case 3, create HSSF file system;
use case 5, write workbook entry).</li>
</ul>
<p><strong>Minimal
Guarantee:</strong> None</p>
<p><strong>Main Success Guarantee:</strong></p>
<ol>
<li>
HSSF requests POIFS for the &quot;Workbook&quot; file</li>
<li>POIFS returns
an InputStream for the file.</li>
<li>HSSF reads
from the InputStream provided by POIFS</li>
<li>HSSF closes
the InputStream provided by POIFS</li>
</ol>
<p><strong>Extensions:</strong></p>
<p>3a. Exceptions
thrown by POIFS will be passed on</p>
</section>
<section title="Use Case 5: Write workbook entry">
<p><strong>Primary Actor:</strong> HSSF</p>
<p><strong>Scope:</strong> HSSF</p>
<p>
<strong>Level:</strong> Summary</p>
<p><strong>Stakeholders and Interests:</strong></p>
<ul>
<li>HSSF - knows how to manage the
write the workbook entry.</li>
<li>POIFS - knows how to manage the file
system.</li>
</ul>
<p><strong>Precondition:</strong>
</p>
<ul>
<li>Either an existing HSSF file has
been read (use case 1, read existing HSSF file) or an HSSF file has
been created (use case 3, create HSSF file).</li>
</ul>
<p><strong>Minimal Guarantee:</strong> None</p>
<p><strong>Main Success Guarantee:</strong></p>
<ol>
<li>HSSF
checks the POIFS file system directory for the &quot;Workbook&quot;
file (POIFS use case 8, read file system directory)</li>
<li>If &quot;Workbook&quot; is in the directory, HSSF requests POIFS to
replace it with the new workbook entry (POIFS use case 4, replace file
in file system). Otherwise, HSSF requests POIFS to write the new
workbook file, with the name &quot;Workbook&quot; (POIFS use case 6,
write new file to file system)</li>
</ol>
<p><strong>Extensions:</strong>None</p>
</section>
</section>
</body>
</document>