--- /dev/null
+This is the base documentation directory. It usually contains two files:
+
+skinconf.xml # This file customizes Forrest for your project. In it, you
+ # tell forrest the project name, logo, copyright info, etc
+
+sitemap.xmap # Optional. This sitemap overrides the default one bundled
+ # with Forrest. Typically, one would copy a sitemap from
+ # xml-forrest/src/resources/conf/sitemap.xmap, and customize
+ # it.
+
--- /dev/null
+The Apache POI project is pleased to announce the release of POI @VERSION@.
+Featured are a handful of new areas of functionality, and numerous bug fixes.
+
+See the downloads page for binary and source distributions: http://poi.apache.org/download.html
+
+Release Notes
+
+Changes
+------------
+The most notable changes in this release are:
+
+@List changes here@
+
+A full list of changes is available in the change log: http://poi.apache.org/changes.html.
+People interested should also follow the dev mailing list to track further progress.
+
+Release Contents
+----------------
+
+This release comes in two forms:
+ - pre-built binaries containing compiled versions of all Apache POI components and documentation
+ (poi-bin-@VERSION@.zip or poi-bin-@VERSION@.tar.gz)
+ - source archive you can build POI from (poi-src-@VERSION@.zip or poi-src-@VERSION@.tar.gz)
+ Unpack the archive and use the following command to build all POI components with Apache Ant 1.6+ and JDK 1.5 or higher:
+
+ ant jar
+
+ Pre-built versions of all POI components are also available in the central Maven repository
+ under Group ID "org.apache.poi" and Version "@VERSION@"
+
+All release artifacts are accompanied by MD5 checksums and a PGP signatures
+that you can use to verify the authenticity of your download.
+The public key used for the PGP signature can be found at
+http://svn.apache.org/repos/asf/poi/tags/@RELEASE_TAG@/KEYS
+
+About Apache POI
+-----------------------
+
+Apache POI is well-known in the Java field as a library for reading and
+writing Microsoft Office file formats, such as Excel, PowerPoint, Visio and
+Word. Since POI 3.5, the new OOXML (Office Open XML) formats introduced in Office 2007 have been supported.
+See http://poi.apache.org/ for more details
+
--- /dev/null
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+ ================================
+ POI Release Checklist
+ ================================
+
+Note - this file should be read in conjunction with the
+ POI Release Guide. They should probably be merged in future...
+
+- ensure the changelog is up to date
+- tag SVN
+- build distributions as if it was the final release
+- update any filename dates from today's date, to the date that the
+ vote will end (typically 7 days time)
+- copy the -redirect pom to a subdirectory of redirect/, and remove
+ -redirect from its name
+- sign and checksum distributions as per
+ http://www.apache.org/dev/mirror-step-by-step.html
+- upload the files to the POI dev dist area under /<version>-RC-<x>/
+ eg https://dist.apache.org/repos/dist/dev/poi/3.8-RC2/ for
+ 3.8 Release Candidate 2
+- add a README.txt to the directory that states the files are a
+ release candidate pending a vote, despite their name being -FINAL
+- include the URL of this in the release vote (goes to dev, not user)
+ (eg https://dist.apache.org/repos/dist/dev/poi/3.8-RC2/)
+
+- wait for release vote to pass
+- send notification of vote passing to private@
+
+- move the regular distributions from the dev area of the dist svn to the
+ release area of svn
+- remove the old distribition from the release area of svn
+- ensure that the artificats show up on www.apache.org/dist/poi/ (they
+ should appear within a minute)
+
+- copy the maven distribution from a checkout of the dev area of the dist
+ svn, to the distribution directories on
+ people.apache.org/repo/m1-ibiblio-rsync-repository/org.apache.poi/
+- copy the maven redirection pom from a checkout of the dev area of the
+ dist svn, to people.apache.org/repo/m1-ibiblio-rsync-repository/poi/poms/
+
+- wait for the distributions to appear on your favourite mirror
+
+- generate announcements
+- generate www pages and upload
+- bump release ID in build.xml
+- send announcements to user and dev lists
+- send announcements to announcement@apache.org, announcements@jakarta.apache.org
+- news to newsgroups: comp.lang.java.softwaretools
+- post stories on
+ *) jakarta news page
+ *) theserverside.com
+ *) freshmeat.net
+ *) www.javaworld.com
+ *) www.javalobby.com
+ *) www.jguru.com
+ *) www.slashdot.org
+ (and follow them up)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Third Party Contributions</title>
+ <authors>
+ <person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ </authors>
+ </header>
+
+ <body>
+
+ <section><title>How to Contribute</title>
+ <p>
+ See <link href="contrib.xml">How to contribute to Poi</link>.
+ </p>
+
+ </section>
+
+ <section><title>Contributed Components</title>
+ <p>
+ These are not necessarily deemed to be high enough quality to be included in the
+ core distribution, but they have been tested under <link href="contrib.xml">
+ several key environments</link>, they are provided under the same license
+ as Poi, and they are included in the POI distribution under the
+ <code>contrib/</code> directory.
+ </p>
+
+ <p>
+ <strong>None as yet!</strong> - although you can expect that some of the links
+ listed below will eventually migrate to the "contributed components" level, and
+ then maybe even into the main distribution.
+ </p>
+ </section>
+
+ <section><title>Patch Queue</title>
+ <p><link href="patches.html">Submissions of modifications</link>
+ to POI which are awaiting review. Anyone can
+ comment on them on the dev mailing list - code reviewers are needed!
+ <strong>Use these at your own risk</strong> - although POI has no guarantee
+ either, these patches have not been reviewed, let alone accepted.
+ </p>
+ </section>
+
+ <section><title>Other Extensions</title>
+ <p>The other extensions listed here are <strong>not endorsed</strong> by the POI
+ project either - they are provided as a convenience only. They may or may not work,
+ they may or may not be open source, etc.
+ </p>
+
+ <p>To have a link added to this table, see <link href="contrib.xml">How to contribute
+ to POI</link>.</p>
+
+ <table>
+ <tr>
+ <th>Name and Link</th>
+ <th>Type</th>
+ <th>Description</th>
+ <th>Status</th>
+ <th>Licensing</th>
+ <th>Contact</th>
+ </tr>
+ </table>
+
+ </section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "./dtd/book-cocoon-v10.dtd">
+
+<book software="POI"
+ title="POI Project Documentation"
+ copyright="@year@ POI Project"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <menu label="Overview">
+ <menu-item label="Home" href="index.html"/>
+ <menu-item label="Download" href="download.html"/>
+ <menu-item label="Components" href="overview.html"/>
+ <menu-item label="Text Extraction" href="text-extraction.html"/>
+ <menu-item label="Encryption support" href="encryption.html"/>
+ <menu-item label="Case Studies" href="casestudies.html"/>
+ <menu-item label="Legal" href="legal.html"/>
+ </menu>
+
+ <menu label="Help">
+ <menu-item label="Javadocs" href="ext:javadoc"/>
+ <menu-item label="FAQ" href="faq.html"/>
+ <menu-item label="Mailing Lists" href="mailinglists.html"/>
+ <menu-item label="Bug Database" href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI"/>
+ <menu-item label="Changes Log" href="changes.html"/>
+ </menu>
+
+ <menu label="Getting Involved">
+ <menu-item label="Subversion Repository" href="subversion.html"/>
+ <menu-item label="How To Build" href="howtobuild.html"/>
+ <menu-item label="Contribution Guidelines" href="guidelines.html"/>
+ <menu-item label="Who We Are" href="who.html"/>
+ </menu>
+
+ <menu label="Component APIs">
+ <menu-item label="Excel (SS=HSSF+XSSF)" href="spreadsheet/index.html"/>
+ <menu-item label="Word (HWPF+XWPF)" href="hwpf/index.html"/>
+ <menu-item label="PowerPoint (HSLF+XSLF)" href="slideshow/index.html"/>
+ <menu-item label="OpenXML4J (OOXML)" href="oxml4j/index.html"/>
+ <menu-item label="OLE2 Filesystem (POIFS)" href="poifs/index.html"/>
+ <menu-item label="OLE2 Document Props (HPSF)" href="hpsf/index.html"/>
+ <menu-item label="Outlook (HSMF)" href="hsmf/index.html"/>
+ <menu-item label="Visio (HDGF)" href="hdgf/index.html"/>
+ <menu-item label="TNEF (HMEF)" href="hmef/index.html"/>
+ <menu-item label="Publisher (HPBF)" href="hpbf/index.html"/>
+ </menu>
+
+ <menu label="Apache Wide">
+ <menu-item label="Apache Software Foundation" href="http://www.apache.org/" />
+ <menu-item label="License" href="http://www.apache.org/licenses/" />
+ <menu-item label="Sponsorship" href="http://www.apache.org/foundation/sponsorship.html" />
+ <menu-item label="Thanks" href="http://www.apache.org/foundation/thanks.html" />
+ <menu-item label="Security" href="http://www.apache.org/security/" />
+ </menu>
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Case Studies</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="CR" name="Cameron Riley" email="crileyNO@SPAMekmail.com"/>
+ <person id="DF" name="David Fisher" email="dfisher@jmlafferty.com"/>
+ <person id="DS" name="Dominik Stadler" email="centic@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section>
+ <title>Introduction</title>
+ <p>
+ A number of people are using POI for a variety of purposes. As with
+ any new API or technology, the first question people generally ask
+ is not "how can I" but rather "Who else is doing what I'm about to
+ do?" This is understandable with the abysmal success rate in the
+ software business. These case statements are meant to help create
+ confidence and understanding.
+ </p>
+ </section>
+ <section>
+ <title>Submitting a Case Study</title>
+ <p>
+ We are actively seeking case studies for this page (after all it
+ just started). To submit a case study, either
+ <link href="guidelines.html">
+ submit a patch for this page</link> or email it to the
+ <link href="mailinglists.html">mailing list
+ </link> (with [PATCH] prefixed subject, please).
+ </p>
+ </section>
+ <section>
+ <title>Case Studies</title>
+ <section><title>REWOO Scope</title>
+ <p>
+ <link href="http://www.rewoo.de/">REWOO Scope</link> is a modern and easy to use web-based enterprise content management system. It supports knowledge workers and managers in making the right decisions based upon all relevant information.
+ </p>
+ <p>
+ The system uses Apache POI to extract information stored within excel files and use it transparently within REWOO Scope. Thus, POI allows our customers to work in their standard office environment while also having all important information in the REWO Scope system.
+ </p>
+ </section>
+
+ <section><title>QuestionPro</title>
+ <p>
+ <link href="http://www.questionpro.com">QuestionPro</link> is an online service allowing businesses and individuals to create, deploy and do in-depth analysis of Online Surveys. The technology is build on open-source frameworks like Struts, Velocity, POI, Lucene ... the List goes on. The application deployment is on a Linux Application Cluster farm with a Mysql database.
+ </p>
+ <p>
+ There are quite a few competitors delivering similar solutions using Microsoft Technologies like asp and .net. One of the distinct advantages our competitors had over us was the ability to generate Excel Spreadsheets, Access Databases (MDB) etc. on the fly using the Component Object Model (COM) - since their servers were running IIS and they had access to the COM registry and such.
+ </p>
+ <p>
+ QuestionPro's initial solution was to generate CSV files. This was easy however it was a cumbersome process for our clients to download the CSV files and then import them into Excel. Moreover, formatting information could not be preserved or captured using the CSV format. This is where POI came to our rescue. With a POI based solution, we could generate a full report with multiple sheets and all the analytical reports. To keep the solution scalable, we had a dedicated cluster for generating out the reports.
+ </p>
+ <p>
+
+ The Apache-POI project has helped QuestionPro compete with the other players in the marketplace with proprietary technology. It leveled the playing field with respect to reporting and data analysis solutions. It helped in opening doors into closed solutions like Microsoft's CDF. Today about 100 excel reports are generated daily, each with about 10-30 sheets in them.
+ </p>
+
+ <p>
+ Vivek Bhaskaran
+ </p>
+ <p>
+ <link href="http://www.questionpro.com">QuestionPro, Inc</link>
+ </p>
+
+ <p>
+ POI In Action - <link href="http://www.questionpro.com/marketing/SurveyReport-289.xls">http://www.questionpro.com/marketing/SurveyReport-289.xls</link>
+ </p>
+
+ </section>
+
+ <section><title>Sunshine Systems</title>
+ <p>
+ <link href="http://www.sunshinesys.com/">Sunshine Systems</link> deveveloped a
+ POI based reporting solution for a price optimization software package which
+ is used by major retail chains.
+ </p>
+ <p>The solution allowed the retailer's merchandise planners and managers to request a
+ markdown decision support reports and price change reports using a standard browser
+ The users could specify report type, report options, as well as company,
+division,
+ and department filter criteria. Report generation took place in the
+multi-threaded
+ application server and was capable of supporting many simultaneous report requests.
+ </p>
+ <p>The reporting application collected business information from the price
+optimization
+ application's Oracle database. The data was aggregated and summarized
+ based upon the
+ specific report type and filter criteria requested by the user. The
+final report was
+ rendered as a Microsoft Excel spreadsheet using the POI HSSF API and
+ was stored on
+ the report database server for that specific user as a BLOB. Reports
+ could be
+ seamlessly and easily viewed using the same browser.
+ </p>
+ <p>The retailers liked the solution because they had instantaneous access
+ to critical
+ business data through an extremely easy to use browser interface. They
+ did not need
+ to train the broader user community on all the complexities of the optimization
+ application. Furthermore, the reports were generated in an Excel spreadsheet
+format,
+ which everyone was familiar with and which also allowed further data
+ analysis using
+ standard Excel features.
+ </p>
+ <p>Rob Stevenson (rstevenson at sunshinesys dot com)
+ </p>
+ </section>
+ <section>
+ <title>Bank of Lithuania</title>
+ <p>
+ The
+ <link href="http://www.lbank.lt/">Bank of Lithuania</link>
+ reports financial statistical data to Excel format using the
+ <link href="http://poi.apache.org/">Apache POI</link>
+ project's
+ <link href="spreadsheet/">
+ HSSF</link> API. The system is based on Oracle JServer and
+ utilizes a Java stored procedure that outputs to XLS format
+ using the HSSF API. - Arian Lashkov (alaskov at lbank.lt)
+ </p>
+ </section>
+<!-- <section>-->
+<!-- <title>Bit Tracker by Tracker Inc., and ThinkVirtual</title>-->
+<!-- <p>-->
+<!-- Bit Tracker (http://www.bittracker.com/) is the world's first and only web-based drill bit tracking system to manage your company's critical bit information and use that data to its full potential. It manages all bit related data, including their usage, locations, how they were used, and results such as rate of penetration and dull grade after use. This data needs to be available in Excel format for backwards compatibility and other uses in the industry. After using CSV and HTML formats, we needed something better for creating the spreadsheets and POI is the answer. It works great and was easy to implement. Kudos to the POI team.-->
+<!-- </p>-->
+<!-- <p>-->
+<!-- Travis Reeder (travis at thinkvirtual dot com)-->
+<!-- </p>-->
+<!-- </section>-->
+ <section>
+ <title>Edwards And Kelcey Technology</title>
+ <p>
+ Edwards and Kelcey Technology (http://www.ekcorp.com/) developed a
+ Facility
+ Managament and Maintenance System for the Telecommunications industry
+ based
+ on Turbine and Velocity. Originally the invoicing was done with a simple
+ CSV
+ sheet which was then marked up by accounts and customized for each client.
+ As growth has been consistent with the application, the requirement for
+ invoices that need not be touched by hand increased. POI provided the
+ solution to this issue, integrating easily and transparently into the
+ system. POI HSSF was used to create the invoices directly from the server
+ in
+ Excel 97 format and now services over 150 unique invoices per month.
+ </p>
+ <p>
+ Cameron Riley (crileyNO@ SPAMekmail.com)
+ </p>
+ </section>
+ <section>
+ <title>ClickFind</title>
+ <p>
+ <link href="http://www.clickfind.com/">ClickFind Inc.</link> used the POI
+ projects HSSF API to provide their medical
+ research clients with an Excel export from their electronic data
+ collection web service Data Collector 3.0. The POI team's assistance
+ allowed ClickFind to give their clients a data format that requires less
+ technical expertise than the XML format used by the Data Collector
+ application. This was important to ClickFind as many of their current
+ and potential clients are already using Excel in their day-to-day
+ operations and in established procedures for handling their generated
+ clinical data. - Jared Walker (jared.walker at clickfind.com)
+ </p>
+ </section>
+ <section>
+ <title>IKAN Software NV</title>
+ <p>In addition to Change Management and Database Modelling, IKAN Software NV
+ (http://www.ikan.be/) develops and supports its own ETL
+ (Extract/Transform/Load) tools.</p>
+
+ <p>IKAN's latest product is this domain is called ETL4ALL
+ (http://www.ikan.be/etl4all/). ETL4ALL is an open source tool
+ allowing data transfer from and to virtually any data source. Users can
+ combine and examine data stored in relational databases, XML databases, PDF
+ files, EDI, CSV files, etc.
+ </p>
+
+ <p>It is obvious that Microsoft Excel files are also supported.
+ POI has been used to successfully implement this support in ETL4ALL.</p>
+ </section>
+ <section>
+ <title>JM Lafferty Associates, Inc.</title>
+ <p>
+ On its <link href="http://www.forecastworks.com/public/">ForecastWorks</link> website
+ <link href="http://www.jmlafferty.com/">JM Lafferty Associates, Inc.</link> produces dynamic on demand
+ financial analyses of companies and institutional funds. The pages produced are selected and exported
+ in several file formats including PPT and XLS.
+ </p>
+ <ul>
+ <li>The PPT files produced are of high quality which is on a par with similar PDF files.</li>
+ <li>The XLS files produced contain a complex forecasting model built from a template with a VBA Macro.</li>
+ </ul>
+ <p>
+ David Fisher (dfisher@jmlafferty.com)
+ </p>
+ </section>
+
+ <section>
+ <title>iDATA Development Ltd (IDD)</title>
+ <p>
+ <link href="http://www.iexlsoftware.com/">IDD</link> have developed the iEXL product to
+ generate Excel spreadsheets directly on the Iseries/AS400 IBM I on Power platform.
+ </p>
+ <p>
+ Professional spreadsheets created via a menu system. Some basic programming is required for more complex options.
+ When programming is required it can be carried out using RPG, SQL, QUERY, JAVA, COBOL etc.
+ In other words your existing staffs knowledge
+ </p>
+ <p>
+ Design spreadsheets with:
+ </p>
+ <ul>
+ <li>Fonts down to cell level</li>
+ <li>Colours (Background and text) down to cell level</li>
+ <li>Shading down to cell level</li>
+ <li>Cell patterns down to cell level</li>
+ <li>Cell initialization</li>
+ <li>Freeze Panes</li>
+ <li>Passwords</li>
+ <li>Images/Pictures both static and dynamic</li>
+ <li>Headings</li>
+ <li>Page breaks</li>
+ <li>Sheet breaks</li>
+ <li>Text insertion and much more</li>
+ <li>Functions/Formula</li>
+ <li>Merge cells</li>
+ <li>Row Height</li>
+ <li>Cell text alignment</li>
+ <li>Text Rotation </li>
+ <li>50 Database files per workbook.</li>
+ <li>E-mail the spreadsheet</li>
+ </ul>
+ <p>
+ The product name is 'iEXL' and has been live on both European and North American systems for over four years.
+ It is being used in preference to more established commercial products which our clients have already purchased.
+ This is due to cost and ease of use.
+ </p>
+ <p>
+ All spreadsheets can be archived if required so that historical spreadsheets can be retrieved.
+ </p>
+ <p>
+ The system has benefits for all departments within an organisation.
+ Examples of this are accounts department for things such as aged trial balance,
+ distribution department for ASN’s, warehousing for stock figures, IS for security reporting etc.
+ </p>
+ <p>
+ Clients have at this point (June 2012) created over 300 spreadsheets which in turn have generated over
+ 500,000 E-mails. iEXL has a menu driven email system.
+ </p>
+ <p>
+ Due to the Apache-POI project IDD have been able to create the IEXL product.
+ This is a well priced product which allows companies of all sizes access to a product that opens up their reporting capabilities
+ </p>
+ <p>
+ Within the <link href="http://www.iexlsoftware.com/">iEXLSOFTWARE.COM</link> website you will find a full user manual,
+ installation instructions, a call log (Ticket) system and a downloadable 45 day trial version.
+ </p>
+ <p>
+ <em>Author: Mark.D.Golden</em>
+ </p>
+ </section>
+ <section>
+ <title>Ugly Duckling</title>
+ <p>
+ <link href="http://uglyduckling.nl/">Ugly Duckling</link> focus on Software, Management and Finance.
+ We have recently been using Apache POI to create tools for the mortgage group of
+ <link href="https://www.abnamro.nl/en/personal/index.html">ABN AMRO</link> in the Netherlands.
+ During this project we created a number of what we call 'Robots' using the HSSF API.
+ </p>
+ <p>
+ These <link href="http://uglyduckling.nl/work/robots/">robots</link> run as services on the network and
+ help automate the processing of large amounts of data. Our Robots can be used to spot problems that
+ a human might not, and also to automate repetitive tasks.
+ </p>
+ <p>
+ We found Apache POI to be extremely useful. We took the base API, wrapped it in a builder pattern and
+ thus created a DSL with a fluid interface. Throughout the project we enjoyed very much working with
+ Apache POI and found it to be very reliable.
+ </p>
+ </section>
+
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Download Release Artifacts</title>
+ </header>
+
+ <body>
+ <section><title>Available Downloads</title>
+ <p>
+ This page provides instructions on how to download and verify the
+ Apache POI release artifacts. Apache POI is a pure Java library for
+ manipulating Microsoft Documents, for more information please see
+ <link href="index.html">the project homepage</link>.
+ </p>
+ <ul>
+ <li><link href="download.html#POI-3.10-FINAL">The latest stable release is Apache POI 3.10-FINAL</link></li>
+ <li><link href="download.html#archive">Archives of all prior releases</link></li>
+ </ul>
+ <p>
+ Apache POI releases are available under the <link href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0.</link>
+ See the NOTICE file contained in each release artifact for applicable copyright attribution notices.
+ </p>
+ <p>
+ To insure that you have downloaded the true release you should <link href="download.html#verify">verify the integrity</link>
+ of the files using the signatures and checksums available from this page.
+ </p>
+ </section>
+
+ <section id="POI-3.10-FINAL"><title>23 January 2013 - POI 3.10-FINAL available</title>
+ <p>The Apache POI team is pleased to announce the release of 3.10-FINAL.
+ This includes a large number of bug fixes and enhancements.
+ </p>
+ <p>A full list of changes is available in the <link href="changes.html">change log</link>.
+ People interested should also follow the <link href="mailinglists.html">dev list</link> to track progress.</p>
+ <p>
+ The POI source release as well as the pre-built binary deployment packages are listed below.
+ Pre-built versions of all <link href="index.html#components">POI components</link> are available in the central Maven repository
+ under Group ID "org.apache.poi" and Version "3.10-FINAL".
+ </p>
+ <section><title>Binary Distribution</title>
+ <ul>
+ <li><link href="http://www.apache.org/dyn/closer.cgi/poi/release/bin/poi-bin-3.10-FINAL-20140208.tar.gz">poi-bin-3.10-FINAL-20140208.tar.gz</link> (
+ 16MB, <link href="http://www.apache.org/dist/poi/release/bin/poi-bin-3.10-FINAL-20140208.tar.gz.asc">signed</link>)
+ <br/>
+ MD5 checksum: <link href="http://www.apache.org/dist/poi/release/bin/poi-bin-3.10-FINAL-20140208.tar.gz.md5">
+ 818d1e99a2efe539ba49f622b554950c</link>
+ <br/>
+ SHA1 checksum: <link href="http://www.apache.org/dist/poi/release/bin/poi-bin-3.10-FINAL-20140208.tar.gz.sha1">
+ 38b61905d780e09604fb8053fd46ab1b8b18392f</link>
+ </li>
+ <li><link href="http://www.apache.org/dyn/closer.cgi/poi/release/bin/poi-bin-3.10-FINAL-20140208.zip">poi-bin-3.10-FINAL-20140208.zip</link> (
+ 23MB, <link href="http://www.apache.org/dist/poi/release/bin/poi-bin-3.10-FINAL-20140208.zip.asc">signed</link>)
+ <br/>
+ MD5 checksum: <link href="http://www.apache.org/dist/poi/release/bin/poi-bin-3.10-FINAL-20140208.zip.md5">
+ e304be0a3169697d31e029f63458a963</link>
+ <br/>
+ SHA1 checksum: <link href="http://www.apache.org/dist/poi/release/bin/poi-bin-3.10-FINAL-20140208.zip.sha1">
+ 704f103bca893e3d4df5c2cc95d275b0cd5d0b33</link>
+ </li>
+ </ul>
+ </section>
+ <section><title>Source Distribution</title>
+ <ul>
+ <li><link href="http://www.apache.org/dyn/closer.cgi/poi/release/src/poi-bin-3.10-FINAL-20140208.tar.gz">poi-src-3.10-FINAL-20140208.tar.gz</link> (
+ 48MB, <link href="http://www.apache.org/dist/poi/release/src/poi-src-3.10-FINAL-20140208.tar.gz.asc">signed</link>)
+ <br/>
+ MD5 checksum: <link href="http://www.apache.org/dist/poi/release/src/poi-src-3.10-FINAL-20140208.tar.gz.md5">
+ 438157bfee9fe74869abd898820c7dae</link>
+ <br/>
+ SHA1 checksum: <link href="http://www.apache.org/dist/poi/release/src/poi-src-3.10-FINAL-20140208.tar.gz.sha1">
+ d0d5f596a649d1a852916fbadec4bdd9bdf70b9e</link>
+ </li>
+ <li><link href="http://www.apache.org/dyn/closer.cgi/poi/release/src/poi-src-3.10-FINAL-20140208.zip">poi-src-3.10-FINAL-20140208.zip</link> (
+ 58MB, <link href="http://www.apache.org/dist/poi/release/src/poi-src-3.10-FINAL-20140208.zip.asc">signed</link>)
+ <br/>
+ MD5 checksum: <link href="http://www.apache.org/dist/poi/release/src/poi-src-3.10-FINAL-20140208.zip.md5">
+ 95536ea16e0e97a3f02f0294a1835b74</link>
+ <br/>
+ SHA1 checksum: <link href="http://www.apache.org/dist/poi/release/src/poi-src-3.10-FINAL-20140208.zip.sha1">
+ 8cc6ad470852295a8af7f08848a8ad9c84f177d1</link>
+ </li>
+ </ul>
+ </section>
+ </section>
+
+ <section><title>Nightly Builds</title>
+ <p>The POI nightly builds are run on <link href="https://builds.apache.org/job/POI/">Jenkins</link> continuous integration server.
+ Note that these are no official builds and they are not endorsed or even supported by the POI team.
+ <br/>
+ <strong>These builds should not be used in production</strong>: they are only intended for use by developers
+ to help with resolving bugs and evaluating new features.
+ </p>
+ <ul>
+ <li><link href="https://builds.apache.org/job/POI/lastSuccessfulBuild/artifact/build/dist/">
+ Last Successful Jenkins build for POI-trunk</link></li>
+ </ul>
+ </section>
+
+ <section id="verify"><title>Verify</title>
+ <p>
+ It is essential that you verify the integrity of the downloaded files using the PGP or MD5 signatures.
+ Please read <link href="http://httpd.apache.org/dev/verification.html">Verifying Apache HTTP Server Releases</link>
+ for more information on why you should verify our releases. This page provides detailed instructions which you can use for POI artifacts.
+ </p>
+ <p>
+ The PGP signatures can be verified using PGP or GPG. First download the KEYS file as well as the .asc signature files
+ for the relevant release packages. Make sure you get these files from the main distribution directory,
+ rather than from a mirror. Then verify the signatures using
+ </p>
+ <source>
+% pgpk -a KEYS
+% pgpv poi-X.Y.Z.jar.asc
+ </source>
+ <p>or</p>
+ <source>
+% pgp -ka KEYS
+% pgp poi-X.Y.Z.jar.asc
+ </source>
+ <p>or</p>
+ <source>
+% gpg --import KEYS
+% gpg --verify poi-X.Y.Z.jar.asc
+ </source>
+ <p>Sample verification of poi-bin-3.5-FINAL-20090928.tar.gz</p>
+ <source>
+% gpg --import KEYS
+gpg: key 12DAE9BE: "Glen Stampoultzis <glens at apache dot org>" not changed
+gpg: key 4CEED75F: "Nick Burch <nick at gagravarr dot org>" not changed
+gpg: key 84B5A42E: "Rainer Klute <rainer.klute at gmx dot de>" not changed
+gpg: key F5BB52CD: "Yegor Kozlov <yegor.kozlov at gmail dot com>" not changed
+gpg: Total number processed: 4
+gpg: unchanged: 4
+% gpg --verify poi-bin-3.5-FINAL-20090928.tar.gz.asc
+gpg: Signature made Mon Sep 28 10:28:25 2009 PDT using DSA key ID F5BB52CD
+gpg: Good signature from "Yegor Kozlov <yegor.kozlov at gmail dot com>"
+gpg: aka "Yegor Kozlov <yegor at dinom dot ru>"
+gpg: aka "Yegor Kozlov <yegor at apache dot org>"
+Primary key fingerprint: 7D77 0C77 6CE7 754E E6AF 23AA 6934 0A02 F5BB 52CD
+% gpg --fingerprint F5BB52CD
+pub 1024D/F5BB52CD 2007-06-18 [expires: 2012-06-16]
+ Key fingerprint = 7D77 0C77 6CE7 754E E6AF 23AA 6934 0A02 F5BB 52CD
+uid Yegor Kozlov <yegor.kozlov at gmail dot com>
+uid Yegor Kozlov <yegor at dinom dot ru>
+uid Yegor Kozlov <yegor at apache dot org>
+sub 4096g/7B45A98A 2007-06-18 [expires: 2012-06-16]
+ </source>
+ </section>
+ <section id="archive"><title>Release Archives</title>
+ <p>
+ Apache POI became a top level project in June 2007 and POI 3.0 aritfacts were re-released.
+ Prior to that date POI was a sub-project of <link href="http://jakarta.apache.org/">Apache Jakarta.</link>
+ </p>
+ <ul>
+ <li><link href="http://archive.apache.org/dist/poi/release/bin/">Binary Artifacts</link></li>
+ <li><link href="http://archive.apache.org/dist/poi/release/src/">Source Artifacts</link></li>
+ <li><link href="http://archive.apache.org/dist/poi/">Keys</link></li>
+ <li><link href="http://archive.apache.org/dist/jakarta/poi/release/">Artifacts from prior to 3.0</link></li>
+ </ul>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOdia PUBLIC
+ "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML">
+ %ISOdia;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+ This entity set uses hexadecimal numeric character references.
+
+ Creator: Rick Jelliffe, Allette Systems
+
+ Version: 1997-07-07
+-->
+
+<!ENTITY acute "´" ><!--=acute accent-->
+<!ENTITY breve "˘" ><!--=breve-->
+<!ENTITY caron "ˇ" ><!--=caron-->
+<!ENTITY cedil "¸" ><!--=cedilla-->
+<!ENTITY circ "^" ><!--=circumflex accent-->
+<!ENTITY dblac "˝" ><!--=double acute accent-->
+<!ENTITY die "¨" ><!--=dieresis-->
+<!ENTITY dot "˙" ><!--=dot above-->
+<!ENTITY grave "`" ><!--=grave accent-->
+<!ENTITY macr "¯" ><!--=macron-->
+<!ENTITY ogon "˛" ><!--=ogonek-->
+<!ENTITY ring "˚" ><!--=ring-->
+<!ENTITY tilde "˜" ><!--=tilde-->
+<!ENTITY uml "¨" ><!--=umlaut mark-->
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOlat1 PUBLIC
+ "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML">
+ %ISOlat1;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 8859-1 or ISO 10646 as its document character
+ set. This includes XML documents and ISO HTML documents.
+-->
+
+ <!ENTITY Agrave "À" ><!-- capital A, grave accent -->
+ <!ENTITY Aacute "Á" ><!-- capital A, acute accent -->
+ <!ENTITY Acirc "Â" ><!-- capital A, circumflex accent -->
+ <!ENTITY Atilde "Ã" ><!-- capital A, tilde -->
+ <!ENTITY Auml "Ä" ><!-- capital A, dieresis or umlaut mark -->
+ <!ENTITY Aring "Å" ><!-- capital A, ring -->
+ <!ENTITY AElig "Æ" ><!-- capital AE diphthong (ligature) -->
+ <!ENTITY Ccedil "Ç" ><!-- capital C, cedilla -->
+ <!ENTITY Egrave "È" ><!-- capital E, grave accent -->
+ <!ENTITY Eacute "É" ><!-- capital E, acute accent -->
+ <!ENTITY Ecirc "Ê" ><!-- capital E, circumflex accent -->
+ <!ENTITY Euml "Ë" ><!-- capital E, dieresis or umlaut mark -->
+ <!ENTITY Igrave "Ì" ><!-- capital I, grave accent -->
+ <!ENTITY Iacute "Í" ><!-- capital I, acute accent -->
+ <!ENTITY Icirc "Î" ><!-- capital I, circumflex accent -->
+ <!ENTITY Iuml "Ï" ><!-- capital I, dieresis or umlaut mark -->
+ <!ENTITY ETH "Ð" ><!-- capital Eth, Icelandic -->
+ <!ENTITY Ntilde "Ñ" ><!-- capital N, tilde -->
+ <!ENTITY Ograve "Ò" ><!-- capital O, grave accent -->
+ <!ENTITY Oacute "Ó" ><!-- capital O, acute accent -->
+ <!ENTITY Ocirc "Ô" ><!-- capital O, circumflex accent -->
+ <!ENTITY Otilde "Õ" ><!-- capital O, tilde -->
+ <!ENTITY Ouml "Ö" ><!-- capital O, dieresis or umlaut mark -->
+ <!ENTITY Oslash "Ø" ><!-- capital O, slash -->
+ <!ENTITY Ugrave "Ù" ><!-- capital U, grave accent -->
+ <!ENTITY Uacute "Ú" ><!-- capital U, acute accent -->
+ <!ENTITY Ucirc "Û" ><!-- capital U, circumflex accent -->
+ <!ENTITY Uuml "Ü" ><!-- capital U, dieresis or umlaut mark -->
+ <!ENTITY Yacute "Ý" ><!-- capital Y, acute accent -->
+ <!ENTITY THORN "Þ" ><!-- capital THORN, Icelandic -->
+ <!ENTITY szlig "ß" ><!-- small sharp s, German (sz ligature) -->
+ <!ENTITY agrave "à" ><!-- small a, grave accent -->
+ <!ENTITY aacute "á" ><!-- small a, acute accent -->
+ <!ENTITY acirc "â" ><!-- small a, circumflex accent -->
+ <!ENTITY atilde "ã" ><!-- small a, tilde -->
+ <!ENTITY auml "ä" ><!-- small a, dieresis or umlaut mark -->
+ <!ENTITY aring "å" ><!-- small a, ring -->
+ <!ENTITY aelig "æ" ><!-- small ae diphthong (ligature) -->
+ <!ENTITY ccedil "ç" ><!-- small c, cedilla -->
+ <!ENTITY egrave "è" ><!-- small e, grave accent -->
+ <!ENTITY eacute "é" ><!-- small e, acute accent -->
+ <!ENTITY ecirc "ê" ><!-- small e, circumflex accent -->
+ <!ENTITY euml "ë" ><!-- small e, dieresis or umlaut mark -->
+ <!ENTITY igrave "ì" ><!-- small i, grave accent -->
+ <!ENTITY iacute "í" ><!-- small i, acute accent -->
+ <!ENTITY icirc "î" ><!-- small i, circumflex accent -->
+ <!ENTITY iuml "ï" ><!-- small i, dieresis or umlaut mark -->
+ <!ENTITY eth "ð" ><!-- small eth, Icelandic -->
+ <!ENTITY ntilde "ñ" ><!-- small n, tilde -->
+ <!ENTITY ograve "ò" ><!-- small o, grave accent -->
+ <!ENTITY oacute "ó" ><!-- small o, acute accent -->
+ <!ENTITY ocirc "ô" ><!-- small o, circumflex accent -->
+ <!ENTITY otilde "õ" ><!-- small o, tilde -->
+ <!ENTITY ouml "ö" ><!-- small o, dieresis or umlaut mark -->
+
+ <!ENTITY oslash "ø" ><!-- small o, slash -->
+ <!ENTITY ugrave "ù" ><!-- small u, grave accent -->
+ <!ENTITY uacute "ú" ><!-- small u, acute accent -->
+ <!ENTITY ucirc "û" ><!-- small u, circumflex accent -->
+ <!ENTITY uuml "ü" ><!-- small u, dieresis or umlaut mark -->
+ <!ENTITY yacute "ý" ><!-- small y, acute accent -->
+ <!ENTITY thorn "þ" ><!-- small thorn, Icelandic -->
+ <!ENTITY yuml "ÿ" ><!-- small y, dieresis or umlaut mark -->
+
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOnum PUBLIC
+ "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML">
+ %ISOnum;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+ This entity set uses hexadecimal numeric character references.
+
+ Creator: Rick Jelliffe, Allette Systems
+
+ Version: 1997-07-07
+-->
+
+<!ENTITY half "½" ><!--=fraction one-half-->
+<!ENTITY frac12 "½" ><!--=fraction one-half-->
+<!ENTITY frac14 "¼" ><!--=fraction one-quarter-->
+<!ENTITY frac34 "¾" ><!--=fraction three-quarters-->
+<!ENTITY frac18 "⅛" >
+ <!-- or "±Ȃ⁄₈" --><!--=fraction one-eighth-->
+<!ENTITY frac38 "⅜" >
+ <!-- or "³⁄₈" --><!--=fraction three-eighths-->
+<!ENTITY frac58 "⅝" >
+ <!-- or "⁵⁄₈" --><!--=fraction five-eighths-->
+<!ENTITY frac78 "⅞" >
+ <!-- or "⁷⁄₈" --><!--=fraction seven-eighths-->
+
+<!ENTITY sup1 "¹" ><!--=superscript one-->
+<!ENTITY sup2 "²" ><!--=superscript two-->
+<!ENTITY sup3 "³" ><!--=superscript three-->
+
+<!ENTITY plus "+" ><!--=plus sign B:-->
+<!ENTITY plusmn "±" ><!--/pm B: =plus-or-minus sign-->
+<!ENTITY lt "&#60;" ><!--=less-than sign R:-->
+<!ENTITY equals "=" ><!--=equals sign R:-->
+<!ENTITY gt ">" ><!--=greater-than sign R:-->
+<!ENTITY divide "÷" ><!--/div B: =divide sign-->
+<!ENTITY times "×" ><!--/times B: =multiply sign-->
+
+<!ENTITY curren "¤" ><!--=general currency sign-->
+<!ENTITY pound "£" ><!--=pound sign-->
+<!ENTITY dollar "$" ><!--=dollar sign-->
+<!ENTITY cent "¢" ><!--=cent sign-->
+<!ENTITY yen "¥" ><!--/yen =yen sign-->
+
+<!ENTITY num "#" ><!--=number sign-->
+<!ENTITY percnt "%" ><!--=percent sign-->
+<!ENTITY amp "&#38;" ><!--=ampersand-->
+<!ENTITY ast "*" ><!--/ast B: =asterisk-->
+<!ENTITY commat "@" ><!--=commercial at-->
+<!ENTITY lsqb "[" ><!--/lbrack O: =left square bracket-->
+<!ENTITY bsol "\" ><!--/backslash =reverse solidus-->
+<!ENTITY rsqb "]" ><!--/rbrack C: =right square bracket-->
+<!ENTITY lcub "{" ><!--/lbrace O: =left curly bracket-->
+<!ENTITY horbar "―" ><!--=horizontal bar-->
+<!ENTITY verbar "|" ><!--/vert =vertical bar-->
+<!ENTITY rcub "}" ><!--/rbrace C: =right curly bracket-->
+<!ENTITY micro "µ" ><!--=micro sign-->
+<!ENTITY ohm "ࡎ" ><!--=ohm sign-->
+<!ENTITY deg "°" ><!--=degree sign-->
+<!ENTITY ordm "º" ><!--=ordinal indicator, masculine-->
+<!ENTITY ordf "ª" ><!--=ordinal indicator, feminine-->
+<!ENTITY sect "§" ><!--=section sign-->
+<!ENTITY para "¶" ><!--=pilcrow (paragraph sign)-->
+<!ENTITY middot "·" ><!--/centerdot B: =middle dot-->
+<!ENTITY larr "←" ><!--/leftarrow /gets A: =leftward arrow-->
+<!ENTITY rarr "→" ><!--/rightarrow /to A: =rightward arrow-->
+<!ENTITY uarr "↑" ><!--/uparrow A: =upward arrow-->
+<!ENTITY darr "↓" ><!--/downarrow A: =downward arrow-->
+<!ENTITY copy "©" ><!--=copyright sign-->
+<!ENTITY reg "®" ><!--/circledR =registered sign-->
+<!ENTITY trade "™" ><!--=trade mark sign-->
+<!ENTITY brvbar "¦" ><!--=bren (vertical) bar-->
+<!ENTITY not "¬" ><!--/neg /lnot =not sign-->
+<!ENTITY sung "♪" ><!--=music note (sung text sign)-->
+
+<!ENTITY excl "!" ><!--=exclamation mark-->
+<!ENTITY iexcl "¡" ><!--=inverted exclamation mark-->
+<!ENTITY quot '"' ><!--=quotation mark-->
+<!ENTITY apos "'" ><!--=apostrophe-->
+<!ENTITY lpar "(" ><!--O: =left parenthesis-->
+<!ENTITY rpar ")" ><!--C: =right parenthesis-->
+<!ENTITY comma "," ><!--P: =comma-->
+<!ENTITY lowbar "_" ><!--=low line-->
+<!ENTITY hyphen "‐" ><!--=hyphen-->
+<!ENTITY period "." ><!--=full stop, period-->
+<!ENTITY sol "/" ><!--=solidus-->
+<!ENTITY colon ":" ><!--/colon P:-->
+<!ENTITY semi ";" ><!--=semicolon P:-->
+<!ENTITY quest "?" ><!--=question mark-->
+<!ENTITY iquest "¿" ><!--=inverted question mark-->
+<!ENTITY laquo "‹" ><!--=angle quotation mark, left
+ But note that Unicode 1 & Maler & el Andaloussi give « -->
+<!ENTITY raquo "›" ><!--=angle quotation mark, right
+ But note that Unicode 1 & Maler & el Andaloussi give » -->
+<!ENTITY lsquo "‘" ><!--=single quotation mark, left-->
+<!ENTITY rsquo "’" ><!--=single quotation mark, right-->
+<!ENTITY ldquo "“" ><!--=double quotation mark, left-->
+<!ENTITY rdquo "”" ><!--=double quotation mark, right-->
+<!ENTITY nbsp " " ><!--=no break (required) space-->
+<!ENTITY shy "­" ><!--=soft hyphen-->
+
+
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOpub PUBLIC
+ "ISO 8879:1986//ENTITIES Publishing//EN//XML">
+ %ISOpub;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+ This entity set uses hexadecimal numeric character references.
+
+ Creator: Rick Jelliffe, Allette Systems
+
+ Version: 1997-07-07
+-->
+<!ENTITY emsp " " ><!--=em space-->
+<!ENTITY ensp " " ><!--=en space (1/2-em)-->
+<!ENTITY emsp13 " " ><!--=1/3-em space-->
+<!ENTITY emsp14 " " ><!--=1/4-em space-->
+<!ENTITY numsp " " ><!--=digit space (width of a number)-->
+<!ENTITY puncsp " " ><!--=punctuation space (width of comma)-->
+<!ENTITY thinsp " " ><!--=thin space (1/6-em)-->
+<!ENTITY hairsp " " ><!--=hair space-->
+<!ENTITY mdash "—" ><!--=em dash-->
+<!ENTITY ndash "–" ><!--=en dash-->
+<!ENTITY dash "‐" ><!--=hyphen (true graphic)-->
+<!ENTITY blank "␣" ><!--=significant blank symbol-->
+<!ENTITY hellip "…" ><!--=ellipsis (horizontal)-->
+<!ENTITY nldr "‥" ><!--=double baseline dot (en leader)-->
+<!ENTITY frac13 "⅓" ><!--=fraction one-third-->
+<!ENTITY frac23 "⅔" ><!--=fraction two-thirds-->
+<!ENTITY frac15 "⅕" ><!--=fraction one-fifth-->
+<!ENTITY frac25 "⅖" ><!--=fraction two-fifths-->
+<!ENTITY frac35 "⅗" ><!--=fraction three-fifths-->
+<!ENTITY frac45 "⅘" ><!--=fraction four-fifths-->
+<!ENTITY frac16 "⅙" ><!--=fraction one-sixth-->
+<!ENTITY frac56 "⅚" ><!--=fraction five-sixths-->
+<!ENTITY incare "℅" ><!--=in-care-of symbol-->
+<!ENTITY block "█" ><!--=full block-->
+<!ENTITY uhblk "▀" ><!--=upper half block-->
+<!ENTITY lhblk "▄" ><!--=lower half block-->
+<!ENTITY blk14 "░" ><!--=25% shaded block-->
+<!ENTITY blk12 "▒" ><!--=50% shaded block-->
+<!ENTITY blk34 "▓" ><!--=75% shaded block-->
+<!ENTITY marker "▮" ><!--=histogram marker-->
+<!ENTITY cir "○" ><!--/circ B: =circle, open-->
+<!ENTITY squ "□" ><!--=square, open-->
+<!ENTITY rect "▭" ><!--=rectangle, open-->
+<!ENTITY utri "▵" ><!--/triangle =up triangle, open-->
+<!ENTITY dtri "▿" ><!--/triangledown =down triangle, open-->
+<!ENTITY star "☆" ><!--=star, open-->
+<!ENTITY bull "•" ><!--/bullet B: =round bullet, filled-->
+<!ENTITY squf "▪" ><!--/blacksquare =sq bullet, filled-->
+<!ENTITY utrif "▴" ><!--/blacktriangle =up tri, filled-->
+<!ENTITY dtrif "▾" ><!--/blacktriangledown =dn tri, filled-->
+<!ENTITY ltrif "◂" ><!--/blacktriangleleft R: =l tri, filled-->
+<!ENTITY rtrif "▸" ><!--/blacktriangleright R: =r tri, filled-->
+<!ENTITY clubs "♣" ><!--/clubsuit =club suit symbol-->
+<!ENTITY diams "♢" ><!--/diamondsuit =diamond suit symbol-->
+<!ENTITY hearts "♡" ><!--/heartsuit =heart suit symbol-->
+<!ENTITY spades "♠" ><!--/spadesuit =spades suit symbol-->
+<!ENTITY malt "✠" ><!--/maltese =maltese cross-->
+<!ENTITY dagger "†" ><!--/dagger B: =dagger-->
+<!ENTITY Dagger "‡" ><!--/ddagger B: =double dagger-->
+<!ENTITY check "✓" ><!--/checkmark =tick, check mark-->
+<!ENTITY cross "✗" ><!--=ballot cross-->
+<!ENTITY sharp "♯" ><!--/sharp =musical sharp-->
+<!ENTITY flat "♭" ><!--/flat =musical flat-->
+<!ENTITY male "♂" ><!--=male symbol-->
+<!ENTITY female "♀" ><!--=female symbol-->
+<!ENTITY phone "⛠" ><!--=telephone symbol-->
+<!ENTITY telrec "⌕" ><!--=telephone recorder symbol-->
+<!ENTITY copysr "℗" ><!--=sound recording copyright sign-->
+<!ENTITY caret "⁁" ><!--=caret (insertion mark)-->
+<!ENTITY lsquor "‚" ><!--=rising single quote, left (low)-->
+<!ENTITY ldquor "„" ><!--=rising dbl quote, left (low)-->
+
+<!ENTITY fflig "ff" ><!--small ff ligature-->
+<!ENTITY filig "fi" ><!--small fi ligature-->
+<!ENTITY fjlig "fj" ><!--small fj ligature-->
+<!ENTITY ffilig "ffi" ><!--small ffi ligature-->
+<!ENTITY ffllig "ffl" ><!--small ffl ligature-->
+<!ENTITY fllig "fl" ><!--small fl ligature-->
+
+<!ENTITY mldr "‥" ><!--em leader-->
+<!ENTITY rdquor "”" ><!--rising dbl quote, right (high)-->
+<!ENTITY rsquor "’" ><!--rising single quote, right (high)-->
+<!ENTITY vellip "⋮" ><!--vertical ellipsis-->
+
+<!ENTITY hybull "⁃" ><!--rectangle, filled (hyphen bullet)-->
+<!ENTITY loz "✧" ><!--/lozenge - lozenge or total mark-->
+<!ENTITY lozf "✦" ><!--/blacklozenge - lozenge, filled-->
+<!ENTITY ltri "◃" ><!--/triangleleft B: l triangle, open-->
+<!ENTITY rtri "▹" ><!--/triangleright B: r triangle, open-->
+<!ENTITY starf "★" ><!--/bigstar - star, filled-->
+
+<!ENTITY natur "♮" ><!--/natural - music natural-->
+<!ENTITY rx "℞" ><!--pharmaceutical prescription (Rx)-->
+<!ENTITY sext "✶" ><!--sextile (6-pointed star)-->
+
+<!ENTITY target "⌖" ><!--register mark or target-->
+<!ENTITY dlcrop "⌍" ><!--downward left crop mark -->
+<!ENTITY drcrop "⌌" ><!--downward right crop mark -->
+<!ENTITY ulcrop "⌏" ><!--upward left crop mark -->
+<!ENTITY urcrop "⌎" ><!--upward right crop mark -->
+
--- /dev/null
+
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOtech PUBLIC
+ "ISO 8879:1986//ENTITIES General Technical//EN//XML"
+ "ISOtech.pen">
+ %ISOtech;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+ This entity set uses hexadecimal numeric character references.
+
+ Creator: Rick Jelliffe, Allette Systems
+
+ Version: 1997-07-07
+-->
+<!ENTITY aleph "ℵ" ><!--/aleph =aleph, Hebrew-->
+<!ENTITY and "∧" ><!--/wedge /land B: =logical and-->
+<!ENTITY ang90 "∟" ><!--=right (90 degree) angle-->
+<!ENTITY angsph "∢" ><!--/sphericalangle =angle-spherical-->
+<!ENTITY ap "≉" ><!--/approx R: =approximate-->
+<!ENTITY becaus "∵" ><!--/because R: =because-->
+<!ENTITY bottom "⊥" ><!--/bot B: =perpendicular-->
+<!ENTITY cap "∩" ><!--/cap B: =intersection-->
+<!ENTITY cong "≅" ><!--/cong R: =congruent with-->
+<!ENTITY conint "∮" ><!--/oint L: =contour integral operator-->
+<!ENTITY cup "∪" ><!--/cup B: =union or logical sum-->
+<!ENTITY equiv "≡" ><!--/equiv R: =identical with-->
+<!ENTITY exist "∃" ><!--/exists =at least one exists-->
+<!ENTITY forall "∀" ><!--/forall =for all-->
+<!ENTITY fnof "ƒ" ><!--=function of (italic small f)-->
+<!ENTITY ge "≥" ><!--/geq /ge R: =greater-than-or-equal-->
+<!ENTITY iff "⇔" ><!--/iff =if and only if-->
+<!ENTITY infin "∞" ><!--/infty =infinity-->
+<!ENTITY int "∫" ><!--/int L: =integral operator-->
+<!ENTITY isin "∈" ><!--/in R: =set membership-->
+<!ENTITY lang "〈" ><!--/langle O: =left angle bracket-->
+<!ENTITY lArr "⇐" ><!--/Leftarrow A: =is implied by-->
+<!ENTITY le "≤" ><!--/leq /le R: =less-than-or-equal-->
+<!ENTITY minus "-" ><!--B: =minus sign-->
+<!ENTITY mnplus "∓" ><!--/mp B: =minus-or-plus sign-->
+<!ENTITY nabla "∇" ><!--/nabla =del, Hamilton operator-->
+<!ENTITY ne "≠" ><!--/ne /neq R: =not equal-->
+<!ENTITY ni "∋" ><!--/ni /owns R: =contains-->
+<!ENTITY or "∨" ><!--/vee /lor B: =logical or-->
+<!ENTITY par "∥" ><!--/parallel R: =parallel-->
+<!ENTITY part "∂" ><!--/partial =partial differential-->
+<!ENTITY permil "‰" ><!--=per thousand-->
+<!ENTITY perp "⊥" ><!--/perp R: =perpendicular-->
+<!ENTITY prime "′" ><!--/prime =prime or minute-->
+<!ENTITY Prime "″" ><!--=double prime or second-->
+<!ENTITY prop "∝" ><!--/propto R: =is proportional to-->
+<!ENTITY radic "√" ><!--/surd =radical-->
+<!ENTITY rang "〉" ><!--/rangle C: =right angle bracket-->
+<!ENTITY rArr "⇒" ><!--/Rightarrow A: =implies-->
+<!ENTITY sim "∼" ><!--/sim R: =similar-->
+<!ENTITY sime "≃" ><!--/simeq R: =similar, equals-->
+<!ENTITY square "□" ><!--/square B: =square-->
+<!ENTITY sub "⊂" ><!--/subset R: =subset or is implied by-->
+<!ENTITY sube "⊆" ><!--/subseteq R: =subset, equals-->
+<!ENTITY sup "⊃" ><!--/supset R: =superset or implies-->
+<!ENTITY supe "⊇" ><!--/supseteq R: =superset, equals-->
+<!ENTITY there4 "∴" ><!--/therefore R: =therefore-->
+<!ENTITY Verbar "‖" ><!--/Vert =dbl vertical bar-->
+
+<!ENTITY angst "Å" ><!--Angstrom =capital A, ring-->
+<!ENTITY bernou "ℬ" ><!--Bernoulli function (script capital B)-->
+<!ENTITY compfn "∘" ><!--B: composite function (small circle)-->
+<!ENTITY Dot "¨" ><!--=dieresis or umlaut mark-->
+<!ENTITY DotDot "⃜" ><!--four dots above-->
+<!ENTITY hamilt "ℋ" ><!--Hamiltonian (script capital H)-->
+<!ENTITY lagran "ℒ" ><!--Lagrangian (script capital L)-->
+<!ENTITY lowast "∗" ><!--low asterisk-->
+<!ENTITY notin "∉" ><!--N: negated set membership-->
+<!ENTITY order "ℴ" ><!--order of (script small o)-->
+<!ENTITY phmmat "ℳ" ><!--physics M-matrix (script capital M)-->
+<!ENTITY tdot "⃛" ><!--three dots above-->
+<!ENTITY tprime "‴" ><!--triple prime-->
+<!ENTITY wedgeq "≙" ><!--R: corresponds to (wedge, equals)-->
+
--- /dev/null
+<!-- ===================================================================
+
+ Apache Cocoon Documentation Book DTD (Version 1.0)
+
+PURPOSE:
+This DTD defines the */book.xml documentation configuration files.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE book PUBLIC
+ "-//APACHE//DTD Cocoon Documentation Book Vx.yz//EN"
+ "book-cocoon-vxyz.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+ z := status identifier (optional)
+
+NOTES:
+We need to replace this DTD with the proper one.
+We are only using this DTD to enable validation during "build docs"
+because every XML instance must declare its ruleset.
+
+This initial minimal DTD has been reverse-engineered from the structure
+of the current documents, e.g.
+ documentation/xdocs/book.xml
+
+AUTHORS:
+ David Crossley <crossley@apache.org>
+
+FIXME:
+ - find the proper DTD for book.xml
+
+CHANGE HISTORY:
+ 20011031 Initial version. (DC)
+
+COPYRIGHT:
+ Copyright (c) @year@ The Apache Software Foundation.
+
+ Permission to copy in any form is granted provided this notice is
+ included in all copies. Permission to redistribute is granted
+ provided this file is distributed untouched in all its parts and
+ included files.
+
+==================================================================== -->
+
+<!ELEMENT book (menu+)>
+<!ELEMENT menu (menu-item|external)*>
+<!ELEMENT menu-item EMPTY>
+<!ELEMENT external EMPTY>
+<!ATTLIST book software CDATA #REQUIRED
+ title CDATA #REQUIRED
+ copyright CDATA #REQUIRED
+ xmlns:xlink CDATA #IMPLIED
+>
+<!ATTLIST menu label CDATA #REQUIRED
+>
+<!ATTLIST menu-item label CDATA #REQUIRED
+ href CDATA #REQUIRED
+ type (visible|hidden) "visible"
+>
+<!ATTLIST external label CDATA #REQUIRED
+ href CDATA #REQUIRED
+ type (visible|hidden) "visible"
+>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!-- ===================================================================
+
+ Apache Changes DTD (Version 1.1)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software development changes for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE document PUBLIC
+ "-//APACHE//DTD Changes Vx.y//EN"
+ "changes-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ It is important, expecially in open developped software projects, to keep
+ track of software changes both to give users indications of bugs that might
+ have been resolved, as well, and not less important, to provide credits
+ for the support given to the project. It is considered vital to provide
+ adequate payback using recognition and credits to let users and developers
+ feel part of the community, thus increasing development power.
+
+AUTHORS:
+ Stefano Mazzocchi <stefano@apache.org>
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+ 19991129 Initial version. (SM)
+ 20000316 Added bugfixing attribute. (SM)
+[Version 1.1]
+ 20011212 Used public identifiers for external entities (SM)
+
+COPYRIGHT:
+ Copyright (c) @year@ The Apache Software Foundation.
+
+ Permission to copy in any form is granted provided this notice is
+ included in all copies. Permission to redistribute is granted
+ provided this file is distributed untouched in all its parts and
+ included files.
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Include the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+ "-//APACHE//DTD Documentation V1.1//EN"
+ "document-v11.dtd">
+%document;
+
+<!-- =============================================================== -->
+<!-- Common entities -->
+<!-- =============================================================== -->
+
+<!ENTITY % types "add|remove|update|fix|unknown">
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ELEMENT changes (devs, release*)>
+<!ATTLIST changes %common.att;
+ %title.att;>
+
+ <!ELEMENT devs (person+)>
+ <!ATTLIST devs %common.att;>
+
+ <!ELEMENT release (action+)>
+ <!ATTLIST release %common.att;
+ version CDATA #REQUIRED
+ date CDATA #REQUIRED>
+
+ <!ELEMENT action (%content.mix;)*>
+ <!ATTLIST action %common.att;
+ dev IDREF #REQUIRED
+ type (%types;) #IMPLIED
+ due-to CDATA #IMPLIED
+ due-to-email CDATA #IMPLIED
+ fixes-bug CDATA #IMPLIED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Changes Module (Version 1.1)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software development changes for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!ENTITY % changes PUBLIC
+ "-//APACHE//ENTITIES Changes Vxy//EN"
+ "changes-vxy.mod">
+ %changes;
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ It is important, expecially in open developped software projects, to keep
+ track of software changes both to give users indications of bugs that might
+ have been resolved, as well, and not less important, to provide credits
+ for the support given to the project. It is considered vital to provide
+ adequate payback using recognition and credits to let users and developers
+ feel part of the community, thus increasing development power.
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+ 19991129 Initial version. (SM)
+ 20000316 Added bugfixing attribute. (SM)
+[Version 1.1]
+ 20011212 Used public identifiers for external entities (SM)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ELEMENT changes (title?, devs?, release+)>
+<!ATTLIST changes %common.att;>
+
+ <!ELEMENT release (action+)>
+ <!ATTLIST release %common.att;
+ version CDATA #REQUIRED
+ date CDATA #REQUIRED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Changes DTD (Version 1.2)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software development changes for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE document PUBLIC
+ "-//APACHE//DTD Changes Vx.y//EN"
+ "changes-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ It is important, expecially in open developped software projects, to keep
+ track of software changes both to give users indications of bugs that might
+ have been resolved, as well, and not less important, to provide credits
+ for the support given to the project. It is considered vital to provide
+ adequate payback using recognition and credits to let users and developers
+ feel part of the community, thus increasing development power.
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+ 20020611 Initial version. (SN)
+ 20020613 Include the module of ISO character entity sets (DC)
+[Version 1.2]
+ 20030424 Adopt the loosened content model from document-v12 (JT)
+ 20040614 Stay current with latest document-v13 (class attribute)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Include the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+ "-//APACHE//ENTITIES Documentation V1.3//EN"
+ "document-v13.mod">
+%document;
+
+<!-- =============================================================== -->
+<!-- Include the Common ISO Character Entity Sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % common-charents PUBLIC
+ "-//APACHE//ENTITIES Common Character Entity Sets V1.0//EN"
+ "common-charents-v10.mod">
+%common-charents;
+
+<!-- =============================================================== -->
+<!-- Include the Common elements -->
+<!-- =============================================================== -->
+
+<!ENTITY % common PUBLIC
+ "-//APACHE//ENTITIES Common Elements V1.0//EN"
+ "common-elems-v10.mod">
+%common;
+
+<!-- =============================================================== -->
+<!-- Include the Changes module -->
+<!-- =============================================================== -->
+
+<!ENTITY % changes PUBLIC
+ "-//APACHE//ENTITIES Changes V1.1//EN"
+ "changes-v11.mod">
+%changes;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Common Character Entity Sets (Version 1.0)
+
+PURPOSE:
+ Common elements across all DTDs.
+
+TYPICAL INVOCATION:
+
+ <!ENTITY % common-charents PUBLIC
+ "-//APACHE//ENTITIES Common Character Entity Sets Vx.y//EN"
+ "common-charents-vxy.mod">
+ %common-charents;
+
+ where
+
+ x := major version
+ y := minor version
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+ 20020613 Initial version. (DC)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Common ISO character entity sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % ISOlat1 PUBLIC
+ "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
+ "../entity/ISOlat1.pen">
+%ISOlat1;
+
+<!ENTITY % ISOpub PUBLIC
+ "ISO 8879:1986//ENTITIES Publishing//EN//XML"
+ "../entity/ISOpub.pen">
+%ISOpub;
+
+<!ENTITY % ISOtech PUBLIC
+ "ISO 8879:1986//ENTITIES General Technical//EN//XML"
+ "../entity/ISOtech.pen">
+%ISOtech;
+
+<!ENTITY % ISOnum PUBLIC
+ "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
+ "../entity/ISOnum.pen">
+%ISOnum;
+
+<!ENTITY % ISOdia PUBLIC
+ "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML"
+ "../entity/ISOdia.pen">
+%ISOdia;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Common Elements (Version 1.0)
+
+PURPOSE:
+ Common elements across DTDs
+
+TYPICAL INVOCATION:
+
+ <!ENTITY % common PUBLIC
+ "-//APACHE//ENTITIES Common elements Vx.y//EN"
+ "common-elems-vxy.mod">
+ %common;
+
+ where
+
+ x := major version
+ y := minor version
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+ 20020611 Initial version. (SN)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Common entities -->
+<!-- =============================================================== -->
+
+<!ENTITY % types "add|remove|update|fix">
+<!ENTITY % contexts "build|docs|code|admin|design">
+
+<!-- =============================================================== -->
+<!-- Common elements -->
+<!-- =============================================================== -->
+
+<!ELEMENT devs (person+)>
+<!ATTLIST devs %common.att;>
+
+<!ELEMENT action (%content.mix;)*>
+<!ATTLIST action %common.att;
+ dev IDREF #REQUIRED
+ type (%types;) #IMPLIED
+ context (%contexts;) #IMPLIED
+ due-to CDATA #IMPLIED
+ due-to-email CDATA #IMPLIED
+ fixes-bug CDATA #IMPLIED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!-- ===================================================================
+
+ Apache Documentation DTD (Version 1.1)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software documentation for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE document PUBLIC
+ "-//APACHE//DTD Documentation Vx.y//EN"
+ "document-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ Many of the design patterns used in this DTD were take from the
+ W3C XML Specification DTD edited by Eve Maler <elm@arbortext.com>.
+
+ Where possible, great care has been used to reuse HTML tag
+ names to reduce learning efforts and to allow HTML editors to be
+ used for complex authorings like tables and lists.
+
+EXTENSIBILITY:
+ This DTD includes several empty placeholders that can be used to
+ extend it. These placeholders are implemented with empty entities. Here
+ is the list of those empty entities and what they are used for:
+
+ - local.inline: this entity should contain extended definitions of
+ elements that can be used 'inline', or directly inside
+ the content. An example for this entity could be
+
+ <!ENTITY % local.inline "|citation">
+
+ - local.blocks: this entity should contain extended definitions of
+ elements that behave as 'blocks', thus can be visually
+ rendered as areas on the canvas. An example for this
+ entity could be:
+
+ <!ENTITY % local.blocks "|poem">
+
+ - local.sections: this entity should contain extended definitions of
+ elements that behave as 'sections', thus can be considered
+ containers of block-level elements. An example for
+ this entity could be:
+
+ <!ENTITY % local.sections "|chapter">
+
+ - local.headers: this entity should contain extended definitions of
+ elements that behave as parts of the document header.
+ An example for this header could be:
+
+ <!ENTITY % local.headers ", notes?">
+
+ - local.footers: this entity should contain extended definitions of
+ elements that behave as parts of the document footer.
+ An example for this header could be:
+
+ <!ENTITY % local.footers ", annotations*">
+
+
+AUTHORS:
+ Stefano Mazzocchi <stefano@apache.org>
+ Steven Noels <stevenn@outerthought.org>
+
+FIXME:
+ - should "form" tags be included?
+
+CHANGE HISTORY:
+[Version 1.0]
+ 19991121 Initial version. (SM)
+ 19991123 Replaced "res" with more standard "strong" for emphasis. (SM)
+ 19991124 Added "fork" element for window forking behavior. (SM)
+ 19991124 Added "img-inline" element to separate from "img". (SM)
+ 19991129 Removed "affiliation" from "author". (SM)
+ 19991129 Made "author" empty and moved "name|email" as attributes. (SM)
+ 19991215 Simplified table section. (SM)
+ 19991215 Changed "img-block" in more friendly "figure". (SM)
+ 20000125 Added the "icon" image. (SM)
+ 20000126 Allowed "anchor" in all levels. (SM)
+ 20000404 Removed the "role" attribute from common-xxx.att. (SM)
+ 20000815 Allowed "code" inside "strong" and "em". (SM)
+[Version 1.1]
+ 20011212 Used public identifiers for external entities. (SM)
+ 20011212 Removed xlink attributes since not used. (SM)
+ 20011212 Removed "connect" since not required at this level. (SM)
+ 20011218 Added "warning" as a block level object. (SM)
+ 20011218 Removed explicitly numbered sections ("s1|s2|s3|s4"). (SM)
+ 20011218 Added "section" element. (SM)
+ 20011218 Allowed "body" to have blocks without a section. (SM)
+ 20011218 Removed "sl" since not really different from "ul". (SM)
+ 20020214 Moved empty placeholder entity declarations up front (SNS)
+ 20020214 Corrected content model of content.mix parameter entity (SNS)
+
+COPYRIGHT:
+ Copyright (c) @year@ The Apache Software Foundation.
+
+ Permission to copy in any form is granted provided this notice is
+ included in all copies. Permission to redistribute is granted
+ provided this file is distributed untouched in all its parts and
+ included files.
+
+==================================================================== -->
+
+
+
+
+<!-- =============================================================== -->
+<!-- Common character entities (included from external file) -->
+<!-- =============================================================== -->
+
+<!ENTITY % ISOlat1 PUBLIC
+ "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
+ "ISOlat1.pen">
+%ISOlat1;
+
+<!ENTITY % ISOpub PUBLIC
+ "ISO 8879:1986//ENTITIES Publishing//EN//XML"
+ "ISOpub.pen">
+%ISOpub;
+
+<!ENTITY % ISOtech PUBLIC
+ "ISO 8879:1986//ENTITIES General Technical//EN//XML"
+ "ISOtech.pen">
+%ISOtech;
+
+<!ENTITY % ISOnum PUBLIC
+ "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
+ "ISOnum.pen">
+%ISOnum;
+
+<!ENTITY % ISOdia PUBLIC
+ "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML"
+ "ISOdia.pen">
+%ISOdia;
+
+<!-- =============================================================== -->
+<!-- Useful entities for increased DTD readability -->
+<!-- =============================================================== -->
+
+<!ENTITY % text "#PCDATA">
+
+<!-- Entities referred to later on are defined up front -->
+
+<!ENTITY % markup "strong|em|code|sub|sup">
+<!ENTITY % special-inline "br|img|icon">
+<!ENTITY % links "link|jump|fork">
+<!ENTITY % paragraphs "p|source|note|warning|fixme">
+<!ENTITY % tables "table">
+<!ENTITY % lists "ol|ul|dl">
+<!ENTITY % special-blocks "figure|anchor">
+
+
+<!-- =============================================================== -->
+<!-- Entities for general XML compliance -->
+<!-- =============================================================== -->
+
+<!-- Common attributes
+ Every element has an ID attribute (sometimes required,
+ but usually optional) for links. %common.att;
+ is for common attributes where the ID is optional, and
+ %common-idreq.att; is for common attributes where the
+ ID is required.
+-->
+<!ENTITY % common.att
+ 'id ID #IMPLIED
+ xml:lang NMTOKEN #IMPLIED'>
+<!ENTITY % common-idreq.att
+ 'id ID #REQUIRED
+ xml:lang NMTOKEN #IMPLIED'>
+
+
+<!-- xml:space attribute ===============================================
+ Indicates that the element contains white space
+ that the formatter or other application should retain,
+ as appropriate to its function.
+==================================================================== -->
+<!ENTITY % xmlspace.att
+ 'xml:space (default|preserve) #FIXED "preserve"'>
+
+
+<!-- def attribute =====================================================
+ Points to the element where the relevant definition can be
+ found, using the IDREF mechanism. %def.att; is for optional
+ def attributes, and %def-req.att; is for required def
+ attributes.
+==================================================================== -->
+<!ENTITY % def.att
+ 'def IDREF #IMPLIED'>
+<!ENTITY % def-req.att
+ 'def IDREF #REQUIRED'>
+
+
+<!-- ref attribute =====================================================
+ Points to the element where more information can be found,
+ using the IDREF mechanism. %ref.att; is for optional
+ ref attributes, and %ref-req.att; is for required ref
+ attributes.
+================================================================== -->
+<!ENTITY % ref.att
+ 'ref IDREF #IMPLIED'>
+<!ENTITY % ref-req.att
+ 'ref IDREF #REQUIRED'>
+
+
+<!-- =============================================================== -->
+<!-- Entities for general usage -->
+<!-- =============================================================== -->
+
+
+<!-- Key attribute =====================================================
+ Optionally provides a sorting or indexing key, for cases when
+ the element content is inappropriate for this purpose.
+==================================================================== -->
+<!ENTITY % key.att
+ 'key CDATA #IMPLIED'>
+
+
+
+<!-- Title attributes ==================================================
+ Indicates that the element requires to have a title attribute.
+==================================================================== -->
+<!ENTITY % title.att
+ 'title CDATA #REQUIRED'>
+
+
+
+<!-- Name attributes ==================================================
+ Indicates that the element requires to have a name attribute.
+==================================================================== -->
+<!ENTITY % name.att
+ 'name CDATA #REQUIRED'>
+
+
+
+<!-- Email attributes ==================================================
+ Indicates that the element requires to have an email attribute.
+==================================================================== -->
+<!ENTITY % email.att
+ 'email CDATA #REQUIRED'>
+
+
+<!-- Link attributes ===================================================
+ Indicates that the element requires to have hyperlink attributes.
+==================================================================== -->
+
+<!ENTITY % link.att
+ 'href CDATA #IMPLIED
+ role CDATA #IMPLIED
+ title CDATA #IMPLIED '>
+
+
+
+<!-- =============================================================== -->
+<!-- General definitions -->
+<!-- =============================================================== -->
+
+<!-- A person is a general human entity -->
+<!ELEMENT person EMPTY>
+<!ATTLIST person %common.att;
+ %name.att;
+ %email.att;>
+
+
+
+<!-- =============================================================== -->
+<!-- Content definitions -->
+<!-- =============================================================== -->
+
+<!ENTITY % local.inline "">
+
+<!ENTITY % link-content.mix "%text;|%markup;|%special-inline; %local.inline;">
+
+<!ENTITY % content.mix "%link-content.mix;|%links;">
+
+ <!-- ==================================================== -->
+ <!-- Phrase Markup -->
+ <!-- ==================================================== -->
+
+ <!-- Strong (typically bold) -->
+ <!ELEMENT strong (%text;|code)*>
+ <!ATTLIST strong %common.att;>
+
+ <!-- Emphasis (typically italic) -->
+ <!ELEMENT em (%text;|code)*>
+ <!ATTLIST em %common.att;>
+
+ <!-- Code (typically monospaced) -->
+ <!ELEMENT code (%text;)>
+ <!ATTLIST code %common.att;>
+
+ <!-- Superscript (typically smaller and higher) -->
+ <!ELEMENT sup (%text;)>
+ <!ATTLIST sup %common.att;>
+
+ <!-- Subscript (typically smaller and lower) -->
+ <!ELEMENT sub (%text;)>
+ <!ATTLIST sub %common.att;>
+
+ <!-- ==================================================== -->
+ <!-- Hypertextual Links -->
+ <!-- ==================================================== -->
+
+ <!-- hyperlink (equivalent of <a ...>) -->
+ <!ELEMENT link (%link-content.mix;)*>
+ <!ATTLIST link %common.att;
+ %link.att;>
+
+ <!-- windows-replacing link (equivalent of <a ... target="_top">) -->
+ <!ELEMENT jump (%link-content.mix;)*>
+ <!ATTLIST jump %common.att;
+ %link.att;>
+
+ <!-- window-forking link (equivalent of <a ... target="_new">) -->
+ <!ELEMENT fork (%link-content.mix;)*>
+ <!ATTLIST fork %common.att;
+ %link.att;>
+
+ <!-- ==================================================== -->
+ <!-- Specials -->
+ <!-- ==================================================== -->
+
+ <!-- Breakline Object (typically forces line break) -->
+ <!ELEMENT br EMPTY>
+ <!ATTLIST br %common.att;>
+
+ <!-- Image Object (typically an inlined image) -->
+ <!ELEMENT img EMPTY>
+ <!ATTLIST img src CDATA #REQUIRED
+ alt CDATA #REQUIRED
+ height CDATA #IMPLIED
+ width CDATA #IMPLIED
+ usemap CDATA #IMPLIED
+ ismap (ismap) #IMPLIED
+ %common.att;>
+
+ <!-- Image Icon (typically an inlined image placed as graphical item) -->
+ <!ELEMENT icon EMPTY>
+ <!ATTLIST icon src CDATA #REQUIRED
+ alt CDATA #REQUIRED
+ height CDATA #IMPLIED
+ width CDATA #IMPLIED
+ %common.att;>
+
+
+<!-- =============================================================== -->
+<!-- Blocks definitions -->
+<!-- =============================================================== -->
+
+<!ENTITY % local.blocks "">
+
+<!ENTITY % blocks "%paragraphs;|%tables;|%lists;|%special-blocks; %local.blocks;">
+
+ <!-- ==================================================== -->
+ <!-- Paragraphs -->
+ <!-- ==================================================== -->
+
+ <!-- Text Paragraph (normally vertically space delimited) -->
+ <!ELEMENT p (%content.mix;)*>
+ <!ATTLIST p %common.att;>
+
+ <!-- Source Paragraph (normally space is preserved) -->
+ <!ELEMENT source (%content.mix;)*>
+ <!ATTLIST source %common.att;
+ %xmlspace.att;>
+
+ <!-- Note Paragraph (normally shown encapsulated) -->
+ <!ELEMENT note (%content.mix;)*>
+ <!ATTLIST note %common.att;>
+
+ <!-- Warning Paragraph (normally shown with eye-catching colors) -->
+ <!ELEMENT warning (%content.mix;)*>
+ <!ATTLIST warning %common.att;>
+
+ <!-- Fixme Paragraph (normally not shown) -->
+ <!ELEMENT fixme (%content.mix;)*>
+ <!ATTLIST fixme author CDATA #REQUIRED
+ %common.att;>
+
+ <!-- ==================================================== -->
+ <!-- Tables -->
+ <!-- ==================================================== -->
+
+ <!-- Attributes that indicate the spanning of the table cell -->
+ <!ENTITY % cell.span
+ 'colspan CDATA "1"
+ rowspan CDATA "1"'>
+
+ <!-- Table element -->
+ <!ELEMENT table (caption?, tr+)>
+ <!ATTLIST table %common.att;>
+
+ <!-- The table title -->
+ <!ELEMENT caption (%content.mix;)*>
+ <!ATTLIST caption %common.att;>
+
+ <!-- The table row element -->
+ <!ELEMENT tr (th|td)+>
+ <!ATTLIST tr %common.att;>
+
+ <!-- The table row header element -->
+ <!ELEMENT th (%content.mix;)*>
+ <!ATTLIST th %common.att;
+ %cell.span;>
+
+ <!-- The table row description element -->
+ <!ELEMENT td (%content.mix;)*>
+ <!ATTLIST td %common.att;
+ %cell.span;>
+
+ <!-- ==================================================== -->
+ <!-- Lists -->
+ <!-- ==================================================== -->
+
+ <!-- List item -->
+ <!ELEMENT li (%content.mix;|%lists;)*>
+ <!ATTLIST li %common.att;>
+
+ <!-- Unordered list (typically bulleted) -->
+ <!ELEMENT ul (li|%lists;)+>
+ <!-- spacing attribute:
+ Use "normal" to get normal vertical spacing for items;
+ use "compact" to get less spacing. The default is dependent
+ on the stylesheet. -->
+ <!ATTLIST ul
+ %common.att;
+ spacing (normal|compact) #IMPLIED>
+
+ <!-- Ordered list (typically numbered) -->
+ <!ELEMENT ol (li|%lists;)+>
+ <!-- spacing attribute:
+ Use "normal" to get normal vertical spacing for items;
+ use "compact" to get less spacing. The default is dependent
+ on the stylesheet. -->
+ <!ATTLIST ol
+ %common.att;
+ spacing (normal|compact) #IMPLIED>
+
+ <!-- Definition list (typically two-column) -->
+ <!ELEMENT dl (dt,dd)+>
+ <!ATTLIST dl %common.att;>
+
+ <!-- Definition term -->
+ <!ELEMENT dt (%content.mix;)*>
+ <!ATTLIST dt %common.att;>
+
+ <!-- Definition description -->
+ <!ELEMENT dd (%content.mix;)*>
+ <!ATTLIST dd %common.att;>
+
+ <!-- ==================================================== -->
+ <!-- Special Blocks -->
+ <!-- ==================================================== -->
+
+ <!-- Image Block (typically a separated and centered image) -->
+ <!ELEMENT figure EMPTY>
+ <!ATTLIST figure src CDATA #REQUIRED
+ alt CDATA #REQUIRED
+ height CDATA #IMPLIED
+ width CDATA #IMPLIED
+ usemap CDATA #IMPLIED
+ ismap (ismap) #IMPLIED
+ %common.att;>
+
+ <!-- anchor point (equivalent of <a name="...">, typically not rendered) -->
+ <!ELEMENT anchor EMPTY>
+ <!ATTLIST anchor %common-idreq.att;>
+
+
+<!-- =============================================================== -->
+<!-- Document -->
+<!-- =============================================================== -->
+
+<!ELEMENT document (header?, body, footer?)>
+<!ATTLIST document %common.att;>
+
+ <!-- ==================================================== -->
+ <!-- Header -->
+ <!-- ==================================================== -->
+
+ <!ENTITY % local.headers "">
+
+ <!ELEMENT header (title, subtitle?, version?, type?, authors,
+ notice*, abstract? %local.headers;)>
+ <!ATTLIST header %common.att;>
+
+ <!ELEMENT title (%text;)>
+ <!ATTLIST title %common.att;>
+
+ <!ELEMENT subtitle (%text;)>
+ <!ATTLIST subtitle %common.att;>
+
+ <!ELEMENT version (%text;)>
+ <!ATTLIST version %common.att;>
+
+ <!ELEMENT type (%text;)>
+ <!ATTLIST type %common.att;>
+
+ <!ELEMENT authors (person+)>
+ <!ATTLIST authors %common.att;>
+
+ <!ELEMENT notice (%content.mix;)*>
+ <!ATTLIST notice %common.att;>
+
+ <!ELEMENT abstract (%content.mix;)*>
+ <!ATTLIST abstract %common.att;>
+
+ <!-- ==================================================== -->
+ <!-- Body -->
+ <!-- ==================================================== -->
+
+ <!ENTITY % local.sections "">
+
+ <!ENTITY % sections "section %local.sections;">
+
+ <!ELEMENT body (%sections;|%blocks;)+>
+ <!ATTLIST body %common.att;>
+
+ <!ELEMENT section (%sections;|%blocks;)*>
+ <!ATTLIST section %title.att; %common.att;>
+
+ <!-- ==================================================== -->
+ <!-- Footer -->
+ <!-- ==================================================== -->
+
+ <!ENTITY % local.footers "">
+
+ <!ELEMENT footer (legal %local.footers;)>
+
+ <!ELEMENT legal (%content.mix;)*>
+ <!ATTLIST legal %common.att;>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Documentation DTD (Version 1.2)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software documentation for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE document PUBLIC
+ "-//APACHE//DTD Documentation Vx.y//EN"
+ "document-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ Many of the design patterns used in this DTD were take from the
+ W3C XML Specification DTD edited by Eve Maler <elm@arbortext.com>.
+
+ Where possible, great care has been used to reuse HTML tag
+ names to reduce learning efforts and to allow HTML editors to be
+ used for complex authorings like tables and lists.
+
+EXTENSIBILITY:
+ This DTD includes several empty placeholders that can be used to
+ extend it. These placeholders are implemented with empty entities. Here
+ is the list of those empty entities and what they are used for:
+
+ - local.inline: this entity should contain extended definitions of
+ elements that can be used 'inline', or directly inside
+ the content. An example for this entity could be
+
+ <!ENTITY % local.inline "|citation">
+
+ - local.blocks: this entity should contain extended definitions of
+ elements that behave as 'blocks', thus can be visually
+ rendered as areas on the canvas. An example for this
+ entity could be:
+
+ <!ENTITY % local.blocks "|poem">
+
+ - local.sections: this entity should contain extended definitions of
+ elements that behave as 'sections', thus can be considered
+ containers of block-level elements. An example for
+ this entity could be:
+
+ <!ENTITY % local.sections "|chapter">
+
+ - local.headers: this entity should contain extended definitions of
+ elements that behave as parts of the document header.
+ An example for this header could be:
+
+ <!ENTITY % local.headers ", notes?">
+
+ - local.footers: this entity should contain extended definitions of
+ elements that behave as parts of the document footer.
+ An example for this header could be:
+
+ <!ENTITY % local.footers ", annotations*">
+
+FIXME:
+ - should "form" tags be included?
+
+CHANGE HISTORY:
+[Version 1.0]
+ 19991121 Initial version. (SM)
+ 19991123 Replaced "res" with more standard "strong" for emphasis. (SM)
+ 19991124 Added "fork" element for window forking behavior. (SM)
+ 19991124 Added "img-inline" element to separate from "img". (SM)
+ 19991129 Removed "affiliation" from "author". (SM)
+ 19991129 Made "author" empty and moved "name|email" as attributes. (SM)
+ 19991215 Simplified table section. (SM)
+ 19991215 Changed "img-block" in more friendly "figure". (SM)
+ 20000125 Added the "icon" image. (SM)
+ 20000126 Allowed "anchor" in all levels. (SM)
+ 20000404 Removed the "role" attribute from common-xxx.att. (SM)
+ 20000815 Allowed "code" inside "strong" and "em". (SM)
+[Version 1.1]
+ 20011212 Used public identifiers for external entities. (SM)
+ 20011212 Removed xlink attributes since not used. (SM)
+ 20011212 Removed "connect" since not required at this level. (SM)
+ 20011218 Added "warning" as a block level object. (SM)
+ 20011218 Removed explicitly numbered sections ("s1|s2|s3|s4"). (SM)
+ 20011218 Added "section" element. (SM)
+ 20011218 Allowed "body" to have blocks without a section. (SM)
+ 20011218 Removed "sl" since not really different from "ul". (SM)
+ 20020214 Moved empty placeholder entity declarations up front (SNS)
+ 20020214 Corrected content model of content.mix parameter entity (SNS)
+ 20020519 The DTDs are now modular so various parts can be re-used (SNS)
+ 20020606 Made title into an child element of its parent instead of an attribute (SNS)
+ 20020613 Move the declarations of ISO character entity sets to module (DC)
+[Version 1.2]
+ 20030320 Make @href required for link elements. (SNS)
+ 20030320 Allow links (link|jump|fork) and inline elements (br|img|icon|acronym) inside title. (SNS)
+ 20030419 Allow inline content (strong|em|code|sub|sup|br|img|icon|acronym|link|jump|fork) in strong and em. (JT)
+ 20030419 Allow paragraphs (p|source|note|warning|fixme), table and figure|anchor inside li. (JT)
+ 20030419 Allow paragraphs (p|source|note|warning|fixme), lists (ol|ul|dl), table, figure|anchor inside dd. (JT)
+ 20030419 Allow paragraphs (p|source|note|warning|fixme), lists (ol|ul|dl), table, figure|anchor inside tables (td|dh). (JT)
+ 20040614 The attribute "class" is now defined on every element. (RT)
+
+==================================================================== -->
+
+
+<!-- =============================================================== -->
+<!-- Include the Common ISO Character Entity Sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % common-charents PUBLIC
+ "-//APACHE//ENTITIES Common Character Entity Sets V1.0//EN"
+ "common-charents-v10.mod">
+%common-charents;
+
+<!-- =============================================================== -->
+<!-- Document -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+ "-//APACHE//ENTITIES Documentation V1.3//EN"
+ "document-v13.mod">
+%document;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Common Documentation elements (Version 1.2)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software documentation for use with the Apache projects.
+
+TYPICAL INVOCATION:
+
+ <!ENTITY % document PUBLIC
+ "-//APACHE//ENTITIES Documentation Vxy//EN"
+ "document-vxy.mod">
+ %document;
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+ 20020608 Initial version. (SN)
+
+==================================================================== -->
+<!-- =============================================================== -->
+<!-- Useful entities for increased DTD readability -->
+<!-- =============================================================== -->
+<!ENTITY % text "#PCDATA">
+<!-- Entities referred to later on are defined up front -->
+<!ENTITY % markup "strong|em|code|sub|sup">
+<!ENTITY % special-inline "br|img|icon|acronym">
+<!ENTITY % links "link|jump|fork">
+<!ENTITY % paragraphs "p|source|note|warning|fixme">
+<!ENTITY % tables "table">
+<!ENTITY % lists "ol|ul|dl">
+<!ENTITY % special-blocks "figure|anchor">
+<!-- =============================================================== -->
+<!-- Entities for general XML compliance -->
+<!-- =============================================================== -->
+<!-- Common attributes
+ Every element has an ID attribute (sometimes required,
+ but usually optional) for links. %common.att;
+ is for common attributes where the ID is optional, and
+ %common-idreq.att; is for common attributes where the
+ ID is required.
+-->
+<!ENTITY % common.att 'id ID #IMPLIED
+ class NMTOKEN #IMPLIED
+ xml:lang NMTOKEN #IMPLIED'>
+<!ENTITY % common-idreq.att 'id ID #REQUIRED
+ class NMTOKEN #IMPLIED
+ xml:lang NMTOKEN #IMPLIED'>
+<!-- xml:space attribute ===============================================
+ Indicates that the element contains white space
+ that the formatter or other application should retain,
+ as appropriate to its function.
+==================================================================== -->
+<!ENTITY % xmlspace.att 'xml:space (default|preserve) #FIXED "preserve"'>
+<!-- def attribute =====================================================
+ Points to the element where the relevant definition can be
+ found, using the IDREF mechanism. %def.att; is for optional
+ def attributes, and %def-req.att; is for required def
+ attributes.
+==================================================================== -->
+<!ENTITY % def.att 'def IDREF #IMPLIED'>
+<!ENTITY % def-req.att 'def IDREF #REQUIRED'>
+<!-- ref attribute =====================================================
+ Points to the element where more information can be found,
+ using the IDREF mechanism. %ref.att; is for optional
+ ref attributes, and %ref-req.att; is for required ref
+ attributes.
+================================================================== -->
+<!ENTITY % ref.att 'ref IDREF #IMPLIED'>
+<!ENTITY % ref-req.att 'ref IDREF #REQUIRED'>
+<!-- =============================================================== -->
+<!-- Entities for general usage -->
+<!-- =============================================================== -->
+<!-- Key attribute =====================================================
+ Optionally provides a sorting or indexing key, for cases when
+ the element content is inappropriate for this purpose.
+==================================================================== -->
+<!ENTITY % key.att 'key CDATA #IMPLIED'>
+<!-- Title attributes ==================================================
+ Indicates that the element requires to have a title attribute.
+==================================================================== -->
+<!ENTITY % title.att 'title CDATA #REQUIRED'>
+<!-- Name attributes ==================================================
+ Indicates that the element requires to have a name attribute.
+==================================================================== -->
+<!ENTITY % name.att 'name CDATA #REQUIRED'>
+<!-- Email attributes ==================================================
+ Indicates that the element requires to have an email attribute.
+==================================================================== -->
+<!ENTITY % email.att 'email CDATA #REQUIRED'>
+<!-- Link attributes ===================================================
+ Indicates that the element requires to have hyperlink attributes.
+==================================================================== -->
+<!ENTITY % link.att 'href CDATA #REQUIRED
+ role CDATA #IMPLIED
+ title CDATA #IMPLIED '>
+<!-- =============================================================== -->
+<!-- General definitions -->
+<!-- =============================================================== -->
+<!-- A person is a general unparsed human entity -->
+<!ELEMENT person EMPTY>
+<!ATTLIST person
+ %common.att;
+ %name.att;
+ %email.att;
+>
+<!-- =============================================================== -->
+<!-- Content definitions -->
+<!-- =============================================================== -->
+<!ENTITY % local.inline "">
+<!ENTITY % link-content.mix "%text;|%markup;|%special-inline; %local.inline;">
+<!ENTITY % content.mix "%link-content.mix;|%links;">
+<!-- ==================================================== -->
+<!-- Phrase Markup -->
+<!-- ==================================================== -->
+<!-- Strong (typically bold) -->
+<!ELEMENT strong (%content.mix;)*>
+<!ATTLIST strong
+ %common.att;
+>
+<!-- Emphasis (typically italic) -->
+<!ELEMENT em (%content.mix;)*>
+<!ATTLIST em
+ %common.att;
+>
+<!-- Code (typically monospaced) -->
+<!ELEMENT code (%text;)>
+<!ATTLIST code
+ %common.att;
+>
+<!-- Superscript (typically smaller and higher) -->
+<!ELEMENT sup (%text;)>
+<!ATTLIST sup
+ %common.att;
+>
+<!-- Subscript (typically smaller and lower) -->
+<!ELEMENT sub (%text;)>
+<!ATTLIST sub
+ %common.att;
+>
+<!-- ==================================================== -->
+<!-- Hypertextual Links -->
+<!-- ==================================================== -->
+<!-- hyperlink (equivalent of <a ...>) -->
+<!ELEMENT link (%link-content.mix;)*>
+<!ATTLIST link
+ %common.att;
+ %link.att;
+>
+<!-- windows-replacing link (equivalent of <a ... target="_top">) -->
+<!ELEMENT jump (%link-content.mix;)*>
+<!ATTLIST jump
+ %common.att;
+ %link.att;
+>
+<!-- window-forking link (equivalent of <a ... target="_blank">) -->
+<!ELEMENT fork (%link-content.mix;)*>
+<!ATTLIST fork
+ %common.att;
+ %link.att;
+>
+
+<!-- ==================================================== -->
+<!-- Specials -->
+<!-- ==================================================== -->
+<!-- Breakline Object (typically forces line break) -->
+<!ELEMENT br EMPTY>
+<!ATTLIST br
+ %common.att;
+>
+<!-- Image Object (typically an inlined image) -->
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+ src CDATA #REQUIRED
+ alt CDATA #REQUIRED
+ height CDATA #IMPLIED
+ width CDATA #IMPLIED
+ usemap CDATA #IMPLIED
+ ismap (ismap) #IMPLIED
+ %common.att;
+>
+<!-- Image Icon (typically an inlined image placed as graphical item) -->
+<!ELEMENT icon EMPTY>
+<!ATTLIST icon
+ src CDATA #REQUIRED
+ alt CDATA #REQUIRED
+ height CDATA #IMPLIED
+ width CDATA #IMPLIED
+ %common.att;
+>
+<!-- Acronym (in modern browsers, will have rollover text) -->
+<!ELEMENT acronym (%text;)*>
+<!ATTLIST acronym
+ title CDATA #REQUIRED
+ %common.att;
+>
+
+<!-- =============================================================== -->
+<!-- Blocks definitions -->
+<!-- =============================================================== -->
+<!ENTITY % local.blocks "">
+<!ENTITY % blocks "%paragraphs;|%tables;|%lists;|%special-blocks; %local.blocks;">
+
+<!-- Flow mixes block and inline -->
+<!ENTITY % flow "%content.mix;|%blocks;">
+
+<!-- ==================================================== -->
+<!-- Paragraphs -->
+<!-- ==================================================== -->
+<!-- Text Paragraph (normally vertically space delimited. Space can be preserved.) -->
+<!ELEMENT p (%content.mix;)*>
+<!ATTLIST p
+ %common.att;
+ xml:space (default|preserve) #IMPLIED
+>
+<!-- Source Paragraph (normally space is preserved) -->
+<!ELEMENT source (%content.mix;)*>
+<!ATTLIST source
+ %common.att;
+ %xmlspace.att;
+>
+<!-- Note Paragraph (normally shown encapsulated) -->
+<!ELEMENT note (%content.mix;)*>
+<!ATTLIST note
+ label CDATA #IMPLIED
+ %common.att;
+>
+<!-- Warning Paragraph (normally shown with eye-catching colors) -->
+<!ELEMENT warning (%content.mix;)*>
+<!ATTLIST warning
+ label CDATA #IMPLIED
+ %common.att;
+>
+<!-- Fixme Paragraph (normally not shown) -->
+<!ELEMENT fixme (%content.mix;)*>
+<!ATTLIST fixme
+ author CDATA #REQUIRED
+ %common.att;
+>
+<!-- ==================================================== -->
+<!-- Tables -->
+<!-- ==================================================== -->
+<!-- Attributes that indicate the spanning of the table cell -->
+<!ENTITY % cell.span 'colspan CDATA "1"
+ rowspan CDATA "1"'>
+<!-- Table element -->
+<!ELEMENT table (caption?, tr+)>
+<!ATTLIST table
+ %common.att;
+>
+<!-- The table title -->
+<!ELEMENT caption (%content.mix;)*>
+<!ATTLIST caption
+ %common.att;
+>
+<!-- The table row element -->
+<!ELEMENT tr (th | td)+>
+<!ATTLIST tr
+ %common.att;
+>
+<!-- The table row header element -->
+<!ELEMENT th (%flow;)*>
+<!ATTLIST th
+ %common.att;
+ %cell.span;
+>
+<!-- The table row description element -->
+<!ELEMENT td (%flow;)*>
+<!ATTLIST td
+ %common.att;
+ %cell.span;
+>
+<!-- ==================================================== -->
+<!-- Lists -->
+<!-- ==================================================== -->
+<!-- List item -->
+<!ELEMENT li (%flow;)*>
+<!ATTLIST li
+ %common.att;
+>
+<!-- Unordered list (typically bulleted) -->
+<!ELEMENT ul (li | %lists;)+>
+<!-- spacing attribute:
+ Use "normal" to get normal vertical spacing for items;
+ use "compact" to get less spacing. The default is dependent
+ on the stylesheet. -->
+<!ATTLIST ul
+ %common.att;
+ spacing (normal | compact) #IMPLIED
+>
+<!-- Ordered list (typically numbered) -->
+<!ELEMENT ol (li | %lists;)+>
+<!-- spacing attribute:
+ Use "normal" to get normal vertical spacing for items;
+ use "compact" to get less spacing. The default is dependent
+ on the stylesheet. -->
+<!ATTLIST ol
+ %common.att;
+ spacing (normal | compact) #IMPLIED
+>
+<!-- Definition list (typically two-column) -->
+<!ELEMENT dl (dt, dd)+>
+<!ATTLIST dl
+ %common.att;
+>
+<!-- Definition term -->
+<!ELEMENT dt (%content.mix;)*>
+<!ATTLIST dt
+ %common.att;
+>
+<!-- Definition description -->
+<!ELEMENT dd (%flow; )*>
+<!ATTLIST dd
+ %common.att;
+>
+<!-- ==================================================== -->
+<!-- Special Blocks -->
+<!-- ==================================================== -->
+<!-- Image Block (typically a separated and centered image) -->
+<!ELEMENT figure EMPTY>
+<!ATTLIST figure
+ src CDATA #REQUIRED
+ alt CDATA #REQUIRED
+ height CDATA #IMPLIED
+ width CDATA #IMPLIED
+ usemap CDATA #IMPLIED
+ ismap (ismap) #IMPLIED
+ align CDATA #IMPLIED
+ %common.att;
+>
+<!-- anchor point (equivalent of <a name="...">, typically not rendered) -->
+<!ELEMENT anchor EMPTY>
+<!ATTLIST anchor
+ %common-idreq.att;
+>
+<!-- =============================================================== -->
+<!-- Document -->
+<!-- =============================================================== -->
+<!ELEMENT document (header, body, footer?)>
+<!ATTLIST document
+ %common.att;
+>
+<!-- ==================================================== -->
+<!-- Header -->
+<!-- ==================================================== -->
+<!ENTITY % local.headers "">
+<!ELEMENT header (title, subtitle?, version?, type?, authors?,
+ notice*, abstract? %local.headers;)>
+<!ATTLIST header
+ %common.att;
+>
+<!ELEMENT title (%text; | %markup; | %links; | %special-inline;)*>
+<!ATTLIST title
+ %common.att;
+>
+<!ELEMENT subtitle (%text; | %markup;)*>
+<!ATTLIST subtitle
+ %common.att;
+>
+<!ELEMENT version (%text;)>
+<!ATTLIST version
+ %common.att;
+ major CDATA #IMPLIED
+ minor CDATA #IMPLIED
+ fix CDATA #IMPLIED
+ tag CDATA #IMPLIED
+>
+<!ELEMENT type (%text;)>
+<!ATTLIST type
+ %common.att;
+>
+<!ELEMENT authors (person+)>
+<!ATTLIST authors
+ %common.att;
+>
+<!ELEMENT notice (%content.mix;)*>
+<!ATTLIST notice
+ %common.att;
+>
+<!ELEMENT abstract (%content.mix;)*>
+<!ATTLIST abstract
+ %common.att;
+>
+<!-- ==================================================== -->
+<!-- Body -->
+<!-- ==================================================== -->
+<!ENTITY % local.sections "">
+<!ENTITY % sections "section %local.sections;">
+<!ELEMENT body (%sections; | %blocks;)+>
+<!ATTLIST body
+ %common.att;
+>
+<!ELEMENT section (title, (%sections; | %blocks;)*)>
+<!ATTLIST section
+ %common.att;
+>
+<!-- ==================================================== -->
+<!-- Footer -->
+<!-- ==================================================== -->
+<!ENTITY % local.footers "">
+<!ELEMENT footer (legal %local.footers;)>
+<!ELEMENT legal (%content.mix;)*>
+<!ATTLIST legal
+ %common.att;
+>
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!-- ===================================================================
+
+ Apache FAQ DTD (Version 1.1)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software FAQ's for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE document PUBLIC
+ "-//APACHE//DTD FAQ Vx.y//EN"
+ "faq-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ FAQs represent a powerful knowledge base and a very good way of solving
+ common user problems reducing messages on mail lists and reducing the effort
+ required for software installation and usage. Thid DTD want to be a common
+ format for FAQ interchange to allow FAQ-O-Matic-type workgroup services to
+ be published in other formats as well as enhancing data interchange.
+
+AUTHORS:
+ Stefano Mazzocchi <stefano@apache.org>
+
+FIXME:
+
+CHANGE HISTORY:
+ 19991129 Initial version. (SM)
+ 20011212 Used public identifiers for external entities (SM)
+
+COPYRIGHT:
+ Copyright (c) @year@ The Apache Software Foundation.
+
+ Permission to copy in any form is granted provided this notice is
+ included in all copies. Permission to redistribute is granted
+ provided this file is distributed untouched in all its parts and
+ included files.
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Include the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+ "-//APACHE//DTD Documentation V1.1//EN"
+ "document-v11.dtd">
+%document;
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ELEMENT faqs (authors?, faq)+>
+<!ATTLIST faqs %common.att;
+ %title.att;>
+
+ <!ELEMENT faq (question, answer)>
+ <!ATTLIST faq %common.att;>
+
+ <!ELEMENT question (%content.mix;)*>
+ <!ATTLIST question %common.att;>
+
+ <!ELEMENT answer (%blocks;)*>
+ <!ATTLIST answer author IDREF #IMPLIED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Faq module (Version 1.1)
+
+TYPICAL INVOCATION:
+
+ <!ENTITY % faq PUBLIC
+ "-//APACHE//ENTITIES FAQ Vxy//EN"
+ "faq-vxy.mod">
+ %faq;
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+ 20020608 Initial version. (SN)
+[Version 1.2]
+ 20030505 Allow mixed content in <answer>, to match <question> (JT)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Element declarations -->
+<!-- =============================================================== -->
+
+<!ELEMENT faqs (authors?, (faq|part)+)>
+<!ATTLIST faqs %common.att;
+ %title.att;>
+
+ <!ELEMENT part (title, (faq | part)+) >
+ <!ATTLIST part %common.att;>
+
+ <!ELEMENT faq (question, answer)>
+ <!ATTLIST faq %common.att;>
+
+ <!ELEMENT question (%content.mix;|elaboration)*>
+ <!ATTLIST question %common.att;>
+
+ <!ELEMENT elaboration (%content.mix;)*>
+ <!ATTLIST elaboration %common.att;>
+
+ <!ELEMENT answer (%flow;)*>
+ <!ATTLIST answer author IDREF #IMPLIED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache FAQ DTD (Version 1.2)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software FAQ's for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE faqs PUBLIC
+ "-//APACHE//DTD FAQ Vx.y//EN"
+ "faq-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ FAQs represent a powerful knowledge base and a very good way of solving
+ common user problems reducing messages on mail lists and reducing the effort
+ required for software installation and usage. Thid DTD want to be a common
+ format for FAQ interchange to allow FAQ-O-Matic-type workgroup services to
+ be published in other formats as well as enhancing data interchange.
+
+FIXME:
+
+CHANGE HISTORY:
+ 19991129 Initial version. (SM)
+ 20011212 Used public identifiers for external entities (SM)
+ 20020418 Added an (optional) 'part' element to create sections in a faq (SN)
+ 20020613 Include the module of ISO character entity sets (DC)
+[Version 1.2]
+ 20030424 Adopt the loosened content model from document-v12 (JT)
+ 20040614 Stay current with latest document-v13 (class attribute)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Include the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+ "-//APACHE//ENTITIES Documentation V1.3//EN"
+ "document-v13.mod">
+%document;
+
+<!-- =============================================================== -->
+<!-- Include the Common ISO Character Entity Sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % common-charents PUBLIC
+ "-//APACHE//ENTITIES Common Character Entity Sets V1.0//EN"
+ "common-charents-v10.mod">
+%common-charents;
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ENTITY % faq PUBLIC
+ "-//APACHE//ENTITIES FAQ V1.1//EN"
+ "faq-v12.mod">
+%faq;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!-- ===================================================================
+
+ Apache JavaDoc DTD (version 0.4-draft)
+
+PURPOSE:
+ This DTD is designed to capture the output of JavaDoc as an XML document
+ through the use of the JavaDocXML Doclet. The hope is that by having the
+ JavaDoc documentation in an XML format, it will be easier for application
+ developers working with XML to treat their java source documentation in the
+ same way they treat any other XML document within their publication framework.
+
+ This DTD should reflect the information contained within the RootDoc object
+ passed to the JavaDocXML Doclet by JavaDoc. The RootDoc object and the rest
+ of the javaDoc Doclet API is specified at
+
+ http://java.sun.com/products/jdk/1.2/docs/tooldocs/javadoc/doclet/index.html
+
+ The only information that appears to be difficult to derive from this DTD
+ that is easy to obtain from the RootDoc object is the information about
+ serialization. However, this information should be derivable by manually
+ looking for the correct serialization methods and other related structures.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE document PUBLIC
+ "-//APACHE//DTD JavaDoc Vx.yz//EN"
+ "javadoc-vxyz.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+ z := status identifier (optional)
+
+NOTES:
+ The authors would like to thank the Cocoon's mail list subscribers for
+ providing such great support and feedback for this DTD.
+
+AUTHORS:
+ Kenneth Murphy <murphyk@umsystem.edu>
+
+FIXME:
+
+CHANGE HISTORY:
+ 199909?? Original idea of XML doclet. (KM)
+ 199910?? Initial version of this DTD. (KM)
+ 19991129 Cleaned up DTD. (SM)
+
+COPYRIGHT:
+ Copyright (c) @year@ The Apache Software Foundation.
+
+ Permission to copy in any form is granted provided this notice is
+ included in all copies. Permission to redistribute is granted
+ provided this file is distributed untouched in all its parts and
+ included files.
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Common Attribute Entities -->
+<!-- =============================================================== -->
+
+<!ENTITY % name 'name CDATA #REQUIRED'>
+<!ENTITY % dimension 'dimension CDATA #REQUIRED'>
+
+<!ENTITY % abstract 'abstract (true | false) "false"'>
+<!ENTITY % anonymous 'anonymous (true | false) "false"'>
+<!ENTITY % synthetic 'synthetic (true | false) "false"'>
+<!ENTITY % static 'static (true | false) "false"'>
+<!ENTITY % final 'final (true | false) "false"'>
+<!ENTITY % transient 'transient (true | false) "false"'>
+<!ENTITY % volatile 'volatile (true | false) "false"'>
+<!ENTITY % native 'native (true | false) "false"'>
+<!ENTITY % synchronized 'synchronized (true | false) "false"'>
+
+<!ENTITY % access 'access (private | package | protected | public) "package"'>
+<!ENTITY % class.access 'access (package | public) "package"'>
+
+<!ENTITY % extensibility 'extensibility (abstract | final | default) "default"'>
+
+
+<!-- =============================================================== -->
+<!-- Javadoc -->
+<!-- =============================================================== -->
+
+<!ELEMENT javadoc (package*, class*, interface*)>
+
+<!-- =============================================================== -->
+<!-- Package -->
+<!-- =============================================================== -->
+
+<!ELEMENT package (doc?, package*, class*, interface*)>
+<!ATTLIST package %name;>
+
+<!-- =============================================================== -->
+<!-- Class -->
+<!-- =============================================================== -->
+
+<!ELEMENT class (doc?,
+ extends_class?,
+ implements?,
+ field*,
+ constructor*,
+ method*,
+ innerclass*)>
+<!ATTLIST class
+ %name;
+ %extensibility;
+ %class.access;>
+
+<!ELEMENT extends_class (classref+)>
+
+<!ELEMENT innerclass (doc?,
+ extends?,
+ implements?,
+ field*,
+ constructor*,
+ method*)>
+<!ATTLIST innerclass
+ %name;
+ %access;
+ %abstract;
+ %anonymous;
+ %final;
+ %static;>
+
+<!-- =============================================================== -->
+<!-- Interface -->
+<!-- =============================================================== -->
+
+<!ELEMENT interface (doc?,
+ extends_interface?,
+ field*,
+ method*)>
+<!ATTLIST interface
+ %name;
+ %access;>
+
+<!ELEMENT extends_interface (interfaceref+)>
+
+<!-- =============================================================== -->
+<!-- Elements -->
+<!-- =============================================================== -->
+
+<!ELEMENT implements (interfaceref+)>
+
+<!ELEMENT throws (classref)+>
+
+<!ELEMENT classref EMPTY>
+<!ATTLIST classref %name;>
+
+<!ELEMENT interfaceref EMPTY>
+<!ATTLIST interfaceref %name;>
+
+<!ELEMENT methodref EMPTY>
+<!ATTLIST methodref %name;>
+
+<!ELEMENT packageref EMPTY>
+<!ATTLIST packageref %name;>
+
+<!ELEMENT primitive EMPTY>
+<!ATTLIST primitive
+ type (void | boolean | int | long | byte | short | double | float | char) #REQUIRED>
+
+<!ELEMENT field (doc?, (classref | interfaceref | primitive))>
+<!ATTLIST field
+ %name;
+ %access;
+ %dimension;
+ %synthetic;
+ %static;
+ %final;
+ %transient;
+ %volatile;>
+
+<!ELEMENT constructor (doc?, parameter*, throws*)>
+<!ATTLIST constructor
+ %name;
+ %access;
+ %synthetic;>
+
+<!ELEMENT method (doc?, returns, parameter*, throws*)>
+<!ATTLIST method
+ %name;
+ %access;
+ %extensibility;
+ %native;
+ %synthetic;
+ %static;
+ %synchronized;>
+
+<!ELEMENT returns (classref | interfaceref | primitive)>
+<!ATTLIST returns %dimension;>
+
+<!ELEMENT parameter (classref | interfaceref | primitive)>
+<!ATTLIST parameter
+ %name;
+ %final;
+ %dimension;>
+
+<!ELEMENT dimension (#PCDATA)>
+
+<!ELEMENT doc (#PCDATA |
+ linktag |
+ authortag |
+ versiontag |
+ paramtag |
+ returntag |
+ exceptiontag |
+ throwstag |
+ seetag |
+ sincetag |
+ deprecatedtag |
+ serialtag |
+ serialfieldtag |
+ serialdatatag)*>
+
+<!ELEMENT linktag (#PCDATA)>
+<!ATTLIST linktag
+ src CDATA #REQUIRED>
+
+<!ELEMENT authortag (#PCDATA | linktag)*>
+
+<!ELEMENT versiontag (#PCDATA | linktag)*>
+
+<!ELEMENT paramtag (#PCDATA | linktag)*>
+<!ATTLIST paramtag %name;>
+
+<!ELEMENT returntag (#PCDATA | linktag)*>
+
+<!ELEMENT exceptiontag (#PCDATA | classref | linktag)*>
+
+<!ELEMENT throwstag (#PCDATA | classref | linktag)*>
+
+<!ELEMENT seetag (#PCDATA | linktag)*>
+<!ATTLIST seetag
+ src CDATA #REQUIRED>
+
+<!ELEMENT sincetag (#PCDATA | linktag)*>
+
+<!ELEMENT deprecatedtag (#PCDATA | linktag)*>
+
+<!ELEMENT serialtag (#PCDATA | linktag)*>
+
+<!ELEMENT serialfieldtag (#PCDATA | linktag)*>
+<!ATTLIST serialfieldtag
+ fieldname CDATA #REQUIRED
+ fieldtype CDATA #REQUIRED>
+
+<!ELEMENT serialdatatag (#PCDATA | linktag)*>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!-- ===================================================================
+
+ Apache Specification DTD (Version 1.1)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software specifications for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE document PUBLIC
+ "-//APACHE//DTD Specification Vx.y//EN"
+ "specification-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+
+AUTHORS:
+ Stefano Mazzocchi <stefano@apache.org>
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+ 19991129 Initial version. (SM)
+[Version 1.1]
+ 20011212 Used public identifiers for external entities (SM)
+
+COPYRIGHT:
+ Copyright (c) @year@ The Apache Software Foundation.
+
+ Permission to copy in any form is granted provided this notice is
+ included in all copies. Permission to redistribute is granted
+ provided this file is distributed untouched in all its parts and
+ included files.
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Include the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+ "-//APACHE//DTD Documentation V1.1//EN"
+ "document-v11.dtd">
+%document;
+
+
+<!-- =============================================================== -->
+<!-- Extend the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!-- extend the local.xxx entities -->
+<!ENTITY % local.blocks "|bl">
+
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ELEMENT specification (header?, body, appendices?, footer?)>
+<!ATTLIST specification %common.att;>
+
+ <!ELEMENT appendices (%sections;)+>
+ <!ATTLIST appendices %common.att;>
+
+<!-- =============================================================== -->
+<!-- Bibliography List -->
+<!-- =============================================================== -->
+
+ <!-- Bibliography list -->
+ <!ELEMENT bl (bi)+>
+ <!ATTLIST bl %common.att;>
+
+ <!-- Book item -->
+ <!ELEMENT bi EMPTY>
+ <!ATTLIST bi %common.att;
+ %name.att;
+ %title.att;
+ %link.att;
+ authors CDATA #REQUIRED
+ date CDATA #IMPLIED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Todos DTD (Version 1.1)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software development todo lists for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE todo PUBLIC
+ "-//APACHE//DTD Todo Vx.y//EN"
+ "todo-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ It is important, expecially in open developped software projects, to keep
+ track of software changes that need to be done, planned features, development
+ assignment, etc. in order to allow better work parallelization and create
+ an entry point for people that want to help. This DTD wants to provide
+ a solid foundation to provide such information and to allow it to be
+ published as well as distributed in a common format.
+
+FIXME:
+ - do we need anymore working contexts? (SM)
+
+CHANGE HISTORY:
+[Version 1.0]
+ 19991129 Initial version. (SM)
+ 19991225 Added actions element for better structure (SM)
+[Version 1.1]
+ 20011212 Used public identifiers for external entities (SM)
+ 20020613 Include the module of ISO character entity sets (DC)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Include the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+ "-//APACHE//ENTITIES Documentation V1.1//EN"
+ "document-v11.mod">
+%document;
+
+<!-- =============================================================== -->
+<!-- Include the Common ISO Character Entity Sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % common-charents PUBLIC
+ "-//APACHE//ENTITIES Common Character Entity Sets V1.0//EN"
+ "common-charents-v10.mod">
+%common-charents;
+
+<!-- =============================================================== -->
+<!-- Include the Common elements -->
+<!-- =============================================================== -->
+
+<!ENTITY % common PUBLIC
+ "-//APACHE//ENTITIES Common Elements V1.0//EN"
+ "common-elems-v10.mod">
+%common;
+
+<!-- =============================================================== -->
+<!-- Include the Todo module -->
+<!-- =============================================================== -->
+
+<!ENTITY % todo PUBLIC
+ "-//APACHE//ENTITIES Todo V1.1//EN"
+ "todo-v11.mod">
+%todo;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Todos module (Version 1.0)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software development todo lists for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!ENTITY % todo PUBLIC
+ "-//APACHE//ENTITIES Todo Vxy//EN"
+ "todo-vxy.mod">
+ %todo;
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ It is important, expecially in open developped software projects, to keep
+ track of software changes that need to be done, planned features, development
+ assignment, etc. in order to allow better work parallelization and create
+ an entry point for people that want to help. This DTD wants to provide
+ a solid foundation to provide such information and to allow it to be
+ published as well as distributed in a common format.
+
+FIXME:
+ - do we need anymore working contexts? (SM)
+
+CHANGE HISTORY:
+[Version 1.0]
+ 19991129 Initial version. (SM)
+ 19991225 Added actions element for better structure (SM)
+[Version 1.1]
+ 20011212 Used public identifiers for external entities (SM)
+
+==================================================================== -->
+<!-- =============================================================== -->
+<!-- Common entities -->
+<!-- =============================================================== -->
+<!ENTITY % priorities "showstopper|high|medium|low|wish|dream">
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+<!ELEMENT todo (title?, devs?, actions+)>
+<!ATTLIST todo
+ %common.att;
+>
+
+<!ELEMENT actions (action+)>
+<!ATTLIST actions
+ %common.att;
+ priority (%priorities;) #IMPLIED
+>
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- ===================================================================
+
+ Apache Todos DTD (Version 1.2)
+
+PURPOSE:
+ This DTD was developed to create a simple yet powerful document
+ type for software development todo lists for use with the Apache projects.
+ It is an XML-compliant DTD and it's maintained by the Apache XML
+ project.
+
+TYPICAL INVOCATION:
+
+ <!DOCTYPE todo PUBLIC
+ "-//APACHE//DTD Todo Vx.y//EN"
+ "todo-vxy.dtd">
+
+ where
+
+ x := major version
+ y := minor version
+
+NOTES:
+ It is important, expecially in open developped software projects, to keep
+ track of software changes that need to be done, planned features, development
+ assignment, etc. in order to allow better work parallelization and create
+ an entry point for people that want to help. This DTD wants to provide
+ a solid foundation to provide such information and to allow it to be
+ published as well as distributed in a common format.
+
+FIXME:
+ - do we need anymore working contexts? (SM)
+
+CHANGE HISTORY:
+[Version 1.0]
+ 19991129 Initial version. (SM)
+ 19991225 Added actions element for better structure (SM)
+[Version 1.1]
+ 20011212 Used public identifiers for external entities (SM)
+ 20020613 Include the module of ISO character entity sets (DC)
+[Version 1.2]
+ 20030424 Adopt the loosened content model from document-v12 (JT)
+ 20040614 Stay current with latest document-v13 (class attribute)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Include the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+ "-//APACHE//ENTITIES Documentation V1.3//EN"
+ "document-v13.mod">
+%document;
+
+<!-- =============================================================== -->
+<!-- Include the Common ISO Character Entity Sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % common-charents PUBLIC
+ "-//APACHE//ENTITIES Common Character Entity Sets V1.0//EN"
+ "common-charents-v10.mod">
+%common-charents;
+
+<!-- =============================================================== -->
+<!-- Include the Common elements -->
+<!-- =============================================================== -->
+
+<!ENTITY % common PUBLIC
+ "-//APACHE//ENTITIES Common Elements V1.0//EN"
+ "common-elems-v10.mod">
+%common;
+
+<!-- =============================================================== -->
+<!-- Include the Todo module -->
+<!-- =============================================================== -->
+
+<!ENTITY % todo PUBLIC
+ "-//APACHE//ENTITIES Todo V1.1//EN"
+ "todo-v11.mod">
+%todo;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+
+<document>
+ <header>
+ <title>Apache POI - Encryption support</title>
+ <authors>
+ <person id="maxcom" name="Maxim Valyanskiy" email="maxcom@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Overview</title>
+ <p>Apache POI contains support for reading few variants of encrypted office files: </p>
+ <ul>
+ <li>XLS - RC4 Encryption</li>
+ <li>XML-based formats (XLSX, DOCX and etc) - AES and Agile Encryption</li>
+ </ul>
+
+ <p>Some "write-protected" files are encrypted with build-in password, POI can read that files too.</p>
+ </section>
+
+ <section><title>XLS</title>
+ <p>When HSSF receive encrypted file, it tries to decode it with MSOffice build-in password.
+ Use static method setCurrentUserPassword(String password) of org.apache.poi.hssf.record.crypto.Biff8EncryptionKey to
+ set password. It sets thread local variable. Do not forget to reset it to null after text extraction.
+ </p>
+ </section>
+
+ <section><title>XML-based formats - Decryption</title>
+ <p>XML-based formats are stored in OLE-package stream "EncryptedPackage". Use org.apache.poi.poifs.crypt.Decryptor
+ to decode file:</p>
+
+ <source>
+EncryptionInfo info = new EncryptionInfo(filesystem);
+Decryptor d = Decryptor.getInstance(info);
+
+try {
+ if (!d.verifyPassword(password)) {
+ throw new RuntimeException("Unable to process: document is encrypted");
+ }
+
+ InputStream dataStream = d.getDataStream(filesystem);
+
+ // parse dataStream
+
+} catch (GeneralSecurityException ex) {
+ throw new RuntimeException("Unable to process encrypted document", ex);
+}
+ </source>
+
+ <p>If you want to read file encrypted with build-in password, use Decryptor.DEFAULT_PASSWORD.</p>
+ </section>
+
+ <section><title>XML-based formats - Encryption</title>
+ <p>Encrypting a file is similar to the above decryption process. Basically you'll need to choose between
+ <link href="http://msdn.microsoft.com/en-us/library/dd952186(v=office.12).aspx">standard and agile encryption</link>.
+ Apart of the CipherMode, the EncryptionInfo class provides further parameters to specify the cipher and
+ hashing algorithm to be used.</p>
+
+ <source>
+POIFSFileSystem fs = new POIFSFileSystem();
+EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile);
+// EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile, CipherAlgorithm.aes192, HashAlgorithm.sha384, -1, -1, null);
+
+Encryptor enc = info.getEncryptor();
+enc.confirmPassword("foobaa");
+
+OPCPackage opc = OPCPackage.open(new File("..."), PackageAccess.READ_WRITE);
+OutputStream os = enc.getDataStream(fs);
+opc.save(os);
+opc.close();
+
+FileOutputStream fos = new FileOutputStream("...");
+fs.writeFilesystem(fos);
+fos.close();
+ </source>
+ </section>
+ </body>
+
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
+
+
+
+
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOdia PUBLIC
+ "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML">
+ %ISOdia;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+ This entity set uses hexadecimal numeric character references.
+
+ Creator: Rick Jelliffe, Allette Systems
+
+ Version: 1997-07-07
+-->
+
+<!ENTITY acute "´" ><!--=acute accent-->
+<!ENTITY breve "˘" ><!--=breve-->
+<!ENTITY caron "ˇ" ><!--=caron-->
+<!ENTITY cedil "¸" ><!--=cedilla-->
+<!ENTITY circ "^" ><!--=circumflex accent-->
+<!ENTITY dblac "˝" ><!--=double acute accent-->
+<!ENTITY die "¨" ><!--=dieresis-->
+<!ENTITY dot "˙" ><!--=dot above-->
+<!ENTITY grave "`" ><!--=grave accent-->
+<!ENTITY macr "¯" ><!--=macron-->
+<!ENTITY ogon "˛" ><!--=ogonek-->
+<!ENTITY ring "˚" ><!--=ring-->
+<!ENTITY tilde "˜" ><!--=tilde-->
+<!ENTITY uml "¨" ><!--=umlaut mark-->
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+
+ Creator: version from ISO 8879:1986
+
+ Version: 0.21 1992-12-04
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOGRK1 PUBLIC
+ "ISO 9573-15:1993//ENTITIES Greek Letters//EN//XML">
+ %ISOGRK1;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+
+ Creator: Rick Jelliffe, from HTMLlat1
+
+ Version: 1997-07-07
+-->
+
+<!ENTITY agr "α" ><!--small alpha, Greek, U03B1 -->
+<!ENTITY Agr "Α" ><!--capital Alpha, Greek, U0391 -->
+<!ENTITY bgr "β" ><!--small beta, Greek, U03B2 -->
+<!ENTITY Bgr "Β" ><!--capital Beta, Greek, U0392 -->
+<!ENTITY ggr "γ" ><!--small gamma, Greek, U03B3 -->
+<!ENTITY Ggr "Γ" ><!--capital Gamma, Greek, U0393 -->
+<!ENTITY dgr "δ" ><!--small delta, Greek, U03B4 -->
+<!ENTITY Dgr "Δ" ><!--capital Delta, Greek, U0394 -->
+<!ENTITY egr "ε" ><!--small epsilon, Greek, U03B5 -->
+<!ENTITY Egr "Ε" ><!--capital Epsilon, Greek, U0395 -->
+<!ENTITY zgr "ζ" ><!--small zeta, Greek, U03B6 -->
+<!ENTITY Zgr "Ζ" ><!--capital Zeta, Greek, U0396 -->
+<!ENTITY eegr "η" ><!--small eta, Greek, U03B7 -->
+<!ENTITY EEgr "Η" ><!--capital Eta, Greek, U0397 -->
+<!ENTITY thgr "θ" ><!--small theta, Greek, U03B8 -->
+<!ENTITY THgr "Θ" ><!--capital Theta, Greek, U0398 -->
+<!ENTITY igr "ι" ><!--small iota, Greek, U03B9 -->
+<!ENTITY Igr "Ι" ><!--capital Iota, Greek, U0399 -->
+<!ENTITY kgr "κ" ><!--small kappa, Greek, U03BA -->
+<!ENTITY Kgr "Κ" ><!--capital Kappa, Greek, U039A -->
+<!ENTITY lgr "λ" ><!--small lambda, Greek, U03BB -->
+<!ENTITY Lgr "Λ" ><!--capital Lambda, Greek, U039B -->
+<!ENTITY mgr "μ" ><!--small mu, Greek, U03BC -->
+<!ENTITY Mgr "Μ" ><!--capital Mu, Greek, U039C -->
+<!ENTITY ngr "ν" ><!--small nu, Greek, U03BD -->
+<!ENTITY Ngr "Ν" ><!--capital Nu, Greek, U039D -->
+<!ENTITY xgr "ξ" ><!--small xi, Greek, U03BE -->
+<!ENTITY Xgr "Ξ" ><!--capital Xi, Greek, U039E -->
+<!ENTITY ogr "ο" ><!--small omicron, Greek, U03BF -->
+<!ENTITY Ogr "Ο" ><!--capital Omicron, Greek, U039F -->
+<!ENTITY pgr "π" ><!--small pi, Greek, U03C0 -->
+<!ENTITY Pgr "Π" ><!--capital Pi, Greek, U03A0 -->
+<!ENTITY rgr "ρ" ><!--small rho, Greek, U03C1 -->
+<!ENTITY Rgr "Ρ" ><!--capital Rho, Greek, U03A1 -->
+<!ENTITY sfgr "ς" ><!--final small sigma, Greek, U03C2 -->
+<!ENTITY sgr "σ" ><!--small sigma, Greek, U03C3 -->
+<!ENTITY Sgr "Σ" ><!--capital Sigma, Greek, U03A3 -->
+<!ENTITY tgr "τ" ><!--small tau, Greek, U03C4 -->
+<!ENTITY Tgr "Τ" ><!--capital Tau, Greek, U03A4 -->
+<!ENTITY ugr "υ" ><!--small upsilon, Greek, U03C5 -->
+<!ENTITY Ugr "Υ" ><!--capital Upsilon, Greek, U03A5 -->
+<!ENTITY phgr "φ" ><!--small phi, Greek, U03C6 -->
+<!ENTITY PHgr "Φ" ><!--capital Phi, Greek, U03A6 -->
+<!ENTITY khgr "χ" ><!--small chi, Greek, U03C7 -->
+<!ENTITY KHgr "Χ" ><!--capital Chi, Greek, U03A7 -->
+<!ENTITY psgr "ψ" ><!--small psi, Greek, U03C8 -->
+<!ENTITY PSgr "Ψ" ><!--capital Psi, Greek, U03A8 -->
+<!ENTITY ohgr "ω" ><!--small omega, Greek, U03C9 -->
+<!ENTITY OHgr "Ω" ><!--capital Omega, Greek, U03A9 -->
+
+
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOlat1 PUBLIC
+ "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML">
+ %ISOlat1;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 8859-1 or ISO 10646 as its document character
+ set. This includes XML documents and ISO HTML documents.
+-->
+
+ <!ENTITY Agrave "À" ><!-- capital A, grave accent -->
+ <!ENTITY Aacute "Á" ><!-- capital A, acute accent -->
+ <!ENTITY Acirc "Â" ><!-- capital A, circumflex accent -->
+ <!ENTITY Atilde "Ã" ><!-- capital A, tilde -->
+ <!ENTITY Auml "Ä" ><!-- capital A, dieresis or umlaut mark -->
+ <!ENTITY Aring "Å" ><!-- capital A, ring -->
+ <!ENTITY AElig "Æ" ><!-- capital AE diphthong (ligature) -->
+ <!ENTITY Ccedil "Ç" ><!-- capital C, cedilla -->
+ <!ENTITY Egrave "È" ><!-- capital E, grave accent -->
+ <!ENTITY Eacute "É" ><!-- capital E, acute accent -->
+ <!ENTITY Ecirc "Ê" ><!-- capital E, circumflex accent -->
+ <!ENTITY Euml "Ë" ><!-- capital E, dieresis or umlaut mark -->
+ <!ENTITY Igrave "Ì" ><!-- capital I, grave accent -->
+ <!ENTITY Iacute "Í" ><!-- capital I, acute accent -->
+ <!ENTITY Icirc "Î" ><!-- capital I, circumflex accent -->
+ <!ENTITY Iuml "Ï" ><!-- capital I, dieresis or umlaut mark -->
+ <!ENTITY ETH "Ð" ><!-- capital Eth, Icelandic -->
+ <!ENTITY Ntilde "Ñ" ><!-- capital N, tilde -->
+ <!ENTITY Ograve "Ò" ><!-- capital O, grave accent -->
+ <!ENTITY Oacute "Ó" ><!-- capital O, acute accent -->
+ <!ENTITY Ocirc "Ô" ><!-- capital O, circumflex accent -->
+ <!ENTITY Otilde "Õ" ><!-- capital O, tilde -->
+ <!ENTITY Ouml "Ö" ><!-- capital O, dieresis or umlaut mark -->
+ <!ENTITY Oslash "Ø" ><!-- capital O, slash -->
+ <!ENTITY Ugrave "Ù" ><!-- capital U, grave accent -->
+ <!ENTITY Uacute "Ú" ><!-- capital U, acute accent -->
+ <!ENTITY Ucirc "Û" ><!-- capital U, circumflex accent -->
+ <!ENTITY Uuml "Ü" ><!-- capital U, dieresis or umlaut mark -->
+ <!ENTITY Yacute "Ý" ><!-- capital Y, acute accent -->
+ <!ENTITY THORN "Þ" ><!-- capital THORN, Icelandic -->
+ <!ENTITY szlig "ß" ><!-- small sharp s, German (sz ligature) -->
+ <!ENTITY agrave "à" ><!-- small a, grave accent -->
+ <!ENTITY aacute "á" ><!-- small a, acute accent -->
+ <!ENTITY acirc "â" ><!-- small a, circumflex accent -->
+ <!ENTITY atilde "ã" ><!-- small a, tilde -->
+ <!ENTITY auml "ä" ><!-- small a, dieresis or umlaut mark -->
+ <!ENTITY aring "å" ><!-- small a, ring -->
+ <!ENTITY aelig "æ" ><!-- small ae diphthong (ligature) -->
+ <!ENTITY ccedil "ç" ><!-- small c, cedilla -->
+ <!ENTITY egrave "è" ><!-- small e, grave accent -->
+ <!ENTITY eacute "é" ><!-- small e, acute accent -->
+ <!ENTITY ecirc "ê" ><!-- small e, circumflex accent -->
+ <!ENTITY euml "ë" ><!-- small e, dieresis or umlaut mark -->
+ <!ENTITY igrave "ì" ><!-- small i, grave accent -->
+ <!ENTITY iacute "í" ><!-- small i, acute accent -->
+ <!ENTITY icirc "î" ><!-- small i, circumflex accent -->
+ <!ENTITY iuml "ï" ><!-- small i, dieresis or umlaut mark -->
+ <!ENTITY eth "ð" ><!-- small eth, Icelandic -->
+ <!ENTITY ntilde "ñ" ><!-- small n, tilde -->
+ <!ENTITY ograve "ò" ><!-- small o, grave accent -->
+ <!ENTITY oacute "ó" ><!-- small o, acute accent -->
+ <!ENTITY ocirc "ô" ><!-- small o, circumflex accent -->
+ <!ENTITY otilde "õ" ><!-- small o, tilde -->
+ <!ENTITY ouml "ö" ><!-- small o, dieresis or umlaut mark -->
+
+ <!ENTITY oslash "ø" ><!-- small o, slash -->
+ <!ENTITY ugrave "ù" ><!-- small u, grave accent -->
+ <!ENTITY uacute "ú" ><!-- small u, acute accent -->
+ <!ENTITY ucirc "û" ><!-- small u, circumflex accent -->
+ <!ENTITY uuml "ü" ><!-- small u, dieresis or umlaut mark -->
+ <!ENTITY yacute "ý" ><!-- small y, acute accent -->
+ <!ENTITY thorn "þ" ><!-- small thorn, Icelandic -->
+ <!ENTITY yuml "ÿ" ><!-- small y, dieresis or umlaut mark -->
+
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOnum PUBLIC
+ "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML">
+ %ISOnum;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+ This entity set uses hexadecimal numeric character references.
+
+ Creator: Rick Jelliffe, Allette Systems
+
+ Version: 1997-07-07
+-->
+
+<!ENTITY half "½" ><!--=fraction one-half-->
+<!ENTITY frac12 "½" ><!--=fraction one-half-->
+<!ENTITY frac14 "¼" ><!--=fraction one-quarter-->
+<!ENTITY frac34 "¾" ><!--=fraction three-quarters-->
+<!ENTITY frac18 "⅛" >
+ <!-- or "±Ȃ⁄₈" --><!--=fraction one-eighth-->
+<!ENTITY frac38 "⅜" >
+ <!-- or "³⁄₈" --><!--=fraction three-eighths-->
+<!ENTITY frac58 "⅝" >
+ <!-- or "⁵⁄₈" --><!--=fraction five-eighths-->
+<!ENTITY frac78 "⅞" >
+ <!-- or "⁷⁄₈" --><!--=fraction seven-eighths-->
+
+<!ENTITY sup1 "¹" ><!--=superscript one-->
+<!ENTITY sup2 "²" ><!--=superscript two-->
+<!ENTITY sup3 "³" ><!--=superscript three-->
+
+<!ENTITY plus "+" ><!--=plus sign B:-->
+<!ENTITY plusmn "±" ><!--/pm B: =plus-or-minus sign-->
+<!ENTITY lt "&#60;" ><!--=less-than sign R:-->
+<!ENTITY equals "=" ><!--=equals sign R:-->
+<!ENTITY gt ">" ><!--=greater-than sign R:-->
+<!ENTITY divide "÷" ><!--/div B: =divide sign-->
+<!ENTITY times "×" ><!--/times B: =multiply sign-->
+
+<!ENTITY curren "¤" ><!--=general currency sign-->
+<!ENTITY pound "£" ><!--=pound sign-->
+<!ENTITY dollar "$" ><!--=dollar sign-->
+<!ENTITY cent "¢" ><!--=cent sign-->
+<!ENTITY yen "¥" ><!--/yen =yen sign-->
+
+<!ENTITY num "#" ><!--=number sign-->
+<!ENTITY percnt "%" ><!--=percent sign-->
+<!ENTITY amp "&#38;" ><!--=ampersand-->
+<!ENTITY ast "*" ><!--/ast B: =asterisk-->
+<!ENTITY commat "@" ><!--=commercial at-->
+<!ENTITY lsqb "[" ><!--/lbrack O: =left square bracket-->
+<!ENTITY bsol "\" ><!--/backslash =reverse solidus-->
+<!ENTITY rsqb "]" ><!--/rbrack C: =right square bracket-->
+<!ENTITY lcub "{" ><!--/lbrace O: =left curly bracket-->
+<!ENTITY horbar "―" ><!--=horizontal bar-->
+<!ENTITY verbar "|" ><!--/vert =vertical bar-->
+<!ENTITY rcub "}" ><!--/rbrace C: =right curly bracket-->
+<!ENTITY micro "µ" ><!--=micro sign-->
+<!ENTITY ohm "ࡎ" ><!--=ohm sign-->
+<!ENTITY deg "°" ><!--=degree sign-->
+<!ENTITY ordm "º" ><!--=ordinal indicator, masculine-->
+<!ENTITY ordf "ª" ><!--=ordinal indicator, feminine-->
+<!ENTITY sect "§" ><!--=section sign-->
+<!ENTITY para "¶" ><!--=pilcrow (paragraph sign)-->
+<!ENTITY middot "·" ><!--/centerdot B: =middle dot-->
+<!ENTITY larr "←" ><!--/leftarrow /gets A: =leftward arrow-->
+<!ENTITY rarr "→" ><!--/rightarrow /to A: =rightward arrow-->
+<!ENTITY uarr "↑" ><!--/uparrow A: =upward arrow-->
+<!ENTITY darr "↓" ><!--/downarrow A: =downward arrow-->
+<!ENTITY copy "©" ><!--=copyright sign-->
+<!ENTITY reg "®" ><!--/circledR =registered sign-->
+<!ENTITY trade "™" ><!--=trade mark sign-->
+<!ENTITY brvbar "¦" ><!--=bren (vertical) bar-->
+<!ENTITY not "¬" ><!--/neg /lnot =not sign-->
+<!ENTITY sung "♪" ><!--=music note (sung text sign)-->
+
+<!ENTITY excl "!" ><!--=exclamation mark-->
+<!ENTITY iexcl "¡" ><!--=inverted exclamation mark-->
+<!ENTITY quot '"' ><!--=quotation mark-->
+<!ENTITY apos "'" ><!--=apostrophe-->
+<!ENTITY lpar "(" ><!--O: =left parenthesis-->
+<!ENTITY rpar ")" ><!--C: =right parenthesis-->
+<!ENTITY comma "," ><!--P: =comma-->
+<!ENTITY lowbar "_" ><!--=low line-->
+<!ENTITY hyphen "‐" ><!--=hyphen-->
+<!ENTITY period "." ><!--=full stop, period-->
+<!ENTITY sol "/" ><!--=solidus-->
+<!ENTITY colon ":" ><!--/colon P:-->
+<!ENTITY semi ";" ><!--=semicolon P:-->
+<!ENTITY quest "?" ><!--=question mark-->
+<!ENTITY iquest "¿" ><!--=inverted question mark-->
+<!ENTITY laquo "‹" ><!--=angle quotation mark, left
+ But note that Unicode 1 & Maler & el Andaloussi give « -->
+<!ENTITY raquo "›" ><!--=angle quotation mark, right
+ But note that Unicode 1 & Maler & el Andaloussi give » -->
+<!ENTITY lsquo "‘" ><!--=single quotation mark, left-->
+<!ENTITY rsquo "’" ><!--=single quotation mark, right-->
+<!ENTITY ldquo "“" ><!--=double quotation mark, left-->
+<!ENTITY rdquo "”" ><!--=double quotation mark, right-->
+<!ENTITY nbsp " " ><!--=no break (required) space-->
+<!ENTITY shy "­" ><!--=soft hyphen-->
+
+
--- /dev/null
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOpub PUBLIC
+ "ISO 8879:1986//ENTITIES Publishing//EN//XML">
+ %ISOpub;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+ This entity set uses hexadecimal numeric character references.
+
+ Creator: Rick Jelliffe, Allette Systems
+
+ Version: 1997-07-07
+-->
+<!ENTITY emsp " " ><!--=em space-->
+<!ENTITY ensp " " ><!--=en space (1/2-em)-->
+<!ENTITY emsp13 " " ><!--=1/3-em space-->
+<!ENTITY emsp14 " " ><!--=1/4-em space-->
+<!ENTITY numsp " " ><!--=digit space (width of a number)-->
+<!ENTITY puncsp " " ><!--=punctuation space (width of comma)-->
+<!ENTITY thinsp " " ><!--=thin space (1/6-em)-->
+<!ENTITY hairsp " " ><!--=hair space-->
+<!ENTITY mdash "—" ><!--=em dash-->
+<!ENTITY ndash "–" ><!--=en dash-->
+<!ENTITY dash "‐" ><!--=hyphen (true graphic)-->
+<!ENTITY blank "␣" ><!--=significant blank symbol-->
+<!ENTITY hellip "…" ><!--=ellipsis (horizontal)-->
+<!ENTITY nldr "‥" ><!--=double baseline dot (en leader)-->
+<!ENTITY frac13 "⅓" ><!--=fraction one-third-->
+<!ENTITY frac23 "⅔" ><!--=fraction two-thirds-->
+<!ENTITY frac15 "⅕" ><!--=fraction one-fifth-->
+<!ENTITY frac25 "⅖" ><!--=fraction two-fifths-->
+<!ENTITY frac35 "⅗" ><!--=fraction three-fifths-->
+<!ENTITY frac45 "⅘" ><!--=fraction four-fifths-->
+<!ENTITY frac16 "⅙" ><!--=fraction one-sixth-->
+<!ENTITY frac56 "⅚" ><!--=fraction five-sixths-->
+<!ENTITY incare "℅" ><!--=in-care-of symbol-->
+<!ENTITY block "█" ><!--=full block-->
+<!ENTITY uhblk "▀" ><!--=upper half block-->
+<!ENTITY lhblk "▄" ><!--=lower half block-->
+<!ENTITY blk14 "░" ><!--=25% shaded block-->
+<!ENTITY blk12 "▒" ><!--=50% shaded block-->
+<!ENTITY blk34 "▓" ><!--=75% shaded block-->
+<!ENTITY marker "▮" ><!--=histogram marker-->
+<!ENTITY cir "○" ><!--/circ B: =circle, open-->
+<!ENTITY squ "□" ><!--=square, open-->
+<!ENTITY rect "▭" ><!--=rectangle, open-->
+<!ENTITY utri "▵" ><!--/triangle =up triangle, open-->
+<!ENTITY dtri "▿" ><!--/triangledown =down triangle, open-->
+<!ENTITY star "☆" ><!--=star, open-->
+<!ENTITY bull "•" ><!--/bullet B: =round bullet, filled-->
+<!ENTITY squf "▪" ><!--/blacksquare =sq bullet, filled-->
+<!ENTITY utrif "▴" ><!--/blacktriangle =up tri, filled-->
+<!ENTITY dtrif "▾" ><!--/blacktriangledown =dn tri, filled-->
+<!ENTITY ltrif "◂" ><!--/blacktriangleleft R: =l tri, filled-->
+<!ENTITY rtrif "▸" ><!--/blacktriangleright R: =r tri, filled-->
+<!ENTITY clubs "♣" ><!--/clubsuit =club suit symbol-->
+<!ENTITY diams "♢" ><!--/diamondsuit =diamond suit symbol-->
+<!ENTITY hearts "♡" ><!--/heartsuit =heart suit symbol-->
+<!ENTITY spades "♠" ><!--/spadesuit =spades suit symbol-->
+<!ENTITY malt "✠" ><!--/maltese =maltese cross-->
+<!ENTITY dagger "†" ><!--/dagger B: =dagger-->
+<!ENTITY Dagger "‡" ><!--/ddagger B: =double dagger-->
+<!ENTITY check "✓" ><!--/checkmark =tick, check mark-->
+<!ENTITY cross "✗" ><!--=ballot cross-->
+<!ENTITY sharp "♯" ><!--/sharp =musical sharp-->
+<!ENTITY flat "♭" ><!--/flat =musical flat-->
+<!ENTITY male "♂" ><!--=male symbol-->
+<!ENTITY female "♀" ><!--=female symbol-->
+<!ENTITY phone "⛠" ><!--=telephone symbol-->
+<!ENTITY telrec "⌕" ><!--=telephone recorder symbol-->
+<!ENTITY copysr "℗" ><!--=sound recording copyright sign-->
+<!ENTITY caret "⁁" ><!--=caret (insertion mark)-->
+<!ENTITY lsquor "‚" ><!--=rising single quote, left (low)-->
+<!ENTITY ldquor "„" ><!--=rising dbl quote, left (low)-->
+
+<!ENTITY fflig "ff" ><!--small ff ligature-->
+<!ENTITY filig "fi" ><!--small fi ligature-->
+<!ENTITY fjlig "fj" ><!--small fj ligature-->
+<!ENTITY ffilig "ffi" ><!--small ffi ligature-->
+<!ENTITY ffllig "ffl" ><!--small ffl ligature-->
+<!ENTITY fllig "fl" ><!--small fl ligature-->
+
+<!ENTITY mldr "‥" ><!--em leader-->
+<!ENTITY rdquor "”" ><!--rising dbl quote, right (high)-->
+<!ENTITY rsquor "’" ><!--rising single quote, right (high)-->
+<!ENTITY vellip "⋮" ><!--vertical ellipsis-->
+
+<!ENTITY hybull "⁃" ><!--rectangle, filled (hyphen bullet)-->
+<!ENTITY loz "✧" ><!--/lozenge - lozenge or total mark-->
+<!ENTITY lozf "✦" ><!--/blacklozenge - lozenge, filled-->
+<!ENTITY ltri "◃" ><!--/triangleleft B: l triangle, open-->
+<!ENTITY rtri "▹" ><!--/triangleright B: r triangle, open-->
+<!ENTITY starf "★" ><!--/bigstar - star, filled-->
+
+<!ENTITY natur "♮" ><!--/natural - music natural-->
+<!ENTITY rx "℞" ><!--pharmaceutical prescription (Rx)-->
+<!ENTITY sext "✶" ><!--sextile (6-pointed star)-->
+
+<!ENTITY target "⌖" ><!--register mark or target-->
+<!ENTITY dlcrop "⌍" ><!--downward left crop mark -->
+<!ENTITY drcrop "⌌" ><!--downward right crop mark -->
+<!ENTITY ulcrop "⌏" ><!--upward left crop mark -->
+<!ENTITY urcrop "⌎" ><!--upward right crop mark -->
+
--- /dev/null
+
+<!-- (C) International Organization for Standardization 1986
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+ <!ENTITY % ISOtech PUBLIC
+ "ISO 8879:1986//ENTITIES General Technical//EN//XML"
+ "ISOtech.pen">
+ %ISOtech;
+-->
+<!-- This version of the entity set can be used with any SGML document
+ which uses ISO 10646 as its document character set.
+ This includes XML documents and ISO HTML documents.
+ This entity set uses hexadecimal numeric character references.
+
+ Creator: Rick Jelliffe, Allette Systems
+
+ Version: 1997-07-07
+-->
+<!ENTITY aleph "ℵ" ><!--/aleph =aleph, Hebrew-->
+<!ENTITY and "∧" ><!--/wedge /land B: =logical and-->
+<!ENTITY ang90 "∟" ><!--=right (90 degree) angle-->
+<!ENTITY angsph "∢" ><!--/sphericalangle =angle-spherical-->
+<!ENTITY ap "≉" ><!--/approx R: =approximate-->
+<!ENTITY becaus "∵" ><!--/because R: =because-->
+<!ENTITY bottom "⊥" ><!--/bot B: =perpendicular-->
+<!ENTITY cap "∩" ><!--/cap B: =intersection-->
+<!ENTITY cong "≅" ><!--/cong R: =congruent with-->
+<!ENTITY conint "∮" ><!--/oint L: =contour integral operator-->
+<!ENTITY cup "∪" ><!--/cup B: =union or logical sum-->
+<!ENTITY equiv "≡" ><!--/equiv R: =identical with-->
+<!ENTITY exist "∃" ><!--/exists =at least one exists-->
+<!ENTITY forall "∀" ><!--/forall =for all-->
+<!ENTITY fnof "ƒ" ><!--=function of (italic small f)-->
+<!ENTITY ge "≥" ><!--/geq /ge R: =greater-than-or-equal-->
+<!ENTITY iff "⇔" ><!--/iff =if and only if-->
+<!ENTITY infin "∞" ><!--/infty =infinity-->
+<!ENTITY int "∫" ><!--/int L: =integral operator-->
+<!ENTITY isin "∈" ><!--/in R: =set membership-->
+<!ENTITY lang "〈" ><!--/langle O: =left angle bracket-->
+<!ENTITY lArr "⇐" ><!--/Leftarrow A: =is implied by-->
+<!ENTITY le "≤" ><!--/leq /le R: =less-than-or-equal-->
+<!ENTITY minus "-" ><!--B: =minus sign-->
+<!ENTITY mnplus "∓" ><!--/mp B: =minus-or-plus sign-->
+<!ENTITY nabla "∇" ><!--/nabla =del, Hamilton operator-->
+<!ENTITY ne "≠" ><!--/ne /neq R: =not equal-->
+<!ENTITY ni "∋" ><!--/ni /owns R: =contains-->
+<!ENTITY or "∨" ><!--/vee /lor B: =logical or-->
+<!ENTITY par "∥" ><!--/parallel R: =parallel-->
+<!ENTITY part "∂" ><!--/partial =partial differential-->
+<!ENTITY permil "‰" ><!--=per thousand-->
+<!ENTITY perp "⊥" ><!--/perp R: =perpendicular-->
+<!ENTITY prime "′" ><!--/prime =prime or minute-->
+<!ENTITY Prime "″" ><!--=double prime or second-->
+<!ENTITY prop "∝" ><!--/propto R: =is proportional to-->
+<!ENTITY radic "√" ><!--/surd =radical-->
+<!ENTITY rang "〉" ><!--/rangle C: =right angle bracket-->
+<!ENTITY rArr "⇒" ><!--/Rightarrow A: =implies-->
+<!ENTITY sim "∼" ><!--/sim R: =similar-->
+<!ENTITY sime "≃" ><!--/simeq R: =similar, equals-->
+<!ENTITY square "□" ><!--/square B: =square-->
+<!ENTITY sub "⊂" ><!--/subset R: =subset or is implied by-->
+<!ENTITY sube "⊆" ><!--/subseteq R: =subset, equals-->
+<!ENTITY sup "⊃" ><!--/supset R: =superset or implies-->
+<!ENTITY supe "⊇" ><!--/supseteq R: =superset, equals-->
+<!ENTITY there4 "∴" ><!--/therefore R: =therefore-->
+<!ENTITY Verbar "‖" ><!--/Vert =dbl vertical bar-->
+
+<!ENTITY angst "Å" ><!--Angstrom =capital A, ring-->
+<!ENTITY bernou "ℬ" ><!--Bernoulli function (script capital B)-->
+<!ENTITY compfn "∘" ><!--B: composite function (small circle)-->
+<!ENTITY Dot "¨" ><!--=dieresis or umlaut mark-->
+<!ENTITY DotDot "⃜" ><!--four dots above-->
+<!ENTITY hamilt "ℋ" ><!--Hamiltonian (script capital H)-->
+<!ENTITY lagran "ℒ" ><!--Lagrangian (script capital L)-->
+<!ENTITY lowast "∗" ><!--low asterisk-->
+<!ENTITY notin "∉" ><!--N: negated set membership-->
+<!ENTITY order "ℴ" ><!--order of (script small o)-->
+<!ENTITY phmmat "ℳ" ><!--physics M-matrix (script capital M)-->
+<!ENTITY tdot "⃛" ><!--three dots above-->
+<!ENTITY tprime "‴" ><!--triple prime-->
+<!ENTITY wedgeq "≙" ><!--R: corresponds to (wedge, equals)-->
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE faqs PUBLIC "-//APACHE//DTD FAQ V1.1//EN" "./dtd/faq-v11.dtd">
+
+<faqs title="Frequently Asked Questions">
+ <faq>
+ <question>
+ My code uses some new feature, compiles fine but fails when live with a "MethodNotFoundException" or "IncompatibleClassChangeError"
+ </question>
+ <answer>
+ <p>You almost certainly have an older version of POI
+ on your classpath. Quite a few runtimes and other packages
+ will ship an older version of POI, so this is an easy problem
+ to hit without your realising.</p>
+ <p>The best way to identify the offending earlier jar file is
+ with a few lines of java. These will load one of the core POI
+ classes, and report where it came from.</p>
+ <source>
+ClassLoader classloader =
+ org.apache.poi.poifs.filesystem.POIFSFileSystem.class.getClassLoader();
+URL res = classloader.getResource(
+ "org/apache/poi/poifs/filesystem/POIFSFileSystem.class");
+String path = res.getPath();
+System.out.println("Core POI came from " + path);
+ </source>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ My code uses the scratchpad, compiles fine but fails to run with a "MethodNotFoundException"
+ </question>
+ <answer>
+ <p>You almost certainly have an older version earlier on your
+ classpath. See the prior answer.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ I'm using the poi-ooxml-schemas jar, but my code is failing with "java.lang.NoClassDefFoundError: org/openxmlformats/schemas/*something*"
+ </question>
+ <answer>
+ <p>To use the new OOXML file formats, POI requires a jar containing
+ the file format XSDs, as compiled by
+ <link href="http://xmlbeans.apache.org/">XMLBeans</link>. These
+ XSDs, once compiled into Java classes, live in the
+ <em>org.openxmlformats.schemas</em> namespace.</p>
+ <p>There are two jar files available, as described in
+ <link href="/overview.html">the components overview section</link>.
+ The <em>full jar of all of the schemas is ooxml-schemas-1.1.jar</em>,
+ and it is currently around 15mb. The <em>smaller poi-ooxml-schemas
+ jar</em> is only about 4mb. This latter jar file only contains the
+ typically used parts though.</p>
+ <p>Many users choose to use the smaller poi-ooxml-schemas jar to save
+ space. However, the poi-ooxml-schemas jar only contains the XSDs and
+ classes that are typically used, as identified by the unit tests.
+ Every so often, you may try to use part of the file format which
+ isn't included in the minimal poi-ooxml-schemas jar. In this case,
+ you should switch to the full ooxml-schemas-1.1.jar. Longer term,
+ you may also wish to submit a new unit test which uses the extra
+ parts of the XSDs, so that a future poi-ooxml-schemas jar will
+ include them.</p>
+ <p>There are a number of ways to get the full ooxml-schemas-1.1.jar.
+ If you are a maven user, see the
+ <link href="/overview.html">the components overview section</link>
+ for the artifact details to have maven download it for you.
+ If you download the source release of POI, and/or checkout the
+ source code from <link href="/subversion.html">subversion</link>,
+ then you can run the ant task "compile-ooxml-xsds" to have the
+ OOXML schemas downloaded and compiled for you (This will also
+ give you the XMLBeans generated source code, in case you wish to
+ look at this). Finally, you can download the jar by hand from the
+ <link href="http://www.ibiblio.org/maven/org.apache.poi/jars/">POI
+ Maven Repository</link>.</p>
+ <p>Note that for POI 3.5 and 3.6, the full ooxml schemas jar was
+ named ooxml-schemas-1.0.jar. For POI 3.7, the filename was bumped
+ to ooxml-schemas-1.1.jar when generics support was added. You can
+ use ooxml-schemas-1.1.jar with POI 3.5 and 3.6 if you wish, but
+ POI 3.7 won't wokr with ooxml-schemas-1.0.jar (it needs thew newer
+ one).</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ Why is reading a simple sheet taking so long?
+ </question>
+ <answer>
+ <p>You've probably enabled logging. Logging is intended only for
+ autopsy style debugging. Having it enabled will reduce performance
+ by a factor of at least 100. Logging is helpful for understanding
+ why POI can't read some file or developing POI itself. Important
+ errors are thrown as exceptions, which means you probably don't need
+ logging.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ What is the HSSF "eventmodel"?
+ </question>
+ <answer>
+ <p>The SS eventmodel package is an API for reading Excel files without loading the whole spreadsheet into memory. It does
+ require more knowledge on the part of the user, but reduces memory consumption by more than
+ tenfold. It is based on the AWT event model in combination with SAX. If you need read-only
+ access, this is the best way to do it.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ Why can't read the document I created using Star Office 5.1?
+ </question>
+ <answer>
+ <p>Star Office 5.1 writes some records using the older BIFF standard. This causes some problems
+ with POI which supports only BIFF8.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ Why am I getting an exception each time I attempt to read my spreadsheet?
+ </question>
+ <answer>
+ <p>It's possible your spreadsheet contains a feature that is not currently supported by POI.
+ If you encounter this then please create the simplest file that demonstrates the trouble and submit it to
+ <link href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI">Bugzilla.</link></p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ How do you tell if a spreadsheet cell contains a date?
+ </question>
+ <answer>
+ <p>Excel stores dates as numbers therefore the only way to determine if a cell is
+ actually stored as a date is to look at the formatting. There is a helper method
+ in HSSFDateUtil that checks for this.
+ Thanks to Jason Hoffman for providing the solution.</p>
+ <source>
+ case HSSFCell.CELL_TYPE_NUMERIC:
+ double d = cell.getNumericCellValue();
+ // test if a date!
+ if (HSSFDateUtil.isCellDateFormatted(cell)) {
+ // format in form of M/D/YY
+ cal.setTime(HSSFDateUtil.getJavaDate(d));
+ cellText =
+ (String.valueOf(cal.get(Calendar.YEAR))).substring(2);
+ cellText = cal.get(Calendar.MONTH)+1 + "/" +
+ cal.get(Calendar.DAY_OF_MONTH) + "/" +
+ cellText;
+ }
+ </source>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ I'm trying to stream an XLS file from a servlet and I'm having some trouble. What's the problem?
+ </question>
+ <answer>
+ <p>
+ The problem usually manifests itself as the junk characters being shown on
+ screen. The problem persists even though you have set the correct mime type.
+ </p>
+ <p>
+ The short answer is, don't depend on IE to display a binary file type properly if you stream it via a
+ servlet. Every minor version of IE has different bugs on this issue.
+ </p>
+ <p>
+ The problem in most versions of IE is that it does not use the mime type on
+ the HTTP response to determine the file type; rather it uses the file extension
+ on the request. Thus you might want to add a
+ <strong>.xls</strong> to your request
+ string. For example
+ <em>http://yourserver.com/myServelet.xls?param1=xx</em>. This is
+ easily accomplished through URL mapping in any servlet container. Sometimes
+ a request like
+ <em>http://yourserver.com/myServelet?param1=xx&dummy=file.xls</em> is also
+ known to work.
+ </p>
+ <p>
+ To guarantee opening the file properly in Excel from IE, write out your file to a
+ temporary file under your web root from your servelet. Then send an http response
+ to the browser to do a client side redirection to your temp file. (Note that using a
+ server side redirect using RequestDispatcher will not be effective in this case)
+ </p>
+ <p>
+ Note also that when you request a document that is opened with an
+ external handler, IE sometimes makes two requests to the webserver. So if your
+ generating process is heavy, it makes sense to write out to a temporary file, so that multiple
+ requests happen for a static file.
+ </p>
+ <p>
+ None of this is particular to Excel. The same problem arises when you try to
+ generate any binary file dynamically to an IE client. For example, if you generate
+ pdf files using
+ <link href="http://xml.apache.org/fop">FOP</link>, you will come across many of the same issues.
+ </p>
+ <!-- Thanks to Avik for the answer -->
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ I want to set a cell format (Data format of a cell) of a excel sheet as ###,###,###.#### or ###,###,###.0000. Is it possible using POI ?
+ </question>
+ <answer>
+ <p>
+ Yes. You first need to get a DataFormat object from the workbook and call getFormat with the desired format. Some examples are <link href="spreadsheet/quick-guide.html#DataFormats">here</link>.
+ </p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ I want to set a cell format (Data format of a cell) of a excel sheet as text. Is it possible using POI ?
+ </question>
+ <answer>
+ <p>
+ Yes. This is a built-in format for excel that you can get from DataFormat object using the format string "@". Also, the string "text" will alias this format.
+ </p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ How do I add a border around a merged cell?
+ </question>
+ <answer>
+ <p>Add blank cells around where the cells normally would have been and set the borders individually for each cell.
+ We will probably enhance HSSF in the future to make this process easier.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ I am using styles when creating a workbook in POI, but Excel refuses to open the file, complaining about "Too Many Styles".
+ </question>
+ <answer>
+ <p>You just create the styles OUTSIDE of the loop in which you create cells.</p>
+ <p>GOOD:</p>
+ <source>
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet = wb.createSheet("new sheet");
+ HSSFRow row = null;
+
+ // 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);
+
+ for (int x = 0; x < 1000; x++) {
+
+ // Create a row and put some cells in it. Rows are 0 based.
+ row = sheet.createRow((short) k);
+
+ for (int y = 0; y < 100; y++) {
+ cell = row.createCell((short) k);
+ cell.setCellValue("X");
+ cell.setCellStyle(style);
+ }
+ }
+
+ // Write the output to a file
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ <p>BAD:</p>
+ <source>
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet = wb.createSheet("new sheet");
+ HSSFRow row = null;
+
+ for (int x = 0; x < 1000; x++) {
+ // 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);
+
+ // Create a row and put some cells in it. Rows are 0 based.
+ row = sheet.createRow((short) k);
+
+ for (int y = 0; y < 100; y++) {
+ cell = row.createCell((short) k);
+ cell.setCellValue("X");
+ cell.setCellStyle(style);
+ }
+ }
+
+ // Write the output to a file
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ I can't seem to find the source for the OOXML CT.. classes, where do they
+ come from?
+ </question>
+ <answer>
+ <p>The OOXML support in Apache POI is built on top of the file format
+ XML Schemas, as compiled into Java using
+ <link href="http://xmlbeans.apache.org/">XMLBeans</link>. Currently,
+ the compilation is done with XMLBeans 2.3, for maximum compatibility
+ with installations. (You can use the resulting classes on the XMLBeans
+ 2.3 runtime, or any later version of XMLBeans. If you are currently using
+ XMLBeans 2.2 or earlier, you will unfortunately have to upgrade, but this
+ isn't common any more).</p>
+ <p>All of the <em>org.openxmlformats.schemas.spreadsheetml.x2006</em> CT...
+ classes are auto-generated by XMLBeans. The resulting generated Java goes
+ in the <em>ooxml-schemas-src</em> jar, and the compiled version into the
+ <em>ooxml-schemas</em> jar.</p>
+ <p>The full <em>ooxml-schemas</em> jar is distributed with Apache POI,
+ along with the cut-down <em>poi-ooxml-schemas</em> jar containing just
+ the common parts. The source jar isn't normally distributed with POI.
+ It is, however, available from Maven Central - ask your favourite Maven
+ mirror for the <em>ooxml-schemas-src</em> jar. Alternately, if you download
+ the POI source distribution (or checkout from SVN) and build, Ant will
+ automatically download the specification XML Schema, and compile it for
+ you to generate the source and binary ooxml-schemas jars.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ An OLE2 ("binary") file is giving me problems, but I can't share it. How can I investigate the problem on my own?
+ </question>
+ <answer>
+ <p>The first thing to try is running the
+ <link href="http://blogs.msdn.com/b/officeinteroperability/archive/2011/07/12/microsoft-office-binary-file-format-validator-is-now-available.aspx">Binary File Format Validator</link>
+ from Microsoft against the file, which will report if the file
+ complies with the specification. If your input file doesn't, then this
+ may well explain why POI isn't able to process it correctly. You
+ should probably in this case speak to whoever is generating the file,
+ and have them fix it there. If your POI generated file is identified
+ as having an issue, and you're on the
+ <link href="/howtobuild.html">latest codebase</link>, report a new
+ POI bug and include the details of the validation failure.</p>
+ <p>Another thing to try, especially if the file is valid but POI isn't
+ behaving as expected, are the POI Dev Tools for the component you're
+ using. For example, HSSF has <em>org.apache.poi.hssf.dev.BiffViewer</em>
+ which will allow you to view the file as POI does. This will often
+ allow you to check that things are being read as you expect, and
+ narrow in on problem records and structures.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ An OOXML ("xml") file is giving me problems, but I can't share it. How can I investigate the problem on my own?
+ </question>
+ <answer>
+ <p>There's not currently a simple validator tool as there is for the
+ OLE2 based (binary) file formats, but checking the basics of a file
+ is generally much easier.</p>
+ <p>Files such as .xlsx, .docx and .pptx are actually a zip file of XML
+ files, with a special structure. Your first step in diagnosing the
+ issues with the input or output file will likely be to unzip the
+ file, and look at the XML of it. Newer versions of Office will
+ normally tell you which area of the file is problematic, so
+ narrow in on there. Looking at the XML, does it look correct?</p>
+ <p>When reporting bugs, ideally include the whole file, but if you're
+ unable to then include the snippet of XML for the problem area, and
+ reference the OOXML standard for what it should contain.</p>
+ </answer>
+ </faq>
+</faqs>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Contribution Guidelines</title>
+ <authors>
+ <person name="Nick Burch" email="dev@poi.apache.org"/>
+ <person name="David Fisher" email="dev@poi.apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+
+ <section><title>Index of Contribution Guidelines</title>
+ <ul>
+ <li><link href="#Introduction">Introduction</link></li>
+ <li><link href="#GetInvolved">I just want to get involved, but don't know where to start?</link></li>
+ <li><link href="#SubmittingPatches">Submitting Patches</link></li>
+ <li><link href="#CodeStyle">Code Style</link></li>
+ <li><link href="#Mentoring">Mentoring and Committership</link></li>
+ </ul>
+ </section>
+
+ <anchor id="Introduction"/>
+ <section><title>Introduction</title>
+
+ <section><title>Disclaimer</title>
+ <p>
+ Any information in here that might be perceived as legal information is
+ informational only. We're not lawyers, so consult a legal professional
+ if needed.
+ </p>
+ </section>
+
+ <section><title>The Licensing</title>
+ <p>
+ The POI project is <link href="http://www.opensource.org">OpenSource</link>
+ and developed/distributed under the <link
+ href="http://www.apache.org/foundation/license-faq.html">
+ Apache Software License</link>. Unlike other licenses this license allows
+ free open source development; however, it does not require you to release
+ your source or use any particular license for your source. If you wish
+ to contribute to POI (which you're very welcome and encouraged to do so)
+ then you must agree to release the rights of your source to us under this
+ license.
+ </p>
+ </section>
+ <section><title>Publicly Available Information on the file formats</title>
+ <p>
+ In early 2008, Microsoft made a fairly complete set of documentation
+ on the binary file formats freely and publicly available. These were
+ released under the <link href="http://www.microsoft.com/interop/osp">Open
+ Specification Promise</link>, which does allow us to use them for
+ building open source software under the <link
+ href="http://www.apache.org/foundation/license-FAQ.html">
+ Apache Software License</link>.
+ </p>
+ <p>
+ You can download the documentation on Excel, Word, PowerPoint and
+ Escher (drawing) from
+ <link href="http://msdn.microsoft.com/en-us/library/cc313118.aspx">http://msdn.microsoft.com/en-us/library/cc313118.aspx</link>.
+ Documentation on a few of the supporting technologies used in these
+ file formats can be downloaded from
+ <link href="http://msdn.microsoft.com/en-us/library/jj633110.aspx">http://msdn.microsoft.com/en-us/library/jj633110.aspx</link>.
+ </p>
+ <p>
+ Previously, Microsoft published a book on the Excel 97 file format.
+ It can still be of plenty of use, and is handy dead tree form. Pick up
+ a copy of "Excel 97 Developer's Kit" from your favourite second hand
+ book store.
+ </p>
+ <p>
+ The newer Office Open XML (ooxml) file formats are documented as part
+ of the ECMA / ISO standardisation effort for the formats. This
+ documentation is quite large, but you can normally find the bit you
+ need without too much effort! This can be downloaded from
+ <link href="http://www.ecma-international.org/publications/standards/Ecma-376.htm">http://www.ecma-international.org/publications/standards/Ecma-376.htm</link>,
+ and is also under the <link href="http://www.microsoft.com/interop/osp">OSP</link>.
+ </p>
+ <p>
+ It is also worth checking the documentation and code of the other
+ open source implementations of the file formats.
+ </p>
+ </section>
+ <section><title>I just signed an NDA to get a spec from Microsoft and I'd like to contribute</title>
+ <p>
+ In short, stay away, stay far far away. Implementing these file formats
+ in POI is done strictly by using public information. Most of this Public
+ Information currently comes from the documentation that Microsoft
+ makes freely available (see above). The rest of the public information
+ includes sources from other open source projects, books that state the
+ purpose intended is for allowing implementation of the file format and
+ do not require any non-disclosure agreement and just hard work.
+ We are intent on keeping it legal, by contributing patches you agree to
+ do the same.
+ </p>
+ <p>
+ If you've ever received information regarding the OLE 2 Compound Document
+ Format under any type of exclusionary agreement from Microsoft, or
+ received such information from a person bound by such an agreement, you
+ cannot participate in this project. Sorry. Well, unless you can persuade
+ Microsoft to release you from the terms of the NDA on the grounds that
+ most of the information is now publically available. However, if you have
+ been party to a Microsoft NDA, you will need to get clearance from Microsoft
+ before contributing.
+ </p>
+ <p>
+ Those submitting patches that show insight into the file format may be
+ asked to state explicitly that they have only ever read the publicly
+ available file format information, and not any received under an NDA
+ or similar, and have only made us of the public documentation.
+ </p>
+ </section>
+ </section>
+
+ <anchor id="GetInvolved"/>
+ <section><title>I just want to get involved, but don't know where to start?</title>
+ <ul>
+ <li>Read the rest of the website, understand what POI is and what it does,
+ the project vision, etc.</li>
+ <li>Use POI a bit, look for gaps in the documentation and examples.</li>
+ <li>Join the <link href="mailinglists.html">mailing lists</link> and share your knowledge with others.</li>
+ <li>Get <link href="subversion.html">Subversion</link> and check out the POI source tree</li>
+ <li>Documentation is always the best place to start contributing, maybe you found that if the documentation just told you how to do X then it would make more sense, modify the documentation.</li>
+ <li>Contribute examples - if there's something people are often asking about on the <link href="mailinglists.html">user list</link> which isn't covered in the documentation or current examples, try writing an example of this and uploading it as a patch.</li>
+ <li>Get used to building POI, you'll be doing it a lot, be one with the build, know its targets, etc.</li>
+ <li>Write Unit Tests. Great way to understand POI. Look for classes that aren't tested, or aren't tested on a public/protected method level, start there.</li>
+ <li>Download the file format documentation from Microsoft -
+ <link href="http://www.microsoft.com/interop/docs/OfficeBinaryFormats.mspx">OLE2 Binary File Formats</link> or
+ <link href="http://www.ecma-international.org/publications/standards/Ecma-376.htm">OOXML XML File Formats</link></li>
+ <li>Submit patches (see below) of your contributions, modifications.</li>
+ <li>Check the <link href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI">bug database</link> for simple problem reports, and write a patch to fix the problem</li>
+ <li>Review existing patches in the <link href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI">bug database</link>, and report if they still apply, if they need unit tests atc.</li>
+ <li>Take a look at all the <link href="https://issues.apache.org/bugzilla/buglist.cgi?product=POI;bug_status=NEW;bug_status=NEEDINFO">unresolved issues in the bug database</link>, and see if you can help with testing or patches for them</li>
+ <li>Add in new features, see <link href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI">Bug database</link> for suggestions.</li>
+ </ul>
+
+ <p>The Apache <link href="http://www.apache.org/dev/contributors.html">Contributors Tech Guide</link> gives a good overview how to start contributing patches.</p>
+
+ <p>The Nutch project also have a very useful guide on becoming a
+ new developer in their project. While it is written for their project,
+ a large part of it will apply to POI too. You can read it at
+ <link href="http://wiki.apache.org/nutch/Becoming_A_Nutch_Developer">http://wiki.apache.org/nutch/Becoming_A_Nutch_Developer</link>. The
+ <link href="http://community.apache.org/">Apache Community Development
+ Project</link> also provides guidance and mentoring for new contributors.</p>
+ </section>
+
+ <anchor id="SubmittingPatches"/>
+ <section><title>Submitting Patches</title>
+ <p>
+ Patches are submitted via the <link href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI">Bug Database</link>.
+ Create a new bug, set the subject to [PATCH] followed by a brief description. Explain you patch and any special instructions and submit/save it.
+ Next, go back to the bug, and create attachements for the patch files you
+ created. Be sure to describe not only the files purpose, but its format.
+ (Is that ZIP or a tgz or a bz2 or what?).
+ </p>
+ <p>
+ Ideally, patches should be submitted early and often. This is for
+ two key reasons. Firstly, it's much easier to review smaller patches
+ than large ones. This means that smaller patches are much more likely
+ to be applied to SVN in a timely fashion. Secondly, by sending in your
+ patches earlier rather than later, it's much easier to get feedback
+ on your coding and direction. If you've missed an easier way to do something,
+ or are duplicating some (probably hidden) existing code, or taking things
+ in an unusual direction, it's best to get the feedback sooner rather than
+ later! As such, when submitting patches to POI, as with other Apache
+ Software Foundation projects, do please try to submit early and often, rather
+ than "throwing a large patch over the wall" at the end.
+ </p>
+ <p>
+ A number of Apache projects provide far more comprehensive guides to producing
+ and submitting patches than we do, you may wish to review some of their
+ information if you're unsure. The
+ <link href="http://commons.apache.org/patches.html">Apache Commons</link> one
+ is fairly similar as a starting point.
+ </p>
+ <p>You may create your patch file using either of the following approaches (the committers recommend the first):</p>
+ <section><title>Approach 1 - use Ant</title>
+ <p>Use Ant to generate a patch file to POI: </p>
+ <source>
+ ant -f patch.xml
+ </source>
+ <p>
+ This will create a file named patch.tar.gz that will contain a unified diff of files that have been modified
+ and also include files that have been added. Review the file for completeness and correctness. This approach
+ is recommended because it standardizes the way in which patch files are constructed. It also eliminates the
+ chance of you missing to submit new files that constitute part of the patch.
+ </p>
+ </section>
+ <section><title>Approach 2 - the manual way</title>
+ <p>
+ Patches to existing files should be generated with svn diff filename and save the output to a file.
+ if you want to get the changes made to multiple files in a directory , just use svn diff.
+ then, tar and gzip the patch file as well as any new files that you have added.
+ </p>
+ <p>If you use a unix shell, you may find the following following
+ sequence of commands useful for building the files to attach.</p>
+ <source>
+ # run this in the root of the checkout, i.e. the directory holding
+ # build.xml and poi.pom
+
+ # build the directory to hold new files
+ mkdir /tmp/poi-patch/
+ mkdir /tmp/poi-patch/new-files/
+
+ # get changes to existing files
+ svn diff > /tmp/poi-patch/diff.txt
+
+ # capture any new files, as svn diff won't include them
+ # preserve the path
+ svn status | grep "^\?" | awk '{printf "cp --parents %s /tmp/poi-patch/new-files/\n", $2 }' | sh -s
+
+ # tar up the new files
+ cd /tmp/poi-patch/new-files/
+ tar jcvf ../new-files.tar.bz2
+ cd ..
+
+ # upload these to bugzilla
+ echo "please upload to bugzilla:"
+ echo " /tmp/poi-patch/diff.txt"
+ echo " /tmp/poi-patch/new-files.tar.bz2"
+ </source>
+ </section>
+ <section><title>checklist before submitting a patch</title>
+ <ul>
+ <li>added code complies with <link href="#CodeStyle">coding standards</link></li>
+ <li>added code compiles and runs on java 1.5</li>
+ <li>new java files begin with the <link href="http://www.apache.org/foundation/license-faq.html">
+ apache software license</link> statement.</li>
+ <li>the code does not depend on gpl or lgpl code.</li>
+ <li>the code doesn't include @author tags</li>
+ <li>existing test cases succeed.</li>
+ <li>new test cases written and succeed.</li>
+ <li>documentation page extended as appropriate.</li>
+ <li>diff files generated using svn diff</li>
+ <li>the bugzilla subject dev contains [patch], task name and patch reason in subject.</li>
+ <li>the bugzilla description contains a rationale for the patch.</li>
+ <li>attachment to the bugzilla entry contains the patch file(s).</li>
+ </ul>
+ </section>
+ </section>
+
+ <anchor id="CodeStyle"/>
+ <section><title>Code Style</title>
+ <p>The long standing
+ <link href="http://poi.apache.org/resolutions/res001.html">Minimal
+ Coding Standards</link> from 2002 still largely apply to the project.</p>
+ <p>When making changes to an existing file, please try to follow the
+ same style that that file already uses. This will keep things
+ looking similar, and will prevent patches becoming largely about
+ whitespace. Whitespace fixing changes, if needed, should normally be
+ in their own commit, so that they don't crowd out coding changes
+ in review.</p>
+ <p>Normally, tabs should not be used to indent code. Instead, spaces
+ should be used. If starting on a fresh file, please use 4 spaces to
+ indent your code. If working on an existing file, please use
+ whichever of 3 or 4 spaces that file already follows.</p>
+ <p>Normally, braces should open on the same line as the decision
+ statement. Braces should normally close on their own line. Brackets
+ should normally have a space before them when they are the first.</p>
+ <p>Lines normally shouldn't be too long. There's no hard and fast rule,
+ but if you line is getting above about 90 characters think about
+ splitting it, and you should rarely create something over about 100
+ characters without a very good reason!</p>
+ </section>
+
+ <anchor id="Mentoring"/>
+ <section><title>Mentoring and Committership</title>
+ <p>The POI project will generally offer committership to contributors who send
+ in consistently good patches over a period of several months.</p>
+ <p>The requirement for "good patches" generally means patches which can be applied
+ to SVN with little or no changes. These patches should include unit test, and
+ appropriate documentation. Whilst your first patch to POI may require quite a
+ bit of work before it can be committed by an existing committer, with any luck
+ your later patches will be applied with no / minor tweaks. Please do take note
+ of any changes required by your earlier patches, to learn for later ones! If
+ in doubt, ask on the <link href="mailinglists.html">dev mailing list</link>.</p>
+ <p>The requirement for patches over several months is to ensure that committers
+ remain with the project. It's very easy for a good developer to fire off half
+ a dozen good patches in the couple of weeks that they're working on a POI
+ powered project. However, if that developer then moves away, and stops
+ contributing to POI after that spurt, then they're not a good candidate for
+ committership. As such, we generally require people to stay around for a while,
+ submitting patches and helping on the mailing list before considering them
+ for committership.</p>
+ <p>Where possible, patches should be submitted early and often. For more details
+ on this, please see the "Submitting Patches" section above.</p>
+
+ <p>Where possible, the existing developers will try to help and mentor new
+ contributors. However, everyone involved in POI is a volunteer, and it may
+ happen that your first few patches come in at a time when all the committers
+ are very busy. Do please have patience, and remember to use the
+ <link href="mailinglists.html">dev mailing list</link> so that other
+ contributors can assist you!</p>
+ <p>For more information on getting started at Apache, mentoring, and local
+ Apache Committers near you who can offer advice, please see the
+ <link href="http://community.apache.org/">Apache Community Development
+ Project</link> website.</p>
+ </section>
+
+</body>
+<footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+</footer>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="HDGF"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="HDGF">
+ <menu-item label="Overview" href="index.html"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HDGF - Java API To Access Microsoft Visio Format Files</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick at apache dot org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section>
+ <title>Overview</title>
+
+ <p>HDGF is the POI Project's pure Java implementation of the Visio file format.</p>
+ <p>Currently, HDGF provides a low-level, read-only api for
+ accessing Visio documents. It also provides a
+ <link href="http://svn.apache.org/repos/asf/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/extractor/">way</link>
+ to extract the textual content from a file.
+ </p>
+ <p>At this time, there is no <em>usermodel</em> api or similar,
+ only low level access to the streams, chunks and chunk commands.
+ Users are advised to check the unit tests to see how everything
+ works. They are also well advised to read the documentation
+ supplied with
+ <link href="http://web.archive.org/web/20071212220759/http://www.gnome.ru/projects/vsdump_en.html">vsdump</link>
+ to get a feel for how Visio files are structured.</p>
+ <p>To get a feel for the contents of a file, and to track down
+ where data of interest is stored, HDGF comes with
+ <link href="http://svn.apache.org/repos/asf/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/">VSDDumper</link>
+ to print out the contents of the file. Users should also make
+ use of
+ <link href="http://web.archive.org/web/20071212220759/http://www.gnome.ru/projects/vsdump_en.html">vsdump</link>
+ to probe the structure of files.</p>
+ <note>
+ This code currently lives the
+ <link href="http://svn.apache.org/viewcvs.cgi/poi/trunk/src/scratchpad/">scratchpad area</link>
+ of the POI SVN repository.
+ Ensure that you have the scratchpad jar or the scratchpad
+ build area in your
+ classpath before experimenting with this code.
+ </note>
+
+ <section>
+ <title>Steps required for write support</title>
+ <p>Currently, HDGF is only able to read visio files, it is
+ not able to write them back out again. We believe the
+ following are the steps that would need to be taken to
+ implement it.</p>
+ <ol>
+ <li>Re-write the decompression support in LZW4HDGF as
+ HDGFLZW, which will be much better documented, and also
+ under the ASL. <strong>Completed October 2007</strong></li>
+ <li>Add compression support to HDGFLZW.
+ <strong>In progress - works for small streams but encoding
+ goes wrong on larger ones</strong></li>
+ <li>Have HDGF just write back the raw bytes it read in, and
+ have a test to ensure the file is un-changed.</li>
+ <li>Have HDGF generate the bytes to write out from the
+ Stream stores, using the compressed data as appropriate,
+ without re-compressing. Plus test to ensure file is
+ un-changed.</li>
+ <li>Have HDGF generate the bytes to write out from the
+ Stream stores, re-compressing any streams that were
+ decompressed. Plus test to ensure file is un-changed.</li>
+ <li>Have HDGF re-generate the offsets in pointers for the
+ locations of the streams. Plus test to ensure file is
+ un-changed.</li>
+ <li>Have HDGF re-generate the bytes for all the chunks, from
+ the chunk commands. Tests to ensure the chunks are
+ serialized properly, and then that the file is un-changed</li>
+ <li>Alter the data of one command, but keep it the same
+ length, and check visio can open the file when written
+ out.</li>
+ <li>Alter the data of one command, to a new length, and
+ check that visio can open the file when written out.</li>
+ </ol>
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Project History</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+
+
+ <section><title>Apache POI - Brief Project History</title>
+
+ <p>The POI project was dreamed up back around April 2001, when
+ Andrew Oliver landed a short term contract to do Java-based
+ reporting to Excel. He'd done this project a few times before
+ and knew right where to look for the tools he needed.
+ Ironically, the API he used to use had skyrocketed from around
+ $300 ($US) to around $10K ($US). He figured it would take two
+ people around six months to write an Excel port so he
+ recommended the client fork out the $10K.
+ </p>
+
+ <p>Around June 2001, Andrew started thinking how great it would
+ be to have an open source Java tool to do this and, while he
+ had some spare time, he started on the project and learned
+ about OLE 2 Compound Document Format. After hitting some real
+ stumpers he realized he'd need help. He posted a message to
+ his local Java User's Group (JUG) and asked if anyone else
+ would be interested. He lucked out and the most talented Java
+ programmer he'd ever met, Marc Johnson, joined the project. He
+ ran rings around Andrew at porting OLE 2 CDF and rewrote his
+ skeletal code into a more sophisticated library. It took Marc
+ a few iterations to get something they were happy with.
+ </p>
+
+ <p>While Marc worked on that, Andrew ported XLS to Java, based
+ on Marc's library. Several users wrote in asking to read XLS
+ (not just write as had originally been planned) and one user
+ had special requests for a different use for POIFS. Before
+ long, the project scope had tripled. POI 1.0 was released a
+ month later than planned, but with far more features. Marc
+ quickly wrote the serializer framework and HSSF Serializer in
+ record time and Andrew banged out more documentation and worked
+ on making people aware of the project
+ </p>
+
+ <p> Shortly before the release, POI was fortunate to come into
+ contact with Nicola -Ken- Barrozzi who gave them samples for
+ the HSSF Serializer and help uncover its unfortunate bugs
+ (which were promptly fixed). More recently, Ken ported most
+ of the POI project documentation to XML from Andrew's crappy
+ HTML docs he wrote with Star Office.
+ </p>
+
+ <p> Around the same time as the release, Glen Stampoultzis
+joined the project. Glen was ticked off at Andrew's flippant attitude
+towards adding graphing to HSSF. Glen got so ticked off he decided to
+grab a hammer and do it himself. Glen has already become an integral
+part of the POI development community; his contributions to HSSF have
+already started making waves.
+ </p>
+
+ <p>Somewhere in there we decided to finally submit the project
+ to <link href="http://cocoon.apache.org/">The Apache
+ Cocoon Project</link>, only to discover the project had
+ outgrown fitting nicely into just Cocoon long ago.
+ Furthermore, Andrew started eyeing other projects he'd like to
+ see POI functionality added to. So it was decided to donate
+ the Serializers and Generators to Cocoon, other POI
+ integration components to other projects, and the POI APIs
+ would become part of Jakarta. It was a bumpy road but it
+ looks like everything turned out since you're reading this!
+ </p>
+
+ <p>In Early 2007, we graduated from
+ <link href="http://jakarta.apache.org/">Jakarta</link>, and became
+ our own Top Level Project (TLP) within Apache.</p>
+ </section>
+
+<!--
+ <section><title>What's next for Poi</title>
+ <p>First we'll tackle this from a project standpoint: Well, we
+ made an offer to Microsoft and Actuate (tongue in cheek
+ ... well mostly) that we'd quit the project and retire if
+ they'd simply write us each a really large check. I've yet to
+ get a phone call or email so I'm assuming they're not going to
+ pay us to go away.
+ </p>
+ <p>Next, we've got some work to do here at Jakarta to finish
+ integrating POI into the community. Furthermore, we're
+ still transitioning the Serializer to Cocoon.
+ </p>
+ <p>HSSF, during the 2.0 cycle, will undergo a few
+ optimizations. We'll also be adding new features like a full
+ implementation of Formulas and custom text formats. We're
+ hoping to be able to generate smaller files by adding
+ write-support for RK, MulRK and MulBlank records. I'm also
+ going to work on a Cocoon 2 Generator. Currently, reading is
+ not very efficient in HSSF. This is mainly because in order to
+ write or modify, one needs to be able to update upstream
+ pointers to downstream data. To do this you have to have
+ everything between in memory. A Generator would allow SAX
+ events to be processed instead. (This will be based on the low
+ level structures). One of the great things about this is that,
+ you'll not only have a more efficient way to read the file,
+ you'll have a great way to use spreadsheets as XML data
+ sources.
+ </p>
+ <p>The HSSF Serializer, will further separate into a general
+ framework for creating serializers for other formats and the
+ HSSF Serializer specific implementation. (This is largely
+ already true). We'll also be adding support for features
+ already supported by HSSF (styles, fonts, text formats). We're
+ hoping to add support for formulas during this cycle.
+ </p>
+ <p>We're beginning to expand our scope yet again. If we could
+ do all of this for XLS files, what about Doc files or PowerPoint
+ files? We're thinking that our next component (HWPF - Manipulates
+ Word Processor Format) should follow the same pattern. We're hoping
+ that new blood will join the team and allow us to tackle this
+ even faster (in part because POIFS is already finished). But
+ maybe what we need most is you! </p>
+ </section> -->
+
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+
+
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="HMEF"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="HMEF">
+ <menu-item label="Overview" href="index.html"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HMEF - Java API To Access Microsoft Transport Neutral Encoding Files (TNEF)</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick at apache dot org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section>
+ <title>Overview</title>
+
+ <p>HMEF is the POI Project's pure Java implementation of Microsoft's
+ TNEF (Transport Neurtral Encoding Format), aka winmail.dat,
+ which is used by Outlook and Exchange in some situations.</p>
+ <p>Currently, HMEF provides a read-only api for accessing common
+ message and attachment attributes, including the message body
+ and attachment files. In addition, it's possible to have
+ read-only access to all of the underlying TNEF and MAPI
+ attributes of the message and attachments.</p>
+ <p>HMEF also provides a command line tool for extracting out
+ the message body and attachment files from a TNEF (winmail.dat)
+ file.</p>
+
+ <note>
+ This code currently lives the
+ <link href="http://svn.apache.org/viewcvs.cgi/poi/trunk/src/scratchpad/">scratchpad area</link>
+ of the POI SVN repository.
+ Ensure that you have the scratchpad jar or the scratchpad
+ build area in your classpath before experimenting with this code.
+ </note>
+ <note>
+ This code is a new POI feature, and the first release that will
+ contain it will be POI 3.8 beta 2. Until then, you will need to
+ build your own jars from a <link href="../subversion.html">svn
+ checkout</link>.
+ </note>
+ </section>
+
+ <section>
+ <title>Using HMEF to access TNEF (winmail.dat) files</title>
+
+ <section>
+ <title>Easy extraction of message body and attachment files</title>
+
+ <p>The class <em>org.apache.poi.hmef.extractor.HMEFContentsExtractor</em>
+ provides both command line and Java extraction. It allows the
+ saving of the message body (an RTF file), and all of the
+ attachment files, to a single directory as specified.</p>
+
+ <p>From the command line, simply call the class specifying the
+ TNEF file to extract, and the directory to place the extracted
+ files into, eg:</p>
+ <source>
+ java -classpath poi-3.8-FINAL.jar:poi-scratchpad-3.8-FINAL.jar org.apache.poi.hmef.extractor.HMEFContentsExtractor winmail.dat /tmp/extracted/
+ </source>
+
+ <p>From Java, there are two method calls on the class, one to
+ extract the message body RTF to a file, and the other to extract
+ all the attachments to a directory. A typical use would be:</p>
+ <source>
+public void extract(String winmailFilename, String directoryName) throws Exception {
+ HMEFContentsExtractor ext = new HMEFContentsExtractor(new File(winmailFilename));
+
+ File dir = new File(directoryName);
+ File rtf = new File(dir, "message.rtf");
+ if(! dir.exists()) {
+ throw new FileNotFoundException("Output directory " + dir.getName() + " not found");
+ }
+
+ System.out.println("Extracting...");
+ ext.extractMessageBody(rtf);
+ ext.extractAttachments(dir);
+ System.out.println("Extraction completed");
+}
+ </source>
+ </section>
+
+ <section>
+ <title>Attachment attributes and contents</title>
+
+ <p>To get at your attachments, simply call the
+ <em>getAttachments()</em> method on a <em>HMEFMessage</em>
+ instance, and you'll receive a list of all the attachments.</p>
+ <p>When you have a <em>org.apache.poi.hmef.Attachment</em> object,
+ there are several helper methods available. These will all
+ return the value of the appropriate underlying attachment
+ attributes, or null if for some reason the attribute isn't
+ present in your file.</p>
+ <ul>
+ <li><em>getFilename()</em> - returns the name of the attachment
+ file, possibly in 8.3 format</li>
+ <li><em>getLongFilename()</em> - returns the full name of the
+ attachment file</li>
+ <li><em>getExtension()</em> - returns the extension of the
+ attachment file, including the "."</li>
+ <li><em>getModifiedDate()</em> - returns the date that the
+ attachment file was last edited on</li>
+ <li><em>getContents()</em> - returns a byte array of the contents
+ of the attached file</li>
+ <li><em>getRenderedMetaFile()</em> - returns a byte array of
+ a windows meta file representation of the attached file</li>
+ </ul>
+ </section>
+
+ <section>
+ <title>Message attributes and message body</title>
+
+ <p>A <em>org.apache.poi.hmef.HMEFMessage</em> instance is created
+ from an <em>InputStream</em> of the underlying TNEF (winmail.dat)
+ file.</p>
+ <p>From a <em>HMEFMessage</em>, there are three main methods of
+ interest to call:</p>
+ <ul>
+ <li><em>getBody()</em> - returns a String containing the RTF
+ contents of the message body. </li>
+ <li><em>getSubject()</em> - returns the message subject</li>
+ <li><em>getAttachments()</em> - returns the list of
+ <em>Attachment</em> objects for the message</li>
+ </ul>
+ </section>
+
+ <section>
+ <title>Low level attribute access</title>
+
+ <p>Both Messages and Attachments contain two kinds of attributes.
+ These are <em>TNEFAttribute</em> and <em>MAPIAttribute</em>.</p>
+ <p>TNEFAttribute is specific to TNEF files in terms of the
+ available types and properties. In general, Attachments have a
+ few more useful ones of these then Messages.</p>
+ <p>MAPIAttributes hold standard MAPI properties and values, and
+ work in a similar way to <link href="../hsmf/">HSMF
+ (Outlook)</link> does. There are typically many of these on both
+ Messages and Attachments. <em>Note - see limitations</em></p>
+ <p>Both <em>HMEFMessage</em> and <em>Attachment</em> supports
+ support two different ways of getting to attributes of interest.
+ Firstly, they support list getters, to return all attributes
+ (either TNEF or MAPI). Secondly, they support specific getters by
+ TNEF or MAPI property.</p>
+ <source>
+HMEFMessage msg = new HMEFMessage(new FileInputStream(file));
+for(TNEFAttribute attr : msg.getMessageAttributes) {
+ System.out.println("TNEF : " + attr);
+}
+for(MAPIAttribute attr : msg.getMessageMAPIAttributes) {
+ System.out.println("MAPI : " + attr);
+}
+System.out.println("Subject is " + msg.getMessageMAPIAttribute(MAPIProperty.CONVERSATION_TOPIC));
+
+for(Attachment attach : msg.getAttachments()) {
+ for(TNEFAttribute attr : attach.getAttributes) {
+ System.out.println("A.TNEF : " + attr);
+ }
+ for(MAPIAttribute attr : attach.getMAPIAttributes) {
+ System.out.println("A.MAPI : " + attr);
+ }
+ System.out.println("Filename is " + attach.getAttribute(TNEFProperty.CID_ATTACHTITLE));
+ System.out.println("Extension is " + attach.getMAPIAttribute(MAPIProperty.ATTACH_EXTENSION));
+}
+ </source>
+ </section>
+ </section>
+
+ <section>
+ <title>Investigating a TNEF file</title>
+
+ <p>To get a feel for the contents of a file, and to track down
+ where data of interest is stored, HMEF comes with
+ <link href="http://svn.apache.org/repos/asf/poi/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/">HMEFDumper</link>
+ to print out the contents of the file.</p>
+ </section>
+
+ <section>
+ <title>Limitations</title>
+
+ <p>HMEF is currently a work-in-progress, and not everything
+ works yet. The current limitations are:</p>
+ <ul>
+ <li>Non-standard MAPI properties from the range 0x8000 to 0x8fff
+ may not be being quite correctly turned into attributes.
+ The values show up, but the name and type may not always
+ be correct.</li>
+ <li>All testing so far has been performed on a small number of
+ English documents. We think we're correctly turning bytes into
+ Java unicode strings, but we need a few non-English sample
+ files in the test suite to verify this!</li>
+ </ul>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - How To Build</title>
+ <authors>
+ <person email="user@poi.apache.org" name="Glen Stampoultzis" id="GS"/>
+ <person email="tetsuya@apache.org" name="Tetsuya Kitahata" id="TK"/>
+ <person email="dfisher@jmlafferty.com" name="David Fisher" id="DF"/>
+ </authors>
+ </header>
+ <body>
+ <section>
+ <title>JDK Version</title>
+ <p>
+ POI 3.5 and later requires the JDK version 1.5 or later.
+ Versions prior to 3.5 require JDK 1.4+
+ </p>
+ </section>
+ <section>
+ <title>Install Apache Ant</title>
+ <p>
+ The POI build system requires <link href="http://ant.apache.org/bindownload.cgi">Apache Ant</link>
+ </p>
+ <p>
+ Specifically the build has been tested to work with Ant version
+ 1.7.1. To install the product download the distribution and follow the instructions.
+ </p>
+ <p>
+ Remember to set the ANT_HOME environment variable and add ANT_HOME/bin
+ to your shell's PATH.
+ </p>
+ </section>
+ <section>
+ <title>Install JUnit</title>
+ <p>
+ Running unit tests and building a distribution requires <link href="http://www.junit.org/">JUnit</link>.
+ </p>
+ <p>
+ Just pick the latest versions of the jars from
+ <link href="http://sourceforge.net/projects/junit/files/junit/">SourceForge</link> and place
+ them in ANT_HOME/lib. Make sure that optional.jar is in ANT_HOME/lib.
+ </p>
+ </section>
+ <section>
+ <title>Install Apache Forrest</title>
+ <p>
+ The POI build system requires <link href="http://forrest.apache.org/">Apache Forrest</link> to build the documentation.
+ </p>
+ <p>
+ Specifically the build has been tested to work with Forrest 0.5. This is an old release which is available
+ <link href="http://archive.apache.org/dist/forrest/pre-0.6/">here</link>.
+ </p>
+ <p>
+ Remember to set the FORREST_HOME environment variable.
+ </p>
+ </section>
+ <section>
+ <title>Building Targets with Ant</title>
+ <p>
+ The main targets of interest to our users are:
+ </p>
+ <table>
+ <tr>
+ <th>Ant Target</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>clean</td>
+ <td>Erase all build work products (ie. everything in the
+ build directory</td>
+ </tr>
+ <tr>
+ <td>compile</td>
+ <td>Compiles all files from main, ooxml and scratchpad</td>
+ </tr>
+ <tr>
+ <td>test</td>
+ <td>Run all unit tests from main, ooxml and scratchpad</td>
+ </tr>
+ <tr>
+ <td>jar</td>
+ <td>Produce jar files</td>
+ </tr>
+ <tr>
+ <td>assemble</td>
+ <td>Produce .zip and tar.gz distribution packages</td>
+ </tr>
+ <tr>
+ <td>docs</td>
+ <td>Generate all documentation (Requires Apache Forrest)</td>
+ </tr>
+ </table>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
+
+
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="HPBF"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="HPBF">
+ <menu-item label="Overview" href="index.html"/>
+ <menu-item label="File Format" href="file-format.xml"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HPBF - A Guide to the Publisher File Format</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick at torchbox dot com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Document Streams</title>
+ <p>
+ The file is made up of a number of POIFS streams. A typical
+ file will be made up as follows:
+ </p>
+<source>
+Root Entry -
+ Objects -
+ (no children)
+ SummaryInformation <(0x05)SummaryInformation>
+ DocumentSummaryInformation <(0x05)DocumentSummaryInformation>
+ Escher -
+ EscherStm
+ EscherDelayStm
+ Quill -
+ QuillSub -
+ CONTENTS
+ CompObj <(0x01)CompObj>
+ Envelope
+ Contents
+ Internal <(0x03)Internal>
+ CompObj <(0x01)CompObj>
+ VBA -
+ (no children)
+</source>
+ </section>
+ <section><title>Changing Text</title>
+ <p>If you make a change to the text of a file, but not change
+ how much text there is, then the <em>CONTENTS</em> stream
+ will undergo a small change, and the <em>Contents</em> stream
+ will undergo a large change.</p>
+ <p>If you make a change to the text of a file, and change the
+ amount of text there is, then both the <em>Contents</em> and
+ the <em>CONTENTS</em> streams change.</p>
+ </section>
+ <section><title>Changing Shapes</title>
+ <p>If you alter the size of a textbox, but make no text changes,
+ then both <em>Contents</em> and <em>CONTENTS</em> streams
+ change. There are no changes to the Escher streams.</p>
+ <p>If you set the background colour of a textbox, but make
+ no changes to the text, (to finish off)</p>
+ </section>
+ <section><title>Structure of CONTENTS</title>
+ <p>First we have "CHNKINK ", followed by 24 bytes.</p>
+ <p>Next we have 20 sequences of 24 bytes each. If the first two bytes
+ at 0x1800, then that sequence entry exists, but if it's 0x0000 then
+ the entry doesn't exist. If it does exist, we then have 4 bytes of
+ upper case ASCII text, followed by three little endian shorts.
+ The first of these seems to be the count of that type, the second is
+ usually 1, the third is usually zero. The we have another 4 bytes of
+ upper case ASCII text, normally but not always the same as the first
+ text. Finally, we have an unsigned little endian 32 bit offset to
+ the start of the data for this, then an unsigned little endian
+ 32 bit offset of the length of this section.</p>
+ <p>Normally, the first sequence entry is for TEXT, and the text data
+ will start at 0x200. After that is normally two or three STSH entries
+ (so the first short has values 0, then 1, then 2). After that it
+ seems to vary.</p>
+ <p>At 0x200 we have the text, stored as little endian 16 bit unicode.</p>
+ <p>After the text comes all sorts of other stuff, presumably as
+ described by the sequences.</p>
+ <p>For a contents stream of length 7168 / 0x1c00 bytes, the start
+ looks something like:</p>
+<source>
+CHNKINK // "CHNKINK "
+04 00 07 00 // Normally 04 00 07 00
+13 00 00 03 // Normally ## 00 00 03
+00 02 00 00 // Normally 00 ## 00 00
+00 1c 00 00 // Normally length of the stream
+f8 01 13 00 // Normally f8 01 11/13 00
+ff ff ff ff // Normally seems to be ffffffff
+
+18 00
+TEXT 00 00 01 00 00 00 // TEXT 0 1 0
+TEXT 00 02 00 00 d0 03 00 00 // TEXT from: 200 (512), len: 3d0 (976)
+18 00
+STSH 00 00 01 00 00 00 // STSH 0 1 0
+STSH d0 05 00 00 1e 00 00 00 // STSH from: 5d0 (1488), len: 1e (30)
+18 00
+STSH 01 00 01 00 00 00 // STSH 1 1 0
+STSH ee 05 00 00 b8 01 00 00 // STSH from: 5ee (1518), len: 1b8 (440)
+18 00
+STSH 02 00 01 00 00 00 // STSH 2 1 0
+STSH a6 07 00 00 3c 00 00 00 // STSH from: 7a6 (1958), len: 3c (60)
+18 00
+FDPP 00 00 01 00 00 00 // FDPP 0 1 0
+FDPP 00 08 00 00 00 02 00 00 // FDPP from: 800 (2048), len: 200 (512)
+18 00
+FDPC 00 00 01 00 00 00 // FDPC 0 1 0
+FDPC 00 0a 00 00 00 02 00 00 // FDPC from: a00 (2560), len: 200 (512)
+18 00
+FDPC 01 00 01 00 00 00 // FDPC 1 1 0
+FDPC 00 0c 00 00 00 02 00 00 // FDPC from: c00 (3072), len: 200 (512)
+18 00
+SYID 00 00 01 00 00 00 // SYID 0 1 0
+SYID 00 0e 00 00 20 00 00 00 // SYID from: e00 (3584), len: 20 (32)
+18 00
+SGP 00 00 01 00 00 00 // SGP 0 1 0
+SGP 20 0e 00 00 0a 00 00 00 // SGP from: e20 (3616), len: a (10)
+18 00
+INK 00 00 01 00 00 00 // INK 0 1 0
+INK 2a 0e 00 00 04 00 00 00 // INK from: e2a (3626), len: 4 (4)
+18 00
+BTEP 00 00 01 00 00 00 // BTEP 0 1 0
+PLC 2e 0e 00 00 18 00 00 00 // PLC from: e2e (3630), len: 18 (24)
+18 00
+BTEC 00 00 01 00 00 00 // BTEC 0 1 0
+PLC 46 0e 00 00 20 00 00 00 // PLC from: e46 (3654), len: 20 (32)
+18 00
+FONT 00 00 01 00 00 00 // FONT 0 1 0
+FONT 66 0e 00 00 48 03 00 00 // FONT from: e66 (3686), len: 348 (840)
+18 00
+TCD 03 00 01 00 00 00 // TCD 3 1 0
+PLC ae 11 00 00 24 00 00 00 // PLC from: 11ae (4526), len: 24 (36)
+18 00
+TOKN 04 00 01 00 00 00 // TOKN 4 1 0
+PLC d2 11 00 00 0a 01 00 00 // PLC from: 11d2 (4562), len: 10a (266)
+18 00
+TOKN 05 00 01 00 00 00 // TOKN 5 1 0
+PLC dc 12 00 00 2a 01 00 00 // PLC from: 12dc (4828), len: 12a (298)
+18 00
+STRS 00 00 01 00 00 00 // STRS 0 1 0
+PLC 06 14 00 00 46 00 00 00 // PLC from: 1406 (5126), len: 46 (70)
+18 00
+MCLD 00 00 01 00 00 00 // MCLD 0 1 0
+MCLD 4c 14 00 00 16 06 00 00 // MCLD from: 144c (5196), len: 616 (1558)
+18 00
+PL 00 00 01 00 00 00 // PL 0 1 0
+PL 62 1a 00 00 48 00 00 00 // PL from: 1a62 (6754), len: 48 (72)
+00 00 // Blank entry follows
+00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00
+
+(the text will then start)
+</source>
+ <p>We think that the first 4 bytes of text describes the
+ the function of the data at the offset. The first short is
+ then the count of that type, eg the 2nd will have 1. We
+ think that the second 4 bytes of text describes the format
+ of data block at the offset. The format of the text block
+ is easy, but we're still trying to figure out the others.</p>
+
+ <section><title>Structure of TEXT bit</title>
+ <p>This is very simple. All the text for the document is
+ stored in a single bit of the Quill CONTENTS. The text
+ is stored as little endian 16 bit unicode strings.</p>
+ </section>
+ <section><title>Structure of PLC bit</title>
+ <p>The first four bytes seem to hold the count of the
+ entries in the bit, and the second four bytes seem to hold
+ the type. There is then some pre-data, and then data for
+ each of the entries, the exact format dependant on the type.</p>
+ <p>Type 0 has 4 2 byte unsigned ints, then a pair of 2 byte
+ unsigned ints for each entry.</p>
+ <p>Type 4 has 4 2 byte unsigned ints, then a pair of 4 byte
+ unsigned ints for each entry.</p>
+ <p>Type 8 has 7 2 byte unsigned ints, then a pair of 4 byte
+ unsigned ints for each entry.</p>
+ <p>Type 12 holds hyperlinks, and is very much more complex.
+ See <code>org.apache.poi.hpbf.model.qcbits.QCPLCBit</code>
+ for our best guess as to how the contents match up.</p>
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HPBF - Java API To Access Microsoft Publisher Format Files</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick at apache dot org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section>
+ <title>Overview</title>
+
+ <p>HPBF is the POI Project's pure Java implementation of the
+ Publisher file format.</p>
+ <p>Currently, HPBF is in an early stage, whilst we try to
+ figure out the file format. So far, we have basic text
+ extraction support, and are able to read some parts within
+ the file. Writing is not yet supported, as we are unable
+ to make sense of the Contents stream, which we think has
+ lots of offsets to other parts of the file.</p>
+ <p>Our initial aim is to provude a text extractor for the format
+ (now done), and be able to extract hyperlinks from within
+ the document (partly supported). Additional low level
+ code to process the file format may follow, if there
+ is demand and developer interest warrant it.</p>
+ <p>Text Extraction is available via the
+ <em>org.apache.poi.hpbf.extractor.PublisherTextExtractor</em>
+ class.</p>
+ <p>At this time, there is no <em>usermodel</em> api or similar.
+ There is only low level support for certain parts of
+ the file, but by no means all of it.</p>
+ <p>Our current understanding of the file format is documented
+ <link href="file-format.html">here</link>.</p>
+ <note>
+ This code currently lives the
+ <link href="http://svn.apache.org/viewcvs.cgi/poi/trunk/src/scratchpad/">scratchpad area</link>
+ of the POI SVN repository.
+ Ensure that you have the scratchpad jar or the scratchpad
+ build area in your
+ classpath before experimenting with this code.
+ </note>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+<book software="POI Project"
+ title="HPSF"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+ <menu label="HPSF">
+ <menu-item label="Overview" href="index.html"/>
+ <menu-item label="How To" href="how-to.html"/>
+ <menu-item label="Thumbnails" href="thumbnails.html"/>
+ <menu-item label="Internals" href="internals.html"/>
+ <menu-item label="To Do" href="todo.html"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
+"../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>HPSF HOW-TO</title>
+ <authors>
+ <person name="Rainer Klute" email="klute@apache.org"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>How To Use the HPSF API</title>
+
+ <p>This HOW-TO is organized in four sections. You should read them
+ sequentially because the later sections build upon the earlier ones.</p>
+
+ <ol>
+ <li>
+ The <link href="#sec1">first section</link> explains how to <strong>read
+ the most important standard properties</strong> of a Microsoft Office
+ document. Standard properties are things like title, author, creation
+ date etc. It is quite likely that you will find here what you need and
+ don't have to read the other sections.
+ </li>
+
+ <li>
+ The <link href="#sec2">second section</link> goes a small step
+ further and focusses on <strong>reading additional standard
+ properties</strong>. It also talks about <strong>exceptions</strong> that
+ may be thrown when dealing with HPSF and shows how you can <strong>read
+ properties of embedded objects</strong>.
+ </li>
+
+ <li>
+ The <link href="#sec3">third section</link> explains how to <strong>write
+ standard properties</strong>. HPSF provides some high-level classes and
+ methods which make writing of standard properties easy. They are based on
+ the low-level writing functions explained in the <link href="#sec3">fifth
+ section</link>.
+ </li>
+
+ <li>
+ The <link href="#sec4">fourth section</link> tells how to <strong>read
+ non-standard properties</strong>. Non-standard properties are
+ application-specific triples consisting of an ID, a type, and a value.
+ </li>
+
+ <li>
+ The <link href="#sec5">fifth section</link> tells you how to <strong>write
+ property set streams</strong> using HPSF's low-level methods. You have to
+ understand the <link href="#sec3">fourth section</link> before you should
+ think about low-level writing properties. Check the Javadoc API
+ documentation to find out about the details!
+ </li>
+ </ol>
+
+ <note><strong>Please note:</strong> HPSF's writing functionality is
+ <strong>not</strong> present in POI releases up to and including 2.5. In
+ order to write properties you have to download a 3.0.x POI release,
+ or retrieve the POI development version from the <link
+ href="../subversion.html">Subversion repository</link>.</note>
+
+
+
+ <anchor id="sec1"/>
+ <section><title>Reading Standard Properties</title>
+
+ <note>This section explains how to read the most important standard
+ properties of a Microsoft Office document. Standard properties are things
+ like title, author, creation date etc. This section introduces the
+ <strong>summary information stream</strong> which is used to keep these
+ properties. Chances are that you will find here what you need and don't
+ have to read the other sections.</note>
+
+ <p>If all you are interested in is getting the textual content of
+ all the document properties, such as for full text indexing, then
+ take a look at
+ <code>org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor</code>. However,
+ if you want full access to the properties, please read on!</p>
+
+ <p>The first thing you should understand is that a Microsoft Office file is
+ not one large bunch of bytes but has an internal filesystem structure with
+ files and directories. You can access these files and directories using
+ the <link href="../poifs/index.html">POI filesystem (POIFS)</link>
+ provides. A file or document in a POI filesystem is also called a
+ <strong>stream</strong> - The properties of, say, an Excel document are
+ stored apart of the actual spreadsheet data in separate streams. The good
+ new is that this separation makes the properties independent of the
+ concrete Microsoft Office file. In the following text we will always say
+ "POI filesystem" instead of "Microsoft Office file" because a POI
+ filesystem is not necessarily created by or for a Microsoft Office
+ application, because it is shorter, and because we want to avoid the name
+ of That Redmond Company.</p>
+
+ <p>The following example shows how to read the "title" property. Reading
+ other properties is similar. Consider the API documentation of the class
+ <code>org.apache.poi.hpsf.SummaryInformation</code> to learn which methods
+ are available.</p>
+
+ <p>The standard properties this section focusses on can be found in a
+ document called <em>\005SummaryInformation</em> located in the root of the
+ POI filesystem. The notation <em>\005</em> in the document's name means
+ the character with a decimal value of 5. In order to read the "title"
+ property, an application has to perform the following steps:</p>
+
+ <ol>
+ <li>
+ Open the document <em>\005SummaryInformation</em> located in the root
+ of the POI filesystem.
+ </li>
+ <li>
+ Create an instance of the class <code>SummaryInformation</code> from
+ that document.
+ </li>
+ <li>
+ Call the <code>SummaryInformation</code> instance's
+ <code>getTitle()</code> method.
+ </li>
+ </ol>
+
+ <p>Sounds easy, doesn't it? Here are the steps in detail.</p>
+
+
+ <section><title>Open the document \005SummaryInformation in the root of the
+ POI filesystem</title>
+
+ <p>An application that wants to open a document in a POI filesystem
+ (POIFS) proceeds as shown by the following code fragment. The full
+ source code of the sample application is available in the
+ <em>examples</em> section of the POI source tree as
+ <em>ReadTitle.java</em>.</p>
+
+ <source>
+import java.io.*;
+import org.apache.poi.hpsf.*;
+import org.apache.poi.poifs.eventfilesystem.*;
+
+// ...
+
+public static void main(String[] args)
+ throws IOException
+{
+ final String filename = args[0];
+ POIFSReader r = new POIFSReader();
+ r.registerListener(new MyPOIFSReaderListener(),
+ "\005SummaryInformation");
+ r.read(new FileInputStream(filename));
+}</source>
+
+ <p>The first interesting statement is</p>
+
+ <source>POIFSReader r = new POIFSReader();</source>
+
+ <p>It creates a
+ <code>org.apache.poi.poifs.eventfilesystem.POIFSReader</code> instance
+ which we shall need to read the POI filesystem. Before the application
+ actually opens the POI filesystem we have to tell the
+ <code>POIFSReader</code> which documents we are interested in. In this
+ case the application should do something with the document
+ <em>\005SummaryInformation</em>.</p>
+
+ <source>
+r.registerListener(new MyPOIFSReaderListener(),
+ "\005SummaryInformation");</source>
+
+ <p>This method call registers a
+ <code>org.apache.poi.poifs.eventfilesystem.POIFSReaderListener</code>
+ with the <code>POIFSReader</code>. The <code>POIFSReaderListener</code>
+ interface specifies the method <code>processPOIFSReaderEvent()</code>
+ which processes a document. The class
+ <code>MyPOIFSReaderListener</code> implements the
+ <code>POIFSReaderListener</code> and thus the
+ <code>processPOIFSReaderEvent()</code> method. The eventing POI
+ filesystem calls this method when it finds the
+ <em>\005SummaryInformation</em> document. In the sample application
+ <code>MyPOIFSReaderListener</code> is a static class in the
+ <em>ReadTitle.java</em> source file.</p>
+
+ <p>Now everything is prepared and reading the POI filesystem can
+ start:</p>
+
+ <source>r.read(new FileInputStream(filename));</source>
+
+ <p>The following source code fragment shows the
+ <code>MyPOIFSReaderListener</code> class and how it retrieves the
+ title.</p>
+
+ <source>
+static class MyPOIFSReaderListener implements POIFSReaderListener
+{
+ public void processPOIFSReaderEvent(POIFSReaderEvent event)
+ {
+ SummaryInformation si = null;
+ try
+ {
+ si = (SummaryInformation)
+ PropertySetFactory.create(event.getStream());
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException
+ ("Property set stream \"" +
+ event.getPath() + event.getName() + "\": " + ex);
+ }
+ final String title = si.getTitle();
+ if (title != null)
+ System.out.println("Title: \"" + title + "\"");
+ else
+ System.out.println("Document has no title.");
+ }
+}
+</source>
+
+ <p>The line</p>
+
+ <source>SummaryInformation si = null;</source>
+
+ <p>declares a <code>SummaryInformation</code> variable and initializes it
+ with <code>null</code>. We need an instance of this class to access the
+ title. The instance is created in a <code>try</code> block:</p>
+
+ <source>si = (SummaryInformation)
+ PropertySetFactory.create(event.getStream());</source>
+
+ <p>The expression <code>event.getStream()</code> returns the input stream
+ containing the bytes of the property set stream named
+ <em>\005SummaryInformation</em>. This stream is passed into the
+ <code>create</code> method of the factory class
+ <code>org.apache.poi.hpsf.PropertySetFactory</code> which returns
+ a <code>org.apache.poi.hpsf.PropertySet</code> instance. It is more or
+ less safe to cast this result to <code>SummaryInformation</code>, a
+ convenience class with methods like <code>getTitle()</code>,
+ <code>getAuthor()</code> etc.</p>
+
+ <p>The <code>PropertySetFactory.create()</code> method may throw all sorts
+ of exceptions. We'll deal with them in the next sections. For now we just
+ catch all exceptions and throw a <code>RuntimeException</code>
+ containing the message text of the origin exception.</p>
+
+ <p>If all goes well, the sample application retrieves the title and prints
+ it to the standard output. As you can see you must be prepared for the
+ case that the POI filesystem does not have a title.</p>
+
+ <source>final String title = si.getTitle();
+if (title != null)
+ System.out.println("Title: \"" + title + "\"");
+else
+ System.out.println("Document has no title.");</source>
+
+ <p>Please note that a POI filesystem does not necessarily contain the
+ <em>\005SummaryInformation</em> stream. The documents created by the
+ Microsoft Office suite have one, as far as I know. However, an Excel
+ spreadsheet exported from StarOffice 5.2 won't have a
+ <em>\005SummaryInformation</em> stream. In this case the applications
+ won't throw an exception but simply does not call the
+ <code>processPOIFSReaderEvent</code> method. You have been warned!</p>
+ </section>
+ </section>
+
+ <anchor id="sec2"/>
+ <section><title>Additional Standard Properties, Exceptions And Embedded
+ Objects</title>
+
+ <note>This section focusses on reading additional standard properties which
+ are kept in the <strong>document summary information</strong> stream. It
+ also talks about exceptions that may be thrown when dealing with HPSF and
+ shows how you can read properties of embedded objects.</note>
+
+ <p>A couple of <strong>additional standard properties</strong> are not
+ contained in the <em>\005SummaryInformation</em> stream explained
+ above. Examples for such properties are a document's category or the
+ number of multimedia clips in a PowerPoint presentation. Microsoft has
+ invented an additional stream named
+ <em>\005DocumentSummaryInformation</em> to hold these properties. With two
+ minor exceptions you can proceed exactly as described above to read the
+ properties stored in <em>\005DocumentSummaryInformation</em>:</p>
+
+ <ul>
+ <li>Instead of <em>\005SummaryInformation</em> use
+ <em>\005DocumentSummaryInformation</em> as the stream's name.</li>
+ <li>Replace all occurrences of the class
+ <code>SummaryInformation</code> by
+ <code>DocumentSummaryInformation</code>.</li>
+ </ul>
+
+ <p>And of course you cannot call <code>getTitle()</code> because
+ <code>DocumentSummaryInformation</code> has different query methods,
+ e.g. <code>getCategory</code>. See the Javadoc API documentation for the
+ details.</p>
+
+ <p>In the previous section the application simply caught all
+ <strong>exceptions</strong> and was in no way interested in any
+ details. However, a real application will likely want to know what went
+ wrong and act appropriately. Besides any I/O exceptions there are three
+ HPSF resp. POI specific exceptions you should know about:</p>
+
+ <dl>
+ <dt><code>NoPropertySetStreamException</code>:</dt>
+ <dd>
+ This exception is thrown if the application tries to create a
+ <code>PropertySet</code> instance from a stream that is not a
+ property set stream. (<code>SummaryInformation</code> and
+ <code>DocumentSummaryInformation</code> are subclasses of
+ <code>PropertySet</code>.) A faulty property set stream counts as not
+ being a property set stream at all. An application should be prepared to
+ deal with this case even if it opens streams named
+ <em>\005SummaryInformation</em> or
+ <em>\005DocumentSummaryInformation</em>. These are just names. A
+ stream's name by itself does not ensure that the stream contains the
+ expected contents and that this contents is correct.
+ </dd>
+
+ <dt><code>UnexpectedPropertySetTypeException</code></dt>
+ <dd>This exception is thrown if a certain type of property set is
+ expected somewhere (e.g. a <code>SummaryInformation</code> or
+ <code>DocumentSummaryInformation</code>) but the provided property
+ set is not of that type.</dd>
+
+ <dt><code>MarkUnsupportedException</code></dt>
+ <dd>This exception is thrown if an input stream that is to be parsed
+ into a property set does not support the
+ <code>InputStream.mark(int)</code> operation. The POI filesystem uses
+ the <code>DocumentInputStream</code> class which does support this
+ operation, so you are safe here. However, if you read a property set
+ stream from another kind of input stream things may be
+ different.</dd>
+ </dl>
+
+ <p>Many Microsoft Office documents contain <strong>embedded
+ objects</strong>, for example an Excel sheet within a Word
+ document. Embedded objects may have property sets of their own. An
+ application can open these property set streams as described above. The
+ only difference is that they are not located in the POI filesystem's root
+ but in a <strong>nested directory</strong> instead. Just register a
+ <code>POIFSReaderListener</code> for the property set streams you are
+ interested in. For example, the <em>POIBrowser</em> application
+ tries to open each and every document in a POI filesystem
+ as a property set stream. If this operation was successful it displays the
+ properties.</p>
+ </section>
+
+
+
+ <anchor id="sec3"/>
+ <section><title>Writing Standard Properties</title>
+
+ <note>This section explains how to <strong>write standard
+ properties</strong>. HPSF provides some high-level classes and methods
+ which make writing of standard properties easy. They are based on the
+ low-level writing functions explained in <link href="#sec4">another
+ section</link>.</note>
+
+ <p>As explained above, standard properties are located in the summary
+ information and document summary information streams of typical POI
+ filesystems. You have already learned about the classes
+ <code>SummaryInformation</code> and
+ <code>DocumentSummaryInformation</code> and their <code>get...()</code>
+ methods for reading standard properties. These classes also provide
+ <code>set...()</code> methods for writing properties.</p>
+
+ <p>After setting properties in <code>SummaryInformation</code> or
+ <code>DocumentSummaryInformation</code> you have to write them to a disk
+ file. The following sample program shows how you can</p>
+
+ <ol>
+ <li>read a disk file into a POI filesystem,</li>
+ <li>read the document summary information from the POI filesystem,</li>
+ <li>set a property to a new value,</li>
+ <li>write the modified document summary information back to the POI
+ filesystem, and</li>
+ <li>write the POI filesystem to a disk file.</li>
+ </ol>
+
+ <p>The complete source code of this program is available as
+ <em>ModifyDocumentSummaryInformation.java</em> in the <em>examples</em>
+ section of the POI source tree.</p>
+
+ <note>Dealing with the summary information stream is analogous to handling
+ the document summary information and therefore does not need to be
+ explained here in detailed. See the HPSF API documentation to learn about
+ the <code>set...()</code> methods of the class
+ <code>SummaryInformation</code>.</note>
+
+ <p>The first step is to read the POI filesystem into memory:</p>
+
+ <source>InputStream is = new FileInputStream(poiFilesystem);
+POIFSFileSystem poifs = new POIFSFileSystem(is);
+is.close();</source>
+
+ <p>The code snippet above assumes that the variable
+ <code>poiFilesystem</code> holds the name of a disk file. It reads the
+ file from an input stream and creates a <code>POIFSFileSystem</code>
+ object in memory. After having read the file, the input stream should be
+ closed as shown.</p>
+
+ <p>In order to read the document summary information stream the application
+ must open the element <em>\005DocumentSummaryInformation</em> in the POI
+ filesystem's root directory. However, the POI filesystem does not
+ necessarily contain a document summary information stream, and the
+ application should be able to deal with that situation. The following
+ code does so by creating a new <code>DocumentSummaryInformation</code> if
+ there is none in the POI filesystem:</p>
+
+ <source>DirectoryEntry dir = poifs.getRoot();
+DocumentSummaryInformation dsi;
+try
+{
+ DocumentEntry dsiEntry = (DocumentEntry)
+ dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
+ DocumentInputStream dis = new DocumentInputStream(dsiEntry);
+ PropertySet ps = new PropertySet(dis);
+ dis.close();
+ dsi = new DocumentSummaryInformation(ps);
+}
+catch (FileNotFoundException ex)
+{
+ /* There is no document summary information. We have to create a
+ * new one. */
+ dsi = PropertySetFactory.newDocumentSummaryInformation();
+}
+ </source>
+
+ <p>In the source code above the statement</p>
+
+ <source>DirectoryEntry dir = poifs.getRoot();</source>
+
+ <p>gets hold of the POI filesystem's root directory as a
+ <code>DirectoryEntry</code>. The <code>getEntry()</code> method of this
+ class is used to access a file or directory entry in a directory. However,
+ if the file to be opened does not exist, a
+ <code>FileNotFoundException</code> will be thrown. Therefore opening the
+ document summary information entry should be done in a <code>try</code>
+ block:</p>
+
+ <source> DocumentEntry dsiEntry = (DocumentEntry)
+ dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);</source>
+
+ <p><code>DocumentSummaryInformation.DEFAULT_STREAM_NAME</code> represents
+ the string "\005DocumentSummaryInformation", i.e. the standard name of a
+ document summary information stream. If this stream exists, the
+ <code>getEntry()</code> method returns a <code>DocumentEntry</code>. To
+ read the <code>DocumentEntry</code>'s contents, create a
+ <code>DocumentInputStream</code>:</p>
+
+ <source> DocumentInputStream dis = new DocumentInputStream(dsiEntry);</source>
+
+ <p>Up to this point we have used POI's <link
+ href="../poifs/index.html">POIFS component</link>. Now HPSF enters the
+ stage. A property set is created from the input stream's data:</p>
+
+ <source> PropertySet ps = new PropertySet(dis);
+ dis.close();
+ dsi = new DocumentSummaryInformation(ps); </source>
+
+ <p>If the data really constitutes a property set, a
+ <code>PropertySet</code> object is created. Otherwise a
+ <code>NoPropertySetStreamException</code> is thrown. After having read the
+ data from the input stream the latter should be closed.</p>
+
+ <p>Since we know - or at least hope - that the stream named
+ "\005DocumentSummaryInformation" is not just any property set but really
+ contains the document summary information, we try to create a new
+ <code>DocumentSummaryInformation</code> from the property set. If the
+ stream is not document summary information stream the sample application
+ fails with a <code>UnexpectedPropertySetTypeException</code>.</p>
+
+ <p>If the POI document does not contain a document summary information
+ stream, we can create a new one in the <code>catch</code> clause. The
+ <code>PropertySetFactory</code>'s method
+ <code>newDocumentSummaryInformation()</code> establishes a new and empty
+ <code>DocumentSummaryInformation</code> instance:</p>
+
+ <source> dsi = PropertySetFactory.newDocumentSummaryInformation();</source>
+
+ <p>Whether we read the document summary information from the POI filesystem
+ or created it from scratch, in either case we now have a
+ <code>DocumentSummaryInformation</code> instance we can write to. Writing
+ is quite simple, as the following line of code shows:</p>
+
+ <source>dsi.setCategory("POI example");</source>
+
+ <p>This statement sets the "category" property to "POI example". Any
+ former "category" value will be lost. If there hasn't been a "category"
+ property yet, a new one will be created.</p>
+
+ <p><code>DocumentSummaryInformation</code> of course has methods to set the
+ other standard properties, too - look into the API documentation to see
+ all of them.</p>
+
+ <p>Once all properties are set as needed, they should be stored into the
+ file on disk. The first step is to write the
+ <code>DocumentSummaryInformation</code> into the POI filesystem:</p>
+
+ <source>dsi.write(dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME);</source>
+
+ <p>The <code>DocumentSummaryInformation</code>'s <code>write()</code>
+ method takes two parameters: The first is the <code>DirectoryEntry</code>
+ in the POI filesystem, the second is the name of the stream to create in
+ the directory. If this stream already exists, it will be overwritten.</p>
+
+ <note>If you not only modified the document summary information but also
+ the summary information you have to write both of them to the POI
+ filesystem.</note>
+
+ <p>Still the POI filesystem is a data structure in memory only and must be
+ written to a disk file to make it permanent. The following lines write
+ back the POI filesystem to the file it was read from before. Please note
+ that in production-quality code you should never write directly to the
+ origin file, because in case of an error everything would be lost. Here it
+ is done this way to keep the example short.</p>
+
+ <source>OutputStream out = new FileOutputStream(poiFilesystem);
+poifs.writeFilesystem(out);
+out.close();</source>
+
+ <section><title>User-Defined Properties</title>
+
+ <p>If you compare the source code excerpts above with the file containing
+ the full source code, you will notice that I left out some following
+ lines of code. The are dealing with the special topic of custom
+ properties.</p>
+
+ <source>DocumentSummaryInformation dsi = ...
+...
+CustomProperties customProperties = dsi.getCustomProperties();
+if (customProperties == null)
+ customProperties = new CustomProperties();
+
+/* Insert some custom properties into the container. */
+customProperties.put("Key 1", "Value 1");
+customProperties.put("Schlüssel 2", "Wert 2");
+customProperties.put("Sample Number", new Integer(12345));
+customProperties.put("Sample Boolean", new Boolean(true));
+customProperties.put("Sample Date", new Date());
+
+/* Read a custom property. */
+Object value = customProperties.get("Sample Number");
+
+/* Write the custom properties back to the document summary
+ * information. */
+dsi.setCustomProperties(customProperties);</source>
+
+ <p>Custom properties are properties the user can define himself. Using for
+ example Microsoft Word he can define these extra properties and give
+ each of them a <strong>name</strong>, a <strong>type</strong> and a
+ <strong>value</strong>. The custom properties are stored in the document
+ information summary along with the standard properties.</p>
+
+ <p>The source code example shows how to retrieve the custom properties
+ as a whole from a <code>DocumentSummaryInformation</code> instance using
+ the <code>getCustomProperties()</code> method. The result is a
+ <code>CustomProperties</code> instance or <code>null</code> if no
+ user-defined properties exist.</p>
+
+ <p>Since <code>CustomProperties</code> implements the <code>Map</code>
+ interface you can read and write properties with the usual
+ <code>Map</code> methods. However, <code>CustomProperties</code> poses
+ some restrictions on the types of keys and values.</p>
+
+ <ul>
+ <li>The <strong>key</strong> is a string.</li>
+ <li>The <strong>value</strong> is one of <code>String</code>,
+ <code>Boolean</code>, <code>Long</code>, <code>Integer</code>,
+ <code>Short</code>, or <code>java.util.Date</code>.</li>
+ </ul>
+
+ <p>The <code>CustomProperties</code> class has been designed for easy
+ access using just keys and values. The underlying Microsoft-specific
+ custom properties data structure is more complicated. However, it does
+ not provide noteworthy additional benefits. It is possible to have
+ multiple properties with the same name or properties without a
+ name at all. When reading custom properties from a document summary
+ information stream, the <code>CustomProperties</code> class ignores
+ properties without a name and keeps only the "last" (whatever that means)
+ of those properties having the same name. You can find out whether a
+ <code>CustomProperties</code> instance dropped any properties with the
+ <code>isPure()</code> method.</p>
+
+ <p>You can read and write the full spectrum of custom properties with
+ HPSF's low-level methods. They are explained in the <link
+ href="#sec4">next section</link>.</p>
+ </section>
+ </section>
+
+
+
+ <anchor id="sec4"/>
+ <section><title>Reading Non-Standard Properties</title>
+
+ <note>This section tells how to read non-standard properties. Non-standard
+ properties are application-specific ID/type/value triples.</note>
+
+ <section><title>Overview</title>
+ <p>Now comes the real hardcode stuff. As mentioned above,
+ <code>SummaryInformation</code> and
+ <code>DocumentSummaryInformation</code> are just special cases of the
+ general concept of a property set. This concept says that a
+ <strong>property set</strong> consists of properties and that each
+ <strong>property</strong> is an entity with an <strong>ID</strong>, a
+ <strong>type</strong>, and a <strong>value</strong>.</p>
+
+ <p>Okay, that was still rather easy. However, to make things more
+ complicated, Microsoft in its infinite wisdom decided that a property set
+ shalt be broken into one or more <strong>sections</strong>. Each section
+ holds a bunch of properties. But since that's still not complicated
+ enough, a section may have an optional <strong>dictionary</strong> that
+ maps property IDs to <strong>property names</strong> - we'll explain
+ later what that means.</p>
+
+ <p>The procedure to get to the properties is the following:</p>
+
+ <ol>
+ <li>Use the <strong><code>PropertySetFactory</code></strong> class to
+ create a <code>PropertySet</code> object from a property set stream. If
+ you don't know whether an input stream is a property set stream, just
+ try to call <code>PropertySetFactory.create(java.io.InputStream)</code>:
+ You'll either get a <code>PropertySet</code> instance returned or an
+ exception is thrown.</li>
+
+ <li>Call the <code>PropertySet</code>'s method <code>getSections()</code>
+ to get the sections contained in the property set. Each section is
+ an instance of the <code>Section</code> class.</li>
+
+ <li>Each section has a format ID. The format ID of the first section in a
+ property set determines the property set's type. For example, the first
+ (and only) section of the summary information property set has a format
+ ID of <code>F29F85E0-4FF9-1068-AB-91-08-00-2B-27-B3-D9</code>. You can
+ get the format ID with <code>Section.getFormatID()</code>.</li>
+
+ <li>The properties contained in a <code>Section</code> can be retrieved
+ with <code>Section.getProperties()</code>. The result is an array of
+ <code>Property</code> instances.</li>
+
+ <li>A property has a name, a type, and a value. The <code>Property</code>
+ class has methods to retrieve them.</li>
+ </ol>
+ </section>
+
+ <section><title>A Sample Application</title>
+ <p>Let's have a look at a sample Java application that dumps all property
+ set streams contained in a POI file system. The full source code of this
+ program can be found as <em>ReadCustomPropertySets.java</em> in the
+ <em>examples</em> area of the POI source code tree. Here are the key
+ sections:</p>
+
+ <source>import java.io.*;
+import java.util.*;
+import org.apache.poi.hpsf.*;
+import org.apache.poi.poifs.eventfilesystem.*;
+import org.apache.poi.util.HexDump;</source>
+
+ <p>The most important package the application needs is
+ <code>org.apache.poi.hpsf.*</code>. This package contains the HPSF
+ classes. Most classes named below are from the HPSF package. Of course we
+ also need the POIFS event file system's classes and <code>java.io.*</code>
+ since we are dealing with POI I/O. From the <code>java.util</code> package
+ we use the <code>List</code> and <code>Iterator</code> class. The class
+ <code>org.apache.poi.util.HexDump</code> provides a methods to dump byte
+ arrays as nicely formatted strings.</p>
+
+ <source>public static void main(String[] args)
+ throws IOException
+{
+ final String filename = args[0];
+ POIFSReader r = new POIFSReader();
+
+ /* Register a listener for *all* documents. */
+ r.registerListener(new MyPOIFSReaderListener());
+ r.read(new FileInputStream(filename));
+}</source>
+
+ <p>The <code>POIFSReader</code> is set up in a way that the listener
+ <code>MyPOIFSReaderListener</code> is called on every file in the POI file
+ system.</p>
+ </section>
+
+ <section><title>The Property Set</title>
+ <p>The listener class tries to create a <code>PropertySet</code> from each
+ stream using the <code>PropertySetFactory.create()</code> method:</p>
+
+ <source>static class MyPOIFSReaderListener implements POIFSReaderListener
+{
+ public void processPOIFSReaderEvent(POIFSReaderEvent event)
+ {
+ PropertySet ps = null;
+ try
+ {
+ ps = PropertySetFactory.create(event.getStream());
+ }
+ catch (NoPropertySetStreamException ex)
+ {
+ out("No property set stream: \"" + event.getPath() +
+ event.getName() + "\"");
+ return;
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException
+ ("Property set stream \"" +
+ event.getPath() + event.getName() + "\": " + ex);
+ }
+
+ /* Print the name of the property set stream: */
+ out("Property set stream \"" + event.getPath() +
+ event.getName() + "\":");</source>
+
+ <p>Creating the <code>PropertySet</code> is done in a <code>try</code>
+ block, because not each stream in the POI file system contains a property
+ set. If it is some other file, the
+ <code>PropertySetFactory.create()</code> throws a
+ <code>NoPropertySetStreamException</code>, which is caught and
+ logged. Then the program continues with the next stream. However, all
+ other types of exceptions cause the program to terminate by throwing a
+ runtime exception. If all went well, we can print the name of the property
+ set stream.</p>
+ </section>
+
+ <section><title>The Sections</title>
+ <p>The next step is to print the number of sections followed by the
+ sections themselves:</p>
+
+ <source>/* Print the number of sections: */
+final long sectionCount = ps.getSectionCount();
+out(" No. of sections: " + sectionCount);
+
+/* Print the list of sections: */
+List sections = ps.getSections();
+int nr = 0;
+for (Iterator i = sections.iterator(); i.hasNext();)
+{
+ /* Print a single section: */
+ Section sec = (Section) i.next();
+
+ // See below for the complete loop body.
+}</source>
+
+ <p>The <code>PropertySet</code>'s method <code>getSectionCount()</code>
+ returns the number of sections.</p>
+
+ <p>To retrieve the sections, use the <code>getSections()</code>
+ method. This method returns a <code>java.util.List</code> containing
+ instances of the <code>Section</code> class in their proper order.</p>
+
+ <p>The sample code shows a loop that retrieves the <code>Section</code>
+ objects one by one and prints some information about each one. Here is
+ the complete body of the loop:</p>
+
+ <source>/* Print a single section: */
+Section sec = (Section) i.next();
+out(" Section " + nr++ + ":");
+String s = hex(sec.getFormatID().getBytes());
+s = s.substring(0, s.length() - 1);
+out(" Format ID: " + s);
+
+/* Print the number of properties in this section. */
+int propertyCount = sec.getPropertyCount();
+out(" No. of properties: " + propertyCount);
+
+/* Print the properties: */
+Property[] properties = sec.getProperties();
+for (int i2 = 0; i2 < properties.length; i2++)
+{
+ /* Print a single property: */
+ Property p = properties[i2];
+ int id = p.getID();
+ long type = p.getType();
+ Object value = p.getValue();
+ out(" Property ID: " + id + ", type: " + type +
+ ", value: " + value);
+}</source>
+ </section>
+
+ <section><title>The Section's Format ID</title>
+ <p>The first method called on the <code>Section</code> instance is
+ <code>getFormatID()</code>. As explained above, the format ID of the
+ first section in a property set determines the type of the property
+ set. Its type is <code>ClassID</code> which is essentially a sequence of
+ 16 bytes. A real application using its own type of a custom property set
+ should have defined a unique format ID and, when reading a property set
+ stream, should check the format ID is equal to that unique format ID. The
+ sample program just prints the format ID it finds in a section:</p>
+
+ <source>String s = hex(sec.getFormatID().getBytes());
+s = s.substring(0, s.length() - 1);
+out(" Format ID: " + s);</source>
+
+ <p>As you can see, the <code>getFormatID()</code> method returns a
+ <code>ClassID</code> object. An array containing the bytes can be
+ retrieved with <code>ClassID.getBytes()</code>. In order to get a nicely
+ formatted printout, the sample program uses the <code>hex()</code> helper
+ method which in turn uses the POI utility class <code>HexDump</code> in
+ the <code>org.apache.poi.util</code> package. Another helper method is
+ <code>out()</code> which just saves typing
+ <code>System.out.println()</code>.</p>
+ </section>
+
+ <section><title>The Properties</title>
+ <p>Before getting the properties, it is possible to find out how many
+ properties are available in the section via the
+ <code>Section.getPropertyCount()</code>. The sample application uses this
+ method to print the number of properties to the standard output:</p>
+
+ <source>int propertyCount = sec.getPropertyCount();
+out(" No. of properties: " + propertyCount);</source>
+
+ <p>Now its time to get to the properties themselves. You can retrieve a
+ section's properties with the method
+ <code>Section.getProperties()</code>:</p>
+
+ <source>Property[] properties = sec.getProperties();</source>
+
+ <p>As you can see the result is an array of <code>Property</code>
+ objects. This class has three methods to retrieve a property's ID, its
+ type, and its value. The following code snippet shows how to call
+ them:</p>
+
+ <source>for (int i2 = 0; i2 < properties.length; i2++)
+{
+ /* Print a single property: */
+ Property p = properties[i2];
+ int id = p.getID();
+ long type = p.getType();
+ Object value = p.getValue();
+ out(" Property ID: " + id + ", type: " + type +
+ ", value: " + value);
+}</source>
+ </section>
+
+ <section><title>Sample Output</title>
+ <p>The output of the sample program might look like the following. It
+ shows the summary information and the document summary information
+ property sets of a Microsoft Word document. However, unlike the first and
+ second section of this HOW-TO the application does not have any code
+ which is specific to the <code>SummaryInformation</code> and
+ <code>DocumentSummaryInformation</code> classes.</p>
+
+ <source>Property set stream "/SummaryInformation":
+ No. of sections: 1
+ Section 0:
+ Format ID: 00000000 F2 9F 85 E0 4F F9 10 68 AB 91 08 00 2B 27 B3 D9 ....O..h....+'..
+ No. of properties: 17
+ Property ID: 1, type: 2, value: 1252
+ Property ID: 2, type: 30, value: Titel
+ Property ID: 3, type: 30, value: Thema
+ Property ID: 4, type: 30, value: Rainer Klute (Autor)
+ Property ID: 5, type: 30, value: Test (Stichwörter)
+ Property ID: 6, type: 30, value: This is a document for testing HPSF
+ Property ID: 7, type: 30, value: Normal.dot
+ Property ID: 8, type: 30, value: Unknown User
+ Property ID: 9, type: 30, value: 3
+ Property ID: 18, type: 30, value: Microsoft Word 9.0
+ Property ID: 12, type: 64, value: Mon Jan 01 00:59:25 CET 1601
+ Property ID: 13, type: 64, value: Thu Jul 18 16:22:00 CEST 2002
+ Property ID: 14, type: 3, value: 1
+ Property ID: 15, type: 3, value: 20
+ Property ID: 16, type: 3, value: 93
+ Property ID: 19, type: 3, value: 0
+ Property ID: 17, type: 71, value: [B@13582d
+Property set stream "/DocumentSummaryInformation":
+ No. of sections: 2
+ Section 0:
+ Format ID: 00000000 D5 CD D5 02 2E 9C 10 1B 93 97 08 00 2B 2C F9 AE ............+,..
+ No. of properties: 14
+ Property ID: 1, type: 2, value: 1252
+ Property ID: 2, type: 30, value: Test
+ Property ID: 14, type: 30, value: Rainer Klute (Manager)
+ Property ID: 15, type: 30, value: Rainer Klute IT-Consulting GmbH
+ Property ID: 5, type: 3, value: 3
+ Property ID: 6, type: 3, value: 2
+ Property ID: 17, type: 3, value: 111
+ Property ID: 23, type: 3, value: 592636
+ Property ID: 11, type: 11, value: false
+ Property ID: 16, type: 11, value: false
+ Property ID: 19, type: 11, value: false
+ Property ID: 22, type: 11, value: false
+ Property ID: 13, type: 4126, value: [B@56a499
+ Property ID: 12, type: 4108, value: [B@506411
+ Section 1:
+ Format ID: 00000000 D5 CD D5 05 2E 9C 10 1B 93 97 08 00 2B 2C F9 AE ............+,..
+ No. of properties: 7
+ Property ID: 0, type: 0, value: {6=Test-JaNein, 5=Test-Zahl, 4=Test-Datum, 3=Test-Text, 2=_PID_LINKBASE}
+ Property ID: 1, type: 2, value: 1252
+ Property ID: 2, type: 65, value: [B@c9ba38
+ Property ID: 3, type: 30, value: This is some text.
+ Property ID: 4, type: 64, value: Wed Jul 17 00:00:00 CEST 2002
+ Property ID: 5, type: 3, value: 27
+ Property ID: 6, type: 11, value: true
+No property set stream: "/WordDocument"
+No property set stream: "/CompObj"
+No property set stream: "/1Table"</source>
+
+ <p>There are some interesting items to note:</p>
+
+ <ul>
+ <li>The first property set (summary information) consists of a single
+ section, the second property set (document summary information) consists
+ of two sections.</li>
+
+ <li>Each section type (identified by its format ID) has its own domain of
+ property ID. For example, in the second property set the properties with
+ ID 2 have different meanings in the two section. By the way, the format
+ IDs of these sections are <strong>not</strong> equal, but you have to
+ look hard to find the difference.</li>
+
+ <li>The properties are not in any particular order in the section,
+ although they slightly tend to be sorted by their IDs.</li>
+ </ul>
+ </section>
+
+ <section><title>Property IDs</title>
+ <p>Properties in the same section are distinguished by their IDs. This is
+ similar to variables in a programming language like Java, which are
+ distinguished by their names. But unlike variable names, property IDs are
+ simple integral numbers. There is another similarity, however. Just like
+ a Java variable has a certain scope (e.g. a member variables in a class),
+ a property ID also has its scope of validity: the section.</p>
+
+ <p>Two property IDs in sections with different section format IDs
+ don't have the same meaning even though their IDs might be equal. For
+ example, ID 4 in the first (and only) section of a summary
+ information property set denotes the document's author, while ID 4 in the
+ first section of the document summary information property set means the
+ document's byte count. The sample output above does not show a property
+ with an ID of 4 in the first section of the document summary information
+ property set. That means that the document does not have a byte
+ count. However, there is a property with an ID of 4 in the
+ <em>second</em> section: This is a user-defined property ID - we'll get
+ to that topic in a minute.</p>
+
+ <p>So, how can you find out what the meaning of a certain property ID in
+ the summary information and the document summary information property set
+ is? The standard property sets as such don't have any hints about the
+ <strong>meanings of their property IDs</strong>. For example, the summary
+ information property set does not tell you that the property ID 4 stands
+ for the document's author. This is external knowledge. Microsoft defined
+ standard meanings for some of the property IDs in the summary information
+ and the document summary information property sets. As a help to the Java
+ and POI programmer, the class <code>PropertyIDMap</code> in the
+ <code>org.apache.poi.hpsf.wellknown</code> package defines constants
+ for the "well-known" property IDs. For example, there is the
+ definition</p>
+
+ <source>public final static int PID_AUTHOR = 4;</source>
+
+ <p>These definitions allow you to use symbolic names instead of
+ numbers.</p>
+
+ <p>In order to provide support for the other way, too, - i.e. to map
+ property IDs to property names - the class <code>PropertyIDMap</code>
+ defines two static methods:
+ <code>getSummaryInformationProperties()</code> and
+ <code>getDocumentSummaryInformationProperties()</code>. Both return
+ <code>java.util.Map</code> objects which map property IDs to
+ strings. Such a string gives a hint about the property's meaning. For
+ example,
+ <code>PropertyIDMap.getSummaryInformationProperties().get(4)</code>
+ returns the string "PID_AUTHOR". An application could use this string as
+ a key to a localized string which is displayed to the user, e.g. "Author"
+ in English or "Verfasser" in German. HPSF might provide such
+ language-dependend ("localized") mappings in a later release.</p>
+
+ <p>Usually you won't have to deal with those two maps. Instead you should
+ call the <code>Section.getPIDString(int)</code> method. It returns the
+ string associated with the specified property ID in the context of the
+ <code>Section</code> object.</p>
+
+ <p>Above you learned that property IDs have a meaning in the scope of a
+ section only. However, there are two exceptions to the rule: The property
+ IDs 0 and 1 have a fixed meaning in <strong>all</strong> sections:</p>
+
+ <table>
+ <tr>
+ <th>Property ID</th>
+ <th>Meaning</th>
+ </tr>
+
+ <tr>
+ <td>0</td>
+ <td>The property's value is a <strong>dictionary</strong>, i.e. a
+ mapping from property IDs to strings.</td>
+ </tr>
+
+ <tr>
+ <td>1</td>
+ <td>The property's value is the number of a <strong>codepage</strong>,
+ i.e. a mapping from character codes to characters. All strings in the
+ section containing this property must be interpreted using this
+ codepage. Typical property values are 1252 (8-bit "western" characters,
+ ISO-8859-1), 1200 (16-bit Unicode characters, UFT-16), or 65001 (8-bit
+ Unicode characters, UFT-8).</td>
+ </tr>
+ </table>
+ </section>
+
+ <section><title>Property types</title>
+ <p>A property is nothing without its value. It is stored in a property set
+ stream as a sequence of bytes. You must know the property's
+ <strong>type</strong> in order to properly interpret those bytes and
+ reasonably handle the value. A property's type is one of the so-called
+ Microsoft-defined <strong>"variant types"</strong>. When you call
+ <code>Property.getType()</code> you'll get a <code>long</code> value
+ which denoting the property's variant type. The class
+ <code>Variant</code> in the <code>org.apache.poi.hpsf</code> package
+ holds most of those <code>long</code> values as named constants. For
+ example, the constant <code>VT_I4 = 3</code> means a signed integer value
+ of four bytes. Examples of other types are <code>VT_LPSTR = 30</code>
+ meaning a null-terminated string of 8-bit characters, <code>VT_LPWSTR =
+ 31</code> which means a null-terminated Unicode string, or <code>VT_BOOL
+ = 11</code> denoting a boolean value.</p>
+
+ <p>In most cases you won't need a property's type because HPSF does all
+ the work for you.</p>
+ </section>
+
+ <section><title>Property values</title>
+ <p>When an application wants to retrieve a property's value and calls
+ <code>Property.getValue()</code>, HPSF has to interpret the bytes making
+ out the value according to the property's type. The type determines how
+ many bytes the value consists of and what
+ to do with them. For example, if the type is <code>VT_I4</code>, HPSF
+ knows that the value is four bytes long and that these bytes
+ comprise a signed integer value in the little-endian format. This is
+ quite different from e.g. a type of <code>VT_LPWSTR</code>. In this case
+ HPSF has to scan the value bytes for a Unicode null character and collect
+ everything from the beginning to that null character as a Unicode
+ string.</p>
+
+ <p>The good new is that HPSF does another job for you, too: It maps the
+ variant type to an adequate Java type.</p>
+
+ <table>
+ <tr>
+ <th>Variant type:</th>
+ <th>Java type:</th>
+ </tr>
+
+ <tr>
+ <td>VT_I2</td>
+ <td>java.lang.Integer</td>
+ </tr>
+
+ <tr>
+ <td>VT_I4</td>
+ <td>java.lang.Long</td>
+ </tr>
+
+ <tr>
+ <td>VT_FILETIME</td>
+ <td>java.util.Date</td>
+ </tr>
+
+ <tr>
+ <td>VT_LPSTR</td>
+ <td>java.lang.String</td>
+ </tr>
+
+ <tr>
+ <td>VT_LPWSTR</td>
+ <td>java.lang.String</td>
+ </tr>
+
+ <tr>
+ <td>VT_CF</td>
+ <td>byte[]</td>
+ </tr>
+
+ <tr>
+ <td>VT_BOOL</td>
+ <td>java.lang.Boolean</td>
+ </tr>
+
+ </table>
+
+ <p>The bad news is that there are still a couple of variant types HPSF
+ does not yet support. If it encounters one of these types it
+ returns the property's value as a byte array and leaves it to be
+ interpreted by the application.</p>
+
+ <p>An application retrieves a property's value by calling the
+ <code>Property.getValue()</code> method. This method's return type is the
+ abstract <code>Object</code> class. The <code>getValue()</code> method
+ looks up the property's variant type, reads the property's value bytes,
+ creates an instance of an adequate Java type, assigns it the property's
+ value and returns it. Primitive types like <code>int</code> or
+ <code>long</code> will be returned as the corresponding class,
+ e.g. <code>Integer</code> or <code>Long</code>.</p>
+ </section>
+
+
+ <section><title>Dictionaries</title>
+ <p>The property with ID 0 has a very special meaning: It is a
+ <strong>dictionary</strong> mapping property IDs to property names. We
+ have seen already that the meanings of standard properties in the
+ summary information and the document summary information property sets
+ have been defined by Microsoft. The advantage is that the labels of
+ properties like "Author" or "Title" don't have to be stored in the
+ property set. However, a user can define custom fields in, say, Microsoft
+ Word. For each field the user has to specify a name, a type, and a
+ value.</p>
+
+ <p>The names of the custom-defined fields (i.e. the property names) are
+ stored in the document summary information second section's
+ <strong>dictionary</strong>. The dictionary is a map which associates
+ property IDs with property names.</p>
+
+ <p>The method <code>Section.getPIDString(int)</code> not only returns with
+ the well-known property names of the summary information and document
+ summary information property sets, but with self-defined properties,
+ too. It should also work with self-defined properties in self-defined
+ sections.</p>
+ </section>
+
+ <section><title>Codepage support</title>
+
+ <p>The property with ID 1 holds the number of the codepage which was used
+ to encode the strings in this section. If this property is not available
+ in a section, the platform's default character encoding will be
+ used. This works fine as long as the document being read has been written
+ on a platform with the same default character encoding. However, if you
+ receive a document from another region of the world and the codepage is
+ undefined, you are in trouble.</p>
+
+ <p>HPSF's codepage support is only as good as the character encoding
+ support of the Java Virtual Machine (JVM) the application runs on. If
+ HPSF encounters a codepage number it assumes that the JVM has a character
+ encoding with a corresponding name. For example, if the codepage is 1252,
+ HPSF uses the character encoding "cp1252" to read or write strings. If
+ the JVM does not have that character encoding installed or if the
+ codepage number is illegal, an UnsupportedEncodingException will be
+ thrown. This works quite well with Java 2 Standard Edition (J2SE)
+ versions since 1.4. However, under J2SE 1.3 or lower you are out of
+ luck. You should install a newer J2SE version to process codepages with
+ HPSF.</p>
+
+ <p>There are some exceptions to the rule saying that a character
+ encoding's name is derived from the codepage number by prepending the
+ string "cp" to it. In these cases the codepage number is mapped to a
+ well-known character encoding name. Here are a few examples:</p>
+
+ <dl>
+ <dt>Codepage 932</dt>
+ <dd>is mapped to the character encoding "SJIS".</dd>
+ <dt>Codepage 1200</dt>
+ <dd>is mapped to the character encoding "UTF-16".</dd>
+ <dt>Codepage 65001</dt>
+ <dd>is mapped to the character encoding "UTF-8".</dd>
+ </dl>
+
+ <p>More of these mappings between codepage and character encoding name are
+ hard-coded in the classes <code>org.apache.poi.hpsf.Constants</code> and
+ <code>org.apache.poi.hpsf.VariantSupport</code>. Probably there will be a
+ need to add more mappings. The HPSF author will appreciate any hints.</p>
+ </section>
+ </section>
+
+ <anchor id="sec5"/>
+ <section><title>Writing Properties</title>
+
+ <note>This section describes how to write properties.</note>
+
+ <section><title>Overview of Writing Properties</title>
+ <p>Writing properties is possible at a high level and at a low level:</p>
+
+ <ul>
+
+ <li>Most users will want to create or change entries in the summary
+ information or document summary information streams. </li>
+
+ <li>On the low level, there are no convenience classes or methods. You
+ have to deal with things like property IDs and variant types to write
+ properties. Therefore you should have read <link href="#sec3">section
+ 3</link> to understand the description of the low-level writing
+ functions.</li>
+ </ul>
+
+ <p>HPSF's writing capabilities come with the classes
+ <code>MutablePropertySet</code>, <code>MutableSection</code>,
+ <code>MutableProperty</code>, and some helper classes. The "mutable"
+ classes extend their respective superclasses <code>PropertySet</code>,
+ <code>Section</code>, and <code>Property</code> and provide "set" and
+ "write" methods, following the <link
+ href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator
+ pattern</link>.</p>
+ </section>
+
+
+ <section><title>Low-Level Writing: An Overview</title>
+ <p>When you are going to write a property set stream your application has
+ to perform the following steps:</p>
+
+ <ol>
+ <li>Create a <code>MutablePropertySet</code> instance.</li>
+
+ <li>Get hold of a <code>MutableSection</code>. You can either retrieve
+ the one that is always present in a new <code>MutablePropertySet</code>,
+ or you have to create a new <code>MutableSection</code> and add it to
+ the <code>MutablePropertySet</code>.
+ </li>
+
+ <li>Set any <code>Section</code> fields as you like.</li>
+
+ <li>Create as many <code>MutableProperty</code> objects as you need. Set
+ each property's ID, type, and value. Add the
+ <code>MutableProperty</code> objects to the
+ <code>MutableSection</code>.
+ </li>
+
+ <li>Create further <code>MutableSection</code>s if you need them.</li>
+
+ <li>Eventually retrieve the property set as a byte stream using
+ <code>MutablePropertySet.toInputStream()</code> and write it to a POIFS
+ document.</li>
+ </ol>
+ </section>
+
+ <section><title>Low-level Writing Functions In Details</title>
+ <p>Writing properties is introduced by an artificial but simple example: a
+ program creating a new document (aka POI file system) which contains only
+ a single document: a summary information property set stream. The latter
+ will hold the document's title only. This is artificial in that it does
+ not contain any Word, Excel or other kind of useful application document
+ data. A document containing just a property set is without any practical
+ use. However, it is perfectly fine for an example because it make it very
+ simple and easy to understand, and you will get used to writing
+ properties in real applications quickly.</p>
+
+ <p>The application expects the name of the POI file system to be written
+ on the command line. The title property it writes is "Sample title".</p>
+
+ <p>Here's the application's source code. You can also find it in the
+ "examples" section of the POI source code distribution. Explanations are
+ following below.</p>
+
+ <source>package org.apache.poi.hpsf.examples;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.hpsf.MutableProperty;
+import org.apache.poi.hpsf.MutablePropertySet;
+import org.apache.poi.hpsf.MutableSection;
+import org.apache.poi.hpsf.SummaryInformation;
+import org.apache.poi.hpsf.Variant;
+import org.apache.poi.hpsf.WritingNotSupportedException;
+import org.apache.poi.hpsf.wellknown.PropertyIDMap;
+import org.apache.poi.hpsf.wellknown.SectionIDMap;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+
+/**
+ * <p>This class is a simple sample application showing how to create a property
+ * set and write it to disk.</p>
+ *
+ * @author Rainer Klute
+ * @since 2003-09-12
+ */
+public class WriteTitle
+{
+ /**
+ * <p>Runs the example program.</p>
+ *
+ * @param args Command-line arguments. The first and only command-line
+ * argument is the name of the POI file system to create.
+ * @throws IOException if any I/O exception occurs.
+ * @throws WritingNotSupportedException if HPSF does not (yet) support
+ * writing a certain property type.
+ */
+ public static void main(final String[] args)
+ throws WritingNotSupportedException, IOException
+ {
+ /* Check whether we have exactly one command-line argument. */
+ if (args.length != 1)
+ {
+ System.err.println("Usage: " + WriteTitle.class.getName() +
+ "destinationPOIFS");
+ System.exit(1);
+ }
+
+ final String fileName = args[0];
+
+ /* Create a mutable property set. Initially it contains a single section
+ * with no properties. */
+ final MutablePropertySet mps = new MutablePropertySet();
+
+ /* Retrieve the section the property set already contains. */
+ final MutableSection ms = (MutableSection) mps.getSections().get(0);
+
+ /* Turn the property set into a summary information property. This is
+ * done by setting the format ID of its first section to
+ * SectionIDMap.SUMMARY_INFORMATION_ID. */
+ ms.setFormatID(SectionIDMap.SUMMARY_INFORMATION_ID);
+
+ /* Create an empty property. */
+ final MutableProperty p = new MutableProperty();
+
+ /* Fill the property with appropriate settings so that it specifies the
+ * document's title. */
+ p.setID(PropertyIDMap.PID_TITLE);
+ p.setType(Variant.VT_LPWSTR);
+ p.setValue("Sample title");
+
+ /* Place the property into the section. */
+ ms.setProperty(p);
+
+ /* Create the POI file system the property set is to be written to. */
+ final POIFSFileSystem poiFs = new POIFSFileSystem();
+
+ /* For writing the property set into a POI file system it has to be
+ * handed over to the POIFS.createDocument() method as an input stream
+ * which produces the bytes making out the property set stream. */
+ final InputStream is = mps.toInputStream();
+
+ /* Create the summary information property set in the POI file
+ * system. It is given the default name most (if not all) summary
+ * information property sets have. */
+ poiFs.createDocument(is, SummaryInformation.DEFAULT_STREAM_NAME);
+
+ /* Write the whole POI file system to a disk file. */
+ poiFs.writeFilesystem(new FileOutputStream(fileName));
+ }
+
+}</source>
+
+ <p>The application first checks that there is exactly one single argument
+ on the command line: the name of the file to write. If this single
+ argument is present, the application stores it in the
+ <code>fileName</code> variable. It will be used in the end when the POI
+ file system is written to a disk file.</p>
+
+ <source>if (args.length != 1)
+{
+ System.err.println("Usage: " + WriteTitle.class.getName() +
+ "destinationPOIFS");
+ System.exit(1);
+}
+final String fileName = args[0];</source>
+
+ <p>Let's create a property set now. We cannot use the
+ <code>PropertySet</code> class, because it is read-only. It does not have
+ a constructor creating an empty property set, and it does not have any
+ methods to modify its contents, i.e. to write sections containing
+ properties into it.</p>
+
+ <p>The class to use is <code>MutablePropertySet</code>. It is a subclass
+ of <code>PropertySet</code>. The sample application calls its no-args
+ constructor in order to establish an empty property set:</p>
+
+ <source>final MutablePropertySet mps = new MutablePropertySet();</source>
+
+ <p>As said, we have an empty property set now. Later we will put some
+ contents into it.</p>
+
+ <p>By the way, the <code>MutablePropertySet</code> class has another
+ constructor taking a <code>PropertySet</code> as parameter. It creates a
+ mutable deep copy of the property set given to it.</p>
+
+ <p>The <code>MutablePropertySet</code> created by the no-args constructor
+ is not really empty: It contains a single section without properties. We
+ can either retrieve that section and fill it with properties or we can
+ replace it by another section. We can also add further sections to the
+ property set. The sample application decides to retrieve the section
+ being already there:</p>
+
+ <source>final MutableSection ms = (MutableSection) mps.getSections().get(0);</source>
+
+ <p>The <code>getSections()</code> method returns the property set's
+ sections as a list, i.e. an instance of
+ <code>java.util.List</code>. Calling <code>get(0)</code> returns the
+ list's first (or zeroth, if you prefer) element. The <code>Section</code>
+ returned is a <code>MutableSection</code>: a subclass of
+ <code>Section</code> you can modify.</p>
+
+ <p>The alternative to retrieving the <code>MutableSection</code> being
+ already there would have been to create an new
+ <code>MutableSection</code> like this:</p>
+
+ <source>MutableSection s = new MutableSection();</source>
+
+ <p>There is also a constructor which takes a <code>Section</code> as
+ parameter and creates a mutable deep copy of it.</p>
+
+ <p>The <code>MutableSection</code> the sample application retrieved from
+ the <code>MutablePropertySet</code> is still empty. It contains no
+ properties and does not have a format ID. As you have read <link
+ href="#sec3">above</link> the format ID of the first section in a
+ property set determines the property set's type. Since our property set
+ should become a SummaryInformation property set we have to set the format
+ ID of its first (and only) section to
+ <code>F29F85E0-4FF9-1068-AB-91-08-00-2B-27-B3-D9</code>. However, you
+ won't have to remember that ID: HPSF has it defined as the well-known
+ constant <code>SectionIDMap.SUMMARY_INFORMATION_ID</code>. The sample
+ application writes it to the section using the
+ <code>setFormatID(byte[])</code> method:</p>
+
+ <source>ms.setFormatID(SectionIDMap.SUMMARY_INFORMATION_ID);</source>
+
+ <p>Now it is time to create a property. As you might expect there is a
+ subclass of <code>Property</code> called
+ <code>MutableProperty</code> with a no-args constructor:</p>
+
+ <source>final MutableProperty p = new MutableProperty();</source>
+
+ <p>A <code>MutableProperty</code> object must have an ID, a type, and a
+ value (see <link href="#sec3">above</link> for details). The class
+ provides methods to set these attributes:</p>
+
+ <source>p.setID(PropertyIDMap.PID_TITLE);
+p.setType(Variant.VT_LPWSTR);
+p.setValue("Sample title");</source>
+
+ <p>The <code>MutableProperty</code> class has a constructor which you can
+ use to pass in all three attributes in a single call. See the Javadoc API
+ documentation for details!</p>
+
+ <p>The sample property set is complete now. We have a
+ <code>MutablePropertySet</code> containing a <code>MutableSection</code>
+ containing a <code>MutableProperty</code>. Of course we could have added
+ more sections to the property set and more properties to the sections but
+ we wanted to keep things simple.</p>
+
+ <p>The property set has to be written to a POI file system. The following
+ statement creates it.</p>
+
+ <source>final POIFSFileSystem poiFs = new POIFSFileSystem();</source>
+
+ <p>Writing the property set includes the step of converting it into a
+ sequence of bytes. The <code>MutablePropertySet</code> class has the
+ method <code>toInputStream()</code> for this purpose. It returns the
+ bytes making out the property set stream as an
+ <code>InputStream</code>:</p>
+
+ <source>final InputStream is = mps.toInputStream();</source>
+
+ <p>If you'd read from this input stream you'd receive all the property
+ set's bytes. However, it is very likely that you'll never do
+ that. Instead you'll pass the input stream to the
+ <code>POIFSFileSystem.createDocument()</code> method, like this:</p>
+
+ <source>poiFs.createDocument(is, SummaryInformation.DEFAULT_STREAM_NAME);</source>
+
+ <p>Besides the <code>InputStream</code> <code>createDocument()</code>
+ takes a second parameter: the name of the document to be created. For a
+ SummaryInformation property set stream the default name is available as
+ the constant <code>SummaryInformation.DEFAULT_STREAM_NAME</code>.</p>
+
+ <p>The last step is to write the POI file system to a disk file:</p>
+
+ <source>poiFs.writeFilesystem(new FileOutputStream(fileName));</source>
+ </section>
+ </section>
+
+
+
+ <section><title>Further Reading</title>
+ <p>There are still some aspects of HSPF left which are not covered by this
+ HOW-TO. You should dig into the Javadoc API documentation to learn
+ further details. Since you've struggled through this document up to this
+ point, you are well prepared.</p>
+ </section>
+
+ </section>
+ </body>
+</document>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - HPSF - Java API to Handle Microsoft Format Document
+ Properties</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Rainer Klute" email="klute@apache.org"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Overview</title>
+
+ <p>Microsoft applications like "Word", "Excel" or "Powerpoint" let the user
+ describe his document by properties like "title", "category" and so on. The
+ application itself adds further information: last author, creation date
+ etc. These document properties are stored in so-called <strong>property set
+ streams</strong>. A property set stream is a separate document within a
+ <link href="../poifs/index.html">POI filesystem</link>. We'll call property
+ set streams mostly just "property sets". HPSF is POI's pure-Java
+ implementation to read and write property sets.</p>
+
+ <p>The <link href="how-to.html">HPSF HOWTO</link> describes what a Java
+ application should do to read a property set using HPSF, how to retrieve
+ the information it needs, and how to write properties into the
+ document.</p>
+
+ <p>HPSF supports OLE2 property set streams in general, and is not limited to
+ the special case of document properties in the Microsoft Office files
+ mentioned above. The <link href="internals.html">HPSF description</link>
+ describes the internal structure of property set streams. A separate
+ document explains the internal of <link href="thumbnails.html">thumbnail
+ images</link>.</p>
+ </section>
+ </body>
+</document>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - HPSF Internals</title>
+ <authors>
+ <person name="Rainer Klute" email="klute@rainer-klute.de"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>HPSF Internals</title>
+
+ <section><title>Introduction</title>
+
+ <p>A Microsoft Office document is internally organized like a filesystem
+ with directory and files. Microsoft calls these files
+ <strong>streams</strong>. A document can have properties attached to it,
+ like author, title, number of words etc. These metadata are not stored in
+ the main stream of, say, a Word document, but instead in a dedicated
+ stream with a special format. Usually this stream's name is
+ <code>\005SummaryInformation</code>, where <code>\005</code> represents
+ the character with a decimal value of 5.</p>
+
+ <p>A single piece of information in the stream is called a
+ <strong>property</strong>, for example the document title. Each property
+ has an integral <strong>ID</strong> (e.g. 2 for title), a
+ <strong>type</strong> (telling that the title is a string of bytes) and a
+ <strong>value</strong> (what this is should be obvious). A stream
+ containing properties is called a
+ <strong>property set stream</strong>.</p>
+
+ <p>This document describes the internal structure of a property set stream,
+ i.e. the <strong>HPSF</strong>. It does
+ not describe how a Microsoft Office document is organized internally and
+ how to retrieve a stream from it. See the <link
+ href="../poifs/index.html">POIFS documentation</link> for that kind of
+ stuff.</p>
+
+ <p>The HPSF is not only used in the Summary
+ Information stream in the top-level document of a Microsoft Office
+ document. Often there is also a property set stream named
+ <code>\005DocumentSummaryInformation</code> with additional properties.
+ Embedded documents may have their own property set streams. You cannot
+ tell by a stream's name whether it is a property set stream or not.
+ Instead you have to open the stream and look at its bytes.</p>
+ </section>
+
+
+
+ <section><title>Data Types</title>
+
+ <p>Before delving into the details of the property set stream format we
+ have to have a short look at data types. Integral values are stored in the
+ so-called <strong>little endian</strong> format. In this format the bytes
+ that make out an integral value are stored in the "wrong" order. For
+ example, the decimal value 4660 is 0x1234 in the hexadecimal notation. If
+ you think this should be represented by a byte 0x12 followed by another
+ byte 0x34, you are right. This is called the <strong>big endian</strong>
+ format. In the little endian format, however, this order is reversed and
+ the low-value byte comes first: 0x3412.
+ </p>
+
+ <p>The following table gives an overview about some important data
+ types:</p>
+
+ <table>
+
+ <tr>
+ <th>Name</th>
+ <th>Length</th>
+ <th>Example (Big Endian)</th>
+ <th>Example (Little Endian)</th>
+ </tr>
+
+ <tr>
+ <td><strong>Bytes</strong></td>
+ <td>1 byte</td>
+ <td><code>0x12</code></td>
+ <td><code>0x12</code></td>
+ </tr>
+
+ <tr>
+ <td><strong>Word</strong></td>
+ <td>2 bytes</td>
+ <td><code>0x1234</code></td>
+ <td><code>0x3412</code></td>
+ </tr>
+
+ <tr>
+ <td><strong>DWord</strong></td>
+ <td>4 bytes</td>
+ <td><code>0x12345678</code></td>
+ <td><code>0x78563412</code></td>
+ </tr>
+
+ <tr>
+ <td><strong>ClassID</strong><br/>
+ A sequence of one DWord, two Words and eight Bytes</td>
+
+ <td>16 bytes</td>
+
+ <td><code>0xE0859FF2F94F6810AB9108002B27B3D9</code> resp.
+ <code>E0859FF2-F94F-6810-AB-91-08-00-2B-27-B3-D9</code></td>
+
+ <td><code>0xF29F85E04FF91068AB9108002B27B3D9</code> resp.
+ <code>F29F85E0-4FF9-1068-AB-91-08-00-2B-27-B3-D9</code></td>
+ </tr>
+
+ <tr>
+ <td></td>
+ <td></td>
+ <td>The ClassID examples are given here in two different notations. The
+ second notation without the "0x" at the beginning and with dashes
+ inside shows the internal grouping into one DWord, two Words and eight
+ Bytes.</td>
+ <td><em>Watch out:</em> Microsoft documentation and tools show class IDs
+ a little bit differently like
+ <code>F29F85E0-4FF9-1068-AB91-08002B27B3D9</code>.
+ However, that representation is (intentionally?) misleading with
+ respect to endianess.</td>
+ </tr>
+ </table>
+ </section>
+
+
+
+ <section><title>HPSF Overview</title>
+
+ <p>A property set stream consists of three main parts:</p>
+
+ <ol>
+ <li>The <strong>header</strong> and</li>
+ <li>the <strong>section(s)</strong> containing the properties.</li>
+ </ol>
+ </section>
+
+
+
+ <section><title>The Header</title>
+
+ <p>The first bytes in a property set stream is the <strong>header</strong>.
+ It has a fixed length and looks like this:</p>
+
+ <table>
+ <tr>
+ <th>Offset</th>
+ <th>Type</th>
+ <th>Contents</th>
+ <th>Remarks</th>
+ </tr>
+
+ <tr>
+ <td>0</td>
+ <td>Word</td>
+ <td><code>0xFFFE</code></td>
+ <td>If the first four bytes of a stream do not contain these values, the
+ stream is not a property set stream.</td>
+ </tr>
+
+ <tr>
+ <td>2</td>
+ <td>Word</td>
+ <td><code>0x0000</code></td>
+ <td></td>
+ </tr>
+
+ <tr>
+ <td>4</td>
+ <td>DWord</td>
+ <td>Denotes the operating system and the OS version under which this
+ stream was created. The operating system ID is in the DWord's higher
+ word (after little endian decoding): <code>0x0000</code> for Win16,
+ <code>0x0001</code> for Macintosh and <code>0x0002</code> for Win32 -
+ that's all. The reader is most likely aware of the fact that there are
+ some more operating systems. However, Microsoft does not seem to
+ know.</td>
+ <td></td>
+ </tr>
+
+ <tr>
+ <td>8</td>
+ <td>ClassID</td>
+ <td><code>0x00000000000000000000000000000000</code></td>
+ <td>Most property set streams have this value but this is not
+ required.</td>
+ </tr>
+
+ <tr>
+ <td>24</td>
+ <td>DWord</td>
+ <td><code>0x01000000</code> or greater</td>
+ <td>Section count. This field's value should be equal to 1 or greater.
+ Microsoft claims that this is a "reserved" field, but it seems to tell
+ how many sections (see below) are following in the stream. This would
+ really make sense because otherwise you could not know where and how
+ far you should read section data.</td>
+ </tr>
+ </table>
+ </section>
+
+
+
+ <section><title>Section List</title>
+
+ <p>Following the header is the section list. This is an array of pairs each
+ consisting of a section format ID and an offset. This array has as many
+ pairs of ClassID and and DWord fields as the section count field in the
+ header says. The Summary Information stream contains a single section, the
+ Document Summary Information stream contains two.</p>
+
+ <table>
+ <tr>
+ <th>Type</th>
+ <th>Contents</th>
+ <th>Remarks</th>
+ </tr>
+
+ <tr>
+ <td>ClassID</td>
+ <td>Section format ID</td>
+ <td><code>0xF29F85E04FF91068AB9108002B27B3D9</code> for the single section
+ in the Summary Information stream.<br/><br/>
+
+ <code>0xD5CDD5022E9C101B939708002B2CF9AE</code> for the first
+ section in the Document Summary Information stream.</td>
+ </tr>
+
+ <tr>
+ <td>DWord</td>
+ <td>Offset</td>
+ <td>The number of bytes between the beginning of the stream and the
+ beginning of the section within the stream.</td>
+ </tr>
+
+ <tr>
+ <td>ClassID</td>
+ <td>Section format ID</td>
+ <td>...</td>
+ </tr>
+
+ <tr>
+ <td>DWord</td>
+ <td>Offset</td>
+ <td>...</td>
+ </tr>
+
+ <tr>
+ <td>...</td>
+ <td>...</td>
+ <td>...</td>
+ </tr>
+ </table>
+ </section>
+
+
+
+ <section><title>Section</title>
+
+ <p>A section is divided into three parts: the section header (with the
+ section length and the number of properties in the section), the
+ properties list (with type and offset of each property), and the
+ properties themselves. Here are the details:</p>
+
+ <table>
+ <tr>
+ <th> </th>
+ <th>Type</th>
+ <th>Contents</th>
+ <th>Remarks</th>
+ </tr>
+
+ <tr>
+ <td>Section header</td>
+
+ <td>DWord</td>
+ <td>Length</td>
+ <td>The length of the section in bytes.</td>
+ </tr>
+
+ <tr>
+ <td></td>
+ <td>DWord</td>
+ <td>Property count</td>
+ <td>The number of properties in the section.</td>
+ </tr>
+
+ <tr>
+
+ <td>Properties list</td>
+
+ <td>DWord</td>
+ <td>Property ID</td>
+ <td>The property ID tells what the property means. For example, an ID of
+ <code>0x0002</code> in the Summary Information stands for the document's
+ title. See the <link href="#property_ids">Property IDs</link>
+ chapter below for more details.</td>
+ </tr>
+
+ <tr>
+ <td></td>
+ <td>DWord</td>
+ <td>Offset</td>
+ <td>The number of bytes between the beginning of the section and the
+ property.</td>
+ </tr>
+
+ <tr>
+ <td></td>
+ <td>...</td>
+ <td>...</td>
+ <td>...</td>
+ </tr>
+
+ <tr>
+ <td>Properties</td>
+
+ <td>DWord</td>
+ <td>Property type ("variant")</td>
+ <td>This is the property's data type, e.g. an integer value, a byte
+ string or a Unicode string. See the
+ <link href="#property_types"><em>Property Types</em></link> chapter
+ for details!</td>
+ </tr>
+
+ <tr>
+ <td></td>
+ <td><em>Field length depends on the property type
+ ("variant")</em></td>
+ <td>Property value</td>
+ <td>This field's length depends on the property's type. These are the
+ bytes that make out the DWord, the byte string or some other data of
+ fixed or variable length.<br/><br/>
+
+ The property value's length is always stored in an area which is a
+ multiple of 4 in length. If the property is shorter, e.g. a byte
+ string of 13 bytes, the remaining bytes are padded with <code>0x00</code>
+ bytes.</td>
+ </tr>
+
+ <tr>
+ <td></td>
+ <td>...</td>
+ <td>...</td>
+ <td>...</td>
+ </tr>
+ </table>
+ </section>
+
+
+
+ <section><title>Property IDs</title>
+ <anchor id="property_ids"/>
+
+ <p>As seen above, a section holds a property list: an array with property
+ IDs and offsets. The property ID gives each property a meaning. For
+ example, in the Summary Information stream the property ID 2 says that
+ this property is the document's title.</p>
+
+ <p>If you want to know a property ID's meaning, it is not sufficient to
+ know the ID itself. You must also know the
+ <strong>section format ID</strong>. For example, in the Document Summary
+ Information stream the property ID 2 means not the document's title but
+ its category. Due to Microsoft's infinite wisdom the section format ID is
+ not part of the section. Thus if you have only a section without the
+ stream it is in, you cannot make any sense of the properties because you
+ do not know what they mean.</p>
+
+ <p>So each section format ID has its own name space of property IDs.
+ Microsoft defined some "well-known" property IDs for the Summary
+ Information and the Document Summary Information streams. You can extend
+ them by your own additional IDs. This will be described below.</p>
+
+ <section><title>Property IDs in The Summary Information Stream</title>
+
+ <p>The Summary Information stream has a single section with a section
+ format ID of <code>0xF29F85E04FF91068AB9108002B27B3D9</code>. The following
+ table defines the meaning of its property IDs. Each row associates a
+ property ID with a <em>name</em> and an <em>ID string</em>. (The property
+ <em>type</em> is just for informational purposes given here. As we have
+ seen above, the type is always given along with the value.)</p>
+
+ <p>The property <em>name</em> is a readable string which could be
+ displayed to the user. However, this string is useful only for users who
+ understand English. The property name does not help with other
+ languages.</p>
+
+ <p>The property <em>ID string</em> is about the same but looks more
+ technically and is nothing a user should bother with. You could the ID
+ string and map it to an appropriate display string in a particular
+ language. Of course you could do that with the property ID as well and
+ with less overhead, but people (including software developers) tend to be
+ better in remembering symbolic constants than remembering numbers.</p>
+
+ <table>
+ <tr>
+ <th>Property ID</th>
+ <th>Property Name</th>
+ <th>Property ID String</th>
+ <th>Property Type</th>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Title</td>
+ <td>PID_TITLE</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>Subject</td>
+ <td>PID_SUBJECT</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td>Author</td>
+ <td>PID_AUTHOR</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>Keywords</td>
+ <td>PID_KEYWORDS</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>6</td>
+ <td>Comments</td>
+ <td>PID_COMMENTS</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>7</td>
+ <td>Template</td>
+ <td>PID_TEMPLATE</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>8</td>
+ <td>Last Saved By</td>
+ <td>PID_LASTAUTHOR</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>9</td>
+ <td>Revision Number</td>
+ <td>PID_REVNUMBER</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>10</td>
+ <td>Total Editing Time</td>
+ <td>PID_EDITTIME</td>
+ <td>VT_FILETIME</td>
+ </tr>
+ <tr>
+ <td>11</td>
+ <td>Last Printed</td>
+ <td>PID_LASTPRINTED</td>
+ <td>VT_FILETIME</td>
+ </tr>
+ <tr>
+ <td>12</td>
+ <td>Create Time/Date</td>
+ <td>PID_CREATE_DTM</td>
+ <td>VT_FILETIME</td>
+ </tr>
+ <tr>
+ <td>13</td>
+ <td>Last Saved Time/Date</td>
+ <td>PID_LASTSAVE_DTM</td>
+ <td>VT_FILETIME</td>
+ </tr>
+ <tr>
+ <td>14</td>
+ <td>Number of Pages</td>
+ <td>PID_PAGECOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>15</td>
+ <td>Number of Words</td>
+ <td>PID_WORDCOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>16</td>
+ <td>Number of Characters</td>
+ <td>PID_CHARCOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>17</td>
+ <td>Thumbnail</td>
+ <td>PID_THUMBNAIL</td>
+ <td>VT_CF</td>
+ </tr>
+ <tr>
+ <td>18</td>
+ <td>Name of Creating Application</td>
+ <td>PID_APPNAME</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>19</td>
+ <td>Security</td>
+ <td>PID_SECURITY</td>
+ <td>VT_I4</td>
+ </tr>
+ </table>
+ </section>
+
+
+
+ <section><title>Property IDs in The Document Summary Information Stream</title>
+
+ <p>The Document Summary Information stream has two sections with a section
+ format ID of <code>0xD5CDD5022E9C101B939708002B2CF9AE</code> for the first
+ one. The following table defines the meaning of the property IDs in the
+ first section. See the preceeding section for interpreting the table.</p>
+
+ <table>
+ <tr>
+ <th>Property ID</th>
+ <th>Property name</th>
+ <th>Property ID string</th>
+ <th>VT type</th>
+ </tr>
+
+ <tr>
+ <td>0</td>
+ <td>Dictionary</td>
+ <td>PID_DICTIONARY</td>
+ <td>[Special format]</td>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>Code page</td>
+ <td>PID_CODEPAGE</td>
+ <td>VT_I2</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Category</td>
+ <td>PID_CATEGORY</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>PresentationTarget</td>
+ <td>PID_PRESFORMAT</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td>Bytes</td>
+ <td>PID_BYTECOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>Lines</td>
+ <td>PID_LINECOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>6</td>
+ <td>Paragraphs</td>
+ <td>PID_PARCOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>7</td>
+ <td>Slides</td>
+ <td>PID_SLIDECOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>8</td>
+ <td>Notes</td>
+ <td>PID_NOTECOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>9</td>
+ <td>HiddenSlides</td>
+ <td>PID_HIDDENCOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>10</td>
+ <td>MMClips</td>
+ <td>PID_MMCLIPCOUNT</td>
+ <td>VT_I4</td>
+ </tr>
+ <tr>
+ <td>11</td>
+ <td>ScaleCrop</td>
+ <td>PID_SCALE</td>
+ <td>VT_BOOL</td>
+ </tr>
+ <tr>
+ <td>12</td>
+ <td>HeadingPairs</td>
+ <td>PID_HEADINGPAIR</td>
+ <td>VT_VARIANT | VT_VECTOR</td>
+ </tr>
+ <tr>
+ <td>13</td>
+ <td>TitlesofParts</td>
+ <td>PID_DOCPARTS</td>
+ <td>VT_LPSTR | VT_VECTOR</td>
+ </tr>
+ <tr>
+ <td>14</td>
+ <td>Manager</td>
+ <td>PID_MANAGER</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>15</td>
+ <td>Company</td>
+ <td>PID_COMPANY</td>
+ <td>VT_LPSTR</td>
+ </tr>
+ <tr>
+ <td>16</td>
+ <td>LinksUpTo Date</td>
+ <td>PID_LINKSDIRTY</td>
+ <td>VT_BOOL</td>
+ </tr>
+ </table>
+ </section>
+ </section>
+
+
+
+ <section><title>Property Types</title>
+ <anchor id="property_types"/>
+
+ <p>A property consists of a DWord <em>type field</em> followed by the
+ property value. The property type is an integer value and tells how the
+ data byte following it are to be interpreted. In the Microsoft world it is
+ also known as the <em>variant</em>.</p>
+
+ <p>The <em>Usage</em> column says where a variant type may occur. Not all
+ of them are allowed in a property set but just those marked with a [P].
+ <strong>[V]</strong> - may appear in a VARIANT, <strong>[T]</strong> - may
+ appear in a TYPEDESC, <strong>[P]</strong> - may appear in an OLE property
+ set, <strong>[S]</strong> - may appear in a Safe Array.</p>
+
+ <table>
+ <tr>
+ <th>Variant ID</th>
+ <th>Variant Type</th>
+ <th>Usage</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>0</td>
+ <td>VT_EMPTY</td>
+ <td>[V] [P]</td>
+ <td>nothing</td>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>VT_NULL</td>
+ <td>[V] [P]</td>
+ <td>SQL style Null</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>VT_I2</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>2 byte signed int</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>VT_I4</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>4 byte signed int</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td>VT_R4</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>4 byte real</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>VT_R8</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>8 byte real</td>
+ </tr>
+ <tr>
+ <td>6</td>
+ <td>VT_CY</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>currency</td>
+ </tr>
+ <tr>
+ <td>7</td>
+ <td>VT_DATE</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>date</td>
+ </tr>
+ <tr>
+ <td>8</td>
+ <td>VT_BSTR</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>OLE Automation string</td>
+ </tr>
+ <tr>
+ <td>9</td>
+ <td>VT_DISPATCH</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>IDispatch *</td>
+ </tr>
+ <tr>
+ <td>10</td>
+ <td>VT_ERROR</td>
+ <td>[V] [T] [S]</td>
+ <td>SCODE</td>
+ </tr>
+ <tr>
+ <td>11</td>
+ <td>VT_BOOL</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>True=-1, False=0</td>
+ </tr>
+ <tr>
+ <td>12</td>
+ <td>VT_VARIANT</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>VARIANT *</td>
+ </tr>
+ <tr>
+ <td>13</td>
+ <td>VT_UNKNOWN</td>
+ <td>[V] [T] [S]</td>
+ <td>IUnknown *</td>
+ </tr>
+ <tr>
+ <td>14</td>
+ <td>VT_DECIMAL</td>
+ <td>[V] [T] [S]</td>
+ <td>16 byte fixed point</td>
+ </tr>
+ <tr>
+ <td>16</td>
+ <td>VT_I1</td>
+ <td>[T]</td>
+ <td>signed char</td>
+ </tr>
+ <tr>
+ <td>17</td>
+ <td>VT_UI1</td>
+ <td>[V] [T] [P] [S]</td>
+ <td>unsigned char</td>
+ </tr>
+ <tr>
+ <td>18</td>
+ <td>VT_UI2</td>
+ <td>[T] [P]</td>
+ <td>unsigned short</td>
+ </tr>
+ <tr>
+ <td>19</td>
+ <td>VT_UI4</td>
+ <td>[T] [P]</td>
+ <td>unsigned short</td>
+ </tr>
+ <tr>
+ <td>20</td>
+ <td>VT_I8</td>
+ <td>[T] [P]</td>
+ <td>signed 64-bit int</td>
+ </tr>
+ <tr>
+ <td>21</td>
+ <td>VT_UI8</td>
+ <td>[T] [P]</td>
+ <td>unsigned 64-bit int</td>
+ </tr>
+ <tr>
+ <td>22</td>
+ <td>VT_INT</td>
+ <td>[T]</td>
+ <td>signed machine int</td>
+ </tr>
+ <tr>
+ <td>23</td>
+ <td>VT_UINT</td>
+ <td>[T]</td>
+ <td>unsigned machine int</td>
+ </tr>
+ <tr>
+ <td>24</td>
+ <td>VT_VOID</td>
+ <td>[T]</td>
+ <td>C style void</td>
+ </tr>
+ <tr>
+ <td>25</td>
+ <td>VT_HRESULT</td>
+ <td>[T]</td>
+ <td>Standard return type</td>
+ </tr>
+ <tr>
+ <td>26</td>
+ <td>VT_PTR</td>
+ <td>[T]</td>
+ <td>pointer type</td>
+ </tr>
+ <tr>
+ <td>27</td>
+ <td>VT_SAFEARRAY</td>
+ <td>[T]</td>
+ <td>(use VT_ARRAY in VARIANT)</td>
+ </tr>
+ <tr>
+ <td>28</td>
+ <td>VT_CARRAY</td>
+ <td>[T]</td>
+ <td>C style array</td>
+ </tr>
+ <tr>
+ <td>29</td>
+ <td>VT_USERDEFINED</td>
+ <td>[T]</td>
+ <td>user defined type</td>
+ </tr>
+ <tr>
+ <td>30</td>
+ <td>VT_LPSTR</td>
+ <td>[T] [P]</td>
+ <td>null terminated string</td>
+ </tr>
+ <tr>
+ <td>31</td>
+ <td>VT_LPWSTR</td>
+ <td>[T] [P]</td>
+ <td>wide null terminated string</td>
+ </tr>
+ <tr>
+ <td>64</td>
+ <td>VT_FILETIME</td>
+ <td>[P]</td>
+ <td>FILETIME</td>
+ </tr>
+ <tr>
+ <td>65</td>
+ <td>VT_BLOB</td>
+ <td>[P]</td>
+ <td>Length prefixed bytes</td>
+ </tr>
+ <tr>
+ <td>66</td>
+ <td>VT_STREAM</td>
+ <td>[P]</td>
+ <td>Name of the stream follows</td>
+ </tr>
+ <tr>
+ <td>67</td>
+ <td>VT_STORAGE</td>
+ <td>[P]</td>
+ <td>Name of the storage follows</td>
+ </tr>
+ <tr>
+ <td>68</td>
+ <td>VT_STREAMED_OBJECT</td>
+ <td>[P]</td>
+ <td>Stream contains an object</td>
+ </tr>
+ <tr>
+ <td>69</td>
+ <td>VT_STORED_OBJECT</td>
+ <td>[P]</td>
+ <td>Storage contains an object</td>
+ </tr>
+ <tr>
+ <td>70</td>
+ <td>VT_BLOB_OBJECT</td>
+ <td>[P]</td>
+ <td>Blob contains an object</td>
+ </tr>
+ <tr>
+ <td>71</td>
+ <td>VT_CF</td>
+ <td>[P]</td>
+ <td>Clipboard format</td>
+ </tr>
+ <tr>
+ <td>72</td>
+ <td>VT_CLSID</td>
+ <td>[P]</td>
+ <td>A Class ID</td>
+ </tr>
+ <tr>
+ <td>0x1000</td>
+ <td>VT_VECTOR</td>
+ <td>[P]</td>
+ <td>simple counted array</td>
+ </tr>
+ <tr>
+ <td>0x2000</td>
+ <td>VT_ARRAY</td>
+ <td>[V]</td>
+ <td>SAFEARRAY*</td>
+ </tr>
+ <tr>
+ <td>0x4000</td>
+ <td>VT_BYREF</td>
+ <td>[V]</td>
+ <td>void* for local use</td>
+ </tr>
+ <tr>
+ <td>0x8000</td>
+ <td>VT_RESERVED</td>
+ <td><br/></td>
+ <td><br/></td>
+ </tr>
+ <tr>
+ <td>0xFFFF</td>
+ <td>VT_ILLEGAL</td>
+ <td><br/></td>
+ <td><br/></td>
+ </tr>
+ <tr>
+ <td>0xFFF</td>
+ <td>VT_ILLEGALMASKED</td>
+ <td><br/></td>
+ <td><br/></td>
+ </tr>
+ <tr>
+ <td>0xFFF</td>
+ <td>VT_TYPEMASK</td>
+ <td><br/></td>
+ <td><br/></td>
+ </tr>
+ </table>
+ </section>
+
+
+
+ <section>
+ <title>The Dictionary</title>
+
+ <p>What a dictionary is good for is explained in the <link
+ href="how-to.html">HPSF HOW-TO</link>. This chapter explains how it is
+ organized internally.</p>
+
+ <p>The dictionary has a simple header consisting of a single UInt value. It
+ tells how many entries the dictionary comprises:</p>
+
+ <table>
+ <tr>
+ <th>Name</th>
+ <th>Data type</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>nrEntries</td>
+ <th>UInt</th>
+ <td>Number of dictionary entries</td>
+ </tr>
+ </table>
+
+ <p>The dictionary entries follow the header. Each one looks like this:</p>
+
+ <table>
+ <tr>
+ <th>Name</th>
+ <td>Data type</td>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>key</td>
+ <td>UInt</td>
+ <td>The unique number of this property, i.e. the PID</td>
+ </tr>
+ <tr>
+ <td>length</td>
+ <td>UInt</td>
+ <td>The length of the property name associated with the key</td>
+ </tr>
+ <tr>
+ <td>value</td>
+ <td>String</td>
+ <td>The property's name, terminated with a 0x00 character</td>
+ </tr>
+ </table>
+
+ <p>The entries are not aligned, i.e. each one follows its predecessor
+ without any gap or fill characters.</p>
+ </section>
+
+
+
+ <section><title>References</title>
+
+ <p>In order to assemble the HPSF description I used information publically
+ available on the Internet only. The references given below have been very
+ helpful. If you have any amendments or corrections, please let us know!
+ Thank you!</p>
+
+ <ol>
+
+ <li>In
+ <link href="http://www.kyler.com/pubs/ddj9894.html"><em>Understanding OLE
+ documents</em></link>, Ken Kyler gives an introduction to OLE2
+ documents and especially to property sets. He names the property names,
+ types, and IDs of the Summary Information and Document Summary
+ Information stream.</li>
+
+ <li>The <link href="http://www.dwam.net/docs/oleref/"><em>ActiveX
+ Programmer's Reference</em></link> at <link
+ href="http://www.dwam.net/docs/oleref/">http://www.dwam.net/docs/oleref/</link>
+ seems a little outdated, but that's what I have found.</li>
+
+ <li>An overview of the <code>VT_</code> types is in
+ <link href="http://www.marin.clara.net/COM/variant_type_definitions.htm"><em>Variant
+ Type Definitions</em></link>.</li>
+
+ <li>What is a <code>FILETIME</code>? The answer can be found
+ under <link
+ href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/filetime_str.asp"></link>, <link href="http://www.vbapi.com/ref/f/filetime.html">http://www.vbapi.com/ref/f/filetime.html</link> or
+ <link href="http://www.cs.rpi.edu/courses/fall01/os/FILETIME.html">http://www.cs.rpi.edu/courses/fall01/os/FILETIME.html</link>.
+ In short: <em>The FILETIME structure holds a date and time associated
+ with a file. The structure identifies a 64-bit integer specifying the
+ number of 100-nanosecond intervals which have passed since January 1,
+ 1601. This 64-bit value is split into the two dwords stored in the
+ structure.</em></li>
+
+ <li>Microsoft provides some public information in the <link
+ href="http://msdn.microsoft.com/library/default.asp">MSDN
+ Library</link>. Use the search function to try to find what you are
+ looking for, e.g. "codepage" or "document summary information" etc.</li>
+
+ <li>This documentation origins from the <link href="http://www.rainer-klute.de/~klute/Software/poibrowser/doc/HPSF-Description.html">HPSF description</link> available at <link href="http://www.rainer-klute.de/~klute/Software/poibrowser/doc/HPSF-Description.html">http://www.rainer-klute.de/~klute/Software/poibrowser/doc/HPSF-Description.html</link>.</li>
+ </ol>
+ </section>
+ </section>
+ </body>
+</document>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
+"../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>HPSF THUMBNAIL HOW-TO</title>
+ <authors>
+ <person name="Drew Varner" email="Drew.Varner@-deleteThis-sc.edu" />
+ </authors>
+ </header>
+ <body>
+ <section><title>The VT_CF Format</title>
+
+ <p>Thumbnail information is stored as a VT_CF, or Thumbnail Variant. The
+ Thumbnail Variant is used to store various types of information in a
+ clipboard. The VT_CF can store information in formats for the Macintosh or
+ Windows clipboard.</p>
+
+ <p>There are many types of data that can be copied to the clipboard, but the
+ only types of information needed for thumbnail manipulation are the image
+ formats.</p>
+
+ <p>The <code>VT_CF</code> structure looks like this:</p>
+
+ <table>
+ <tr>
+ <th>Element:</th>
+ <td>Clipboard Size</td>
+ <td>Clipboard Format Tag</td>
+ <td>Clipboard Data</td>
+ </tr>
+ <tr>
+ <th>Size:</th>
+ <td>32 bit unsigned integer (DWord)</td>
+ <td>32 bit signed integer (DWord)</td>
+ <td>variable length (byte array)</td>
+ </tr>
+ </table>
+
+ <p>The Clipboard Size refers to the size (in bytes) of Clipboard Data
+ (variable size) plus the Clipboard Format (four bytes).</p>
+
+ <p>Clipboard Format Tag has four possible values:</p>
+
+ <table>
+ <tr>
+ <th>Value</th>
+ <th>Identifier</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>-1L</code></td>
+ <td><code>CFTAG_WINDOWS</code></td>
+ <td>a built-in Windows© clipboard format value</td>
+ </tr>
+ <tr>
+ <td><code>-2L</code></td>
+ <td><code>CFTAG_MACINTOSH</code></td>
+ <td>a Macintosh clipboard format value</td>
+ </tr>
+ <tr>
+ <td><code>-3L</code></td>
+ <td><code>CFTAG_FMTID</code></td>
+ <td>a format identifier (FMTID) This is rarely used.</td>
+ </tr>
+ <tr>
+ <td><code>0L</code></td>
+ <td><code>CFTAG_NODATA</code></td>
+ <td>No data This is rarely used.</td>
+ </tr>
+ </table>
+ </section>
+
+
+
+ <section><title>Windows Clipboard Data</title>
+
+ <p>Windows clipboard data has four image formats for thumbnails:</p>
+
+ <table>
+ <tr>
+ <th>Value</th>
+ <th>Identifier</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td><code>CF_METAFILEPICT</code></td>
+ <td>Windows metafile format - recommended</td>
+ </tr>
+ <tr>
+ <td>8</td>
+ <td><code>CF_DIB</code></td>
+ <td>Device Independent Bitmap</td>
+ </tr>
+ <tr>
+ <td>14</td>
+ <td><code>CF_ENHMETAFILE</code></td>
+ <td>Enhanced Windows metafile format</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td><code>CF_BITMAP</code></td>
+ <td>Bitmap - Obsolete - Use <code>CF_DIB</code> instead</td>
+ </tr>
+ </table>
+ </section>
+
+ <section><title>Windows Metafile Format</title>
+
+ <p>The most common format for thumbnails on the Windows platform is the
+ Windows metafile format. The Clipboard places and extra header in front of
+ a the standard Windows Metafile Format data.</p>
+
+ <p>The Clipboard Data byte array looks like this when an image is stored in
+ Windows' Clipboard WMF format.</p>
+
+ <table>
+ <tr>
+ <th>Identifier</th>
+ <td>CF_METAFILEPICT</td>
+ <td>mm</td>
+ <td>width</td>
+ <td>height</td>
+ <td>handle</td>
+ <td>WMF data</td>
+ </tr>
+ <tr>
+ <th>Size</th>
+ <td>32 bit unsigned int</td>
+ <td>16 bit unsigned(?) int</td>
+ <td>16 bit unsigned(?) int</td>
+ <td>16 bit unsigned(?) int</td>
+ <td>16 bit unsigned(?) int</td>
+ <td>byte array - variable length</td>
+ </tr>
+ <tr>
+ <th>Description</th>
+ <td>Clipboard WMF</td>
+ <td>Mapping Mode</td>
+ <td>Image Width</td>
+ <td>Image Height</td>
+ <td>handle to the WMF data array in memory, or 0</td>
+ <td>standard WMF byte stream</td>
+ </tr>
+ </table>
+ </section>
+
+
+ <section><title>Device Independent Bitmap</title>
+ <p><strong>FIXME:</strong> Describe the Device Independent Bitmap
+ format!</p>
+ </section>
+
+
+
+ <section><title>Macintosh Clipboard Data</title>
+ <p><strong>FIXME:</strong> Describe the Macintosh clipboard formats!</p>
+ </section>
+
+ </body>
+</document>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>To Do</title>
+ <authors>
+ <person name="Rainer Klute" email="klute@rainer-klute.de"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>To Do</title>
+
+ <p>The following functionalities should be added to HPFS:</p>
+
+ <ol>
+ <li>
+ Improve writing support! We need convenience classes and methods for
+ easily writing summary information streams and document summary
+ information streams.
+ </li>
+ <li>
+ Add resource bundles to
+ <code>org.apache.poi.hpsf.wellknown</code> to ease
+ localizations. This would be useful for mapping standard property IDs to
+ localized strings. Example: The property ID 4 could be mapped to "Author"
+ in English or "Verfasser" in German.
+ </li>
+ <li>
+ Implement reading functionality for those property types that are not
+ yet supported. HPSF should return proper Java types instead of just byte
+ arrays.
+ </li>
+ <li>
+ Add WMF to <code>java.awt.Image</code> example code in the <link
+ href="thumbnails.html">Thumbnail HOW-TO</link>.
+ </li>
+ </ol>
+ </section>
+ </body>
+</document>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="HSMF"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="HSMF">
+ <menu-item label="Overview" href="index.html"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HSMF - Java API To Access Microsoft Outlook MSG Files</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick at apache dot org"/>
+ <person name="Travis Ferguson" email="uniformstupidity at gmail dot com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section>
+ <title>Overview</title>
+
+ <p>HSMF is the POI Project's pure Java implementation of the Outlook MSG format.</p>
+ <p>At this time, it provides low-level read access to all of the file, along
+ with a user-facing way to get at the common textual content of MSG files.
+ to all</p>
+ <p>There is an example MSG textual renderer, which shows how to access the
+ common parts such as sender, subject, message body and examples. This is
+ in the
+ <link href="http://svn.apache.org/viewcvs.cgi/poi/trunk/src/examples/src/org/apache/poi/hsmf/examples/">HSMF examples area</link>
+ of SVN. You may also wish to look at the unit tests for more use guides.</p>
+
+ <note>
+ This code currently lives the
+ <link href="http://svn.apache.org/viewcvs.cgi/poi/trunk/src/scratchpad/">scratchpad area</link>
+ of the POI SVN repository.
+ Ensure that you have the scratchpad jar or the scratchpad
+ build area in your classpath before experimenting with this code.
+ </note>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+<book software="POI Project" title="HWPF" copyright="@year@ POI Project">
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+ <menu label="HWPF">
+ <menu-item label="Overview" href="index.html"/>
+ <menu-item label="Quick Guide" href="quick-guide.html"/>
+ <menu-item label="HWPF Format" href="docoverview.html"/>
+ <menu-item label="HWPF Project plan" href="projectplan.html"/>
+ </menu>
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - HWPF - Java API to Handle Microsoft Word Files</title>
+ <subtitle>Word File Format</subtitle>
+ <authors>
+ <person name="S. Ryan Ackley" email="sackley@cfl.rr.com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>The Word 97 File Format in semi-plain English</title>
+
+ <p>The purpose of this document is to give a brief high level overview of the
+ HWPF document format. This document does not go into in-depth technical
+ detail and is only meant as a supplement to the Microsoft Word 97-2007
+ Binary File Format freely available from
+ <link href="http://www.microsoft.com/interop/docs/officebinaryformats.mspx">Microsoft</link>.</p>
+ <p>The OLE file format is not discussed in this document. It is assumed that
+ the reader has a working knowledge of the POIFS API. </p>
+
+ <section><title>Word file structure</title>
+ <p>A Word file is made up of the document text and data structures
+ containing formatting information about the text. Of course, this is a
+ very simplified illustration. There are fields and macros and other
+ things that have not been considered. At this stage, HWPF is mainly
+ concerned with formatted text.</p>
+ </section>
+ <section><title>Reading Word files</title>
+ <p>The entry point for HWPF's reading of a Word file is the File Information
+ Block (FIB). This structure is the entry point for the locations and size
+ of a document's text and data structures. The FIB is located at the
+ beginning of the main stream.</p>
+ <section><title>Text</title>
+ <p>The document's text is also located in the main stream. Its starting
+ location is given as FIB.fcMin and its length is given in bytes by
+ FIB.ccpText. These two values are not very useful in getting the text
+ because of unicode. There may be unicode text intermingled with ASCII
+ text. That brings us to the piece table.</p>
+ <p>The piece table is used to divide the text into non-unicode and unicode
+ pieces. The size and offset are given in FIB.fcClx and FIB.lcbClx
+ respectively. The piece table may contain Property Modifiers (prm).
+ These are for complex(fast-saved) files and are skipped. Each text piece
+ contains offsets in the main stream that contain text for that piece.
+ If the piece uses unicode, the file offset is masked with a certain bit.
+ Then you have to unmask the bit and divide by 2 to get the real file
+ offset. </p>
+ </section>
+ <section><title>Text Formatting</title>
+ <section><title>Stylesheet</title>
+ <p>All text formatting is based on styles contained in the StyleSheet.
+ The StyleSheet is a data structure containing among other things, style
+ descriptions. Each style description can contain a paragraph style and
+ a character style or simply a character style. Each style description
+ is stored in a compressed version on file. Basically these are deltas
+ from another style.</p>
+ <p>Eventually, you have to chain back to the nil style which is an
+ imaginary style with certain implied values.</p>
+ </section>
+ <section><title>Paragraph and Character styles</title>
+ <p>Paragraph and Character formatting properties for a document's text are
+ stored on file as deltas from some base style in the Stylesheet. The
+ deltas are used to create a complete uncompressed style in memory.</p>
+ <p>Uncompressed paragraph styles are represented by the Pargraph
+ Properties(PAP) data structure. Uncompressed character styles are
+ represented by the Character Properties(CHP) data structure. The styles
+ for the document text are stored in compressed format in the
+ corresponding Formatted Disk Pages (FKP). A compressed PAP is referred
+ to as a PAPX and a compressed CHP is a CHPX. The FKP locations are
+ stored in the bin table. There are seperate bin tables for CHPXs and
+ PAPXs. The bin tables' locations and sizes are stored in the FIB.</p>
+ <p>A FKP is a 512 byte OLE page. It contains the offsets of the beginning
+ and end of each paragraph/character run in the main stream and the
+ compressed properties for that interval. The compessed PAPX is based on
+ its base style in the StyleSheet. The compressed CHPX is based on the
+ enclosing paragraph's base style in the Stylesheet.</p>
+ </section>
+ <section><title>Uncompressing styles and other data structures</title>
+ <p>All compressed properties(CHPX, PAPX, SEPX) contain a grpprl. A grpprl
+ is an array of sprms. A sprm defines a delta from some base property.
+ There is a table of possible sprms in the Word 97 spec. Each sprm is a
+ two byte operand followed by a parameter. The parameter size depends on
+ the sprm. Each sprm describes an operation that should be performed on
+ the base style. After every sprm in the grpprl is performed on the base
+ style you will have the style for the paragraph, character run,
+ section, etc.</p>
+ </section>
+ </section>
+ </section>
+ </section>
+ </body>
+</document>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - HWPF - Java API to Handle Microsoft Word Files</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ <person name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person name="Ryan Ackley" email="sackley@apache.org"/>
+ <person name="Rainer Klute" email="klute@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Overview</title>
+
+ <p>HWPF is the name of our port of the Microsoft Word 97(-2007) file format
+ to pure Java. It also provides limited read only support for the older
+ Word 6 and Word 95 file formats.</p>
+
+ <p>The partner to HWPF for the new Word 2007 .docx format is <em>XWPF</em>.
+ Whilst HWPF and XWPF provide similar features, there is not a common
+ interface across the two of them at this time.</p>
+
+ <p>HWPF is still in early development. It is in the <link
+ href="http://svn.apache.org/viewcvs.cgi/poi/trunk/src/scratchpad/">
+ scratchpad section of the SVN.</link> You will need to ensure you
+ either have a recent SVN checkout, or a recent SVN nightly build
+ (including the scratchpad jar!)</p>
+
+ <p>
+ Source code in the
+ <em>org.apache.poi.hdf</em>
+ tree is the old legacy code. Source in the
+ <em>org.apache.poi.hwpf.model</em>
+ tree is the old legacy code refactored into an new object model. Those packages contains
+ Java representation of internal Word format structure. This code is "internal", it shall not
+ be used by your code. Because of backward-compatibility some API still has references to
+ those packages. They are subject to be deprecated and removed. Code from
+ <em>org.apache.poi.hwpf.usermodel</em>
+ package is actual public and user-friendly (as much as possible) API to access document
+ parts. Source code in the
+ <em>org.apache.poi.hwpf.extractor</em>
+ tree is a wrapper of this to facilitate easy extraction of interesting things (eg the Text),
+ and
+ <em>org.apache.poi.hwpf.converter</em>
+ package contains Word-to-HTML and Word-to-FO converters (latest can be used to generate PDF
+ from Word files when using with
+ <link href="http://xmlgraphics.apache.org/fop/">Apache FOP</link>
+ ). Also there is a small file-structure-dumping utility in
+ <em>org.apache.poi.hwpf.dev</em>
+ package, primally for developing purposes.
+ </p>
+
+ <p>
+ The main entry point to HWPF is HWPFDocument. Currently it has a lot of references both to
+ internal interfaces (
+ <em>org.apache.poi.hwpf.model</em>
+ package) and public API (
+ <em>org.apache.poi.hwpf.usermodel</em>
+ ) package. It is possible that it will be split into two different interfaces (like WordFile
+ and WordDocument) in later versions.
+ </p>
+
+ <p>Word document can be considered as very long single text buffer. HWPF API provides "pointers"
+ to document parts, like sections, paragraphs and character runs. Usually user will iterates
+ over main document part sections, paragraphs from sections and character runs from
+ paragraph. Each such interface is a pointer to document text subrange along with additional
+ properties (and they all extends same Range parent class). There is additional Range
+ implementations like Table, TableRow, TableCell, etc. Some structures like Bookmark or Field
+ can also provide subranges pointers.
+ </p>
+
+ <p>Changing file content usually requires a lot of synchronized changes in those structures like
+ updating property boundaries, position handlers, etc. Because of that HWPF API shall be
+ considered as not thread safe. In addition, there is a "one pointer" rule for changing
+ content. It means you should not use two different Range instances at one time. More
+ precisely, if you are changing file content using some range pointer, all other range
+ pointers except parents' ones become invalid. For example if you obtain overall range (1),
+ paragraph range (2) from overall range and character run range (3) from paragraph range and
+ change text of paragraph, character run range is now invalid and should not be used, but
+ overall range pointer still valid. Each time you obtaining range (pointer) new instance is
+ created. It means if you obtained two range pointers and changed document text using first
+ range pointer, second one became invalid.
+ </p>
+
+ </section>
+ <section>
+ <title>XWPF Patches Required!</title>
+
+ <p>At the moment, XWPF covers many common use cases for reading and writing
+ .docx files. Whilst this is a great thing, it does mean that XWPF does
+ everything that the current POI committers need it to do, and so none of
+ the committers are actively adding new features.</p>
+
+ <p>If you come across a feature in XWPF that you need, and isn't currently
+ there, please do send in a patch to add the extra functionality! More details
+ on contributing patches are available on the <link
+ href="../guidelines.html">"Contribution to POI" page</link>.</p>
+ </section>
+
+ <section>
+ <title>HWPF Pointman Needed!</title>
+
+ <p>At the moment we unfortunately do not have someone taking care for HWPF
+ and fostering its development. What we need is someone to stand up, take
+ this thing under his hood as his baby and push it forward. Ryan Ackley,
+ who put a lot of effort into HWPF, is no longer on board, so HWPF is an
+ orphan child waiting to be adopted.</p>
+
+ <p>If <strong>you</strong> are interested in becoming the new HWPF
+ pointman, you should look into the Microsoft Word internals. A good
+ starting point seems to be Ryan Ackley's <link
+ href="docoverview.html">overview</link>. Full details on the word format
+ is available from
+ <link href="http://www.microsoft.com/interop/docs/OfficeBinaryFormats.mspx">Microsoft</link>,
+ but the documentation can be a little hard to get into at first... Try reading the
+ <link href="docoverview.html">overview</link> first, and looking at the existing
+ code, then finally look up the documentation for specific missing features.</p>
+
+ <p>As a first step you should familiarize yourself with the source code,
+ examples, test cases, and the HWPF patches available at <link
+ href="http://issues.apache.org/">Bugzilla</link> (if any). Then you
+ should compile an overview of</p>
+
+ <ul>
+ <li>the current HWPF status,</li>
+ <li>the patches in <link
+ href="http://issues.apache.org/bugzilla/">Bugzilla</link> to be checked
+ in (and those that should better be ditched),</li>
+ <li>the available test cases and the test cases still to be written,</li>
+ <li>the available documentation and the docs to be written,</li>
+ <li>anything else that seems reasonable</li>
+ </ul>
+
+ <p>When you start coding, you will not yet have write access to the
+ SVN repository. Please submit your patches to <link
+ href="http://issues.apache.org/">Bugzilla</link> and nag <link
+ href="mailto:dev@poi.apache.org">the dev list</link> until someone commits
+ them. Besides the actual checking in of HWPF patches, current POI
+ committers will also do some minor reviews now and then of your source code
+ patches, test cases and documentation to help ensure software quality. But
+ most of the time you will be on your own. However, anyone offering useful
+ contributions over a period of time will be offered committership!</p>
+
+ <p>Please do not forget to write <link
+ href="http://www.junit.org/">JUnit</link> test cases and documentation!
+ We won't accept code that doesn't come with test cases. And please
+ consider that other contributors should be able to understand your source
+ code easily. If you need any help getting started with JUnit test cases
+ for HWPF, please ask on the developers' mailing list! If you show that you
+ are prepared to stick at it you will most likely be given SVN commit
+ access. See <link href="../guidelines.html">"Contribution to POI" page</link>
+ for more details and help getting started.</p>
+
+ <p>Of course we will help you as best as we can. However, presently there
+ is no committer who is really familiar with the Word format, so you'll be
+ mostly on your own. We are looking forward for you and your contributions!
+ Honor and glory of becoming a POI committer are waiting!</p>
+ </section>
+ </body>
+</document>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!-- edited with XMLSPY v5 rel. 4 U (http://www.xmlspy.com) by Ryan Ackley (Myself) -->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+<document>
+ <header>
+ <title>Apache POI - HWPF - Java API to Handle Microsoft Word Files</title>
+ <subtitle>Project Plan</subtitle>
+ <authors>
+ <person name="Ryan Ackley" email="sackley@apache.org"/>
+ </authors>
+ </header>
+ <body>
+ <p>HWPF Milestones</p>
+ <table>
+ <tr>
+ <th>
+ Milestones
+ </th>
+ <th>
+ Target Date
+ </th>
+ <th>
+ Owner
+ </th>
+ </tr>
+ <tr>
+ <td>
+ Read in a Word document
+with minimum formatting
+(no lists, tables, footnotes,
+endnotes, headers, footers)
+and write it back out with the
+result viewable in Word
+97/2000
+ </td>
+ <td>
+ 07/11/2003
+ </td>
+ <td>
+ Ryan
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Add support for Lists and
+Tables
+ </td>
+ <td>
+ 8/15/2003
+ </td>
+ <td>
+  
+ </td>
+ </tr>
+ <tr>
+ <td>
+ HWPF 1.0-alpha release with
+documentation and examples
+ </td>
+ <td>
+ 8/18/2003
+ </td>
+ <td>
+ Praveen/Ryan
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Add support for Headers,
+Footers, endnotes, and
+footnotes
+ </td>
+ <td>
+ 8/31/2003
+ </td>
+ <td>
+ ?
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Add support for forms and
+mail merge
+ </td>
+ <td>
+ September/October 2003
+ </td>
+ <td>
+ ?
+ </td>
+ </tr>
+ </table>
+ <p>HWPF Task Lists</p>
+ <p>Read in a Word document with minimum formatting (no lists, tables, footnotes,
+endnotes, headers, footers) and write it back out with the result viewable in Word 97/2000</p>
+ <table>
+ <tr>
+ <th>
+ Task
+ </th>
+ <th>
+ Target Date
+ </th>
+ <th>
+ Owner
+ </th>
+ </tr>
+ <tr>
+ <td>
+ Create classes to read and
+write low level data
+structures with test cases
+ </td>
+ <td>
+ 7/10/2003
+ </td>
+ <td>
+ Ryan
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Create classes to read and
+write FontTable and Font
+names with test case
+ </td>
+ <td>
+ 7/10/2003
+ </td>
+ <td>
+ Praveen
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Final test
+ </td>
+ <td>
+ 7/11/2003
+ </td>
+ <td>
+ Ryan
+ </td>
+ </tr>
+ </table>
+ <p>Develop user friendly API so it is fun and easy to read and write word documents
+with java.</p>
+ <table>
+ <tr>
+ <th>
+ Task
+ </th>
+ <th>
+ Target Date
+ </th>
+ <th>
+ Owner
+ </th>
+ </tr>
+ <tr>
+ <td>
+ Develop a way for SPRMS to
+be compressed and
+uncompressed
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Override CHPAbstractType
+with a concrete class that
+exposes attributes with
+human readable names
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Override PAPAbstractType
+with a concrete class that
+exposes attributes with
+human readable names
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Override SEPAbstractType
+with a concrete class that
+exposes attributes with
+human readable names
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Override DOPAbstractType
+with a concrete class that
+exposes attributes with
+human readable names
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Override TAPAbstractType
+with a concrete class that
+exposes attributes with
+human readable names
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Override TCAbstractType
+with a concrete class that
+exposes attributes with
+human readable names
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Develop a VerifyIntegrity
+class for testing so it is easy
+to determine if a Word
+Document is well-formed.
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Develop general intuitive
+API to tie everything together
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ </table>
+ <p>Add support for lists and tables</p>
+ <table>
+ <tr>
+ <th>
+ Task
+ </th>
+ <th>
+ Target Date
+ </th>
+ <th>
+ Owner
+ </th>
+ </tr>
+ <tr>
+ <td>
+ Add data structures for
+reading and writing list data
+with test cases.
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Add data structures for
+reading and writing tables
+with test cases.
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ </table>
+ <p>HWPF 1.0-alpha release with documentation and examples</p>
+ <table>
+ <tr>
+ <th>
+ Task
+ </th>
+ <th>
+ Target Date
+ </th>
+ <th>
+ Owner
+ </th>
+ </tr>
+ <tr>
+ <td>
+ Document the user model
+API
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Document the low level
+classes
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Come up with detailed How-To’s
+ </td>
+ <td>
+
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ </table>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HWPF - A Quick Guide</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick at torchbox dot com"/>
+ </authors>
+ </header>
+
+ <body>
+ <p>HWPF is still in early development. It is in the <link
+ href="http://svn.apache.org/viewcvs.cgi/poi/trunk/src/scratchpad/">
+ scratchpad section of the SVN.</link> You will need to ensure you
+ either have a recent SVN checkout, or a recent SVN nightly build
+ (including the scratchpad jar!)</p>
+
+ <section><title>Basic Text Extraction</title>
+ <p>For basic text extraction, make use of
+<code>org.apache.poi.hwpf.extractor.WordExtractor</code>. It accepts an input
+stream or a <code>HWPFDocument</code>. The <code>getText()</code>
+method can be used to
+get the text from all the paragraphs, or <code>getParagraphText()</code>
+can be used to fetch the text from each paragraph in turn. The other
+option is <code>getTextFromPieces()</code>, which is very fast, but
+tends to return things that aren't text from the page. YMMV.
+ </p>
+ </section>
+
+ <section><title>Specific Text Extraction</title>
+ <p>To get specific bits of text, first create a
+<code>org.apache.poi.hwpf.HWPFDocument</code>. Fetch the range
+with <code>getRange()</code>, then get paragraphs from that. You
+can then get text and other properties.
+ </p>
+ </section>
+
+ <section><title>Headers and Footers</title>
+ <p>To get at the headers and footers of a word document, first create a
+<code>org.apache.poi.hwpf.HWPFDocument</code>. Next, you need to create a
+<code>org.apache.poi.hwpf.usermodel.HeaderStores</code>, passing it your
+HWPFDocument. Finally, the HeaderStores gives you access to the headers and
+footers, including first / even / odd page ones if defined in your
+document. Additionally, HeaderStores provides a method for removing
+any macros in the text, which is helpful as many headers and footers
+do end up with macros in them.</p>
+ </section>
+
+ <section><title>Changing Text</title>
+ <p>It is possible to change the text via
+ <code>insertBefore()</code> and <code>insertAfter()</code>
+ on a <code>Range</code> object (either a <code>Range</code>,
+ <code>Paragraph</code> or <code>CharacterRun</code>).
+ It is also possible to delete a <code>Range</code>.
+ This code will work in many, but not all cases, and patches to
+ improve it are gratefully received!
+ </p>
+ </section>
+
+ <section><title>Further Examples</title>
+ <p>For now, the best source of additional examples is in the unit
+ tests. <link
+ href="http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/">
+ Browse the HWPF unit tests.</link>
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - the Java API for Microsoft Documents</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="GJS" name="Glen Stampoultzis" email="user@poi.apache.org"/>
+ <person id="AS" name="Avik Sengupta" email="user@poi.apache.org"/>
+ <person id="RK" name="Rainer Klute" email="klute@apache.org"/>
+ <person id="DF" name="David Fisher" email="dfisher@jmlafferty.com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Project News</title>
+ <section><title>19 September 2013 - POI 3.10 Beta 2 available</title>
+ <p>The Apache POI team is pleased to announce the release of 3.10 Beta 2. This primarily
+ includes a large number of bug fixes, and some enhancements (especially in the number of
+ Formula Functions supported).
+ </p>
+ <p>A full list of changes is available in the <link href="changes.html">change log</link>.
+ People interested should also follow the <link href="mailinglists.html">dev mailing list</link> to track further progress.</p>
+ <p>See the <link href="download.html">downloads</link> page for more details.</p>
+ </section>
+ <section><title>3 December 2012 - POI 3.9 available</title>
+ <p>The Apache POI team is pleased to announce the release of 3.9. This includes a large number of bug fixes, and some
+ enhancements (especially text extraction). See the
+ <link href="http://www.apache.org/dist/poi/release/RELEASE-NOTES.txt">release notes</link> for more details.
+ </p>
+ <p>A full list of changes is available in the <link href="changes.html">change log</link>.
+ People interested should also follow the <link href="mailinglists.html">dev mailing list</link> to track further progress.</p>
+ <p>See the <link href="download.html">downloads</link> page for more details.</p>
+ </section>
+ <section><title>28 August 2011 - The Apache POI project is celebrating its 10th anniversary</title>
+ <p>
+ The Apache POI project is celebrating its 10th anniversary. On the 28th of August 2001, the first 0.1 alpha version of POI was released.
+ <link href="https://blogs.apache.org/foundation/entry/the_apache_software_foundation_announces14">Read more...</link></p>
+ </section>
+ </section>
+
+ <section><title>Mission Statement</title>
+ <p>
+ The Apache POI Project's mission is to create and maintain Java APIs for manipulating various file formats
+ based upon the Office Open XML standards (OOXML) and Microsoft's OLE 2 Compound Document format (OLE2).
+ In short, you can read and write MS Excel files using Java.
+ In addition, you can read and write MS Word and MS PowerPoint files using Java. Apache POI is your Java Excel
+ solution (for Excel 97-2008). We have a complete API for porting other OOXML and OLE2 formats and welcome others to participate.
+ </p>
+ <p>
+ OLE2 files include most Microsoft Office files such as XLS, DOC, and PPT as well as MFC serialization API based file formats.
+ The project provides APIs for the <link href="poifs/index.html">OLE2 Filesystem (POIFS)</link> and
+ <link href="hpsf/index.html">OLE2 Document Properties (HPSF)</link>.
+ </p>
+ <p>
+ Office OpenXML Format is the new standards based XML file format found in Microsoft Office 2007 and 2008.
+ This includes XLSX, DOCX and PPTX. The project provides a low level API to support the Open Packaging Conventions
+ using <link href="oxml4j/index.html">openxml4j</link>.
+ </p>
+ <p>
+ For each MS Office application there exists a component module that attempts to provide a common high level Java api to both OLE2 and OOXML
+ document formats. This is most developed for <link href="spreadsheet/index.html">Excel workbooks (SS=HSSF+XSSF)</link>.
+ Work is progressing for <link href="hwpf/index.html">Word documents (HWPF+XWPF)</link> and
+ <link href="slideshow/index.html">PowerPoint presentations (HSLF+XSLF)</link>.
+ </p>
+ <p>
+ The project has recently added support for <link href="hsmf/index.html">Outlook (HSMF)</link>. Microsoft opened the specifications
+ to this format in October 2007. We would welcome contributions.
+ </p>
+ <p>
+ There are also projects for
+ <link href="hdgf/index.html">Visio (HDGF)</link>,
+ <link href="hmef/index.html">TNEF (HMEF)</link>,
+ and <link href="hpbf/index.html">Publisher (HPBF)</link>.
+ </p>
+ <p>
+ As a general policy we collaborate as much as possible with other projects to
+ provide this functionality. Examples include: <link href="http://xml.apache.org/cocoon">Cocoon</link> for
+ which there are serializers for HSSF;
+ <link href="http://www.openoffice.org">Open Office.org</link> with whom we collaborate in documenting the
+ XLS format; and <link href="http://tika.apache.org/">Tika</link> /
+ <link href="http://lucene.apache.org/">Lucene</link>,
+ for which we provide format interpretors. When practical, we donate
+ components directly to those projects for POI-enabling them.
+ </p>
+ <section><title>Why should I use Apache POI?</title>
+ <p>
+ A major use of the Apache POI api is for <link href="text-extraction.html">Text Extraction</link> applications
+ such as web spiders, index builders, and content management systems.
+ </p>
+ <p>
+ So why should you use POIFS, HSSF or XSSF?
+ </p>
+ <p>
+ You'd use POIFS if you had a document written in OLE 2 Compound Document Format, probably written using
+ MFC, that you needed to read in Java. Alternatively, you'd use POIFS to write OLE 2 Compound Document Format
+ if you needed to inter-operate with software running on the Windows platform. We are not just bragging when
+ we say that POIFS is the most complete and correct implementation of this file format to date!
+ </p>
+ <p>
+ You'd use HSSF if you needed to read or write an Excel file using Java (XLS). You'd use
+ XSSF if you need to read or write an OOXML Excel file using Java (XLSX). The combined
+ SS interface allows you to easily read and write all kinds of Excel files (XLS and XLSX)
+ using Java.
+ </p>
+ </section>
+ <section><title>Components</title>
+ <p>
+ The Apache POI Project provides several component modules some of which may not be of interest to you.
+ Use the information on our <link href="overview.html#components">Components</link> page to determine which
+ jar files to include in your classpath.
+ </p>
+ </section>
+ </section>
+
+ <section><title>Contributing </title>
+ <p>
+ So you'd like to contribute to the project? Great! We need enthusiastic, hard-working, talented folks to help
+ us on the project. So if you're motivated, ready, and have the time time download the source from the
+ <link href="subversion.html">Subversion Repository</link>, <link href="howtobuild.html">build the code</link>,
+ join the <link href="mailinglists.html">mailing lists</link> and we'll be happy to help you get started on the project!
+ </p>
+ <p>
+ Please read our <link href="guidelines.html">Contribution Guidelines</link>. When your contribution is ready
+ submit a patch to our <link href="https://issues.apache.org/bugzilla/buglist.cgi?product=POI">Bug Database</link>.
+ </p>
+
+
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Legal Stuff</title>
+ <authors>
+ <person id="TK" name="Tetsuya Kitahata" email="tetsuya@apache.org"/>
+ <person id="DF" name="David Fisher" email="dfisher@jmlafferty.com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>License and Notice</title>
+<p>
+ Apache POI releases are available under the <link href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0.</link>
+ See the NOTICE file contained in each release artifact for applicable copyright attribution notices. Release artifacts are available
+ from the <link href="download.html">Download</link> page.
+</p>
+</section>
+ <section><title>Copyrights and Trademarks</title>
+<p>
+All material on this website is Copyright © 2002-2010, The Apache
+Software Foundation.
+</p>
+<p>
+Apache POI, POI, Apache, the Apache feather logo, and the Apache POI
+project logo are trademarks of The Apache Software Foundation.
+</p>
+<p>
+Sun, Sun Microsystems, Solaris, Java, JavaServer Web Development Kit,
+and JavaServer Pages are trademarks or registered trademarks of Sun
+Microsystems, Inc. UNIX is a registered trademark in the United States
+and other countries, exclusively licensed through 'The Open Group'.
+Microsoft, Windows, WindowsNT, Excel, Word, PowerPoint, Viso, Publisher, Outlook,
+and Win32 are registered trademarks of Microsoft Corporation.
+Linux is a registered trademark of Linus Torvalds.
+All other product names mentioned herein and throughout the entire
+web site are trademarks of their respective owners.
+</p>
+ <section><title>Cryptography Notice</title>
+ <p>
+ This distribution includes cryptographic software. The country in
+ which you currently reside may have restrictions on the import,
+ possession, use, and/or re-export to another country, of
+ encryption software. BEFORE using any encryption software, please
+ check your country's laws, regulations and policies concerning the
+ import, possession, or use, and re-export of encryption software, to
+ see if this is permitted. See
+ <link href="http://www.wassenaar.org/">http://www.wassenaar.org/</link>
+ for more information.
+ </p>
+
+ <p>
+ The U.S. Government Department of Commerce, Bureau of Industry and
+ Security (BIS), has classified this software as Export Commodity
+ Control Number (ECCN) 5D002.C.1, which includes information security
+ software using or performing cryptographic functions with asymmetric
+ algorithms. The form and manner of this Apache Software Foundation
+ distribution makes it eligible for export under the License Exception
+ ENC Technology Software Unrestricted (TSU) exception (see the BIS
+ Export Administration Regulations, Section 740.13) for both object
+ code and source code.
+ </p>
+
+ <p>
+ The cryptographic software used is from <em>java.security</em> and
+ <em>javax.crypto</em> and is used when processing encrypted and
+ protected documents.
+ </p>
+ </section>
+</section>
+</body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Mailing Lists</title>
+ <authors>
+ <person id="NB" name="Nick Burch" email="nick@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Mailing Lists - Guidelines</title>
+ <p>
+ <strong>Before subscribing to any of the mailing lists, please make
+ sure that you have read and understand the following
+ guidelines:</strong>
+ </p>
+ <ul>
+ <li><link href="http://www.apache.org/foundation/mailinglists.html">ASF guide to Mailing Lists</link></li>
+ <li><link href="http://www.apache.org/dev/contrib-email-tips.html">ASF Tips for email contributors</link></li>
+ <li><link href="http://jakarta.apache.org/site/mail.html">The Jakarta guide to Mailing Lists</link></li>
+ </ul>
+ </section>
+ <section><title>Lists</title>
+ <section><title>The POI User List</title>
+ <p>
+ <strong>Medium Traffic</strong>
+ <link href="mailto:user-subscribe@poi.apache.org">Subscribe</link>
+ <link href="mailto:user-unsubscribe@poi.apache.org">Unsubscribe</link>
+ <link href="http://mail-archives.apache.org/mod_mbox/poi-user/">Archive</link>
+ <link href="http://news.gmane.org/thread.php?group=gmane.comp.jakarta.poi.user">gmane.org</link>
+ </p>
+ <p>
+ This list is for users of POI to ask questions, share knowledge,
+ and discuss issues. POI developers are also expected to be
+ lurking on this list to offer support to users of POI.
+ </p>
+ </section>
+ <section><title>The POI Developer List</title>
+ <p>
+ <strong>Low Traffic</strong>
+ <link href="mailto:dev-subscribe@poi.apache.org">Subscribe</link>
+ <link href="mailto:dev-unsubscribe@poi.apache.org">Unsubscribe</link>
+ <link href="http://mail-archives.apache.org/mod_mbox/poi-dev/">Archive</link>
+ <link href="http://news.gmane.org/gmane.comp.jakarta.poi.devel">gmane.org</link>
+ </p>
+ <p>
+ This is the list where participating developers of the POI
+ project meet and discuss issues, code changes/additions, etc.
+ Subscribers to this list also get notices of each and every
+ code change, build results, testing notices, etc.
+ <strong>Do not send mail to this list with usage questions or
+ configuration problems.</strong>
+ </p>
+ </section>
+ <section><title>The POI General List</title>
+ <p>
+ <strong>Low Traffic</strong>
+ <link href="mailto:general-subscribe@poi.apache.org">Subscribe</link>
+ <link href="mailto:general-unsubscribe@poi.apache.org">Unsubscribe</link>
+ <link href="http://mail-archives.apache.org/mod_mbox/poi-general/">Archive</link>
+ </p>
+ <p>
+ This list exists for general discussions on POI, not specific to
+ code or problems with code. Used for discussion of general matters
+ relating to all of the POI project, such as the website and
+ changes in procedures.
+ </p>
+ </section>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI Mirror Site</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Mirrors</title>
+ <p>
+ These are mirrors of the
+ <link href="http://poi.apache.org/">POI</link> website.
+ If you know of others...report them! :-)
+ </p>
+ </section>
+ <section><title>Austria</title>
+ <ul>
+ <li><link href="http://gd.tuwien.ac.at/infosys/servers/http/apache-jakarta-site/poi/index.html">Austrian Mirror of Jakarta POI</link></li>
+ </ul>
+ </section>
+ <section><title>Korea</title>
+ <ul>
+ <li><link href="http://jakarta.ktech21.co.kr/">Jakarta site partially translated into Korean and Mirrored</link></li>
+ </ul>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - In the News over the world</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="TK" name="Tetsuya Kitahata" email="tetsuya@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>POI in the news</title>
+ <p>
+ These are articles/etc. posted about POI around the web. If you
+ see POI in the news or mentioned at least somewhat prominently
+ on a site (not your homepage that you put the work POI on in
+ order to get us to link you and by the why here is a picture of
+ your wife in kids) then send a patch to the list. In general
+ equal time will be given so please feel free to send inflamatory
+ defamation as well as favorable, technical and factual. Really
+ stupid things won't be mentioned (sorry).
+ </p>
+ </section>
+ <section><title>English</title>
+ <ul>
+ <li>
+ <link href="http://archive.midrange.com/web400/200204/msg00023.html">Discussion about using POI on AS/400s</link>
+ </li>
+ <li>
+ <link href="http://www.somelist.com/mails/23819.html">Discussion from back when we almost had POI as the filter for KOffice if politics and licenses hadn't killed iit</link>
+ </li>
+ <li>
+ <link href="http://www.oreillynet.com/pub/wlg/1552?page=last&x-showcontent=text">Java discussion on O'Reilly Network including discussion about POI</link> - O'Reilly.net
+ </li>
+ <li>
+ <link href="http://www.rollerweblogger.org/page/roller/20020715">Poor Obfuscation Implementation.</link> - Blog of David M. Johnson
+ </li>
+ <li>
+ <link href="http://www.jsurfer.org/article.php?sid=322">
+ POI 1.5-dev-rc2 released </link> - JSurfer
+ </li>
+
+ <li>
+ <link href="http://directory.google.com/Top/Computers/Programming/Languages/Java/Class_Libraries/Data_Formats/Microsoft_Formats/"> Google says we're the most important in our category </link>
+ </li>
+ <li>
+ <link href="http://www.javaworld.com/javaworld/javaqa/2002-05/01-qa-0503-excel3.html">It's POI-fect</link> - Tony Sintes, Javaworld
+ </li>
+ <li>
+ <link href="http://www.need-a-cake.com/categories/cocoonWeblog/2002/03/07.html">
+ Nicola announces POI serialization code
+ </link> - Matthew Langham's Radio Weblog
+ </li>
+ <li>
+ <link href="http://javalobby.org/discussionContext/showThreaded/frm/javalobby?folderId=20&discussionContextId=11523">
+ Jakarta POI 1.4583 Released</link> - JavaLobby
+ </li>
+ <li>
+ <link href="http://javalobby.org/discussionContext/showThreaded/frm/javalobby?discussionContextId=11442&folderId=20">
+ POI project moves to Jakarta (OLE 2 CDF/Excel/Word in
+ pure java)</link> - JavaLobby
+ </li>
+ <li>
+ <link
+ href="http://www.geocities.com/marcoschmidt.geo/java-image-coding.html">
+ List of Java libraries to read and write image and document files
+ </link> Marco Schmidt's homepage (normally we wouldn't
+ feature someone's homepage but its an extensive list of
+ information including "alternatives to POI" (for those
+ of you who are very wealthy). But heck I think I'll
+ bookmark his page for myself since he's like got every
+ piece of info known to man linked or featured on it!
+ </li>
+ <li>
+ <link href="http://radio.weblogs.com/0101350/">
+ The Experiences of an Operator (Måns af Klercker)
+ </link> - radio.weblogs.com
+ </li>
+ <li>
+ <link href="http://dataconv.org/apps_office.html">
+ DATACONV - Data Conversion Tools: Office
+ </link> DATACONV
+ </li>
+ <li>
+ <link href="http://chicago.sourceforge.net/devel/">
+ Chicago Developer Page
+ </link>
+ </li>
+ <li>
+ <link href="http://www.onjava.com/pub/d/1157">
+ POI/POI Serialization Project
+ </link> - Man you know you've hit the bigtime when
+ O'Reilly Likes you.. ;-)
+ </li>
+ <li>
+ <link
+ href="http://www.javaworld.com/netnews/index.shtml">
+ News Around the Net
+ </link> - Java World
+ </li>
+
+ </ul>
+ </section>
+ <section><title>Nederlandstalige (Dutch)</title>
+ <ul>
+ <li>
+ <link
+ href="http://www.ster.be/java/java9.html">
+ Een Excel-werkboek maken vanuit Java - Lieven Smits
+ </link>
+ </li>
+ </ul>
+ </section>
+ <section><title>Deutsch (German)</title>
+ <ul>
+ <li> <link
+ href="http://www.entwickler.com/itr/news/show.php3?id=6132&nodeid=82 ">Apache POI verffentlicht</link> - entwicker.com
+ </li>
+ <li>
+ <link
+ href="http://www.jsp-develop.de/newsletter/10/">
+ Apache Jakarta-Projekt bringt Word und Excel in die Java-Welt </link> - jsp-develop.de (for the misguided who use JSP ;-) )
+ </li>
+ <li>
+ <link
+ href="http://www.entwickler.com/news/2002/02/5718/news.shtml">
+ Neues Apache-Projekt bringt Word- und Excel nach Java
+ </link> - entwickler.com
+ </li>
+ </ul>
+ </section>
+ <section><title>Español (Spanish)</title>
+ <ul>
+ <li>
+ <link href="http://www.javahispano.com/noticias/todas.jsp">
+ OLE2 desde Java nativo
+ </link> - javaHispano
+ </li>
+ <li>
+ <link href="http://p2p.wrox.com/archive/java_espanol/2002-08/3.asp">Spanish discussion about Excel and Java including POI from Wrox forums</link>
+ </li>
+ </ul>
+ </section>
+ <section><title>Français (French)</title>
+ <ul>
+ <li>
+ <link href="http://linuxfr.org/section/D%E9veloppeur,0,1,8,0.html">
+ Excel/OLE accessibles
+ </link> - Da Linux French Page
+ </li>
+ <li>
+ <link href="http://www.sogid.com/javalist/f2002/traiter_word_java.html">Discussion on POI in French</link>
+ </li>
+ </ul>
+ </section>
+ <section><title>Nihongo (Japanese)</title>
+ <ul>
+ <li>
+ <link href="http://drpanda.freezope.org/Memo/docs/jakarta/poi/poi_sample">100% PureJava...</link> - Dr. Panda Portal
+ </li>
+ <li>
+ <link
+ href="http://www.gimlay.org/~andoh/java/javanew.html">
+ What's new with java?
+ </link> - gimlay.org
+ </li>
+ <li><link href="http://taka-2.com/jclass/POI/">Java de Excel</link> - How to use Japanese with POI</li>
+ <li><link href="http://www.tech-arts.co.jp/macosx/webobjects-jp/htdocs/3200/3218.html">Various discussion in Japanese including on POI</link></li>
+ <li><link href="http://muimi.com/j/jakarta/">Japanese resources on Jakarta projects including POI</link></li>
+ <li><link href="http://www.fk.urban.ne.jp/home/kishida/">Kishida's site</link> -- Weekly Forte Lectures -- includes a snip about POI and Japanese.</li>
+
+ </ul>
+ </section>
+ <section><title>Russkii Yazyk (Russian)</title>
+ <ul>
+ <li>
+ <link href="http://www.nestor.minsk.by/kg/kg02/21/kg22108.html">
+ Probably a translation of the Javalobby announcement of 1.5-final
+ </link> -- Computer News (What's New)
+ </li>
+ </ul>
+ </section>
+ <section><title>Hangul (Korean)</title>
+ <ul>
+ <li>
+ <link href="http://www.javabrain.co.kr/AnswerView?questionId=1189&categoryId=8">Various discussion in Korean about Excel output/APIs including POI</link>
+ </li>
+ </ul>
+ </section>
+ <section><title>No freaking idea</title>
+ <p>
+ If you can read one of these languages, send mail to the list
+ telling us what language it is and we'll categorize it!
+ </p>
+ <ul>
+ <li>
+ <link
+ href="http://www.javacentrix.com/index.htm">
+ If I had to guess, I'd say this is Thai, but
+ maybe you actually know</link> - javacentrix.com
+ </li>
+ </ul>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="POI Project News Pages"
+ copyright="@year@ POI Project">
+
+ <menu label="Navigation">
+ <menu-item label="Main" href="../index.html"/>
+ </menu>
+
+ <menu label="News">
+ <menu-item label="Logo Submissions" href="logocontest.html"/>
+ </menu>
+
+
+</book>
+
+
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd">
+
+<document>
+ <header>
+ <title></title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="GS" name="Glen Stampoultzis" email="user@poi.apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>POI logos</title>
+ <p>
+ Here are the current logo submissions. Thanks to the artists!
+ </p>
+ <section><title>Michael Mosmann</title>
+ <p>
+ <img alt="logo" src="images/logoMichaelMosmann.png"/>
+ </p>
+ </section>
+ <section><title>Loïc Lefèvre</title>
+ <p>
+ <img alt="logo" src="images/logoLoicLefevre.png"/>
+ <img alt="logo" src="images/logoLoicLefevre2.png"/>
+ </p>
+ </section>
+ <section><title>Glen Stampoultzis</title>
+ <p>
+ <img alt="logo" src="images/logoGlenStampoutlzis.png"/>
+ </p>
+ </section>
+ <section><title>Marcus Gustafsson</title>
+ <p>
+ <img alt="logo" src="images/logoGustafsson1.png"/>
+ <img alt="logo" src="images/logoGustafsson2.png"/>
+ </p>
+ </section>
+ <section><title>Adrianus Handoyo</title>
+ <p>
+ <img alt="logo" src="images/logoAdria1.png"/>
+ <img alt="logo" src="images/logoAdria2.png"/>
+ <img alt="logo" src="images/logoAdria3.png"/>
+ </p>
+ </section>
+ <section><title>RussellBeattie</title>
+ <p>
+ <img alt="logo" src="images/logoRussellBeattie1.png"/>
+ <img alt="logo" src="images/logoRussellBeattie2.png"/>
+ <img alt="logo" src="images/logoRussellBeattie3.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRussellBeattie4.png"/>
+ <img alt="logo" src="images/logoRussellBeattie5.png"/>
+ </p>
+ </section>
+ <section><title>Daniel Fernandez</title>
+ <p>
+ <img alt="logo" src="images/logoDanielFernandez.png"/>
+ </p>
+ </section>
+ <section><title>Andrew Clements</title>
+ <p>
+ <img alt="logo" src="images/logoAndrewClements.png"/>
+ <img alt="logo" src="images/logoAndrewClements2.png"/>
+ </p>
+ </section>
+ <section><title>Wendy Wise</title>
+ <p>
+ <img alt="logo" src="images/logoWendyWise.png"/>
+ <img alt="logo" src="images/logoWendyWise2.png"/>
+ </p>
+ </section>
+ <section><title>Nikhil Karmokar</title>
+ <p>
+ <img alt="logo" src="images/logoKarmokar1.png"/>
+ <img alt="logo" src="images/logoKarmokar1s.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoKarmokar2.png"/>
+ <img alt="logo" src="images/logoKarmokar2s.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoKarmokar3.png"/>
+ <img alt="logo" src="images/logoKarmokar3s.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoKarmokar4.png"/>
+ <img alt="logo" src="images/logoKarmokar4s.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoKarmokar5.png"/>
+ <img alt="logo" src="images/logoKarmokar5s.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoKarmokar6.png"/>
+ <img alt="logo" src="images/logoKarmokar6s.png"/>
+ </p>
+ </section>
+ <section><title>Lieven Janssen</title>
+ <p>
+ <img alt="logo" src="images/logoJanssen1.png"/>
+ <img alt="logo" src="images/logoJanssen2.png"/>
+ </p>
+ </section>
+ <section><title>RaPi GmbH</title>
+ <p>
+ Contact Person: Fancy at: fancy at my-feiqi.com
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH1.png"/>
+ <img alt="logo" src="images/logoRaPiGmbH2.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH5.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH6.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH7.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH8.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH9.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH10.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH11.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRaPiGmbH12.png"/>
+ </p>
+ </section>
+ <section><title>Randy Stanard</title>
+ <p>
+ <img alt="logo" src="images/logoRandyStanard01.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRandyStanard02.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRandyStanard03.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRandyStanard04.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRandyStanard05.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRandyStanard06.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRandyStanard07.png"/>
+ </p>
+ <p>
+ <img alt="logo" src="images/logoRandyStanard08.png"/>
+ </p>
+ </section>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Component Overview</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="RK" name="Rainer Klute" email="klute@apache.org"/>
+ <person id="DF" name="David Fisher" email="dfisher@jmlafferty.com"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Apache POI Project Components</title>
+ <section><title>POIFS for OLE 2 Documents</title>
+ <p>
+ POIFS is the oldest and most stable part of the project. It is our port of the OLE 2 Compound Document Format to
+ pure Java. It supports both read and write functionality. All of our components ultimately rely on it by
+ definition. Please see <link href="./poifs/index.html">the POIFS project page</link> for more information.
+ </p>
+ </section>
+ <section><title>HSSF and XSSF for Excel Documents</title>
+ <p>
+ HSSF is our port of the Microsoft Excel 97(-2007) file format (BIFF8) to pure
+ Java. XSSF is our port of the Microsoft Excel XML (2007+) file format (OOXML) to
+ pure Java. SS is a package that provides common support for both formats with a common API.
+ They both support read and write capability. Please see
+ <link href="./spreadsheet/index.html">the HSSF+XSSF project page</link> for more
+ information.
+ </p>
+ </section>
+ <section><title>HWPF and XWPF for Word Documents</title>
+ <p>
+ HWPF is our port of the Microsoft Word 97 (-2003) file format to pure
+ Java. It supports read, and limited write capabilities. It also provides
+ simple text extraction support for the older Word 6 and Word 95 formats.
+ Please see <link href="./hwpf/index.html">the HWPF project page for more
+ information</link>. This component remains in early stages of
+ development. It can already read and write simple files.
+ </p>
+ <p>
+ We are also working on the XWPF for the WordprocessingML (2007+) format from the
+ OOXML specification. This provides read and write support for simpler
+ files, along with text extraction capabilities.
+ </p>
+ </section>
+ <section><title>HSLF and XSLF for PowerPoint Documents</title>
+ <p>
+ HSLF is our port of the Microsoft PowerPoint 97(-2003) file format to pure
+ Java. It supports read and write capabilities. Please see <link
+ href="./slideshow/index.html">the HSLF project page for more
+ information</link>.
+ </p>
+ <p>
+ We are also working on the XSLF for the PresentationML (2007+) format from the
+ OOXML specification.
+ </p>
+ </section>
+ <section><title>HPSF for OLE 2 Document Properties</title>
+ <p>
+ HPSF is our port of the OLE 2 property set format to pure
+ Java. Property sets are mostly use to store a document's properties
+ (title, author, date of last modification etc.), but they can be used
+ for application-specific purposes as well.
+ </p>
+ <p>
+ HPSF supports both reading and writing of properties.
+ </p>
+ <p>
+ Please see <link href="./hpsf/index.html">the HPSF project
+ page</link> for more information.
+ </p>
+ </section>
+ <section><title>HDGF for Visio Documents</title>
+ <p>
+ HDGF is our port of the Microsoft Viso 97(-2003) file format to pure
+ Java. It currently only supports reading at a very low level, and
+ simple text extraction. Please see <link
+ href="./hdgf/index.html">the HDGF project page for more
+ information</link>.
+ </p>
+ </section>
+ <section><title>HPBF for Publisher Documents</title>
+ <p>
+ HPBF is our port of the Microsoft Publisher 98(-2007) file format to pure
+ Java. It currently only supports reading at a low level for around
+ half of the file parts, and simple text extraction. Please see <link
+ href="./hpbf/index.html">the HPBF project page for more
+ information</link>.
+ </p>
+ </section>
+ <section><title>HMEF for TNEF (winmail.dat) Outlook Attachments</title>
+ <p>
+ HMEF is our port of the Microsoft TNEF (Transport Neutral Encoding
+ Format) file format to pure Java. TNEF is sometimes used by Outlook
+ for encoding the message, and will typically come through as
+ winmail.dat. HMEF currently only supports reading at a low level, but
+ we hope to add text and attachment extraction shortly. Please see <link
+ href="./hmef/index.html">the HMEF project page for more
+ information</link>.
+ </p>
+ </section>
+ <section><title>HSMF for Outlook Messages</title>
+ <p>
+ HSMF is our port of the Microsoft Outlook message file format to pure
+ Java. It currently only some of the textual content of MSG files, and
+ some attachments. Further support and documentation is coming in slowly.
+ For now, users are advised to consult the unit tests for example use.
+ Please see <link href="./hsmf/index.html">the HPBF project page for more
+ information</link>.
+ </p>
+ <p>
+ Microsoft has recently added the Outlook file format to its OSP. More information
+ is now available making implementation of this API an easier task.
+ </p>
+ </section>
+ </section>
+ <section><title>What is it?</title>
+ <p>The Apache POI project is the master project for developing pure
+ Java ports of file formats based on Microsoft's OLE 2 Compound
+ Document Format. OLE 2 Compound Document Format is used by
+ Microsoft Office Documents, as well as by programs using MFC
+ property sets to serialize their document objects.
+ </p>
+ <p>Apache POI is also the master project for developing pure
+ Java ports of file formats based on Office Open XML (ooxml.)
+ OOXML is part of an ECMA / ISO standardisation effort. This
+ documentation is quite large, but you can normally find the bit you
+ need without too much effort!
+ <link href="http://www.ecma-international.org/publications/standards/Ecma-376.htm">ECMA-376 standard is here</link>,
+ and is also under the <link href="http://www.microsoft.com/interop/osp">Microsoft OSP</link>.
+ </p>
+ </section>
+ <section id="components"><title>Component Map</title>
+ <p>
+ The Apache POI distribution consists of support for many document file formats. This support is provided
+ in several Jar files. Not all of the Jars are needed for every format. The following tables
+ show the relationships between POI components, Maven repository tags, and the project's Jar files.
+ </p>
+ <table>
+ <tr>
+ <th>Component</th>
+ <th>Application type</th>
+ <th>Maven artifactId</th>
+ <th>Notes</th>
+ </tr>
+ <tr>
+ <td><link href="./poifs/index.html">POIFS</link></td>
+ <td>OLE2 Filesystem</td>
+ <td><em>poi</em></td>
+ <td>Required to work with OLE2 / POIFS based files</td>
+ </tr>
+ <tr>
+ <td><link href="./hpsf/index.html">HPSF</link></td>
+ <td>OLE2 Property Sets</td>
+ <td>poi</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./spreadsheet/index.html">HSSF</link></td>
+ <td>Excel XLS</td>
+ <td>poi</td>
+ <td>For HSSF only, if common SS is needed see below</td>
+ </tr>
+ <tr>
+ <td><link href="./slideshow/index.html">HSLF</link></td>
+ <td>PowerPoint PPT</td>
+ <td>poi-scratchpad</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./hwpf/index.html">HWPF</link></td>
+ <td>Word DOC</td>
+ <td>poi-scratchpad</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./hdgf/index.html">HDGF</link></td>
+ <td>Visio VSD</td>
+ <td>poi-scratchpad</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./hpbf/index.html">HPBF</link></td>
+ <td>Publisher PUB</td>
+ <td>poi-scratchpad</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./hsmf/index.html">HSMF</link></td>
+ <td>Outlook MSG</td>
+ <td>poi-scratchpad</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./oxml4j/index.html">OpenXML4J</link></td>
+ <td>OOXML</td>
+ <td>poi-ooxml plus one of<br />poi-ooxml-schemas, ooxml-schemas</td>
+ <td>Only one schemas jar is needed, see below for differences</td>
+ </tr>
+ <tr>
+ <td><link href="./spreadsheet/index.html">XSSF</link></td>
+ <td>Excel XLSX</td>
+ <td>poi-ooxml</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./slideshow/index.html">XSLF</link></td>
+ <td>PowerPoint PPTX</td>
+ <td>poi-ooxml</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./hwpf/index.html">XWPF</link></td>
+ <td>Word DOCX</td>
+ <td>poi-ooxml</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td><link href="./spreadsheet/index.html">Common SS</link></td>
+ <td>Excel XLS and XLSX</td>
+ <td>poi-ooxml</td>
+ <td>WorkbookFactory and friends all require poi-ooxml, not just core poi</td>
+ </tr>
+ </table>
+
+ <p><br /></p>
+
+ <p>
+ This table maps artifacts into the jar file name. "version-yyyymmdd" is
+ the POI version stamp. For the latest stable release it is
+ 3.9-20121203
+ . For the latest beta release it is
+ 3.10-beta2-20130904
+ .
+ </p>
+ <table>
+ <tr>
+ <th>Maven artifactId</th>
+ <th>Prerequisites</th>
+ <th>JAR</th>
+ </tr>
+ <tr>
+ <td>poi</td>
+ <td>commons-logging, commons-codec, log4j</td>
+ <td>poi-version-yyyymmdd.jar</td>
+ </tr>
+ <tr>
+ <td>poi-scratchpad</td>
+ <td>poi</td>
+ <td>poi-scratchpad-version-yyyymmdd.jar</td>
+ </tr>
+ <tr>
+ <td>poi-ooxml</td>
+ <td>poi, poi-ooxml-schemas, dom4j</td>
+ <td>poi-ooxml-version-yyyymmdd.jar</td>
+ </tr>
+ <tr>
+ <td>poi-ooxml-schemas</td>
+ <td>xmlbeans, stax-api-1.0.1</td>
+ <td>poi-ooxml-schemas-version-yyyymmdd.jar</td>
+ </tr>
+ <tr>
+ <td>poi-examples</td>
+ <td>poi, poi-scratchpad, poi-ooxml</td>
+ <td>poi-examples-version-yyyymmdd.jar</td>
+ </tr>
+ <tr>
+ <td>ooxml-schemas</td>
+ <td>xmlbeans, stax-api-1.0.1</td>
+ <td>ooxml-schemas-1.1.jar</td>
+ </tr>
+ </table>
+
+ <p> </p>
+ <p>
+ poi-ooxml requires poi-ooxml-schemas. This is a substantially smaller
+ version of the ooxml-schemas jar (ooxml-schemas-1.1.jar for POI 3.7 or
+ later, ooxml-scheams-1.0.jar for POI 3.5 and 3.6).
+ The larger ooxml-schemas jar is <link href="faq.html">normally</link>
+ only required for development
+ </p>
+ <p>
+ The OOXML jars require a stax implementation. The "stax-api-1.0.1" jar
+ should normally be used (it is recommended for compatibility with other
+ Apache projects), though any compliant implementation should work fine though.
+ </p>
+ </section>
+ <section><title>Examples</title>
+ <p>
+ Small sample programs using the POI API are available in the
+ <em>src/examples</em> directory of the source distribution. Before
+ studying the source code you might want to have a look at the
+ "Examples" section of the <link href="apidocs/overview-summary.html">POI API
+ documentation</link>.
+ </p>
+ <section><title>POI Browser</title>
+ <p>
+ The POI Browser is a very simple Swing GUI tool that displays the
+ internal structure of a Microsoft Office file and especially the
+ property set streams. Further information and instructions how to
+ execute it can be found in the <link
+ href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/poifs/poibrowser/POIBrowser.java">POI
+ source code</link>.
+ </p>
+ </section>
+ <p>
+ All of the examples are inclided in POI distributions as a poi-examples artifact.
+ </p>
+ </section>
+ <section><title>Contributed Software</title>
+ <p>
+ Besides the "official" components outlined above there is some further
+ software distributed with POI. This is called "contributed" software. It
+ is not explicitly recommended or even maintained by the POI team, but
+ it might still be useful to you.
+ </p>
+ <p>
+ See <link href="poi-ruby.html">POI Ruby Bindings</link> and other code in the
+ <link
+ href="http://svn.apache.org/repos/asf/poi/trunk/src/contrib/">poi-contrib module</link>
+ </p>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="OpenXML4J"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="OpenXML4J">
+ <menu-item label="Overview" href="index.html"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-OpenXML4J - Java API To Access Office Open XML documents</title>
+ <subtitle>Overview</subtitle>
+ </header>
+
+ <body>
+ <section>
+ <title>Overview</title>
+ <p>OpenXML4J is the POI Project's pure Java implementation of the Open Packaging Conventions (OPC) defined in
+ <link href="http://www.ecma-international.org/publications/standards/Ecma-376.htm">ECMA-376</link>.</p>
+ <p>Every OpenXML file comprises a collection of byte streams called parts, combined into a container called a package.
+ POI OpenXML4J provides a physical implementation of the OPC that uses the Zip file format.</p>
+ </section>
+ <section>
+ <title>History</title>
+ <p>OpenXML4J was originally developed by <link href="http://openxml4j.org/">http://openxml4j.org/</link> and contributed to POI in 2008.
+ Thanks to the support and guidance of Julien Chable</p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+<!-- Is this being used? -->
+
+<document>
+ <header>
+ <title>Patch Queue</title>
+ <authors>
+ <person email="greenrd@hotmail.com" name="Robin Green"/>
+ <person email="barozzi@nicolaken.com" name="Nicola Ken Barozzi"/>
+ </authors>
+ </header>
+ <body>
+ <section>
+ <title>Introduction</title>
+ <p>
+ This is an
+ <strong>informal</strong> list - in chronological order -
+ of some of the noteworthy patches that have been posted
+ to the
+ <code>developers</code> mailing list.
+ These patches are not (yet) part of the POI project, but need reviewing for possible
+ inclusion. This system was instituted because, due to the large volume of mail and
+ the lack of time of the committers, some patches tended to get forgotten about. This
+ queue does not guarantee that any patch will be reviewed within a reasonable time frame,
+ but it does at least make them easier to find!
+ </p>
+ <p>
+ <strong>Reviewers wanted!</strong> - If you have time to review and/or test these patches,
+ we would be grateful for your time. Please post comments to the dev mailing lists.
+ </p>
+ <p>
+ Before submitting a patch, please read the page on
+ <link href="contrib.xml">Third-Party
+ Contributions</link>. The preferred submission method for patches is:
+ </p>
+ <ul>
+ <li>Post to POI developers list</li>
+ <li>Describe the patch, the reason for it and (if necessary) why this
+ is important.</li>
+ <li>Generate the patch in the unified diff format. This format is
+ created by the typical Subversion client when you execute the
+ <code>svn diff</code> command or the equivalent of it in a GUI environment.</li>
+ <li>Also generate a documentation patch or new file, if this is
+ something that should be documented.</li>
+ <li>Post as an attachment rather than inline (unless it is trivially small).</li>
+ </ul>
+ <p>Following the above guidelines will facilitate your patch being reviewed
+ and applied efficiently.</p>
+ </section>
+ <section>
+ <title>Patch Queue</title>
+ <p>
+ <strong> [Under Construction] </strong> Archive links will be added later.
+ <strong>Please do not bother the patch submitters/authors</strong> without first reading the
+ relevant post(s) in the
+ <link href="mail-archives.xml">mailing list archives.</link>
+ </p>
+ <p>Vapourware will not be listed.</p>
+ <table>
+ <tr>
+ <th>id</th>
+ <th>Summary</th>
+ <th>Reviewer</th>
+ <th>Resolution</th>
+ <th>Status</th>
+ </tr>
+ </table>
+ <p>See also additional list of patches to be added in
+ <link href="todo.xml">To Do</link>.
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI 1.0 Vision Document</title>
+ <authors>
+ <person name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person name="Marcus W. Johnson" email="mjohnson@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+
+ <section><title>Preface</title>
+ <p>
+ (21-Jan-02) While this document is just full of useful project
+ introductory information and I do suggest those interested in getting
+ involved in the project read it, it is woefully out of date.
+ </p>
+ <p>
+ We deliberately allowed this document to run out of date because it
+ is a good reflection of what the original vision was for POI 1.0.
+ You'll note that some of the terminology is not used in quite the same
+ way any longer. I've made some minor corrections where reading this
+ confused me. An example: in some places this document may refer to
+ POI API instead of POIFS API. When this vision was written we had
+ an incomplete understanding of the project.
+ </p>
+ <p>
+ Lastly, the scope of the project expanded dramatically near the end
+ of the 1.0 cycle. Our vision at the time was to focus merely on the
+ Excel port (having no idea how the project would grow or be received)
+ and provide the OLE 2 Compound Document port for others to port later
+ formats. We now plan to spearhead these ports under the umbrella of
+ the POI project. So, you've been warned. Read on, but just realize
+ that we had a fuzzy view of things to come, and hindsight is 20-20.
+ </p>
+ <p>
+ If I recall major holes were: a complete understanding of the format
+ of OLE 2 Compound Document format, Excel file format, and exactly how
+ Cocoon 2 Serializers worked. (that just about covers the whole range
+ huh?)
+ </p>
+ </section>
+
+ <section><title>1. Introduction</title>
+ <section><title>1.1 Purpose of this document</title>
+ <p>
+ The purpose of this document is to
+ collect, analyze and define high-level requirements, user needs and
+ features of the HSSF Serializer for Cocoon 2 and related libraries.
+ The HSSF Serializer is a java class supporting the Serializer
+ interface from the Cocoon 2 project and outputting in a compatible
+ format of that used by the spreadsheet program Microsoft Excel '97.
+ The HSSF Serializer will be responsible for converting XML
+ spreadsheet-like documents into Excel-compatible XLS spreadsheets.
+ </p>
+ </section>
+
+
+ <section><title>1.2 Project Overview</title>
+ <p>
+ Many web apps today hit a brick wall
+ when it comes to the user request that they be able to easily
+ manipulate their reports and data extracts in the popular Microsoft
+ Excel spreadsheet format. This often causes inferior technologies to be
+ chosen for the project simply because they easily support this
+ format. This project seeks to extend existing XML, Java and Apache
+ Cocoon 2 project technologies by:
+ </p>
+
+ <ul>
+ <li>
+ providing an extensible library
+ (POIFS) which reads/writes in a compatable format to OLE 2 Compound
+ Document Format (aka Structured Storage Format) for easy
+ implementation of other document types;
+ </li>
+ <li>
+ providing a library (HSSF) for
+ manipulating spreadsheet data and outputting it in a compatible
+ format to Microsoft Excel XLS format;
+ </li>
+ <li>
+ and providing a Cocoon 2
+ Serializer (HSSFSerializer) for serializing XML documents as
+ Excel-compatible spreadsheets.
+ </li>
+ </ul>
+
+ </section>
+ </section>
+ <section><title>2. User Description</title>
+ <section><title>2.1 User/Market Demographics</title>
+ <p>
+ There are a number of enthusiastic
+ users of XML, UNIX and Java technology. Secondly, the Microsoft
+ solution for outputting Office Document formats often involves
+ actually manipulating the software as an OLE Server. This method
+ provides extremely low performance, extremely high overhead and is
+ only capable of handling one document at a time.
+ </p>
+ <ol>
+ <li>
+ Our intended audience for the HSSF
+ Serializer portion of this project are developers writing reports or
+ data extracts in XML format.
+ </li>
+ <li>
+ Our intended audience for the HSSF
+ library portion of this project is ourselves as we are developing
+ the Serializer and anyone who needs to write to Excel spreadsheets
+ in a non-XML Java environment or who has specific needs not
+ addressed by the Serializer.
+ </li>
+ <li>
+ Our intended audience for the
+ "POIFS" OLE 2 Compound Document format reader/writer is
+ ourselves as we are writing the HSSF library and secondly, anyone
+ wishing to provide other libraries for reading/writing OLE 2
+ Compound Document Format in Java.
+ </li>
+ </ol>
+ </section>
+ <section><title>2.2. User environment</title>
+ <p>
+ The users of this software shall be
+ developers in a Java environment on any Operating System or power
+ users who are capable of XML document generation/deployment.
+ </p>
+ </section>
+ <section><title>2.3. Key User Needs</title>
+ <p>
+ The OLE 2 Compound Document format is
+ undocumented for all practical purposes and cryptic for all
+ impractical purposes. Developer needs in this area include
+ documentation and an easy to use library for reading and writing in
+ this format without requiring the developer to have intimate
+ knowledge of the format.
+ </p>
+ <p>
+ There is currently no good way to write
+ to Microsoft Excel documents from Java or from a non-Microsoft
+ Windows based platform for that matter. Developers need an easy to
+ use library that supports a reasonable feature set and allows
+ seperation of data from formatting/stylistic concerns.
+ </p>
+ <p>
+ There is currently no good way to
+ transform XML data to Microsoft Excel. Apache's Cocoon 2 project
+ supplies a complete framework for XML, but nothing for outputting in
+ Excel's XLS format. Developers and power users alike need a simple
+ method to output XML documents to Excel through server-side
+ processing.
+ </p>
+
+
+ </section>
+ </section>
+ <section><title>3. Project Overview</title>
+ <section><title>3.1. Project Perspective</title>
+ <p>
+ The produced code shall be licensed by
+ the Apache License as used by the Cocoon 2 project and maintained on
+ a project page until such time as the Cocoon 2 developers accept it
+ as a donation (at which time the copyright will be turned over to
+ them).
+ </p>
+ </section>
+ <section><title>3.2. Project Position Statement</title>
+ <p>
+ For developers on a Java and/or XML
+ environment this project will provide all the tools necessary for
+ outputting XML data in the Microsoft Excel format. This project seeks
+ to make the use of Microsoft Windows based servers unnecessary for
+ file format considerations and to fully document the OLE 2 Compound
+ Document format. The project aims not only to provide the tools for
+ serializing XML to Excel's file format and the tools for writing to
+ that file format from Java, but also to provide the tools for later
+ projects to convert other OLE 2 Compound Document formats to pure
+ Java APIs.
+ </p>
+ </section>
+ <section><title>3.3. Summary of Capabilities</title>
+ <p>
+ HSSF Serializer for Apache Cocoon 2
+ </p>
+ <table>
+ <tr>
+ <td>
+ Benefit
+ </td>
+ <td>
+ Supporting Features
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Standard XML tag language for sheet data
+ </td>
+ <td>
+ Serializer will transform documents utilizing a defined tag
+ language
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Utilize XML to output in Excel
+ </td>
+ <td>
+ Serializer will output in Excel
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Java API to output in Excel on any platform
+ </td>
+ <td>
+ The project will develop an API that outputs in Excel using
+ pure Java.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Make it easy for developers to port other OLE 2 Compound
+ Document-based formats to Java.
+ </td>
+ <td>
+ The POIFS library will contain both a high-level abstraction
+ along with low-level constructs. The project will fully document
+ the OLE 2 Compound Document Format.
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section><title>3.4. Assumptions and Dependencies</title>
+ <ul>
+ <li>
+ The HSSF Serializer will run on
+ any Java 2 supporting platform with Apache Cocoon 2 installed along
+ with the HSSF and POIFS APIs.
+ </li>
+ <li>
+ The HSSF API requires a Java 2
+ implementation and the POI API.
+ </li>
+ <li>
+ The POIFS API requires a Java 2
+ implementation.
+ </li>
+ </ul>
+ </section>
+ </section>
+ <section><title>4. Project Features</title>
+ <p>
+ The POIFS API will include:
+ </p>
+ <ul>
+ <li>
+ Low level structures representing
+ the structures in a POI filesystems.
+ </li>
+ <li>
+ A low-level API for
+ creating/manipulating POI filesystems.
+ </li>
+ <li>
+ A set of high level interfaces
+ abstracting the user from the POI filesystem constructs and
+ representing it as a standard filesystem (Files, directories, etc)
+ </li>
+ </ul>
+ <p>
+ The HSSF API will include:
+ </p>
+ <ul>
+ <li>
+ Low level structures representing
+ the structures in an Excel file.
+ </li>
+ <li>
+ A low-level API for creating and
+ manipulating Excel files and writing them into POI filesystems.
+ </li>
+ <li>
+ A high level model and style
+ interface for manipulating spreadsheet data without knowing anything
+ about the Excel format itself.
+ </li>
+ </ul>
+ <section><title>4.1 POI Filesystem API</title>
+ <p>
+ The POI Filesystem API includes:
+ </p>
+ <ul>
+ <li>An implementation of Big Blocks</li>
+ <li>An implementation of Small Blocks</li>
+ <li>An implementation of Header Blocks</li>
+ <li>An implementation of Block Allocation Tables</li>
+ <li>An implementation of Property Sets</li>
+ <li>An implementation of the POI
+ filesystem including functions to get and set the above constructs;
+ compound functions for reading/writing files/directories.
+ </li>
+ <li>An abstraction of the POI
+ filesystem providing interfaces representing Files, Directories,
+ FileSystems in normal terminology and encapulating the above
+ constructs.
+ </li>
+ <li>Full documentation of the POI file
+ format.
+ </li>
+ <li>Full documentation of the APIs and
+ interfaces provided through Javadoc, user documentation (aimed at
+ developers using the APIs)
+ </li>
+ <li>Examples aimed at teaching the
+ user to write code using POI. (titled: recipes for POI)
+ </li>
+ <li>Performance specifications.
+ (Example POI filesystems rated by some measure of complexity along
+ with system specifications and execution times for given operations)
+ </li>
+ </ul>
+ </section>
+ <section><title>4.2 HSSF API</title>
+ <p>
+ The HSSF API includes:
+ </p>
+ <ul>
+ <li>An implementation of Record
+ (binary 2 byte type followed by 2 byte size (n) followed by n bytes)</li>
+ <li>Implementations of many standard
+ record types mapping the data bytes to fields along with methods to
+ reserialize those fields</li>
+ <li>An implementation of the HSSF File
+ including functions to get/set the above constructs, create a blank
+ file with the minimum required record types and mappings between
+ getting/setting data and style in a workbook to the creation of
+ record types, and read HSSF files.</li>
+ <li>An abstraction of the HSSF file
+ format providing interfaces representing the HSSF File, HSSF
+ Workbook, HSSF Sheet, HSSF Column, HSSF Formulas in a manner
+ seperating the data from the styling and encapsulating the above
+ constructs.</li>
+ <li>Full documentation of the HSSF
+ file format (which will be a subset of the Excel '97 File format).
+ This must be done with care for legal reasons.</li>
+ <li>Full documentation of the APIs and
+ interfaces provided through Javadoc, user documentation (aimed at
+ developers using the apis).</li>
+ <li>Examples aimed at teaching
+ developers to use the APIs.
+ </li>
+ <li>Performance specifications.
+ (Example files rated by some measure of complexity along with system
+ specifications and execution times for given operations - possibly
+ the same files used for POI's tests)</li>
+ </ul>
+ </section>
+ <section><title>4.3 HSSF Serializer</title>
+ <p>
+ The HSSF Serializer subproject:
+ </p>
+ <ul>
+ <li>A class supporting the Cocoon 2
+ Serializer Interface.</li>
+ <li>An interface between the SAX
+ events and the HSSF APIs.</li>
+ <li>A specified tag language for using
+ with the Serializer.</li>
+ <li>Documentation on the tag language
+ for the HSSF Serializer</li>
+ <li>Normal javadocs.</li>
+ <li>Example XML files</li>
+ <li>Performance specifications.
+ (Example XML docs and stylesheets rated by some measure of
+ complexity along with system specifications and execution times)</li>
+ </ul>
+ </section>
+ </section>
+ <section><title>5. Other Product Requirements</title>
+ <section><title>5.1. Applicable Standards</title>
+ <p>
+ All Java code will be 100% pure Java.
+ </p>
+ </section>
+ <section><title>5.2. System Requirements</title>
+ <p>
+ The minimum system requirements for POIFS are:
+ </p>
+ <ul>
+ <li>64 Mbytes memory</li>
+ <li>Java 2 environment</li>
+ <li>Pentium or better processor (or equivalent on other platforms)</li>
+ </ul>
+ <p>
+ The minimum system requirements for HSSF are:
+ </p>
+ <ul>
+ <li>64 Mbytes memory</li>
+ <li>Java 2 environment</li>
+ <li>Pentium or better processor (or equivalent on other platforms)</li>
+ <li>POIFS API</li>
+ </ul>
+ <p>
+ The minimum system requirements for the HSSF Serializer are:
+ </p>
+ <ul>
+ <li>64 Mbytes memory</li>
+ <li>Java 2 environment</li>
+ <li>Pentium or better processor (or equivalent on other platforms)</li>
+ <li>Cocoon 2</li>
+ <li>HSSF API</li>
+ <li>POI API</li>
+ </ul>
+ </section>
+ <section><title>5.3. Performance Requirements</title>
+ <p>
+ All components must perform well enough
+ to be practical for use in a webserver environment (especially
+ Cocoon2/Tomcat/Apache combo)
+ </p>
+ </section>
+ <section><title>5.4. Environmental Requirements</title>
+ <p>
+ The software will run primarily in
+ developer environments. We should make some allowances for
+ not-highly-technical users to write XML documents for the HSSF
+ Serializer. All other components will assume intermediate Java 2
+ knowledge. No XML knowledge will be required except for using the
+ HSSF Serializer. As much documentation as is practical shall be
+ required for all components as XML is relatively new, and the
+ concepts introduced for writing spreadsheets and to POI filesystems
+ will be brand new to Java and many Java developers.
+ </p>
+ </section>
+ </section>
+ <section><title>6. Documentation Requirements</title>
+ <section><title>6.1 POI Filesystem</title>
+ <p>
+ The filesystem as read and written by
+ POI shall be fully documented and explained so that the average Java
+ developer can understand it.
+ </p>
+ </section>
+ <section><title>6.2. POI API</title>
+ <p>
+ The POI API will be fully documented
+ through Javadoc. A walkthrough of using the high level POI API shall
+ be provided. No documentation outside of the Javadoc shall be
+ provided for the low-level POI APIs.
+ </p>
+ </section>
+ <section><title>6.3. HSSF File Format</title>
+ <p>
+ The HSSF File Format as implemented by
+ the HSSF API will be fully documented. No documentation will be
+ provided for features that are not supported by HSSF API that are
+ supported by the Excel 97 File Format. Care will be taken not to
+ infringe on any "legal stuff".
+ </p>
+ </section>
+ <section><title>6.4. HSSF API</title>
+ <p>
+ The HSSF API will be documented by
+ javadoc. A walkthrough of using the high level HSSF API shall be
+ provided. No documentation outside of the Javadoc shall be provided
+ for the low level HSSF APIs.
+ </p>
+ </section>
+
+ <section><title>6.5. HSSF Serializer</title>
+ <p>
+ The HSSF Serializer will be documented
+ by javadoc.
+ </p>
+ </section>
+
+ <section><title>6.6 HSSF Serializer Tag language</title>
+ <p>
+ The XML tag language along with
+ function and usage shall be fully documented. Examples will be
+ provided as well.
+ </p>
+ </section>
+ </section>
+ <section><title>7. Terminology</title>
+ <section><title>7.1 Filesystem</title>
+ <p>
+ filesystem shall refer only to the POI formatted archive.
+ </p>
+ </section>
+ <section><title>7.2 File</title>
+ <p>
+ file shall refer to the embedded data stream within a
+ POI filesystem. This will be the actual embedded document.
+ </p>
+ </section>
+ </section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI 2.0 Vision Document</title>
+ <authors>
+ <person name="Andrew C. Oliver" email="acoliver2@users.sourceforge.net"/>
+ <person name="Marcus W. Johnson" email="mjohnson@apache.org"/>
+ <person name="Glen Stampoultzis" email="user@poi.apache.org"/>
+ <person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ </authors>
+ </header>
+
+ <body>
+
+ <section><title>Preface</title>
+ <p>
+ This is the POI 2.0 cycle vision document. Although the vision
+ has not changed and this document is certainly not out of date and
+ the vision has not changed, the structure of the project has
+ changed a bit. We're not going to change the vision document to
+ reflect this (however proper that may be) because it would only
+ involve deletion. There is no purpose in providing less
+ information provided we give clarification.
+ </p>
+ <p>
+ This document was created before the POI components for
+ <link href="http://xml.apache.org/cocoon">Apache Cocoon</link>
+ were accepted into the Cocoon project itself. It was also
+ written before POI was accepted into Jakarta. So while the
+ vision hasn't changed some of the components are actually now
+ part of other projects. We'll still be working on them on the
+ same timeline roughly (minus the overhead of coordination with
+ other groups), but they are no longer technically part of the
+ POI project itself.
+ </p>
+ </section>
+
+ <section><title>1. Introduction</title>
+ <section><title>1.1 Purpose of this document</title>
+ <p>
+ The purpose of this document is to
+ collect, analyze and define high-level requirements, user needs,
+ and features of the second release of the POI project software.
+ The POI project currently consists of the following components:
+ the HSSF Serializer, the HSSF library and the POIFS library.
+ </p>
+ <ul>
+ <li>
+ The HSSF Serializer is a set of Java classes whose main
+ class supports the Serializer interface from the Cocoon
+ 2 project and outputs the serialized data in a format
+ compatible with the spreadsheet program Microsoft Excel
+ '97.
+ </li>
+ <li>
+ The HSSF library is a set of classes for reading and
+ writing Microsoft Excel 97 file format using pure Java.
+ </li>
+ <li>
+ The POIFS library is a set of classes for reading and
+ writing Microsoft's OLE 2 Compound Document format using
+ pure Java.
+ </li>
+ </ul>
+ <p>By the completion of this release cycle the POI project will also
+ include the HSSF Generator and the HWPF library.
+ </p>
+ <ul>
+ <li>The HSSF Generator will be responsible for using HSSF to read
+ in the XLS (Excel 97) file format and create SAX events. The HSSF
+ Generator will support the applicable interfaces specified by the
+ Apache Cocoon 2 project.
+ </li>
+ <li>The HWPF library will provide a set of high level interfaces
+ for reading and writing Microsoft Word 97 file format using pure
+ Java.</li>
+ </ul>
+
+ </section>
+
+
+ <section><title>1.2 Project Overview</title>
+ <p>
+ The first release of the POI project
+ was an astounding success. This release seeks to build on that
+ success by:
+ </p>
+ <ul>
+ <li>
+ Refactoring POIFS into imput and
+ output classes as well as an event-driven API for reading.
+ </li>
+ <li>
+ Refactor HSSF for greater
+ performance as well as an event-driven API for reading
+ </li>
+ <li>
+ Extend HSSF by adding the ability to read and write formulas.
+ </li>
+ <li>
+ Extend HSSF by adding the ability to read and write
+ user-defined styles.
+ </li>
+ <li>
+ Create a Cocoon 2 Generator for HSSF using the same tags
+ as the HSSF Serializer.
+ </li>
+ <li>
+ Create a new library (HWPF) for reading and writing
+ Microsoft Word DOC format.
+ </li>
+ <li>
+ Refactor the HSSFSerializer into a separate extensible
+ POIFSSerializer and HSSFSerializer
+ </li>
+ <li>
+ Providing the create excel charts. (write only)
+ </li>
+ </ul>
+ </section>
+ </section>
+ <section><title>2. User Description</title>
+ <section><title>2.1 User/Market Demographics</title>
+ <p>
+ There are a number of enthusiastic
+ users of XML, UNIX and Java technology. Furthermore, the Microsoft
+ solution for outputting Office Document formats often involves
+ actually manipulating the software as an OLE Server. This method
+ provides extremely low performance, extremely high overhead and is
+ only capable of handing one document at a time.
+ </p>
+ <ol>
+ <li>
+ Our intended audience for the HSSF
+ Serializer portion of this project are developers writing reports or
+ data extracts in XML format.
+ </li>
+ <li>
+ Our intended audience for the HSSF
+ library portion of this project is ourselves as we are developing
+ the HSSF serializer and anyone who needs to read and write Excel
+ spreadsheets in a non-XML Java environment, or who has specific
+ needs not addressed by the Serializer
+ </li>
+ <li>
+ Our intended audience for the
+ POIFS library is ourselves as we are developing the HSSF and HWPF
+ libraries and anyone wishing to provide other libraries for
+ reading/writing other file formats utilizing the OLE 2 Compound
+ Document Format in Java.
+ </li>
+ <li>
+ Our intended audience for the HSSF
+ generator are developers who need to export Excel spreadsheets to
+ XML in a non-proprietary environment.
+ </li>
+ <li>
+ Our intended audience for the HWPF
+ library is ourselves, as we will be developing a HWPF Serializer in a
+ later release, and anyone wishing to add .DOC file processing and
+ creation to their projects.
+ </li>
+ </ol>
+ </section>
+ <section><title>2.2. User environment</title>
+ <p>
+ The users of this software shall be
+ developers in a Java environment on any operating system, or power
+ users who are capable of XML document generation/deployment.
+ </p>
+ </section>
+ <section><title>2.3. Key User Needs</title>
+ <p>
+ The HSSF library currently requires a
+ full object representation to be created before reading values. This
+ results in very high memory utilization. We need to reduce this
+ substantially for reading. It would be preferable to do this for
+ writing, but it may not be possible due to the constraints imposed by
+ the file format itself. Memory utilization during read is our top
+ user complaint.
+ </p>
+ <p>
+ The POIFS library currently requires a
+ full object representation to be created before reading values. This
+ results in very high memory utilization. We need to reduce this
+ substantially for reading.
+ </p>
+ <p>
+ The HSSF library currently ignores
+ formula cells and identifies them as "UnknownRecord" at the
+ lower level of the API. We must provide a way to read and write
+ formulas. This is now the top requested feature.
+ </p>
+ <p>
+ The HSSF library currently does not support
+ charts. This is a key requirement of some users who wish to use HSSF
+ in a reporting engine.
+ </p>
+ <p>
+ The HSSF Serializer currently does not
+ provide serialization for cell styling. User's will want stylish
+ spreadsheets to result from their XML.
+ </p>
+ <p>
+ There is currently no way to generate
+ the XML from an XLS that is consistent with the format used by the
+ HSSF Serializer.
+ </p>
+ <p>
+ There should be a way to read and write
+ the DOC file format using pure Java.
+ </p>
+
+ </section>
+ </section>
+ <section><title>3. Project Overview</title>
+ <section><title>3.1. Project Perspective</title>
+ <p>
+ The produced code shall be licensed by
+ the Apache License as used by the Cocoon 2 project (APL 1.1) and
+ maintained on at <link href="http://poi.sourceforge.net/">http://poi.sourceforge.net</link>
+ and <link href="http://sourcefoge.net/projects/poi">http://sourcefoge.net/projects/poi</link>.
+ It is our hope to at some point integrate with the various Apache
+ projects (xml.apache.org and jakarta.apache.org), at which point we'd
+ turn the copyright over to them.
+ </p>
+ </section>
+ <section><title>3.2. Project Position Statement</title>
+ <p>
+ For developers on a Java and/or XML
+ environment this project will provide all the tools necessary for
+ outputting XML data in the Microsoft Excel format. This project seeks
+ to make the use of Microsoft Windows based servers unnecessary for
+ file format considerations and to fully document the OLE 2 Compound
+ Document format. The project aims not only to provide the tools for
+ serializing XML to Excel and Word file formats and the tools for
+ writing to those file formats from Java, but also to provide the
+ tools for later projects to convert other OLE 2 Compound Document
+ formats to pure Java APIs.
+ </p>
+ </section>
+ <section><title>3.3. Summary of Capabilities</title>
+ <p>
+ HSSF Serializer for Apache Cocoon 2
+ </p>
+ <table>
+ <tr>
+ <th>
+ Benefit
+ </th>
+ <th>
+ Supporting Features
+ </th>
+ </tr>
+ <tr>
+ <td>
+ Ability to serialize styles from XML spreadsheets.
+ </td>
+ <td>
+ HSSFSerialzier will support styles.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Ability to read and write formulas in XLS files.
+ </td>
+ <td>
+ HSSF will support reading/writing formulas.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Ability to output in MS Word on any platform using Java.
+ </td>
+ <td>
+ The project will develop an API that outputs in Word format
+ using pure Java.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Enhance performance for reading and writing XLS files.
+ </td>
+ <td>
+ HSSF will undergo a number of performance enhancements. HSSF
+ will include a new event-based API for reading XLS files. POIFS
+ will support a new event-based API for reading OLE2 CDF files.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Ability to generate XML from XLS files
+ </td>
+ <td>
+ The project will develop an HSSF Generator.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ The ability to generate charts
+ </td>
+ <td>
+ HSSF will provide low level support for chart records as well
+ as high level API support for generating charts. The ability
+ to read chart information will not initially be provided.
+ </td>
+ </tr>
+
+ </table>
+ </section>
+ <section><title>3.4. Assumptions and Dependencies</title>
+ <ul>
+ <li>
+ The HSSF Serializer and Generator
+ will support the Gnumeric 1.0 XML tag language.
+ </li>
+ <li>
+ The HSSF Generator and HSSF
+ Serializer will be mutually validating. It should be possible to
+ have an XLS file created by the Serializer run through the Generator
+ and the output back through the Serializer (via the Cocoon pipeline)
+ and get the same file or a reasonable facimille (no one cares if it
+ differs by the order of the binary records in some minor but
+ non-visually recognizable manner).
+ </li>
+ <li>
+ The HSSF Generator will run on any
+ Java 2 supporting platform with Apache Cocoon 2 installed along with
+ the HSSF and POIFS APIs.
+ </li>
+ <li>
+ The HSSF Serializer will run on
+ any Java 2 supporting platform with Apache Cocoon 2 installed along
+ with the HSSF and POIFS APIs.
+ </li>
+ <li>
+ The HWPF API requires a Java 2
+ implementation and the POIFS API.
+ </li>
+ <li>
+ The HSSF API requires a Java 2
+ implementation and the POIFS API.
+ </li>
+ <li>
+ The POIFS API requires a Java 2
+ implementation.
+ </li>
+
+ </ul>
+ </section>
+ </section>
+ <section><title>4. Project Features</title>
+ <p>
+ Enhancements to the POIFS API will
+ include:
+ </p>
+ <ul>
+ <li>
+ An event driven API for reading
+ POIFS Filesystems.
+ </li>
+ <li>
+ A low-level API for
+ creating/manipulating POI filesystems.
+ </li>
+ <li>
+ Code improvements supporting
+ greater separation between read and write structures.
+ </li>
+ </ul>
+ <p>
+ Enhancements to the HSSF API will
+ include:
+ </p>
+ <ul>
+ <li>
+ An event driven API for reading
+ XLS files.
+ </li>
+ <li>
+ Performance improvements.
+ </li>
+ <li>
+ Formula support (read/write)
+ </li>
+ <li>
+ Support for user-defined data
+ formats
+ </li>
+ <li>
+ Better documentation of the file
+ format and structure.
+ </li>
+ <li>
+ An API for creation of charts.
+ </li>
+ </ul>
+ <p>
+ The HSSF Generator will include:
+ </p>
+ <ul>
+ <li>
+ A set of classes supporting the
+ Cocoon 2 Generator interfaces providing a method for reading XLS
+ files and outputting SAX events.
+ </li>
+ <li>
+ The same tag format used by the
+ HSSFSerializer in any given release.
+ </li>
+ </ul>
+ <p>
+ The HWPF API will include:
+ </p>
+ <ul>
+ <li>
+ An event driven API for reading
+ DOC files.
+ </li>
+ <li>
+ A set of high and low level APIs
+ for reading and writing DOC files.
+ </li>
+ <li>
+ Documentation of the DOC file
+ format or enhancements to existing documentation.
+ </li>
+ </ul>
+ </section>
+ <section><title>5. Other Product Requirements</title>
+ <section><title>5.1. Applicable Standards</title>
+ <p>
+ All Java code will be 100% pure Java.
+ </p>
+ </section>
+ <section><title>5.2. System Requirements</title>
+ <p>
+ The minimum system requirements for the POIFS API are:
+ </p>
+ <ul>
+ <li>64 Mbytes memory</li>
+ <li>Java 2 environment</li>
+ <li>Pentium or better processor (or equivalent on other platforms)</li>
+ </ul>
+ <p>
+ The minimum system requirements for the the HSSF API are:
+ </p>
+ <ul>
+ <li>64 Mbytes memory</li>
+ <li>Java 2 environment</li>
+ <li>Pentium or better processor (or equivalent on other platforms)</li>
+ <li>POIFS API</li>
+ </ul>
+ <p>
+ The minimum system requirements for the the HWPF API are:
+ </p>
+ <ul>
+ <li>64 Mbytes memory</li>
+ <li>Java 2 environment</li>
+ <li>Pentium or better processor (or equivalent on other platforms)</li>
+ <li>POIFS API</li>
+ </ul>
+
+ <p>
+ The minimum system requirements for the HSSF Serializer are:
+ </p>
+ <ul>
+ <li>64 Mbytes memory</li>
+ <li>Java 2 environment</li>
+ <li>Pentium or better processor (or equivalent on other platforms)</li>
+ <li>Cocoon 2</li>
+ <li>HSSF API</li>
+ <li>POI API</li>
+ </ul>
+ </section>
+ <section><title>5.3. Performance Requirements</title>
+ <p>
+ All components must perform well enough
+ to be practical for use in a webserver environment (especially
+ the "killer trio": Cocoon2/Tomcat/Apache combo)
+ </p>
+ </section>
+ <section><title>5.4. Environmental Requirements</title>
+ <p>
+ The software will run primarily in
+ developer environments. We should make some allowances for
+ not-highly-technical users to write XML documents for the HSSF
+ Serializer. All other components will assume intermediate Java 2
+ knowledge. No XML knowledge will be required except for using the
+ HSSF Serializer. As much documentation as is practical shall be
+ required for all components as XML is relatively new, and the
+ concepts introduced for writing spreadsheets and to POI filesystems
+ will be brand new to Java and many Java developers.
+ </p>
+ </section>
+ </section>
+ <section><title>6. Documentation Requirements</title>
+ <section><title>6.1 POI Filesystem</title>
+ <p>
+ The filesystem as read and written by
+ POI shall be fully documented and explained so that the average Java
+ developer can understand it.
+ </p>
+ </section>
+ <section><title>6.2. POI API</title>
+ <p>
+ The POI API will be fully documented
+ through Javadoc. A walkthrough of using the high level POI API shall
+ be provided. No documentation outside of the Javadoc shall be
+ provided for the low-level POI APIs.
+ </p>
+ </section>
+ <section><title>6.3. HSSF File Format</title>
+ <p>
+ The HSSF File Format as implemented by
+ the HSSF API will be fully documented. No documentation will be
+ provided for features that are not supported by HSSF API that are
+ supported by the Excel 97 File Format. Care will be taken not to
+ infringe on any "legal stuff". Additionally, we are
+ collaborating with the fine folks at OpenOffice.org on
+ *free* documentation of the format.
+ </p>
+ </section>
+ <section><title>6.4. HSSF API</title>
+ <p>
+ The HSSF API will be documented by
+ javadoc. A walkthrough of using the high level HSSF API shall be
+ provided. No documentation outside of the Javadoc shall be provided
+ for the low level HSSF APIs.
+ </p>
+ </section>
+ <section><title>6.5 HWPF API</title>
+ <p>
+ The HWPF API will be documented by
+ javadoc. A walkthrough of using the high level HWPF API shall be
+ provided. No documentation outside of the Javadoc shall be provided
+ for the low level HWPF APIs.
+ </p>
+ </section>
+ <section><title>6.6 HSSF Serializer</title>
+ <p>
+ The HSSF Serializer will be documented
+ by javadoc.
+ </p>
+ </section>
+ <section><title>6.7 HSSF Generator</title>
+ <p>
+ The HSSF Generator will be documented
+ by javadoc.
+ </p>
+ </section>
+ <section><title>6.8 HSSF Serializer Tag language</title>
+ <p>
+ The XML tag language along with
+ function and usage shall be fully documented. Examples will be
+ provided as well.
+ </p>
+ </section>
+ </section>
+ <section><title>7. Terminology</title>
+ <section><title>7.1 Filesystem</title>
+ <p>
+ filesystem shall refer only to the POI formatted archive.
+ </p>
+ </section>
+ <section><title>7.2 File</title>
+ <p>
+ file shall refer to the embedded data stream within a
+ POI filesystem. This will be the actual embedded document.
+ </p>
+ </section>
+ </section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="POI Project planning"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="Planning Documents">
+ <menu-item label="Overview" href="index.html"/>
+ <menu-item label="1.0 Vision" href="POI10Vision.html"/>
+ <menu-item label="2.0 Vision" href="POI20Vision.html"/>
+ </menu>
+
+
+</book>
+
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Planning Documentation</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="David Crossley" email="crossley@apache.org"/>
+ <person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Overview</title>
+
+ <p>This is a collection of notes to assist with long-term planning and
+ development.
+ </p>
+
+ <p>There is much discussion of issues and research topics (RT) threads on
+ the <code>dev</code> mailing list (and elsewhere). However, details
+ get lost in the sheer volume. This is the place to document the summary of
+ discussions on some key topics. Some new and complex capabilities will take
+ lots of design and specification before they can be implemented.
+ </p>
+
+ <p>Another use for this collection of notes is as a place to quickly store
+ a snippet from an email discussion or even a link to a discussion thread.
+ The concepts can then be fleshed-out over time.
+ </p>
+
+ <p>Anyone can participate in this process. Please get involved in discussion
+ on <code>dev</code> and contribute patches for these summary planning
+ documents via the normal <link href="../guidelines.html">contribution</link>
+ process.
+ </p>
+
+ <p>These planning documents are intended to be concise notes only. They are
+ also ever-evolving, because as issues are addressed these notes will be
+ revised.
+ </p>
+ </section>
+
+ <section><title>Topics and Issues</title>
+
+ <ul>
+ <li><link href="POI20Vision.html">POI Version 2.0 Vision</link>
+ </li>
+ <li><link href="POI10Vision.html">POI Version 1.0 Vision</link>
+ </li>
+ <li>See the general <link href="../todo.html">To Do</link> list
+ and the <code>dev</code> email archives for other issues</li>
+ </ul>
+ </section>
+
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Release Plan 2.0</title>
+ <subtitle>Planning Documentation</subtitle>
+ <authors>
+ <person name="David Crossley" email="crossley@apache.org"/>
+ <person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Preparation for release of Poi</title>
+ <p>Todo</p>
+<!-- NKB todo
+ <p>The 2.0 final release is scheduled for the end of November 2001.
+ </p>
+
+ <p>
+ The following is extracted from the thread
+ [C2]: Release Candidate 2 ... 2001-10-29
+ </p>
+
+<source><![CDATA[
+> The question is now, what has to be done until then?
+>
+> 1) We have many open bugs in bugzilla. These must be reviewed
+> and then solved (or declared invalid etc).
+>
+> 2) Documentation updates (this area lacks most)
+> We could move this to the final release.
+Documentation must be happening all the time, and not left
+until last.
+
+> 3) Decide what to backport from the 2.1 head.
+> I'm +1 on removing the CodeFactories completly in 2.0, too.
+> This would avoid any backcompatibility problems.
+>
+> 4) Layout the distribution
+> This is a point we haven't discussed yet. Currently our
+> distribution is a mixture of a source and a binary one.
+> We deliver the source and a compiled version, but in order
+> to run Cocoon, the user has to build a war file.
+> I propose to split this: one source distribution which is
+> similar to the current one but without the precompiled
+> cocoon jar and a binary distribution containing only the
+> war file. This war file should work in most servlet engines,
+> perhaps not in all.
+>
+> So anything missing here?
+
+5) Ensure that licensing requirements have been met.
+ update jars.xml, ensure proper banner in *.java header,
+ verify the current LICENSE* files, ensure that external
+ components have suitable licensing requirements.
+]]></source>
+-->
+ </section>
+
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>POI Ruby Bindings</title>
+ <authors>
+ <person id="AS" name="Avik Sengupta" email="avik@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Intro</title>
+ <p>The POI library can now be compiled as a Ruby extension, allowing the API to be called from
+ Ruby language programs. Ruby users can therefore read and write OLE2 documents, such as Excel files
+ with ease
+ </p>
+ <p>The bindings are generated by compiling POI with <link href="http://gcc.gnu.org/java/">gcj</link>,
+ and generating the Ruby wrapper using <link href="http://www.swig.org">SWIG</link>. The aim is the keep
+ the POI api as-is. However, where java standard library objects are used, an effort is made to transform them smoothly
+ into Ruby objects. Therefore, where the POI API takes an OutputStream, you can pass an IO object. Where the POI works
+ java.util.Date or java.util.Calendar object, you can work with a Ruby Time object. </p>
+ </section>
+
+
+ <section><title>Getting Started</title>
+ <section><title>Pre-Requisites</title>
+ <p>The bindings have been developed with GCC 3.4.3 and Ruby 1.8.2. You are unlikely to get correct results with
+ versions of GCC prior to 3.4 or versions of Ruby prior to 1.8. To compile the Ruby extension, you must have
+ GCC (compiled with java language support), Ruby development headers, and SWIG. To run, you will need Ruby (obviously!) and
+ <em>libgcj </em>, presumably from the same version of GCC with which you compiled.
+ </p>
+ </section>
+ <section><title>Subversion</title>
+ <p>
+ The POI-Ruby module sits under the POI <link href="http://svn.apache.org/repos/asf/poi/trunk/src/contrib/poi-ruby/">Subversion</link>. Running <em>make</em>
+ inside that directory will create a loadable ruby extention <em>poi4r.so</em> in the release subdirectory. Tests
+ are in the <em>tests/</em> subdirectory, and should be run from the <em>poi-ruby</em> directory. Please read the tests to figure out the usage.
+ </p>
+ <p>Note that the makefile, though designed to work accross Linux/OS X/Cygwin, has been tested only on linux.
+ There are likely to be issues on other platform; fixes gratefully accepted! </p>
+ </section>
+ <section><title>Binary</title>
+ <p>A version of poi4r.so is available <link href="http://www.apache.org/~avik/dist/poi4r.so">here</link>. Its been compiled on a linux box
+ with GCC 3.4.3 and Ruby 1.8.2. It dynamically links to libgcj. No guarantees about working on any other box. </p>
+ </section>
+ </section>
+
+
+
+
+ <section>
+ <title>Usage</title>
+ <p>The following ruby code shows some of the things you can do with POI in Ruby</p>
+ <source>
+ h=Poi4r::HSSFWorkbook.new
+ #Test Sheet Creation
+ s=h.createSheet("Sheet1")
+
+ #Test setting cell values
+ s=h.getSheetAt(0)
+ r=s.createRow(0)
+ c=r.createCell(0)
+ c.setCellValue(1.5)
+
+ c=r.createCell(1)
+ c.setCellValue("Ruby")
+
+ #Test styles
+ st = h.createCellStyle()
+ c=r.createCell(2)
+ st.setAlignment(Poi4r::HSSFCellStyle.ALIGN_CENTER)
+ c.setCellStyle(st)
+ c.setCellValue("centr'd")
+
+ #Date handling
+ c=r.createCell(3)
+ t1=Time.now
+ c.setCellValue(Time.now)
+ t2= c.getDateCellValue().gmtime
+
+ st=h.createCellStyle();
+ st.setDataFormat(Poi4r::HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"))
+ c.setCellStyle(st)
+
+ #Formulas
+ c=r.createCell(4)
+ c.setCellFormula("A1*2")
+ c.getCellFormula()
+
+ #Writing
+ h.write(File.new("test.xls","w"))
+ </source>
+ <p> The <em>tc_base_tests.rb</em> file in the <em>tests</em> sub directory of the source distribution
+ contains examples of simple uses of the API. The <link href="spreadsheet/quick-guide.html">quick quide </link> is the best
+ place to learn HSSF API use. (Note however that none of the Drawing features are implemented in the Ruby binding.)
+ See also the <link href="apidocs/overview-summary.html">POI API documentation</link> for more details.
+ </p>
+ </section>
+
+ <section>
+ <title>Future Directions</title>
+ <section><title>TODO's</title>
+ <ul>
+ <li>Implement support for reading Excel files (easy)</li>
+ <li>Expose POIFS API to read raw OLE2 files from Ruby</li>
+ <li>Expose HPSF API to read property streams </li>
+ <li>Tests... Tests... Tests...</li>
+ </ul>
+ </section>
+ <section><title>Limitations</title>
+ <ul>
+ <li>Check operations in 64bit machines - Java primitive types are fixed irrespective of machine type, unlike C/C++ types. The wrapping code
+ that converts C/C++ primitive types to/from Java types is making assumptions on type sizes that MAY be incorrect on wide architectures. </li>
+ <li>The current implementation is with the POI 2.0 release. The 2.5 release adds support for Excel drawing primitives, and
+ thus has a dependency on java AWT. Since AWT is not very mature in gcj, leaving it out seemed to be the safer option.</li>
+ <li>Packaging - The current make file makes no effort to install the extension into the standard ruby directories. This should probably be
+ packaged as a <link href="http://www.rubygems.org">gem</link>.</li>
+ </ul>
+ </section>
+
+ </section>
+
+ </body>
+ <footer>
+ <legal>
+ Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="POIFS"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="POIFS">
+ <menu-item label="Overview" href="index.html"/>
+ <menu-item label="How To" href="how-to.html"/>
+ <menu-item label="Embeded Documents" href="embeded.html"/>
+ <menu-item label="File System Documentation" href="fileformat.html"/>
+ <menu-item label="Use Cases" href="usecases.html"/>
+ </menu>
+
+</book>
+
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+<document>
+ <header>
+ <title>Apache POI - POIFS - Documents embeded in other documents</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick@apache.org"/>
+ <person name="Yegor Kozlov" email="yegor@apache.org"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Overview</title>
+ <p>It is possible for one OLE 2 based document to have other
+ OLE 2 documents embeded in it. For example, and Excel file
+ may have a word document and a powerpoint slideshow
+ embeded as part of it.</p>
+ <p>Normally, these other documents are stored in subdirectories
+ of the OLE 2 (POIFS) filesystem. The exact location of the
+ embeded documents will vary depending on the type of the
+ master document, and the exact directory names will differ
+ each time. To figure out exactly which directory to look
+ in, you will either need to process the appropriate OLE 2
+ linking entry in the master document, or simple iterate
+ over all the directories in the filesystem.</p>
+ <p>As a general rule, you will find the same OLE 2 entries
+ in the subdirectories, as you would've found at the root
+ of the filesystem were a document to not be embeded.</p>
+
+ <section><title>Files embeded in Excel</title>
+ <p>Excel normally stores embeded files in subdirectories
+ of the filesystem root. Typically these subdirectories
+ are named starting with MBD, with 8 hex characters following.</p>
+ </section>
+
+ <section><title>Files embeded in Word</title>
+ <p>Word normally stores embeded files in subdirectories
+ of the ObjectPool directory, itself a subdirectory of the
+ filesystem root. Typically these subdirectories and named
+ starting with an underscore, followed by 10 numbers.</p>
+ </section>
+
+ <section><title>Files embeded in PowerPoint</title>
+ <p>PowerPoint does not normally store embeded files
+ in the OLE2 layer. Instead, they are held within records
+ of the main PowerPoint file.
+ <br/>See the <link href="./../slideshow/how-to-shapes.html#OLE">HSLF Tutorial</link>
+ for how to retrieve embedded OLE objects from a presentation</p>
+ </section>
+ </section>
+
+ <section><title>Listing POIFS contents</title>
+ <p>POIFS provides a simple tool for listing the contents of
+ OLE2 files. This can allow you to see what your POIFS file
+ contents, and hence if it has any embeded documents in it,
+ and where.</p>
+ <p>The tool to use is <em>org.apache.poi.poifs.dev.POIFSLister</em>.
+ This tool may be run from the command line, and takes a filename
+ as its parameter. It will print out all the directories and
+ files contained within the POIFS file.</p>
+ </section>
+
+ <section><title>Opening embeded files</title>
+ <p>All of the POIDocument classes (HSSFWorkbook, HSLFSlideShow,
+ HWPFDocument and HDGFDiagram) can either be opened from
+ a POIFSFileSystem, or from a specific directory within a
+ POIFSFileSystem. So, to open embeded files, simply locate the
+ appropriate DirectoryNode that represents the subdirectory
+ of interest, and pass this + the overall POIFSFileSystem to
+ the constructor.</p>
+ <p>I you want to extract the textual contents of the embeded file,
+ then open the appropriate POIDocument, and then pass this to
+ the extractor class, instead of simply passing the POIFSFilesystem
+ to the extractor.</p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+<document>
+ <header>
+ <title>POIFS File System Internals</title>
+ <authors>
+ <person email="mjohnson@apache.org" name="Marc Johnson" id="MJ"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>POIFS File System Internals</title>
+ <section><title>Introduction</title>
+ <p>POIFS file systems are essentially normal files stored on a
+ Java-compatible platform's native file system. They are
+ typically identified by names ending in a four character
+ extension noting what type of data they contain. For
+ example, a file ending in ".xls" would likely
+ contain spreadsheet data, and a file ending in
+ ".doc" would probably contain a word processing
+ document. POIFS file systems are called "file
+ system", because they contain multiple embedded files
+ in a manner similar to traditional file systems. Along
+ functional lines, it would be more accurate to call these
+ POIFS archives. For the remainder of this document it is
+ referred to as a file system in order to avoid confusion
+ with the "files" it contains.</p>
+ <p>POIFS file systems are compatible with those document
+ formats used by a well-known software company's popular
+ office productivity suite and programs outputting
+ compatible data. Because the POIFS file system does not
+ provide compression, encryption or any other worthwhile
+ feature, its not a good choice unless you require
+ interoperability with these programs.</p>
+ <p>The POIFS file system does not encode the documents
+ themselves. For example, if you had a word processor file
+ with the extension ".doc", you would actually
+ have a POIFS file system with a document file archived
+ inside of that file system.</p>
+ <p>Note - this document is a good overview and explanation of
+ the file format, but for the very nitty-gritty details,
+ you should refer to
+ <link href="http://msdn.microsoft.com/en-us/library/dd942138%28v=prot.13%29.aspx">[MS-CFB].pdf</link>
+ in the (now public) Microsoft Documentation.</p>
+ </section>
+ <section><title>Document Conventions</title>
+ <p>This document utilizes the numeric types as described by
+ the Java Language Specification, which can be found at
+ <link href="http://java.sun.com">http://java.sun.com</link>. In
+ short:</p>
+ <ul>
+ <li>A <em>byte</em> is an 8 bit signed integer ranging from
+ -128 to 127.</li>
+ <li>A <em>short</em> is a 16 bit signed integer ranging from
+ -32768 to 32767</li>
+ <li>An <em>int</em> is a 32 bit signed integer ranging from
+ -2147483648 to 2147483647</li>
+ <li>A <em>long</em> is a 64 bit signed integer ranging from
+ -9.22E18 to 9.22E18.</li>
+ </ul>
+ <p>The Java Language Specification spells out a number of
+ other types that are not referred to by this document.</p>
+ <p>Where this document makes references to "endian
+ conversion" it is referring to the byte order of
+ stored numbers. Numbers in "little-endian order"
+ are stored with the <em>least</em> significant byte first. In
+ order to properly read a short, for example, you'd read two
+ bytes and then shift the second byte 8 bits to the left
+ before performing an <code>or</code> operation to it
+ against the first byte. The following code illustrates this
+ method:</p>
+ <source>
+public int getShort (byte[] rec)
+{
+ return ((rec[1] << 8) | (rec[0] & 0x00ff));
+}</source>
+ </section>
+ <section><title>File System Walkthrough</title>
+ <p>This is a walkthrough of a POIFS file system and how it is
+ put together. It is not intended to give a concise
+ description but to give a "big picture" of the
+ general structure and how it's interpreted.</p>
+ <p>A POIFS file system begins with a header. This header
+ identifies locations in the file by function and provides a
+ sanity check identifying a file as a POIFS file system.</p>
+ <p>The first 64 bits of the header compose a <em>magic number
+ identifier.</em> This identifier tells the client software
+ that this is indeed a POIFS file system and that it should
+ be treated as such. This is a "sanity check" to
+ make sure this is a POIFS file system and not some other
+ format. The header also contains an <em>array of block
+ numbers</em>. These block numbers refer to blocks in the
+ file. When these blocks are read together they form the
+ <em>Block Allocation Table</em>. The header also contains a
+ pointer to the first element in the <em>property table</em>,
+ also known as the <em>root element</em>, and a pointer to the
+ <em>small Block Allocation Table (SBAT)</em>.</p>
+ <p>The <em>block allocation table</em> or <em>BAT</em>, along with
+ the <em>property table</em>, specify which blocks in the file
+ system belong to which files. After the header block, the
+ file system is divided into identically sized blocks of
+ data, numbered from 0 to however many blocks there are in
+ the file system. For each file in the file system, its
+ entry in the property table includes the index of the first
+ block in the array of blocks. Each block's index into the
+ array of blocks is also its index into the BAT, and the
+ integer value stored at that index in the BAT gives the
+ index of the next block in the array (and thus the index of
+ the next BAT value). A special value is stored in the BAT
+ to indicate "end of file".</p>
+ <p>The <em>property table</em> is essentially the directory
+ storage for the file system. It consists of the name of the
+ file or directory, its <em>start block</em> in both the file
+ system and <em>BAT</em>, and its actual size. The first
+ property in the property table is the <em>root
+ element</em>. It has two purposes: to be a directory entry
+ (the root of the directory tree, to be specific), and to
+ hold the start block for the <em>small block data</em>.</p>
+ <p>Small block data is a special file that contains the data
+ for small files (less than 4K bytes). It subdivides its
+ blocks into smaller blocks and there is a special small
+ block allocation table that, like the main BAT for larger
+ files, is used to map a small file to its small blocks.</p>
+ </section>
+ <section><title>Header Block</title>
+ <p>The POIFS file system begins with a <em>header
+ block</em>. The first 64 bits of the header form a long
+ <em>file type id</em> or <em>magic number identifier</em> of
+ <code>0xE11AB1A1E011CFD0L</code>. This is basically a
+ sanity check. If this isn't the first thing in the header
+ (and consequently the file system) then this is not a
+ POIFS file system and should be read with some other
+ library.</p>
+ <p>It's important to know the most important parts of the
+ header. These are discussed in the rest of this
+ section.</p>
+ <section><title>BATs</title>
+ <p>At offset <em>0x2C</em> is an int specifying the number
+ of elements in the <em>BAT array</em>. The array at
+ <em>0x4C</em> an array of ints. This array contains the
+ indices of every block in the Block Allocation
+ Table.</p>
+ </section>
+ <section><title>XBATs</title>
+ <p>Very large POIFS archives may have more blocks than can
+ be addressed by the BAT blocks enumerated in the header
+ block. How large? Well, the BAT array in the header can
+ contain up to 109 BAT block indices; each BAT block
+ references up to 128 blocks, and each block is 512
+ bytes, so we're talking about 109 * 128 * 512 =
+ 6.8MB. That's a pretty respectable document! But, you
+ could have much more data than that, and in today's
+ world of cheap gigabyte drives, why not? So, the BAT
+ may be extended in that event. The integer value at
+ offset <em>0x44</em> of the header is the index of the
+ first <em>extended BAT (XBAT) block</em>. At offset
+ <em>0x48</em> of the header, there is an int value that
+ specifies how many XBAT blocks there are. The XBAT
+ blocks begin at the specified index into the array of
+ blocks making up the POIFS file system, and are chained
+ for the specified count of XBAT blocks.</p>
+ <p>Each XBAT block contains the indices of up to 127 BAT
+ blocks, so the document size can be expanded by another
+ ~8MB for each XBAT block. The BAT blocks indexed by an
+ XBAT block are appended to the end of the list of BAT
+ blocks enumerated in the header block. Thus the BAT
+ blocks enumerated in the header block are BAT blocks 0
+ through 108, the BAT blocks enumerated in the first
+ XBAT block are BAT blocks 109 through 235, the BAT
+ blocks enumerated in the second XBAT block are BAT
+ blocks 236 through 362, and so on.</p>
+ <p>While a normal BAT block holds 128 entries, each XBAT
+ only references 127 BAT blocks. The last, 128th entry
+ in an XBAT is the offset to the next XBAT block in the
+ chain (or -1 if this is the last XBAT).</p>
+ <p>Through the use of XBAT blocks, the limit on the
+ overall document size is that imposed by the 4-byte
+ block indices; if the indices are unsigned ints, the
+ maximum file size is 2 terabytes, 1 terabyte if the
+ indices are treated as signed ints. Either way, I have
+ yet to see a disk drive large enough to accommodate
+ such a file on the shelves at the local office supply
+ stores.</p>
+ </section>
+ <section><title>SBATs</title>
+ <p>If a file contained in a POIFS archive is smaller than
+ 4096 bytes, it is stored in small blocks. Small blocks
+ are 64 bytes in length and are contained within big
+ blocks, up to 8 to a big block. As the main BAT is used
+ to navigate the array of big blocks, so the <em>small
+ block allocation table</em> is used to navigate the
+ array of small blocks. The SBAT's start block index is
+ found at offset <em>0x3C</em> of the header block, and
+ remaining blocks constituting the SBAT are found by
+ walking the main BAT as if it were an ordinary file in
+ the POIFS file system (this process is described
+ below).</p>
+ </section>
+ <section><title>Property Table Start Index</title>
+ <p>An integer at address <em>0x30</em> specifies the start
+ index of the property table. This integer is specified
+ as a <em>"block index"</em>. The Property Table
+ is stored, as is almost everything in a POIFS file
+ system, in big blocks and walked via the BAT. The
+ Property Table is described below.</p>
+ </section>
+ </section>
+ <section><title>Property Table</title>
+ <p>The property table is essentially nothing more than the
+ directory system. Properties are 128 byte records
+ contained within the 512 byte blocks. The first property
+ is always the Root Entry. The following applies to
+ individual properties within a property table:</p>
+ <ul>
+ <li>At offset <em>0x00</em> in the property is the
+ "<em>name</em>". This is stored as an
+ uncompressed 16 bit unicode string. In short every
+ other byte corresponds to an "ASCII"
+ character. The size of this string is stored at offset
+ <em>0x40</em> (<em>string size</em>) as a short.</li>
+ <li>At offset <em>0x42</em> is the <em>property type</em>
+ (byte). The type is 1 for directory, 2 for file or 5
+ for the Root Entry.</li>
+ <li>At offset <em>0x43</em> is the <em>node color</em>
+ (byte). The color is either 1, (black), or 0,
+ (red). Properties are apparently meant to be arranged
+ in a red-black binary tree, subject to the following
+ rules:
+ <ol>
+ <li>The root of the tree is always black</li>
+ <li>Two consecutive nodes cannot both be red</li>
+ <li>A property is less than another property if its
+ name length is less than the other property's name
+ length</li>
+ <li>If two properties have the same name length, the
+ sort order is determined by the sort order of the
+ properties' names.</li>
+ </ol></li>
+ <li>At offset <em>0x44</em> is the index (int) of the
+ <em>previous property</em>.</li>
+ <li>At offset <em>0x48</em> is the index (int) of the
+ <em>next property</em>.</li>
+ <li>At offset <em>0x4C</em> is the index (int) of the
+ <em>first directory entry</em>. This is used by
+ directory entries.</li>
+ <li>At offset <em>0x74</em> is an integer giving the
+ <em>start block</em> for the file described by this
+ property. This index corresponds to an index in the
+ array of indices that is the Block Allocation Table
+ (or the Small Block Allocation Table) as well as the
+ index of the first block in the file. This is used by
+ files and the root entry.</li>
+ <li>At offset <em>0x78</em> is an integer giving the total
+ <em>actual size</em> of the file pointed at by this
+ property. If the file size is less than 4096, the file
+ is stored in small blocks and the SBAT is used to walk
+ the small blocks making up the file. If the file size
+ is 4096 or larger, the file is stored in big blocks
+ and the main BAT is used to walk the big blocks making
+ up the file. The exception to this rule is the <em>Root
+ Entry</em>, which, regardless of its size, is
+ <em>always</em> stored in big blocks and the main BAT is
+ used to walk the big blocks making up this special
+ file.</li>
+ </ul>
+ </section>
+ <section><title>Root Entry</title>
+ <p>The <em>Root Entry</em> in the <em>Property Table</em>
+ contains the information necessary to read and write
+ small files, which are files less than 4096 bytes
+ long. The start block field of the Root Entry is the
+ start index of the <em>Small Block Array</em>, which is
+ read like any other file in the POIFS file system. Since
+ the SBAT cannot be used without the Small Block Array,
+ the Root Entry MUST be read or written using the <em>Block
+ Allocation Table</em>. The blocks making up the Small
+ Block Array are divided into 64-byte small blocks, up to
+ the size indicated in the Root Entry (which should always
+ be a multiple of 64).</p>
+ </section>
+ <section><title>Walking the Nodes of the Property Table</title>
+ <p>The individual properties form a directory tree, with the
+ <em>Root Entry</em> as the directory tree's root, as shown
+ in the accompanying drawing. Note the numbers in
+ parentheses in each node; they represent the node's index
+ in the array of properties. The <em>NEXT_PROP</em>,
+ <em>PREVIOUS_PROP</em>, and <em>CHILD_PROP</em> fields hold
+ these indices, and are used to navigate the tree.</p>
+ <p><img alt="property set" src="images/PropertySet.jpg" /></p>
+ <p>Each directory entry (i.e., a property whose type is
+ <em>directory</em> or <em>root entry</em>) uses its
+ <em>CHILD_PROP</em> field to point to one of its
+ subordinate (child) properties. It doesn't seem to matter
+ which of its children it points to. Thus in the previous
+ drawing, the Root Entry's CHILD_PROP field may contain 1,
+ 4, or the index of one of its other children. Similarly,
+ the directory node (index 1) may have, in its CHILD_PROP
+ field, 2, 3, or the index of one of its other
+ children.</p>
+ <p>The children of a given directory property point to each
+ other in a similar fashion by using their
+ <em>NEXT_PROP</em> and <em>PREVIOUS_PROP</em> fields.</p>
+ <p>Unused <em>NEXT_PROP</em>, <em>PREVIOUS_PROP</em>, and
+ <em>CHILD_PROP</em> fields contain the marker value of
+ -1. All file properties have a value of -1 for their
+ CHILD_PROP fields for example.</p>
+ </section>
+ <section><title>Block Allocation Table</title>
+ <p>The <em>BAT blocks</em> are pointed at by the bat array
+ contained in the header and supplemented, if necessary,
+ by the <em>XBAT blocks</em>. These blocks form a large
+ table of integers. These integers are block numbers. The
+ <em>Block Allocation Table</em> holds chains of integers.
+ These chains are terminated with -2. The elements in
+ these chains refer to blocks in the files. The starting
+ block of a file is NOT specified in the BAT. It is
+ specified by the <em>property</em> for a given file. The
+ elements in this BAT are both the block number (within
+ the file minus the header) <em>and</em> the number of the
+ next BAT element in the chain. This can be thought of as
+ a linked list of blocks. The BAT array contains the links
+ from one block to the next, including the end of chain
+ marker.</p>
+ <p>Here's an example: Let's assume that the BAT begins as
+ follows:</p>
+ <p><code>BAT[ 0 ] = 2</code></p>
+ <p><code>BAT[ 1 ] = 5</code></p>
+ <p><code>BAT[ 2 ] = 3</code></p>
+ <p><code>BAT[ 3 ] = 4</code></p>
+ <p><code>BAT[ 4 ] = 6</code></p>
+ <p><code>BAT[ 5 ] = -2</code></p>
+ <p><code>BAT[ 6 ] = 7</code></p>
+ <p><code>BAT[ 7 ] = -2</code></p>
+ <p><code>...</code></p>
+ <p>Now, if we have a file whose Property Table entry says it
+ begins with index 0, we walk the BAT array and see that
+ the file consists of blocks 0 (because the start block is
+ 0), 2 (because BAT[ 0 ] is 2), 3 (BAT[ 2 ] is 3), 4 (BAT[
+ 3 ] is 4), 6 (BAT[ 4 ] is 6), and 7 (BAT[ 6 ] is 7). It
+ ends at block 7 because BAT[ 7 ] is -2, which is the end
+ of chain marker.</p>
+ <p>Similarly, a file beginning at index 1 consists of
+ blocks 1 and 5.</p>
+ <p>Other special numbers in a BAT array are:</p>
+ <ul>
+ <li>-1, which indicates an unused block</li>
+ <li>-3, which indicates a "special" block, such
+ as a block used to make up the Small Block Array, the
+ Property Table, the main BAT, or the SBAT</li>
+ </ul>
+ </section>
+ <section><title>File System Structures</title>
+ <p>The following outlines the basic file system structures.</p>
+ <section><title>Header (block 1) -- 512 (0x200) bytes</title>
+ <table>
+ <tr>
+ <td><em>Field</em></td>
+ <td><em>Description</em></td>
+ <td><em>Offset</em></td>
+ <td><em>Length</em></td>
+ <td><em>Default value or const</em></td>
+ </tr>
+ <tr>
+ <td>FILETYPE</td>
+ <td>Magic number identifying this as a POIFS file
+ system.</td>
+ <td>0x0000</td>
+ <td>Long</td>
+ <td>0xE11AB1A1E011CFD0</td>
+ </tr>
+ <tr>
+ <td>UK1</td>
+ <td>Unknown constant</td>
+ <td>0x0008</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>UK2</td>
+ <td>Unknown Constant</td>
+ <td>0x000C</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>UK3</td>
+ <td>Unknown Constant</td>
+ <td>0x0014</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>UK4</td>
+ <td>Unknown Constant (revision?)</td>
+ <td>0x0018</td>
+ <td>Short</td>
+ <td>0x003B</td>
+ </tr>
+ <tr>
+ <td>UK5</td>
+ <td>Unknown Constant (version?)</td>
+ <td>0x001A</td>
+ <td>Short</td>
+ <td>0x0003</td>
+ </tr>
+ <tr>
+ <td>UK6</td>
+ <td>Unknown Constant</td>
+ <td>0x001C</td>
+ <td>Short</td>
+ <td>-2</td>
+ </tr>
+ <tr>
+ <td>LOG_2_BIG_BLOCK_SIZE</td>
+ <td>Log, base 2, of the big block size</td>
+ <td>0x001E</td>
+ <td>Short</td>
+ <td>9 (2 ^ 9 = 512 bytes)</td>
+ </tr>
+ <tr>
+ <td>LOG_2_SMALL_BLOCK_SIZE</td>
+ <td>Log, base 2, of the small block size</td>
+ <td>0x0020</td>
+ <td>Integer</td>
+ <td>6 (2 ^ 6 = 64 bytes)</td>
+ </tr>
+ <tr>
+ <td>UK7</td>
+ <td>Unknown Constant</td>
+ <td>0x0024</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>UK8</td>
+ <td>Unknown Constant</td>
+ <td>0x0028</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>BAT_COUNT</td>
+ <td>Number of elements in the BAT array</td>
+ <td>0x002C</td>
+ <td>Integer</td>
+ <td>required</td>
+ </tr>
+ <tr>
+ <td>PROPERTIES_START</td>
+ <td>Block index of the first block of the property
+ table</td>
+ <td>0x0030</td>
+ <td>Integer</td>
+ <td>required</td>
+ </tr>
+ <tr>
+ <td>UK9</td>
+ <td>Unknown Constant</td>
+ <td>0x0034</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>UK10</td>
+ <td>Unknown Constant</td>
+ <td>0x0038</td>
+ <td>Integer</td>
+ <td>0x00001000</td>
+ </tr>
+ <tr>
+ <td>SBAT_START</td>
+ <td>Block index of first big block containing the small
+ block allocation table (SBAT)</td>
+ <td>0x003C</td>
+ <td>Integer</td>
+ <td>-2</td>
+ </tr>
+ <tr>
+ <td>SBAT_Block_Count</td>
+ <td>Number of big blocks holding the SBAT</td>
+ <td>0x0040</td>
+ <td>Integer</td>
+ <td>1</td>
+ </tr>
+ <tr>
+ <td>XBAT_START</td>
+ <td>Block index of the first block in the Extended Block
+ Allocation Table (XBAT)</td>
+ <td>0x0044</td>
+ <td>Integer</td>
+ <td>-2</td>
+ </tr>
+ <tr>
+ <td>XBAT_COUNT</td>
+ <td>Number of elements in the Extended Block Allocation
+ Table (to be added to the BAT)</td>
+ <td>0x0048</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>BAT_ARRAY</td>
+ <td>Array of block indices constituting the Block
+ Allocation Table (BAT)</td>
+ <td>0x004C, 0x0050, 0x0054 ... 0x01FC</td>
+ <td>Integer[]</td>
+ <td>-1 for unused elements, at least first element must
+ be filled.</td>
+ </tr>
+ <tr>
+ <td>N/A</td>
+ <td>Header block data not otherwise described in this
+ table</td>
+ <td>N/A</td>
+ <td>N/A</td>
+ <td>-1</td>
+ </tr>
+ </table>
+ </section>
+ <section>
+ <title>Block Allocation Table Block -- 512 (0x200) bytes</title>
+ <table>
+ <tr>
+ <td>
+ <em>Field</em>
+ </td>
+ <td>
+ <em>Description</em>
+ </td>
+ <td>
+ <em>Offset</em>
+ </td>
+ <td>
+ <em>Length</em>
+ </td>
+ <td>
+ <em>Default value or const</em>
+ </td>
+ </tr>
+ <tr>
+ <td>BAT_ELEMENT</td>
+ <td>Any given element in the BAT block</td>
+ <td>0x0000, 0x0004, 0x0008, ... 0x01FC</td>
+ <td>Integer</td>
+ <td>
+ -1 = unused<br/>
+ -2 = end of chain<br/>
+ -3 = special (e.g., BAT block)<br/>
+ All other values point to the next element in the
+ chain and the next index of a block composing the
+ file.
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Property Block -- 512 (0x200) byte block</title>
+ <table>
+ <tr>
+ <td><em>Field</em></td>
+ <td><em>Description</em></td>
+ <td><em>Offset</em></td>
+ <td><em>Length</em></td>
+ <td><em>Default value or const</em></td>
+ </tr>
+ <tr>
+ <td>Properties[]</td>
+ <td>This block contains the properties.</td>
+ <td>0x0000, 0x0080, 0x0100, 0x0180</td>
+ <td>128 bytes</td>
+ <td>All unused space is set to -1.</td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Property -- 128 (0x80) byte block</title>
+ <table>
+ <tr>
+ <td><em>Field</em></td>
+ <td><em>Description</em></td>
+ <td><em>Offset</em></td>
+ <td><em>Length</em></td>
+ <td><em>Default value or const</em></td>
+ </tr>
+ <tr>
+ <td>NAME</td>
+ <td>A unicode null-terminated uncompressed 16bit string
+ (lose the high bytes) containing the name of the
+ property.</td>
+ <td>0x00, 0x02, 0x04, ... 0x3E</td>
+ <td>Short[]</td>
+ <td>0x0000 for unused elements, field required, 32
+ (0x40) element max</td>
+ </tr>
+ <tr>
+ <td>NAME_SIZE</td>
+ <td>Number of characters in the NAME field</td>
+ <td>0x40</td>
+ <td>Short</td>
+ <td>Required</td>
+ </tr>
+ <tr>
+ <td>PROPERTY_TYPE</td>
+ <td>Property type (directory, file, or root)</td>
+ <td>0x42</td>
+ <td>Byte</td>
+ <td>1 (directory), 2 (file), or 5 (root entry)</td>
+ </tr>
+ <tr>
+ <td>NODE_COLOR</td>
+ <td>Node color</td>
+ <td>0x43</td>
+ <td>Byte</td>
+ <td>0 (red) or 1 (black)</td>
+ </tr>
+ <tr>
+ <td>PREVIOUS_PROP</td>
+ <td>Previous property index</td>
+ <td>0x44</td>
+ <td>Integer</td>
+ <td>-1</td>
+ </tr>
+ <tr>
+ <td>NEXT_PROP</td>
+ <td>Next property index</td>
+ <td>0x48</td>
+ <td>Integer</td>
+ <td>-1</td>
+ </tr>
+ <tr>
+ <td>CHILD_PROP</td>
+ <td>First child property index</td>
+ <td>0x4c</td>
+ <td>Integer</td>
+ <td>-1</td>
+ </tr>
+ <tr>
+ <td>SECONDS_1</td>
+ <td>Seconds component of the created timestamp?</td>
+ <td>0x64</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>DAYS_1</td>
+ <td>Days component of the created timestamp?</td>
+ <td>0x68</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>SECONDS_2</td>
+ <td>Seconds component of the modified timestamp?</td>
+ <td>0x6C</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>DAYS_2</td>
+ <td>Days component of the modified timestamp?</td>
+ <td>0x70</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>START_BLOCK</td>
+ <td>Starting block of the file, used as the first block
+ in the file and the pointer to the next block from
+ the BAT</td>
+ <td>0x74</td>
+ <td>Integer</td>
+ <td>Required</td>
+ </tr>
+ <tr>
+ <td>SIZE</td>
+ <td>Actual size of the file this property points
+ to. (used to truncate the blocks to the real
+ size).</td>
+ <td>0x78</td>
+ <td>Integer</td>
+ <td>0</td>
+ </tr>
+ </table>
+ </section>
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+<document>
+ <header>
+ <title>How To Use the POIFS APIs</title>
+ <authors>
+ <person email="mjohnson@apache.org" name="Marc Johnson" id="MJ"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>How To Use the POIFS APIs</title>
+ <p>This document describes how to use the POIFS APIs to read, write,
+ and modify files that employ a POIFS-compatible data structure to
+ organize their content.</p>
+ <section><title>Target Audience</title>
+ <p>This document is intended for Java developers who need to use the POIFS APIs to read, write, or modify files that employ a POIFS-compatible data structure to organize their content. It is not necessary for developers to understand the POIFS data structures, and an explanation of those data structures is beyond the scope of this document. It is expected that the members of the target audience will understand the rudiments of a hierarchical file system, and familiarity with the event pattern employed by Java APIs such as AWT would be helpful.</p>
+ </section>
+ <section><title>Glossary</title>
+ <p>This document attempts to be consistent in its terminology, which is defined here:</p>
+ <table>
+ <tr>
+ <td><em>Term</em></td>
+ <td><em>Definition</em></td>
+ </tr>
+ <tr>
+ <td>Directory</td>
+ <td>A special file that may contain other directories and documents.</td>
+ </tr>
+ <tr>
+ <td>DirectoryEntry</td>
+ <td>Representation of a directory within another directory.</td>
+ </tr>
+ <tr>
+ <td>Document</td>
+ <td>A file containing data, such as word processing data or a spreadsheet workbook.</td>
+ </tr>
+ <tr>
+ <td>DocumentEntry</td>
+ <td>Representation of a document within a directory.</td>
+ </tr>
+ <tr>
+ <td>Entry</td>
+ <td>Representation of a file in a directory.</td>
+ </tr>
+ <tr>
+ <td>File</td>
+ <td>A named entity, managed and contained by the file system.</td>
+ </tr>
+ <tr>
+ <td>File System</td>
+ <td>The POIFS data structures, plus the contained directories and documents, which are maintained in a hierarchical directory structure.</td>
+ </tr>
+ <tr>
+ <td>Root Directory</td>
+ <td>The directory at the base of a file system. All file systems have a root directory. The POIFS APIs will not allow the root directory to be removed or renamed, but it can be accessed for the purpose of reading its contents or adding files (directories and documents) to it.</td>
+ </tr>
+ </table>
+ </section>
+ </section>
+ <section><title>Reading a File System</title>
+ <p>This section covers reading a file system. There are two ways to read a file system; these techniques are sketched out in the following table, and then explained in greater depth in the sections following the table.</p>
+ <table>
+ <tr>
+ <td><em>Technique</em></td>
+ <td><em>Advantages</em></td>
+ <td><em>Disadvantages</em></td>
+ </tr>
+ <tr>
+ <td>Conventional Reading (POIFSFileSystem)</td>
+ <td>
+ Simpler API similar to reading a conventional file system.<br/>
+ Can read documents in any order.
+ </td>
+ <td>
+ All files are resident in memory, whether your application needs them or not.
+ </td>
+ </tr>
+ <tr>
+ <td>New NIO driven Reading (NPOIFSFileSystem)</td>
+ <td>
+ Simpler API similar to reading a conventional file system.<br/>
+ Can read documents in any order.<br/>
+ Lower memory than POIFSFileSystem
+ </td>
+ <td>
+ If created from an InputStream, all files are resident in memory.
+ (If created from a File, only certain key structures are)<br/>
+ Currently doesn't support writing
+ </td>
+ </tr>
+ <tr>
+ <td>Event-Driven Reading</td>
+ <td>
+ Reduced footprint -- only the documents you care about are processed.<br/>
+ Improved performance -- no time is wasted reading the documents you're not interested in.
+ </td>
+ <td>
+ More complicated API.<br/>
+ Need to know in advance which documents you want to read.<br/>
+ No control over the order in which the documents are read.<br/>
+ No way to go back and get additional documents except to re-read the file system, which may not be possible, e.g., if the file system is being read from an input stream that lacks random access support.
+ </td>
+ </tr>
+ </table>
+ <section><title>Conventional Reading</title>
+ <p>In this technique for reading, the entire file system is loaded into memory, and the entire directory tree can be walked by an application, reading specific documents at the application's leisure.</p>
+ <section><title>Preparation</title>
+ <p>Before an application can read a file from the file system, the file system needs to be loaded into memory. This is done by using the <code>org.apache.poi.poifs.filesystem.POIFSFileSystem</code> class. Once the file system has been loaded into memory, the application may need the root directory. The following code fragment will accomplish this preparation stage:</p>
+ <source>
+// need an open InputStream; for a file-based system, this would be appropriate:
+// InputStream stream = new FileInputStream(fileName);
+POIFSFileSystem fs;
+try
+{
+ fs = new POIFSFileSystem(inputStream);
+}
+catch (IOException e)
+{
+ // an I/O error occurred, or the InputStream did not provide a compatible
+ // POIFS data structure
+}
+DirectoryEntry root = fs.getRoot();</source>
+ <p>Assuming no exception was thrown, the file system can then be read.</p>
+ <p>Note: loading the file system can take noticeable time, particularly for large file systems.</p>
+ </section>
+ <section><title>Reading the Directory Tree</title>
+ <p>Once the file system has been loaded into memory and the root directory has been obtained, the root directory can be read. The following code fragment shows how to read the entries in an <code>org.apache.poi.poifs.filesystem.DirectoryEntry</code> instance:</p>
+ <source>
+// dir is an instance of DirectoryEntry ...
+for (Entry entry : dir)
+{
+ System.out.println("found entry: " + entry.getName());
+ if (entry instanceof DirectoryEntry)
+ {
+ // .. recurse into this directory
+ }
+ else if (entry instanceof DocumentEntry)
+ {
+ // entry is a document, which you can read
+ }
+ else
+ {
+ // currently, either an Entry is a DirectoryEntry or a DocumentEntry,
+ // but in the future, there may be other entry subinterfaces. The
+ // internal data structure certainly allows for a lot more entry types.
+ }
+}</source>
+ </section>
+ <section><title>Reading a Specific Document</title>
+ <p>There are a couple of ways to read a document, depending on whether the document resides in the root directory or in another directory. Either way, you will obtain an <code>org.apache.poi.poifs.filesystem.DocumentInputStream</code> instance.</p>
+ <section><title>DocumentInputStream</title>
+ <p>The DocumentInputStream class is a simple implementation of InputStream that makes a few guarantees worth noting:</p>
+ <ul>
+ <li><code>available()</code> always returns the number of bytes in the document from your current position in the document.</li>
+ <li><code>markSupported()</code> returns <code>true</code>.</li>
+ <li><code>mark(int limit)</code> ignores the limit parameter; basically the method marks the current position in the document.</li>
+ <li><code>reset()</code> takes you back to the position when <code>mark()</code> was last called, or to the beginning of the document if <code>mark()</code> has not been called.</li>
+ <li><code>skip(long n)</code> will take you to your current position + n (but not past the end of the document).</li>
+ </ul>
+ <p>The behavior of <code>available</code> means you can read in a document in a single read call like this:</p>
+ <source>
+byte[] content = new byte[ stream.available() ];
+stream.read(content);
+stream.close();</source>
+ <p>The combination of <code>mark</code>, <code>reset</code>, and <code>skip</code> provide the basic mechanisms needed for random access of the document contents.</p>
+ </section>
+ <section><title>Reading a Document From the Root Directory</title>
+ <p>If the document resides in the root directory, you can obtain a <code>DocumentInputStream</code> like this:</p>
+ <source>
+// load file system
+try
+{
+ DocumentInputStream stream = filesystem.createDocumentInputStream(documentName);
+ // process data from stream
+}
+catch (IOException e)
+{
+ // no such document, or the Entry represented by documentName is not a
+ // DocumentEntry
+}</source>
+ </section>
+ <section><title>Reading a Document From an Arbitrary Directory</title>
+ <p>A more generic technique for reading a document is to obtain an <code>org.apache.poi.poifs.filesystem.DirectoryEntry</code> instance for the directory containing the desired document (recall that you can use <code>getRoot()</code> to obtain the root directory from its file system). From that DirectoryEntry, you can then obtain a <code>DocumentInputStream</code> like this:</p>
+ <source>
+DocumentEntry document = (DocumentEntry)directory.getEntry(documentName);
+DocumentInputStream stream = new DocumentInputStream(document);
+</source>
+ </section>
+ </section>
+ </section>
+ <section><title>NIO Reading using NPOIFSFileSystem</title>
+ <p>In this technique for reading, certain key structures are loaded
+ into memory, and the entire directory tree can be walked by the
+ application, reading specific documents at leisure.</p>
+ <p>If you create a NPOIFSFileSystem instance from a File, the memory
+ footprint is very small. However, if you createa a NPOIFSFileSystem
+ instance from an input stream, then the whole contents must be
+ buffered into memory to allow random access. As such, you should
+ budget on memory use of up to 20% of the file size when using a File,
+ or up to 120% of the file size when using an InputStream.</p>
+ <section><title>Preparation</title>
+ <p>Before an application can read a file from the file system, the
+ file system needs to be opened and core parts processed. This is done
+ using the <code>org.apache.poi.poifs.filesystem.NPOIFSFileSystem</code>
+ class. Once the file system has been loaded into memory, the
+ application may need the root directory. The following code fragment
+ will accomplish this preparation stage:</p>
+ <source>
+// This is the most memory efficient way to open the FileSystem
+NPOIFSFileSystem fs;
+try
+{
+ fs = new NPOIFSFileSystem(new File(filename));
+}
+catch (IOException e)
+{
+ // an I/O error occurred, or the InputStream did not provide a compatible
+ // POIFS data structure
+}
+DirectoryEntry root = fs.getRoot();
+
+
+// Using an InputStream requires more memory than using a File
+NPOIFSFileSystem fs;
+try
+{
+ fs = new NPOIFSFileSystem(inputStream);
+}
+catch (IOException e)
+{
+ // an I/O error occurred, or the InputStream did not provide a compatible
+ // POIFS data structure
+}
+DirectoryEntry root = fs.getRoot();
+ </source>
+ <p>Assuming no exception was thrown, the file system can then be read.</p>
+ <p>One the NPOFSFileSytem is open, you can manipulate it just like
+ a POIFSFileSytem one.</p>
+ </section>
+ </section>
+ <section><title>Event-Driven Reading</title>
+ <p>The event-driven API for reading documents is a little more complicated and requires that your application know, in advance, which files it wants to read. The benefit of using this API is that each document is in memory just long enough for your application to read it, and documents that you never read at all are not in memory at all. When you're finished reading the documents you wanted, the file system has no data structures associated with it at all and can be discarded.</p>
+ <section><title>Preparation</title>
+ <p>The preparation phase involves creating an instance of <code>org.apache.poi.poifs.eventfilesystem.POIFSReader</code> and to then register one or more <code>org.apache.poi.poifs.eventfilesystem.POIFSReaderListener</code> instances with the <code>POIFSReader</code>.</p>
+ <source>
+POIFSReader reader = new POIFSReader();
+// register for everything
+reader.registerListener(myOmnivorousListener);
+// register for selective files
+reader.registerListener(myPickyListener, "foo");
+reader.registerListener(myPickyListener, "bar");
+// register for selective files
+reader.registerListener(myOtherPickyListener, new POIFSDocumentPath(),
+ "fubar");
+reader.registerListener(myOtherPickyListener, new POIFSDocumentPath(
+ new String[] { "usr", "bin" ), "fubar");</source>
+ </section>
+ <section><title>POIFSReaderListener</title>
+ <p><code>org.apache.poi.poifs.eventfilesystem.POIFSReaderListener</code> is an interface used to register for documents. When a matching document is read by the <code>org.apache.poi.poifs.eventfilesystem.POIFSReader</code>, the <code>POIFSReaderListener</code> instance receives an <code>org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent</code> instance, which contains an open <code>DocumentInputStream</code> and information about the document.</p>
+ <p>A <code>POIFSReaderListener</code> instance can register for individual documents, or it can register for all documents; once it has registered for all documents, subsequent (and previous!) registration requests for individual documents are ignored. There is no way to unregister a <code>POIFSReaderListener</code>.</p>
+ <p>Thus, it is possible to register a single <code>POIFSReaderListener</code> for multiple documents - one, some, or all documents. It is guaranteed that a single <code>POIFSReaderListener</code> will receive exactly one notification per registered document. There is no guarantee as to the order in which it will receive notification of its documents, as future implementations of <code>POIFSReader</code> are free to change the algorithm for walking the file system's directory structure.</p>
+ <p>It is also permitted to register more than one <code>POIFSReaderListener</code> for the same document. There is no guarantee of ordering for notification of <code>POIFSReaderListener</code> instances that have registered for the same document when <code>POIFSReader</code> processes that document.</p>
+ <p>It is guaranteed that all notifications occur in the same thread. A future enhancement may be made to provide multi-threaded notifications, but such an enhancement would very probably be made in a new reader class, a <code>ThreadedPOIFSReader</code> perhaps.</p>
+ <p>The following table describes the three ways to register a <code>POIFSReaderListener</code> for a document or set of documents:</p>
+ <table>
+ <tr>
+ <td><em>Method Signature</em></td>
+ <td><em>What it does</em></td>
+ </tr>
+ <tr>
+ <td>registerListener(POIFSReaderListener <em>listener</em>)</td>
+ <td>registers <em>listener</em> for all documents.</td>
+ </tr>
+ <tr>
+ <td>registerListener(POIFSReaderListener <em>listener</em>, String <em>name</em>)</td>
+ <td>registers <em>listener</em> for a document with the specified <em>name</em> in the root directory.</td>
+ </tr>
+ <tr>
+ <td>registerListener(POIFSReaderListener <em>listener</em>, POIFSDocumentPath <em>path</em>, String <em>name</em>)</td>
+ <td>registers <em>listener</em> for a document with the specified <em>name</em> in the directory described by <em>path</em></td>
+ </tr>
+ </table>
+ </section>
+ <section><title>POIFSDocumentPath</title>
+ <p>The <code>org.apache.poi.poifs.filesystem.POIFSDocumentPath</code> class is used to describe a directory in a POIFS file system. Since there are no reserved characters in the name of a file in a POIFS file system, a more traditional string-based solution for describing a directory, with special characters delimiting the components of the directory name, is not feasible. The constructors for the class are used as follows:</p>
+ <table>
+ <tr>
+ <td><em>Constructor example</em></td>
+ <td><em>Directory described</em></td>
+ </tr>
+ <tr>
+ <td>new POIFSDocumentPath()</td>
+ <td>The root directory.</td>
+ </tr>
+ <tr>
+ <td>new POIFSDocumentPath(null)</td>
+ <td>The root directory.</td>
+ </tr>
+ <tr>
+ <td>new POIFSDocumentPath(new String[ 0 ])</td>
+ <td>The root directory.</td>
+ </tr>
+ <tr>
+ <td>new POIFSDocumentPath(new String[ ] { "foo", "bar"} )</td>
+ <td>in Unix terminology, "/foo/bar".</td>
+ </tr>
+ <tr>
+ <td>new POIFSDocumentPath(new POIFSDocumentPath(new String[] { "foo" }), new String[ ] { "fu", "bar"} )</td>
+ <td>in Unix terminology, "/foo/fu/bar".</td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Processing POIFSReaderEvent Events</title>
+ <p>Processing <code>org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent</code> events is relatively easy. After all of the <code>POIFSReaderListener</code> instances have been registered with <code>POIFSReader</code>, the <code>POIFSReader.read(InputStream stream)</code> method is called.</p>
+ <p>Assuming that there are no problems with the data, as the <code>POIFSReader</code> processes the documents in the specified <code>InputStream</code>'s data, it calls registered <code>POIFSReaderListener</code> instances' <code>processPOIFSReaderEvent</code> method with a <code>POIFSReaderEvent</code> instance.</p>
+ <p>The <code>POIFSReaderEvent</code> instance contains information to identify the document (a <code>POIFSDocumentPath</code> object to identify the directory that the document is in, and the document name), and an open <code>DocumentInputStream</code> instance from which to read the document.</p>
+ </section>
+ </section>
+ </section>
+ <section><title>Writing a File System</title>
+ <p>Writing a file system is very much like reading a file system in that there are multiple ways to do so. You can load an existing file system into memory and modify it (removing files, renaming files) and/or add new files to it, and write it, or you can start with a new, empty file system:</p>
+ <source>
+POIFSFileSystem fs = new POIFSFileSystem();</source>
+ <section><title>The Naming of Names</title>
+ <p>There are two restrictions on the names of files in a file system that must be considered when creating files:</p>
+ <ol>
+ <li>The name of the file must not exceed 31 characters. If it does, the POIFS API will silently truncate the name to fit.</li>
+ <li>The name of the file must be unique within its containing directory. This seems pretty obvious, but if it isn't spelled out, there'll be hell to pay, to be sure. Uniqueness, of course, is determined <em>after</em> the name has been truncated, if the original name was too long to begin with.</li>
+ </ol>
+ </section>
+ <section><title>Creating a Document</title>
+ <p>A document can be created by acquiring a <code>DirectoryEntry</code> and calling one of the two <code>createDocument</code> methods:</p>
+ <table>
+ <tr>
+ <td><em>Method Signature</em></td>
+ <td><em>Advantages</em></td>
+ <td><em>Disadvantages</em></td>
+ </tr>
+ <tr>
+ <td>CreateDocument(String name, InputStream stream)</td>
+ <td>
+ Simple API.
+ </td>
+ <td>
+ Increased memory footprint (document is in memory until file system is written).
+ </td>
+ </tr>
+ <tr>
+ <td>CreateDocument(String name, int size, POIFSWriterListener writer)</td>
+ <td>
+ Decreased memory footprint (only very small documents are held in memory, and then only for a short time).
+ </td>
+ <td>
+ More complex API.<br/>
+ Determining document size in advance may be difficult.<br/>
+ Lose control over when document is to be written.
+ </td>
+ </tr>
+ </table>
+ <p>Unlike reading, you don't have to choose between the in-memory and event-driven writing models; both can co-exist in the same file system.</p>
+ <p>Writing is initiated when the <code>POIFSFileSystem</code> instance's <code>writeFilesystem()</code> method is called with an <code>OutputStream</code> to write to.</p>
+ <p>The event-driven model is quite similar to the event-driven model for reading, in that the file system calls your <code>org.apache.poi.poifs.filesystem.POIFSWriterListener</code> when it's time to write your document, just as the <code>POIFSReader</code> calls your <code>POIFSReaderListener</code> when it's time to read your document. Internally, when <code>writeFilesystem()</code> is called, the final POIFS data structures are created and are written to the specified <code>OutputStream</code>. When the file system needs to write a document out that was created with the event-driven model, it calls the <code>POIFSWriterListener</code> back, calling its <code>processPOIFSWriterEvent()</code> method, passing an <code>org.apache.poi.poifs.filesystem.POIFSWriterEvent</code> instance. This object contains the <code>POIFSDocumentPath</code> and name of the document, its size, and an open <code>org.apache.poi.poifs.filesystem.DocumentOutputStream</code> to which to write. A <code>DocumentOutputStream</code> is a wrapper over the <code>OutputStream</code> that was provided to the <code>POIFSFileSystem</code> to write to, and has the responsibility of making sure that the document your application writes fits within the size you specified for it.</p>
+ </section>
+ <section><title>Creating a Directory</title>
+ <p>Creating a directory is similar to creating a document, except that there's only one way to do so:</p>
+ <source>
+DirectoryEntry createdDir = existingDir.createDirectory(name);</source>
+ </section>
+ <section><title>Using POIFSFileSystem Directly To Create a Document Or Directory</title>
+ <p>As with reading documents, it is possible to create a new document or directory in the root directory by using convenience methods of POIFSFileSystem.</p>
+ <table>
+ <tr>
+ <td>DirectoryEntry Method Signature</td>
+ <td>POIFSFileSystem Method Signature</td>
+ </tr>
+ <tr>
+ <td>createDocument(String name, InputStream stream)</td>
+ <td>createDocument(InputStream stream, String name)</td>
+ </tr>
+ <tr>
+ <td>createDocument(String name, int size, POIFSWriterListener writer)</td>
+ <td>createDocument(String name, int size, POIFSWriterListener writer)</td>
+ </tr>
+ <tr>
+ <td>createDirectory(String name)</td>
+ <td>createDirectory(String name)</td>
+ </tr>
+ </table>
+ </section>
+ </section>
+ <section><title>Modifying a File System</title>
+ <p>It is possible to modify an existing POIFS file system, whether it's one your application has loaded into memory, or one which you are creating on the fly.</p>
+ <section><title>Removing a Document</title>
+ <p>Removing a document is simple: you get the <code>Entry</code> corresponding to the document and call its <code>delete()</code> method. This is a boolean method, but should always return <code>true</code>, indicating that the operation succeeded.</p>
+ </section>
+ <section><title>Removing a Directory</title>
+ <p>Removing a directory is also simple: you get the <code>Entry</code> corresponding to the directory and call its <code>delete()</code> method. This is a boolean method, but, unlike deleting a document, may not always return <code>true</code>, indicating that the operation succeeded. Here are the reasons why the operation may fail:</p>
+ <ul>
+ <li>The directory still has files in it (to check, call <code>isEmpty()</code> on its DirectoryEntry; is the return value <code>false</code>?)</li>
+ <li>The directory is the root directory. You cannot remove the root directory.</li>
+ </ul>
+ </section>
+ <section><title>Renaming a File</title>
+ <p>Regardless of whether the file is a directory or a document, it can be renamed, with one exception - the root directory has a special name that is expected by the components of a major software vendor's office suite, and the POIFS API will not let that name be changed. Renaming is done by acquiring the file's corresponding <code>Entry</code> instance and calling its <code>renameTo</code> method, passing in the new name.</p>
+ <p>Like <code>delete</code>, <code>renameTo</code> returns <code>true</code> if the operation succeeded, otherwise <code>false</code>. Reasons for failure include these:</p>
+ <ul>
+ <li>The new name is the same as another file in the same directory. And don't forget - if the new name is longer than 31 characters, it <em>will</em> be silently truncated. In its original length, the new name may have been unique, but truncated to 31 characters, it may not be unique any longer.</li>
+ <li>You tried to rename the root directory.</li>
+ </ul>
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<HTML>
+ <HEAD>
+ <TITLE>POIFS Design Document</TITLE>
+ </HEAD>
+ <BODY>
+ <FONT SIZE="+3"><B>POIFS Design Document</B></FONT>
+ <P>
+ This document describes the design of the POIFS system. It is
+ organized as follows:
+ </P>
+ <UL>
+ <LI>
+ <A HREF="#Scope">Scope</A> A description of the limitations of
+ this document.
+ </LI>
+ <LI>
+ <A HREF="#Assumptions">Assumptions</A> The assumptions on
+ which this design is based.
+ </LI>
+ <LI>
+ <A HREF="#Considerations">Design Considerations</A> The
+ constraints and goals applied to the design.
+ </LI>
+ <LI>
+ <A HREF="#Design">Design</A> The design of the POIFS system.
+ </LI>
+ </UL>
+ <P></P>
+ <OL TYPE="I">
+ <LI>
+ <A NAME="Scope"><FONT
+ SIZE="+2"><B>Scope</B></FONT></A>
+ <P>
+ This document is written as part of an iterative process.
+ As that process is not yet complete, neither is this
+ document.
+ </P>
+ </LI>
+ <LI>
+ <A NAME="Assumptions"><FONT
+ SIZE="+2"><B>Assumptions</B></FONT></A>
+ <P>
+ The design of POIFS is not dependent on the code written
+ for the proof-of-concept prototype POIFS package.
+ </P>
+ </LI>
+ <LI>
+ <A NAME="Considerations"><FONT SIZE="+2"><B>Design
+ Considerations</B></FONT></A>
+ <P>
+ As usual, the primary considerations in the design of the
+ POIFS assumption involve the classic space-time tradeoff.
+ In this case, the main consideration has to involve
+ minimizing the memory footprint of POIFS. POIFS may be
+ called upon to create relatively large documents, and in
+ web application server, it may be called upon to create
+ several documents simultaneously, and it will likely
+ co-exist with other Serializer systems, competing with
+ those other systems for space on the server.
+ </P>
+ <P>
+ We've addressed the risk of being too slow through a
+ proof-of-concept prototype. This prototype for POIFS
+ involved reading an existing file, decomposing it into its
+ constituent documents, composing a new POIFS from the
+ constituent documents, and writing the POIFS file back to
+ disk and verifying that the output file, while not
+ necessarily a byte-for-byte image of the input file, could
+ be read by the application that generated the input file.
+ This prototype proved to be quite fast, reading,
+ decomposing, and re-generating a large (300K) file in 2 to
+ 2.5 seconds.
+ </P>
+ <P>
+ While the POIFS format allows great flexibility in laying
+ out the documents and the other internal data structures,
+ the layout of the filesystem will be kept as simple as
+ possible.
+ </P>
+ </LI>
+ <LI>
+ <A NAME="Design"><FONT
+ SIZE="+2"><B>Design</B></FONT></A>
+ <P>
+ The design of the POIFS is broken down into two parts:
+ <A HREF="#Classes">discussion of the classes and
+ interfaces</A>, and <A HREF="#Scenarios">discussion of how
+ these classes and interfaces will be used to convert an
+ appropriate Java InputStream (such as an XML stream) to a
+ POIFS output stream containing an HSSF document</A>.
+ </P>
+ <A NAME="Classes"><FONT SIZE="+1"><B>Classes and Interfaces</B></FONT></A>
+ <P>
+ The classes and interfaces used in the POIFS are broken
+ down as follows:
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Package</B></TH>
+ <TH><B>Contents</B></TH>
+ </TR>
+ <TR>
+ <TD><A
+ HREF="#BlockClasses">net.sourceforge.poi.poifs.storage</A></TD>
+ <TD>Block classes and interfaces</TD>
+ </TR>
+ <TR>
+ <TD><A
+ HREF="#PropertyClasses">net.sourceforge.poi.poifs.property</A></TD>
+ <TD>Property classes and interfaces</TD>
+ </TR>
+ <TR>
+ <TD><A
+ HREF="#FilesystemClasses">net.sourceforge.poi.poifs.filesystem</A></TD>
+ <TD>Filesystem classes and interfaces</TD>
+ </TR>
+ <TR>
+ <TD><A
+ HREF="#UtilityClasses">net.sourceforge.poi.util</A></TD>
+ <TD>Utility classes and interfaces</TD>
+ </TR>
+ </TABLE>
+ <OL>
+ <LI>
+ <A NAME="BlockClasses"><B>Block Classes and
+ Interfaces</B></A>
+ <P>
+ The block classes and interfaces are shown
+ in the following class diagram.
+ </P>
+ <P>
+ <IMG SRC="BlockClassDiagram.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Class/Interface</B></TH>
+ <TH><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="BATBlock"><B>BATBlock</B></A></TD>
+ <TD>The <B>BATBlock</B> class
+ represents a single big block
+ containing 128 <A
+ HREF="POIFSFormat.html#BAT">BAT
+ entries</A>.<BR>Its
+ <CODE><I>_fields</I></CODE> array is
+ used to read and write the BAT entries
+ into the <CODE><I>_data</I></CODE>
+ array.<BR>Its
+ <CODE><I>createBATBlocks</I></CODE>
+ method is used to create an array of
+ BATBlock instances from an array of
+ int BAT entries.<BR>Its
+ <CODE><I>calculateStorageRequirements</I></CODE>
+ method calculates the number of BAT
+ blocks necessary to hold the specified
+ number of BAT entries.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="BigBlock"><B>BigBlock</B></A></TD>
+ <TD>The <B>BigBlock</B> class is an
+ abstract class representing the common
+ big block of 512 bytes. It implements
+ <A
+ HREF="#BlockWritable">BlockWritable</A>,
+ trivially delegating the
+ <CODE><I>writeBlocks</I></CODE> method
+ of BlockWritable to its own abstract
+ <CODE><I>writeData</I></CODE>
+ method.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="BlockWritable"><B>BlockWritable</B></A></TD>
+ <TD>The <B>BlockWritable</B> interface
+ defines a single method,
+ <CODE><I>writeBlocks</I></CODE>, that
+ is used to write an implementation's
+ block data to an
+ <CODE>OutputStream</CODE>.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="DocumentBlock"><B>DocumentBlock</B></A></TD>
+ <TD>The <B>DocumentBlock</B> class is
+ used by a <A
+ HREF="#Document">Document</A> to holds
+ its raw data. It also retains the
+ number of bytes read, as this is used
+ by the Document class to determine the
+ total size of the data, and is also
+ used internally to determine whether
+ the block was filled by the
+ <CODE>InputStream</CODE> or
+ not.<BR>The
+ <CODE><I>DocumentBlock</I></CODE>
+ constructor is passed an
+ <CODE>InputStream</CODE> from which to
+ fill its <CODE><I>_data</I></CODE>
+ array.<BR>The <CODE><I>size</I></CODE>
+ method returns the number of bytes
+ read (<CODE><I>_bytes_read</I></CODE>
+ when the instance was
+ constructed.<BR>The
+ <CODE><I>partiallyRead</I></CODE>
+ method returns true if the
+ <CODE><I>_data</I></CODE> array was
+ not completely filled, which may be
+ interpreted by the Document as having
+ reached the end of file
+ point.<BR>Typical use of the
+ DocumentBlock class is like
+ this:<BR><CODE>while
+ (true)<BR>{<BR> DocumentBlock
+ block = new
+ DocumentBlock(stream);<BR> blocks.add(block);<BR> size
+ +=
+ block.size();<BR> if
+ (block.partiallyRead())<BR> {<BR> break;<BR> }<BR>}</CODE></TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="HeaderBlock"><B>HeaderBlock</B></A></TD>
+ <TD>The <B>HeaderBlock</B> class is
+ used to contain the data found in a
+ POIFS header.<BR>Its <A
+ HREF="#IntegerField">IntegerField</A>
+ members are used to read and write the
+ appropriate entries into the
+ <CODE><I>_data</I></CODE>
+ array.<BR>Its
+ <CODE><I>setBATBlocks</I></CODE>,
+ <CODE><I>setPropertyStart</I></CODE>,
+ and <CODE><I>setXBATStart</I></CODE>
+ methods are used to set the
+ appropriate fields in the
+ <CODE><I>_data</I></CODE>
+ array.<BR>The
+ <CODE><I>calculateXBATStorageRequirements</I></CODE>
+ method is used to determine how many
+ XBAT blocks are necessary to
+ accommodate the specified number of
+ BAT blocks.
+ </TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="PropertyBlock"><B>PropertyBlock</B></A></TD>
+ <TD>The <B>PropertyBlock</B> class is
+ used to contain <A
+ HREF="#Property">Property</A>
+ instances for the <A
+ HREF="#PropertyTable">PropertyTable</A>
+ class.<BR>It contains an array,
+ <CODE><I>_properties</I></CODE> of 4
+ Property instances, which together
+ comprise the 512 bytes of a <A
+ HREF="#BigBlock">BigBlock</A>.<BR>The
+ <CODE><I>createPropertyBlockArray</I></CODE>
+ method is used to convert a
+ <CODE>List</CODE> of Property
+ instances into an array of
+ PropertyBlock instances. The number of
+ Property instances is rounded up to a
+ multiple of 4 by creating empty
+ anonymous inner class extensions of
+ Property.</TD>
+ </TR>
+ </TABLE>
+ </LI>
+ <LI>
+ <A NAME="PropertyClasses"><B>Property Classes
+ and Interfaces</B></A>
+ <P>
+ The property classes and interfaces are
+ shown in the following class diagram.
+ </P>
+ <P>
+ <IMG SRC="PropertyTableClassDiagram.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Class/Interface</B></TH>
+ <TH><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="Directory"><B>Directory</B></A></TD>
+ <TD>The <B>Directory</B> interface is
+ implemented by the <A
+ HREF="#RootProperty">RootProperty</A>
+ class. It is not strictly necessary
+ for the initial POIFS implementation,
+ but when the POIFS supports <A
+ HREF="POIFSFormat.html#directoryEntry">directory
+ elements</A>, this interface will be
+ more widely implemented, and so is
+ included in the design at this point
+ to ease the eventual support of
+ directory elements.<BR>Its methods are
+ a getter/setter pair,
+ <CODE><I>getChildren</I></CODE>,
+ returning an <CODE>Iterator</CODE> of
+ <A HREF="#Property">Property</A>
+ instances; and
+ <CODE><I>addChild</I></CODE>, which
+ will allow the caller to add another
+ Property instance to the Directory's
+ children.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="DocumentProperty"><B>DocumentProperty</B></A></TD>
+ <TD>The <B>DocumentProperty</B> class
+ is a trivial extension of <A
+ HREF="#Property">Property</A> and is
+ used by <A
+ HREF="#Document">Document</A> to keep
+ track of its associated entry in the
+ <A
+ HREF="#PropertyTable">PropertyTable</A>.<BR>Its
+ constructor takes a name and the
+ document size, on the assumption that
+ the Document will not create a
+ DocumentProperty until after it has
+ created the storage for the document
+ data and therefore knows how much data
+ there is.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="File"><B>File</B></A></TD>
+ <TD>The <B>File</B> interface
+ specifies the behavior of reading and
+ writing the next and previous child
+ fields of a <A
+ HREF="#Property">Property</A>.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="Property"><B>Property</B></A></TD>
+ <TD>The <B>Property</B> class is an
+ abstract class that defines the basic
+ data structure of an element of the <A
+ HREF="POIFSFormat.html#PropertyTable">Property
+ Table</A>.<BR>Its <A
+ HREF="#ByteField">ByteField</A>, <A
+ HREF="#ShortField">ShortField</A>, and
+ <A
+ HREF="#IntegerField">IntegerField</A>
+ members are used to read and write
+ data into the appropriate locations in
+ the <CODE><I>_raw_data</I></CODE>
+ array.<BR>The
+ <CODE><I>_index</I></CODE> member is
+ used to hold a Propery instance's
+ index in the <CODE>List</CODE> of
+ Property instances maintained by <A
+ HREF="#PropertyTable">PropertyTable</A>,
+ which is used to populate the child
+ property of parent <A
+ HREF="#Directory">Directory</A>
+ properties and the next property and
+ previous property of sibling <A
+ HREF="#File">File</A>
+ properties.<BR>The
+ <CODE><I>_name</I></CODE>,
+ <CODE><I>_next_file</I></CODE>, and
+ <CODE><I>_previous_file</I></CODE>
+ members are used to help fill the
+ appropriate fields of the _raw_data
+ array.<BR>Setters are provided for
+ some of the fields (name, property
+ type, node color, child property,
+ size, index, start block), as well as
+ a few getters (index, child
+ property).<BR>The
+ <CODE><I>preWrite</I></CODE> method is
+ abstract and is used by the owning
+ PropertyTable to iterate through its
+ Property instances and prepare each
+ for writing.<BR>The
+ <CODE><I>shouldUseSmallBlocks</I></CODE>
+ method returns true if the Property's
+ size is sufficiently small - how small
+ is none of the caller's business.
+ </TD>
+ </TR>
+ <TR>
+ <TD><B>PropertyBlock</B></TD>
+ <TD>See the description in <A
+ HREF="#PropertyBlock">PropertyBlock</A>.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="PropertyTable"><B>PropertyTable</B></A></TD>
+ <TD>The <B>PropertyTable</B> class
+ holds all of the <A
+ HREF="#DocumentProperty">DocumentProperty</A>
+ instances and the <A
+ HREF="#RootProperty">RootProperty</A>
+ instance for a <A
+ HREF="#Filesystem">Filesystem</A>
+ instance.<BR>It maintains a
+ <CODE>List</CODE> of its <A
+ HREF="#Property">Property</A>
+ instances
+ (<CODE><I>_properties</I></CODE>), and
+ when prepared to write its data by a
+ call to <CODE><I>preWrite</I></CODE>,
+ it gets and holds an array of <A
+ HREF="#PropertyBlock">PropertyBlock</A>
+ instances
+ (<CODE><I>_blocks</I></CODE>.<BR>It
+ also maintains its start block in its
+ <CODE><I>_start_block</I></CODE>
+ member.<BR>It has a method,
+ <CODE><I>getRoot</I></CODE>, to get
+ the RootProperty, returning it as an
+ implementation of <A
+ HREF="#Directory">Directory</A>, and a
+ method to add a Property,
+ <CODE><I>addProperty</I></CODE>, and a
+ method to get its start block,
+ <CODE><I>getStartBlock</I></CODE>.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="RootProperty"><B>RootProperty</B></A></TD>
+ <TD>The <B>RootProperty</B> class acts
+ as the <A
+ HREF="#Directory">Directory</A> for
+ all of the <A
+ HREF="#DocumentProperty">DocumentProperty</A>
+ instance. As such, it is more of a
+ pure <A
+ HREF="POIFSFormat.html#directoryEntry">directory
+ entry</A> than a proper <A
+ HREF="POIFSFormat.html#RootEntry">root
+ entry</A> in the <A
+ HREF="POIFSFormat.html#PropertyTable">Property
+ Table</A>, but the initial POIFS
+ implementation does not warrant the
+ additional complexity of a full-blown
+ root entry, and so it is not modeled
+ in this design.<BR>It maintains a
+ <CODE>List</CODE> of its children,
+ <CODE><I>_children</I></CODE>, in
+ order to perform its
+ directory-oriented duties.</TD>
+ </TR>
+ </TABLE>
+ </LI>
+ <LI>
+ <A NAME="FilesystemClasses"><B>Filesystem
+ Classes and Interfaces</B></A>
+ <P>
+ The property classes and interfaces are
+ shown in the following class diagram.
+ </P>
+ <P>
+ <IMG SRC="POIFSClassDiagram.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Class/Interface</B></TH>
+ <TH><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="Filesystem"><B>Filesystem</B></A></TD>
+ <TD>The <B>Filesystem</B> class is the
+ top-level class that manages the
+ creation of a POIFS document.<BR>It
+ maintains a <A
+ HREF="#PropertyTable">PropertyTable</A>
+ instance in its
+ <CODE><I>_property_table</I></CODE>
+ member, a <A
+ HREF="#HeaderBlock">HeaderBlock</A>
+ instance in its
+ <CODE><I>_header_block</I></CODE>
+ member, and a <CODE>List</CODE> of its
+ <A HREF="#Document">Document</A>
+ instances in its
+ <CODE><I>_documents</I></CODE>
+ member.<BR>It provides methods for a
+ client to create a document
+ (<CODE><I>createDocument</I></CODE>),
+ and a method to write the Filesystem
+ to an <CODE>OutputStream</CODE>
+ (<CODE><I>writeFilesystem</I></CODE>).</TD>
+ </TR>
+ <TR>
+ <TD><B>BATBlock</B></TD>
+ <TD>See the description in <A
+ HREF="#BATBlock">BATBlock</A></TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="BATManaged"><B>BATManaged</B></A></TD>
+ <TD>The <B>BATManaged</B> interface
+ defines common behavior for objects
+ whose location in the written file is
+ managed by the <A
+ HREF="POIFSFormat.html#BAT">Block
+ Allocation Table</A>.<BR>It defines
+ methods to get a count of the
+ implementation's <A
+ HREF="#BigBlock">BigBlock</A>
+ instances
+ (<CODE><I>countBlocks</I></CODE>), and
+ to set an implementation's start block
+ (<CODE><I>setStartBlock</I></CODE>).</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="BlockAllocationTable"><B>BlockAllocationTable</B></A></TD>
+ <TD>The <B>BlockAllocationTable</B> is
+ an implementation of the POIFS <A
+ HREF="POIFSFormat.html#BAT">Block
+ Allocation Table</A>. It is only
+ created when the <A
+ HREF="#Filesystem">Filesystem</A> is
+ about to be written to an
+ <CODE>OutputStream</CODE>.<BR>It
+ contains an <A
+ HREF="#IntList">IntList</A> of block
+ numbers for all of the <A
+ HREF="#BATManaged">BATManaged</A>
+ implementations owned by the
+ Filesystem,
+ <CODE><I>_entries</I></CODE>, which is
+ filled by calls to
+ <CODE><I>allocateSpace</I></CODE>.<BR>It
+ fills its array,
+ <CODE><I>_blocks</I></CODE>, of <A
+ HREF="#BATBlock">BATBlock</A>
+ instances when its
+ <CODE><I>createBATBlocks</I></CODE>
+ method is called. This method has to
+ take into account its own storage
+ requirements, as well as those of the
+ XBAT blocks, and so calls
+ <CODE><I>BATBlock.calculateStorageRequirements</I></CODE>
+ and
+ <CODE><I>HeaderBlock.calculateXBATStorageRequirements</I></CODE>
+ repeatedly until the counts returned
+ by those methods stabilize.<BR>The
+ <CODE><I>countBlocks</I></CODE> method
+ returns the number of BATBlock
+ instances created by the preceding
+ call to createBlocks.</TD>
+ </TR>
+ <TR>
+ <TD><B>BlockWritable</B></TD>
+ <TD>See the description in <A
+ HREF="#BlockWritable">BlockWritable</A></TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="Document"><B>Document</B></A></TD>
+ <TD>The <B>Document</B> class is used
+ to contain a document, such as an HSSF
+ workbook.<BR>It has its own <A
+ HREF="#DocumentProperty">DocumentProperty</A>
+ (<CODE><I>_property</I></CODE>) and
+ stores its data in a collection of <A
+ HREF="#DocumentBlock">DocumentBlock</A>
+ instances
+ (<CODE><I>_blocks</I></CODE>).<BR>It
+ has a method,
+ <CODE><I>getDocumentProperty</I></CODE>,
+ to get its DocumentProperty.</TD>
+ </TR>
+ <TR>
+ <TD><B>DocumentBlock</B></TD>
+ <TD>See the description in <A
+ HREF="#DocumentBlock">DocumentBlock</A></TD>
+ </TR>
+ <TR>
+ <TD><B>DocumentProperty</B></TD>
+ <TD>See the description in <A
+ HREF="#DocumentProperty">DocumentProperty</A></TD>
+ </TR>
+ <TR>
+ <TD><B>HeaderBlock</B></TD>
+ <TD>See the description in <A
+ HREF="#HeaderBlock">HeaderBlock</A></TD>
+ </TR>
+ <TR>
+ <TD><B>PropertyTable</B></TD>
+ <TD>See the description in <A
+ HREF="#PropertyTable">PropertyTable</A></TD>
+ </TR>
+ </TABLE>
+ </LI>
+ <LI>
+ <A NAME="UtilityClasses"><B>Utility Classes
+ and Interfaces</B></A>
+ <P>
+ The utility classes and interfaces are
+ shown in the following class diagram.
+ </P>
+ <P>
+ <IMG SRC="utilClasses.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Class/Interface</B></TH>
+ <TH><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="BitField"><B>BitField</B></A></TD>
+ <TD>The <B>BitField</B> class is used
+ primarily by HSSF code to manage
+ bit-mapped fields of HSSF records. It
+ is not likely to be used in the POIFS
+ code itself and is only included here
+ for the sake of complete documentation
+ of the POI utility classes.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="ByteField"><B>ByteField</B></A></TD>
+ <TD>The <B>ByteField</B> class is an
+ implementation of <A
+ HREF="#FixedField">FixedField</A> for
+ the purpose of managing reading and
+ writing to a byte-wide field in an
+ array of <CODE>bytes</CODE>.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="FixedField"><B>FixedField</B></A></TD>
+ <TD>The <B>FixedField</B> interface
+ defines a set of methods for reading a
+ field from an array of
+ <CODE>bytes</CODE> or from an
+ <CODE>InputStream</CODE>, and for
+ writing a field to an array of
+ <CODE>bytes</CODE>. Implementations
+ typically require an offset in their
+ constructors that, for the purposes of
+ reading and writing to an array of
+ <CODE>bytes</CODE>, makes sure that
+ the correct <CODE>bytes</CODE> in the
+ array are read or written.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="HexDump"><B>HexDump</B></A></TD>
+ <TD>The <B>HexDump</B> class is a
+ debugging class that can be used to
+ dump an array of <CODE>bytes</CODE> to
+ an <CODE>OutputStream</CODE>. The
+ static method <CODE><I>dump</I></CODE>
+ takes an array of <CODE>bytes</CODE>,
+ a <CODE>long</CODE> offset that is
+ used to label the output, an open
+ <CODE>OutputStream</CODE>, and an
+ <CODE>int</CODE> index that specifies
+ the starting index within the array of
+ <CODE>bytes</CODE>.<BR>The data is
+ displayed 16 bytes per line, with each
+ byte displayed in hexadecimal format
+ and again in printable form, if
+ possible (a byte is considered
+ printable if its value is in the range
+ of 32 ... 126).<BR>Here is an example
+ of a small array of <CODE>bytes</CODE>
+ with an offset of
+ 0x110:<BR><CODE>00000110 C8 00 00 00 FF 7F 90 01 00 00 00 00 00 00 05 01 ................<BR>00000120 41 00 72 00 69 00 61 00 6C 00 A.r.i.a.l.</CODE></TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="IntegerField"><B>IntegerField</B></A></TD>
+ <TD>The <B>IntegerField</B> class is
+ an implementation of <A
+ HREF="#FixedField">FixedField</A> for
+ the purpose of managing reading and
+ writing to an integer-wide field in an
+ array of <CODE>bytes</CODE>.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="IntList"><B>IntList</B></A></TD>
+ <TD>The <B>IntList</B> class is a
+ work-around for functionality missing
+ in Java (see <A
+ HREF="http://developer.java.sun.com/developer/bugParade/bugs/4487555.html">http://developer.java.sun.com/developer/bugParade/bugs/4487555.html</A>
+ for details); it is a simple growable
+ array of <CODE>ints</CODE> that gets
+ around the requirement of wrapping and
+ unwrapping <CODE>ints</CODE> in
+ <CODE>Integer</CODE> instances in
+ order to use the
+ <CODE>java.util.List</CODE>
+ interface.<BR><B>IntList</B> mimics
+ the functionality of the
+ <CODE>java.util.List</CODE> interface
+ as much as possible.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="LittleEndian"><B>LittleEndian</B></A></TD>
+ <TD>The <B>LittleEndian</B> class
+ provides a set of static methods for
+ reading and writing
+ <CODE>shorts</CODE>,
+ <CODE>ints</CODE>, <CODE>longs</CODE>,
+ and <CODE>doubles</CODE> in and out of
+ <CODE>byte</CODE> arrays, and out of
+ <CODE>InputStreams</CODE>, preserving
+ the Intel byte ordering and encoding
+ of these values.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="LittleEndianConsts"><B>LittleEndianConsts</B></A></TD>
+ <TD>The <B>LittleEndianConsts</B>
+ interface defines the width of a
+ <CODE>short</CODE>, <CODE>int</CODE>,
+ <CODE>long</CODE>, and
+ <CODE>double</CODE> as stored by Intel
+ processors.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="LongField"><B>LongField</B></A></TD>
+ <TD>The <B>LongField</B> class is an
+ implementation of <A
+ HREF="#FixedField">FixedField</A> for
+ the purpose of managing reading and
+ writing to a long-wide field in an
+ array of <CODE>bytes</CODE>.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="ShortField"><B>ShortField</B></A></TD>
+ <TD>The <B>ShortField</B> class is an
+ implementation of <A
+ HREF="#FixedField">FixedField</A> for
+ the purpose of managing reading and
+ writing to a short-wide field in an
+ array of <CODE>bytes</CODE>.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="ShortList"><B>ShortList</B></A></TD>
+ <TD>The <B>ShortList</B> class is a
+ work-around for functionality missing
+ in Java (see <A
+ HREF="http://developer.java.sun.com/developer/bugParade/bugs/4487555.html">http://developer.java.sun.com/developer/bugParade/bugs/4487555.html</A>
+ for details); it is a simple growable
+ array of <CODE>shorts</CODE> that gets
+ around the requirement of wrapping and
+ unwrapping <CODE>shorts</CODE> in
+ <CODE>Short</CODE> instances in order
+ to use the <CODE>java.util.List</CODE>
+ interface.<BR> <B>ShortList</B> mimics
+ the functionality of the
+ <CODE>java.util.List</CODE> interface
+ as much as possible.</TD>
+ </TR>
+ <TR>
+ <TD><A
+ NAME="StringUtil"><B>StringUtil</B></A></TD>
+ <TD>The <B>StringUtil</B> class
+ manages the processing of Unicode
+ strings.</TD>
+ </TR>
+ </TABLE>
+ </LI>
+ </OL>
+ <A NAME="Scenarios"><FONT
+ SIZE="+1"><B>Scenarios</B></FONT></A>
+ <P>
+ This section describes the scenarios of how the
+ POIFS classes and interfaces will be used to
+ convert an appropriate XML stream to a POIFS
+ output stream containing an HSSF document.
+ </P>
+ <P>
+ It is broken down as suggested by the following
+ scenario diagram:
+ </P>
+ <P>
+ <IMG SRC="POIFSLifeCycle.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Step</B></TH>
+ <TH><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><B>1</B></TD>
+ <TD><A HREF="Initialization">The Filesystem is
+ created by the client application.</A></TD>
+ </TR>
+ <TR>
+ <TD><B>2</B></TD>
+ <TD><A HREF="CreateDocument">The client
+ application tells the Filesystem to create a
+ document</A>, providing an
+ <CODE>InputStream</CODE> and the name of the
+ document. This may be repeated several
+ times.</TD>
+ </TR>
+ <TR>
+ <TD><B>3</B></TD>
+ <TD><A HREF="Initialization">The client
+ application asks the Filesystem to write its
+ data to an <CODE>OutputStream</CODE>.</A></TD>
+ </TR>
+ </TABLE>
+ <OL>
+ <LI>
+ <P>
+ <A
+ NAME="Initialization">Initialization</A>
+ </P>
+ <P>
+ Initialization of the POIFS system is
+ shown in the following scenario diagram:
+ </P>
+ <P>
+ <IMG SRC="POIFSInitialization.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Step</B></TH>
+ <TH><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><B>1</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A>
+ object, which is created for each
+ request to convert an appropriate XML
+ stream to a POIFS output stream
+ containing an HSSF document, creates
+ its <A
+ HREF="#PropertyTable">PropertyTable</A>.</TD>
+ </TR>
+ <TR>
+ <TD><B>2</B></TD>
+ <TD>The <A
+ HREF="#PropertyTable">PropertyTable</A>
+ creates its <A
+ HREF="#RootProperty">RootProperty</A>
+ instance, making the RootProperty the
+ first <A HREF="#Property">Property</A>
+ in its <CODE>List</CODE> of Property
+ instances.</TD>
+ </TR>
+ <TR>
+ <TD><B>3</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A>
+ creates its <A
+ HREF="#HeaderBlock">HeaderBlock</A>
+ instance. It should be noted that the
+ decision to create the HeaderBlock at
+ Filesystem initialization is
+ arbitrary; creation of the HeaderBlock
+ could easily and harmlessly be
+ postponed to the appropriate moment in
+ <A HREF="#WriteFilesystem">writing the
+ filesystem</A>.</TD>
+ </TR>
+ </TABLE>
+ </LI>
+ <LI>
+ <P>
+ <A NAME="CreateDocument">Creating a
+ Document</A>
+ </P>
+ <P>
+ Creating and adding a document to a POIFS
+ system is shown in the following scenario
+ diagram:
+ </P>
+ <P>
+ <IMG SRC="POIFSAddDocument.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Step</B></TH>
+ <TH><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><B>1</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A>
+ instance creates a new <A
+ HREF="#Document">Document</A>
+ instance. It will store the newly
+ created Document in a
+ <CODE>List</CODE> of <A
+ HREF="#BATManaged">BATManaged</A>
+ instances.</TD>
+ </TR>
+ <TR>
+ <TD><B>2</B></TD>
+ <TD>The <A
+ HREF="#Document">Document</A> reads
+ data from the provided
+ <CODE>InputStream</CODE>, storing the
+ data in <A
+ HREF="#DocumentBlock">DocumentBlock</A>
+ instances. It keeps track of the byte
+ count as it reads the data.</TD>
+ </TR>
+ <TR>
+ <TD><B>3</B></TD>
+ <TD>The <A
+ HREF="#Document">Document</A> creates
+ a <A
+ HREF="#DocumentProperty">DocumentProperty</A>
+ to keep track of its property
+ data. The byte count is stored in the
+ newly created DocumentProperty
+ instance.</TD>
+ </TR>
+ <TR>
+ <TD><B>4</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A>
+ requests the newly created <A
+ HREF="#DocumentProperty">DocumentProperty</A>
+ from the newly created <A
+ HREF="#Document">Document</A>
+ instance.</TD>
+ </TR>
+ <TR>
+ <TD><B>5</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A>
+ sends the newly created <A
+ HREF="#DocumentProperty">DocumentProperty</A>
+ to the Filesystem's <A
+ HREF="#PropertyTable">PropertyTable</A>
+ so that the PropertyTable can add the
+ DocumentProperty to its
+ <CODE>List</CODE> of <A
+ HREF="#Property">Property</A>
+ instances.</TD>
+ </TR>
+ <TR>
+ <TD><B>6</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A> gets
+ the <A
+ HREF="#RootProperty">RootProperty</A>
+ from its <A
+ HREF="#PropertyTable">PropertyTable</A>.</TD>
+ </TR>
+ <TR>
+ <TD><B>7</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A> adds
+ the newly created <A
+ HREF="#DocumentProperty">DocumentProperty</A>
+ to the <A
+ HREF="#RootProperty">RootProperty</A>.</TD>
+ </TR>
+ </TABLE>
+ <P>
+ Although typical deployment of the POIFS
+ system will only entail adding a single <A
+ HREF="#Document">Document</A> (the
+ workbook) to the <A
+ HREF="#Filesystem">Filesystem</A>, there
+ is nothing in the design to prevent
+ multiple Documents from being added to the
+ Filesystem. This flexibility can be
+ employed to write summary information
+ document(s) in addition to the workbook.
+ </P>
+ </LI>
+ <LI>
+ <P>
+ <A NAME="WriteFilesystem">Writing the
+ Filesystem</A>
+ </P>
+ <P>
+ Writing the filesystem is shown in the
+ following scenario diagram:
+ </P>
+ <P>
+ <IMG SRC="POIFSWriteFilesystem.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Step</B></TH>
+ <TH COLSPAN="2"><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><B>1</B></TD>
+ <TD COLSPAN="2">The <A
+ HREF="#Filesystem">Filesystem</A> adds
+ the <A
+ HREF="#PropertyTable">PropertyTable</A>
+ to its <CODE>List</CODE> of <A
+ HREF="#BATManaged">BATManaged</A>
+ instances and calls the
+ PropertyTable's
+ <CODE><I>preWrite</I></CODE>
+ method. The action taken by the
+ PropertyTable is shown in the <A
+ HREF="#PropertyTablePreWrite">PropertyTable
+ preWrite scenario diagram</A>.</TD>
+ </TR>
+ <TR>
+ <TD><B>2</B></TD>
+ <TD COLSPAN="2">The <A
+ HREF="#Filesystem">Filesystem</A>
+ creates the <A
+ HREF="#BlockAllocationTable">BlockAllocationTable</A>.</TD>
+ </TR>
+ <TR>
+ <TD><B>3</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A> gets
+ the block count from the <A
+ HREF="#BATManaged">BATManaged</A>
+ instance.</TD> <TD
+ ROWSPAN="3"><B>These three steps are
+ repeated for each <A
+ HREF="#BATManaged">BATManaged</A>
+ instance in the <A
+ HREF="#Filesystem">Filesystem</A>'s
+ <CODE>List</CODE> of BATManaged
+ instances (i.e., the <A
+ HREF="#Document">Documents</A>, in
+ order of their addition to the
+ Filesystem, followed by the <A
+ HREF="#PropertyTable">PropertyTable</A>).</B></TD>
+ </TR>
+ <TR>
+ <TD><B>4</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A>
+ sends the block count to the <A
+ HREF="#BlockAllocationTable">BlockAllocationTable</A>,
+ which adds the appropriate entries to
+ is <A HREF="#IntList">IntList</A> of
+ entries, returning the starting block
+ for the newly added entries.</TD>
+ </TR>
+ <TR>
+ <TD><B>5</B></TD>
+ <TD>The <A
+ HREF="#Filesystem">Filesystem</A>
+ gives the start block number to the <A
+ HREF="#BATManaged">BATManaged</A>
+ instance. If the BATManaged instance
+ is a <A HREF="#Document">Document</A>,
+ it sets the start block field in its
+ <A
+ HREF="#DocumentProperty">DocumentProperty</A>.</TD>
+ </TR>
+ <TR>
+ <TD><B>6</B></TD>
+ <TD COLSPAN="2">The <A
+ HREF="#Filesystem">Filesystem</A>
+ tells the <A
+ HREF="#BlockAllocationTable">BlockAllocationTable</A>
+ to create its <A
+ HREF="#BATBlock">BatBlocks</A>.</TD>
+ </TR>
+ <TR>
+ <TD><B>7</B></TD>
+ <TD COLSPAN="2">The <A
+ HREF="#Filesystem">Filesystem</A>
+ gives the BAT information to the <A
+ HREF="#HeaderBlock">HeaderBlock</A> so
+ that it can set its BAT fields and, if
+ necessary, create XBAT blocks.</TD>
+ </TR>
+ <TR>
+ <TD><B>8</B></TD>
+ <TD COLSPAN="2">If the filesystem is
+ unusually large (over <B>7MB</B>), the
+ <A HREF="#HeaderBlock">HeaderBlock</A>
+ will create XBAT blocks to contain the
+ BAT data that it cannot hold
+ directly. In this case, the <A
+ HREF="#Filesystem">Filesystem</A>
+ tells the HeaderBlock where those
+ additional blocks will be stored.</TD>
+ </TR>
+ <TR>
+ <TD><B>9</B></TD>
+ <TD COLSPAN="2">The <A
+ HREF="#Filesystem">Filesystem</A>
+ gives the <A
+ HREF="#PropertyTable">PropertyTable</A>
+ start block to the <A
+ HREF="#HeaderBlock">HeaderBlock</A>.</TD>
+ </TR>
+ <TR>
+ <TD><B>10</B></TD>
+ <TD COLSPAN="2">The <A
+ HREF="#Filesystem">Filesystem</A>
+ tells the <A
+ HREF="#BlockWritable">BlockWritable</A>
+ instance to write its blocks to the
+ provided
+ <CODE>OutputStream</CODE>.<BR>This
+ step is repeated for each
+ BlockWritable instance, in this
+ order:<BR>
+ <OL>
+ <LI>
+ The <A
+ HREF="#HeaderBlock">HeaderBlock</A>.
+ </LI>
+ <LI>
+ Each <A
+ HREF="#Document">Document</A>,
+ in the order in which it was
+ added to the <A
+ HREF="#Filesystem">Filesystem</A>.
+ </LI>
+ <LI>
+ The <A
+ HREF="#PropertyTable">PropertyTable</A>.
+ </LI>
+ <LI>
+ The <A
+ HREF="#BlockAllocationTable">BlockAllocationTable</A>
+ </LI>
+ <LI>
+ The XBAT blocks created by the
+ <A
+ HREF="#HeaderBlock">HeaderBlock</A>,
+ if any.
+ </LI>
+ </OL></TD>
+ </TR>
+ </TABLE>
+ <P>
+ <A
+ NAME="PropertyTablePreWrite"><B>PropertyTable
+ preWrite scenario diagram</B></A>
+ </P>
+ <P>
+ <IMG SRC="POIFSPropertyTablePreWrite.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Step</B></TH>
+ <TH><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><B>1</B></TD>
+ <TD>The <A
+ HREF="#PropertyTable">PropertyTable</A>
+ calls <CODE><I>setIndex</I></CODE> for
+ each of its <A
+ HREF="#Property">Property</A>
+ instances, so that each Property now
+ knows its index within the
+ PropertyTable's <CODE>List</CODE> of
+ Property instances.</TD>
+ </TR>
+ <TR>
+ <TD><B>2</B></TD> <TD>The <A
+ HREF="#PropertyTable">PropertyTable</A>
+ requests the <A
+ HREF="#PropertyBlock">PropertyBlock</A>
+ class to create an array of <A
+ HREF="#PropertyBlock">PropertyBlock</A>
+ instances.</TD>
+ </TR>
+ <TR>
+ <TD><B>3</B></TD>
+
+ <TD>The <A
+ HREF="#PropertyBlock">PropertyBlock</A>
+ calculates the number of empty <A
+ HREF="#Property">Property</A>
+ instances it needs to create and
+ creates them. The algorithm for the
+ number to create is:<BR>
+ <CODE>block_count = (properties.size()
+ + 3) / 4;<BR> emptyPropertiesNeeded =
+ (block_count * 4) -
+ properties.size();</CODE></TD>
+ </TR>
+ <TR>
+ <TD><B>4</B></TD> <TD>The <A
+ HREF="#PropertyBlock">PropertyBlock</A>
+ creates the required number of <A
+ HREF="#PropertyBlock">PropertyBlock</A>
+ instances from the <CODE>List</CODE>
+ of <A HREF="#Property">Property</A>
+ instances, including the newly created
+ empty <A HREF="#Property">Property</A>
+ instances.</TD>
+ </TR>
+ <TR>
+ <TD><B>5</B></TD>
+ <TD>The <A
+ HREF="#PropertyTable">PropertyTable</A>
+ calls <CODE><I>preWrite</I></CODE> on
+ each of its <A
+ HREF="#Property">Property</A>
+ instances. For <A
+ HREF="#DocumentProperty">DocumentProperty</A>
+ instances, this call is a no-op. For
+ the <A
+ HREF="#RootProperty">RootProperty</A>,
+ the action taken is shown in the <A
+ HREF="#RootPropertyPreWrite">RootProperty
+ preWrite scenario diagram</A>.</TD>
+ </TR>
+ </TABLE>
+ <P>
+ <A
+ NAME="RootPropertyPreWrite"><B>RootProperty
+ preWrite scenario diagram</B></A>
+ </P>
+ <P>
+ <IMG SRC="POIFSRootPropertyPreWrite.gif">
+ </P>
+ <TABLE BORDER="1">
+ <TR>
+ <TH><B>Step</B></TH>
+ <TH COLSPAN="2"><B>Description</B></TH>
+ </TR>
+ <TR>
+ <TD><B>1</B></TD>
+ <TD COLSPAN="2">The <A
+ HREF="#RootProperty">RootProperty</A>
+ sets its child property with the index
+ of the child <A
+ HREF="#Property">Property</A> that is
+ first in its <CODE>List</CODE> of
+ children.</TD>
+ </TR>
+ <TR>
+ <TD><B>2</B></TD>
+ <TD>The <A
+ HREF="#RootProperty">RootProperty</A>
+ sets its child's next property field
+ with the index of the child's next
+ sibling in the RootProperty's
+ <CODE>List</CODE> of children. If the
+ child is the last in the
+ <CODE>List</CODE>, its next property
+ field is set to <CODE>-1</CODE>.</TD>
+ <TD ROWSPAN="2"><B>These two steps are
+ repeated for each <A
+ HREF="#File">File</A> in the <A
+ HREF="#RootProperty">RootProperty</A>'s
+ <CODE>List</CODE> of
+ children.</B></TD>
+ </TR>
+ <TR>
+ <TD><B>3</B></TD>
+ <TD>The <A
+ HREF="#RootProperty">RootProperty</A>
+ sets its child's previous property
+ field with a value of
+ <CODE>-1</CODE>.</TD>
+ </TR>
+ </TABLE>
+ </LI>
+ </OL>
+ </LI>
+ </OL>
+ </BODY>
+</HTML>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+<document>
+ <header>
+ <title>Apache POI - POIFS - Java implementation of the OLE 2 Compound Document format</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</title>
+ <p>POIFS is a pure Java implementation of the OLE 2 Compound
+ Document format.</p>
+ <p>By definition, all APIs developed by the POI project are
+ based somehow on the POIFS API.</p>
+ <p>A common confusion is on just what POIFS buys you or what OLE
+ 2 Compound Document format is exactly. POIFS does not buy you
+ DOC, or XLS, but is necessary to generate or read DOC or XLS
+ files. You see, all file formats based on the OLE 2 Compound
+ Document Format have a common structure. The OLE 2 Compound
+ Document Format is essentially a convoluted archive
+ format. Think of POIFS as a "zip" library. Once you can get
+ the data in a zip file you still need to interpret the
+ data. As a general rule, while all of our formats <em>use</em>
+ POIFS, most of them attempt to abstract you from it. There
+ are some circumstances where this is not possible, but as a
+ general rule this is true.</p>
+ <p>If you're an end user type just looking to generate XLS
+ files, then you'd be looking for HSSF not POIFS; however, if
+ you have legacy code that uses MFC property sets, POIFS is
+ for you! Regardless, you may or may not need to know how to
+ use POIFS but ultimately if you use technologies that come
+ from the POI project, you're using POIFS underneith. Perhaps
+ we should have a branding campaign "POIFS Inside!". ;-)</p>
+
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+<document>
+ <header>
+ <title>POIFS Use Cases</title>
+ <authors>
+ <person email="mjohnson@apache.org" name="Marc Johnson" id="MJ"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>POIFS Use Cases</title>
+ <section><title>Use Case 1: Read existing file system</title>
+ <table>
+ <tr>
+ <td><em>Primary Actor:</em></td>
+ <td>POIFS client</td>
+ </tr>
+ <tr>
+ <td><em>Scope:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Level:</em></td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td><em>Stakeholders and Interests:</em></td>
+ <td>
+ POIFS client- wants to read content of file
+ system<br/>
+ POIFS - understands POIFS file system
+ </td>
+ </tr>
+ <tr>
+ <td><em>Precondition:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Minimal Guarantee:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Main Success Guarantee:</em></td>
+ <td>
+ 1. POIFS client requests POIFS to read a POIFS file
+ system, providing an
+ <code>InputStream</code>
+ containing POIFS file system in question.<br/>
+ 2. POIFS reads from the
+ <code>InputStream</code> in
+ 512 byte blocks.<br/>
+ 3. POIFS verifies that the first block begins with
+ the well known signature
+ (
+ <code>0xE11AB1A1E011CFD0</code>)<br/>
+ 4. POIFS reads the Block Allocation Table from the
+ first block and, if necessary, from the XBAT
+ blocks.<br/>
+ 5. POIFS obtains the start block of the Property
+ Table and reads the Property Table (use case 9,
+ read file)<br/>
+ 6. POIFS reads the individual entries in the Property
+ Table<br/>
+ 7. POIFS obtains the start block of the Small Block
+ Allocation Table and reads the Small Block
+ Allocation Table (use case 9, read file)<br/>
+ 8. POIFS obtains the start block of the Small Block
+ store from the first entry in the Property Table
+ and reads the Small Block Array (use case 9, read
+ file)<br/>
+ </td>
+ </tr>
+ <tr>
+ <td><em>Extensions:</em></td>
+ <td>
+ 2a. If the last block read is not a 512 byte
+ block, the
+ <code>InputStream</code> is not that of
+ a POIFS file system, and POIFS throws an
+ appropriate exception.
+ <br/>
+ 3a. If the signature is incorrect, the
+ <code>InputStream</code> is not that of a POIFS
+ file system, and POIFS throws an appropriate
+ exception.<br/>
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 2: Write file system</title>
+ <table>
+ <tr>
+ <th>Primary Actor:</th>
+ <th>POIFS client</th>
+ </tr>
+ <tr>
+ <th>Scope:</th>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <th>Level:</th>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <th>Stakeholders and Interests:</th>
+ <td>
+ POIFS client- wants to write file system out.<br/>
+ POIFS - knows how to write file system out.
+ </td>
+ </tr>
+ <tr>
+ <th>Precondition:</th>
+ <td>
+ File system has been read (use case 1, read
+ existing file system) and subsequently modified
+ (use case 4, replace file in file system; use case
+ 5, delete file from file system; or use case 6,
+ write new file to file system; in any
+ combination)
+ <br/>or<br/>
+ File system has been created (use case 3, create
+ new file system)
+ </td>
+ </tr>
+ <tr>
+ <th>Minimal Guarantee:</th>
+ <td>None</td>
+ </tr>
+ <tr>
+ <th>Main Success Guarantee:</th>
+ <td>
+ 1. POIFS client provides an
+ <code>OutputStream</code>
+ to write the file system to.
+ <br/>
+ 2. POIFS gets the sizes of the Property Table and
+ each file in the file system.<br/>
+ 3. If any files in the file system requires storage
+ in a Small Block Array, POIFS creates a Small
+ Block Array of sufficient size to hold all of the
+ small files.<br/>
+ 4. POIFS calculates the number of big blocks needed
+ to hold all of the large files, the Property
+ Table, and, if necessary, the Small Block Array
+ and the Small Block Allocation Table.<br/>
+ 5. POIFS creates a set of big blocks sufficient to
+ store the Block Allocation Table<br/>
+ 6. POIFS creates and writes the header block<br/>
+ 7. POIFS writes out the XBAT blocks, if needed.<br/>
+ 8. POIFS writes out the Small Block Array, if
+ needed<br/>
+ 9. POIFS writes out the Small Block Allocation Table,
+ if needed<br/>
+ 10. POIFS writes out the Property Table<br/>
+ 11. POIFS writes out the large files, if needed<br/>
+ 12. POIFS closes the <code>OutputStream</code>.
+ </td>
+ </tr>
+ <tr>
+ <th>Extensions:</th>
+ <td>
+ 6a. Exceptions writing to the
+ <code>OutputStream</code> will be propagated back
+ to the POIFS client.
+ <br/>
+ 7a. Exceptions writing to the
+ <code>OutputStream</code> will be propagated back
+ to the POIFS client.
+ <br/>
+ 8a. Exceptions writing to the
+ <code>OutputStream</code> will be propagated back
+ to the POIFS client.
+ <br/>
+ 9a. Exceptions writing to the
+ <code>OutputStream</code> will be propagated back
+ to the POIFS client.
+ <br/>
+ 10a. Exceptions writing to the
+ <code>OutputStream</code> will be propagated back
+ to the POIFS client.
+ <br/>
+ 11a. Exceptions writing to the
+ <code>OutputStream</code> will be propagated back
+ to the POIFS client.
+ <br/>
+ 12a. Exceptions closing the
+ <code>OutputStream</code> will be propagated back
+ to the POIFS client.
+ <br/>
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 3: Create new file system</title>
+ <table>
+ <tr>
+ <th>Primary Actor:</th>
+ <td>POIFS client</td>
+ </tr>
+ <tr>
+ <th>Scope:</th>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <th>Level:</th>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <th>Stakeholders and Interests:</th>
+ <td>
+ POIFS client- wants to create a new file
+ system<br/>
+ POIFS - knows how to create a new file system
+ </td>
+ </tr>
+ <tr>
+ <th>Precondition:</th>
+ <td>None</td>
+ </tr>
+ <tr>
+ <th>Minimal Guarantee:</th>
+ <td>None</td>
+ </tr>
+ <tr>
+ <th>Main Success Guarantee:</th>
+ <td>
+ POIFS creates an empty Property Table.
+ </td>
+ </tr>
+ <tr>
+ <th>Extensions:</th>
+ <td>None</td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 4: Replace file in file system</title>
+ <table>
+ <tr>
+ <td><em>Primary Actor:</em></td>
+ <td>POIFS client</td>
+ </tr>
+ <tr>
+ <td><em>Scope:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Level:</em></td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td><em>Stakeholders and Interests:</em></td>
+ <td>
+ 1. POIFS client- wants to replace an existing file in
+ the file system<br/>
+ 2. POIFS - knows how to manage the file system
+ </td>
+ </tr>
+ <tr>
+ <td><em>Precondition:</em></td>
+ <td>
+ Either
+ <br/><br/>
+ The file system has been read (use case 1, read
+ existing file system) and a file has been
+ extracted from the file system (use case 7, read
+ existing file from file system)
+ <br/><br/>or<br/><br/>
+ The file system has been created (use case 3,
+ create new file system) and a file has been
+ written to the file system (use case 6, write new
+ file to file system)
+ </td>
+ </tr>
+ <tr>
+ <td><em>Minimal Guarantee:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Main Success Guarantee:</em></td>
+ <td>
+ 1. POIFS discards storage of the existing file.<br/>
+ 2. POIFS updates the existing file's entry in the
+ Property Table<br/>
+ 3. POIFS stores the new file's data
+ </td>
+ </tr>
+ <tr>
+ <td><em>Extensions:</em></td>
+ <td>
+ 1a. POIFS throws an exception if the file does not
+ exist.
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 5: Delete file from file system</title>
+ <table>
+ <tr>
+ <td><em>Primary Actor:</em></td>
+ <td>POIFS client</td>
+ </tr>
+ <tr>
+ <td><em>Scope:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Level:</em></td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td><em>Stakeholders and Interests:</em></td>
+ <td>
+ * POIFS client- wants to remove a file from a file
+ system<br/>
+ * POIFS - knows how to manage the file system
+ </td>
+ </tr>
+ <tr>
+ <td><em>Precondition:</em></td>
+ <td>
+ Either<br/><br/>
+ The file system has been read (use case 1, read
+ existing file system) and a file has been
+ extracted from the file system (use case 7, read
+ existing file from file system)<br/>
+ <br/>
+ or<br/>
+ <br/>
+ The file system has been created (use case 3,
+ create new file system) and a file has been
+ written to the file system (use case 6, write new
+ file to file system)
+ </td>
+ </tr>
+ <tr>
+ <td><em>Minimal Guarantee:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Main Success Guarantee:</em></td>
+ <td>
+ 1. POIFS discards the specified file's storage.<br/>
+ 2. POIFS discards the file's Property Table
+ entry.
+ </td>
+ </tr>
+ <tr>
+ <td><em>Extensions:</em></td>
+ <td>
+ 1a. POIFS throws an exception if the file does not
+ exist.
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 6: Write new file to file system</title>
+ <table>
+ <tr>
+ <td><em>Primary Actor:</em></td>
+ <td>POIFS client</td>
+ </tr>
+ <tr>
+ <td><em>Scope:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Level:</em></td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td><em>Stakeholders and Interests:</em></td>
+ <td>
+ * POIFS client- wants to add a new file to the file
+ system<br/>
+ * POIFS - knows how to manage the file system
+ </td>
+ </tr>
+ <tr>
+ <td><em>Precondition:</em></td>
+ <td>The specified file does not yet exist in the file
+ system</td>
+ </tr>
+ <tr>
+ <td><em>Minimal Guarantee:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Main Success Guarantee:</em></td>
+ <td>
+ 1. The POIFS client provides a file name<br/>
+ 2. POIFS creates a new Property Table entry for the
+ new file<br/>
+ 3. POIFS provides the POIFS client with an
+ <code>OutputStream</code> to write to.<br/>
+ 4. The POIFS client writes data to the provided
+ <code>OutputStream</code>.<br/>
+ 5. The POIFS client closes the provided
+ <code>OutputStream</code><br/>
+ 6. POIFS updates the Property Table entry with the
+ new file's size
+ </td>
+ </tr>
+ <tr>
+ <td><em>Extensions:</em></td>
+ <td>
+ 1a. POIFS throws an exception if a file with the
+ specified name already exists in the file
+ system.<br/>
+ 1b. POIFS throws an exception if the file name is
+ too long. The limit on file name length is 31
+ characters.
+ </td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 7: Read existing file from file system</title>
+ <table>
+ <tr>
+ <td><em>Primary Actor:</em></td>
+ <td>POIFS client</td>
+ </tr>
+ <tr>
+ <td><em>Scope:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Level:</em></td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td><em>Stakeholders and Interests:</em></td>
+ <td>
+ * POIFS client- wants to read a file from the file
+ system<br/>
+ * POIFS - knows how to manage the file system
+ </td>
+ </tr>
+ <tr>
+ <td><em>Precondition:</em></td>
+ <td>
+ * The file system has been read (use case 1, read
+ existing file system) or has been created and
+ written to (use case 3, create new file system;
+ use case 6, write new file to file system).<br/>
+ * The specified file exists in the file system.
+ </td>
+ </tr>
+ <tr>
+ <td><em>Minimal Guarantee:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Main Success Guarantee:</em></td>
+ <td>
+ * The POIFS client provides the name of a file to be read <br/>
+ * POIFS provides an <code>InputStream</code> to read from. <br/>
+ * The POIFS client reads from the <code>InputStream</code>.<br/>
+ * The POIFS client closes the <code>InputStream</code>.
+ </td>
+ </tr>
+ <tr>
+ <td><em>Extensions:</em></td>
+ <td>1a. POIFS throws an exception if no file with the
+ specified name exists.</td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 8: Read file system directory</title>
+ <table>
+ <tr>
+ <td><em>Primary Actor:</em></td>
+ <td>POIFS client</td>
+ </tr>
+ <tr>
+ <td><em>Scope:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Level:</em></td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td><em>Stakeholders and Interests:</em></td>
+ <td>
+ * POIFS client- wants to know what files exist in
+ the file system<br/>
+ * POIFS - knows how to manage the file system
+ </td>
+ </tr>
+ <tr>
+ <td><em>Precondition:</em></td>
+ <td>The file system has been read (use case 1, read
+ existing file system) or created (use case 3, create
+ new file system)</td>
+ </tr>
+ <tr>
+ <td><em>Minimal Guarantee:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Main Success Guarantee:</em></td>
+ <td>
+ 1. The POIFS client requests the file system
+ directory.
+ 2. POIFS returns an <code>Iterator</code>. The
+ <code>Iterator</code> will not include the root
+ entry in the Property Table, and may be an
+ <code>Iterator</code> over an empty
+ <code>Collection</code>.
+ </td>
+ </tr>
+ <tr>
+ <td><em>Extensions:</em></td>
+ <td>None</td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 9: Read file</title>
+ <table>
+ <tr>
+ <td><em>Primary Actor:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Scope:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Level:</em></td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td><em>Stakeholders and Interests:</em></td>
+ <td>
+ POIFS - POIFS needs to read a file, or something
+ resembling a file (i.e., the Property Table, the
+ Small Block Array, or the Small Block Allocation
+ Table)
+ </td>
+ </tr>
+ <tr>
+ <td><em>Precondition:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Minimal Guarantee:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Main Success Guarantee:</em></td>
+ <td>
+ 1. POIFS begins with a start block, a file size, and
+ a flag indicating whether to use the Big Block
+ Allocation Table or the Small Block Allocation
+ Table<br/>
+ 2. POIFS returns an <code>InputStream</code>.<br/>
+ 3. Reads from the <code>InputStream</code> are
+ performed by walking the specified Block
+ Allocation Table and reading the blocks
+ indicated.<br/>
+ 4. POIFS closes the <code>InputStream</code> when
+ finished reading the file, or its client wants to
+ close the <code>InputStream</code>.
+ </td>
+ </tr>
+ <tr>
+ <td><em>Extensions:</em></td>
+ <td>3a. An exception will be thrown if the specified Block
+ Allocation Table is corrupt, as evidenced by an index
+ pointing to a non-existent block, or by a chain
+ extending past the known size of the file.</td>
+ </tr>
+ </table>
+ </section>
+ <section><title>Use Case 10: Rename existing file in the file system</title>
+ <table>
+ <tr>
+ <td><em>Primary Actor:</em></td>
+ <td>POIFS client</td>
+ </tr>
+ <tr>
+ <td><em>Scope:</em></td>
+ <td>POIFS</td>
+ </tr>
+ <tr>
+ <td><em>Level:</em></td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td><em>Stakeholders and Interests:</em></td>
+ <td>
+ * POIFS client- wants to rename an existing file in
+ the file system.<br/>
+ * POIFS - knows how to manage the file system.
+ </td>
+ </tr>
+ <tr>
+ <td><em>Precondition:</em></td>
+ <td>
+ * The file system is has been read (use case 1, read
+ existing file system) or has been created and
+ written to (use case 3, create new file system;
+ use case 6, write new file to file system.<br/>
+ * The specified file exists in the file system.<br/>
+ * The new name for the file does not duplicate
+ another file in the file system.
+ </td>
+ </tr>
+ <tr>
+ <td><em>Minimal Guarantee:</em></td>
+ <td>None</td>
+ </tr>
+ <tr>
+ <td><em>Main Success Guarantee:</em></td>
+ <td>
+ 1. POIFS updates the Property Table entry for the
+ specified file with its new name.
+ </td>
+ </tr>
+ <tr>
+ <td><em>Extensions:</em></td>
+ <td>
+ * 1a. If the old file name is not in the file
+ system, POIFS throws an exception.<br/>
+ * 1b. If the new file name already exists in the
+ file system, POIFS throws an exception.<br/>
+ * 1c. If the new file name is too long (the limit is
+ 31 characters), POIFS throws an exception.
+ </td>
+ </tr>
+ </table>
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "./dtd/book-cocoon-v10.dtd">
+
+<book software="POI"
+ title="POI Project Documentation"
+ copyright="@year@ POI Project"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="References">
+ <menu-item label="Live Sites" href="index.html"/>
+ <menu-item label="XLS spec [PDF]" href="http://sc.openoffice.org/excelfileformat.pdf"/>
+ <menu-item label="Apache Cocoon" href="http://xml.apache.org/cocoon/"/>
+ </menu>
+
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Live Sites using Poi</title>
+ <authors>
+ <person name="Donald Ball" email="balld@webslingerZ.com"/>
+ <person name="Stefano Mazzocchi" email="stefano@apache.org"/>
+ <person name="Robin Green" email="greenrd@hotmail.com"/>
+ <person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ <person name="Glen Stampoultzis" email="user@poi.apache.org"/>
+ <person name="Rainer Klute" email="klute@rainer-klute.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>References</title>
+
+ <section><title>Live Sites using POI</title>
+ <p>Currently we don't have any sites listed that use POI, but we're
+ sure they're out there. Help us change this. If you've written a site
+ that utilises POI let us know.</p>
+ <!--
+ <ul>
+ <li><link href=""></link></li>
+ </ul>
+ -->
+ </section>
+
+ <section><title>Products/Projects using POI</title>
+ <p>Publically available products/projects using POI include:</p>
+ <ul>
+ <li><link href="http://jtimetracker.sourceforge.net/">JTimeTracker</link></li>
+ </ul>
+ </section>
+
+ <section><title>File Format Descriptions</title>
+ <p>POI depends on publically available documents describing various
+ file formats. The list below contains links to some of them.</p>
+ <ul>
+ <li><link href="http://www.wotsit.org/">Wotsit's Format</link></li>
+ </ul>
+ </section>
+
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="Resolutions"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="About">
+ <menu-item label="About" href="index.html"/>
+ </menu>
+
+ <menu label="Resolutions">
+ <menu-item label="Coding Standards" href="res001.html"/>
+ </menu>
+
+</book>
+
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Resolutions</title>
+ <subtitle>About this section</subtitle>
+ <authors>
+ <person name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>About Resolutions</title>
+ <p>
+ Every project in Apache has resolutions that they vote on.
+ Decisions are made, etc. But what happens once those decisions
+ are made? They are archived in the mail list archive never to
+ be read again (once its not in the top 10 or so posts). So they
+ get discussed again and again.
+ </p>
+ <p>
+ Rather than have that big waste of time, we have this section to
+ record important POI decisions. Once a decision is passed it
+ need only be linked to this page (either by creating a page for
+ it or by simply linking it to the archive messages). Wherever
+ possible a brief about how many votes for and against an maybe
+ some background should be posted.
+ </p>
+ <p>
+ This section is intended mainly to reduce big waste of time
+ discussions from taking away from whats important...developing
+ POI! :-D
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI Resoluton</title>
+ <subtitle>Resolution 001 - Minimal Coding Standards</subtitle>
+ <authors>
+ <person name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Resolution 001 - Minimal Coding Standards</title>
+ <section><title>Majority Position</title>
+ <p>
+ As the POI project has grown the "styles" used have become more
+ varied, some see this as a bad thing, but in reality it
+ can be a good thing. Each can learn from the different
+ styles by working with different code. That being said
+ there are some universal "good quality" guidelines that
+ must be adopted on a project of any proportions.
+ </p>
+ <p>
+ Marc Johnson Authored the following resolution:
+ </p>
+ <p>
+ On Tue, 2002-01-08 at 22:23, Marc Johnson wrote:
+ Standards are wonderful; everyone should have a set.
+ Here's what I propose for coding standards for POI WRT comments (should I
+ feel the need, I'll post more of these little gems):
+ </p>
+ <ol>
+ <li>
+ All classes and interfaces MUST have, right at the
+ beginning of the file, the Apache Software License
+ 2.0 License Header. (see /legal/LICENSE).
+ </li>
+ <li>
+ All classes and interfaces MUST include class javadoc. Conventionally,
+ this goes after the package and imports, and before the start of the class
+ or interface.
+ <!-- No more author tags -->
+ <!-- The class javadoc MUST have at least one @author tag -->
+ </li>
+ <li>
+ All methods that are accessible outside the class MUST have javadoc
+ comments. In other words, if it isn't private, it MUST have javadoc
+ comments. Simple getters can consist of a simple @return tag; simple setters
+ can consist of a simple @param tag. Anything else requires some verbiage
+ plus all the standard javadoc tags as appropriate. You MUST include @throws
+ or @exception for any non-runtime exceptions, and you SHOULD document any
+ runtime exceptions you expect to throw. @throws/@exception tags SHOULD
+ include an explanation of why that exception would be thrown. If your method
+ might return null, you MUST say so. An accompanying explanation of the
+ circumstances for doing so would be nice.
+ </li>
+ </ol>
+ </section>
+ <section><title>Amendments (informal by extension and not by vote)</title>
+ <section><title>License</title>
+ <p>
+ As opposed to the formerly used POI License (which was
+ based on the Apache Public License), now that POI is
+ part of Apache, use the standard Apache Software
+ License 2.0 header. As per standard Apache Software
+ Foundation policy, the full (long) version of the
+ header should be used.
+ </p>
+ </section>
+ <section><title>2 cents</title>
+ <p>
+ Tip: No laughing or joking allowed in conversations regarding coding
+ standards.
+ Any mail on coding standards will be treated very seriously,
+ and sent here with a RTFM.
+ </p>
+ </section>
+ </section>
+ <section><title>Dissent</title>
+ <p>
+ The motion was passed unanimously with no negative or
+ neutral votes.
+ </p>
+ </section>
+ <section><title>Comments</title>
+ <p>
+ Andy didn't feel like going through his mail and sucking
+ out the comments.. If there is anything you feel should
+ be added here do it yourself ;-).
+ </p>
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<!--
+Forrest site.xml
+
+This file contains an outline of the site's information content. It is used to:
+- Generate the website menus (though these can be overridden - see docs)
+- Provide semantic, location-independent aliases for internal 'site:' URIs, eg
+<link href="site:changes"> links to changes.html (or ../changes.html if in
+ subdir).
+- Provide aliases for external URLs in the external-refs section. Eg, <link
+ href="ext:cocoon"> links to http://xml.apache.org/cocoon/
+
+See http://xml.apache.org/forrest/linking.html for more info
+-->
+
+<site label="POI" href="" xmlns="http://apache.org/forrest/linkmap/1.0">
+
+ <external-refs>
+ <xml.apache.org href="http://xml.apache.org/">
+ <forrest href="forrest/">
+ <validation href="validation.html"/>
+ <webapp href="your-project.html#webapp"/>
+ </forrest>
+ <cocoon href="cocoon/"/>
+ </xml.apache.org>
+ <junit href="junit/index.html"/>
+ <jdepend href="jdepend/index.html"/>
+ <javadoc href="apidocs/index.html"/>
+ <download href="http://www.apache.org/dyn/closer.cgi/poi/"/>
+ </external-refs>
+
+</site>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="HSLF"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="HSLF">
+ <menu-item label="Overview" href="index.html"/>
+ <menu-item label="Quick Guide" href="quick-guide.html"/>
+ <menu-item label="HSLF Cookbok" href="how-to-shapes.html"/>
+ <menu-item label="XSLF Cookbok" href="xslf-cookbook.html"/>
+ <menu-item label="PPT File Format" href="ppt-file-format.html"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Busy Developers' Guide to HSLF drawing layer</title>
+ <authors>
+ <person email="yegor@dinom.ru" name="Yegor Kozlov" id="CO"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Busy Developers' Guide to HSLF drawing layer</title>
+ <section><title>Index of Features</title>
+ <ul>
+ <li><link href="#NewPresentation">How to create a new presentation and add new slides to it</link></li>
+ <li><link href="#PageSize">How to retrieve or change slide size</link></li>
+ <li><link href="#GetShapes">How to get shapes contained in a particular slide</link></li>
+ <li><link href="#Shapes">Drawing a shape on a slide</link></li>
+ <li><link href="#Pictures">How to work with pictures</link></li>
+ <li><link href="#SlideTitle">How to set slide title</link></li>
+ <li><link href="#Fill">How to work with slide/shape background</link></li>
+ <li><link href="#Bullets">How to create bulleted lists</link></li>
+ <li><link href="#Hyperlinks">Hyperlinks</link></li>
+ <li><link href="#Tables">Tables</link></li>
+ <li><link href="#RemoveShape">How to remove shapes</link></li>
+ <li><link href="#OLE">How to retrieve embedded OLE objects</link></li>
+ <li><link href="#Sound">How to retrieve embedded sounds</link></li>
+ <li><link href="#Freeform">How to create shapes of arbitrary geometry</link></li>
+ <li><link href="#Graphics2D">Shapes and Graphics2D</link></li>
+ <li><link href="#Render">How to convert slides into images</link></li>
+ <li><link href="#HeadersFooters">Headers / Footers</link></li>
+ </ul>
+ </section>
+ <section><title>Features</title>
+ <anchor id="NewPresentation"/>
+ <section><title>New Presentation</title>
+ <source>
+ //create a new empty slide show
+ SlideShow ppt = new SlideShow();
+
+ //add first slide
+ Slide s1 = ppt.createSlide();
+
+ //add second slide
+ Slide s2 = ppt.createSlide();
+
+ //save changes in a file
+ FileOutputStream out = new FileOutputStream("slideshow.ppt");
+ ppt.write(out);
+ out.close();
+ </source>
+ </section>
+ <anchor id="PageSize"/>
+ <section><title>How to retrieve or change slide size</title>
+ <source>
+ SlideShow ppt = new SlideShow(new HSLFSlideShow("slideshow.ppt"));
+ //retrieve page size. Coordinates are expressed in points (72 dpi)
+ java.awt.Dimension pgsize = ppt.getPageSize();
+ int pgx = pgsize.width; //slide width
+ int pgy = pgsize.height; //slide height
+
+ //set new page size
+ ppt.setPageSize(new java.awt.Dimension(1024, 768));
+ //save changes
+ FileOutputStream out = new FileOutputStream("slideshow.ppt");
+ ppt.write(out);
+ out.close();
+ </source>
+ </section>
+ <anchor id="GetShapes"/>
+ <section><title>How to get shapes contained in a particular slide</title>
+ <p>
+ The following code demonstrates how to iterate over shapes for each slide.
+ </p>
+ <source>
+ SlideShow ppt = new SlideShow(new HSLFSlideShow("slideshow.ppt"));
+ //get slides
+ Slide[] slide = ppt.getSlides();
+ for (int i = 0; i < slide.length; i++){
+ Shape[] sh = slide[i].getShapes();
+ for (int j = 0; j < sh.length; j++){
+ //name of the shape
+ String name = sh[j].getShapeName();
+
+ //shapes's anchor which defines the position of this shape in the slide
+ java.awt.Rectangle anchor = sh[j].getAnchor();
+
+ if (sh[j] instanceof Line){
+ Line line = (Line)sh[j];
+ //work with Line
+ } else if (sh[j] instanceof AutoShape){
+ AutoShape shape = (AutoShape)sh[j];
+ //work with AutoShape
+ } else if (sh[j] instanceof TextBox){
+ TextBox shape = (TextBox)sh[j];
+ //work with TextBox
+ } else if (sh[j] instanceof Picture){
+ Picture shape = (Picture)sh[j];
+ //work with Picture
+ }
+ }
+ }
+ </source>
+ </section>
+ <anchor id="Shapes"/>
+ <section><title>Drawing a shape on a slide</title>
+ <warning>
+ To work with graphic objects HSLF uses Java2D classes
+ that may throw exceptions if graphical environment is not available. In case if graphical environment
+ is not available, you must tell Java that you are running in headless mode and
+ set the following system property: <code> java.awt.headless=true </code>
+ (either via <code>-Djava.awt.headless=true</code> startup parameter or via <code>System.setProperty("java.awt.headless", "true")</code>).
+ </warning>
+ <p>
+ When you add a shape, you usually specify the dimensions of the shape and the position
+ of the upper left corner of the bounding box for the shape relative to the upper left
+ corner of the slide. Distances in the drawing layer are measured in points (72 points = 1 inch).
+ </p>
+ <source>
+ SlideShow ppt = new SlideShow();
+
+ Slide slide = ppt.createSlide();
+
+ //Line shape
+ Line line = new Line();
+ line.setAnchor(new java.awt.Rectangle(50, 50, 100, 20));
+ line.setLineColor(new Color(0, 128, 0));
+ line.setLineStyle(Line.LINE_DOUBLE);
+ slide.addShape(line);
+
+ //TextBox
+ TextBox txt = new TextBox();
+ txt.setText("Hello, World!");
+ txt.setAnchor(new java.awt.Rectangle(300, 100, 300, 50));
+
+ //use RichTextRun to work with the text format
+ RichTextRun rt = txt.getTextRun().getRichTextRuns()[0];
+ rt.setFontSize(32);
+ rt.setFontName("Arial");
+ rt.setBold(true);
+ rt.setItalic(true);
+ rt.setUnderlined(true);
+ rt.setFontColor(Color.red);
+ rt.setAlignment(TextBox.AlignRight);
+
+ slide.addShape(txt);
+
+ //Autoshape
+ //32-point star
+ AutoShape sh1 = new AutoShape(ShapeTypes.Star32);
+ sh1.setAnchor(new java.awt.Rectangle(50, 50, 100, 200));
+ sh1.setFillColor(Color.red);
+ slide.addShape(sh1);
+
+ //Trapezoid
+ AutoShape sh2 = new AutoShape(ShapeTypes.Trapezoid);
+ sh2.setAnchor(new java.awt.Rectangle(150, 150, 100, 200));
+ sh2.setFillColor(Color.blue);
+ slide.addShape(sh2);
+
+ FileOutputStream out = new FileOutputStream("slideshow.ppt");
+ ppt.write(out);
+ out.close();
+
+ </source>
+ </section>
+ <anchor id="Pictures"/>
+ <section><title>How to work with pictures</title>
+
+ <p>
+ Currently, HSLF API supports the following types of pictures:
+ </p>
+ <ul>
+ <li>Windows Metafiles (WMF)</li>
+ <li>Enhanced Metafiles (EMF)</li>
+ <li>JPEG Interchange Format</li>
+ <li>Portable Network Graphics (PNG)</li>
+ <li>Macintosh PICT</li>
+ </ul>
+
+ <source>
+ SlideShow ppt = new SlideShow(new HSLFSlideShow("slideshow.ppt"));
+
+ //extract all pictures contained in the presentation
+ PictureData[] pdata = ppt.getPictureData();
+ for (int i = 0; i < pdata.length; i++){
+ PictureData pict = pdata[i];
+
+ // picture data
+ byte[] data = pict.getData();
+
+ int type = pict.getType();
+ String ext;
+ switch (type){
+ case Picture.JPEG: ext=".jpg"; break;
+ case Picture.PNG: ext=".png"; break;
+ case Picture.WMF: ext=".wmf"; break;
+ case Picture.EMF: ext=".emf"; break;
+ case Picture.PICT: ext=".pict"; break;
+ default: continue;
+ }
+ FileOutputStream out = new FileOutputStream("pict_"+i + ext);
+ out.write(data);
+ out.close();
+
+ }
+
+ // add a new picture to this slideshow and insert it in a new slide
+ int idx = ppt.addPicture(new File("clock.jpg"), Picture.JPEG);
+
+ Picture pict = new Picture(idx);
+
+ //set image position in the slide
+ pict.setAnchor(new java.awt.Rectangle(100, 100, 300, 200));
+
+ Slide slide = ppt.createSlide();
+ slide.addShape(pict);
+
+ //now retrieve pictures containes in the first slide and save them on disk
+ slide = ppt.getSlides()[0];
+ Shape[] sh = slide.getShapes();
+ for (int i = 0; i < sh.length; i++){
+ if (sh[i] instanceof Picture){
+ Picture pict = (Picture)sh[i];
+ PictureData pictData = pict.getPictureData();
+ byte[] data = pictData.getData();
+ int type = pictData.getType();
+ if (type == Picture.JPEG){
+ FileOutputStream out = new FileOutputStream("slide0_"+i+".jpg");
+ out.write(data);
+ out.close();
+ } else if (type == Picture.PNG){
+ FileOutputStream out = new FileOutputStream("slide0_"+i+".png");
+ out.write(data);
+ out.close();
+ }
+ }
+ }
+
+ FileOutputStream out = new FileOutputStream("slideshow.ppt");
+ ppt.write(out);
+ out.close();
+
+ </source>
+ </section>
+ <anchor id="SlideTitle"/>
+ <section><title>How to set slide title</title>
+ <source>
+ SlideShow ppt = new SlideShow();
+ Slide slide = ppt.createSlide();
+ TextBox title = slide.addTitle();
+ title.setText("Hello, World!");
+
+ //save changes
+ FileOutputStream out = new FileOutputStream("slideshow.ppt");
+ ppt.write(out);
+ out.close();
+ </source>
+ <p>
+ Below is the equivalent code in PowerPoint VBA:
+ </p>
+ <source>
+ Set myDocument = ActivePresentation.Slides(1)
+ myDocument.Shapes.AddTitle.TextFrame.TextRange.Text = "Hello, World!"
+ </source>
+ </section>
+ <anchor id="Fill"/>
+ <section><title>How to modify background of a slide master</title>
+ <source>
+ SlideShow ppt = new SlideShow();
+ SlideMaster master = ppt.getSlidesMasters()[0];
+
+ Fill fill = master.getBackground().getFill();
+ int idx = ppt.addPicture(new File("background.png"), Picture.PNG);
+ fill.setFillType(Fill.FILL_PICTURE);
+ fill.setPictureData(idx);
+ </source>
+ </section>
+ <section><title>How to modify background of a slide</title>
+ <source>
+ SlideShow ppt = new SlideShow();
+ Slide slide = ppt.createSlide();
+
+ //This slide has its own background.
+ //Without this line it will use master's background.
+ slide.setFollowMasterBackground(false);
+ Fill fill = slide.getBackground().getFill();
+ int idx = ppt.addPicture(new File("background.png"), Picture.PNG);
+ fill.setFillType(Fill.FILL_PATTERN);
+ fill.setPictureData(idx);
+ </source>
+ </section>
+ <section><title>How to modify background of a shape</title>
+ <source>
+ SlideShow ppt = new SlideShow();
+ Slide slide = ppt.createSlide();
+
+ Shape shape = new AutoShape(ShapeTypes.Rectangle);
+ shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200));
+ Fill fill = shape.getFill();
+ fill.setFillType(Fill.FILL_SHADE);
+ fill.setBackgroundColor(Color.red);
+ fill.setForegroundColor(Color.green);
+
+ slide.addShape(shape);
+ </source>
+ </section>
+ <anchor id="Bullets"/>
+ <section><title>How to create bulleted lists</title>
+ <source>
+ SlideShow ppt = new SlideShow();
+
+ Slide slide = ppt.createSlide();
+
+ TextBox shape = new TextBox();
+ RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];
+ shape.setText(
+ "January\r" +
+ "February\r" +
+ "March\r" +
+ "April");
+ rt.setFontSize(42);
+ rt.setBullet(true);
+ rt.setBulletOffset(0); //bullet offset
+ rt.setTextOffset(50); //text offset (should be greater than bullet offset)
+ rt.setBulletChar('\u263A'); //bullet character
+ slide.addShape(shape);
+
+ shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300)); //position of the text box in the slide
+ slide.addShape(shape);
+
+ FileOutputStream out = new FileOutputStream("bullets.ppt");
+ ppt.write(out);
+ out.close();
+ </source>
+ </section>
+ <anchor id="Hyperlinks"/>
+ <section><title>How to read hyperlinks from a slide show</title>
+ <source>
+ FileInputStream is = new FileInputStream("slideshow.ppt");
+ SlideShow ppt = new SlideShow(is);
+ is.close();
+
+ Slide[] slide = ppt.getSlides();
+ for (int j = 0; j < slide.length; j++) {
+
+ //read hyperlinks from the text runs
+ TextRun[] txt = slide[j].getTextRuns();
+ for (int k = 0; k < txt.length; k++) {
+ String text = txt[k].getText();
+ Hyperlink[] links = txt[k].getHyperlinks();
+ if(links != null) for (int l = 0; l < links.length; l++) {
+ Hyperlink link = links[l];
+ String title = link.getTitle();
+ String address = link.getAddress();
+ String substring = text.substring(link.getStartIndex(), link.getEndIndex()-1); //in ppt end index is inclusive
+ }
+ }
+
+ //in PowerPoint you can assign a hyperlink to a shape without text,
+ //for example to a Line object. The code below demonstrates how to
+ //read such hyperlinks
+ Shape[] sh = slide[j].getShapes();
+ for (int k = 0; k < sh.length; k++) {
+ Hyperlink link = sh[k].getHyperlink();
+ if(link != null) {
+ String title = link.getTitle();
+ String address = link.getAddress();
+ }
+ }
+ }
+ </source>
+ </section>
+ <anchor id="Tables"/>
+ <section><title>How to create tables</title>
+ <source>
+ //table data
+ String[][] data = {
+ {"INPUT FILE", "NUMBER OF RECORDS"},
+ {"Item File", "11,559"},
+ {"Vendor File", "300"},
+ {"Purchase History File", "10,000"},
+ {"Total # of requisitions", "10,200,038"}
+ };
+
+ SlideShow ppt = new SlideShow();
+
+ Slide slide = ppt.createSlide();
+ //create a table of 5 rows and 2 columns
+ Table table = new Table(5, 2);
+ for (int i = 0; i < data.length; i++) {
+ for (int j = 0; j < data[i].length; j++) {
+ TableCell cell = table.getCell(i, j);
+ cell.setText(data[i][j]);
+
+ RichTextRun rt = cell.getTextRun().getRichTextRuns()[0];
+ rt.setFontName("Arial");
+ rt.setFontSize(10);
+
+ cell.setVerticalAlignment(TextBox.AnchorMiddle);
+ cell.setHorizontalAlignment(TextBox.AlignCenter);
+ }
+ }
+
+ //set table borders
+ Line border = table.createBorder();
+ border.setLineColor(Color.black);
+ border.setLineWidth(1.0);
+ table.setAllBorders(border);
+
+ //set width of the 1st column
+ table.setColumnWidth(0, 300);
+ //set width of the 2nd column
+ table.setColumnWidth(1, 150);
+
+ slide.addShape(table);
+ table.moveTo(100, 100);
+
+ FileOutputStream out = new FileOutputStream("hslf-table.ppt");
+ ppt.write(out);
+ out.close();
+
+ </source>
+ </section>
+
+ <anchor id="RemoveShape"/>
+ <section><title>How to remove shapes from a slide</title>
+ <source>
+
+ Shape[] shape = slide.getShapes();
+ for (int i = 0; i < shape.length; i++) {
+
+ //remove the shape
+ boolean ok = slide.removeShape(shape[i]);
+ if(ok){
+ //the shape was removed. Do something.
+ }
+ }
+ </source>
+ </section>
+ <anchor id="OLE"/>
+ <section><title>How to retrieve embedded OLE objects</title>
+ <source>
+
+ Shape[] shape = slide.getShapes();
+ for (int i = 0; i < shape.length; i++) {
+ if (shape[i] instanceof OLEShape) {
+ OLEShape ole = (OLEShape) shape[i];
+ ObjectData data = ole.getObjectData();
+ String name = ole.getInstanceName();
+ if ("Worksheet".equals(name)) {
+ HSSFWorkbook wb = new HSSFWorkbook(data.getData());
+ } else if ("Document".equals(name)) {
+ HWPFDocument doc = new HWPFDocument(data.getData());
+ }
+ }
+ }
+ </source>
+ </section>
+
+ <anchor id="Sound"/>
+ <section><title>How to retrieve embedded sounds</title>
+ <source>
+
+ FileInputStream is = new FileInputStream(args[0]);
+ SlideShow ppt = new SlideShow(is);
+ is.close();
+
+ SoundData[] sound = ppt.getSoundData();
+ for (int i = 0; i < sound.length; i++) {
+ //save *WAV sounds on disk
+ if(sound[i].getSoundType().equals(".WAV")){
+ FileOutputStream out = new FileOutputStream(sound[i].getSoundName());
+ out.write(sound[i].getData());
+ out.close();
+ }
+ }
+ </source>
+ </section>
+
+ <anchor id="Freeform"/>
+ <section><title>How to create shapes of arbitrary geometry</title>
+ <source>
+
+ SlideShow ppt = new SlideShow();
+ Slide slide = ppt.createSlide();
+
+ java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath();
+ path.moveTo(100, 100);
+ path.lineTo(200, 100);
+ path.curveTo(50, 45, 134, 22, 78, 133);
+ path.curveTo(10, 45, 134, 56, 78, 100);
+ path.lineTo(100, 200);
+ path.closePath();
+
+ Freeform shape = new Freeform();
+ shape.setPath(path);
+ slide.addShape(shape);
+ </source>
+ </section>
+
+ <anchor id="Graphics2D"/>
+ <section><title>How to draw into a slide using Graphics2D</title>
+ <warning>
+ Current implementation of the PowerPoint Graphics2D driver is not fully compliant with the java.awt.Graphics2D specification.
+ Some features like clipping, drawing of images are not yet supported.
+ </warning>
+ <source>
+ SlideShow ppt = new SlideShow();
+ Slide slide = ppt.createSlide();
+
+ //draw a simple bar graph
+ //bar chart data. The first value is the bar color, the second is the width
+ Object[] def = new Object[]{
+ Color.yellow, new Integer(100),
+ Color.green, new Integer(150),
+ Color.gray, new Integer(75),
+ Color.red, new Integer(200),
+ };
+
+ //all objects are drawn into a shape group so we need to create one
+
+ ShapeGroup group = new ShapeGroup();
+ //define position of the drawing in the slide
+ Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);
+ //if you want to draw in the entire slide area then define the anchor as follows:
+ //Dimension pgsize = ppt.getPageSize();
+ //java.awt.Rectangle bounds = new java.awt.Rectangle(0, 0, pgsize.width, pgsize.height);
+
+ group.setAnchor(bounds);
+ slide.addShape(group);
+
+ //draw a simple bar chart
+ Graphics2D graphics = new PPGraphics2D(group);
+ int x = bounds.x + 50, y = bounds.y + 50;
+ graphics.setFont(new Font("Arial", Font.BOLD, 10));
+ for (int i = 0, idx = 1; i < def.length; i+=2, idx++) {
+ graphics.setColor(Color.black);
+ int width = ((Integer)def[i+1]).intValue();
+ graphics.drawString("Q" + idx, x-20, y+20);
+ graphics.drawString(width + "%", x + width + 10, y + 20);
+ graphics.setColor((Color)def[i]);
+ graphics.fill(new Rectangle(x, y, width, 30));
+ y += 40;
+ }
+ graphics.setColor(Color.black);
+ graphics.setFont(new Font("Arial", Font.BOLD, 14));
+ graphics.draw(bounds);
+ graphics.drawString("Performance", x + 70, y + 40);
+
+ FileOutputStream out = new FileOutputStream("hslf-graphics2d.ppt");
+ ppt.write(out);
+ out.close();
+
+ </source>
+ </section>
+
+ <anchor id="Render"/>
+ <section><title>Export PowerPoint slides into java.awt.Graphics2D</title>
+ <p>
+ HSLF provides a way to export slides into images. You can capture slides into java.awt.Graphics2D object (or any other)
+ and serialize it into a PNG or JPEG format. Please note, although HSLF attempts to render slides as close to PowerPoint as possible,
+ the output may look differently from PowerPoint due to the following reasons:
+ </p>
+ <ul>
+ <li>Java2D renders fonts differently vs PowerPoint. There are always some differences in the way the font glyphs are painted</li>
+ <li>HSLF uses java.awt.font.LineBreakMeasurer to break text into lines. PowerPoint may do it in a different way.</li>
+ <li>If a font from the presentation is not avaiable, then the JDK default font will be used.</li>
+ </ul>
+ <p>
+ Current Limitations:
+ </p>
+ <ul>
+ <li>Some types of shapes are not yet supported (WordArt, complex auto-shapes)</li>
+ <li>Only Bitmap images (PNG, JPEG, DIB) can be rendered in Java</li>
+ </ul>
+ <source>
+ FileInputStream is = new FileInputStream("slideshow.ppt");
+ SlideShow ppt = new SlideShow(is);
+ is.close();
+
+ Dimension pgsize = ppt.getPageSize();
+
+ Slide[] slide = ppt.getSlides();
+ for (int i = 0; i < slide.length; i++) {
+
+ BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
+ Graphics2D graphics = img.createGraphics();
+ //clear the drawing area
+ graphics.setPaint(Color.white);
+ graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
+
+ //render
+ slide[i].draw(graphics);
+
+ //save the output
+ FileOutputStream out = new FileOutputStream("slide-" + (i+1) + ".png");
+ javax.imageio.ImageIO.write(img, "png", out);
+ out.close();
+ }
+
+ </source>
+ </section>
+
+ </section>
+ <anchor id="HeadersFooters"/>
+ <section><title>How to extract Headers / Footers from an existing presentation</title>
+ <source>
+
+ FileInputStream is = new FileInputStream("slideshow.ppt");
+ SlideShow ppt = new SlideShow(is);
+ is.close();
+ Slide[] slides = ppt.getSlides();
+
+ //presentation-scope headers / footers
+ HeadersFooters hdd = ppt.getSlideHeadersFooters();
+ if(hdd.isFooterVisible()) {
+ String footerText = hdd.getFooterText();
+ }
+
+ //per-slide headers / footers
+ for (int i=0; i < slides.length; i++){
+ HeadersFooters hdd2 = slides[i].getHeadersFooters();
+ if(hdd2.isFooterVisible()) {
+ String footerText = hdd2.getFooterText();
+ }
+ if(hdd2.isUserDateVisible()) {
+ String customDate = hdd2.getDateTimeText();
+ }
+ if(hdd2.isSlideNumberVisible()){
+ int slideNUm = slides[i].getSlideNumber();
+ }
+
+ }
+ </source>
+ </section>
+ <section><title>How to set Headers / Footers</title>
+ <source>
+
+ SlideShow ppt = new SlideShow();
+
+ //presentation-scope headers / footers
+ HeadersFooters hdd = ppt.getSlideHeadersFooters();
+ hdd.setSlideNumberVisible(true);
+ hdd.setFootersText("Created by POI-HSLF");
+ </source>
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HSLF and and POI-XLSF - Java API To Access Microsoft Powerpoint Format Files</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Avik Sengupta" email="avik at apache dot org"/>
+ <person name="Nick Burch" email="nick at apache dot org"/>
+ <person name="Yegor Kozlov" email="yegor at apache dot org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section>
+ <title>POI-HSLF</title>
+
+ <p>HSLF is the POI Project's pure Java implementation of the Powerpoint '97(-2007) file format. </p>
+ <p>HSLF provides a way to read, create or modify PowerPoint presentations. In particular, it provides:
+ </p>
+ <ul>
+ <li>api for data extraction (text, pictures, embedded objects, sounds)</li>
+ <li>usermodel api for creating, reading and modifying ppt files</li>
+ </ul>
+ <note>
+ This code currently lives the
+ <link href="http://svn.apache.org/viewcvs.cgi/poi/trunk/src/scratchpad/">scratchpad area</link>
+ of the POI SVN repository.
+ Ensure that you have the scratchpad jar or the scratchpad
+ build area in your classpath before experimenting with
+ this code - the main POI jar is not enough.
+ </note>
+ <p>The <link href="./quick-guide.html">quick guide</link> documentation provides
+ information on using this API. Comments and fixes gratefully accepted on the POI
+ dev mailing lists.</p>
+ </section>
+ <section>
+ <title>POI-XSLF</title>
+ <p>
+ XSLF is the POI Project's pure Java implementation of the PowerPoint 2007 OOXML (.xlsx) file format.
+ Whilst HSLF and XSLF provide similar features, there is not a common interface across the two of them at this time.
+ </p>
+ <p>
+ Please note that XSLF is still in early development and is a subject to incompatible changes in future.
+ </p>
+ <p>
+ A quick guide is available in the <link href="./xslf-cookbook.html">XSLF Cookbook</link>
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HSLF - A Guide to the PowerPoint File Format</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick at torchbox dot com"/>
+ <person name="Yegor Kozlov" email="yegor at dinom dot ru"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Records, Containers and Atoms</title>
+ <p>
+ PowerPoint documents are made up of a tree of records. A record may
+ contain either other records (in which case it is a Container),
+ or data (in which case it's an Atom). A record can't hold both.
+ </p>
+ <p>
+ PowerPoint documents don't have one overall container record. Instead,
+ there are a number of different container records to be found at
+ the top level.
+ </p>
+ <p>
+ Any numbers or strings stored in the records are always stored in
+ Little Endian format (least important bytes first). This is the case
+ no matter what platform the file was written on - be that a
+ Little Endian or a Big Endian system.
+ </p>
+ <p>
+ PowerPoint may have Escher (DDF) records embeded in it. These
+ are always held as the children of a PPDrawing record (record
+ type 1036). Escher records have the same format as PowerPoint
+ records.
+ </p>
+ </section>
+
+ <section><title>Record Headers</title>
+ <p>
+ All records, be they containers or atoms, have the same standard
+ 8 byte header. It is:
+ </p>
+ <ul><li>1/2 byte container flag</li>
+ <li>1.5 byte option field</li>
+ <li>2 byte record type</li>
+ <li>4 byte record length</li></ul>
+ <p>
+ If the first byte of the header, BINARY_AND with 0x0f, is 0x0f,
+ then the record is a container. Otherwise, it's an atom. The rest
+ of the first two bytes are used to store the "options" for the
+ record. Most commonly, this is used to indicate the version of
+ the record, but the exact useage is record specific.
+ </p>
+ <p>
+ The record type is a little endian number, which tells you what
+ kind of record you're dealing with. Each different kind of record
+ has it's own value that gets stored here. PowerPoint records have
+ a type that's normally less than 6000 (decimal). Escher records
+ normally have a type between 0xF000 and 0xF1FF.
+ </p>
+ <p>
+ The record length is another little endian number. For an atom,
+ it's the size of the data part of the record, i.e. the length
+ of the record <em>less</em> its 8 byte record header. For a
+ container, it's the size of all the records that are children of
+ this record. That means that the size of a container record is the
+ length, plus 8 bytes for its record header.
+ </p>
+ </section>
+
+ <section><title>CurrentUserAtom, UserEditAtom and PersistPtrIncrementalBlock</title>
+ <p><strong>aka Records that care about the byte level position of other records</strong></p>
+ <p>
+ A small number of records contain byte level position offsets to other
+ records. If you change the position of any records in the file, then
+ there's a good chance that you will need to update some of these
+ special records.
+ </p>
+ <p>
+ First up, CurrentUserAtom. This is actually stored in a different
+ OLE2 (POIFS) stream to the main PowerPoint document. It contains
+ a few bits of information on who lasted edited the file. Most
+ importantly, at byte 8 of its contents, it stores (as a 32 bit
+ little endian number) the offset in the main stream to the most
+ recent UserEditAtom.
+ </p>
+ <p>
+ The UserEditAtom contains two byte level offsets (again as 32 bit
+ little endian numbers). At byte 12 is the offset to the
+ PersistPtrIncrementalBlock associated with this UserEditAtom
+ (each UserEditAtom has one and only one PersistPtrIncrementalBlock).
+ At byte 8, there's the offset to the previous UserEditAtom. If this
+ is 0, then you're at the first one.
+ </p>
+ <p>
+ Every time you do a non full save in PowerPoint, it tacks on another
+ UserEditAtom and another PersistPtrIncrementalBlock. The
+ CurrentUserAtom is updated to point to this new UserEditAtom, and the
+ new UserEditAtom points back to the previous UserEditAtom. You then
+ end up with a chain, starting from the CurrentUserAtom, linking
+ back through all the UserEditAtoms, until you reach the first one
+ from a full save.
+ </p>
+<source>
+/-------------------------------\
+| CurrentUserAtom (own stream) |
+| OffsetToCurrentEdit = 10562 |==\
+\-------------------------------/ |
+ |
+/==================================/
+| /-----------------------------------\
+| | PersistPtrIncrementalBlock @ 6144 |
+| \-----------------------------------/
+| /---------------------------------\ |
+| | UserEditAtom @ 6176 | |
+| | LastUserEditAtomOffset = 0 | |
+| | PersistPointersOffset = 6144 |==================/
+| \---------------------------------/
+| | /-----------------------------------\
+| \====================\ | PersistPtrIncrementalBlock @ 8646 |
+| | \-----------------------------------/
+| /---------------------------------\ | |
+| | UserEditAtom @ 8674 | | |
+| | LastUserEditAtomOffset = 6176 |=/ |
+| | PersistPointersOffset = 8646 |==================/
+| \---------------------------------/
+| | /------------------------------------\
+| \====================\ | PersistPtrIncrementalBlock @ 10538 |
+| | \------------------------------------/
+| /---------------------------------\ | |
+\==| UserEditAtom @ 10562 | | |
+ | LastUserEditAtomOffset = 8674 |=/ |
+ | PersistPointersOffset = 10538 |==================/
+ \---------------------------------/
+</source>
+ <p>
+ The PersistPtrIncrementalBlock contains byte offsets to all the
+ Slides, Notes, Documents and MasterSlides in the file. The first
+ PersistPtrIncrementalBlock will point to all the ones that
+ were present the first time the file was saved. Subsequent
+ PersistPtrIncrementalBlocks will contain pointers to all the ones
+ that were changed in that edit. To find the offset to a given
+ sheet in the latest version, then start with the most recent
+ PersistPtrIncrementalBlock. If this knows about the sheet, use the
+ offset it has. If it doesn't, then work back through older
+ PersistPtrIncrementalBlocks until you find one which does, and
+ use that.
+ </p>
+ <p>
+ Each PersistPtrIncrementalBlock can contain a number of entries
+ blocks. Each block holds information on a sequence of sheets.
+ Each block starts with a 32 bit little endian integer. Once read
+ into memory, the lower 20 bits contain the starting number for the
+ sequence of sheets to be described. The higher 12 bits contain
+ the count of the number of sheets described. Following that is
+ one 32 bit little endian integer for each sheet in the sequence,
+ the value being the offset to that sheet. If there is any data
+ left after parsing a block, then it corresponds to the next block.
+ </p>
+<source>
+hex on disk decimal description
+----------- ------- -----------
+0000 0 No options
+7217 6002 Record type is 6002
+2000 0000 32 Length of data is 32 bytes
+0100 5000 5242881 Count is 5 (12 highest bits)
+ Starting number is 1 (20 lowest bits)
+0000 0000 0 Sheet (1+0)=1 starts at offset 0
+900D 0000 3472 Sheet (1+1)=2 starts at offset 3472
+E403 0000 996 Sheet (1+2)=3 starts at offset 996
+9213 0000 5010 Sheet (1+3)=4 starts at offset 5010
+BE15 0000 5566 Sheet (1+4)=5 starts at offset 5566
+0900 1000 1048585 Count is 1 (12 highest bits)
+ Starting number is 9 (20 lowest bits)
+4418 0000 6212 Sheet (9+0)=9 starts at offset 9212
+</source>
+ </section>
+
+ <section><title>Paragraph and Text Styling</title>
+ <p>
+ There are quite a number of records that affect the styling
+ of text, and a smaller number that are responsible for the
+ styling of paragraphs.
+ </p>
+ <p>
+ By default, a given set of text will inherit paragraph and text
+ stylings from the appropriate master sheet. If anything differs
+ from the master sheet, then appropriate styling records will
+ follow the text record.
+ </p>
+ <p>
+ <em>(We don't currently know enough about master sheet styling
+ to write about it)</em>
+ </p>
+ <p>
+ Normally, powerpoint will have one text record (TextBytesAtom
+ or TextCharsAtom) for every paragraph, with a preceeding
+ TextHeaderAtom to describe what sort of paragraph it is.
+ If any of the stylings differ from the master's, then a
+ StyleTextPropAtom will follow the text record. This contains
+ the paragraph style information, and the styling information
+ for each section of the text which has a different style.
+ (More on StyleTextPropAtom later)
+ </p>
+ <p>
+ For every font used, a FontEntityAtom must exist for that font.
+ The FontEntityAtoms live inside a FontCollection record, and
+ there's one of those inside Environment record inside the
+ Document record. <em>(More on Fonts to be discovered)</em>
+ </p>
+ </section>
+
+ <section><title>StyleTextPropAtom</title>
+ <p>
+ If the text or paragraph stylings for a given text record
+ differ from those of the appropriate master, then there will
+ be one of these records.
+ </p>
+ <p>
+ This record is made up of two lists of lists. Firstly,
+ there's a list of paragraph stylings - each made up of the
+ number of characters it applies two, followed by the matching
+ styling elements. Following that is the equivalent for
+ character stylings.
+ </p>
+ <p>
+ Each styling list (in either list) starts with the number
+ of characters it applies to, stored in a 2 byte little
+ endian number. If it is a paragraph styling, it will be
+ followed by a 2 byte number (of unknown use). After this is
+ a four byte number, which is a mask indicating which stylings
+ will follow. You then have an entry for each of the stylings
+ indicated in the mask. Finally, you move onto the next set
+ of stylings.
+ </p>
+ <p>
+ Each styling has a specific mask flag to indicate its
+ presence. (The list may be found towards the top of
+ org.apache.poi.hslf.record.StyleTextPropAtom.java, and is
+ too long to sensibly include here). For each styling entry
+ will occur in the order of its mask value (so one with mask
+ 1 will come first, followed by the next higest mask value).
+ Depending on the styling, it is either made up of a 2 byte
+ or 4 byte numeric value. The meaning of the value will
+ depend on the styling (eg for font.size, it is the font
+ size in points).
+ </p>
+ <p>
+ Some stylings are actually mask stylings. For these, the
+ value will be a 4 byte number. This is then processed as
+ mask, to indicate a number of different sub-stylings.
+ The styling for bold/italic/underline is one such example.
+ </p>
+<source>
+hex on disk decimal description
+----------- ------- -----------
+
+0000 0 No options
+A10F 4001 Record type is 4001
+8000 0000 128 Length of data is 128 bytes
+1E00 0000 30 The paragraph styling applies to 30 characters
+0000 0 Paragraph options are 0
+0018 0000 6144 0x0800=Text Alignment, 0x1000=Line Spacing
+0000 0 Text Alignment = Left
+5000 80 Line Spacing = 80
+
+1C00 0000 28 The paragraph styling applies to 28 characters
+0000 0 Paragraph options are 0
+0010 0000 4096 0x1000=Line Spacing
+5000 80 Line Spacing = 80
+
+1900 0000 25 The paragraph styling applies to 25 characters
+0000 0 Paragraph options are 0
+0018 0000 6144 0x0800=Text Alignment, 0x1000=Line Spacing
+0200 0 Text Alignment = Right
+5000 80 Line Spacing = 80
+
+6100 0000 61 The paragraph styling applies to 61 characters
+ (includes final CR)
+0000 0 Paragraph options are 0
+0018 0000 6144 0x0800=Text Alignment, 0x1000=Line Spacing
+0000 0 Text Alignment = Left
+5000 80 Line Spacing = 80
+
+1E00 0000 30 The character styling applies to 30 characters
+0100 0200 131073 0x0001=Char Props Mask, 0x20000=Font Size
+0100 1 Char Props 0x0001=Bold
+1400 20 Font Size = 20
+
+1C00 0000 28 The character styling applies to 28 characters
+0200 0600 393218 0x0002=Char Props Mask, 0x20000=Font Size, 0x40000=Font Color
+0200 2 Char Props 0x0002=Italic
+1400 20 Font Size = 20
+0000 0005 83886080 Blue
+
+1900 0000 25 The character styling applies to 25 characters
+0000 0600 393216 0x20000=Font Size, 0x40000=Font Color
+1400 20 Font Size = 20
+FF33 00FE 4261426175 Red
+
+6000 0000 96 The character styling applies to 96 characters
+0400 0300 196612 0x0004=Char Props Mask, 0x10000=Font Index, 0x20000=Font Size
+0400 4 Char Props 0x0004=Underlined
+0100 1 Font Index = 1 (2nd Font in table)
+1800 24 Font Size = 24
+</source>
+ </section>
+
+ <section><title>Fonts in PowerPoint</title>
+ <p>
+ PowerPoint stores information about the fonts used in FontEntityAtoms,
+ which live inside Document.Environment.FontCollection. For every different
+ font used, a FontEntityAtom must exist for that font. There is always at
+ least one FontEntityAtom in Document.Environment.FontCollection,
+ which describes the default font.
+ </p>
+ </section>
+
+ <section><title>FontEntityAtom</title>
+ <p>
+ The instance field of the record header contains the zero based index of the
+ font. Font index entries in StyleTextPropAtoms will refer to their required
+ font via this index.
+ </p>
+ <p>
+ The length of FontEntityAtoms is always 68 bytes. The first 64 bytes of
+ it hold the typeface name of the font to be used. This is stored as
+ a null-terminated string, and encoded as little endian unicode. (The
+ length of the string must not exceed 32 characters including the null
+ termination, so the typeface name cannot exceed 31 characters).
+ </p>
+
+ <p>
+ After the typeface name there are 4 bytes of bitmask flags. The details of these
+ can be found in the Windows API, under the LOGFONT structure.
+ The 65th byte is the output precision, which defines how closely the system chosen
+ font must match the requested font, in terms of heigh, width, pitch etc.
+ The 66th byte is the clipping precision, which defines how to clip characters
+ that occur partly outside the clipping region.
+ The 67th byte is the output quality, which defines how closely the system
+ must match the logical font's attributes to those of the physical font used.
+ The 68th (and final) byte is the pitch and family, which is used by the
+ system when matching fonts.
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HSLF - A Quick Guide</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nick Burch" email="nick at torchbox dot com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Basic Text Extraction</title>
+ <p>For basic text extraction, make use of
+<code>org.apache.poi.hslf.extractor.PowerPointExtractor</code>. It accepts a file or an input
+stream. The <code>getText()</code> method can be used to get the text from the slides, and the <code>getNotes()</code> method can be used to get the text
+from the notes. Finally, <code>getText(true,true)</code> will get the text
+from both.
+ </p>
+ </section>
+
+ <section><title>Specific Text Extraction</title>
+ <p>To get specific bits of text, first create a <code>org.apache.poi.hslf.usermodel.SlideShow</code>
+(from a <code>org.apache.poi.hslf.HSLFSlideShow</code>, which accepts a file or an input
+stream). Use <code>getSlides()</code> and <code>getNotes()</code> to get the slides and notes.
+These can be queried to get their page ID (though they should be returned
+in the right order).</p>
+ <p>You can then call <code>getTextRuns()</code> on these, to get
+their blocks of text. (One TextRun normally holds all the text in a
+given area of the page, eg in the title bar, or in a box).
+From the <code>TextRun</code>, you can extract the text, and check
+what type of text it is (eg Body, Title). You can allso call
+<code>getRichTextRuns()</code>, which will return the
+<code>RichTextRun</code>s that make up the <code>TextRun</code>. A
+<code>RichTextRun</code> is made up of a sequence of text, all having the
+same character and paragraph formatting.
+ </p>
+ </section>
+
+ <section><title>Poor Quality Text Extraction</title>
+ <p>If speed is the most important thing for you, you don't care
+ about getting duplicate blocks of text, you don't care about
+ getting text from master sheets, and you don't care about getting
+ old text, then
+ <code>org.apache.poi.hslf.extractor.QuickButCruddyTextExtractor</code>
+ might be of use.</p>
+ <p>QuickButCruddyTextExtractor doesn't use the normal record
+ parsing code, instead it uses a tree structure blind search
+ method to get all text holding records. You will get all the text,
+ including lots of text you normally wouldn't ever want. However,
+ you will get it back very very fast!</p>
+ <p>There are two ways of getting the text back.
+ <code>getTextAsString()</code> will return a single string with all
+ the text in it. <code>getTextAsVector()</code> will return a
+ vector of strings, one for each text record found in the file.
+ </p>
+ </section>
+
+ <section><title>Changing Text</title>
+ <p>It is possible to change the text via
+ <code>TextRun.setText(String)</code> or
+ <code>RichTextRun.setText(String)</code>. It is not yet possible
+ to add additional TextRuns or RichTextRuns.</p>
+ <p>When calling <code>TextRun.setText(String)</code>, all
+ the text will end up with the same formatting. When calling
+ <code>RichTextRun.setText(String)</code>, the text will retain
+ the old formatting of that <code>RichTextRun</code>.
+ </p>
+ </section>
+
+ <section><title>Adding Slides</title>
+ <p>You may add new slides by calling
+ <code>SlideShow.createSlide()</code>, which will add a new slide
+ to the end of the SlideShow. It is not currently possible to
+ re-order slides, nor to add new text to slides (currently only
+ adding Escher objects to new slides is supported).
+ </p>
+ </section>
+
+ <section><title>Guide to key classes</title>
+ <ul>
+ <li><code>org.apache.poi.hslf.HSLFSlideShow</code>
+ Handles reading in and writing out files. Calls
+ <code>org.apache.poi.hslf.record.record</code> to build a tree
+ of all the records in the file, which it allows access to.
+ </li>
+ <li><code>org.apache.poi.hslf.record.record</code>
+ Base class of all records. Also provides the main record generation
+ code, which will build up a tree of records for a file.
+ </li>
+ <li><code>org.apache.poi.hslf.usermodel.SlideShow</code>
+ Builds up model entries from the records, and presents a user facing
+ view of the file
+ </li>
+ <li><code>org.apache.poi.hslf.model.Slide</code>
+ A user facing view of a Slide in a slidesow. Allows you to get at the
+ Text of the slide, and at any drawing objects on it.
+ </li>
+ <li><code>org.apache.poi.hslf.model.TextRun</code>
+ Holds all the Text in a given area of the Slide, and will
+ contain one or more <code>RichTextRun</code>s.
+ </li>
+ <li><code>org.apache.poi.hslf.usermodel.RichTextRun</code>
+ Holds a run of text, all having the same character and
+ paragraph stylings. It is possible to modify text, and/or text stylings.
+ </li>
+ <li><code>org.apache.poi.hslf.extractor.PowerPointExtractor</code>
+ Uses the model code to allow extraction of text from files
+ </li>
+ <li><code>org.apache.poi.hslf.extractor.QuickButCruddyTextExtractor</code>
+ Uses the record code to extract all the text from files very fast,
+ but including deleted text (and other bits of Crud).
+ </li>
+ </ul>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>XSLF Cookbook</title>
+ <authors>
+ <person email="yegor@apache.org" name="Yegor Kozlov" id="YK"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>XSLF Cookbook</title>
+ <p>
+ This page offers a short introduction into the XSLF API. More examples can be found in the
+ <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xslf/usermodel/"> XSLF Examples</link>
+ in the POI SVN repository.
+ </p>
+ <note>
+ Please note that XSLF is still in early development and is a subject to incompatible changes in a future release.
+ </note>
+ <section><title>Index of Features</title>
+ <ul>
+ <li><link href="#NewPresentation">Create a new presentation</link></li>
+ <li><link href="#ReadPresentation">Read an existing presentation</link></li>
+ <li><link href="#SlideLayout">Create a slide with a predefined layout</link></li>
+ <li><link href="#DeleteSlide">Delete slide</link></li>
+ <li><link href="#MoveSlide">Re-order slides</link></li>
+ <li><link href="#SlideSize">Change slide size</link></li>
+ <li><link href="#GetShapes">Read shapes</link></li>
+ <li><link href="#AddImage">Add image</link></li>
+ <li><link href="#ReadImages">Read images contained in a presentation</link></li>
+ <li><link href="#Text">Format text</link></li>
+ <li><link href="#Hyperlinks">Hyperlinks</link></li>
+ <li><link href="#PPTX2PNG">Convert .pptx slides into images</link></li>
+ <li><link href="#Merge">Merge multiple presentations together</link></li>
+ </ul>
+ </section>
+ <section><title>Cookbok</title>
+ <anchor id="NewPresentation"/>
+ <section><title>New Presentation</title>
+ <p>
+ The following code creates a new .pptx slide show and adds a blank slide to it:
+ </p>
+ <source>
+ //create a new empty slide show
+ XMLSlideShow ppt = new XMLSlideShow();
+
+ //add first slide
+ XSLFSlide blankSlide = ppt.createSlide();
+ </source>
+ </section>
+ <anchor id="ReadPresentation"/>
+ <section><title>Read an existing presentation and append a slide to it</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow(new FileInputStream("slideshow.pptx"));
+
+ //append a new slide to the end
+ XSLFSlide blankSlide = ppt.createSlide();
+ </source>
+ </section>
+
+ <anchor id="SlideLayout"/>
+ <section><title>Create a new slide from a predefined slide layout</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow(new FileInputStream("slideshow.pptx"));
+
+ // first see what slide layouts are available :
+ System.out.println("Available slide layouts:");
+ for(XSLFSlideMaster master : ppt.getSlideMasters()){
+ for(XSLFSlideLayout layout : master.getSlideLayouts()){
+ System.out.println(layout.getType());
+ }
+ }
+
+ // blank slide
+ XSLFSlide blankSlide = ppt.createSlide();
+
+ // there can be multiple masters each referencing a number of layouts
+ // for demonstration purposes we use the first (default) slide master
+ XSLFSlideMaster defaultMaster = ppt.getSlideMasters()[0];
+
+ // title slide
+ XSLFSlideLayout titleLayout = defaultMaster.getLayout(SlideLayout.TITLE);
+ // fill the placeholders
+ XSLFSlide slide1 = ppt.createSlide(titleLayout);
+ XSLFTextShape title1 = slide1.getPlaceholder(0);
+ title1.setText("First Title");
+
+ // title and content
+ XSLFSlideLayout titleBodyLayout = defaultMaster.getLayout(SlideLayout.TITLE_AND_CONTENT);
+ XSLFSlide slide2 = ppt.createSlide(titleBodyLayout);
+
+ XSLFTextShape title2 = slide2.getPlaceholder(0);
+ title2.setText("Second Title");
+
+ XSLFTextShape body2 = slide2.getPlaceholder(1);
+ body2.clearText(); // unset any existing text
+ body2.addNewTextParagraph().addNewTextRun().setText("First paragraph");
+ body2.addNewTextParagraph().addNewTextRun().setText("Second paragraph");
+ body2.addNewTextParagraph().addNewTextRun().setText("Third paragraph");
+ </source>
+ </section>
+
+ <anchor id="DeleteSlide"/>
+ <section><title>Delete slide</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow(new FileInputStream("slideshow.pptx"));
+
+ ppt.removeSlide(0); // 0-based index of a slide to be removed
+ </source>
+ </section>
+
+ <anchor id="MoveSlide"/>
+ <section><title>Re-order slides</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow(new FileInputStream("slideshow.pptx"));
+ XSLFSlide[] slides = ppt.getSlides();
+
+ XSLFSlide thirdSlide = slides[2];
+ ppt.setSlideOrder(thirdSlide, 0); // move the third slide to the beginning
+ </source>
+ </section>
+
+ <anchor id="SlideSize"/>
+ <section><title>How to retrieve or change slide size</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow();
+ //retrieve page size. Coordinates are expressed in points (72 dpi)
+ java.awt.Dimension pgsize = ppt.getPageSize();
+ int pgx = pgsize.width; //slide width in points
+ int pgy = pgsize.height; //slide height in points
+
+ //set new page size
+ ppt.setPageSize(new java.awt.Dimension(1024, 768));
+ </source>
+ </section>
+ <anchor id="GetShapes"/>
+ <section><title>How to read shapes contained in a particular slide</title>
+ <p>
+ The following code demonstrates how to iterate over shapes for each slide.
+ </p>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow(new FileInputStream("slideshow.pptx"));
+ //get slides
+ XSLFSlide[] slide = ppt.getSlides();
+ for (int i = 0; i < slide.length; i++){
+ XSLFShape[] sh = slide[i].getShapes();
+ for (int j = 0; j < sh.length; j++){
+ //name of the shape
+ String name = sh[j].getShapeName();
+
+ //shapes's anchor which defines the position of this shape in the slide
+ java.awt.geom.Rectangle2D anchor = sh[j].getAnchor();
+
+ if (sh[j] instanceof XSLFConnectorShape){
+ XSLFConnectorShape line = (XSLFConnectorShape)sh[j];
+ //work with Line
+ } else if (sh[j] instanceof XSLFTextShape){
+ XSLFTextShape shape = (XSLFTextShape)sh[j];
+ //work with a shape that can hold text
+ } else if (sh[j] instanceof XSLFPictureShape){
+ XSLFPictureShape shape = (XSLFPictureShape)sh[j];
+ //work with Picture
+ }
+ }
+ }
+ </source>
+ </section>
+ <anchor id="AddImage"/>
+ <section><title>Add Image to Slide</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow();
+ XSLFSlide slide = ppt.createSlide();
+
+ byte[] pictureData = IOUtils.toByteArray(new FileInputStream("image.png"));
+
+ int idx = ppt.addPicture(pictureData, XSLFPictureData.PICTURE_TYPE_PNG);
+ XSLFPictureShape pic = slide.createPicture(idx);
+ </source>
+ </section>
+
+ <anchor id="ReadImages"/>
+ <section><title>Read Images contained within a presentation</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow(new FileInputStream("slideshow.pptx"));
+ for(XSLFPictureData data : ppt.getAllPictures()){
+ byte[] bytes = data.getData();
+ String fileName = data.getFileName();
+
+ }
+ </source>
+ </section>
+
+ <anchor id="Text"/>
+ <section><title>Basic text formatting</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow();
+ XSLFSlide slide = ppt.createSlide();
+
+ XSLFTextBox shape = slide.createTextBox();
+ XSLFTextParagraph p = shape.addNewTextParagraph();
+
+ XSLFTextRun r1 = p.addNewTextRun();
+ r1.setText("The");
+ r1.setFontColor(Color.blue);
+ r1.setFontSize(24);
+
+ XSLFTextRun r2 = p.addNewTextRun();
+ r2.setText(" quick");
+ r2.setFontColor(Color.red);
+ r2.setBold(true);
+
+ XSLFTextRun r3 = p.addNewTextRun();
+ r3.setText(" brown");
+ r3.setFontSize(12);
+ r3.setItalic(true);
+ r3.setStrikethrough(true);
+
+ XSLFTextRun r4 = p.addNewTextRun();
+ r4.setText(" fox");
+ r4.setUnderline(true);
+ </source>
+ </section>
+ <anchor id="Hyperlinks"/>
+ <section><title>How to read hyperlinks from a slide show</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow();
+ XSLFSlide slide = ppt.createSlide();
+
+ // assign a hyperlink to a text run
+ XSLFTextBox shape = slide.createTextBox();
+ XSLFTextRun r = shape.addNewTextParagraph().addNewTextRun();
+ r.setText("Apache POI");
+ XSLFHyperlink link = r.createHyperlink();
+ link.setAddress("http://poi.apache.org");
+ </source>
+ </section>
+ <anchor id="PPTX2PNG"/>
+ <section><title>PPTX2PNG is an application that converts each slide of a .pptx slideshow into a PNG image</title>
+ <source>
+Usage: PPTX2PNG [options] <pptx file>
+Options:
+ -scale <float> scale factor (default is 1.0)
+ -slide <integer> 1-based index of a slide to render. Default is to render all slides.
+ </source>
+ <p>How it works:</p>
+ <p>
+ The XSLFSlide object implements a draw(Graphics2D graphics) method that recursively paints all shapes
+ in the slide into the supplied graphics canvas:
+ </p>
+ <source>
+ slide.draw(graphics);
+ </source>
+ <p>
+ where graphics is a class implementing java.awt.Graphics2D. In PPTX2PNG the graphic canvas is derived from
+ java.awt.image.BufferedImage, i.e. the destination is an image in memory, but in general case you can pass
+ any compliant implementation of java.awt.Graphics2D. The
+ <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xslf/usermodel/PPTX2SVG.txt">PPTX2SVG</link>
+ example demonstrates how to use Apache Batik to convert .pptx slides into SVG format.
+ </p>
+ </section>
+ <anchor id="Merge"/>
+ <section>
+ <title>Merge multiple presentations together</title>
+ <source>
+ XMLSlideShow ppt = new XMLSlideShow();
+ String[] inputs = {"presentations1.pptx", "presentation2.pptx"};
+ for(String arg : inputs){
+ FileInputStream is = new FileInputStream(arg);
+ XMLSlideShow src = new XMLSlideShow(is);
+ is.close();
+
+ for(XSLFSlide srcSlide : src.getSlides()){
+ ppt.createSlide().importContent(srcSlide);
+ }
+ }
+
+ FileOutputStream out = new FileOutputStream("merged.pptx");
+ ppt.write(out);
+ out.close();
+ </source>
+ </section>
+
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="HSSF+XSSF"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="HSSF+XSSF">
+ <menu-item label="Overview" href="index.html"/>
+ <menu-item label="Quick Guide" href="quick-guide.html"/>
+ <menu-item label="HOWTO" href="how-to.html"/>
+ <menu-item label="HSSF to SS Converting" href="converting.html"/>
+ <menu-item label="Formula Support" href="formula.html" />
+ <menu-item label="Formula Evaluation" href="eval.html" />
+ <menu-item label="Eval Dev Guide" href="eval-devguide.html" />
+ <menu-item label="Examples" href="examples.html"/>
+ <menu-item label="Use Case" href="use-case.html"/>
+ <menu-item label="Pictorial Docs" href="diagrams.html"/>
+ <menu-item label="Limitations" href="limitations.html"/>
+ <menu-item label="User Defined Functions" href="user-defined-functions.html"/>
+ <menu-item label="ExcelAnt Tests" href="excelant.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-item label="Charts" href="chart.html"/>
+ </menu>
+
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Chart record information</title>
+ <authors>
+ <person email="user@poi.apache.org" name="Glen Stampoultzis" id="GS"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Introduction</title>
+ <p>
+ This document is intended as a work in progress for describing
+ our current understanding of how the chart records are are
+ written to produce a valid chart.
+ </p>
+ </section>
+ <section><title>Bar chart</title>
+ <p>
+ The following records detail the records written for a
+ 'simple' bar chart.
+ </p>
+ <source>
+
+ ============================================
+ rectype = 0xec, recsize = 0xc8
+ -BEGIN DUMP---------------------------------
+ 00000000 0F 00 02 F0 C0 00 00 00 10 00 08 F0 08 00 00 00 ................
+ 00000010 02 00 00 00 02 04 00 00 0F 00 03 F0 A8 00 00 00 ................
+ 00000020 0F 00 04 F0 28 00 00 00 01 00 09 F0 10 00 00 00 ....(...........
+ 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000040 02 00 0A F0 08 00 00 00 00 04 00 00 05 00 00 00 ................
+ 00000050 0F 00 04 F0 70 00 00 00 92 0C 0A F0 08 00 00 00 ....p...........
+ 00000060 02 04 00 00 00 0A 00 00 93 00 0B F0 36 00 00 00 ............6...
+ 00000070 7F 00 04 01 04 01 BF 00 08 00 08 00 81 01 4E 00 ..............N.
+ 00000080 00 08 83 01 4D 00 00 08 BF 01 10 00 11 00 C0 01 ....M...........
+ 00000090 4D 00 00 08 FF 01 08 00 08 00 3F 02 00 00 02 00 M.........?.....
+ 000000A0 BF 03 00 00 08 00 00 00 10 F0 12 00 00 00 00 00 ................
+ 000000B0 04 00 C0 02 0A 00 F4 00 0E 00 66 01 20 00 E9 00 ..........f. ...
+ 000000C0 00 00 11 F0 00 00 00 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0xec, size =200
+ [UNKNOWN RECORD:ec]
+ .id = ec
+ [/UNKNOWN RECORD]
+
+ ============================================
+ rectype = 0x5d, recsize = 0x1a
+ -BEGIN DUMP---------------------------------
+ 00000000 15 00 12 00 05 00 02 00 11 60 00 00 00 00 B8 03 .........`......
+ 00000010 87 03 00 00 00 00 00 00 00 00 ..........
+ -END DUMP-----------------------------------
+ recordid = 0x5d, size =26
+ [UNKNOWN RECORD:5d]
+ .id = 5d
+ [/UNKNOWN RECORD]
+
+ ============================================
+ rectype = 0x809, recsize = 0x10
+ -BEGIN DUMP---------------------------------
+ 00000000 00 06 20 00 FE 1C CD 07 C9 40 00 00 06 01 00 00 .. ......@......
+ -END DUMP-----------------------------------
+ recordid = 0x809, size =16
+ [BOF RECORD]
+ .version = 600
+ .type = 20
+ .build = 1cfe
+ .buildyear = 1997
+ .history = 40c9
+ .requiredversion = 106
+ [/BOF RECORD]
+
+ ============================================
+ rectype = 0x14, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x14, size =0
+ [HEADER]
+ .length = 0
+ .header = null
+ [/HEADER]
+
+ ============================================
+ rectype = 0x15, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x15, size =0
+ [FOOTER]
+ .footerlen = 0
+ .footer = null
+ [/FOOTER]
+
+ ============================================
+ rectype = 0x83, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x83, size =2
+ [HCENTER]
+ .hcenter = false
+ [/HCENTER]
+
+ ============================================
+ rectype = 0x84, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x84, size =2
+ [VCENTER]
+ .vcenter = false
+ [/VCENTER]
+
+ ============================================
+ rectype = 0xa1, recsize = 0x22
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 12 00 01 00 01 00 01 00 04 00 00 00 B8 03 ................
+ 00000010 00 00 00 00 00 00 E0 3F 00 00 00 00 00 00 E0 3F .......?.......?
+ 00000020 0F 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0xa1, size =34
+ [PRINTSETUP]
+ .papersize = 0
+ .scale = 18
+ .pagestart = 1
+ .fitwidth = 1
+ .fitheight = 1
+ .options = 4
+ .ltor = false
+ .landscape = false
+ .valid = true
+ .mono = false
+ .draft = false
+ .notes = false
+ .noOrientat = false
+ .usepage = false
+ .hresolution = 0
+ .vresolution = 952
+ .headermargin = 0.5
+ .footermargin = 0.5
+ .copies = 15
+ [/PRINTSETUP]
+
+ <!-- Comment to avoid forrest bug -->
+ ============================================
+ rectype = 0x33, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 03 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x33, size =2
+ [UNKNOWN RECORD:33]
+ .id = 33
+ [/UNKNOWN RECORD]
+
+ ============================================
+ rectype = 0x1060, recsize = 0xa
+ -BEGIN DUMP---------------------------------
+ 00000000 A0 23 08 16 C8 00 00 00 05 00 .#........
+ -END DUMP-----------------------------------
+ recordid = 0x1060, size =10
+ [FBI]
+ .xBasis = 0x23A0 (9120 )
+ .yBasis = 0x1608 (5640 )
+ .heightBasis = 0x00C8 (200 )
+ .scale = 0x0000 (0 )
+ .indexToFontTable = 0x0005 (5 )
+ [/FBI]
+
+ ============================================
+ rectype = 0x1060, recsize = 0xa
+ -BEGIN DUMP---------------------------------
+ 00000000 A0 23 08 16 C8 00 01 00 06 00 .#........
+ -END DUMP-----------------------------------
+ recordid = 0x1060, size =10
+ [FBI]
+ .xBasis = 0x23A0 (9120 )
+ .yBasis = 0x1608 (5640 )
+ .heightBasis = 0x00C8 (200 )
+ .scale = 0x0001 (1 )
+ .indexToFontTable = 0x0006 (6 )
+ [/FBI]
+
+ ============================================
+ rectype = 0x12, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x12, size =2
+ [PROTECT]
+ .rowheight = 0
+ [/PROTECT]
+
+ ============================================
+ Offset 0xf22 (3874)
+ rectype = 0x1001, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1001, size =2
+ [UNITS]
+ .units = 0x0000 (0 )
+ [/UNITS]
+
+ ============================================
+ Offset 0xf28 (3880)
+ rectype = 0x1002, recsize = 0x10
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 00 00 00 00 00 00 58 66 D0 01 40 66 22 01 ........Xf..@f".
+ -END DUMP-----------------------------------
+ recordid = 0x1002, size =16
+ [CHART]
+ .x = 0x00000000 (0 )
+ .y = 0x00000000 (0 )
+ .width = 0x01D06658 (30434904 )
+ .height = 0x01226640 (19031616 )
+ [/CHART]
+
+ ============================================
+ Offset 0xf3c (3900)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0xf40 (3904)
+ rectype = 0xa0, recsize = 0x4
+ -BEGIN DUMP---------------------------------
+ 00000000 01 00 01 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0xa0, size =4
+ [SCL]
+ .numerator = 0x0001 (1 )
+ .denominator = 0x0001 (1 )
+ [/SCL]
+
+ <!-- Comment to avoid forrest bug -->
+ ============================================
+ Offset 0xf48 (3912)
+ rectype = 0x1064, recsize = 0x8
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 01 00 00 00 01 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0x1064, size =8
+ [PLOTGROWTH]
+ .horizontalScale = 0x00010000 (65536 )
+ .verticalScale = 0x00010000 (65536 )
+ [/PLOTGROWTH]
+
+ ============================================
+ Offset 0xf54 (3924)
+ rectype = 0x1032, recsize = 0x4
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 02 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x1032, size =4
+ [FRAME]
+ .borderType = 0x0000 (0 )
+ .options = 0x0002 (2 )
+ .autoSize = false
+ .autoPosition = true
+ [/FRAME]
+
+ ============================================
+ Offset 0xf5c (3932)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0xf60 (3936)
+ rectype = 0x1007, recsize = 0xc
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 00 00 00 00 FF FF 09 00 4D 00 ..........M.
+ -END DUMP-----------------------------------
+ recordid = 0x1007, size =12
+ [LINEFORMAT]
+ .lineColor = 0x00000000 (0 )
+ .linePattern = 0x0000 (0 )
+ .weight = 0xFFFF (-1 )
+ .format = 0x0009 (9 )
+ .auto = true
+ .drawTicks = false
+ .unknown = false
+ .colourPaletteIndex = 0x004D (77 )
+ [/LINEFORMAT]
+
+ ============================================
+ Offset 0xf70 (3952)
+ rectype = 0x100a, recsize = 0x10
+ -BEGIN DUMP---------------------------------
+ 00000000 FF FF FF 00 00 00 00 00 01 00 01 00 4E 00 4D 00 ............N.M.
+ -END DUMP-----------------------------------
+ recordid = 0x100a, size =16
+ [AREAFORMAT]
+ .foregroundColor = 0x00FFFFFF (16777215 )
+ .backgroundColor = 0x00000000 (0 )
+ .pattern = 0x0001 (1 )
+ .formatFlags = 0x0001 (1 )
+ .automatic = true
+ .invert = false
+ .forecolorIndex = 0x004E (78 )
+ .backcolorIndex = 0x004D (77 )
+ [/AREAFORMAT]
+
+ ============================================
+ Offset 0xf84 (3972)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0xf88 (3976)
+ rectype = 0x1003, recsize = 0xc
+ -BEGIN DUMP---------------------------------
+ 00000000 01 00 01 00 20 00 1F 00 01 00 00 00 .... .......
+ -END DUMP-----------------------------------
+ recordid = 0x1003, size =12
+ [SERIES]
+ .categoryDataType = 0x0001 (1 )
+ .valuesDataType = 0x0001 (1 )
+ .numCategories = 0x0020 (32 )
+ .numValues = 0x001F (31 )
+ .bubbleSeriesType = 0x0001 (1 )
+ .numBubbleValues = 0x0000 (0 )
+ [/SERIES]
+
+ ============================================
+ Offset 0xf98 (3992)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ <!-- Comment to avoid forrest bug -->
+ ============================================
+ Offset 0xf9c (3996)
+ rectype = 0x1051, recsize = 0x8
+ -BEGIN DUMP---------------------------------
+ 00000000 00 01 00 00 00 00 00 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0x1051, size =8
+ [AI]
+ .linkType = 0x00 (0 )
+ .referenceType = 0x01 (1 )
+ .options = 0x0000 (0 )
+ .customNumberFormat = false
+ .indexNumberFmtRecord = 0x0000 (0 )
+ .formulaOfLink = (org.apache.poi.hssf.record.LinkedDataFormulaField@1ee3914 )
+ [/AI]
+
+ ============================================
+ Offset 0xfa8 (4008)
+ rectype = 0x1051, recsize = 0x13
+ -BEGIN DUMP---------------------------------
+ 00000000 01 02 00 00 00 00 0B 00 3B 00 00 00 00 1E 00 01 ........;.......
+ 00000010 00 01 00 ...
+ -END DUMP-----------------------------------
+ recordid = 0x1051, size =19
+ [AI]
+ .linkType = 0x01 (1 )
+ .referenceType = 0x02 (2 )
+ .options = 0x0000 (0 )
+ .customNumberFormat = false
+ .indexNumberFmtRecord = 0x0000 (0 )
+ .formulaOfLink = (org.apache.poi.hssf.record.LinkedDataFormulaField@e5855a )
+ [/AI]
+
+ ============================================
+ Offset 0xfbf (4031)
+ rectype = 0x1051, recsize = 0x13
+ -BEGIN DUMP---------------------------------
+ 00000000 02 02 00 00 69 01 0B 00 3B 00 00 00 00 1F 00 00 ....i...;.......
+ 00000010 00 00 00 ...
+ -END DUMP-----------------------------------
+ recordid = 0x1051, size =19
+ [AI]
+ .linkType = 0x02 (2 )
+ .referenceType = 0x02 (2 )
+ .options = 0x0000 (0 )
+ .customNumberFormat = false
+ .indexNumberFmtRecord = 0x0169 (361 )
+ .formulaOfLink = (org.apache.poi.hssf.record.LinkedDataFormulaField@95fd19 )
+ [/AI]
+
+ ============================================
+ Offset 0xfd6 (4054)
+ rectype = 0x1051, recsize = 0x8
+ -BEGIN DUMP---------------------------------
+ 00000000 03 01 00 00 00 00 00 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0x1051, size =8
+ [AI]
+ .linkType = 0x03 (3 )
+ .referenceType = 0x01 (1 )
+ .options = 0x0000 (0 )
+ .customNumberFormat = false
+ .indexNumberFmtRecord = 0x0000 (0 )
+ .formulaOfLink = (org.apache.poi.hssf.record.LinkedDataFormulaField@11b9fb1 )
+ [/AI]
+
+ ============================================
+ Offset 0xfe2 (4066)
+ rectype = 0x1006, recsize = 0x8
+ -BEGIN DUMP---------------------------------
+ 00000000 FF FF 00 00 00 00 00 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0x1006, size =8
+ [DATAFORMAT]
+ .pointNumber = 0xFFFF (-1 )
+ .seriesIndex = 0x0000 (0 )
+ .seriesNumber = 0x0000 (0 )
+ .formatFlags = 0x0000 (0 )
+ .useExcel4Colors = false
+ [/DATAFORMAT]
+
+ ============================================
+ Offset 0xfee (4078)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0xff2 (4082)
+ rectype = 0x105f, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x105f, size =2
+ [UNKNOWN RECORD]
+ .id = 105f
+ [/UNKNOWN RECORD]
+
+ ============================================
+ Offset 0xff8 (4088)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0xffc (4092)
+ rectype = 0x1045, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1045, size =2
+ [SeriesToChartGroup]
+ .chartGroupIndex = 0x0000 (0 )
+ [/SeriesToChartGroup]
+
+ ============================================
+ Offset 0x1002 (4098)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x1006 (4102)
+ rectype = 0x1044, recsize = 0x4
+ -BEGIN DUMP---------------------------------
+ 00000000 0A 00 00 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x1044, size =4
+ [SHTPROPS]
+ .flags = 0x000A (10 )
+ .chartTypeManuallyFormatted = false
+ .plotVisibleOnly = true
+ .doNotSizeWithWindow = false
+ .defaultPlotDimensions = true
+ .autoPlotArea = false
+ .empty = 0x00 (0 )
+ [/SHTPROPS]
+
+ ============================================
+ Offset 0x100e (4110)
+ rectype = 0x1024, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 02 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1024, size =2
+ [DEFAULTTEXT]
+ .categoryDataType = 0x0002 (2 )
+ [/DEFAULTTEXT]
+
+ ============================================
+ Offset 0x1014 (4116)
+ rectype = 0x1025, recsize = 0x20
+ -BEGIN DUMP---------------------------------
+ 00000000 02 02 01 00 00 00 00 00 DB FF FF FF C4 FF FF FF ................
+ 00000010 00 00 00 00 00 00 00 00 B1 00 4D 00 50 2B 00 00 ..........M.P+..
+ -END DUMP-----------------------------------
+ recordid = 0x1025, size =32
+ [TEXT]
+ .horizontalAlignment = 0x02 (2 )
+ .verticalAlignment = 0x02 (2 )
+ .displayMode = 0x0001 (1 )
+ .rgbColor = 0x00000000 (0 )
+ .x = 0xFFFFFFDB (-37 )
+ .y = 0xFFFFFFC4 (-60 )
+ .width = 0x00000000 (0 )
+ .height = 0x00000000 (0 )
+ .options1 = 0x00B1 (177 )
+ .autoColor = true
+ .showKey = false
+ .showValue = false
+ .vertical = false
+ .autoGeneratedText = true
+ .generated = true
+ .autoLabelDeleted = false
+ .autoBackground = true
+ .rotation = 0
+ .showCategoryLabelAsPercentage = false
+ .showValueAsPercentage = false
+ .showBubbleSizes = false
+ .showLabel = false
+ .indexOfColorValue = 0x004D (77 )
+ .options2 = 0x2B50 (11088 )
+ .dataLabelPlacement = 0
+ .textRotation = 0x0000 (0 )
+ [/TEXT]
+
+ ============================================
+ Offset 0x1038 (4152)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ <!-- Comment to avoid forrest bug -->
+ ============================================
+ Offset 0x103c (4156)
+ rectype = 0x104f, recsize = 0x14
+ -BEGIN DUMP---------------------------------
+ 00000000 02 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 00 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x104f, size =20
+ [UNKNOWN RECORD]
+ .id = 104f
+ [/UNKNOWN RECORD]
+
+ ============================================
+ Offset 0x1054 (4180)
+ rectype = 0x1026, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 05 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1026, size =2
+ [FONTX]
+ .fontIndex = 0x0005 (5 )
+ [/FONTX]
+
+ ============================================
+ Offset 0x105a (4186)
+ rectype = 0x1051, recsize = 0x8
+ -BEGIN DUMP---------------------------------
+ 00000000 00 01 00 00 00 00 00 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0x1051, size =8
+ [AI]
+ .linkType = 0x00 (0 )
+ .referenceType = 0x01 (1 )
+ .options = 0x0000 (0 )
+ .customNumberFormat = false
+ .indexNumberFmtRecord = 0x0000 (0 )
+ .formulaOfLink = (org.apache.poi.hssf.record.LinkedDataFormulaField@913fe2 )
+ [/AI]
+
+ ============================================
+ Offset 0x1066 (4198)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x106a (4202)
+ rectype = 0x1024, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 03 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1024, size =2
+ [DEFAULTTEXT]
+ .categoryDataType = 0x0003 (3 )
+ [/DEFAULTTEXT]
+
+ ============================================
+ Offset 0x1070 (4208)
+ rectype = 0x1025, recsize = 0x20
+ -BEGIN DUMP---------------------------------
+ 00000000 02 02 01 00 00 00 00 00 DB FF FF FF C4 FF FF FF ................
+ 00000010 00 00 00 00 00 00 00 00 B1 00 4D 00 50 2B 00 00 ..........M.P+..
+ -END DUMP-----------------------------------
+ recordid = 0x1025, size =32
+ [TEXT]
+ .horizontalAlignment = 0x02 (2 )
+ .verticalAlignment = 0x02 (2 )
+ .displayMode = 0x0001 (1 )
+ .rgbColor = 0x00000000 (0 )
+ .x = 0xFFFFFFDB (-37 )
+ .y = 0xFFFFFFC4 (-60 )
+ .width = 0x00000000 (0 )
+ .height = 0x00000000 (0 )
+ .options1 = 0x00B1 (177 )
+ .autoColor = true
+ .showKey = false
+ .showValue = false
+ .vertical = false
+ .autoGeneratedText = true
+ .generated = true
+ .autoLabelDeleted = false
+ .autoBackground = true
+ .rotation = 0
+ .showCategoryLabelAsPercentage = false
+ .showValueAsPercentage = false
+ .showBubbleSizes = false
+ .showLabel = false
+ .indexOfColorValue = 0x004D (77 )
+ .options2 = 0x2B50 (11088 )
+ .dataLabelPlacement = 0
+ .textRotation = 0x0000 (0 )
+ [/TEXT]
+
+ ============================================
+ Offset 0x1094 (4244)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0x1098 (4248)
+ rectype = 0x104f, recsize = 0x14
+ -BEGIN DUMP---------------------------------
+ 00000000 02 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 00 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x104f, size =20
+ [UNKNOWN RECORD]
+ .id = 104f
+ [/UNKNOWN RECORD]
+
+ ============================================
+ Offset 0x10b0 (4272)
+ rectype = 0x1026, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 06 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1026, size =2
+ [FONTX]
+ .fontIndex = 0x0006 (6 )
+ [/FONTX]
+
+ ============================================
+ Offset 0x10b6 (4278)
+ rectype = 0x1051, recsize = 0x8
+ -BEGIN DUMP---------------------------------
+ 00000000 00 01 00 00 00 00 00 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0x1051, size =8
+ [AI]
+ .linkType = 0x00 (0 )
+ .referenceType = 0x01 (1 )
+ .options = 0x0000 (0 )
+ .customNumberFormat = false
+ .indexNumberFmtRecord = 0x0000 (0 )
+ .formulaOfLink = (org.apache.poi.hssf.record.LinkedDataFormulaField@1f934ad )
+ [/AI]
+
+ ============================================
+ Offset 0x10c2 (4290)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x10c6 (4294)
+ rectype = 0x1046, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 01 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1046, size =2
+ [AXISUSED]
+ .numAxis = 0x0001 (1 )
+ [/AXISUSED]
+
+ ============================================
+ Offset 0x10cc (4300)
+ rectype = 0x1041, recsize = 0x12
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 DF 01 00 00 DD 00 00 00 B3 0B 00 00 56 0B ..............V.
+ 00000010 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1041, size =18
+ [AXISPARENT]
+ .axisType = 0x0000 (0 )
+ .x = 0x000001DF (479 )
+ .y = 0x000000DD (221 )
+ .width = 0x00000BB3 (2995 )
+ .height = 0x00000B56 (2902 )
+ [/AXISPARENT]
+
+ ============================================
+ Offset 0x10e2 (4322)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0x10e6 (4326)
+ rectype = 0x104f, recsize = 0x14
+ -BEGIN DUMP---------------------------------
+ 00000000 02 00 02 00 3A 00 00 00 5E 00 00 00 58 0D 00 00 ....:...^...X...
+ 00000010 E5 0E 00 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x104f, size =20
+ [UNKNOWN RECORD]
+ .id = 104f
+ [/UNKNOWN RECORD]
+
+ ============================================
+ Offset 0x10fe (4350)
+ rectype = 0x101d, recsize = 0x12
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x101d, size =18
+ [AXIS]
+ .axisType = 0x0000 (0 )
+ .reserved1 = 0x00000000 (0 )
+ .reserved2 = 0x00000000 (0 )
+ .reserved3 = 0x00000000 (0 )
+ .reserved4 = 0x00000000 (0 )
+ [/AXIS]
+
+ ============================================
+ Offset 0x1114 (4372)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0x1118 (4376)
+ rectype = 0x1020, recsize = 0x8
+ -BEGIN DUMP---------------------------------
+ 00000000 01 00 01 00 01 00 01 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0x1020, size =8
+ [CATSERRANGE]
+ .crossingPoint = 0x0001 (1 )
+ .labelFrequency = 0x0001 (1 )
+ .tickMarkFrequency = 0x0001 (1 )
+ .options = 0x0001 (1 )
+ .valueAxisCrossing = true
+ .crossesFarRight = false
+ .reversed = false
+ [/CATSERRANGE]
+
+ ============================================
+ Offset 0x1124 (4388)
+ rectype = 0x1062, recsize = 0x12
+ -BEGIN DUMP---------------------------------
+ 00000000 1C 90 39 90 02 00 00 00 01 00 00 00 00 00 1C 90 ..9.............
+ 00000010 FF 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1062, size =18
+ [AXCEXT]
+ .minimumCategory = 0x901C (-28644 )
+ .maximumCategory = 0x9039 (-28615 )
+ .majorUnitValue = 0x0002 (2 )
+ .majorUnit = 0x0000 (0 )
+ .minorUnitValue = 0x0001 (1 )
+ .minorUnit = 0x0000 (0 )
+ .baseUnit = 0x0000 (0 )
+ .crossingPoint = 0x901C (-28644 )
+ .options = 0x00FF (255 )
+ .defaultMinimum = true
+ .defaultMaximum = true
+ .defaultMajor = true
+ .defaultMinorUnit = true
+ .isDate = true
+ .defaultBase = true
+ .defaultCross = true
+ .defaultDateSettings = true
+ [/AXCEXT]
+
+ ============================================
+ Offset 0x113a (4410)
+ rectype = 0x101e, recsize = 0x1e
+ -BEGIN DUMP---------------------------------
+ 00000000 02 00 03 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 00 00 00 00 00 00 23 00 4D 00 2D 00 ........#.M.-.
+ -END DUMP-----------------------------------
+ recordid = 0x101e, size =30
+ [TICK]
+ .majorTickType = 0x02 (2 )
+ .minorTickType = 0x00 (0 )
+ .labelPosition = 0x03 (3 )
+ .background = 0x01 (1 )
+ .labelColorRgb = 0x00000000 (0 )
+ .zero1 = 0x0000 (0 )
+ .zero2 = 0x0000 (0 )
+ .options = 0x0023 (35 )
+ .autoTextColor = true
+ .autoTextBackground = true
+ .rotation = 0
+ .autorotate = true
+ .tickColor = 0x004D (77 )
+ .zero3 = 0x002D (45 )
+ [/TICK]
+
+ ============================================
+ Offset 0x115c (4444)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x1160 (4448)
+ rectype = 0x101d, recsize = 0x12
+ -BEGIN DUMP---------------------------------
+ 00000000 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x101d, size =18
+ [AXIS]
+ .axisType = 0x0001 (1 )
+ .reserved1 = 0x00000000 (0 )
+ .reserved2 = 0x00000000 (0 )
+ .reserved3 = 0x00000000 (0 )
+ .reserved4 = 0x00000000 (0 )
+ [/AXIS]
+
+ <!-- Comment to avoid forrest bug -->
+ ============================================
+ Offset 0x1176 (4470)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0x117a (4474)
+ rectype = 0x101f, recsize = 0x2a
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000020 00 00 00 00 00 00 00 00 1F 01 ..........
+ -END DUMP-----------------------------------
+ recordid = 0x101f, size =42
+ [VALUERANGE]
+ .minimumAxisValue = (0.0 )
+ .maximumAxisValue = (0.0 )
+ .majorIncrement = (0.0 )
+ .minorIncrement = (0.0 )
+ .categoryAxisCross = (0.0 )
+ .options = 0x011F (287 )
+ .automaticMinimum = true
+ .automaticMaximum = true
+ .automaticMajor = true
+ .automaticMinor = true
+ .automaticCategoryCrossing = true
+ .logarithmicScale = false
+ .valuesInReverse = false
+ .crossCategoryAxisAtMaximum = false
+ .reserved = true
+ [/VALUERANGE]
+
+ ============================================
+ Offset 0x11a8 (4520)
+ rectype = 0x101e, recsize = 0x1e
+ -BEGIN DUMP---------------------------------
+ 00000000 02 00 03 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 00 00 00 00 00 00 23 00 4D 00 00 00 ........#.M...
+ -END DUMP-----------------------------------
+ recordid = 0x101e, size =30
+ [TICK]
+ .majorTickType = 0x02 (2 )
+ .minorTickType = 0x00 (0 )
+ .labelPosition = 0x03 (3 )
+ .background = 0x01 (1 )
+ .labelColorRgb = 0x00000000 (0 )
+ .zero1 = 0x0000 (0 )
+ .zero2 = 0x0000 (0 )
+ .options = 0x0023 (35 )
+ .autoTextColor = true
+ .autoTextBackground = true
+ .rotation = 0
+ .autorotate = true
+ .tickColor = 0x004D (77 )
+ .zero3 = 0x0000 (0 )
+ [/TICK]
+
+ ============================================
+ Offset 0x11ca (4554)
+ rectype = 0x1021, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 01 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1021, size =2
+ [AXISLINEFORMAT]
+ .axisType = 0x0001 (1 )
+ [/AXISLINEFORMAT]
+
+ ============================================
+ Offset 0x11d0 (4560)
+ rectype = 0x1007, recsize = 0xc
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 00 00 00 00 FF FF 09 00 4D 00 ..........M.
+ -END DUMP-----------------------------------
+ recordid = 0x1007, size =12
+ [LINEFORMAT]
+ .lineColor = 0x00000000 (0 )
+ .linePattern = 0x0000 (0 )
+ .weight = 0xFFFF (-1 )
+ .format = 0x0009 (9 )
+ .auto = true
+ .drawTicks = false
+ .unknown = false
+ .colourPaletteIndex = 0x004D (77 )
+ [/LINEFORMAT]
+
+ ============================================
+ Offset 0x11e0 (4576)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x11e4 (4580)
+ rectype = 0x1035, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1035, size =0
+ [PLOTAREA]
+ [/PLOTAREA]
+
+ ============================================
+ Offset 0x11e8 (4584)
+ rectype = 0x1032, recsize = 0x4
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 03 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x1032, size =4
+ [FRAME]
+ .borderType = 0x0000 (0 )
+ .options = 0x0003 (3 )
+ .autoSize = true
+ .autoPosition = true
+ [/FRAME]
+
+ ============================================
+ Offset 0x11f0 (4592)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0x11f4 (4596)
+ rectype = 0x1007, recsize = 0xc
+ -BEGIN DUMP---------------------------------
+ 00000000 80 80 80 00 00 00 00 00 00 00 17 00 ............
+ -END DUMP-----------------------------------
+ recordid = 0x1007, size =12
+ [LINEFORMAT]
+ .lineColor = 0x00808080 (8421504 )
+ .linePattern = 0x0000 (0 )
+ .weight = 0x0000 (0 )
+ .format = 0x0000 (0 )
+ .auto = false
+ .drawTicks = false
+ .unknown = false
+ .colourPaletteIndex = 0x0017 (23 )
+ [/LINEFORMAT]
+
+ ============================================
+ Offset 0x1204 (4612)
+ rectype = 0x100a, recsize = 0x10
+ -BEGIN DUMP---------------------------------
+ 00000000 C0 C0 C0 00 00 00 00 00 01 00 00 00 16 00 4F 00 ..............O.
+ -END DUMP-----------------------------------
+ recordid = 0x100a, size =16
+ [AREAFORMAT]
+ .foregroundColor = 0x00C0C0C0 (12632256 )
+ .backgroundColor = 0x00000000 (0 )
+ .pattern = 0x0001 (1 )
+ .formatFlags = 0x0000 (0 )
+ .automatic = false
+ .invert = false
+ .forecolorIndex = 0x0016 (22 )
+ .backcolorIndex = 0x004F (79 )
+ [/AREAFORMAT]
+
+ ============================================
+ Offset 0x1218 (4632)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x121c (4636)
+ rectype = 0x1014, recsize = 0x14
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 00 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x1014, size =20
+ [CHARTFORMAT]
+ .xPosition = 0
+ .yPosition = 0
+ .width = 0
+ .height = 0
+ .grBit = 0
+ [/CHARTFORMAT]
+
+ ============================================
+ Offset 0x1234 (4660)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0x1238 (4664)
+ rectype = 0x1017, recsize = 0x6
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 96 00 00 00 ......
+ -END DUMP-----------------------------------
+ recordid = 0x1017, size =6
+ [BAR]
+ .barSpace = 0x0000 (0 )
+ .categorySpace = 0x0096 (150 )
+ .formatFlags = 0x0000 (0 )
+ .horizontal = false
+ .stacked = false
+ .displayAsPercentage = false
+ .shadow = false
+ [/BAR]
+
+ ============================================
+ Offset 0x1242 (4674)
+ rectype = 0x1022, recsize = 0xa
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 00 00 00 00 00 00 0F 00 ..........
+ -END DUMP-----------------------------------
+ recordid = 0x1022, size =10
+ [UNKNOWN RECORD]
+ .id = 1022
+ [/UNKNOWN RECORD]
+
+ ============================================
+ Offset 0x1250 (4688)
+ rectype = 0x1015, recsize = 0x14
+ -BEGIN DUMP---------------------------------
+ 00000000 D6 0D 00 00 1E 06 00 00 B5 01 00 00 D5 00 00 00 ................
+ 00000010 03 01 1F 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x1015, size =20
+ [LEGEND]
+ .xAxisUpperLeft = 0x00000DD6 (3542 )
+ .yAxisUpperLeft = 0x0000061E (1566 )
+ .xSize = 0x000001B5 (437 )
+ .ySize = 0x000000D5 (213 )
+ .type = 0x03 (3 )
+ .spacing = 0x01 (1 )
+ .options = 0x001F (31 )
+ .autoPosition = true
+ .autoSeries = true
+ .autoXPositioning = true
+ .autoYPositioning = true
+ .vertical = true
+ .dataTable = false
+ [/LEGEND]
+
+ ============================================
+ Offset 0x1268 (4712)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0x126c (4716)
+ rectype = 0x104f, recsize = 0x14
+ -BEGIN DUMP---------------------------------
+ 00000000 05 00 02 00 D6 0D 00 00 1E 06 00 00 00 00 00 00 ................
+ 00000010 00 00 00 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x104f, size =20
+ [UNKNOWN RECORD]
+ .id = 104f
+ [/UNKNOWN RECORD]
+
+ ============================================
+ Offset 0x1284 (4740)
+ rectype = 0x1025, recsize = 0x20
+ -BEGIN DUMP---------------------------------
+ 00000000 02 02 01 00 00 00 00 00 DB FF FF FF C4 FF FF FF ................
+ 00000010 00 00 00 00 00 00 00 00 B1 00 4D 00 70 37 00 00 ..........M.p7..
+ -END DUMP-----------------------------------
+ recordid = 0x1025, size =32
+ [TEXT]
+ .horizontalAlignment = 0x02 (2 )
+ .verticalAlignment = 0x02 (2 )
+ .displayMode = 0x0001 (1 )
+ .rgbColor = 0x00000000 (0 )
+ .x = 0xFFFFFFDB (-37 )
+ .y = 0xFFFFFFC4 (-60 )
+ .width = 0x00000000 (0 )
+ .height = 0x00000000 (0 )
+ .options1 = 0x00B1 (177 )
+ .autoColor = true
+ .showKey = false
+ .showValue = false
+ .vertical = false
+ .autoGeneratedText = true
+ .generated = true
+ .autoLabelDeleted = false
+ .autoBackground = true
+ .rotation = 0
+ .showCategoryLabelAsPercentage = false
+ .showValueAsPercentage = false
+ .showBubbleSizes = false
+ .showLabel = false
+ .indexOfColorValue = 0x004D (77 )
+ .options2 = 0x3770 (14192 )
+ .dataLabelPlacement = 0
+ .textRotation = 0x0000 (0 )
+ [/TEXT]
+
+ ============================================
+ Offset 0x12a8 (4776)
+ rectype = 0x1033, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1033, size =0
+ [BEGIN]
+ [/BEGIN]
+
+ ============================================
+ Offset 0x12ac (4780)
+ rectype = 0x104f, recsize = 0x14
+ -BEGIN DUMP---------------------------------
+ 00000000 02 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00000010 00 00 00 00 ....
+ -END DUMP-----------------------------------
+ recordid = 0x104f, size =20
+ [UNKNOWN RECORD]
+ .id = 104f
+ [/UNKNOWN RECORD]
+
+ ============================================
+ Offset 0x12c4 (4804)
+ rectype = 0x1051, recsize = 0x8
+ -BEGIN DUMP---------------------------------
+ 00000000 00 01 00 00 00 00 00 00 ........
+ -END DUMP-----------------------------------
+ recordid = 0x1051, size =8
+ [AI]
+ .linkType = 0x00 (0 )
+ .referenceType = 0x01 (1 )
+ .options = 0x0000 (0 )
+ .customNumberFormat = false
+ .indexNumberFmtRecord = 0x0000 (0 )
+ .formulaOfLink = (org.apache.poi.hssf.record.LinkedDataFormulaField@1d05c81 )
+ [/AI]
+
+ ============================================
+ Offset 0x12d0 (4816)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ <!-- Comment to avoid forrest bug -->
+ ============================================
+ Offset 0x12d4 (4820)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x12d8 (4824)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x12dc (4828)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ Offset 0x12e0 (4832)
+ rectype = 0x1034, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0x1034, size =0
+ [END]
+ [/END]
+
+ ============================================
+ rectype = 0x200, recsize = 0xe
+ -BEGIN DUMP---------------------------------
+ 00000000 00 00 00 00 1F 00 00 00 00 00 01 00 00 00 ..............
+ -END DUMP-----------------------------------
+ recordid = 0x200, size =14
+ [DIMENSIONS]
+ .firstrow = 0
+ .lastrow = 1f
+ .firstcol = 0
+ .lastcol = 1
+ .zero = 0
+ [/DIMENSIONS]
+
+ ============================================
+ rectype = 0x1065, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 02 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1065, size =2
+ [SINDEX]
+ .index = 0x0002 (2 )
+ [/SINDEX]
+
+ ============================================
+ rectype = 0x1065, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 01 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1065, size =2
+ [SINDEX]
+ .index = 0x0001 (1 )
+ [/SINDEX]
+
+ ============================================
+ rectype = 0x1065, recsize = 0x2
+ -BEGIN DUMP---------------------------------
+ 00000000 03 00 ..
+ -END DUMP-----------------------------------
+ recordid = 0x1065, size =2
+ [SINDEX]
+ .index = 0x0003 (3 )
+ [/SINDEX]
+
+ ============================================
+ rectype = 0xa, recsize = 0x0
+ -BEGIN DUMP---------------------------------
+ **NO RECORD DATA**
+ -END DUMP-----------------------------------
+ recordid = 0xa, size =0
+ [EOF]
+ [/EOF]
+
+
+ </source>
+ <p>
+ The next section breaks those records down into an easier
+ to read format:
+ </p>
+ <source>
+[UNKNOWN RECORD:ec]
+[UNKNOWN RECORD:5d]
+[BOF RECORD]
+ [HEADER]
+ [FOOTER]
+ [HCENTER]
+ [VCENTER]
+ [PRINTSETUP]
+ [UNKNOWN RECORD:33]
+ [FBI]
+ [FBI]
+ [PROTECT]
+ [UNITS]
+ [CHART]
+ [BEGIN]
+ [SCL] // zoom magnification
+ [PLOTGROWTH] // font scaling
+ [FRAME] // border around text
+ [BEGIN] // default line and area format
+ [LINEFORMAT]
+ [AREAFORMAT]
+ [END]
+ [SERIES] // start of series
+ [BEGIN]
+ [AI] // LINK_TYPE_TITLE_OR_TEXT
+ [AI] // LINK_TYPE_VALUES
+ [AI] // LINK_TYPE_CATEGORIES
+ [AI] // ??
+ [DATAFORMAT] // Formatting applies to series?
+ [BEGIN] // ??
+ [UNKNOWN RECORD]
+ [END]
+ [SeriesToChartGroup] // Used to support > 1 chart?
+ [END]
+ [SHTPROPS] // Some defaults for how chart is displayed.
+ [DEFAULTTEXT] // Describes the characteristics of the next
+ // record
+ [TEXT] // Details of the text that follows in the
+ // next section
+ [BEGIN]
+ [UNKNOWN RECORD] // POS record... looks like I missed this one.
+ // docs seem to indicate it's better to use
+ // defaults...
+ [FONTX] // index to font record.
+ [AI] // link to text? seems to be linking to nothing
+ [END]
+ [DEFAULTTEXT] // contains a category type of 3 which is not
+ // documented (sigh).
+ [TEXT] // defines position, color etc for text on chart.
+ [BEGIN]
+ [UNKNOWN RECORD] // Another pos record
+ [FONTX] // font
+ [AI] // reference type is DIRECT (not sure what this
+ // means)
+ [END]
+ [AXISUSED] // number of axis on the chart.
+ [AXISPARENT] // axis size and location
+ [BEGIN] // beginning of axis details
+ [UNKNOWN RECORD] // Another pos record.
+ [AXIS] // Category axis
+ [BEGIN]
+ [CATSERRANGE] // defines tick marks and other stuff
+ [AXCEXT] // unit information
+ [TICK] // tick formating characteristics
+ [END]
+ [AXIS] // Value axis
+ [BEGIN]
+ [VALUERANGE] // defines tick marks and other stuff
+ [TICK] // tick formating characteristics
+ [AXISLINEFORMAT] // major grid line axis format
+ [LINEFORMAT] // what do the lines look like?
+ [END]
+ [PLOTAREA] // marks that the frame following belongs
+ // to the frame.
+ [FRAME] // border
+ [BEGIN]
+ [LINEFORMAT] // border line
+ [AREAFORMAT] // border area
+ [END]
+ [CHARTFORMAT] // marks a chart group
+ [BEGIN]
+ [BAR] // indicates a bar chart
+ [UNKNOWN RECORD] // apparently this record is ignoreable
+ [LEGEND] // positioning for the legend
+ [BEGIN]
+ [UNKNOWN RECORD] // another position record.
+ [TEXT] // details of the text that follows
+ // in the next section
+ [BEGIN]
+ [UNKNOWN RECORD] // yet another pos record
+ [AI] // another link (of type direct)
+ [END]
+ [END]
+ [END]
+ [END]
+ [END]
+ [DIMENSIONS]
+ [SINDEX]
+ [SINDEX]
+ [SINDEX]
+[EOF]
+ </source>
+ <p>
+ Just a quick note on some of the unknown records:
+ </p>
+ <ul>
+ <li>EC: MSODRAWING - A Microsoft drawing record. (Need to
+ track down where this is documented).</li>
+ <li>5D: OBJ: Description of a drawing object. (This is going to
+ be a PITA to implement).</li>
+ <li>33: Not documented. :-(</li>
+ <li>105f: Not documented. :-(</li>
+ <li>104f: POS: Position record (should be able to safely leave this out).</li>
+ <li>1022: CHARTFORMATLINK: Can be left out.</li>
+ </ul>
+ <p>
+ It is currently suspected that many of those records could be
+ left out when generating a bar chart from scratch. The way
+ we will be proceeding with this is to write code that generates
+ most of these records and then start removing them to see
+ how this effects the chart in excel.
+ </p>
+ </section>
+ <section><title>Inserting the Chart into the Workbook</title>
+ <ul>
+ <li>
+ Unknown record (sid=00eb) is inserted before the SST
+ record.
+ </li>
+ </ul>
+ <source>
+ ============================================
+ rectype = 0xeb, recsize = 0x5a
+ -BEGIN DUMP---------------------------------
+ 00000000 0F 00 00 F0 52 00 00 00 00 00 06 F0 18 00 00 00 ....R...........
+ 00000010 01 08 00 00 02 00 00 00 02 00 00 00 01 00 00 00 ................
+ 00000020 01 00 00 00 03 00 00 00 33 00 0B F0 12 00 00 00 ........3.......
+ 00000030 BF 00 08 00 08 00 81 01 09 00 00 08 C0 01 40 00 ..............@.
+ 00000040 00 08 40 00 1E F1 10 00 00 00 0D 00 00 08 0C 00 ..@.............
+ 00000050 00 08 17 00 00 08 F7 00 00 10 ..........
+ -END DUMP-----------------------------------
+ recordid = 0xeb, size =90
+ [UNKNOWN RECORD:eb]
+ .id = eb
+ [/UNKNOWN RECORD]
+
+ ============================================
+ </source>
+ <ul>
+ <li>
+ Any extra font records are inserted as needed
+ </li>
+ <li>
+ Chart records inserted after DBCell records.
+ </li>
+ </ul>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Upgrading to POI 3.5, including converting existing HSSF Usermodel code to SS Usermodel (for XSSF and HSSF)</title>
+ <authors>
+ <person email="nick@apache.org" name="Nick Burch" id="NB"/>
+ </authors>
+ </header>
+ <body>
+<section><title>Things that have to be changed when upgrading to POI 3.5</title>
+ <p>Wherever possible, we have tried to ensure that you can use your
+ existing POI code with POI 3.5 without requiring any changes. However,
+ Java doesn't always make that easy, and unfortunately there are a
+ few changes that may be required for some users.</p>
+ <section><title>org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue</title>
+ <p>Annoyingly, java will not let you access a static inner class via
+ a child of the parent one. So, all references to
+ <em>org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue</em>
+ will need to be changed to
+ <em>org.apache.poi.ss.usermodel.FormulaEvaluator.CellValue</em>
+ </p>
+ </section>
+ <section><title>org.apache.poi.hssf.usermodel.HSSFRow.MissingCellPolicy</title>
+ <p>Annoyingly, java will not let you access a static inner class via
+ a child of the parent one. So, all references to
+ <em>org.apache.poi.hssf.usermodel.HSSFRow.MissingCellPolicy</em>
+ will need to be changed to
+ <em>org.apache.poi.ss.usermodel.Row.MissingCellPolicy</em>
+ </p>
+ </section>
+ <section><title>DDF and org.apache.poi.hssf.record.RecordFormatException</title>
+ <p>Previously, record level errors within DDF would throw an
+ exception from the hssf class heirachy. Now, record level errors
+ within DDF will throw a more general RecordFormatException,
+ <em>org.apache.poi.util.RecordFormatException</em></p>
+ <p>In addition, org.apache.poi.hssf.record.RecordFormatException
+ has been changed to inherit from the new
+ <em>org.apache.poi.util.RecordFormatException</em>, so you may
+ wish to change catches of the hssf version to the new util version.
+ </p>
+ </section>
+ </section>
+ <section><title>Converting existing HSSF Usermodel code to SS Usermodel (for XSSF and HSSF)</title>
+
+ <section><title>Why change?</title>
+ <p>If you have existing HSSF usermodel code that works just
+ fine, and you don't want to use the new OOXML XSSF support,
+ then you probably don't need to. Your existing HSSF only code
+ will continue to work just fine.</p>
+ <p>However, if you want to be able to work with both HSSF for
+ your .xls files, and also XSSF for .xslx files, then you will
+ need to make some slight tweaks to your code.</p>
+ </section>
+ <section><title>org.apache.poi.ss.usermodel</title>
+ <p>The new SS usermodel (org.apache.poi.ss.usermodel) is very
+ heavily based on the old HSSF usermodel
+ (org.apache.poi.hssf.usermodel). The main difference is that
+ the package name and class names have been tweaked to remove
+ HSSF from them. Otherwise, the new SS Usermodel interfaces
+ should provide the same functionality.</p>
+ </section>
+ <section><title>Constructors</title>
+ <p>Calling the empty HSSFWorkbook remains as the way to
+ create a new, empty Workbook object. To open an existing
+ Worbook, you should now call WorkbookFactory.create(inp).</p>
+ <p>For all other cases when you would have called a
+ Usermodel constructor, such as 'new HSSFRichTextString()' or
+ 'new HSSFDataFormat', you should instead use a CreationHelper.
+ There's a method on the Workbook to get a CreationHelper, and
+ the CreationHelper will then handle constructing new objects
+ for you.</p>
+ </section>
+ <section><title>Other Code</title>
+ <p>For all other code, generally change a reference from
+ org.apache.poi.hssf.usermodel.HSSFFoo to a reference to
+ org.apache.poi.ss.usermodel.Foo. Method signatures should
+ otherwise remain the same, and it should all then work for
+ both XSSF and HSSF.</p>
+ </section>
+ </section>
+ <section><title>Worked Examples</title>
+ <section><title>Old HSSF Code</title>
+<source><![CDATA[
+// import org.apache.poi.hssf.usermodel.*;
+
+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 2 cell styles
+HSSFCellStyle cs = wb.createCellStyle();
+HSSFCellStyle cs2 = wb.createCellStyle();
+HSSFDataFormat df = wb.createDataFormat();
+
+// create 2 fonts objects
+HSSFFont f = wb.createFont();
+HSSFFont f2 = wb.createFont();
+
+// Set font 1 to 12 point type, blue and bold
+f.setFontHeightInPoints((short) 12);
+f.setColor( HSSFColor.RED.index );
+f.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
+
+// Set font 2 to 10 point type, red and bold
+f2.setFontHeightInPoints((short) 10);
+f2.setColor( HSSFFont.RED.index );
+f2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
+
+// Set cell style and formatting
+cs.setFont(f);
+cs.setDataFormat(df.getFormat("#,##0.0"));
+
+// Set the other cell style and formatting
+cs2.setBorderBottom(cs2.BORDER_THIN);
+cs2.setDataFormat(HSSFDataFormat.getBuiltinFormat("text"));
+cs2.setFont(f2);
+
+
+// Define a few rows
+for(short rownum = (short)0; rownum < 30; rownum++) {
+ HSSFRow r = s.createRow(rownum);
+ for(short cellnum = (short)0; cellnum < 10; cellnum += 2) {
+ HSSFCell c = r.createCell(cellnum);
+ HSSFCell c2 = r.createCell(cellnum+1);
+
+ c.setCellValue((double)rownum + (cellnum/10));
+ c2.setCellValue(new HSSFRichTextString("Hello! " + cellnum);
+ }
+}
+
+// Save
+FileOutputStream out = new FileOutputStream("workbook.xls");
+wb.write(out);
+out.close();
+ ]]></source>
+ </section>
+ <section><title>New, generic SS Usermodel Code</title>
+<source><![CDATA[
+// import org.apache.poi.ss.usermodel.*;
+
+Workbook[] wbs = new Workbook[] { new HSSFWorkbook(), new XSSFWorkbook() };
+for(int i=0; i<wbs.length; i++) {
+ Workbook wb = wbs[i];
+ CreationHelper createHelper = wb.getCreationHelper();
+
+ // create a new sheet
+ Sheet s = wb.createSheet();
+ // declare a row object reference
+ Row r = null;
+ // declare a cell object reference
+ Cell c = null;
+ // create 2 cell styles
+ CellStyle cs = wb.createCellStyle();
+ CellStyle cs2 = wb.createCellStyle();
+ DataFormat df = wb.createDataFormat();
+
+ // create 2 fonts objects
+ Font f = wb.createFont();
+ Font f2 = wb.createFont();
+
+ // Set font 1 to 12 point type, blue and bold
+ f.setFontHeightInPoints((short) 12);
+ f.setColor( IndexedColors.RED.getIndex() );
+ f.setBoldweight(Font.BOLDWEIGHT_BOLD);
+
+ // Set font 2 to 10 point type, red and bold
+ f2.setFontHeightInPoints((short) 10);
+ f2.setColor( IndexedColors.RED.getIndex() );
+ f2.setBoldweight(Font.BOLDWEIGHT_BOLD);
+
+ // Set cell style and formatting
+ cs.setFont(f);
+ cs.setDataFormat(df.getFormat("#,##0.0"));
+
+ // Set the other cell style and formatting
+ cs2.setBorderBottom(cs2.BORDER_THIN);
+ cs2.setDataFormat(df.getFormat("text"));
+ cs2.setFont(f2);
+
+
+ // Define a few rows
+ for(int rownum = 0; rownum < 30; rownum++) {
+ Row r = s.createRow(rownum);
+ for(int cellnum = 0; cellnum < 10; cellnum += 2) {
+ Cell c = r.createCell(cellnum);
+ Cell c2 = r.createCell(cellnum+1);
+
+ c.setCellValue((double)rownum + (cellnum/10));
+ c2.setCellValue(
+ createHelper.createRichTextString("Hello! " + cellnum)
+ );
+ }
+ }
+
+ // Save
+ String filename = "workbook.xls";
+ if(wb instanceof XSSFWorkbook) {
+ filename = filename + "x";
+ }
+
+ FileOutputStream out = new FileOutputStream(filename);
+ wb.write(out);
+ out.close();
+}
+ ]]></source>
+ </section>
+</section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!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</title>
+ <p>
+ <img src="images/usermodel.gif" alt="Usermodel"/>
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!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</title>
+ <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 "bug" 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 < 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>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Developing Formula Evaluation</title>
+ <authors>
+ <person email="amoweb@yahoo.com" name="Amol Deshmukh" id="AD"/>
+ <person email="yegor@apache.org" name="Yegor Kozlov" id="YK"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Introduction</title>
+ <p>This document is for developers wishing to contribute to the
+ FormulaEvaluator API functionality.</p>
+ <p>When evaluating workbooks you may encounter a org.apache.poi.ss.formula.eval.NotImplementedException
+ which indicates that a function is not (yet) supported by POI. Is there a workaround?
+ Yes, the POI framework makes it easy to add implementation of new functions. Prior to POI-3.8
+ you had to checkout the source code from svn and make a custom build with your function implementation.
+ Since POI-3.8 you can register new functions in run-time.
+ </p>
+ <p>Currently, contribution is desired for implementing the standard MS
+ excel functions. Place holder classes for these have been created,
+ contributors only need to insert implementation for the
+ individual "evaluate()" methods that do the actual evaluation.</p>
+ </section>
+
+ <section><title>Overview of FormulaEvaluator </title>
+ <p>Briefly, a formula string (along with the sheet and workbook that
+ form the context in which the formula is evaluated) is first parsed
+ into RPN tokens using the FormulaParser class .
+ (If you dont know what RPN tokens are, now is a good time to
+ read <link href="http://www-stone.ch.cam.ac.uk/documentation/rrf/rpn.html">
+ this</link>.)
+ </p>
+ <section><title> The big picture</title>
+ <p>RPN tokens are mapped to Eval classes. (Class hierarchy for the Evals
+ is best understood if you view the class diagram in a class diagram
+ viewer.) Depending on the type of RPN token (also called as Ptgs
+ henceforth since that is what the FormulaParser calls the classes) a
+ specific type of Eval wrapper is constructed to wrap the RPN token and
+ is pushed on the stack.... UNLESS the Ptg is an OperationPtg. If it is an
+ OperationPtg, an OperationEval instance is created for the specific
+ type of OperationPtg. And depending on how many operands it takes,
+ that many Evals are popped of the stack and passed in an array to
+ the OperationEval instance's evaluate method which returns an Eval
+ of subtype ValueEval.Thus an operation in the formula is evaluated. </p>
+ <note> An Eval is of subinterface ValueEval or OperationEval.
+ Operands are always ValueEvals, Operations are always OperationEvals.</note>
+ <p><code>OperationEval.evaluate(Eval[])</code> returns an Eval which is supposed
+ to be of type ValueEval (actually since ValueEval is an interface,
+ the return value is instance of one of the implementations of
+ ValueEval). The valueEval resulting from evaluate() is pushed on the
+ stack and the next RPN token is evaluated.... this continues till
+ eventually there are no more RPN tokens at which point, if the formula
+ string was correctly parsed, there should be just one Eval on the
+ stack - which contains the result of evaluating the formula.</p>
+ <p>Of course I glossed over the details of how AreaPtg and ReferencePtg
+ are handled a little differently, but the code should be self
+ explanatory for that. Very briefly, the cells included in AreaPtg and
+ RefPtg are examined and their values are populated in individual
+ ValueEval objects which are set into the AreaEval and RefEval (ok,
+ since AreaEval and RefEval are interfaces, the implementations of
+ AreaEval and RefEval - but you'll figure all that out from the code)</p>
+ <p>OperationEvals for the standard operators have been implemented and tested.</p>
+ </section>
+ </section>
+
+ <section><title>What functions are supported?</title>
+ <p>
+ As of Feb 2012, POI supports about 140 built-in functions,
+ see <link href="#appendixA">Appendix A</link> for the full list.
+ You can programmatically list supported / unsuported functions using the following helper methods:
+ </p>
+ <source>
+ // list of functions that POI can evaluate
+ Collection<String> supportedFuncs = WorkbookEvaluator.getSupportedFunctionNames();
+
+ // list of functions that are not supported by POI
+ Collection<String> unsupportedFuncs = WorkbookEvaluator.getNotSupportedFunctionNames();
+
+ </source>
+ </section>
+
+ <section><title>Two base interfaces to start your implementation</title>
+ <p>
+ All Excel formula function classes implement either
+ org.apache.poi.hssf.record.formula.functions.Function or
+ org.apache.poi.hssf.record.formula.functions.FreeRefFunction interface.
+
+ Function is a commonn interface for the functions defined in the binary Excel format (BIFF8): these are "classic" Excel functions like SUM, COUNT, LOOKUP, etc.
+ FreeRefFunction is a common interface for the functions from the Excel Analysis Toolpack and for User-Defined Functions.
+ In the future these two interfaces are expected be unified into one, but for now you have to start your implementation from two slightly different roots.
+
+ </p>
+ </section>
+
+ <section><title>Which interface to start from?</title>
+ <p>
+ You are about to implement a function XXX and don't know which interface to start from: Function or FreeRefFunction.
+ Use the following code to check whether your function is from the excel Analysis Toolpack:
+ </p>
+ <source>
+ if(AnalysisToolPack.isATPFunction(functionName)){
+ // the function implements org.apache.poi.hssf.record.formula.functions.Function
+ } else {
+ // the function implements org.apache.poi.hssf.record.formula.functions.FreeRefFunction
+ }
+ </source>
+ </section>
+
+
+ <section><title>Walkthrough of an "evaluate()" implementation.</title>
+ <p>Here is the fun part: lets walk through the implementation of the excel function <strong>SQRT()</strong>
+ </p>
+ <p>
+ AnalysisToolPack.isATPFunction("SQRTPI") returns false so the base interface is Function.
+
+ There are sub-interfaces that make life easier when implementing numeric functions or functions
+ with fixed number of arguments, 1-arg, 2-arg and 3-arg function:
+ </p>
+ <ul>
+ <li>org.apache.poi.hssf.record.formula.functions.NumericFunction</li>
+ <li>org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction</li>
+ <li>org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction</li>
+ <li>org.apache.poi.hssf.record.formula.functions.Fixed3ArgFunction</li>
+ <li>org.apache.poi.hssf.record.formula.functions.Fixed4ArgFunction</li>
+ </ul>
+ <p>
+ Since SQRTPI takes exactly one argument we start our implementation from org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction:
+ </p>
+
+ <source>
+ Function SQRTPI = new Fixed1ArgFunction() {
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
+ try {
+ // Retrieves a single value from a variety of different argument types according to standard
+ // Excel rules. Does not perform any type conversion.
+ ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
+
+ // Applies some conversion rules if the supplied value is not already a number.
+ // Throws EvaluationException(#VALUE!) if the supplied parameter is not a number
+ double arg = OperandResolver.coerceValueToDouble(ve);
+
+ // this where all the heavy-lifting happens
+ double result = Math.sqrt(arg*Math.PI);
+
+ // Excel uses the error code #NUM! instead of IEEE <em>NaN</em> and <em>Infinity</em>,
+ // so when a numeric function evaluates to Double.NaN or Double.Infinity,
+ // be sure to translate the result to the appropriate error code
+ if (Double.isNaN(result) || Double.isInfinite(result)) {
+ throw new EvaluationException(ErrorEval.NUM_ERROR);
+ }
+
+ return new NumberEval(result);
+ } catch (EvaluationException e){
+ return e.getErrorEval();
+ }
+ }
+ }
+ </source>
+
+ <p>Now when the implementation is ready we need to register it in the formula evaluator:</p>
+ <source>
+ WorkbookEvaluator.registerFunction("SQRTPI", SQRTPI);
+ </source>
+
+ <p>Voila! The formula evaluator now recognizes SQRTPI! </p>
+
+ </section>
+
+ <section><title>Floating-point Arithmetic in Excel</title>
+ <p>Excel uses the IEEE Standard for Double Precision Floating Point numbers
+ except two cases where it does not adhere to IEEE 754:
+ </p>
+ <ol>
+ <li>Positive/Negative Infinities: Infinities occur when you divide by 0.
+ Excel does not support infinities, rather, it gives a #DIV/0! error in these cases.
+ </li>
+ <li>Not-a-Number (NaN): NaN is used to represent invalid operations
+ (such as infinity/infinity, infinity-infinity, or the square root of -1).
+ NaNs allow a program to continue past an invalid operation.
+ Excel instead immediately generates an error such as #NUM! or #DIV/0!.
+ </li>
+ </ol>
+ <p>Be aware of these two cases when saving results of your scientific calculations in Excel:
+ “where are my Infinities and NaNs? They are gone!”
+ </p>
+ </section>
+
+ <section><title>Testing Framework</title>
+ <p>Automated testing of the implemented Function is easy.
+ The source code for this is in the file: o.a.p.h.record.formula.GenericFormulaTestCase.java
+ This class has a reference to the test xls file (not /a/ test xls, /the/ test xls :)
+ which may need to be changed for your environment. Once you do that, in the test xls,
+ locate the entry for the function that you have implemented and enter different tests
+ in a cell in the FORMULA row. Then copy the "value of" the formula that you entered in the
+ cell just below it (this is easily done in excel as:
+ [copy the formula cell] > [go to cell below] > Edit > Paste Special > Values > "ok").
+ You can enter multiple such formulas and paste their values in the cell below and the
+ test framework will automatically test if the formula evaluation matches the expected
+ value (Again, hard to put in words, so if you will, please take time to quickly look
+ at the code and the currently entered tests in the patch attachment "FormulaEvalTestData.xls"
+ file).
+ </p>
+ </section>
+
+ <anchor id="appendixA"/>
+ <section>
+ <title>Appendix A</title>
+ <p>Functions supported by POI ( as of Feb 2012)</p>
+ <source>
+ ABS
+ ACOS
+ ACOSH
+ ADDRESS
+ AND
+ ASIN
+ ASINH
+ ATAN
+ ATAN2
+ ATANH
+ AVEDEV
+ AVERAGE
+ CEILING
+ CHAR
+ CHOOSE
+ CLEAN
+ COLUMN
+ COLUMNS
+ COMBIN
+ CONCATENATE
+ COS
+ COSH
+ COUNT
+ COUNTA
+ COUNTBLANK
+ COUNTIF
+ DATE
+ DAY
+ DAYS360
+ DEGREES
+ DEVSQ
+ DOLLAR
+ ERROR.TYPE
+ EVEN
+ EXACT
+ EXP
+ FACT
+ FALSE
+ FIND
+ FLOOR
+ FV
+ HLOOKUP
+ HOUR
+ HYPERLINK
+ IF
+ INDEX
+ INDIRECT
+ INT
+ IRR
+ ISBLANK
+ ISERROR
+ ISEVEN
+ ISLOGICAL
+ ISNA
+ ISNONTEXT
+ ISNUMBER
+ ISODD
+ ISREF
+ ISTEXT
+ LARGE
+ LEFT
+ LEN
+ LN
+ LOG
+ LOG10
+ LOOKUP
+ LOWER
+ MATCH
+ MAX
+ MAXA
+ MEDIAN
+ MID
+ MIN
+ MINA
+ MINUTE
+ MOD
+ MODE
+ MONTH
+ MROUND
+ NA
+ NETWORKDAYS
+ NOT
+ NOW
+ NPER
+ NPV
+ ODD
+ OFFSET
+ OR
+ PI
+ PMT
+ POISSON
+ POWER
+ PRODUCT
+ PV
+ RADIANS
+ RAND
+ RANDBETWEEN
+ RANK
+ RATE
+ REPLACE
+ RIGHT
+ ROUND
+ ROUNDDOWN
+ ROUNDUP
+ ROW
+ ROWS
+ SEARCH
+ SECOND
+ SIGN
+ SIN
+ SINH
+ SMALL
+ SQRT
+ STDEV
+ SUBSTITUTE
+ SUBTOTAL
+ SUM
+ SUMIF
+ SUMIFS
+ SUMPRODUCT
+ SUMSQ
+ SUMX2MY2
+ SUMX2PY2
+ SUMXMY2
+ T
+ TAN
+ TANH
+ TEXT
+ TIME
+ TODAY
+ TRIM
+ TRUE
+ TRUNC
+ UPPER
+ VALUE
+ VAR
+ VARP
+ VLOOKUP
+ WEEKDAY
+ WORKDAY
+ YEAR
+ YEARFRAC
+ </source>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Formula Evaluation</title>
+ </header>
+ <body>
+ <section><title>Introduction</title>
+ <p>The POI formula evaluation code enables you to calculate the result of
+ formulas in Excels sheets read-in, or created in POI. This document explains
+ how to use the API to evaluate your formulas.
+ </p>
+ </section>
+
+ <anchor id="WhyEvaluate"/>
+ <section><title>Why do I need to evaluate formulas?</title>
+ <p>The Excel file format (both .xls and .xlsx) stores a "cached" result for
+ every formula along with the formula itself. This means that when the file
+ is opened, it can be quickly displayed, without needing to spend a long
+ time calculating all of the formula results. It also means that when reading
+ a file through Apache POI, the result is quickly available to you too!
+ </p>
+ <p>After making changes with Apache POI to either Formula Cells themselves,
+ or those that they depend on, you should normally perform a Formula
+ Evaluation to have these "cached" results updated. This is normally done
+ after all changes have been performed, but before you write the file out.
+ If you don't do this, there's a good chance that when you open the file in
+ Excel, until you go to the cell and hit enter or F9, you will either see
+ the old value or '#VALUE!' for the cell. (Sometimes Excel will notice
+ itself, and trigger a recalculation on load, but unless you know you are
+ using volatile functions it's generally best to trigger a Recalulation
+ through POI)
+ </p>
+ </section>
+
+ <anchor id="Status"/>
+ <section><title>Status</title>
+ <p>The code currently provides implementations for all the arithmatic operators.
+ It also provides implementations for approx. 140 built in
+ functions in Excel. The framework however makes it easy to add
+ implementation of new functions. See the <link href="eval-devguide.html"> Formula
+ evaluation development guide</link> and <link href="../apidocs/org/apache/poi/hssf/record/formula/functions/package-summary.html">javadocs</link>
+ for details. </p>
+ <p> Both HSSFWorkbook and XSSFWorkbook are supported, so you can
+ evaluate formulas on both .xls and .xlsx files.</p>
+ <p> Note that user-defined functions are not supported, and is not likely to done
+ any time soon... at least, not till there is a VB implementation in Java!
+ </p>
+ </section>
+ <section><title>User API How-TO</title>
+ <p>The following code demonstrates how to use the FormulaEvaluator
+ in the context of other POI excel reading code.
+ </p>
+ <p>There are several ways in which you can use the FormulaEvalutator API.</p>
+
+ <anchor id="Evaluate"/>
+ <section><title>Using FormulaEvaluator.<strong>evaluate</strong>(Cell cell)</title>
+ <p>This evaluates a given cell, and returns the new value,
+ without affecting the cell</p>
+ <source>
+FileInputStream fis = new FileInputStream("c:/temp/test.xls");
+Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("c:/temp/test.xls")
+Sheet sheet = wb.getSheetAt(0);
+FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
+
+// suppose your formula is in B3
+CellReference cellReference = new CellReference("B3");
+Row row = sheet.getRow(cellReference.getRow());
+Cell cell = row.getCell(cellReference.getCol());
+
+CellValue cellValue = evaluator.evaluate(cell);
+
+switch (cellValue.getCellType()) {
+ case Cell.CELL_TYPE_BOOLEAN:
+ System.out.println(cellValue.getBooleanValue());
+ break;
+ case Cell.CELL_TYPE_NUMERIC:
+ System.out.println(cellValue.getNumberValue());
+ break;
+ case Cell.CELL_TYPE_STRING:
+ System.out.println(cellValue.getStringValue());
+ break;
+ case Cell.CELL_TYPE_BLANK:
+ break;
+ case Cell.CELL_TYPE_ERROR:
+ break;
+
+ // CELL_TYPE_FORMULA will never happen
+ case Cell.CELL_TYPE_FORMULA:
+ break;
+}
+ </source>
+ <p>Thus using the retrieved value (of type
+ FormulaEvaluator.CellValue - a nested class) returned
+ by FormulaEvaluator is similar to using a Cell object
+ containing the value of the formula evaluation. CellValue is
+ a simple value object and does not maintain reference
+ to the original cell.
+ </p>
+ </section>
+
+ <anchor id="EvaluateFormulaCell"/>
+ <section><title>Using FormulaEvaluator.<strong>evaluateFormulaCell</strong>(Cell cell)</title>
+ <p><strong>evaluateFormulaCell</strong>(Cell cell)
+ will check to see if the supplied cell is a formula cell.
+ If it isn't, then no changes will be made to it. If it is,
+ then the formula is evaluated. The value for the formula
+ is saved alongside it, to be displayed in excel. The
+ formula remains in the cell, just with a new value</p>
+ <p>The return of the function is the type of the
+ formula result, such as Cell.CELL_TYPE_BOOLEAN</p>
+ <source>
+FileInputStream fis = new FileInputStream("/somepath/test.xls");
+Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")
+Sheet sheet = wb.getSheetAt(0);
+FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
+
+// suppose your formula is in B3
+CellReference cellReference = new CellReference("B3");
+Row row = sheet.getRow(cellReference.getRow());
+Cell cell = row.getCell(cellReference.getCol());
+
+if (cell!=null) {
+ switch (evaluator.evaluateFormulaCell(cell)) {
+ case Cell.CELL_TYPE_BOOLEAN:
+ System.out.println(cell.getBooleanCellValue());
+ break;
+ case Cell.CELL_TYPE_NUMERIC:
+ System.out.println(cell.getNumericCellValue());
+ break;
+ case Cell.CELL_TYPE_STRING:
+ System.out.println(cell.getStringCellValue());
+ break;
+ case Cell.CELL_TYPE_BLANK:
+ break;
+ case Cell.CELL_TYPE_ERROR:
+ System.out.println(cell.getErrorCellValue());
+ break;
+
+ // CELL_TYPE_FORMULA will never occur
+ case Cell.CELL_TYPE_FORMULA:
+ break;
+ }
+}
+ </source>
+ </section>
+
+ <anchor id="EvaluateInCell"/>
+ <section><title>Using FormulaEvaluator.<strong>evaluateInCell</strong>(Cell cell)</title>
+ <p><strong>evaluateInCell</strong>(Cell cell) will check to
+ see if the supplied cell is a formula cell. If it isn't,
+ then no changes will be made to it. If it is, then the
+ formula is evaluated, and the new value saved into the cell,
+ in place of the old formula.</p>
+ <source>
+FileInputStream fis = new FileInputStream("/somepath/test.xls");
+Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")
+Sheet sheet = wb.getSheetAt(0);
+FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
+
+// suppose your formula is in B3
+CellReference cellReference = new CellReference("B3");
+Row row = sheet.getRow(cellReference.getRow());
+Cell cell = row.getCell(cellReference.getCol());
+
+if (cell!=null) {
+ switch (evaluator.<strong>evaluateInCell</strong>(cell).getCellType()) {
+ case Cell.CELL_TYPE_BOOLEAN:
+ System.out.println(cell.getBooleanCellValue());
+ break;
+ case Cell.CELL_TYPE_NUMERIC:
+ System.out.println(cell.getNumericCellValue());
+ break;
+ case Cell.CELL_TYPE_STRING:
+ System.out.println(cell.getStringCellValue());
+ break;
+ case Cell.CELL_TYPE_BLANK:
+ break;
+ case Cell.CELL_TYPE_ERROR:
+ System.out.println(cell.getErrorCellValue());
+ break;
+
+ // CELL_TYPE_FORMULA will never occur
+ case Cell.CELL_TYPE_FORMULA:
+ break;
+ }
+}
+
+ </source>
+ </section>
+
+ <anchor id="EvaluateAll"/>
+ <section><title>Re-calculating all formulas in a Workbook</title>
+ <source>
+FileInputStream fis = new FileInputStream("/somepath/test.xls");
+Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")
+FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
+for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
+ Sheet sheet = wb.getSheetAt(sheetNum);
+ for(Row r : sheet) {
+ for(Cell c : r) {
+ if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
+ evaluator.evaluateFormulaCell(c);
+ }
+ }
+ }
+}
+ </source>
+
+ <p>Alternately, if you know which of HSSF or XSSF you're working
+ with, then you can call the static
+ <strong>evaluateAllFormulaCells</strong> method on the appropriate
+ HSSFFormulaEvaluator or XSSFFormulaEvaluator class.</p>
+ </section>
+ </section>
+
+ <anchor id="recalculation"/>
+ <section><title>Recalculation of Formulas</title>
+ <p>
+ In certain cases you may want to force Excel to re-calculate formulas when the workbook is opened.
+ Consider the following example:
+ </p>
+ <p>
+ Open Excel and create a new workbook. On the first sheet set A1=1, B1=1, C1=A1+B1.
+ Excel automatically calculates formulas and the value in C1 is 2. So far so good.
+ </p>
+ <p>
+ Now modify the workbook with POI:
+ </p>
+ <source>
+ Workbook wb = WorkbookFactory.create(new FileInputStream("workbook.xls"));
+
+ Sheet sh = wb.getSheetAt(0);
+ sh.getRow(0).getCell(0).setCellValue(2); // set A1=2
+
+ FileOutputStream out = new FileOutputStream("workbook2.xls");
+ wb.write(out);
+ out.close();
+ </source>
+ <p>
+ Now open workbook2.xls in Excel and the value in C1 is still 2 while you expected 3. Wrong? No!
+ The point is that Excel caches previously calculated results and you need to trigger recalculation to updated them.
+ It is not an issue when you are creating new workbooks from scratch, but important to remember when you are modifing
+ existing workbooks with formulas. This can be done in two ways:
+ </p>
+ <p>
+ 1. Re-evaluate formulas with POI's FormulaEvaluator:
+ </p>
+ <source>
+ Workbook wb = WorkbookFactory.create(new FileInputStream("workbook.xls"));
+
+ Sheet sh = wb.getSheetAt(0);
+ sh.getRow(0).getCell(0).setCellValue(2); // set A1=2
+
+ wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
+ </source>
+ <p>
+ 2. Delegate re-calculation to Excel. The application will perform a full recalculation when the workbook is opened:
+ </p>
+ <source>
+ Workbook wb = WorkbookFactory.create(new FileInputStream("workbook.xls"));
+
+ Sheet sh = wb.getSheetAt(0);
+ sh.getRow(0).getCell(0).setCellValue(2); // set A1=2
+
+ wb.setForceFormulaRecalculation(true);
+ </source>
+ </section>
+
+ <anchor id="Performance"/>
+ <section><title>Performance Notes</title>
+ <ul>
+ <li>Generally you should have to create only one FormulaEvaluator
+ instance per Workbook. The FormulaEvaluator will cache
+ evaluations of dependent cells, so if you have multiple
+ formulas all depending on a cell then subsequent evaluations
+ will be faster.
+ </li>
+ <li>You should normally perform all of your updates to cells,
+ before triggering the evaluation, rather than doing one
+ cell at a time. By waiting until all the updates/sets are
+ performed, you'll be able to take best advantage of the caching
+ for complex formulas.
+ </li>
+ <li>If you do end up making changes to cells part way through
+ evaluation, you should call <em>notifySetFormula</em> or
+ <em>notifyUpdateCell</em> to trigger suitable cache clearance.
+ Alternately, you could instantiate a new FormulaEvaluator,
+ which will start with empty caches.
+ </li>
+ <li>Also note that FormulaEvaluator maintains a reference to
+ the sheet and workbook, so ensure that the evaluator instance
+ is available for garbage collection when you are done with it
+ (in other words don't maintain long lived reference to
+ FormulaEvaluator if you don't really need to - unless
+ all references to the sheet and workbook are removed, these
+ don't get garbage collected and continue to occupy potentially
+ large amounts of memory).
+ </li>
+ <li>CellValue instances however do not maintain reference to the
+ Cell or the sheet or workbook, so these can be long-lived
+ objects without any adverse effect on performance.
+ </li>
+ </ul>
+ </section>
+ <section><title>Formula Evaluation Debugging</title>
+ <p>POI is not perfect and you may stumble across formula evaluation problems (Java exceptions
+ or just different results) in your special use case. To support an easy detailed analysis, a special
+ logging of the full evaluation is provided.</p>
+ <p>The output of this logging may be very large (depends on your EXCEL), so this logging has to be explicitly enabled
+ for each single formula evaluation. Should not be used in production - only for specific development use.</p>
+ <p>Example use:</p>
+ <source>
+ // activate logging to console
+ System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.SystemOutLogger");
+ System.setProperty("poi.log.level", POILogger.INFO + "");
+
+ // open your file
+ Workbook wb = new HSSFWorkbook(new FileInputStream("foobar.xls"));
+ FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
+
+ // get your cell
+ Cell cell = wb.getSheet(0).getRow(0).getCell(0); // just a dummy example
+
+ // perform debug output for the next evaluate-call only
+ evaluator.setDebugEvaluationOutputForNextEval(true);
+ evaluator.evaluateFormulaCell(cell);
+ evaluator.evaluateFormulaCell(cell); // no logging performed for this next evaluate-call
+ </source>
+ <p>The special Logger called "POI.FormulaEval" is used (useful if you use the CommonsLogger and a detailed logging configuration).
+ The used log levels are WARN and INFO (for detailed parameter info and results) - the level are so high to allow this
+ special logging without beeing disturbed by the bunch of DEBUG log entries from other classes.</p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>HSSF and XSSF Examples</title>
+ <authors>
+ <person id="YK" name="Yegor Kozlov" email="user@poi.apache.org"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>HSSF and XSSF examples</title>
+ <p>POI 3.5 and later comes with a number of examples that demonstrate how you can use POI API to create documents from "real life".
+ The examples are based on common XSSF-HSSF interfaces so that you can generate either *.xls or *.xlsx output just by setting a command-line argument:
+ </p>
+ <source>
+ BusinessPlan -xls
+ or
+ BusinessPlan -xlsx
+ </source>
+ <p>All sample source is available in <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/">SVN</link></p>
+ </section>
+ <section><title>Business Plan</title>
+ <p> The <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java">BusinessPlan</link>
+ application creates a sample business plan with three phases, weekly iterations and time highlighting. Demonstrates advanced cell formatting
+ (number and date formats, alignmnets, fills, borders) and various settings for organizing data in a sheet (freezed panes, groupped rows).
+ </p>
+ <p>
+ <img src="../resources/images/businessplan.jpg" alt="business plan demo"/>
+ </p>
+ </section>
+ <section><title>Calendar</title>
+ <p> The <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/CalendarDemo.java">Calendar</link>
+ demo creates a multi sheet calendar. Each month is on a separate sheet.
+ </p>
+ <p>
+ <img src="../resources/images/calendar.jpg" alt="calendar demo"/>
+ </p>
+ </section>
+ <section><title>Loan Calculator</title>
+ <p> The <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/LoanCalculator.java">LoanCalculator</link>
+ demo creates a simple loan calculator. Demonstrates advance usage of cell formulas and named ranges.
+ </p>
+ <p>
+ <img src="../resources/images/loancalc.jpg" alt="loan calculator demo"/>
+ </p>
+ </section>
+ <section><title>Timesheet</title>
+ <p> The <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java">Timesheet</link>
+ demo creates a weekly timesheet with automatic calculation of total hours. Demonstrates advance usage of cell formulas.
+ </p>
+ <p>
+ <img src="../resources/images/timesheet.jpg" alt="timesheet demo"/>
+ </p>
+ </section>
+ <section><title>Conditional Formats</title>
+ <p> The <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java">ConditionalFormats</link>
+ demo is a collection of short examples showing what you can do with Excel conditional formating in POI:
+ </p>
+ <ul>
+ <li>Highlight cells based on their values</li>
+ <li>Highlight a range of cells based on a formula</li>
+ <li>Hide errors</li>
+ <li>Hide the duplicate values</li>
+ <li>Highlight duplicate entries in a column</li>
+ <li>Highlight items that are in a list on the worksheet</li>
+ <li>Highlight payments that are due in the next thirty days</li>
+ <li>Shade alternating rows on the worksheet</li>
+ <li>Shade bands of rows on the worksheet</li>
+ </ul>
+ </section>
+ <section><title>ToHtml</title>
+ <p> The <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java">ToHtml</link>
+ example shows how to display a spreadsheet in HTML using the classes for spreadsheet display.
+ </p>
+ </section>
+ <section><title>ToCSV</title>
+ <p> The <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/ToCSV.java">ToCSV</link>
+ example demonstrates <em>one</em> way to convert an Excel spreadsheet into a CSV file.
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+ ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+ ====================================================================\r
+-->\r
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">\r
+\r
+<document>\r
+ <header>\r
+ <title>ExcelAnt - Ant Tasks for Validating Excel Spreadsheets</title>\r
+ <authors>\r
+ <person email="jon@loquatic.com" name="Jon Svede" id="JDS"/>\r
+ <person email="brian.bush@nrel.gov" name="Brian Bush" id="BWB"/>\r
+ </authors>\r
+ </header>\r
+ <body>\r
+ <section><title>ExcelAnt - Ant Tasks for Validating Excel Spreadsheets</title>\r
+ \r
+ <section><title>Introduction</title>\r
+ <p>ExcelAnt is a set of Ant tasks that make it possible to verify or test\r
+ a workbook without having to write Java code. Of course, the tasks themselves\r
+ are written in Java, but to use this frame work you only need to know a little \r
+ bit about Ant.</p>\r
+ <p>This document covers the basic usage and set up of ExcelAnt.</p>\r
+ <p>This document will assume basic familiarity with Ant and Ant build files.</p>\r
+ </section>\r
+ <section><title>Setup</title>\r
+ <p>To start with, you'll need to have the POI 3.8 or higher jar files. If you test only .xls\r
+workbooks then you need to have the following jars in your path:</p>\r
+ <ul>\r
+ <li>poi-excelant-$version-YYYYDDMM.jar</li>\r
+ <li>poi-$version-YYYYDDMM.jar</li>\r
+ <li>poi-ooxml-$version-YYYYDDMM.jar</li>\r
+ </ul>\r
+ <p> If you evaluate .xlsx workbooks then you need to add these: </p>\r
+ <ul>\r
+ <li>poi-ooxml-schemas-$version-YYYYDDMM.jar</li>\r
+ <li>xmlbeans.jar</li>\r
+ <li>dom4j.jar</li>\r
+ </ul>\r
+ <p>For example, if you have these jars in a lib/ dir in your project, your build.xml \r
+ might look like this:</p>\r
+<source><![CDATA[\r
+<property name="lib.dir" value="lib" />\r
+\r
+<path id="excelant.path">\r
+ <pathelement location="${lib.dir}/poi-excelant-3.8-beta1-20101230.jar" />\r
+ <pathelement location="${lib.dir}/poi-3.8-beta1-20101230.jar" />\r
+ <pathelement location="${lib.dir}/poi-ooxml-3.8-beta1-20101230.jar" />\r
+</path> \r
+]]></source> \r
+ <p>Next, you'll need to define the Ant tasks. There are several ways to use ExcelAnt:</p>\r
+\r
+<ul><li>The traditional way:</li></ul>\r
+<source><![CDATA[\r
+ <typedef resource="org/apache/poi/ss/excelant/antlib.xml" classpathref="excelant.path" />\r
+]]></source>\r
+<p>\r
+ Where excelant.path refers to the classpath with POI jars.\r
+ Using this approach the provided extensions will live in the default namespace. Note that the default task/typenames (evaluate, test) may be too generic and should either be explicitly overridden or used with a namespace.\r
+</p>\r
+<ul><li>Similar, but assigning a namespace URI:</li></ul> \r
+<source><![CDATA[\r
+<project name="excelant-demo" xmlns:poi="antlib:org.apache.poi.ss.excelant">\r
+\r
+ <typedef resource="org/apache/poi/ss/excelant/antlib.xml"\r
+ classpathref="excelant.classpath"\r
+ uri="antlib:org.apache.poi.ss.excelant"/>\r
+\r
+ <target name="test-nofile">\r
+ <poi:excelant>\r
+\r
+ </poi:excelant>\r
+ </target>\r
+</project>\r
+]]></source>\r
+ </section>\r
+ \r
+ <section><title>A Simple Example</title>\r
+ <p>The simplest example of using Excel is the ability to validate that POI is giving you back\r
+ the value you expect it to. Does this mean that POI is inaccurate? Hardly. There are cases\r
+ where POI is unable to evaluate cells for a variety of reasons. If you need to write code\r
+ to integrate a worksheet into an app, you may want to know that it's going to work before \r
+ you actually try to write that code. ExcelAnt helps with that.</p>\r
+ \r
+ <p>Consider the mortgage-calculation.xls file found in the Examples \r
+ (/examples/src/org/apache/poi/ss/examples/excelant/simple-mortgage-calculation.xls). This sheet\r
+ is shown below:</p>\r
+ \r
+ <!--img src="../resources/images/simple-xls-with-function.jpg" alt="mortgage calculation spreadsheet"/-->\r
+ \r
+ <p>This sheet calculates the principal and interest payment for a mortgage based\r
+ on the amount of the loan, term and rate. To write a simple ExcelAnt test you \r
+ need to tell ExcelAnt about the file like this:</p>\r
+<source><![CDATA[\r
+<property name="xls.file" value="" />\r
+ \r
+<target name="simpleTest">\r
+ <excelant fileName="${xls.file}">\r
+ <test name="checkValue" showFailureDetail="true">\r
+ <evaluate showDelta="true" cell="'MortgageCalculator'!$B$4" expectedValue="790.7936" precision="1.0e-4" />\r
+ </test>\r
+ </excelant>\r
+</target> \r
+]]></source>\r
+\r
+ \r
+ <p>This code sets up ExcelAnt to access the file defined in the ant property\r
+ xls.file. Then it creates a 'test' named 'checkValue'. Finally it tries\r
+ to evaluate the B4 on the sheet named 'MortgageCalculator'. There are some assumptions\r
+ here that are worth explaining. For starters, ExcelAnt is focused on the testing\r
+ numerically oriented sheets. The <evaluate> task is actually evaluating the\r
+ cell as a formula using a FormulaEvaluator instance from POI. Therefore it will fail\r
+ if you point it to a cell that doesn't contain a formula or a test a plain old number.</p>\r
+ \r
+ <p>Having said all that, here is what the output looks like:</p>\r
+ \r
+<source><![CDATA[\r
+simpleTest:\r
+ [excelant] ExcelAnt version 0.4.0 Copyright 2011\r
+ [excelant] Using input file: resources/excelant.xls\r
+ [excelant] 1/1 tests passed.\r
+BUILD SUCCESSFUL\r
+Total time: 391 milliseconds \r
+]]></source>\r
+\r
+ </section>\r
+ \r
+ <section><title>Setting Values into a Cell</title>\r
+ <p>So now we know that at a minimum POI can use our sheet to calculate the existing value.\r
+ This is an important point: in many cases sheets have dependencies, i.e., cells they reference.\r
+ As is often the case, these cells may have dependencies, which may have dependencies, etc.\r
+ The point is that sometimes a dependent cell may get adjusted by a macro or a function\r
+ and it may be that POI doesn't have the capabilities to do the same thing. This test\r
+ verifies that we can rely on POI to retrieve the default value, based on the stored values\r
+ of the sheet. Now we want to know if we can manipulate those dependencies and verify\r
+ the output.</p>\r
+ \r
+ <p>To verify that we can manipulate cell values, we need a way in ExcelAnt to set a value.\r
+ This is provided by the following task types:</p>\r
+ <ul>\r
+ <li>setDouble() - sets the specified cell as a double.</li>\r
+ <li>setFormula() - sets the specified cell as a formula.</li>\r
+ <li>setString() = sets the specified cell as a String.</li>\r
+ </ul>\r
+ \r
+ <p>For the purposes of this example we'll use the <setDouble> task. Let's\r
+ start with a $240,000, 30 year loan at 11% (let's pretend it's like 1984). Here\r
+ is how we will set that up:</p>\r
+ \r
+<source><![CDATA[\r
+<setDouble cell="'MortgageCalculator'!$B$1" value="240000"/>\r
+<setDouble cell="'MortgageCalculator'!$B$2" value ="0.11"/>\r
+<setDouble cell="'MortgageCalculator'!$B$3" value ="30"/>\r
+<evaluate showDelta="true" cell="'MortgageCalculator'!$B$4" expectedValue="2285.576149" precision="1.0e-4" /> \r
+]]></source>\r
+\r
+ <p>Don't forget that we're verifying the behavior so you need to put all this\r
+ into the sheet. That is how I got the result of $2,285 and change. So save your\r
+ changes and run it; you should get the following: </p>\r
+ \r
+<source><![CDATA[ \r
+Buildfile: C:\opt\eclipse\workspaces\excelant\excelant.examples\build.xml\r
+simpleTest:\r
+ [excelant] ExcelAnt version 0.4.0 Copyright 2011\r
+ [excelant] Using input file: resources/excelant.xls\r
+ [excelant] 1/1 tests passed.\r
+BUILD SUCCESSFUL\r
+Total time: 406 milliseconds \r
+]]></source>\r
+\r
+</section>\r
+ \r
+ <section><title>Getting More Details</title>\r
+\r
+ <p>This is great, it's working! However, suppose you want to see a little more detail. The\r
+ ExcelAnt tasks leverage the Ant logging so you can add the -verbose and -debug flags to\r
+ the Ant command line to get more detail. Try adding -verbose. Here is what \r
+ you should see:</p>\r
+ \r
+<source><![CDATA[\r
+simpleTest:\r
+ [excelant] ExcelAnt version 0.4.0 Copyright 2011\r
+ [excelant] Using input file: resources/excelant.xls\r
+ [evaluate] test precision = 1.0E-4 global precision = 0.0\r
+ [evaluate] Using evaluate precision of 1.0E-4\r
+ [excelant] 1/1 tests passed.\r
+BUILD SUCCESSFUL\r
+Total time: 406 milliseconds \r
+]]></source>\r
+\r
+ \r
+ <p>We see a little more detail. Notice that we see that there is a setting for global precision.\r
+ Up until now we've been setting the precision on each evaluate that we call. This \r
+ is obviously useful but it gets cumbersome. It would be better if there were a way\r
+ that we could specify a global precision - and there is. There is a <precision> \r
+ tag that you can specify as a child of the <excelant> tag. Let's go back to \r
+ our original task we set up earlier and modify it:</p>\r
+ \r
+<source><![CDATA[\r
+<property name="xls.file" value="" />\r
+ \r
+<target name="simpleTest">\r
+ <excelant fileName="${xls.file}">\r
+ <precision value="1.0e-3"/>\r
+ <test name="checkValue" showFailureDetail="true">\r
+ <evaluate showDelta="true" cell="'MortgageCalculator'!$B$4" expectedValue="790.7936" />\r
+ </test>\r
+ </excelant>\r
+</target> \r
+]]></source>\r
+ \r
+ <p>In this example we have set the global precision to 1.0e-3. This means that\r
+ in the absence of something more stringent, all tests in the task will use\r
+ the global precision. We can still override this by specifying the\r
+ precision attribute of all of our <evaluate> task. Let's first run\r
+ this task with the global precision and the -verbose flag:</p>\r
+ \r
+<source><![CDATA[ \r
+simpleTest:\r
+[excelant] ExcelAnt version 0.4.0 Copyright 2011\r
+[excelant] Using input file: resources/excelant.xls\r
+[excelant] setting precision for the test checkValue\r
+ [test] setting globalPrecision to 0.0010 in the evaluator\r
+[evaluate] test precision = 0.0 global precision = 0.0010\r
+[evaluate] Using global precision of 0.0010\r
+[excelant] 1/1 tests passed.\r
+]]></source>\r
+\r
+ \r
+ <p>As the output clearly shows, the test itself has no precision but there is\r
+ the global precision. Additionally, it tells us we're going to use that\r
+ more stringent global value. Now suppose that for this test we want \r
+ to use a more stringent precision, say 1.0e-4. We can do that by adding\r
+ the precision attribute back to the <evaluate> task:</p>\r
+\r
+<source><![CDATA[\r
+<excelant fileName="${xls.file}">\r
+ <precision value="1.0e-3"/>\r
+ <test name="checkValue" showFailureDetail="true">\r
+ <setDouble cell="'MortgageCalculator'!$B$1" value="240000"/>\r
+ <setDouble cell="'MortgageCalculator'!$B$2" value ="0.11"/>\r
+ <setDouble cell="'MortgageCalculator'!$B$3" value ="30"/>\r
+ <evaluate showDelta="true" cell="'MortgageCalculator'!$B$4" expectedValue="2285.576149" precision="1.0e-4" />\r
+ </test>\r
+</excelant>\r
+]]></source>\r
+\r
+\r
+ <p>Now when you re-run this test with the verbose flag you will see that\r
+ your test ran and passed with the higher precision:</p>\r
+<source><![CDATA[\r
+simpleTest:\r
+ [excelant] ExcelAnt version 0.4.0 Copyright 2011\r
+ [excelant] Using input file: resources/excelant.xls\r
+ [excelant] setting precision for the test checkValue\r
+ [test] setting globalPrecision to 0.0010 in the evaluator\r
+ [evaluate] test precision = 1.0E-4 global precision = 0.0010\r
+ [evaluate] Using evaluate precision of 1.0E-4 over the global precision of 0.0010\r
+ [excelant] 1/1 tests passed.\r
+BUILD SUCCESSFUL\r
+Total time: 390 milliseconds \r
+]]></source>\r
+ </section>\r
+ \r
+ <section><title>Leveraging User Defined Functions</title>\r
+ <p>POI has an excellent feature (besides ExcelAnt) called <link href="user-defined-functions.html">User Defined Functions</link>,\r
+ that allows you to write Java code that will be used in place of custom VB\r
+ code or macros is a spreadsheet. If you have read the documentation and written\r
+ your own FreeRefFunction implmentations, ExcelAnt can make use of this code.\r
+ For each <excelant> task you define you can nest a <udf> tag \r
+ which allows you to specify the function alias and the class name.</p>\r
+ \r
+ <p>Consider the previous example of the mortgage calculator. What if, instead\r
+ of being a formula in a cell, it was a function defined in a VB macro? As luck\r
+ would have it, we already have an example of this in the examples from the \r
+ User Defined Functions example, so let's use that. In the example spreadsheet\r
+ there is a tab for MortgageCalculatorFunction, which will use. If you look in\r
+ cell B4, you see that rather than a messy cell based formula, there is only the function\r
+ call. Let's not get bogged down in the function/Java implementation, as these\r
+ are covered in the User Defined Function documentation. Let's just add\r
+ a new target and test to our existing build file:</p> \r
+<source><![CDATA[\r
+ <target name="functionTest">\r
+ <excelant fileName="${xls.file}">\r
+ <udf functionAlias="calculatePayment" class="org.apache.poi.ss.examples.formula.CalculateMortgage"/>\r
+ <precision value="1.0e-3"/>\r
+ <test name="checkValue" showFailureDetail="true">\r
+ <setDouble cell="'MortgageCalculator'!$B$1" value="240000"/>\r
+ <setDouble cell="'MortgageCalculator'!$B$2" value ="0.11"/>\r
+ <setDouble cell="'MortgageCalculator'!$B$3" value ="30"/>\r
+ <evaluate showDelta="true" cell="'MortgageCalculatorFunction'!$B$4" expectedValue="2285.576149" precision="1.0e-4" />\r
+ </test>\r
+ </excelant>\r
+ </target>\r
+]]></source> \r
+\r
+ <p>So if you look at this carefully it looks the same as the previous examples. We\r
+ still use the global precision, we're still setting values, and we still want\r
+ to evaluate a cell. The only real differences are the sheet name and the\r
+ addition of the function.</p> \r
+ </section>\r
+ </section>\r
+</body>\r
+</document> \r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!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</title>
+ <p>
+ This document describes the current state of formula support in POI.
+ The information in this document currently applies to the 3.5 version of POI.
+ 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</title>
+ <p>
+ In org.apache.poi.hssf.usermodel.HSSFCell
+ <strong> setCellFormula("formulaString") </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 grammar for formulas. Thus, the string that you pass in
+ to the <em> setCellFormula </em> 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</title>
+ <ul>
+ <li>References: single cell & area, 2D & 3D, relative & absolute</li>
+ <li>Literals: Number, text, boolean, error and array</li>
+ <li>Operators: arithmetic and logical, some region operators</li>
+ <li>Built-in functions: over 350 recognised, 280 evaluatable</li>
+ <li>Add-in functions: 3 from Analysis Toolpack</li>
+ </ul>
+ </section>
+ <section><title>Not yet supported</title>
+ <ul>
+ <li>Manipulating array/table formulas (In Excel, formulas that look like "{=...}" as opposed to "=...")</li>
+ <li>Region operators: union, intersection</li>
+ <li>Parsing of previously uncalled add-in functions</li>
+ <li>Preservation of whitespace in formulas (when POI manipulates them)</li>
+ </ul>
+ </section>
+
+ <section><title>Internals</title>
+ <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.ss.formula.FormulaParser</strong> class. This class implements a hand
+ written recursive descent parser.
+ </p>
+ <p>
+ Formula tokens in Excel are stored in one of three possible <em> operand 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
+ occurrence 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.)
+ </p>
+ <p>Check out the <link href="http://poi.apache.org/apidocs/">javadocs </link> for details.
+ </p>
+ </section>
+
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Hacking HSSF</title>
+ <authors>
+ <person email="user@poi.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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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?</title>
+ <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?</title>
+ <p>Make sure you <link href="../guidelines.html">read the contributing section</link>
+ as it contains more generation information about contributing to POI in general.</p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!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="user@poi.apache.org" name="Glen Stampoultzis" id="GJS"/>
+ <person email="nick@apache.org" name="Nick Burch" id="NB"/>
+ <person email="sergeikozello@mail.ru" name="Sergei Kozello" id="SK"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>How to use the HSSF API</title>
+
+ <section><title>Capabilities</title>
+ <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 formuala 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>
+ </section>
+ <section><title>Different APIs</title>
+ <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><link href="#user_api">User API (HSSF and XSSF)</link></li>
+ <li><link href="#event_api">Event API (HSSF Only)</link></li>
+ <li><link href="#record_aware_event_api">Event API with extensions to be Record Aware (HSSF Only)</link></li>
+ <li><link href="#xssf_sax_api">XSSF and SAX (Event API)</link></li>
+ <li><link href="#sxssf">SXSSF (Streaming User API)</link></li>
+ <li><link href="#low_level_api">Low Level API</link></li>
+ </ul>
+ </section>
+ </section>
+ <section><title>General Use</title>
+ <anchor id="user_api" />
+ <section><title>User API (HSSF and XSSF)</title>
+ <section><title>Writing a new file</title>
+
+ <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>
+<source><![CDATA[
+short rownum;
+
+// create a new file
+FileOutputStream out = new FileOutputStream("workbook.xls");
+// create a new workbook
+Workbook wb = new HSSFWorkbook();
+// create a new sheet
+Sheet s = wb.createSheet();
+// declare a row object reference
+Row r = null;
+// declare a cell object reference
+Cell c = null;
+// create 3 cell styles
+CellStyle cs = wb.createCellStyle();
+CellStyle cs2 = wb.createCellStyle();
+CellStyle cs3 = wb.createCellStyle();
+DataFormat df = wb.createDataFormat();
+// create 2 fonts objects
+Font f = wb.createFont();
+Font 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(Font.BOLDWEIGHT_BOLD);
+
+//set font 2 to 10 point type
+f2.setFontHeightInPoints((short) 10);
+//make it red
+f2.setColor( (short)Font.COLOR_RED );
+//make it bold
+f2.setBoldweight(Font.BOLDWEIGHT_BOLD);
+
+f2.setStrikeout( true );
+
+//set cell stlye
+cs.setFont(f);
+//set the cell format
+cs.setDataFormat(df.getFormat("#,##0.0"));
+
+//set a thin border
+cs2.setBorderBottom(cs2.BORDER_THIN);
+//fill w fg fill color
+cs2.setFillPattern((short) CellStyle.SOLID_FOREGROUND);
+//set the cell format to text see DataFormat for a full list
+cs2.setDataFormat(HSSFDataFormat.getBuiltinFormat("text"));
+
+// 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" );
+// in case of plain ascii
+// wb.setSheetName(0, "HSSF Test");
+// create a sheet with 30 rows (0-29)
+int rownum;
+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.setCellValue( "Test" );
+ }
+ else
+ {
+ c.setCellStyle(cs2);
+ // set the cell's string value to "\u0422\u0435\u0441\u0442"
+ 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</title>
+
+<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://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java">org.apache.poi.hssf.usermodel.examples.HSSFReadWrite</link>.</p>
+ </section>
+ </section>
+
+ <anchor id="event_api" />
+ <section><title>Event API (HSSF Only)</title>
+
+ <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
+ <link href="#record_aware_event_api">Record Aware</link> 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>
+<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>
+
+ <anchor id="record_aware_event_api" />
+ <section><title>Record Aware Event API (HSSF Only)</title>
+<p>
+This is an extension to the normal
+<link href="#event_api">Event API</link>. 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
+<code>/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java</code>,
+and may be called on the command line, or from within your own code.
+The latest version is always available from
+<link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/">subversion</link>.
+</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>
+ <link href="../subversion.html">subversion checkout</link>.
+</p>
+ </section>
+
+ <anchor id="xssf_sax_api"/>
+ <section><title>XSSF and SAX (Event API)</title>
+
+ <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 interace 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 svn
+ src/examples/src/org/apache/poi/xssf/eventusermodel/exmaples/FromHowTo.java</p>
+<source><![CDATA[
+import java.io.InputStream;
+import java.util.Iterator;
+
+import org.apache.poi.xssf.eventusermodel.XSSFReader;
+import org.apache.poi.xssf.model.SharedStringsTable;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+public class ExampleEventUserModel {
+ public void processOneSheet(String filename) throws Exception {
+ OPCPackage pkg = OPCPackage.open(filename);
+ XSSFReader r = new XSSFReader( pkg );
+ SharedStringsTable sst = r.getSharedStringsTable();
+
+ XMLReader parser = fetchSheetParser(sst);
+
+ // rId2 found by processing the Workbook
+ // Seems to either be rId# or rSheet#
+ InputStream sheet2 = r.getSheet("rId2");
+ InputSource sheetSource = new InputSource(sheet2);
+ parser.parse(sheetSource);
+ sheet2.close();
+ }
+
+ public void processAllSheets(String filename) throws Exception {
+ OPCPackage pkg = OPCPackage.open(filename);
+ XSSFReader r = new XSSFReader( pkg );
+ SharedStringsTable sst = r.getSharedStringsTable();
+
+ XMLReader parser = fetchSheetParser(sst);
+
+ Iterator<InputStream> sheets = r.getSheetsData();
+ while(sheets.hasNext()) {
+ System.out.println("Processing new sheet:\n");
+ InputStream sheet = sheets.next();
+ InputSource sheetSource = new InputSource(sheet);
+ parser.parse(sheetSource);
+ sheet.close();
+ System.out.println("");
+ }
+ }
+
+ public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
+ XMLReader parser =
+ XMLReaderFactory.createXMLReader(
+ "org.apache.xerces.parsers.SAXParser"
+ );
+ ContentHandler handler = new SheetHandler(sst);
+ parser.setContentHandler(handler);
+ return parser;
+ }
+
+ /**
+ * See org.xml.sax.helpers.DefaultHandler javadocs
+ */
+ private static class SheetHandler extends DefaultHandler {
+ private SharedStringsTable sst;
+ private String lastContents;
+ private boolean nextIsString;
+
+ private SheetHandler(SharedStringsTable sst) {
+ this.sst = sst;
+ }
+
+ public void startElement(String uri, String localName, String name,
+ Attributes attributes) throws SAXException {
+ // c => cell
+ if(name.equals("c")) {
+ // Print the cell reference
+ System.out.print(attributes.getValue("r") + " - ");
+ // Figure out if the value is an index in the SST
+ String cellType = attributes.getValue("t");
+ if(cellType != null && cellType.equals("s")) {
+ nextIsString = true;
+ } else {
+ nextIsString = false;
+ }
+ }
+ // Clear contents cache
+ lastContents = "";
+ }
+
+ public void endElement(String uri, String localName, String name)
+ throws SAXException {
+ // Process the last contents as required.
+ // Do now, as characters() may be called more than once
+ if(nextIsString) {
+ int idx = Integer.parseInt(lastContents);
+ lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
+ nextIsString = false;
+ }
+
+ // v => contents of a cell
+ // Output after we've seen the string contents
+ if(name.equals("v")) {
+ System.out.println(lastContents);
+ }
+ }
+
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ lastContents += new String(ch, start, length);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ FromHowTo howto = new FromHowTo();
+ howto.processOneSheet(args[0]);
+ howto.processAllSheets(args[0]);
+ }
+}
+]]></source>
+ </section>
+ <anchor id="sxssf"/>
+ <section><title>SXSSF (Streaming Usermodel API)</title>
+ <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> 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>
+
+
+<source><![CDATA[
+
+import junit.framework.Assert;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+ public static void main(String[] args) throws Throwable {
+ SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk
+ Sheet sh = wb.createSheet();
+ for(int rownum = 0; rownum < 1000; rownum++){
+ Row row = sh.createRow(rownum);
+ for(int cellnum = 0; cellnum < 10; cellnum++){
+ Cell cell = row.createCell(cellnum);
+ String address = new CellReference(cell).formatAsString();
+ cell.setCellValue(address);
+ }
+
+ }
+
+ // Rows with rownum < 900 are flushed and not accessible
+ for(int rownum = 0; rownum < 900; rownum++){
+ Assert.assertNull(sh.getRow(rownum));
+ }
+
+ // ther last 100 rows are still in memory
+ for(int rownum = 900; rownum < 1000; rownum++){
+ Assert.assertNotNull(sh.getRow(rownum));
+ }
+
+ FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");
+ wb.write(out);
+ out.close();
+
+ // dispose of temporary files backing this workbook on disk
+ wb.dispose();
+ }
+
+
+]]></source>
+<p>The next example turns off auto-flushing (windowSize=-1) and the code manually controls how portions of data are written to disk</p>
+<source><![CDATA[
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+ public static void main(String[] args) throws Throwable {
+ SXSSFWorkbook wb = new SXSSFWorkbook(-1); // turn off auto-flushing and accumulate all rows in memory
+ Sheet sh = wb.createSheet();
+ for(int rownum = 0; rownum < 1000; rownum++){
+ Row row = sh.createRow(rownum);
+ for(int cellnum = 0; cellnum < 10; cellnum++){
+ Cell cell = row.createCell(cellnum);
+ String address = new CellReference(cell).formatAsString();
+ cell.setCellValue(address);
+ }
+
+ // manually control how rows are flushed to disk
+ if(rownum % 100 == 0) {
+ ((SXSSFSheet)sh).flushRows(100); // retain 100 last rows and flush all others
+
+ // ((SXSSFSheet)sh).flushRows() is a shortcut for ((SXSSFSheet)sh).flushRows(0),
+ // this method flushes all rows
+ }
+
+ }
+
+ FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");
+ wb.write(out);
+ out.close();
+
+ // dispose of temporary files backing this workbook on disk
+ wb.dispose();
+ }
+
+
+]]></source>
+<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>
+<source><![CDATA[
+ SXSSFWorkbook wb = new SXSSFWorkbook();
+ wb.setCompressTempFiles(true); // temp files will be gzipped
+
+]]></source>
+ </section>
+
+ <anchor id="low_level_api" />
+ <section><title>Low Level APIs</title>
+
+<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>
+ </section>
+ <section><title>Generating XLS from XML</title>
+<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 <link href="http://cocoon.apache.org/">Cocoon</link>.
+In Cocoon, there is the <link href="http://cocoon.apache.org/2.1/userdocs/xls-serializer.html">HSSF Serializer</link>,
+which takes in XML (in the gnumeric format), and outputs an XLS file for you.</p>
+ </section>
+ <section><title>HSSF Class/Test Application</title>
+
+<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>"myxls.xls"</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</title>
+ <p>POI can dynamically select its logging implementation. POI tries 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</title>
+
+<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>
+
+ </section>
+ <section><title>What's Next?</title>
+
+<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><link href="../guidelines.html"> So jump in! </link> </p>
+
+ </section>
+
+</section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI-HSSF and POI-XSSF - Java API To Access Microsoft Excel Format Files</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</title>
+
+ <p>HSSF is the POI Project's pure Java implementation of the
+ Excel '97(-2007) file format. XSSF is the POI Project's pure
+ Java implementation of the Excel 2007 OOXML (.xlsx) file
+ format.</p>
+ <p>HSSF and XSSF provides ways to read spreadsheets create,
+ modify, read and write XLS spreadsheets. They provide:
+ </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>For people converting from pure HSSF usermodel, who wish
+ to use the joint SS Usermodel for HSSF and XSSF support, then
+ see the <link href="converting.html">ss usermodel converting
+ guide</link>.
+ </p>
+ <p>
+ An alternate way of generating a spreadsheet is via the <link href="http://cocoon.apache.org">Cocoon</link> serializer (yet you'll still be using HSSF indirectly).
+ With Cocoon you can serialize any XML datasource (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 either the org.apache.poi.hssf.eventusermodel
+ package, or the org.apache.poi.xssf.eventusermodel package, depending
+ on your file format.
+ </p>
+ <p>
+ If you're modifying spreadsheet data then use the usermodel api. You
+ can also generate spreadsheets this way.
+ </p>
+ <p>
+ Note that the usermodel system has a higher memory footprint than
+ the low level eventusermodel, but have the major advantage of being
+ much simpler to work with. Also please be aware that as the new
+ XSSF supported Excel 2007 OOXML (.xlsx) files are XML based,
+ the memory footprint for processing them is higher than for the
+ older HSSF supported (.xls) binary files.
+ </p>
+
+
+
+ </section>
+
+<section>
+<title>SXSSF (Since POI 3.8 beta3)</title>
+<p>Since 3.8-beta3, POI provides a low-memory footprint SXSSF API built on top of XSSF.</p>
+<p>
+SXSSF 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>
+In auto-flush mode the size of the access window can be specified, to hold a certain number of rows in memory.
+When that value is reached, the creation of an additional row causes the row with the lowest index to to be
+removed from the access window and written to disk. Or, the window size can be set to grow dynamically;
+it can be trimmed periodically by an explicit call to flushRows(int keepRows) as needed.
+</p>
+<p>
+Due to the streaming nature of the implementation, there are the following
+limitations when compared to XSSF:
+</p>
+ <ul>
+ <li>Only a limited number of rows are accessible at a point in time.</li>
+ <li>Sheet.clone() is not supported.</li>
+ <li>Formula evaluation is not supported</li>
+ </ul>
+
+ <p> See more details at <link href="how-to.html#sxssf">SXSSF How-To</link></p>
+
+<p>The table below synopsizes the comparative features of POI's Spreadsheet API:</p>
+ <p><em>Spreadsheet API Feature Summary</em></p>
+
+ <p>
+ <img src="../resources/images/ss-features.png" alt="Spreadsheet API Feature Summary"/>
+ </p>
+</section>
+
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Limitations</title>
+ <authors>
+ <person email="user@poi.apache.org" name="Glen Stampoultzis" id="GJS"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Version 3.7 limitations</title>
+ <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. 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>
+ Macros<br/><br/>
+ Macros can not be created. However, reading and re-writing files containing macros will
+ safely preserve the macros.<br/><br/>
+ </li>
+ <li>
+ Pivot Tables<br/><br/>
+ Generating pivot tables is not supported. It has been reported that files containing pivot
+ tables can be read and re-written safely.
+ </li>
+ </ul>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Busy Developers' Guide to HSSF and XSSF Features</title>
+ </header>
+ <body>
+ <section><title>Busy Developers' Guide to Features</title>
+ <p>
+ Want to use HSSF and XSSF read and write spreadsheets in a hurry? This
+ guide is for you. If you're after more in-depth coverage of the HSSF and
+ XSSF user-APIs, 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</title>
+ <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="#Iterator">Iterate over rows and cells</link></li>
+ <li><link href="#CellContents">Getting the cell contents</link></li>
+ <li><link href="#TextExtraction">Text Extraction</link></li>
+ <li><link href="#FileInputStream">Files vs InputStreams</link></li>
+ <li><link href="#Alignment">Aligning cells</link></li>
+ <li><link href="#Borders">Working with borders</link></li>
+ <li><link href="#FillsAndFrills">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="#CustomColors">Custom colors</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="#FitTo">Fit Sheet to One Page</link></li>
+ <li><link href="#PrintArea2">Set print area for a sheet</link></li>
+ <li><link href="#FooterPageNumbers">Set page numbers on the footer of a sheet</link></li>
+ <li><link href="#ShiftRows">Shift rows</link></li>
+ <li><link href="#SelectSheet">Set a sheet as selected</link></li>
+ <li><link href="#Zoom">Set the zoom magnification for a sheet</link></li>
+ <li><link href="#Splits">Create split and freeze panes</link></li>
+ <li><link href="#Repeating">Repeating rows and columns</link></li>
+ <li><link href="#HeaderFooter">Headers and Footers</link></li>
+ <li><link href="#DrawingShapes">Drawing Shapes</link></li>
+ <li><link href="#StylingShapes">Styling Shapes</link></li>
+ <li><link href="#Graphics2d">Shapes and Graphics2d</link></li>
+ <li><link href="#Outlining">Outlining</link></li>
+ <li><link href="#Images">Images</link></li>
+ <li><link href="#NamedRanges">Named Ranges and Named Cells</link></li>
+ <li><link href="#CellComments">How to set cell comments</link></li>
+ <li><link href="#Autofit">How to adjust column width to fit the contents</link></li>
+ <li><link href="#Hyperlinks">Hyperlinks</link></li>
+ <li><link href="#Validation">Data Validations</link></li>
+ <li><link href="#Embedded">Embedded Objects</link></li>
+ <li><link href="#Autofilter">Autofilters</link></li>
+ <li><link href="#ConditionalFormatting">Conditional Formatting</link></li>
+ <li><link href="#Hiding">Hiding and Un-Hiding Rows</link></li>
+ </ul>
+ </section>
+ <section><title>Features</title>
+ <anchor id="NewWorkbook"/>
+ <section><title>New Workbook</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+
+ Workbook wb = new XSSFWorkbook();
+ FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+ <anchor id="NewSheet"/>
+ <section><title>New Sheet</title>
+ <source>
+ Workbook wb = new HSSFWorkbook(); // or new XSSFWorkbook();
+ Sheet sheet1 = wb.createSheet("new sheet");
+ Sheet sheet2 = wb.createSheet("second sheet");
+
+ // Note that sheet name is Excel must not exceed 31 characters
+ // and must not contain any of the any of the following characters:
+ // 0x0000
+ // 0x0003
+ // colon (:)
+ // backslash (\)
+ // asterisk (*)
+ // question mark (?)
+ // forward slash (/)
+ // opening square bracket ([)
+ // closing square bracket (])
+
+ // You can use org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)}
+ // for a safe way to create valid names, this utility replaces invalid characters with a space (' ')
+ String safeName = WorkbookUtil.createSafeSheetName("[O'Brien's sales*?]"); // returns " O'Brien's sales "
+ Sheet sheet3 = wb.createSheet(safeName);
+
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+ <anchor id="CreateCells"/>
+ <section><title>Creating Cells</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ //Workbook wb = new XSSFWorkbook();
+ CreationHelper createHelper = wb.getCreationHelper();
+ Sheet sheet = wb.createSheet("new sheet");
+
+ // Create a row and put some cells in it. Rows are 0 based.
+ Row row = sheet.createRow((short)0);
+ // Create a cell and put a value in it.
+ Cell cell = row.createCell(0);
+ cell.setCellValue(1);
+
+ // Or do it on one line.
+ row.createCell(1).setCellValue(1.2);
+ row.createCell(2).setCellValue(
+ createHelper.createRichTextString("This is a string"));
+ row.createCell(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</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ //Workbook wb = new XSSFWorkbook();
+ CreationHelper createHelper = wb.getCreationHelper();
+ Sheet sheet = wb.createSheet("new sheet");
+
+ // Create a row and put some cells in it. Rows are 0 based.
+ Row row = sheet.createRow(0);
+
+ // Create a cell and put a date value in it. The first cell is not styled
+ // as a date.
+ Cell cell = row.createCell(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.
+ CellStyle cellStyle = wb.createCellStyle();
+ cellStyle.setDataFormat(
+ createHelper.createDataFormat().getFormat("m/d/yy h:mm"));
+ cell = row.createCell(1);
+ cell.setCellValue(new Date());
+ cell.setCellStyle(cellStyle);
+
+ //you can also set date as java.util.Calendar
+ cell = row.createCell(2);
+ cell.setCellValue(Calendar.getInstance());
+ 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</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("new sheet");
+ Row row = sheet.createRow((short)2);
+ row.createCell(0).setCellValue(1.1);
+ row.createCell(1).setCellValue(new Date());
+ row.createCell(2).setCellValue(Calendar.getInstance());
+ row.createCell(3).setCellValue("a string");
+ row.createCell(4).setCellValue(true);
+ row.createCell(5).setCellType(Cell.CELL_TYPE_ERROR);
+
+ // Write the output to a file
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+
+ <anchor id="FileInputStream"/>
+ <section><title>Files vs InputStreams</title>
+ <p>When opening a workbook, either a .xls HSSFWorkbook, or a .xlsx
+ XSSFWorkbook, the Workbook can be loaded from either a <em>File</em>
+ or an <em>InputStream</em>. Using a <em>File</em> object allows for
+ lower memory consumption, while an <em>InputStream</em> requires more
+ memory as it has to buffer the whole file.</p>
+ <p>If using <em>WorkbookFactory</em>, it's very easy to use one or
+ the other:</p>
+ <source>
+ // Use a file
+ Workbook wb = WorkbookFactory.create(new File("MyExcel.xls"));
+
+ // Use an InputStream, needs more memory
+ Workbook wb = WorkbookFactory.create(new FileInputStream("MyExcel.xlsx"));
+ </source>
+ <p>If using <em>HSSFWorkbook</em> or <em>XSSFWorkbook</em> directly,
+ you should generally go through <em>NPOIFSFileSystem</em> or
+ <em>OPCPackage</em>, to have full control of the lifecycle (including
+ closing the file when done):</p>
+ <source>
+ // HSSFWorkbook, File
+ NPOIFSFileSytem fs = new NPOIFSFileSystem(new File("file.xls"));
+ HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot());
+ ....
+ fs.close();
+
+ // HSSFWorkbook, InputStream, needs more memory
+ NPOIFSFileSytem fs = new NPOIFSFileSystem(myInputStream);
+ HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot());
+
+ // XSSFWorkbook, File
+ OPCPackage pkg = OPCPackage.open(new File("file.xlsx"));
+ XSSFWorkbook wb = new XSSFWorkbook(pkg);
+ ....
+ pkg.close();
+
+ // XSSFWorkbook, InputStream, needs more memory
+ OPCPackage pkg = OPCPackage.open(myInputStream);
+ XSSFWorkbook wb = new XSSFWorkbook(pkg);
+ ....
+ pkg.close();
+ </source>
+ </section>
+
+ <anchor id="Alignment"/>
+ <section><title>Demonstrates various alignment options</title>
+ <source>
+ public static void main(String[] args) throws Exception {
+ Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
+
+ Sheet sheet = wb.createSheet();
+ Row row = sheet.createRow((short) 2);
+ row.setHeightInPoints(30);
+
+ createCell(wb, row, (short) 0, CellStyle.ALIGN_CENTER, CellStyle.VERTICAL_BOTTOM);
+ createCell(wb, row, (short) 1, CellStyle.ALIGN_CENTER_SELECTION, CellStyle.VERTICAL_BOTTOM);
+ createCell(wb, row, (short) 2, CellStyle.ALIGN_FILL, CellStyle.VERTICAL_CENTER);
+ createCell(wb, row, (short) 3, CellStyle.ALIGN_GENERAL, CellStyle.VERTICAL_CENTER);
+ createCell(wb, row, (short) 4, CellStyle.ALIGN_JUSTIFY, CellStyle.VERTICAL_JUSTIFY);
+ createCell(wb, row, (short) 5, CellStyle.ALIGN_LEFT, CellStyle.VERTICAL_TOP);
+ createCell(wb, row, (short) 6, CellStyle.ALIGN_RIGHT, CellStyle.VERTICAL_TOP);
+
+ // Write the output to a file
+ FileOutputStream fileOut = new FileOutputStream("xssf-align.xlsx");
+ 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 halign the horizontal alignment for the cell.
+ */
+ private static void createCell(Workbook wb, Row row, short column, short halign, short valign) {
+ Cell cell = row.createCell(column);
+ cell.setCellValue("Align It");
+ CellStyle cellStyle = wb.createCellStyle();
+ cellStyle.setAlignment(halign);
+ cellStyle.setVerticalAlignment(valign);
+ cell.setCellStyle(cellStyle);
+ }
+ </source>
+ </section>
+ <anchor id="Borders"/>
+ <section><title>Working with borders</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("new sheet");
+
+ // Create a row and put some cells in it. Rows are 0 based.
+ Row row = sheet.createRow(1);
+
+ // Create a cell and put a value in it.
+ Cell cell = row.createCell(1);
+ cell.setCellValue(4);
+
+ // Style the cell with borders all around.
+ CellStyle style = wb.createCellStyle();
+ style.setBorderBottom(CellStyle.BORDER_THIN);
+ style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+ style.setBorderLeft(CellStyle.BORDER_THIN);
+ style.setLeftBorderColor(IndexedColors.GREEN.getIndex());
+ style.setBorderRight(CellStyle.BORDER_THIN);
+ style.setRightBorderColor(IndexedColors.BLUE.getIndex());
+ style.setBorderTop(CellStyle.BORDER_MEDIUM_DASHED);
+ style.setTopBorderColor(IndexedColors.BLACK.getIndex());
+ cell.setCellStyle(style);
+
+ // Write the output to a file
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+ <anchor id="Iterator"/>
+ <section><title>Iterate over rows and cells</title>
+ <p>Sometimes, you'd like to just iterate over all the rows in
+ a sheet, or all the cells in a row. This is possible with
+ a simple for loop.</p>
+ <p>Luckily, this is very easy. Row defines a
+ <em>CellIterator</em> inner class to handle iterating over
+ the cells (get one with a call to <em>row.cellIterator()</em>),
+ and Sheet provides a <em>rowIterator()</em> method to
+ give an iterator over all the rows. These implement the
+ <em>java.lang.Iterable</em> interface to allow foreach loops.</p>
+
+ <source>
+ Sheet sheet = wb.getSheetAt(0);
+ for (Row row : sheet) {
+ for (Cell cell : row) {
+ // Do something here
+ }
+ }
+ </source>
+ </section>
+ <section><title>Iterate over cells, with control of missing / blank cells</title>
+ <p>In some cases, when iterating, you need full control over how
+ missing or blank cells are treated, and you need to ensure you
+ visit every cell and not just those defined in the file. (The
+ CellIterator will only return the cells defined in the file, which
+ is largely those with values or stylings, but it depends on Excel).</p>
+ <p>In cases such as these, you should fetch the first and last column
+ information for a row, then call <em>getCell(int, MissingCellPolicy)</em>
+ to fetch the cell. Use a
+ <link href="../apidocs/org/apache/poi/ss/usermodel/Row.MissingCellPolicy.html">MissingCellPolicy</link>
+ to control how blank or null cells are handled.</p>
+ <source>
+ // Decide which rows to process
+ int rowStart = Math.min(15, sheet.getFirstRowNum());
+ int rowEnd = Math.max(1400, sheet.getLastRowNum());
+
+ for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
+ Row r = sheet.getRow(rowNum);
+
+ int lastColumn = Math.max(r.getLastCellNum(), MY_MINIMUM_COLUMN_COUNT);
+
+ for (int cn = 0; cn < lastColumn; cn++) {
+ Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
+ if (c == null) {
+ // The spreadsheet is empty in this cell
+ } else {
+ // Do something useful with the cell's contents
+ }
+ }
+ }
+ </source>
+ </section>
+
+ <anchor id="CellContents"/>
+ <section><title>Getting the cell contents</title>
+ <p>To get the contents of a cell, you first need to
+ know what kind of cell it is (asking a string cell
+ for its numeric contents will get you a
+ NumberFormatException for example). So, you will
+ want to switch on the cell's type, and then call
+ the appropriate getter for that cell.</p>
+ <p>In the code below, we loop over every cell
+ in one sheet, print out the cell's reference
+ (eg A3), and then the cell's contents.</p>
+ <source>
+ // import org.apache.poi.ss.usermodel.*;
+
+ Sheet sheet1 = wb.getSheetAt(0);
+ for (Row row : sheet1) {
+ for (Cell cell : row) {
+ CellReference cellRef = new CellReference(row.getRowNum(), cell.getColumnIndex());
+ System.out.print(cellRef.formatAsString());
+ System.out.print(" - ");
+
+ switch (cell.getCellType()) {
+ case Cell.CELL_TYPE_STRING:
+ System.out.println(cell.getRichStringCellValue().getString());
+ break;
+ case Cell.CELL_TYPE_NUMERIC:
+ if (DateUtil.isCellDateFormatted(cell)) {
+ System.out.println(cell.getDateCellValue());
+ } else {
+ System.out.println(cell.getNumericCellValue());
+ }
+ break;
+ case Cell.CELL_TYPE_BOOLEAN:
+ System.out.println(cell.getBooleanCellValue());
+ break;
+ case Cell.CELL_TYPE_FORMULA:
+ System.out.println(cell.getCellFormula());
+ break;
+ default:
+ System.out.println();
+ }
+ }
+ }
+ </source>
+ </section>
+
+ <anchor id="TextExtraction"/>
+ <section><title>Text Extraction</title>
+ <p>For most text extraction requirements, the standard
+ ExcelExtractor class should provide all you need.</p>
+ <source>
+ InputStream inp = new FileInputStream("workbook.xls");
+ HSSFWorkbook wb = new HSSFWorkbook(new POIFSFileSystem(inp));
+ ExcelExtractor extractor = new ExcelExtractor(wb);
+
+ extractor.setFormulasNotResults(true);
+ extractor.setIncludeSheetNames(false);
+ String text = extractor.getText();
+ </source>
+ <p>For very fancy text extraction, XLS to CSV etc,
+ take a look at
+ <em>/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java</em>
+ </p>
+ </section>
+ <anchor id="FillsAndFrills"/>
+ <section><title>Fills and colors</title>
+ <source>
+ Workbook wb = new XSSFWorkbook();
+ Sheet sheet = wb.createSheet("new sheet");
+
+ // Create a row and put some cells in it. Rows are 0 based.
+ Row row = sheet.createRow((short) 1);
+
+ // Aqua background
+ CellStyle style = wb.createCellStyle();
+ style.setFillBackgroundColor(IndexedColors.AQUA.getIndex());
+ style.setFillPattern(CellStyle.BIG_SPOTS);
+ Cell 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(IndexedColors.ORANGE.getIndex());
+ style.setFillPattern(CellStyle.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</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("new sheet");
+
+ Row row = sheet.createRow((short) 1);
+ Cell cell = row.createCell((short) 1);
+ cell.setCellValue("This is a test of merging");
+
+ sheet.addMergedRegion(new CellRangeAddress(
+ 1, //first row (0-based)
+ 1, //last row (0-based)
+ 1, //first column (0-based)
+ 2 //last column (0-based)
+ ));
+
+ // 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</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("new sheet");
+
+ // Create a row and put some cells in it. Rows are 0 based.
+ Row row = sheet.createRow(1);
+
+ // Create a new font and alter it.
+ Font 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.
+ CellStyle style = wb.createCellStyle();
+ style.setFont(font);
+
+ // Create a cell and put a value in it.
+ Cell cell = row.createCell(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>
+<p>
+ Note, the maximum number of unique fonts in a workbook is limited to 32767 (
+ the maximum positive short). You should re-use fonts in your apllications instead of
+ creating a font for each cell.
+Examples:
+</p>
+<p><strong>Wrong:</strong></p>
+<source>
+ for (int i = 0; i < 10000; i++) {
+ Row row = sheet.createRow(i);
+ Cell cell = row.createCell((short) 0);
+
+ CellStyle style = workbook.createCellStyle();
+ Font font = workbook.createFont();
+ font.setBoldweight(Font.BOLDWEIGHT_BOLD);
+ style.setFont(font);
+ cell.setCellStyle(style);
+ }
+</source>
+<p><strong>Correct:</strong></p>
+<source>
+
+ CellStyle style = workbook.createCellStyle();
+ Font font = workbook.createFont();
+ font.setBoldweight(Font.BOLDWEIGHT_BOLD);
+ style.setFont(font);
+ for (int i = 0; i < 10000; i++) {
+ Row row = sheet.createRow(i);
+ Cell cell = row.createCell((short) 0);
+ cell.setCellStyle(style);
+ }
+</source>
+
+ </section>
+ <anchor id="CustomColors"/>
+ <section><title>Custom colors</title>
+ <p><strong>HSSF:</strong></p>
+ <source>
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet = wb.createSheet();
+ HSSFRow row = sheet.createRow((short) 0);
+ HSSFCell cell = row.createCell((short) 0);
+ cell.setCellValue("Default Palette");
+
+ //apply some colors from the standard palette,
+ // as in the previous examples.
+ //we'll use red text on a lime background
+
+ HSSFCellStyle style = wb.createCellStyle();
+ style.setFillForegroundColor(HSSFColor.LIME.index);
+ style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
+
+ HSSFFont font = wb.createFont();
+ font.setColor(HSSFColor.RED.index);
+ style.setFont(font);
+
+ cell.setCellStyle(style);
+
+ //save with the default palette
+ FileOutputStream out = new FileOutputStream("default_palette.xls");
+ wb.write(out);
+ out.close();
+
+ //now, let's replace RED and LIME in the palette
+ // with a more attractive combination
+ // (lovingly borrowed from freebsd.org)
+
+ cell.setCellValue("Modified Palette");
+
+ //creating a custom palette for the workbook
+ HSSFPalette palette = wb.getCustomPalette();
+
+ //replacing the standard red with freebsd.org red
+ palette.setColorAtIndex(HSSFColor.RED.index,
+ (byte) 153, //RGB red (0-255)
+ (byte) 0, //RGB green
+ (byte) 0 //RGB blue
+ );
+ //replacing lime with freebsd.org gold
+ palette.setColorAtIndex(HSSFColor.LIME.index, (byte) 255, (byte) 204, (byte) 102);
+
+ //save with the modified palette
+ // note that wherever we have previously used RED or LIME, the
+ // new colors magically appear
+ out = new FileOutputStream("modified_palette.xls");
+ wb.write(out);
+ out.close();
+ </source>
+ <p><strong>XSSF:</strong></p>
+ <source>
+ XSSFWorkbook wb = new XSSFWorkbook();
+ XSSFSheet sheet = wb.createSheet();
+ XSSFRow row = sheet.createRow(0);
+ XSSFCell cell = row.createCell( 0);
+ cell.setCellValue("custom XSSF colors");
+
+ XSSFCellStyle style1 = wb.createCellStyle();
+ style1.setFillForegroundColor(new XSSFColor(new java.awt.Color(128, 0, 128)));
+ style1.setFillPattern(CellStyle.SOLID_FOREGROUND);
+ </source>
+ </section>
+ <anchor id="ReadWriteWorkbook"/>
+ <section><title>Reading and Rewriting Workbooks</title>
+ <source>
+ InputStream inp = new FileInputStream("workbook.xls");
+ //InputStream inp = new FileInputStream("workbook.xlsx");
+
+ Workbook wb = WorkbookFactory.create(inp);
+ Sheet sheet = wb.getSheetAt(0);
+ Row row = sheet.getRow(2);
+ Cell cell = row.getCell(3);
+ if (cell == null)
+ cell = row.createCell(3);
+ cell.setCellType(Cell.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="NewLinesInCells"/>
+ <section><title>Using newlines in cells</title>
+ <source>
+ Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
+ Sheet sheet = wb.createSheet();
+
+ Row row = sheet.createRow(2);
+ Cell cell = row.createCell(2);
+ cell.setCellValue("Use \n with word wrap on to create a new line");
+
+ //to enable newlines you need set a cell styles with wrap=true
+ CellStyle cs = wb.createCellStyle();
+ cs.setWrapText(true);
+ cell.setCellStyle(cs);
+
+ //increase row height to accomodate two lines of text
+ row.setHeightInPoints((2*sheet.getDefaultRowHeightInPoints()));
+
+ //adjust column width to fit the content
+ sheet.autoSizeColumn((short)2);
+
+ FileOutputStream fileOut = new FileOutputStream("ooxml-newlines.xlsx");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+ <anchor id="DataFormats"/>
+ <section><title>Data Formats</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("format sheet");
+ CellStyle style;
+ DataFormat format = wb.createDataFormat();
+ Row row;
+ Cell 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="FitTo"/>
+ <section><title>Fit Sheet to One Page</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("format sheet");
+ PrintSetup 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="PrintArea2"/>
+ <section><title>Set Print Area</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("Sheet1");
+ //sets the print area for the first sheet
+ wb.setPrintArea(0, "$A$1:$C$2");
+
+ //Alternatively:
+ wb.setPrintArea(
+ 0, //sheet index
+ 0, //start column
+ 1, //end column
+ 0, //start row
+ 0 //end row
+ );
+
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+
+ <anchor id="FooterPageNumbers"/>
+ <section><title>Set Page Numbers on Footer</title>
+ <source>
+ Workbook wb = new HSSFWorkbook(); // or new XSSFWorkbook();
+ Sheet sheet = wb.createSheet("format sheet");
+ Footer footer = sheet.getFooter();
+
+ footer.setRight( "Page " + HeaderFooter.page() + " of " + HeaderFooter.numPages() );
+
+
+
+ // Create various cells and rows for spreadsheet.
+
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+
+ <anchor id="ConvenienceFunctions"/>
+ <section><title>Using the Convenience Functions</title>
+ <p>
+ The convenience functions provide
+ utility features such as setting borders around merged
+ regions and changing style attributes without explicitly
+ creating new styles.
+ </p>
+ <source>
+ Workbook wb = new HSSFWorkbook(); // or new XSSFWorkbook()
+ Sheet sheet1 = wb.createSheet( "new sheet" );
+
+ // Create a merged region
+ Row row = sheet1.createRow( 1 );
+ Row row2 = sheet1.createRow( 2 );
+ Cell cell = row.createCell( 1 );
+ cell.setCellValue( "This is a test of merging" );
+ CellRangeAddress region = CellRangeAddress.valueOf("B2:E5");
+ sheet1.addMergedRegion( region );
+
+ // Set the border and border colors.
+ final short borderMediumDashed = CellStyle.BORDER_MEDIUM_DASHED;
+ RegionUtil.setBorderBottom( borderMediumDashed,
+ region, sheet1, wb );
+ RegionUtil.setBorderTop( borderMediumDashed,
+ region, sheet1, wb );
+ RegionUtil.setBorderLeft( borderMediumDashed,
+ region, sheet1, wb );
+ RegionUtil.setBorderRight( borderMediumDashed,
+ region, sheet1, wb );
+ RegionUtil.setBottomBorderColor(IndexedColors.AQUA.getIndex(), region, sheet1, wb);
+ RegionUtil.setTopBorderColor(IndexedColors.AQUA.getIndex(), region, sheet1, wb);
+ RegionUtil.setLeftBorderColor(IndexedColors.AQUA.getIndex(), region, sheet1, wb);
+ RegionUtil.setRightBorderColor(IndexedColors.AQUA.getIndex(), region, sheet1, wb);
+
+ // Shows some usages of HSSFCellUtil
+ CellStyle style = wb.createCellStyle();
+ style.setIndention((short)4);
+ CellUtil.createCell(row, 8, "This is the value of the cell", style);
+ Cell cell2 = CellUtil.createCell( row2, 8, "This is the value of the cell");
+ CellUtil.setAlignment(cell2, wb, CellStyle.ALIGN_CENTER);
+
+ // Write out the workbook
+ FileOutputStream fileOut = new FileOutputStream( "workbook.xls" );
+ wb.write( fileOut );
+ fileOut.close();
+ </source>
+ </section>
+
+ <anchor id="ShiftRows"/>
+ <section><title>Shift rows up or down on a sheet</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("row sheet");
+
+ // Create various cells and rows for spreadsheet.
+
+ // Shift rows 6 - 11 on the spreadsheet to the top (rows 0 - 5)
+ sheet.shiftRows(5, 10, -5);
+
+ </source>
+ </section>
+
+ <anchor id="SelectSheet"/>
+ <section><title>Set a sheet as selected</title>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("row sheet");
+ sheet.setSelected(true);
+
+ </source>
+ </section>
+
+ <anchor id="Zoom"/>
+ <section><title>Set the zoom magnification</title>
+ <p>
+ The zoom is expressed as a fraction. For example to
+ express a zoom of 75% use 3 for the numerator and
+ 4 for the denominator.
+ </p>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet1 = wb.createSheet("new sheet");
+ sheet1.setZoom(3,4); // 75 percent magnification
+ </source>
+ </section>
+
+ <anchor id="Splits"/>
+ <section><title>Splits and freeze panes</title>
+ <p>
+ There are two types of panes you can create; freeze panes and split panes.
+ </p>
+ <p>
+ A freeze pane is split by columns and rows. You create
+ a freeze pane using the following mechanism:
+ </p>
+ <p>
+ sheet1.createFreezePane( 3, 2, 3, 2 );
+ </p>
+ <p>
+ The first two parameters are the columns and rows you
+ wish to split by. The second two parameters indicate
+ the cells that are visible in the bottom right quadrant.
+ </p>
+ <p>
+
+ Split pains appear differently. The split area is
+ divided into four separate work area's. The split
+ occurs at the pixel level and the user is able to
+ adjust the split by dragging it to a new position.
+ </p>
+ <p>
+
+ Split panes are created with the following call:
+ </p>
+ <p>
+ sheet2.createSplitPane( 2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT );
+ </p>
+ <p>
+
+ The first parameter is the x position of the split.
+ This is in 1/20th of a point. A point in this case
+ seems to equate to a pixel. The second parameter is
+ the y position of the split. Again in 1/20th of a point.
+ </p>
+ <p>
+ The last parameter indicates which pane currently has
+ the focus. This will be one of Sheet.PANE_LOWER_LEFT,
+ PANE_LOWER_RIGHT, PANE_UPPER_RIGHT or PANE_UPPER_LEFT.
+ </p>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet1 = wb.createSheet("new sheet");
+ Sheet sheet2 = wb.createSheet("second sheet");
+ Sheet sheet3 = wb.createSheet("third sheet");
+ Sheet sheet4 = wb.createSheet("fourth sheet");
+
+ // Freeze just one row
+ sheet1.createFreezePane( 0, 1, 0, 1 );
+ // Freeze just one column
+ sheet2.createFreezePane( 1, 0, 1, 0 );
+ // Freeze the columns and rows (forget about scrolling position of the lower right quadrant).
+ sheet3.createFreezePane( 2, 2 );
+ // Create a split with the lower left side being the active quadrant
+ sheet4.createSplitPane( 2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT );
+
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+
+ <anchor id="Repeating"/>
+ <section><title>Repeating rows and columns</title>
+ <p>
+ It's possible to set up repeating rows and columns in
+ your printouts by using the setRepeatingRows() and
+ setRepeatingColumns() methods in the Sheet class.
+ </p>
+ <p>
+ These methods expect a CellRangeAddress parameter
+ which specifies the range for the rows or columns to
+ repeat.
+ For setRepeatingRows(), it should specify a range of
+ rows to repeat, with the column part spanning all
+ columns.
+ For setRepeatingColums(), it should specify a range of
+ columns to repeat, with the row part spanning all
+ rows.
+ If the parameter is null, the repeating rows or columns
+ will be removed.
+ </p>
+ <source>
+ Workbook wb = new HSSFWorkbook(); // or new XSSFWorkbook();
+ Sheet sheet1 = wb.createSheet("Sheet1");
+ Sheet sheet2 = wb.createSheet("Sheet2");
+
+ // Set the rows to repeat from row 4 to 5 on the first sheet.
+ sheet1.setRepeatingRows(CellRangeAddress.valueOf("4:5"));
+ // Set the columns to repeat from column A to C on the second sheet
+ sheet2.setRepeatingColumns(CellRangeAddress.valueOf("A:C"));
+
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+ <anchor id="HeaderFooter"/>
+ <section><title>Headers and Footers</title>
+ <p>
+ Example is for headers but applies directly to footers.
+ </p>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet("new sheet");
+
+ Header header = sheet.getHeader();
+ header.setCenter("Center Header");
+ header.setLeft("Left Header");
+ header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") +
+ HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16");
+
+ FileOutputStream fileOut = new FileOutputStream("workbook.xls");
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ </section>
+
+ <anchor id="DrawingShapes"/>
+ <section><title>Drawing Shapes</title>
+ <p>
+ POI supports drawing shapes using the Microsoft Office
+ drawing tools. Shapes on a sheet are organized in a
+ hiearchy of groups and and shapes. The top-most shape
+ is the patriarch. This is not visisble on the sheet
+ at all. To start drawing you need to call <code>createPatriarch</code>
+ on the <code>HSSFSheet</code> class. This has the
+ effect erasing any other shape information stored
+ in that sheet. By default POI will leave shape
+ records alone in the sheet unless you make a call to
+ this method.
+ </p>
+ <p>
+ To create a shape you have to go through the following
+ steps:
+ </p>
+ <ol>
+ <li>Create the patriarch.</li>
+ <li>Create an anchor to position the shape on the sheet.</li>
+ <li>Ask the patriarch to create the shape.</li>
+ <li>Set the shape type (line, oval, rectangle etc...)</li>
+ <li>Set any other style details converning the shape. (eg:
+ line thickness, etc...)</li>
+ </ol>
+ <source>
+ HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+ a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 );
+ HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
+ shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
+ </source>
+ <p>
+ Text boxes are created using a different call:
+ </p>
+ <source>
+ HSSFTextbox textbox1 = patriarch.createTextbox(
+ new HSSFClientAnchor(0,0,0,0,(short)1,1,(short)2,2));
+ textbox1.setString(new HSSFRichTextString("This is a test") );
+ </source>
+ <p>
+ It's possible to use different fonts to style parts of
+ the text in the textbox. Here's how:
+ </p>
+ <source>
+ HSSFFont font = wb.createFont();
+ font.setItalic(true);
+ font.setUnderline(HSSFFont.U_DOUBLE);
+ HSSFRichTextString string = new HSSFRichTextString("Woo!!!");
+ string.applyFont(2,5,font);
+ textbox.setString(string );
+ </source>
+ <p>
+ Just as can be done manually using Excel, it is possible
+ to group shapes together. This is done by calling
+ <code>createGroup()</code> and then creating the shapes
+ using those groups.
+ </p>
+ <p>
+ It's also possible to create groups within groups.
+ </p>
+ <warning>Any group you create should contain at least two
+ other shapes or subgroups.</warning>
+ <p>
+ Here's how to create a shape group:
+ </p>
+ <source>
+ // Create a shape group.
+ HSSFShapeGroup group = patriarch.createGroup(
+ new HSSFClientAnchor(0,0,900,200,(short)2,2,(short)2,2));
+
+ // Create a couple of lines in the group.
+ HSSFSimpleShape shape1 = group.createShape(new HSSFChildAnchor(3,3,500,500));
+ shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
+ ( (HSSFChildAnchor) shape1.getAnchor() ).setAnchor((short)3,3,500,500);
+ HSSFSimpleShape shape2 = group.createShape(new HSSFChildAnchor((short)1,200,400,600));
+ shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
+ </source>
+ <p>
+ If you're being observant you'll noticed that the shapes
+ that are added to the group use a new type of anchor:
+ the <code>HSSFChildAnchor</code>. What happens is that
+ the created group has it's own coordinate space for
+ shapes that are placed into it. POI defaults this to
+ (0,0,1023,255) but you are able to change it as desired.
+ Here's how:
+ </p>
+ <source>
+ myGroup.setCoordinates(10,10,20,20); // top-left, bottom-right
+ </source>
+ <p>
+ If you create a group within a group it's also going
+ to have it's own coordinate space.
+ </p>
+ </section>
+
+ <anchor id="StylingShapes"/>
+ <section><title>Styling Shapes</title>
+ <p>
+ By default shapes can look a little plain. It's possible
+ to apply different styles to the shapes however. The
+ sorts of things that can currently be done are:
+ </p>
+ <ul>
+ <li>Change the fill color.</li>
+ <li>Make a shape with no fill color.</li>
+ <li>Change the thickness of the lines.</li>
+ <li>Change the style of the lines. Eg: dashed, dotted.</li>
+ <li>Change the line color.</li>
+ </ul>
+ <p>
+ Here's an examples of how this is done:
+ </p>
+ <source>
+ HSSFSimpleShape s = patriarch.createSimpleShape(a);
+ s.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
+ s.setLineStyleColor(10,10,10);
+ s.setFillColor(90,10,200);
+ s.setLineWidth(HSSFShape.LINEWIDTH_ONE_PT * 3);
+ s.setLineStyle(HSSFShape.LINESTYLE_DOTSYS);
+ </source>
+ </section>
+ <anchor id="Graphics2d"/>
+ <section><title>Shapes and Graphics2d</title>
+ <p>
+ While the native POI shape drawing commands are the
+ recommended way to draw shapes in a shape it's sometimes
+ desirable to use a standard API for compatibility with
+ external libraries. With this in mind we created some
+ wrappers for <code>Graphics</code> and <code>Graphics2d</code>.
+ </p>
+ <warning>
+ It's important to not however before continuing that
+ <code>Graphics2d</code> is a poor match to the capabilities
+ of the Microsoft Office drawing commands. The older
+ <code>Graphics</code> class offers a closer match but is
+ still a square peg in a round hole.
+ </warning>
+ <p>
+ All Graphics commands are issued into an <code>HSSFShapeGroup</code>.
+ Here's how it's done:
+ </p>
+ <source>
+ a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 );
+ group = patriarch.createGroup( a );
+ group.setCoordinates( 0, 0, 80 * 4 , 12 * 23 );
+ float verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / (float)Math.abs(group.getY2() - group.getY1());
+ g = new EscherGraphics( group, wb, Color.black, verticalPointsPerPixel );
+ g2d = new EscherGraphics2d( g );
+ drawChemicalStructure( g2d );
+ </source>
+ <p>
+ The first thing we do is create the group and set it's coordinates
+ to match what we plan to draw. Next we calculate a reasonable
+ fontSizeMultipler then create the EscherGraphics object.
+ Since what we really want is a <code>Graphics2d</code>
+ object we create an EscherGraphics2d object and pass in
+ the graphics object we created. Finally we call a routine
+ that draws into the EscherGraphics2d object.
+ </p>
+ <p>
+ The vertical points per pixel deserves some more explanation.
+ One of the difficulties in converting Graphics calls
+ into escher drawing calls is that Excel does not have
+ the concept of absolute pixel positions. It measures
+ it's cell widths in 'characters' and the cell heights in points.
+ Unfortunately it's not defined exactly what type of character it's
+ measuring. Presumably this is due to the fact that the Excel will be
+ using different fonts on different platforms or even within the same
+ platform.
+ </p>
+ <p>
+ Because of this constraint we've had to implement the concept of a
+ verticalPointsPerPixel. This the amount the font should be scaled by when
+ you issue commands such as drawString(). To calculate this value
+ use the follow formula:
+ </p>
+ <source>
+ multipler = groupHeightInPoints / heightOfGroup
+ </source>
+ <p>
+ The height of the group is calculated fairly simply by calculating the
+ difference between the y coordinates of the bounding box of the shape. The
+ height of the group can be calculated by using a convenience called
+ <code>HSSFClientAnchor.getAnchorHeightInPoints()</code>.
+ </p>
+ <p>
+ Many of the functions supported by the graphics classes
+ are not complete. Here's some of the functions that are known
+ to work.
+ </p>
+ <ul>
+ <li>fillRect()</li>
+ <li>fillOval()</li>
+ <li>drawString()</li>
+ <li>drawOval()</li>
+ <li>drawLine()</li>
+ <li>clearRect()</li>
+ </ul>
+ <p>
+ Functions that are not supported will return and log a message
+ using the POI logging infrastructure (disabled by default).
+ </p>
+ </section>
+ <anchor id="Outlining"/>
+ <section>
+ <title>Outlining</title>
+ <p>
+ Outlines are great for grouping sections of information
+ together and can be added easily to columns and rows
+ using the POI API. Here's how:
+ </p>
+ <source>
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet1 = wb.createSheet("new sheet");
+
+ sheet1.groupRow( 5, 14 );
+ sheet1.groupRow( 7, 14 );
+ sheet1.groupRow( 16, 19 );
+
+ sheet1.groupColumn( (short)4, (short)7 );
+ sheet1.groupColumn( (short)9, (short)12 );
+ sheet1.groupColumn( (short)10, (short)11 );
+
+ FileOutputStream fileOut = new FileOutputStream(filename);
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ <p>
+ To collapse (or expand) an outline use the following calls:
+ </p>
+ <source>
+ sheet1.setRowGroupCollapsed( 7, true );
+ sheet1.setColumnGroupCollapsed( (short)4, true );
+ </source>
+ <p>
+ The row/column you choose should contain an already
+ created group. It can be anywhere within the group.
+ </p>
+ </section>
+ </section>
+ </section>
+ <anchor id="Images"/>
+ <section>
+ <title>Images</title>
+ <p>
+ Images are part of the drawing support. To add an image just
+ call <code>createPicture()</code> on the drawing patriarch.
+ At the time of writing the following types are supported:
+ </p>
+ <ul>
+ <li>PNG</li>
+ <li>JPG</li>
+ <li>DIB</li>
+ </ul>
+ <p>
+ It should be noted that any existing drawings may be erased
+ once you add a image to a sheet.
+ </p>
+ <source>
+ //create a new workbook
+ Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
+
+ //add picture data to this workbook.
+ InputStream is = new FileInputStream("image1.jpeg");
+ byte[] bytes = IOUtils.toByteArray(is);
+ int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
+ is.close();
+
+ CreationHelper helper = wb.getCreationHelper();
+
+ //create sheet
+ Sheet sheet = wb.createSheet();
+
+ // Create the drawing patriarch. This is the top level container for all shapes.
+ Drawing drawing = sheet.createDrawingPatriarch();
+
+ //add a picture shape
+ ClientAnchor anchor = helper.createClientAnchor();
+ //set top-left corner of the picture,
+ //subsequent call of Picture#resize() will operate relative to it
+ anchor.setCol1(3);
+ anchor.setRow1(2);
+ Picture pict = drawing.createPicture(anchor, pictureIdx);
+
+ //auto-size picture relative to its top-left corner
+ pict.resize();
+
+ //save workbook
+ String file = "picture.xls";
+ if(wb instanceof XSSFWorkbook) file += "x";
+ FileOutputStream fileOut = new FileOutputStream(file);
+ wb.write(fileOut);
+ fileOut.close();
+ </source>
+ <warning>
+ Picture.resize() works only for JPEG and PNG. Other formats are not yet supported.
+ </warning>
+ <p>Reading images from a workbook:</p>
+ <source>
+
+ List lst = workbook.getAllPictures();
+ for (Iterator it = lst.iterator(); it.hasNext(); ) {
+ PictureData pict = (PictureData)it.next();
+ String ext = pict.suggestFileExtension();
+ byte[] data = pict.getData();
+ if (ext.equals("jpeg")){
+ FileOutputStream out = new FileOutputStream("pict.jpg");
+ out.write(data);
+ out.close();
+ }
+ }
+ </source>
+ </section>
+ <anchor id="NamedRanges"/>
+ <section>
+ <title>Named Ranges and Named Cells</title>
+ <p>
+ Named Range is a way to refer to a group of cells by a name. Named Cell is a
+ degenerate case of Named Range in that the 'group of cells' contains exactly one
+ cell. You can create as well as refer to cells in a workbook by their named range.
+ When working with Named Ranges, the classes: org.apache.poi.hssf.util.CellReference and
+ & org.apache.poi.hssf.util.AreaReference are used (these
+ work for both XSSF and HSSF, despite the package name).
+ </p>
+ <p>
+ Creating Named Range / Named Cell
+ </p>
+ <source>
+ // setup code
+ String sname = "TestSheet", cname = "TestName", cvalue = "TestVal";
+ Workbook wb = new HSSFWorkbook();
+ Sheet sheet = wb.createSheet(sname);
+ sheet.createRow(0).createCell((short) 0).setCellValue(cvalue);
+
+ // 1. create named range for a single cell using areareference
+ Name namedCell = wb.createName();
+ namedCell.setNameName(cname);
+ String reference = sname+"!A1:A1"; // area reference
+ namedCell.setRefersToFormula(reference);
+
+ // 2. create named range for a single cell using cellreference
+ Name namedCel2 = wb.createName();
+ namedCel2.setNameName(cname);
+ String reference = sname+"!A1"; // cell reference
+ namedCel2.setRefersToFormula(reference);
+
+ // 3. create named range for an area using AreaReference
+ Name namedCel3 = wb.createName();
+ namedCel3.setNameName(cname);
+ String reference = sname+"!A1:C5"; // area reference
+ namedCel3.setRefersToFormula(reference);
+
+ // 4. create named formula
+ Name namedCel4 = wb.createName();
+ namedCel4.setNameName("my_sum");
+ namedCel4.setRefersToFormula("SUM(sname+!$I$2:$I$6)");
+ </source>
+ <p>
+ Reading from Named Range / Named Cell
+ </p>
+ <source>
+ // setup code
+ String cname = "TestName";
+ Workbook wb = getMyWorkbook(); // retrieve workbook
+
+ // retrieve the named range
+ int namedCellIdx = wb.getNameIndex(cellName);
+ Name aNamedCell = wb.getNameAt(namedCellIdx);
+
+ // retrieve the cell at the named range and test its contents
+ AreaReference aref = new AreaReference(aNamedCell.getRefersToFormula());
+ CellReference[] crefs = aref.getAllReferencedCells();
+ for (int i=0; i<crefs.length; i++) {
+ Sheet s = wb.getSheet(crefs[i].getSheetName());
+ Row r = sheet.getRow(crefs[i].getRow());
+ Cell c = r.getCell(crefs[i].getCol());
+ // extract the cell contents based on cell type etc.
+ }
+ </source>
+ <p>
+ Reading from non-contiguous Named Ranges
+ </p>
+ <source>
+ // Setup code
+ String cname = "TestName";
+ Workbook wb = getMyWorkbook(); // retrieve workbook
+
+ // Retrieve the named range
+ // Will be something like "$C$10,$D$12:$D$14";
+ int namedCellIdx = wb.getNameIndex(cellName);
+ Name aNamedCell = wb.getNameAt(namedCellIdx);
+
+ // Retrieve the cell at the named range and test its contents
+ // Will get back one AreaReference for C10, and
+ // another for D12 to D14
+ AreaReference[] arefs = AreaReference.generateContiguous(aNamedCell.getRefersToFormula());
+ for (int i=0; i<arefs.length; i++) {
+ // Only get the corners of the Area
+ // (use arefs[i].getAllReferencedCells() to get all cells)
+ CellReference[] crefs = arefs[i].getCells();
+ for (int j=0; j<crefs.length; j++) {
+ // Check it turns into real stuff
+ Sheet s = wb.getSheet(crefs[j].getSheetName());
+ Row r = s.getRow(crefs[j].getRow());
+ Cell c = r.getCell(crefs[j].getCol());
+ // Do something with this corner cell
+ }
+ }
+ </source>
+ <p>
+ Note, when a cell is deleted, Excel does not delete the
+ attached named range. As result, workbook can contain
+ named ranges that point to cells that no longer exist.
+ You should check the validity of a reference before
+ constructing AreaReference
+ </p>
+ <source>
+ if(name.isDeleted()){
+ //named range points to a deleted cell.
+ } else {
+ AreaReference ref = new AreaReference(name.getRefersToFormula());
+ }
+ </source>
+ </section>
+ <anchor id="CellComments"/>
+ <section><title>Cell Comments - HSSF and XSSF</title>
+ <p>
+ A comment is a rich text note that is attached to &
+ associated with a cell, separate from other cell content.
+ Comment content is stored separate from the cell, and is displayed in a drawing object (like a text box)
+ that is separate from, but associated with, a cell
+ </p>
+ <source>
+ Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
+
+ CreationHelper factory = wb.getCreationHelper();
+
+ Sheet sheet = wb.createSheet();
+
+ Rowl row = sheet.createRow(3);
+ Cell cell = row.createCell(5);
+ cell.setCellValue("F4");
+
+ Drawing drawing = sheet.createDrawingPatriarch();
+
+ // When the comment box is visible, have it show in a 1x3 space
+ ClientAnchor anchor = factory.createClientAnchor();
+ anchor.setCol1(cell.getColumnIndex());
+ anchor.setCol2(cell.getColumnIndex()+1);
+ anchor.setRow1(row.getRowNul());
+ anchor.setRow2(row.getRowNul()+3);
+
+ // Create the comment and set the text+author
+ Comment comment = drawing.createCellComment(anchor);
+ RichTextString str = factory.createRichTextString("Hello, World!");
+ comment.setString(str);
+ comment.setAuthor("Apache POI");
+
+ // Assign the comment to the cell
+ cell.setCellComment(comment);
+
+ String fname = "comment-xssf.xls";
+ if(wb instanceof XSSFWorkbook) fname += "x";
+ FileOutputStream out = new FileOutputStream(fname);
+ wb.write(out);
+ out.close();
+ </source>
+ <p>
+ Reading cell comments
+ </p>
+ <source>
+ Cell cell = sheet.get(3).getColumn((short)1);
+ Comment comment = cell.getCellComment();
+ if (comment != null) {
+ RichTextString str = comment.getString();
+ String author = comment.getAuthor();
+ }
+ // alternatively you can retrieve cell comments by (row, column)
+ comment = sheet.getCellComment(3, 1);
+ </source>
+ </section>
+
+ <anchor id="Autofit"/>
+ <section><title>Adjust column width to fit the contents</title>
+ <source>
+ Sheet sheet = workbook.getSheetAt(0);
+ sheet.autoSizeColumn(0); //adjust width of the first column
+ sheet.autoSizeColumn(1); //adjust width of the second column
+ </source>
+ <p>
+ Note, that Sheet#autoSizeColumn() does not evaluate formula cells,
+ the width of formula cells is calculated based on the cached formula result.
+ If your workbook has many formulas then it is a good idea to evaluate them before auto-sizing.
+ </p>
+ <warning>
+ To calculate column width Sheet.autoSizeColumn uses Java2D classes
+ that throw exception if graphical environment is not available. In case if graphical environment
+ is not available, you must tell Java that you are running in headless mode and
+ set the following system property: <code> java.awt.headless=true </code>.
+ </warning>
+ </section>
+ <anchor id="Hyperlinks"/>
+ <section><title>How to read hyperlinks</title>
+ <source>
+ Sheet sheet = workbook.getSheetAt(0);
+
+ Cell cell = sheet.getRow(0).getCell((short)0);
+ Hyperlink link = cell.getHyperlink();
+ if(link != null){
+ System.out.println(link.getAddress());
+ }
+ </source>
+ </section>
+ <section><title>How to create hyperlinks</title>
+ <source>
+ Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
+ CreationHelper createHelper = wb.getCreationHelper();
+
+ //cell style for hyperlinks
+ //by default hyperlinks are blue and underlined
+ CellStyle hlink_style = wb.createCellStyle();
+ Font hlink_font = wb.createFont();
+ hlink_font.setUnderline(Font.U_SINGLE);
+ hlink_font.setColor(IndexedColors.BLUE.getIndex());
+ hlink_style.setFont(hlink_font);
+
+ Cell cell;
+ Sheet sheet = wb.createSheet("Hyperlinks");
+ //URL
+ cell = sheet.createRow(0).createCell((short)0);
+ cell.setCellValue("URL Link");
+
+ Hyperlink link = createHelper.createHyperlink(Hyperlink.LINK_URL);
+ link.setAddress("http://poi.apache.org/");
+ cell.setHyperlink(link);
+ cell.setCellStyle(hlink_style);
+
+ //link to a file in the current directory
+ cell = sheet.createRow(1).createCell((short)0);
+ cell.setCellValue("File Link");
+ link = createHelper.createHyperlink(Hyperlink.LINK_FILE);
+ link.setAddress("link1.xls");
+ cell.setHyperlink(link);
+ cell.setCellStyle(hlink_style);
+
+ //e-mail link
+ cell = sheet.createRow(2).createCell((short)0);
+ cell.setCellValue("Email Link");
+ link = createHelper.createHyperlink(Hyperlink.LINK_EMAIL);
+ //note, if subject contains white spaces, make sure they are url-encoded
+ link.setAddress("mailto:poi@apache.org?subject=Hyperlinks");
+ cell.setHyperlink(link);
+ cell.setCellStyle(hlink_style);
+
+ //link to a place in this workbook
+
+ //create a target sheet and cell
+ Sheet sheet2 = wb.createSheet("Target Sheet");
+ sheet2.createRow(0).createCell((short)0).setCellValue("Target Cell");
+
+ cell = sheet.createRow(3).createCell((short)0);
+ cell.setCellValue("Worksheet Link");
+ Hyperlink link2 = createHelper.createHyperlink(Hyperlink.LINK_DOCUMENT);
+ link2.setAddress("'Target Sheet'!A1");
+ cell.setHyperlink(link2);
+ cell.setCellStyle(hlink_style);
+
+ FileOutputStream out = new FileOutputStream("hyperinks.xlsx");
+ wb.write(out);
+ out.close();
+ </source>
+ </section>
+ <anchor id="Validation"/>
+ <section><title>Data Validations</title>
+ <p>
+ As of version 3.8, POI has slightly different syntax to work with data validations with .xls and .xlsx formats.
+ </p>
+ <section>
+ <title>hssf.usermodel (binary .xls format)</title>
+ <p><strong>Check the value a user enters into a cell against one or more predefined value(s).</strong></p>
+ <p>The following code will limit the value the user can enter into cell A1 to one of three integer values, 10, 20 or 30.</p>
+ <source>
+ HSSFWorkbook workbook = new HSSFWorkbook();
+ HSSFSheet sheet = workbook.createSheet("Data Validation");
+ CellRangeAddressList addressList = new CellRangeAddressList(
+ 0, 0, 0, 0);
+ DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(
+ new String[]{"10", "20", "30"});
+ DataValidation dataValidation = new HSSFDataValidation
+ (addressList, dvConstraint);
+ dataValidation.setSuppressDropDownArrow(true);
+ sheet.addValidationData(dataValidation);
+ </source>
+ <p><strong> Drop Down Lists:</strong></p>
+ <p>This code will do the same but offer the user a drop down list to select a value from.</p>
+ <source>
+ HSSFWorkbook workbook = new HSSFWorkbook();
+ HSSFSheet sheet = workbook.createSheet("Data Validation");
+ CellRangeAddressList addressList = new CellRangeAddressList(
+ 0, 0, 0, 0);
+ DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(
+ new String[]{"10", "20", "30"});
+ DataValidation dataValidation = new HSSFDataValidation
+ (addressList, dvConstraint);
+ dataValidation.setSuppressDropDownArrow(false);
+ sheet.addValidationData(dataValidation);
+ </source>
+ <p><strong>Messages On Error:</strong></p>
+ <p>To create a message box that will be shown to the user if the value they enter is invalid.</p>
+ <source>
+ dataValidation.setErrorStyle(DataValidation.ErrorStyle.STOP);
+ dataValidation.createErrorBox("Box Title", "Message Text");
+ </source>
+ <p>Replace 'Box Title' with the text you wish to display in the message box's title bar
+ and 'Message Text' with the text of your error message.</p>
+ <p><strong>Prompts:</strong></p>
+ <p>To create a prompt that the user will see when the cell containing the data validation receives focus</p>
+ <source>
+ dataValidation.createPromptBox("Title", "Message Text");
+ dataValidation.setShowPromptBox(true);
+ </source>
+ <p>The text encapsulated in the first parameter passed to the createPromptBox() method will appear emboldened
+ and as a title to the prompt whilst the second will be displayed as the text of the message.
+ The createExplicitListConstraint() method can be passed and array of String(s) containing interger, floating point, dates or text values.</p>
+
+ <p><strong>Further Data Validations:</strong></p>
+ <p>To obtain a validation that would check the value entered was, for example, an integer between 10 and 100,
+ use the DVConstraint.createNumericConstraint(int, int, String, String) factory method.</p>
+ <source>
+ dvConstraint = DVConstraint.createNumericConstraint(
+ DVConstraint.ValidationType.INTEGER,
+ DVConstraint.OperatorType.BETWEEN, "10", "100");
+ </source>
+ <p>Look at the javadoc for the other validation and operator types; also note that not all validation
+ types are supported for this method. The values passed to the two String parameters can be formulas; the '=' symbol is used to denote a formula</p>
+ <source>
+ dvConstraint = DVConstraint.createNumericConstraint(
+ DVConstraint.ValidationType.INTEGER,
+ DVConstraint.OperatorType.BETWEEN, "=SUM(A1:A3)", "100");
+ </source>
+ <p>It is not possible to create a drop down list if the createNumericConstraint() method is called,
+ the setSuppressDropDownArrow(false) method call will simply be ignored.</p>
+ <p>Date and time constraints can be created by calling the createDateConstraint(int, String, String, String)
+ or the createTimeConstraint(int, String, String). Both are very similar to the above and are explained in the javadoc. </p>
+ <p><strong>Creating Data Validations From Spreadsheet Cells.</strong></p>
+ <p>The contents of specific cells can be used to provide the values for the data validation
+ and the DVConstraint.createFormulaListConstraint(String) method supports this.
+ To specify that the values come from a contiguous range of cells do either of the following:</p>
+ <source>
+ dvConstraint = DVConstraint.createFormulaListConstraint("$A$1:$A$3");
+ </source>
+ <p>or</p>
+ <source>
+ Name namedRange = workbook.createName();
+ namedRange.setNameName("list1");
+ namedRange.setRefersToFormula("$A$1:$A$3");
+ dvConstraint = DVConstraint.createFormulaListConstraint("list1");
+ </source>
+ <p>and in both cases the user will be able to select from a drop down list containing the values from cells A1, A2 and A3.</p>
+ <p>The data does not have to be as the data validation. To select the data from a different sheet however, the sheet
+ must be given a name when created and that name should be used in the formula. So assuming the existence of a sheet named 'Data Sheet' this will work:</p>
+ <source>
+ Name namedRange = workbook.createName();
+ namedRange.setNameName("list1");
+ namedRange.setRefersToFormula("'Data Sheet'!$A$1:$A$3");
+ dvConstraint = DVConstraint.createFormulaListConstraint("list1");
+ </source>
+ <p>as will this:</p>
+ <source>
+ dvConstraint = DVConstraint.createFormulaListConstraint("'Data Sheet'!$A$1:$A$3");
+ </source>
+ <p>whilst this will not:</p>
+ <source>
+ Name namedRange = workbook.createName();
+ namedRange.setNameName("list1");
+ namedRange.setRefersToFormula("'Sheet1'!$A$1:$A$3");
+ dvConstraint = DVConstraint.createFormulaListConstraint("list1");
+ </source><p>and nor will this:</p><source>
+ dvConstraint = DVConstraint.createFormulaListConstraint("'Sheet1'!$A$1:$A$3");
+ </source>
+ </section>
+ <section>
+ <title>xssf.usermodel (.xlsx format)</title>
+<p>
+Data validations work similarly when you are creating an xml based, SpreadsheetML,
+workbook file; but there are differences. Explicit casts are required, for example,
+in a few places as much of the support for data validations in the xssf stream was
+built into the unifying ss stream, of which more later. Other differences are
+noted with comments in the code.
+</p>
+
+<p><strong>Check the value the user enters into a cell against one or more predefined value(s).</strong></p>
+<source>
+ XSSFWorkbook workbook = new XSSFWorkbook();
+ XSSFSheet sheet = workbook.createSheet("Data Validation");
+ XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createExplicitListConstraint(new String[]{"11", "21", "31"});
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ XSSFDataValidation validation =(XSSFDataValidation)dvHelper.createValidation(
+ dvConstraint, addressList);
+
+ // Here the boolean value false is passed to the setSuppressDropDownArrow()
+ // method. In the hssf.usermodel examples above, the value passed to this
+ // method is true.
+ validation.setSuppressDropDownArrow(false);
+
+ // Note this extra method call. If this method call is omitted, or if the
+ // boolean value false is passed, then Excel will not validate the value the
+ // user enters into the cell.
+ validation.setShowErrorBox(true);
+ sheet.addValidationData(validation);
+</source>
+
+<p><strong>Drop Down Lists:</strong></p>
+<p>This code will do the same but offer the user a drop down list to select a value from.</p>
+<source>
+ XSSFWorkbook workbook = new XSSFWorkbook();
+ XSSFSheet sheet = workbook.createSheet("Data Validation");
+ XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createExplicitListConstraint(new String[]{"11", "21", "31"});
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ XSSFDataValidation validation = (XSSFDataValidation)dvHelper.createValidation(
+ dvConstraint, addressList);
+ validation.setShowErrorBox(true);
+ sheet.addValidationData(validation);
+</source>
+<p>Note that the call to the setSuppressDropDowmArrow() method can either be simply excluded or replaced with:</p>
+<source>
+ validation.setSuppressDropDownArrow(true);
+</source>
+
+<p><strong>Prompts and Error Messages:</strong></p>
+<p>
+These both exactly mirror the hssf.usermodel so please refer to the 'Messages On Error:' and 'Prompts:' sections above.
+</p>
+
+<p><strong>Further Data Validations:</strong></p>
+<p>
+To obtain a validation that would check the value entered was, for example,
+an integer between 10 and 100, use the XSSFDataValidationHelper(s) createNumericConstraint(int, int, String, String) factory method.
+</p>
+<source>
+
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createNumericConstraint(
+ XSSFDataValidationConstraint.ValidationType.INTEGER,
+ XSSFDataValidationConstraint.OperatorType.BETWEEN,
+ "10", "100");
+</source>
+<p>
+The values passed to the final two String parameters can be formulas; the '=' symbol is used to denote a formula.
+Thus, the following would create a validation the allows values only if they fall between the results of summing two cell ranges
+</p>
+<source>
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createNumericConstraint(
+ XSSFDataValidationConstraint.ValidationType.INTEGER,
+ XSSFDataValidationConstraint.OperatorType.BETWEEN,
+ "=SUM(A1:A10)", "=SUM(B24:B27)");
+</source>
+<p>
+It is not possible to create a drop down list if the createNumericConstraint() method is called,
+the setSuppressDropDownArrow(true) method call will simply be ignored.
+</p>
+<p>
+Please check the javadoc for other constraint types as examples for those will not be included here.
+There are, for example, methods defined on the XSSFDataValidationHelper class allowing you to create
+the following types of constraint; date, time, decimal, integer, numeric, formula, text length and custom constraints.
+</p>
+<p><strong>Creating Data Validations From Spread Sheet Cells:</strong></p>
+<p>
+One other type of constraint not mentioned above is the formula list constraint.
+It allows you to create a validation that takes it value(s) from a range of cells. This code
+</p>
+<source>
+XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createFormulaListConstraint("$A$1:$F$1");
+</source>
+
+<p>
+would create a validation that took it's values from cells in the range A1 to F1.
+</p>
+<p>
+The usefulness of this technique can be extended if you use named ranges like this;
+</p>
+
+<source>
+ XSSFName name = workbook.createName();
+ name.setNameName("data");
+ name.setRefersToFormula("$B$1:$F$1");
+ XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
+ XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
+ dvHelper.createFormulaListConstraint("data");
+ CellRangeAddressList addressList = new CellRangeAddressList(
+ 0, 0, 0, 0);
+ XSSFDataValidation validation = (XSSFDataValidation)
+ dvHelper.createValidation(dvConstraint, addressList);
+ validation.setSuppressDropDownArrow(true);
+ validation.setShowErrorBox(true);
+ sheet.addValidationData(validation);
+</source>
+<p>
+OpenOffice Calc has slightly different rules with regard to the scope of names.
+Excel supports both Workbook and Sheet scope for a name but Calc does not, it seems only to support Sheet scope for a name.
+Thus it is often best to fully qualify the name for the region or area something like this;
+</p>
+<source>
+ XSSFName name = workbook.createName();
+ name.setNameName("data");
+ name.setRefersToFormula("'Data Validation'!$B$1:$F$1");
+ ....
+</source>
+<p>
+This does open a further, interesting opportunity however and that is to place all of the data for the validation(s) into named ranges of cells on a hidden sheet within the workbook. These ranges can then be explicitly identified in the setRefersToFormula() method argument.
+</p>
+ </section>
+ <section><title>ss.usermodel</title>
+<p>
+The classes within the ss.usermodel package allow developers to create code that can be used
+to generate both binary (.xls) and SpreadsheetML (.xlsx) workbooks.
+</p>
+<p>
+The techniques used to create data validations share much in common with the xssf.usermodel examples above.
+As a result just one or two examples will be presented here.
+</p>
+<p><strong>Check the value the user enters into a cell against one or more predefined value(s).</strong></p>
+<source>
+ Workbook workbook = new XSSFWorkbook(); // or new HSSFWorkbook
+ Sheet sheet = workbook.createSheet("Data Validation");
+ DataValidationHelper dvHelper = sheet.getDataValidationHelper();
+ DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(
+ new String[]{"13", "23", "33"});
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ DataValidation validation = dvHelper.createValidation(
+ dvConstraint, addressList);
+ // Note the check on the actual type of the DataValidation object.
+ // If it is an instance of the XSSFDataValidation class then the
+ // boolean value 'false' must be passed to the setSuppressDropDownArrow()
+ // method and an explicit call made to the setShowErrorBox() method.
+ if(validation instanceof XSSFDataValidation) {
+ validation.setSuppressDropDownArrow(false);
+ validation.setShowErrorBox(true);
+ }
+ else {
+ // If the Datavalidation contains an instance of the HSSFDataValidation
+ // class then 'true' should be passed to the setSuppressDropDownArrow()
+ // method and the call to setShowErrorBox() is not necessary.
+ validation.setSuppressDropDownArrow(true);
+ }
+ sheet.addValidationData(validation);
+</source>
+
+<p><strong>Drop Down Lists:</strong></p>
+
+<p>This code will do the same but offer the user a drop down list to select a value from.</p>
+
+<source>
+ Workbook workbook = new XSSFWorkbook(); // or new HSSFWorkbook
+ Sheet sheet = workbook.createSheet("Data Validation");
+ DataValidationHelper dvHelper = sheet.getDataValidationHelper();
+ DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(
+ new String[]{"13", "23", "33"});
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ DataValidation validation = dvHelper.createValidation(
+ dvConstraint, addressList);
+ // Note the check on the actual type of the DataValidation object.
+ // If it is an instance of the XSSFDataValidation class then the
+ // boolean value 'false' must be passed to the setSuppressDropDownArrow()
+ // method and an explicit call made to the setShowErrorBox() method.
+ if(validation instanceof XSSFDataValidation) {
+ validation.setSuppressDropDownArrow(true);
+ validation.setShowErrorBox(true);
+ }
+ else {
+ // If the Datavalidation contains an instance of the HSSFDataValidation
+ // class then 'true' should be passed to the setSuppressDropDownArrow()
+ // method and the call to setShowErrorBox() is not necessary.
+ validation.setSuppressDropDownArrow(false);
+ }
+ sheet.addValidationData(validation);
+</source>
+
+<p><strong>Prompts and Error Messages:</strong></p>
+<p>
+These both exactly mirror the hssf.usermodel so please refer to the 'Messages On Error:' and 'Prompts:' sections above.
+</p>
+<p>
+As the differences between the ss.usermodel and xssf.usermodel examples are small -
+restricted largely to the way the DataValidationHelper is obtained, the lack of any
+need to explicitly cast data types and the small difference in behaviour between
+the hssf and xssf interpretation of the setSuppressDropDowmArrow() method,
+no further examples will be included in this section.
+</p>
+<p><strong>Advanced Data Validations.</strong></p>
+<p><strong>Dependent Drop Down Lists.</strong></p>
+<p>
+In some cases, it may be necessary to present to the user a sheet which contains more than one drop down list.
+Further, the choice the user makes in one drop down list may affect the options that are presented to them in
+the second or subsequent drop down lists. One technique that may be used to implement this behaviour will now be explained.
+</p>
+<p>
+There are two keys to the technique; one is to use named areas or regions of cells to hold the data for the drop down lists,
+the second is to use the INDIRECT() function to convert between the name and the actual addresses of the cells.
+In the example section there is a complete working example- called LinkedDropDownLists.java -
+that demonstrates how to create linked or dependent drop down lists. Only the more relevant points are explained here.
+</p>
+<p>
+To create two drop down lists where the options shown in the second depend upon the selection made in the first,
+begin by creating a named region of cells to hold all of the data for populating the first drop down list.
+Next, create a data validation that will look to this named area for its data, something like this;
+</p>
+<source>
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
+ DataValidationHelper dvHelper = sheet.getDataValidationHelper();
+ DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(
+ "CHOICES");
+ DataValidation validation = dvHelper.createValidation(
+ dvConstraint, addressList);
+ sheet.addValidationData(validation);
+</source>
+<p>
+Note that the name of the area - in the example above it is 'CHOICES' -
+is simply passed to the createFormulaListConstraint() method. This is sufficient
+to cause Excel to populate the drop down list with data from that named region.
+</p>
+<p>
+Next, for each of the options the user could select in the first drop down list,
+create a matching named region of cells. The name of that region should match the
+text the user could select in the first drop down list. Note, in the example,
+all upper case letters are used in the names of the regions of cells.
+</p>
+
+<p>
+Now, very similar code can be used to create a second, linked, drop down list;
+</p>
+
+<source>
+ CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 1, 1);
+ DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(
+ "INDIRECT(UPPER($A$1))");
+ DataValidation validation = dvHelper.createValidation(
+ dvConstraint, addressList);
+ sheet.addValidationData(validation);
+</source>
+
+<p>
+The key here is in the following Excel function - INDIRECT(UPPER($A$1)) - which is used to populate the second,
+linked, drop down list. Working from the inner-most pair of brackets, it instructs Excel to look
+at the contents of cell A1, to convert what it reads there into upper case – as upper case letters are used
+in the names of each region - and then convert this name into the addresses of those cells that contain
+the data to populate another drop down list.
+</p>
+ </section>
+ </section>
+ <anchor id="Embedded"/>
+ <section><title>Embedded Objects</title>
+ <p>It is possible to perform more detailed processing of an embedded Excel, Word or PowerPoint document,
+ or to work with any other type of embedded object.</p>
+ <p><strong>HSSF:</strong></p>
+ <source>
+ POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("excel_with_embeded.xls"));
+ HSSFWorkbook workbook = new HSSFWorkbook(fs);
+ for (HSSFObjectData obj : workbook.getAllEmbeddedObjects()) {
+ //the OLE2 Class Name of the object
+ String oleName = obj.getOLE2ClassName();
+ if (oleName.equals("Worksheet")) {
+ DirectoryNode dn = (DirectoryNode) obj.getDirectory();
+ HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(dn, fs, false);
+ //System.out.println(entry.getName() + ": " + embeddedWorkbook.getNumberOfSheets());
+ } else if (oleName.equals("Document")) {
+ DirectoryNode dn = (DirectoryNode) obj.getDirectory();
+ HWPFDocument embeddedWordDocument = new HWPFDocument(dn, fs);
+ //System.out.println(entry.getName() + ": " + embeddedWordDocument.getRange().text());
+ } else if (oleName.equals("Presentation")) {
+ DirectoryNode dn = (DirectoryNode) obj.getDirectory();
+ SlideShow embeddedPowerPointDocument = new SlideShow(new HSLFSlideShow(dn, fs));
+ //System.out.println(entry.getName() + ": " + embeddedPowerPointDocument.getSlides().length);
+ } else {
+ if(obj.hasDirectoryEntry()){
+ // The DirectoryEntry is a DocumentNode. Examine its entries to find out what it is
+ DirectoryNode dn = (DirectoryNode) obj.getDirectory();
+ for (Iterator entries = dn.getEntries(); entries.hasNext();) {
+ Entry entry = (Entry) entries.next();
+ //System.out.println(oleName + "." + entry.getName());
+ }
+ } else {
+ // There is no DirectoryEntry
+ // Recover the object's data from the HSSFObjectData instance.
+ byte[] objectData = obj.getObjectData();
+ }
+ }
+ }
+ </source>
+ <p><strong>XSSF:</strong></p>
+ <source>
+ XSSFWorkbook workbook = new XSSFWorkbook("excel_with_embeded.xlsx");
+ for (PackagePart pPart : workbook.getAllEmbedds()) {
+ String contentType = pPart.getContentType();
+ // Excel Workbook - either binary or OpenXML
+ if (contentType.equals("application/vnd.ms-excel")) {
+ HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(pPart.getInputStream());
+ }
+ // Excel Workbook - OpenXML file format
+ else if (contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
+ OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());
+ XSSFWorkbook embeddedWorkbook = new XSSFWorkbook(docPackage);
+ }
+ // Word Document - binary (OLE2CDF) file format
+ else if (contentType.equals("application/msword")) {
+ HWPFDocument document = new HWPFDocument(pPart.getInputStream());
+ }
+ // Word Document - OpenXML file format
+ else if (contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) {
+ OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());
+ XWPFDocument document = new XWPFDocument(docPackage);
+ }
+ // PowerPoint Document - binary file format
+ else if (contentType.equals("application/vnd.ms-powerpoint")) {
+ HSLFSlideShow slideShow = new HSLFSlideShow(pPart.getInputStream());
+ }
+ // PowerPoint Document - OpenXML file format
+ else if (contentType.equals("application/vnd.openxmlformats-officedocument.presentationml.presentation")) {
+ OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());
+ XSLFSlideShow slideShow = new XSLFSlideShow(docPackage);
+ }
+ // Any other type of embedded object.
+ else {
+ System.out.println("Unknown Embedded Document: " + contentType);
+ InputStream inputStream = pPart.getInputStream();
+ }
+ }
+ </source>
+ </section>
+ <anchor id="Autofilter"/>
+ <p>(Since POI-3.7)</p>
+ <section><title>Autofilters</title>
+ <source>
+ Workbook wb = new HSSFWorkbook(); //or new XSSFWorkbook();
+ Sheet sheet = wb.createSheet();
+ sheet.setAutoFilter(CellRangeAddress.valueOf("C5:F200"));
+ </source>
+ </section>
+ <anchor id="ConditionalFormatting"/>
+ <section><title>Conditional Formatting</title>
+ <source>
+ Workbook workbook = new HSSFWorkbook(); // or new XSSFWorkbook();
+ Sheet sheet = workbook.createSheet();
+
+ SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
+
+ ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.EQUAL, "0");
+ FontFormatting fontFmt = rule1.createFontFormatting();
+ fontFmt.setFontStyle(true, false);
+ fontFmt.setFontColorIndex(IndexedColors.DARK_RED.index);
+
+ BorderFormatting bordFmt = rule1.createBorderFormatting();
+ bordFmt.setBorderBottom(BorderFormatting.BORDER_THIN);
+ bordFmt.setBorderTop(BorderFormatting.BORDER_THICK);
+ bordFmt.setBorderLeft(BorderFormatting.BORDER_DASHED);
+ bordFmt.setBorderRight(BorderFormatting.BORDER_DOTTED);
+
+ PatternFormatting patternFmt = rule1.createPatternFormatting();
+ patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index);
+
+ ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "-10", "10");
+ ConditionalFormattingRule [] cfRules =
+ {
+ rule1, rule2
+ };
+
+ CellRangeAddress[] regions = {
+ CellRangeAddress.valueOf("A3:A5")
+ };
+
+ sheetCF.addConditionalFormatting(regions, cfRules);
+ </source>
+ <p> See more examples on Excel conditional formatting in
+ <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java">ConditionalFormats.java</link>
+ </p>
+
+ </section>
+ <anchor id="Hiding"/>
+ <section><title>Hiding and Un-Hiding Rows</title>
+ <p>
+ Using Excel, it is possible to hide a row on a worksheet by selecting that row (or rows),
+ right clicking once on the right hand mouse button and selecting 'Hide' from the pop=up menu that appears.
+ </p>
+ <p>
+ To emulate this using POI, simply call the setZeroHeight() method on an instance of either
+ XSSFRow or HSSFRow (the method is defined on the ss.usermodel.Row interface that both classes implement), like this:
+ </p>
+ <source>
+ Workbook workbook = new XSSFWorkbook(); // OR new HSSFWorkbook()
+ Sheet sheet = workbook.createSheet(0);
+ Row row = workbook.createRow(0);
+ row.setZeroHeight();
+ </source>
+ <p>
+ If the file were saved away to disc now, then the first row on the first sheet would not be visible.
+ </p>
+ <p>
+ Using Excel, it is possible to unhide previously hidden rows by selecting the row above and the row below
+ the one that is hidden and then pressing and holding down the Ctrl key, the Shift and the pressing
+ the number 9 before releasing them all.
+ </p>
+ <p>
+ To emulate this behaviour using POI do something like this:
+ </p>
+ <source>
+ Workbook workbook = WorkbookFactory.create(new File(.......));
+ Sheet = workbook.getSheetAt(0);
+ Iterator<Row> row Iter = sheet.iterator();
+ while(rowIter.hasNext()) {
+ Row row = rowIter.next();
+ if(row.getZeroHeight()) {
+ row.setZeroHeight(false);
+ }
+ }
+ </source>
+ <p>
+ If the file were saved away to disc now, any previously hidden rows on the first sheet of the workbook would now be visible.
+ </p>
+ <p>
+ The example illustrates two features. Firstly, that it is possible to unhide a row simply by calling the setZeroHeight()
+ method and passing the boolean value 'false'. Secondly, it ilustrates how to test whther a row is hidden or not.
+ Simply call the getZeroHeight() method and it will return 'true' if the row is hidden, 'false' otherwise.
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Record Generator HOWTO</title>
+ <authors>
+ <person email="user@poi.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</title>
+
+ <section><title>History</title>
+ <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 and repetitive work.
+ </p>
+ </section>
+
+ <section><title>Capabilities</title>
+ <p>
+ The record generator takes XML as input and produces the following
+ output:
+ </p>
+ <ul>
+ <li>A Java file capabile of decoding and encoding the record.</li>
+ <li>A test class that provides a fill-in-the-blanks implementation
+ of a test case for ensuring the record operates as
+ designed.</li>
+ </ul>
+ </section>
+ <section><title>Usage</title>
+ <p>
+ The record generator is invoked as an Ant target
+ (generate-records). It goes through looking for all files in
+ <code>src/records/defintitions</code> 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"
+ excel-record-id="FRAME">
+ <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>
+ The following table details the allowable types and sizes for
+ the fields.
+ </p>
+ <table>
+ <tr>
+ <th>Type</th>
+ <th>Size</th>
+ <th>Java Type</th>
+ </tr>
+ <tr>
+ <td>int</td>
+ <td>1</td>
+ <td>byte</td>
+ </tr>
+ <tr>
+ <td>int</td>
+ <td>2</td>
+ <td>short</td>
+ </tr>
+ <tr>
+ <td>int</td>
+ <td>4</td>
+ <td>int</td>
+ </tr>
+ <tr>
+ <td>int</td>
+ <td>8</td>
+ <td>long</td>
+ </tr>
+ <tr>
+ <td>int</td>
+ <td>varword</td>
+ <td>array of shorts</td>
+ </tr>
+ <tr>
+ <td>bits</td>
+ <td>1</td>
+ <td>A byte comprising of a bits (defined by the bit element)
+ </td>
+ </tr>
+ <tr>
+ <td>bits</td>
+ <td>2</td>
+ <td>An short comprising of a bits</td>
+ </tr>
+ <tr>
+ <td>bits</td>
+ <td>4</td>
+ <td>A int comprising of a bits</td>
+ </tr>
+ <tr>
+ <td>float</td>
+ <td>8</td>
+ <td>double</td>
+ </tr>
+ <tr>
+ <td>hbstring</td>
+ <td>java expression</td>
+ <td>String</td>
+ </tr>
+ </table>
+ <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>Custom Field Types</title>
+ <p>
+ Occationally the builtin types are not enough. More control
+ over the encoding and decoding of the streams is required. This
+ can be achieved using a custom type.
+ </p>
+ <p>
+ A custom type lets you escape to java to define the way in which
+ the field encodes and decodes. To code a custom type you
+ declare your field like this:
+ </p>
+ <source><![CDATA[
+ <field type="custom:org.apache.poi.hssf.record.LinkedDataFormulaField"
+ size="var" name="formula of link" description="formula"/>
+ ]]></source>
+ <p>
+ Where the class name specified after <code>custom:</code> is a
+ class implementing the interface <code>CustomField</code>.
+ </p>
+ <p>
+ You can then implement the encoding yourself.
+ </p>
+ </section>
+ <section><title>How it Works</title>
+ <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>
+ <p>
+ There is a corresponding "type" generator for HWPF.
+ See the HWPF documentation for details.
+ </p>
+ </section>
+ <section><title>Limitations</title>
+ <p>
+ The record generator does not handle all possible record types and
+ goes not intend to perform this function. When dealing with a
+ non-standard record sometimes the cost-benifit of coding the
+ record by hand will be greater than attempting modify the
+ generator. The main point of the record generator is to save
+ time, so keep that in mind.
+ </p>
+ <p>
+ Currently the the XSL file that generates the record calls out to
+ Java objects. The Java code for the record generation is
+ currently quite messy with minimal comments.
+ </p>
+ </section>
+</section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!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</title>
+ <section><title>Use Case 1: Read existing HSSF</title>
+
+<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 "Workbook"
+ 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</title>
+
+<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 "Workbook" 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</title>
+
+<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</title>
+<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 "Workbook" 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</title>
+
+
+<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 "Workbook"
+ file (POIFS use case 8, read file system directory)</li>
+ <li>If "Workbook" 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 "Workbook" (POIFS use case 6,
+ write new file to file system)</li>
+</ol>
+<p><strong>Extensions:</strong>None</p>
+</section>
+
+</section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>User Defined Functions</title>
+ <authors>
+ <person email="jon@loquatic.com" name="Jon Svede" id="JDS"/>
+ <person email="brian.bush@nrel.gov" name="Brian Bush" id="BWB"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>How to Create and Use User Defined Functions</title>
+
+ <section><title>Description</title>
+ <p>This document describes the User Defined Functions within POI.
+ User defined functions allow you to take code that is written in VBA
+ and re-write in Java and use within POI. Consider the following example.</p>
+ </section>
+ <section><title>An Example</title>
+ <p>Suppose you are given a spreadsheet that can calculate the principal and interest
+ payments for a mortgage. The user enters the principal loan amount, the interest rate
+ and the term of the loan. The Excel spreadsheet does the rest.</p>
+ <p>
+ <img src="../resources/images/simple-xls-with-function.jpg" alt="mortgage calculation spreadsheet"/>
+ </p>
+ <p>When you actually look at the workbook you discover that rather than having
+ the formula in a cell it has been written as VBA function. You review the
+ function and determine that it could be written in Java:</p>
+ <p>
+ <img src="../resources/images/calculatePayment.jpg" alt="VBA code"/>
+ </p>
+ <p>If we write a small program to try to evaluate this cell, we'll fail. Consider this source code:</p>
+ <source><![CDATA[
+import java.io.File ;
+import java.io.FileInputStream ;
+import java.io.FileNotFoundException ;
+import java.io.IOException ;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException ;
+import org.apache.poi.ss.formula.functions.FreeRefFunction ;
+import org.apache.poi.ss.formula.udf.AggregatingUDFFinder ;
+import org.apache.poi.ss.formula.udf.DefaultUDFFinder ;
+import org.apache.poi.ss.formula.udf.UDFFinder ;
+import org.apache.poi.ss.usermodel.Cell ;
+import org.apache.poi.ss.usermodel.CellValue ;
+import org.apache.poi.ss.usermodel.Row ;
+import org.apache.poi.ss.usermodel.Sheet ;
+import org.apache.poi.ss.usermodel.Workbook ;
+import org.apache.poi.ss.usermodel.WorkbookFactory ;
+import org.apache.poi.ss.util.CellReference ;
+
+public class Evaluator {
+
+
+
+ public static void main( String[] args ) {
+
+ System.out.println( "fileName: " + args[0] ) ;
+ System.out.println( "cell: " + args[1] ) ;
+
+ File workbookFile = new File( args[0] ) ;
+
+ try {
+ FileInputStream fis = new FileInputStream(workbookFile);
+ Workbook workbook = WorkbookFactory.create(fis);
+
+ FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
+
+ CellReference cr = new CellReference( args[1] ) ;
+ String sheetName = cr.getSheetName() ;
+ Sheet sheet = workbook.getSheet( sheetName ) ;
+ int rowIdx = cr.getRow() ;
+ int colIdx = cr.getCol() ;
+ Row row = sheet.getRow( rowIdx ) ;
+ Cell cell = row.getCell( colIdx ) ;
+
+ CellValue value = evaluator.evaluate( cell ) ;
+
+ System.out.println("returns value: " + value ) ;
+
+
+ } catch( FileNotFoundException e ) {
+ e.printStackTrace();
+ } catch( InvalidFormatException e ) {
+ e.printStackTrace();
+ } catch( IOException e ) {
+ e.printStackTrace();
+ }
+ }
+}
+
+]]></source>
+ <p>If you run this code, you're likely to get the following error:</p>
+
+ <source><![CDATA[
+Exception in thread "main" org.apache.poi.ss.formula.eval.NotImplementedException: Error evaluating cell Sheet1!B4
+ at org.apache.poi.ss.formula.WorkbookEvaluator.addExceptionInfo(WorkbookEvaluator.java:321)
+ at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateAny(WorkbookEvaluator.java:288)
+ at org.apache.poi.ss.formula.WorkbookEvaluator.evaluate(WorkbookEvaluator.java:221)
+ at org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.evaluateFormulaCellValue(HSSFFormulaEvaluator.java:320)
+ at org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.evaluate(HSSFFormulaEvaluator.java:182)
+ at poi.tests.Evaluator.main(Evaluator.java:61)
+Caused by: org.apache.poi.ss.formula.eval.NotImplementedException: calculatePayment
+ at org.apache.poi.ss.formula.UserDefinedFunction.evaluate(UserDefinedFunction.java:59)
+ at org.apache.poi.ss.formula.OperationEvaluatorFactory.evaluate(OperationEvaluatorFactory.java:129)
+ at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateFormula(WorkbookEvaluator.java:456)
+ at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateAny(WorkbookEvaluator.java:279)
+ ... 4 more
+
+]]></source>
+
+ <p>How would we make it so POI can use this sheet?</p>
+ </section>
+
+ <section><title>Defining Your Function</title>
+ <p>To 'convert' this code to Java and make it available to POI you need to implement
+ a FreeRefFunction instance. FreeRefFunction is an interface in the org.apache.poi.ss.formula.functions
+ package. This interface defines one method, evaluate(ValueEval[] args, OperationEvaluationContext ec),
+ which is how you will receive the argument values from POI.</p>
+ <p>The evaluate() method as defined above is where you will convert the ValueEval instances to the
+ proper number types. The following code snippet shows you how to get your values:</p>
+
+ <source><![CDATA[
+public class CalculateMortgage implements FreeRefFunction {
+
+@Override
+public ValueEval evaluate( ValueEval[] args, OperationEvaluationContext ec ) {
+ if (args.length != 3) {
+ return ErrorEval.VALUE_INVALID;
+ }
+
+ double principal, rate, years, result;
+ try {
+ ValueEval v1 = OperandResolver.getSingleValue( args[0],
+ ec.getRowIndex(),
+ ec.getColumnIndex() ) ;
+ ValueEval v2 = OperandResolver.getSingleValue( args[1],
+ ec.getRowIndex(),
+ ec.getColumnIndex() ) ;
+ ValueEval v3 = OperandResolver.getSingleValue( args[2],
+ ec.getRowIndex(),
+ ec.getColumnIndex() ) ;
+
+ principal = OperandResolver.coerceValueToDouble( v1 ) ;
+ rate = OperandResolver.coerceValueToDouble( v2 ) ;
+ years = OperandResolver.coerceValueToDouble( v3 ) ;
+ ]]></source>
+
+ <p>The first thing we do is check the number of arguments being passed since there is no sense
+ in attempting to go further if you are missing critical information.</p>
+ <p>Next we declare our variables, in our case we need variables for:</p>
+ <ul>
+ <li>principal - the amount of the loan</li>
+ <li>rate - the interest rate as a decimal</li>
+ <li>years - the length of the loan in years</li>
+ <li>result - the result of the calculation</li>
+ </ul>
+ <p>Next, we use the OperandResolver to convert the ValueEval instances to doubles, though not directly.
+ First we start by getting discreet values. Using the OperandResolver.getSingleValue() method
+ we retrieve each of the values passed in by the cell in the spreadsheet. Next, we use the
+ OperandResolver again to convert the ValueEval instances to doubles, in this case. This
+ class has other methods of coercion for gettings Strings, ints and booleans. Now that we've
+ got our primitive values we can move on to calculating the value.</p>
+ <p>As shown previously, we have the VBA source. We need to add code to our class to calculate
+ the payment. To do this you could simply add it to the method we've already created but I've
+ chosen to add it as its own method. Add the following method: </p>
+ <source><![CDATA[
+public double calculateMortgagePayment( double p, double r, double y ) {
+
+ double i = r / 12 ;
+ double n = y * 12 ;
+
+ double principalAndInterest =
+ p * (( i * Math.pow((1 + i),n ) ) / ( Math.pow((1 + i),n) - 1)) ;
+
+ return principalAndInterest ;
+}
+ ]]></source>
+ <p>The biggest change necessary is related to the exponents; Java doesn't have a notation for this
+ so we had to add calls to Math.pow(). Now we need to add this call to our previous method:</p>
+ <source><![CDATA[
+ result = calculateMortgagePayment( principal, rate, years ) ;
+ ]]></source>
+ <p>Having done that, the last things we need to do are to check to make sure we didn't get a bad result and,
+ if not, we need to return the value. Add the following code to the class:</p>
+ <source><![CDATA[
+private void checkValue(double result) throws EvaluationException {
+ if (Double.isNaN(result) || Double.isInfinite(result)) {
+ throw new EvaluationException(ErrorEval.NUM_ERROR);
+ }
+}
+ ]]></source>
+ <p>Then add a line of code to our evaluate method to call this new static method, complete our try/catch and return the value:</p>
+ <source><![CDATA[
+ checkValue(result);
+
+ } catch (EvaluationException e) {
+ e.printStackTrace() ;
+ return e.getErrorEval();
+ }
+
+ return new NumberEval( result ) ;
+ ]]></source>
+
+ <p>So the whole class would be as follows:</p>
+
+ <source><![CDATA[
+import org.apache.poi.ss.formula.OperationEvaluationContext ;
+import org.apache.poi.ss.formula.eval.ErrorEval ;
+import org.apache.poi.ss.formula.eval.EvaluationException ;
+import org.apache.poi.ss.formula.eval.NumberEval ;
+import org.apache.poi.ss.formula.eval.OperandResolver ;
+import org.apache.poi.ss.formula.eval.ValueEval ;
+import org.apache.poi.ss.formula.functions.FreeRefFunction ;
+
+/**
+ * A simple function to calculate principal and interest.
+ *
+ * @author Jon Svede
+ *
+ */
+public class CalculateMortgage implements FreeRefFunction {
+
+ @Override
+ public ValueEval evaluate( ValueEval[] args, OperationEvaluationContext ec ) {
+ if (args.length != 3) {
+ return ErrorEval.VALUE_INVALID;
+ }
+
+ double principal, rate, years, result;
+ try {
+ ValueEval v1 = OperandResolver.getSingleValue( args[0],
+ ec.getRowIndex(),
+ ec.getColumnIndex() ) ;
+ ValueEval v2 = OperandResolver.getSingleValue( args[1],
+ ec.getRowIndex(),
+ ec.getColumnIndex() ) ;
+ ValueEval v3 = OperandResolver.getSingleValue( args[2],
+ ec.getRowIndex(),
+ ec.getColumnIndex() ) ;
+
+ principal = OperandResolver.coerceValueToDouble( v1 ) ;
+ rate = OperandResolver.coerceValueToDouble( v2 ) ;
+ years = OperandResolver.coerceValueToDouble( v3 ) ;
+
+ result = calculateMortgagePayment( principal, rate, years ) ;
+
+ checkValue(result);
+
+ } catch (EvaluationException e) {
+ e.printStackTrace() ;
+ return e.getErrorEval();
+ }
+
+ return new NumberEval( result ) ;
+ }
+
+ public double calculateMortgagePayment( double p, double r, double y ) {
+ double i = r / 12 ;
+ double n = y * 12 ;
+
+ //M = P [ i(1 + i)n ] / [ (1 + i)n - 1]
+ double principalAndInterest =
+ p * (( i * Math.pow((1 + i),n ) ) / ( Math.pow((1 + i),n) - 1)) ;
+
+ return principalAndInterest ;
+ }
+
+ /**
+ * Excel does not support infinities and NaNs, rather, it gives a #NUM! error in these cases
+ *
+ * @throws EvaluationException (#NUM!) if <tt>result</tt> is <tt>NaN</> or <tt>Infinity</tt>
+ */
+ static final void checkValue(double result) throws EvaluationException {
+ if (Double.isNaN(result) || Double.isInfinite(result)) {
+ throw new EvaluationException(ErrorEval.NUM_ERROR);
+ }
+ }
+
+}
+
+ ]]></source>
+
+ <p>Great! Now we need to go back to our original program that failed to evaluate our cell and add code that will allow it run our new Java code.</p>
+
+ </section>
+
+ <section><title>Registering Your Function</title>
+ <p>Now we need to register our function in the Workbook, so that the Formula Evaluator can resolve the name "calculatePayment"
+and map it to the actual implementation (CalculateMortgage). This is done using the UDFFinder object.
+The UDFFinder manages FreeRefFunctions which are our analogy for the VBA code. We need to create a UDFFinder. There are
+ a few things we need to know in order to do this:</p>
+ <ul>
+ <li>The name of the function in the VBA code (in our case it is calculatePayment)</li>
+ <li>The Class name of our FreeRefFunction</li>
+ </ul>
+ <p>UDFFinder is actually an interface, so we need to use an actual implementation of this interface. Therefore we use the org.apache.poi.ss.formula.udf.DefaultUDFFinder class. If you refer to the Javadocs you'll see that this class expects to get two arrays, one
+ containing the alias and the other containing an instance of the class that will represent that alias. In our case our alias will be calculatePayment
+ and our class instance will be of the CalculateMortgage type. This class needs to be available at compile and runtime. Be sure to keep these arrays
+ well organized because you'll run into problems if these arrays are of different sizes or the alias aren't in the same relative position in their respective
+ arrays. Add the following code:</p>
+ <source><![CDATA[
+String[] functionNames = { "calculatePayment" } ;
+FreeRefFunction[] functionImpls = { new CalculateMortgage() } ;
+
+UDFFinder udfs = new DefaultUDFFinder( functionNames, functionImpls ) ;
+UDFFinder udfToolpack = new AggregatingUDFFinder( udfs ) ;
+ ]]></source>
+ <p>Now we have our UDFFinder instance and we've created the AggregatingUDFFinder instance. The last step is to pass this to our Workbook:</p>
+
+ <source><![CDATA[
+workbook.addToolPack(udfToolpack);
+ ]]></source>
+ <p>So now the whole class will look like this:</p>
+ <source><![CDATA[
+import java.io.File ;
+import java.io.FileInputStream ;
+import java.io.FileNotFoundException ;
+import java.io.IOException ;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException ;
+import org.apache.poi.ss.formula.functions.FreeRefFunction ;
+import org.apache.poi.ss.formula.udf.AggregatingUDFFinder ;
+import org.apache.poi.ss.formula.udf.DefaultUDFFinder ;
+import org.apache.poi.ss.formula.udf.UDFFinder ;
+import org.apache.poi.ss.usermodel.Cell ;
+import org.apache.poi.ss.usermodel.CellValue ;
+import org.apache.poi.ss.usermodel.Row ;
+import org.apache.poi.ss.usermodel.Sheet ;
+import org.apache.poi.ss.usermodel.Workbook ;
+import org.apache.poi.ss.usermodel.WorkbookFactory ;
+import org.apache.poi.ss.util.CellReference ;
+
+public class Evaluator {
+
+ public static void main( String[] args ) {
+
+ System.out.println( "fileName: " + args[0] ) ;
+ System.out.println( "cell: " + args[1] ) ;
+
+ File workbookFile = new File( args[0] ) ;
+
+ try {
+ FileInputStream fis = new FileInputStream(workbookFile);
+ Workbook workbook = WorkbookFactory.create(fis);
+
+ String[] functionNames = { "calculatePayment" } ;
+ FreeRefFunction[] functionImpls = { new CalculateMortgage() } ;
+
+ UDFFinder udfs = new DefaultUDFFinder( functionNames, functionImpls ) ;
+ UDFFinder udfToolpack = new AggregatingUDFFinder( udfs ) ;
+
+ workbook.addToolPack(udfToolpack);
+
+ FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
+
+ CellReference cr = new CellReference( args[1] ) ;
+ String sheetName = cr.getSheetName() ;
+ Sheet sheet = workbook.getSheet( sheetName ) ;
+ int rowIdx = cr.getRow() ;
+ int colIdx = cr.getCol() ;
+ Row row = sheet.getRow( rowIdx ) ;
+ Cell cell = row.getCell( colIdx ) ;
+
+ CellValue value = evaluator.evaluate( cell ) ;
+
+ System.out.println("returns value: " + value ) ;
+
+
+ } catch( FileNotFoundException e ) {
+ e.printStackTrace();
+ } catch( InvalidFormatException e ) {
+ e.printStackTrace();
+ } catch( IOException e ) {
+ e.printStackTrace();
+ }
+ }
+}
+
+ ]]></source>
+ <p>Now that our evaluator is aware of the UDFFinder which in turn is aware of our FreeRefFunction, we're ready to re-run our example:</p>
+ <source>Evaluator mortgage-calculation.xls Sheet1!B4</source>
+ <p>which prints the following output in the console:</p>
+ <source><![CDATA[
+fileName: mortgage-calculation.xls
+cell: Sheet1!B4
+returns value: org.apache.poi.ss.usermodel.CellValue [790.7936267415464]
+ ]]></source>
+ <p>That is it! Now you can create Java code and register it, allowing your POI based appliction to run spreadsheets that previously were inaccessible.</p>
+ <p>This example can be found in the <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/formula">src/examples/src/org/apache/poi/ss/examples/formula</link> folder in the source.</p>
+ </section>
+ </section>
+</body>
+</document>
+
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<status>
+ <developers>
+ <!-- in strict alphabetical order -->
+ <person id="AB" name="Andreas Beeker" email="kiwiwings@apache.org"/>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver2@users.sourceforge.net"/>
+ <person id="DS" name="Dominik Stadler" email="centic@apache.org"/>
+ <person id="GJS" name="Glen Stampoultzis" email="user@poi.apache.org"/>
+ <person id="JM" name="Josh Micich" email="josh@apache.org"/>
+ <person id="MJ" name="Marc Johnson" email="mjohnson@apache.org"/>
+ <person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ <person id="NB" name="Nick Burch" email="nick@torchbox.com"/>
+ <person id="POI-DEVELOPERS" name="POI Developers" email="dev@poi.apache.org"/>
+ <person id="RK" name="Rainer Klute" email="klute@apache.org"/>
+ <person id="UC" name="Ugo Cei" email="ugo@apache.org"/>
+ <person id="YK" name="Yegor Kozlov" email="yegor@apache.org"/>
+ </developers>
+
+ <changes>
+ <release version="3.11-beta1" date="2014-??-??">
+ </release>
+ <release version="3.10-FINAL" date="2014-02-08">
+ <action dev="poi-developers" type="fix">51585 - WorkbookFactory.create() hangs when creating a workbook</action>
+ <action dev="poi-developers" type="add">55873 - Support for COUNTIFS function</action>
+ <action dev="poi-developers" type="fix">55723 - Inconsistent behavior in HSSFSheet.setAutoFilter() function, also make XSSF work when setAutoFilter is called multiple times</action>
+ <action dev="poi-developers" type="fix">51158 - Writing a workbook multiple times produces unreadable content</action>
+ <action dev="poi-developers" type="fix">45776 - Fix corrupt file problem using TextRun.setText</action>
+ <action dev="poi-developers" type="fix">41246 - AIOOBE with missing notes entries</action>
+ <action dev="poi-developers" type="fix">48593 - Multiple Saves Causes Slide Corruption</action>
+ <action dev="poi-developers" type="add">55579 - Support embedding OLE objects into HSLF</action>
+ <action dev="poi-developers" type="add">55818 - Add encryption support</action>
+ <action dev="poi-developers" type="fix">55731 - Fix StringBuilder logic in DataFormatter.cleanFormatForNumber </action>
+ <action dev="poi-developers" type="fix">55730 - Fix org.apache.poi.ss.usermodel.BuiltinFormats.java for 0x29-0x2c </action>
+ <action dev="poi-developers" type="fix">55901 - Avoid using RMI based exception from PropertySetFactory, as it's not needed nor helpful</action>
+ <action dev="poi-developers" type="fix">55850 - Fix NullPointerException during Xml-extraction from xslx</action>
+ <action dev="poi-developers" type="fix">55640 - Avoid IndexOutOfboundsException when setting nested row grouping</action>
+ <action dev="poi-developers" type="fix">55745 - fix handling of tables in XSSF if there are comments as well</action>
+ <action dev="poi-developers" type="add">55560 - Patch for hiding slides in HSLF</action>
+ <action dev="poi-developers" type="fix">53176 - Fixed auto shapes render problem in pptx files</action>
+ <action dev="poi-developers" type="add">55661 - CellStyle support for get/set Shrink To Fit</action>
+ <action dev="poi-developers" type="fix">49237 - HSSF Row Style XfIndex is 12 not 16 bits of data</action>
+ <action dev="poi-developers" type="fix">53475 - OOXML encrypted document fix for cspname being optional</action>
+ <action dev="poi-developers" type="fix">55733 - XWPFWordExtractor needs to handle .docx files with neither headers nor footers</action>
+ <action dev="poi-developers" type="fix">55729 - DataFormatter should format Error cells, returning the Excel error string</action>
+ <action dev="poi-developers" type="add">55612 - Performance improvement in HSSFCellStyle.getDataFormatString()</action>
+ <action dev="poi-developers" type="add">55611 - Performance improvement in DateUtil.isADateFormat(int, String)</action>
+ <action dev="poi-developers" type="add">55578 - Support embedding OLE1.0 packages in HSSF</action>
+ <action dev="poi-developers" type="add">49658 - Support embedding EMF/WMF pictures in HSSF</action>
+ <action dev="poi-developers" type="fix">52400 - Fix handling some types of TNEF files</action>
+ <action dev="poi-developers" type="fix">54400 - Updating the index in the LinkTable whenever sheets are removed</action>
+ <action dev="poi-developers" type="fix">49940 - Apply patch to avoid XmlValueDisconnectedException when saving a file twice</action>
+ <action dev="poi-developers" type="add">55369 - Add support for collapsing rows in SXSSF</action>
+ <action dev="poi-developers" type="fix">55692 - Give a more helpful error if an Encrypted .xlsx file is passed to HSSF</action>
+ <action dev="poi-developers" type="fix">55650 - Avoid AIOOBE if a non-existant Xfs is requested for a style</action>
+ <action dev="poi-developers" type="fix">55658 - Don't fail in SXSSF if a numeric cell is overwritten with a string</action>
+ <action dev="poi-developers" type="fix">55341 - Constants for HAIR and DOTTED border styles are swapped</action>
+ <action dev="poi-developers" type="add">Add Eclipse project files</action>
+ <action dev="poi-developers" type="add">55647 - When creating a temp file, ensure the name isn't already taken</action>
+ <action dev="poi-developers" type="add">54722 - Extract text from HSLF tables</action>
+ <action dev="poi-developers" type="add">55544 - Support for SHA-512 hashes on OOXML protected documents, as used by Office 2013</action>
+ </release>
+ <release version="3.10-beta2" date="2013-09-19">
+ <action dev="poi-developers" type="fix">53798 - Add fix for XmlValueDisconnectException during shifting rows</action>
+ <action dev="poi-developers" type="fix">54524 - Fix handling of special case in FormulaShifter</action>
+ <action dev="poi-developers" type="fix">50298 - Fix corruption of Workbook when setting sheet order</action>
+ <action dev="poi-developers" type="fix">55419 - Fix SimpleFractionException when fraction goes to greater than overflow</action>
+ <action dev="poi-developers" type="add">54786 - Add support for quoting in date formatting</action>
+ <action dev="poi-developers" type="fix">52233 - Do not make the XSSFSheet invalid during write()</action>
+ <action dev="poi-developers" type="add">55195 - MultiOperandNumericFunction.collectValue() currently uses concrete final classes but should use interfaces instead</action>
+ <action dev="poi-developers" type="fix">55380 - Endless loop in CellRangeUtil.mergeRanges() when regions are overlapping</action>
+ <action dev="poi-developers" type="add">55347/45551 - Integrate 55292 into XSSF extractors -- extract text from text boxes in xlsx files</action>
+ <action dev="poi-developers" type="fix">55361/Tika 792 - Avoid CTMarkup NoSuchMethodException stack trace by adding two beans to ooxml-lite"</action>
+ <action dev="poi-developers" type="fix">55294 and 52186 - Fix column grouping in XSSF.</action>
+ <action dev="poi-developers" type="add">55292 - Enhancements to XSSFSimpleShape (textbox) including: ability to add multiple paragraphs, formatting (read/write) and text extraction.</action>
+ <action dev="poi-developers" type="fix">55191 - Avoid a ClassCastException if a HPSF string property isn't directly stored as a string</action>
+ <action dev="poi-developers" type="fix">HSMF ascii encoding detection should use the CodePage properties where available</action>
+ <action dev="poi-developers" type="fix">HSMF fixed length property parsing should be more forgiving of some type differences from the property default</action>
+ <action dev="poi-developers" type="fix">54233 - Some HPSF documents require UnicodeStrings to be 4-byte aligned, spot these from the otherwise invalid length</action>
+ <action dev="poi-developers" type="add">Upgrade version of JUnit to 4.11 to avoid problems when executing unit tests using Apache Ant >= 1.7</action>
+ </release>
+ <release version="3.10-beta1" date="2013-06-28">
+ <action dev="poi-developers" type="fix">54925 - Avoid issues if the length of a StyleTextPropAtom prop is longer than the parent text</action>
+ <action dev="poi-developers" type="fix">54564 - Fix error message text for a workbook with no sheets when a sheet operation is performed</action>
+ <action dev="poi-developers" type="fix">53972 - Presence of PLV record shouldn't affect HSSF Data Validation</action>
+ <action dev="poi-developers" type="fix">55142 - Not all XWPF SDT blocks need newlines</action>
+ <action dev="poi-developers" type="fix">54920 - XSSFDrawing.createCellComment causes CommentsTable to lose reference to comment in cell A1</action>
+ <action dev="poi-developers" type="fix">54982 - ExtractorFactory does not close files when extracting via OCPPackage.open()</action>
+ <action dev="poi-developers" type="fix">54607 - NullPointerException in XSSFSheet.getTopRow() when the top row is 1</action>
+ <action dev="poi-developers" type="fix">54686 - Improve how DataFormatter handles fractions</action>
+ <action dev="poi-developers" type="fix">55066 - Don't load XWPF Footnotes twice</action>
+ <action dev="poi-developers" type="add">54849 - Controlled content/Form (Std/StdBlock) content</action>
+ <action dev="poi-developers" type="fix">github2 - HSSFWorkbook.getAllEmbeddedObjects() needs to recurse into container Shapes</action>
+ <action dev="poi-developers" type="add">github4 - Expose from XWPFParagraph the number level and format, if applied</action>
+ <action dev="poi-developers" type="add">github3 - Extract references from XWPF footnotes</action>
+ <action dev="poi-developers" type="fix">55053 - Update License links following ECMA site re-organisation</action>
+ <action dev="poi-developers" type="add">49658 - Support embedding EMF/WMF pictures in HSSF </action>
+ <action dev="poi-developers" type="add">55047 - REPT formula support </action>
+ <action dev="poi-developers" type="add">55042 - COMPLEX formula support </action>
+ <action dev="poi-developers" type="add">55041 - CODE formula support </action>
+ <action dev="poi-developers" type="fix">55001 - Support Unicode text (TextCharsAtom) in HSLF TextShape</action>
+ <action dev="poi-developers" type="fix">54682 - UnhandledDataStructure should sanity check before allocating, not after</action>
+ <action dev="poi-developers" type="add">54673 - Simple wildcard support in HLOOKUP, VOOLKUP, MATCH, COUNTIF </action>
+ <action dev="poi-developers" type="fix">54625 - Register user-defined functions in instance scope instead of static </action>
+ <action dev="poi-developers" type="fix">54469 - Support for financial functions IPMT and PPMT </action>
+ <action dev="poi-developers" type="fix">54407 - Avoid XmlValueDisconnectedException when merging slides </action>
+ <action dev="poi-developers" type="fix">54356 - Support of statistical function SLOPE</action>
+ <action dev="poi-developers" type="fix">54403 - Support of statistical function INTERCEPT</action>
+ <action dev="poi-developers" type="fix">54557 - Don't mis-detect format patterns like .000 as dates</action>
+ <action dev="poi-developers" type="fix">54506 - Support unusual .xls files with a BOOK directory entry (normally it is Workbook)</action>
+ <action dev="poi-developers" type="add">54508 - EDATE formula support</action>
+ <action dev="poi-developers" type="fix">53810 - NPOIFS fix for 0 not -1 padded partially used XBATs</action>
+ <action dev="poi-developers" type="fix">54402 - IfError handling of indirect references</action>
+ <action dev="poi-developers" type="add">53966 - IfError support (from Analysis Toolpak)</action>
+ <action dev="poi-developers" type="fix">53650 - Prevent unreadable content and disalow to overwrite rows from input template in SXSSF</action>
+ <action dev="poi-developers" type="fix">54228,53672 - Fixed XSSF to read cells with missing R attribute</action>
+ <action dev="poi-developers" type="fix">54206 - Ensure that shared formuals are updated when shifting rows in a spreadsheet</action>
+ <action dev="poi-developers" type="fix">Synchronize table headers with parent sheet in XSSF</action>
+ <action dev="poi-developers" type="fix">54210 - Fixed rendering text in flipped shapes in PPT2PNG and PPTX2PNG</action>
+ </release>
+ <release version="3.9" date="2012-12-03">
+ <action dev="poi-developers" type="fix">54188 - Avoid NPE in PPT2PNG</action>
+ <action dev="poi-developers" type="fix">52628 - Replace System.err info messages with a POILogger</action>
+ <action dev="poi-developers" type="fix">54137 - improved performance of DataFormatter with Fractions</action>
+ <action dev="poi-developers" type="fix">54099 - Ensure that CTHMerge and CTTcBorders go to poi-ooxml-schemas jar</action>
+ <action dev="poi-developers" type="fix">54111 - Fixed extracting text from table cells in HSLF</action>
+ <action dev="poi-developers" type="add">52583 - add support for drop-down lists in doc to html convertion</action>
+ <action dev="poi-developers" type="add">52863 - add workaround for files with broken CHP SPRMs</action>
+ <action dev="poi-developers" type="fix">53182 - Reading combined character styling and direct formatting of a character run</action>
+ <action dev="poi-developers" type="fix">52311 - Conversion to html : Problem in titles number </action>
+ <action dev="poi-developers" type="fix">53914 - TableRow#getTopBorder() return bottom's border</action>
+ <action dev="poi-developers" type="fix">53282 - Avoid exception when parsing OPC relationships with non-breaking spaces</action>
+ <action dev="poi-developers" type="fix">54016 - Avoid exception when parsing workbooks with DConRefRecord in row aggregate</action>
+ <action dev="poi-developers" type="fix">54008 - Fixed Ant build to support build directories with blanks</action>
+ <action dev="poi-developers" type="fix">53374 - Avoid exceptions when parsing hyperlinks of type "javascript://"</action>
+ <action dev="poi-developers" type="fix">53404 - Fixed compatibility bug with modifying xls files created by POI-3.6 and earlier</action>
+ <action dev="poi-developers" type="add">53979 - Support fetching properties of Numbered Lists from PPT files</action>
+ <action dev="poi-developers" type="add">53784 - Partial HSMF support for fixed sized properties</action>
+ <action dev="poi-developers" type="add">53943 - added method processSymbol() to allow converting word symbols </action>
+ <action dev="poi-developers" type="fix">53763 - avoid style mess when using HSSFOptimiser </action>
+ <action dev="poi-developers" type="fix">52972 - preserve leading / trailing spaces in SXSSF </action>
+ <action dev="poi-developers" type="fix">53965 - Fixed XmlValueOutOfRangeExceptio calling getDataValidations for custom validations with XSSFSheet </action>
+ <action dev="poi-developers" type="fix">53974 - Avoid NPE when constructing HSSFWorbook on Google App Engine</action>
+ <action dev="poi-developers" type="fix">53568 - Fixed null returned by XSSFPicture.getPictureData()</action>
+ <action dev="poi-developers" type="fix">53950 - fixed setForceFormulaRecalculation to reset workbook-level "manual" flag</action>
+ <action dev="poi-developers" type="fix">52211 - avoid unnessary re-coverting content types to US-ASCII, it can cause exceptions on ibm mainframes</action>
+ <action dev="poi-developers" type="fix">53568 - Set shapes anchors in XSSF when reading from existing drawings</action>
+ <action dev="poi-developers" type="add">HSSFOptimiser will now also tidy away un-used cell styles, in addition to duplicate styles</action>
+ <action dev="poi-developers" type="fix">53493 - Fixed memory and temporary file leak in SXSSF </action>
+ <action dev="poi-developers" type="fix">53780 - Fixed memory and temporary file leak in SXSSF </action>
+ <action dev="poi-developers" type="fix">53380 - ArrayIndexOutOfBounds Excetion parsing word 97 document. </action>
+ <action dev="poi-developers" type="fix">53434 - Subtotal is not return correct value. </action>
+ <action dev="poi-developers" type="fix">53642 - [PATCH] XLS formula evaluation logging </action>
+ <action dev="poi-developers" type="fix">53561 - Unexpected adding of drawings into a workbook </action>
+ <action dev="poi-developers" type="fix">53413 - [GSoC] Improved work with shapes. HSSF </action>
+ <action dev="poi-developers" type="fix">53361 - feature: enhancements in EscherAggregate </action>
+ <action dev="poi-developers" type="fix">53302 - [Patch] EscherAggregate does not handle Continue records </action>
+ <action dev="poi-developers" type="fix">53144 - First comment not cloned after cloneSheet() </action>
+ <action dev="poi-developers" type="fix">53028 - Broken auto fit row height in the cells with word wrap </action>
+ <action dev="poi-developers" type="fix">53010 - [GSoC2012] Improve drawing support in HSSF </action>
+ <action dev="poi-developers" type="fix">52764 - Unmodified cell comments disappear after HSSFWorkbook.write </action>
+ <action dev="poi-developers" type="fix">52300 - Corrupted File after cloneSheet() </action>
+ <action dev="poi-developers" type="fix">52272 - [PATCH] Inserting images on cloned sheet with images. </action>
+ <action dev="poi-developers" type="fix">51796 - The [EscherClientAnchorRecord] for object (eg: TextBox,Shape) may get lost. </action>
+ <action dev="poi-developers" type="fix">51683 - [HSSF] Improve support for Shapes and Shape Groups </action>
+ <action dev="poi-developers" type="fix">51676 - Using drawingPatriarch.createCellComment(anchor) leads to File error: data may have been lost </action>
+ <action dev="poi-developers" type="fix">51675 - Background images cause problems in HSSF spreadsheet </action>
+ <action dev="poi-developers" type="fix">51455 - It would be really nice to be able to set the background picture of a comment </action>
+ <action dev="poi-developers" type="fix">51341 - Adding Image to Header in Excel Using HSSF </action>
+ <action dev="poi-developers" type="fix">51280 - when we insert a new image to the existing excel file that corrupts the previous images </action>
+ <action dev="poi-developers" type="fix">50696 - File Error: data may have been lost </action>
+ <action dev="poi-developers" type="fix">48989 - If we have a comment but the row is not created we will not be able to get it. </action>
+ <action dev="poi-developers" type="fix">48873 - Comments not saving in XLS files with collapsible columns </action>
+ <action dev="poi-developers" type="fix">48654 - Not able to read Excel (xls) file having drawing objects </action>
+ <action dev="poi-developers" type="fix">48590 - Excel chrashes after using removeCellComment methods </action>
+ <action dev="poi-developers" type="fix">46444 - cloning cloned sheet with autofilters corrupts the workbook </action>
+ <action dev="poi-developers" type="fix">45129 - Lost picture in file output after saving with POI </action>
+ <action dev="poi-developers" type="fix">47624 - File Error Data May Have been Lost error while opening commented workbook(excel file) </action>
+ <action dev="poi-developers" type="fix">46143 - setLineStyleColor for comments donot work </action>
+ <action dev="poi-developers" type="fix">53699 - Patch to correct BorderStyle enum positions </action>
+ <action dev="poi-developers" type="add">53064 - Ugly Duckling case study</action>
+ <action dev="poi-developers" type="add">53644 - XLS formula bugfix (CalFieldFunc) + WeekDay addon </action>
+ <action dev="poi-developers" type="add">53446 - Fixed some problems extracting PNGs </action>
+ <action dev="poi-developers" type="fix">53205 - Fixed some parsing errors and encoding issues in HDGF </action>
+ <action dev="poi-developers" type="add">53204 - Improved performanceof PageSettingsBlock in HSSF </action>
+ <action dev="poi-developers" type="add">53500 - Getter for repeating rows and columns</action>
+ <action dev="poi-developers" type="fix">53369 - Fixed tests failing on JDK 1.7</action>
+ <action dev="poi-developers" type="fix">53360 - Fixed SXSSF to correctly write text before escaped Unicode control character</action>
+ <action dev="poi-developers" type="add">Change HSMF Types to have full data on ID, Name and Length, rather than just being a simple ID</action>
+ <action dev="poi-developers" type="add">48469 - Updated case study</action>
+ <action dev="poi-developers" type="add">53476 - Support Complex Name in formulas </action>
+ <action dev="poi-developers" type="fix">53414 - properly update sheet dimensions when adding column </action>
+ <action dev="poi-developers" type="add">Add File based constructor to OPCPackage, alongside existing String one (which constructed a File from the string internally)</action>
+ <action dev="poi-developers" type="fix">53389 - Handle formatting General and @ formats even if a locale is prefixed to them</action>
+ <action dev="poi-developers" type="fix">53271 - Removed unconditional asserts in SXSSF</action>
+ <action dev="poi-developers" type="add">53025 - Updatad documentation and example on using Data Validations </action>
+ <action dev="poi-developers" type="add">53227 - Corrected AddDimensionedImage.java to support XSSF/SXSSF </action>
+ <action dev="poi-developers" type="add">53058 - Utility for representing drawings contained in a binary Excel file as a XML tree</action>
+ <action dev="poi-developers" type="add">53165 - HWPF support for fetching the description (alt text) of a picture</action>
+ <action dev="poi-developers" type="fix">48528 - support negative arguments to the DATE() function</action>
+ <action dev="poi-developers" type="fix">53092 - allow specifying of a TimeZone to DateUtil.getJavaDate(), for when it is known that a file comes from a different (known) timezone to the current machine</action>
+ <action dev="poi-developers" type="fix">53043 - don't duplicate hyperlink relationships when saving XSSF file</action>
+ <action dev="poi-developers" type="fix">53101 - fixed evaluation of SUM over cell range > 255</action>
+ <action dev="poi-developers" type="fix">49529 - avoid exception when cloning sheets with no drawing records and initialized drawing patriarch</action>
+ </release>
+ <release version="3.8-FINAL" date="2012-03-26">
+ <action dev="poi-developers" type="add">52928 - DateFormatConverter: an utility to convert instances of java.text.DateFormat to Excel format patterns</action>
+ <action dev="poi-developers" type="fix">52895 - show SSTIndex instead of XFIndex in LabelSSTRecord.toString()</action>
+ <action dev="poi-developers" type="fix">52835 - Tolerate missing Count and UniqueCount attributes when parsing shared strings table in XSSF eventusermodel</action>
+ <action dev="poi-developers" type="add">52818 - Added implementation for RANK()</action>
+ <action dev="poi-developers" type="fix">52682 - allow setting text with trailing carriage return in HSLF</action>
+ <action dev="poi-developers" type="fix">52244 - use correct text attributes when presentation has multiple TxMasterStyleAtoms of the same type</action>
+ <action dev="poi-developers" type="add">support setting background color of sheet tab in XSSF</action>
+ <action dev="poi-developers" type="add">51564 - support for enforcing fields update in XWPF</action>
+ <action dev="poi-developers" type="add">51673 - support grouping rows in SXSSF</action>
+ <action dev="poi-developers" type="add">51780 - support replacement of content types in OPC packages </action>
+ <action dev="poi-developers" type="fix">52784 - replace ISO control characters with question marks in SXSSF to be consistent with XSSF </action>
+ <action dev="poi-developers" type="add">52057 - updated formula test framework to be aware of recently added Functions </action>
+ <action dev="poi-developers" type="add">52574 - support setting header / footer page margins in HSSF </action>
+ <action dev="poi-developers" type="add">52583 - fixed WorkbookUtil#createSafeSheetName to escape colon </action>
+ <action dev="poi-developers" type="add">51710 - fixed reading shared formulas in XSSF </action>
+ <action dev="poi-developers" type="add">52708 - misc improvements in CellFormat </action>
+ <action dev="poi-developers" type="add">52690 - added a getter for length of encrypted data in Ecma and Agile decryptors</action>
+ <action dev="poi-developers" type="fix">52255 - support adding TIFF,EPS and WPG pictures in OOXML documents </action>
+ <action dev="poi-developers" type="fix">52078 - avoid OutOfMemoryError when rendering groupped pictures in HSLF </action>
+ <action dev="poi-developers" type="fix">52745 - fixed XSSFRichtextString.append to preserve leading / trailing spaces </action>
+ <action dev="poi-developers" type="fix">52716 - tolerate hyperlinks that have neither location nor relation </action>
+ <action dev="poi-developers" type="fix">52599 - avoid duplicate text when rendering slides in HSLF</action>
+ <action dev="poi-developers" type="fix">52598 - respect slide background when rendering slides in HSLF</action>
+ <action dev="poi-developers" type="fix">51731 - fixed painting shape outlines in HSLF</action>
+ <action dev="poi-developers" type="fix">52701 - fixed seting vertical alignment for XSLFTableCell</action>
+ <action dev="poi-developers" type="fix">52687 - fixed merging slides with pictures with associated custom tags</action>
+ <action dev="poi-developers" type="add"> allow runtime registration of functions in FormulaEvaluator</action>
+ <action dev="poi-developers" type="fix">52665 - When reading from a ZipFileZipEntrySource that has already been closed, give IllegalArgumentException rather than NPE</action>
+ <action dev="poi-developers" type="fix">52664 - MAPIMessage may not always have name chunks when checking for 7 bit encodings</action>
+ <action dev="poi-developers" type="fix">52649 - fixed namespace issue in WordToFoConverter</action>
+ <action dev="poi-developers" type="fix">52385 - avoid trancated array and vector data when reading OLE properties</action>
+ <action dev="poi-developers" type="fix">52662 - CharacterRun NPE fix when fetching symbol fonts, where no fonts are defined</action>
+ <action dev="poi-developers" type="add">52658 - support mergin table cells in XSLF</action>
+ <action dev="poi-developers" type="add">validate row number and column index in SXSSF when creating new rows / cells</action>
+ <action dev="poi-developers" type="fix">51498 - fixed evaluation of blank cells in COUNTIF</action>
+ <action dev="poi-developers" type="add">52576 - support changing external file references in HSSFWorkbook</action>
+ <action dev="poi-developers" type="add">49896 - support external references in FormulaRenderer</action>
+ <action dev="poi-developers" type="fix">52527 - avoid exception when matching shared formula records in HSSF</action>
+ <action dev="poi-developers" type="add">52568 - Added methods to set/get an XWPFRun's text color</action>
+ <action dev="poi-developers" type="add">52566 - Added methods to set/get vertical alignment and color in XWPFTableCell</action>
+ <action dev="poi-developers" type="add">52562 - Added methods to get/set a table row's Can't Split and Repeat Header attributes in XWPF</action>
+ <action dev="poi-developers" type="add">52561 - Added methods to set table inside borders and cell margins in XWPF</action>
+ <action dev="poi-developers" type="add">52569 - Support DConRefRecord in HSSF</action>
+ <action dev="poi-developers" type="add">52575 - added an option to ignore missing workbook references in formula evaluator</action>
+ <action dev="poi-developers" type="add">Validate address of hyperlinks in XSSF</action>
+ <action dev="poi-developers" type="fix">52540 - Relax the M4.1 constraint on reading OOXML files, as some Office produced ones do have 2 Core Properties, despite the specification explicitly forbidding this</action>
+ <action dev="poi-developers" type="add">52462 - Added implementation for SUMIFS()</action>
+ <action dev="poi-developers" type="add">POIXMLPropertiesTextExtractor support for extracting custom OOXML properties as text</action>
+ <action dev="poi-developers" type="fix">52449 - Support writing XWPF documents with glossaries (Glossaries are not yet supported, but can now be written out again without changes)</action>
+ <action dev="poi-developers" type="fix">52446 - Handle files which have been truncated by a few bytes in NPropertyTable</action>
+ <action dev="poi-developers" type="fix">52438 - Update CellDateFormatter to handle times without seconds</action>
+ <action dev="poi-developers" type="add">52389 - Support ?/? as well as #/# fractions, and tighten DataFormatter rules for fraction matching</action>
+ <action dev="poi-developers" type="add">52200 - Updated XWPF table example code </action>
+ <action dev="poi-developers" type="add">52378 - Support for WORKDAY and NETWORKDAYS functions</action>
+ <action dev="poi-developers" type="add">52349 - Merge the logic between the TEXT function and DataFormatter</action>
+ <action dev="poi-developers" type="fix">52349 - Correctly support excel style date format strings in the TEXT function</action>
+ <action dev="poi-developers" type="fix">52369 - XSSFExcelExtractor should format numeric cells based on the format strings applied to them</action>
+ <action dev="poi-developers" type="fix">52369 - Event based XSSF parsing should handle formatting of formula values in XSSFSheetXMLHandler</action>
+ <action dev="poi-developers" type="fix">52348 - Avoid exception when creating cell style in a workbook that has an empty xf table</action>
+ <action dev="poi-developers" type="fix">52219 - fixed XSSFSimpleShape to set rich text attributes from XSSFRichtextString</action>
+ <action dev="poi-developers" type="fix">52314 - enhanced SheetUtil.getColumnWidth</action>
+ </release>
+ <release version="3.8-beta5" date="2011-12-17">
+ <action dev="poi-developers" type="fix">52204 - Deprecated XSSFWorkbook(String path) constructor because it does not close underlying .zip file</action>
+ <action dev="poi-developers" type="fix">46288 - fixed refcount of Fill pictures in HSLF </action>
+ <action dev="poi-developers" type="add">51961 - support compression of temp files in SXSSF </action>
+ <action dev="poi-developers" type="add">52268 - support cloning sheets with drawings in XSSF </action>
+ <action dev="poi-developers" type="add">52285 - Support XWPF smart tags text in Paragraphs</action>
+ <action dev="poi-developers" type="fix">51875 - More XSSF new-line in formula support</action>
+ <action dev="poi-developers" type="add">POIFS EntryUtils.copyNodes(POFS,POIFS) now uses FilteringDirectoryNode, so can exclude from copying nodes not just directly under the root</action>
+ <action dev="poi-developers" type="add">POIFS Helper FilteringDirectoryNode, which wraps a DirectoryEntry and allows certain parts to be ignored</action>
+ <action dev="poi-developers" type="fix">52209 - fixed inserting multiple pictures in XSLF </action>
+ <action dev="poi-developers" type="fix">51803 - fixed HSLF TextExtractor to extract content from master slide </action>
+ <action dev="poi-developers" type="fix">52190 - null check on XWPF setFontFamily</action>
+ <action dev="poi-developers" type="fix">52062 - ensure that temporary files in SXSSF are deleted</action>
+ <action dev="poi-developers" type="fix">50936 - Exception parsing MS Word 8.0 file (as duplicate of 47958)</action>
+ <action dev="poi-developers" type="fix">47958 - ArrayIndexOutOfBoundsException from PicturesTable.getAllPictures() during Escher tree walk</action>
+ <action dev="poi-developers" type="fix">51944 - PAPFormattedDiskPage.getPAPX - IndexOutOfBounds</action>
+ <action dev="poi-developers" type="fix">52032 - HWPF - ArrayIndexOutofBoundsException with no stack trace (broken after revision 1178063)</action>
+ <action dev="poi-developers" type="add">support for converting pptx files into images with a PPTX2PNG tool</action>
+ <action dev="poi-developers" type="add">52050 - Support for the Excel RATE function</action>
+ <action dev="poi-developers" type="fix">51566 - HSLF fix for finishing parsing the picture stream on the first non-valid type</action>
+ <action dev="poi-developers" type="fix">51974 - Avoid HWPF issue when identifying the picture type</action>
+ <action dev="poi-developers" type="fix">52035 - Fix signed issue with very large word 6 files</action>
+ <action dev="poi-developers" type="fix">51949 - Avoid NPE on double close of ZipFileZipEntrySource</action>
+ <action dev="poi-developers" type="fix">51950 - XWPF fix for footnotes not always being present in a document</action>
+ <action dev="poi-developers" type="fix">51963 - Correct AreaReference handling of references containing a sheet name which includes a comma</action>
+ <action dev="poi-developers" type="fix">51955 - XSSFReader supplied StylesTables need to have the theme data available</action>
+ <action dev="poi-developers" type="fix">51716 - Removed incorrect assert in SXSSFSheet#getSXSSFSheet</action>
+ <action dev="poi-developers" type="fix">51834 - Opening and Writing .doc file results in corrupt document</action>
+ <action dev="poi-developers" type="fix">51902 - Picture.fillRawImageContent - ArrayIndexOutOfBoundsException (duplicate)</action>
+ <action dev="poi-developers" type="fix">51890 - ArrayIndexOutOfBounds ExceptionPicture.fillRawImageContent</action>
+ <action dev="poi-developers" type="add">Allow the passing of a File object to WorkbookFactory.create, which permits lower memory processing than the InputStream version</action>
+ <action dev="poi-developers" type="fix">51873 - update HSMF to ignore Outlook 2002 Olk10SideProp entries, which don't behave like normal chunks</action>
+ <action dev="poi-developers" type="fix">51850 - support creating comments in XSSF on an earlier slide when later ones already have them</action>
+ <action dev="poi-developers" type="add">51804 - optionally include Master Slide text in XSLF text extraction, as HSLF already offers</action>
+ <action dev="poi-developers" type="add">New PackagePart method getRelatedPart(PackageRelationship) to simplify navigation of relations between OPC Parts</action>
+ <action dev="poi-developers" type="fix">51832 - handle XLS files where the WRITEPROTECT record preceeds the FILEPASS one, rather than following as normal</action>
+ <action dev="poi-developers" type="fix">51809 - correct GTE handling in COUNTIF</action>
+ <action dev="poi-developers" type="add">Add HWPF API to update range text and delete bookmarks</action>
+ <action dev="poi-developers" type="add">HWPF Bookmarks tables are correctly updated on text updates</action>
+ <action dev="poi-developers" type="add">51670 - avoid LeftoverDataException when reading .xls files with invalid LabelRecords</action>
+ <action dev="poi-developers" type="add">51196 - prevent NPE in XWPFPicture.getPictureData() </action>
+ <action dev="poi-developers" type="add">51771 - prevent NPE when getting object data from OLEShape in HSLF</action>
+ <action dev="poi-developers" type="add">51196 - more progress with Chart APi in XSSF</action>
+ <action dev="poi-developers" type="fix">51785 - Allow XSSF setForceFormulaRecalculation to work with the minimal ooxml-schemas jar</action>
+ <action dev="poi-developers" type="fix">51772 - IllegalArgumentException Parsing MS Word 97 - 2003</action>
+ <action dev="poi-developers" type="add">XSLFPowerPointExtractor support for including comment authors with comment text</action>
+ <action dev="poi-developers" type="fix">Converted XSLFPowerPointExtractor to use UserModel for all text extraction</action>
+ <action dev="poi-developers" type="add">XSLF initial UserModel support for Notes and Comments for Slides</action>
+ <action dev="poi-developers" type="add">HSLF: support for uncompressed OLE embeddings</action>
+ </release>
+ <release version="3.8-beta4" date="2011-08-26">
+ <action dev="poi-developers" type="fix">51678 - Extracting text from Bug51524.zip is slow</action>
+ <action dev="poi-developers" type="fix">51671 - HWPFDocument.write based on NPOIFSFileSystem throws a NullPointerException</action>
+ <action dev="poi-developers" type="add">support for tables and hyperlinks in XSLF</action>
+ <action dev="poi-developers" type="fix">51535 - correct signed vs unsigned short reading in NDocumentInputStream</action>
+ <action dev="poi-developers" type="add">51634 - support SXSSF streaming from templates</action>
+ <action dev="poi-developers" type="add">initial support for XSLF usermodel API</action>
+ <action dev="poi-developers" type="fix">51187 - fixed OPCPackage to correctly handle self references</action>
+ <action dev="poi-developers" type="fix">51635 - Improved performance of XSSFSheet#write</action>
+ <action dev="poi-developers" type="fix">47731 - Word Extractor considers text copied from some website as an embedded object</action>
+ <action dev="poi-developers" type="add">Add Word-to-Text converter and use it as replacement for WordExtractor</action>
+ <action dev="poi-developers" type="fix">51604 - replace text fails for doc ( poi 3.8 beta release from download site )</action>
+ <action dev="poi-developers" type="fix">Fixed incorrect encoding of non-breaking space (0xA0) in SXSSF</action>
+ <action dev="poi-developers" type="add">Support for conditional formatting in XSSF</action>
+ <action dev="poi-developers" type="add">Support isRightToLeft and setRightToLeft on the common spreadsheet Sheet interface, as per existing HSSF support</action>
+ <action dev="poi-developers" type="fix">50209 - Fixed evaluation of Subtotals to ignore nested subtotals</action>
+ <action dev="poi-developers" type="fix">44431 - HWPFDocument.write destroys fields</action>
+ <action dev="poi-developers" type="fix">50401 - fixed EscherProperty to return property name instead of 'unknown' for complex properties </action>
+ <action dev="poi-developers" type="add">Initial support for endnotes and footnotes in HWPF</action>
+ <action dev="poi-developers" type="fix">51470 - avoid exception when cloning XSSF sheets with background images</action>
+ <action dev="poi-developers" type="fix">51481 - Fixed autofilters in HSSF to avoid warnings in Excel 2007</action>
+ <action dev="poi-developers" type="fix">51533 - Avoid exception when changing name of a sheet containing shared formulas</action>
+ <action dev="poi-developers" type="add">Support for appending images to existing drawings in HSSF</action>
+ <action dev="poi-developers" type="add">Initial support for bookmarks in HWPF</action>
+ <action dev="poi-developers" type="fix">46250 - Fixed cloning worksheets with images</action>
+ <action dev="poi-developers" type="fix">51524 - PapBinTable constructor is slow (regression)</action>
+ <action dev="poi-developers" type="fix">51514 - allow HSSFObjectData to work with both POIFS and NPOIFS</action>
+ <action dev="poi-developers" type="fix">51514 - avoid NPE when copying nodes from one HSSF workbook to a new one, when opened from NPOIFS</action>
+ <action dev="poi-developers" type="fix">51504 - avoid NPE when DefaultRowHeight or DefaultColumnWidth records are missing</action>
+ <action dev="poi-developers" type="fix">51502 - Correct Subtotal function javadoc entry</action>
+ <action dev="poi-developers" type="add">Support for hyperlinks in SXSSF</action>
+ <action dev="poi-developers" type="fix">49933 - Word 6/95 documents with sections cause ArrayIndexOutOfBoundsException</action>
+ <action dev="poi-developers" type="add">51469 - XSSF support for row styles, to match existing HSSF functionality</action>
+ <action dev="poi-developers" type="fix">51476 - Correct XSSF cell formatting in HTML export</action>
+ <action dev="poi-developers" type="add">51486 - XWPF support for adding new footnotes</action>
+ <action dev="poi-developers" type="fix">48065 - Problems with save output of HWPF (losing formatting)</action>
+ <action dev="poi-developers" type="fix">47563 - Exception when working with table</action>
+ <action dev="poi-developers" type="fix">47287 - StringIndexOutOfBoundsException in CharacterRun.replaceText()</action>
+ <action dev="poi-developers" type="fix">46817 - Regression: Text from some table cells missing</action>
+ <action dev="poi-developers" type="add">Add getOverallRange() method to HWPFDocumentCore</action>
+ <action dev="poi-developers" type="fix">PAPX referenced outside of TextPiecesTable are ignored now and not loaded</action>
+ <action dev="poi-developers" type="fix">Fix main part range (and section) detection for files with additional parts (like footers/headers).</action>
+ <action dev="poi-developers" type="fix">Fix wrong TextPiece parsing in very rare cases like Bug33519.doc</action>
+ <action dev="poi-developers" type="fix">Inner tables are correctly supported</action>
+ <action dev="poi-developers" type="add">Allow user to retrieve Table nesting level (based on file information)</action>
+ <action dev="poi-developers" type="add">Functionality of internal tool HWPFLister is greatly improved, including output of document PAPX and paragraphs</action>
+ <action dev="poi-developers" type="add">Expand Word structures definitions (TAP, PAP, TLP, etc) based on official documentation</action>
+ <action dev="poi-developers" type="add">Add Excel-to-HTML converter (2007 versions)</action>
+ <action dev="poi-developers" type="add">Add Word-to-HTML converter (95-2007 versions)</action>
+ <action dev="poi-developers" type="fix">Skip wrong-type SPRMs when characters SPRM is expected</action>
+ <action dev="poi-developers" type="add">Add toStrings() methods to internal HWPF structures: BorderCode, PAPX, Paragraph, PieceDescriptor, Section, SEPX, SprmOperation, TextPiece etc.</action>
+ <action dev="poi-developers" type="fix">51474 - SXSSF handling for null strings</action>
+ <action dev="poi-developers" type="fix">48294 - Fixed HSSFWorkbook.setSheetOrder() to respect inter-sheet references </action>
+ <action dev="poi-developers" type="fix">51448 - Avoid exception when evaluating workbooks with more than 256 sheets </action>
+ <action dev="poi-developers" type="fix">51458 - Correct BitField wrapping when setting large values</action>
+ <action dev="poi-developers" type="add">51460 - Improve HSSF performance when loading very long rows, by switching the CellValue array to an iterator</action>
+ <action dev="poi-developers" type="fix">51444 - Prevent corrupted output when saving files created by LibreOffice 3.3 </action>
+ <action dev="poi-developers" type="add">51422 - Support using RecalcIdRecord to trigger a full formula recalculation on load </action>
+ <action dev="poi-developers" type="add">50474 - Example demonstrating how to update Excel workbook embedded in a WordprocessingML document </action>
+ <action dev="poi-developers" type="fix">51431 - Avoid IndexOutOfBoundException when removing freeze panes in XSSF </action>
+ <action dev="poi-developers" type="fix">48877 - Fixed XSSFRichTextString to respect leading and trailing line breaks </action>
+ <action dev="poi-developers" type="fix">49564 - Fixed default behaviour of XSSFCellStyle.getLocked() </action>
+ <action dev="poi-developers" type="fix">48314 - Fixed setting column and row breaks in XSSF</action>
+ <action dev="poi-developers" type="add">51424 - Ignore exceptions in ParagraphSprmUncompressor</action>
+ <action dev="poi-developers" type="fix">51415 - Fixed Workbook.createSheet(sheetName) to truncate names longer than 31 characters</action>
+ <action dev="poi-developers" type="fix">51332 - Fixed internal IDs of shapes generated by HSSFPatriarch when there are more than 1023 drawing objects </action>
+ <action dev="poi-developers" type="fix">48408 - Improved documentation for Sheet.setColumnWidth </action>
+ <action dev="poi-developers" type="add">51390 - Added handling of additional properties to HWPF ParagraphSprmCompressor</action>
+ <action dev="poi-developers" type="add">51389 - Support for sprmPJc paragraph SPRM in HWPF</action>
+ <action dev="poi-developers" type="fix">48469 - New Case Study for POI web site </action>
+ <action dev="poi-developers" type="fix">50681 - Avoid exceptions in HSSFDataFormat.getDataFormatString() </action>
+ <action dev="poi-developers" type="fix">50681 - Fixed autosizing columns beyond 255 character limit </action>
+ <action dev="poi-developers" type="fix">51374 - Fixed incorrect setting of lastPrinted OOXML core property </action>
+ <action dev="poi-developers" type="add">51351 - Word to XSL-FO converter</action>
+ <action dev="poi-developers" type="fix">50458 - Fixed missing shapeId in XSSF drawings </action>
+ <action dev="poi-developers" type="fix">51339 - Fixed arithmetic rounding in formula evaluation </action>
+ <action dev="poi-developers" type="add">51356 - Support autoSizeColumn in SXSSF</action>
+ <action dev="poi-developers" type="add">51335 - Parse picture goal and crop sizes in HWPF</action>
+ <action dev="poi-developers" type="add">51305 - Add sprmTCellPaddingDefault support in HWPF</action>
+ <action dev="poi-developers" type="add">51265 - Enhanced Handling of Picture Parts in XWPF</action>
+ <action dev="poi-developers" type="add">51292 - Additional HWPF Table Cell Descriptor values</action>
+ </release>
+ <release version="3.8-beta3" date="2011-06-06">
+ <action dev="poi-developers" type="fix">51098 - Correctly calculate image width/height, if image fits into one cell</action>
+ <action dev="poi-developers" type="fix">47147 - Correct extra paragraphs from XWPF Table Cells</action>
+ <action dev="poi-developers" type="add">51188 - Support for getting and setting XPWF zoom settings</action>
+ <action dev="poi-developers" type="add">51134 - Support for adding Numbering and Styles to a XWPF document that doesn't already have them</action>
+ <action dev="poi-developers" type="fix">51273 - Formula Value Cache fix for repeated evaluations</action>
+ <action dev="poi-developers" type="add">51171 - Improved performance of SharedValueManager </action>
+ <action dev="poi-developers" type="fix">51236 - XSSF set colour support for black/white to match getter</action>
+ <action dev="poi-developers" type="add">51196 - Initial support for Spreadsheet Chart API</action>
+ <action dev="poi-developers" type="add">Add support for OOXML Agile Encryption</action>
+ <action dev="poi-developers" type="add">51160 - Initial version of SXSSF, a low memory foortprint API to produce xlsx files</action>
+ <action dev="poi-developers" type="fix">51171 - Improved performance of opening large .xls files</action>
+ <action dev="poi-developers" type="add">51172 - Add XWPF support for GIF pictures</action>
+ <action dev="poi-developers" type="add">NPOIFS Mini Streams now support extending the underlying big block stream to fit more data</action>
+ <action dev="poi-developers" type="fix">51148 - XWPFDocument now properly tracks paragraphs and tables when adding/removing them</action>
+ <action dev="poi-developers" type="fix">51153 - Correct sizing of LbsDataSubRecord with unused padding fields</action>
+ <action dev="poi-developers" type="fix">51143 - NameCommentRecord correction for writing non ASCII strings</action>
+ <action dev="poi-developers" type="fix">51112 - Correct XWPFTable tracking of new rows</action>
+ <action dev="poi-developers" type="fix">51113 - Correct XWPFParagraph tracking of inserted runs</action>
+ <action dev="poi-developers" type="fix">51111 - Correct XWPFParagraph tracking of new runs</action>
+ <action dev="poi-developers" type="fix">51115 - Handle DataFormatter escaping of "." in the same way as "-" and "/"</action>
+ <action dev="poi-developers" type="fix">51100 - Fix IOUtils issue for NPOIFS reading from an InputStream where every block is full</action>
+ <action dev="poi-developers" type="fix">50956 - Correct XSSF cell style cloning between workbooks</action>
+ <action dev="poi-developers" type="add">Add get/setForceFormulaRecalculation for XSSF, and promote the methods to the common usermodel Sheet</action>
+ <action dev="poi-developers" type="fix">Tweak the logic for sizing the HSSFCells array on a HSSFRow to reduce memory over allocation in many use cases</action>
+ <action dev="poi-developers" type="add">49765 - Support for adding a picture to a XSSFRun</action>
+ <action dev="poi-developers" type="fix">Rename/Move xssf.model.Table to xssf.usermodel.XSSFTable as it now has usermodel-like features</action>
+ <action dev="poi-developers" type="fix">51061 - Correct target URI for new XSSF Tables</action>
+ <action dev="poi-developers" type="add">Initial support for XSSF Charts. Provides easy access to the underlying CTChart object via the Sheet Drawing, but no high level interface onto the chart contents as yet.</action>
+ <action dev="poi-developers" type="fix">50884 - XSSF and HSSF freeze panes now behave the same</action>
+ <action dev="poi-developers" type="add">Support for adding a table to a XSSFSheet</action>
+ <action dev="poi-developers" type="add">Improve HSMF MAPIMessage access to the HTML and RTF versions of the message body (where available)</action>
+ <action dev="poi-developers" type="add">Add new method to HSMF of MAPIMessage.has7BitEncodingStrings() to make it easier to decide when encoding guessing is needed</action>
+ <action dev="poi-developers" type="fix">OutlookTextExtractor now requests 7 bit encoding guessing</action>
+ <action dev="poi-developers" type="add">Improve HSMF encoding guessing for 7 bit fields in MAPIMessage</action>
+ <action dev="poi-developers" type="add">Allow HSMF access to the HTML body contents in MAPIMessage</action>
+ </release>
+ <release version="3.8-beta2" date="2011-04-08">
+ <action dev="poi-developers" type="add">Implement the load method on MemoryPackagePart</action>
+ <action dev="poi-developers" type="add">50967 - Support for continued ExtSSTRecords</action>
+ <action dev="poi-developers" type="add">48968 - Support for HOUR, MINUTE and SECOND date formulas</action>
+ <action dev="poi-developers" type="add">Added NPOIFS constructors to most POIDocument classes and their extractors, and more widely deprecated the Document(DirectoryNode, POIFSFileSystem) constructor in favour of the more general Document(DirectoryNode) one</action>
+ <action dev="poi-developers" type="fix">Fixed NPOIFS handling of new and empty Document Nodes</action>
+ <action dev="poi-developers" type="fix">Fixed NPOIFS access to Document Nodes not in the top level directory</action>
+ <action dev="poi-developers" type="fix">50841 - Improved SpreadSheet DataFormatter to handle scientific notation, invalid dates and format spacers</action>
+ <action dev="poi-developers" type="fix">49381 - Correct createFreezePane in XSSF, so that the left row/column matches the documentation + HSSF</action>
+ <action dev="poi-developers" type="fix">49253 - When setting repeating rows and columns for XSSF, don't break the print settings if they were already there</action>
+ <action dev="poi-developers" type="fix">49219 - ExternalNameRecord support for DDE Link entries without an operation</action>
+ <action dev="poi-developers" type="fix">50846 - More XSSFColor theme improvements, this time for Cell Borders</action>
+ <action dev="poi-developers" type="fix">50939 - ChartEndObjectRecord is supposed to have 6 bytes at the end, but handle it not</action>
+ <action dev="poi-developers" type="add">HMEF - New component which supports TNEF (Transport Neutral Encoding Format), aka winmail.dat</action>
+ <action dev="poi-developers" type="fix">50313 - support for getting HWPFDocument fields</action>
+ <action dev="poi-developers" type="fix">50912 - fixed setting named styles to HSSFCells</action>
+ <action dev="poi-developers" type="fix">50779 - fixed RecordFormatException when reading unicode strings with photenic data</action>
+ <action dev="poi-developers" type="fix">50718 - More helpful error message when you try to create a CellReference with #REF!</action>
+ <action dev="poi-developers" type="fix">50784 - XSSFColors return by XSSFFont now have theme information applied to them</action>
+ <action dev="poi-developers" type="fix">50846 - Improve how XSSFColor inherits from Themes</action>
+ <action dev="poi-developers" type="fix">50847 - XSSFFont now accepts the full range of Charsets from FontChartset</action>
+ <action dev="poi-developers" type="fix">50786 - Speed up calls to HSSFColor.getIndexHash() by returning a cached, unmodifiable Map. HSSFColor.getModifiableIndexHash() provides access to the old (slow but modifiable) functionality</action>
+ <action dev="poi-developers" type="fix">47100 - Change related formulas and named ranges when XSSFWorkbook.setSheetName is called</action>
+ </release>
+ <release version="3.8-beta1" date="2011-03-07">
+ <action dev="poi-developers" type="add">50610 - Ant tasks for running POI against a workbook</action>
+ <action dev="poi-developers" type="add">32903 - Correct XBAT chaining explanation in /poifs/fileformat.html</action>
+ <action dev="poi-developers" type="add">50829 - Support for getting the tables associated with a XSSFSheet</action>
+ <action dev="poi-developers" type="fix">50299 - More XSSFColor updates for ARGB vs RGB</action>
+ <action dev="poi-developers" type="fix">50581 - Use stax:stax-api instead of org.apache.geronimo.specs:geronimo-stax-api_1.0_spec</action>
+ <action dev="poi-developers" type="fix">50786 - Fix XSSFColor to fetch the RGB values of old-style indexed colours</action>
+ <action dev="poi-developers" type="fix">50299 - Fix XSSFColor fetching of white and black background themes</action>
+ <action dev="poi-developers" type="fix">50795 - Avoid NPE from xmlbeans when moving XSSF Comments from one cell to another</action>
+ <action dev="poi-developers" type="fix">46664 - When creating HSSF Print Areas, ensure the named range is reference based not value based</action>
+ <action dev="poi-developers" type="fix">50756 - When formatting numbers based on their Cell Style, treat GENERAL the same as the more typical General</action>
+ <action dev="poi-developers" type="fix">fixed HSSFWorkbook.createCellStyle to throw exception if the maximum number of cell styles was exceeded</action>
+ <action dev="poi-developers" type="fix">50539 - Better fix for html-style br tags (invalid XML) inside XSSF documents</action>
+ <action dev="poi-developers" type="add">49928 - allow overridden built-in formats in HSSFCellStyle</action>
+ <action dev="POI-DEVELOPERS" type="add">50607 - Added implementation for CLEAN(), CHAR() and ADDRESS()</action>
+ <action dev="poi-developers" type="add">50587 - Improved documentation on user-defined functions</action>
+ <action dev="poi-developers" type="add">Inside ExtractorFactory, support finding embedded OOXML documents and providing extractors for them</action>
+ <action dev="poi-developers" type="add">Partial HDGF LZW compression support</action>
+ <action dev="poi-developers" type="add">50244 - Support for continued NameRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix">50416 - Correct shifting of the first or last row in a sheet by multiple rows</action>
+ <action dev="POI-DEVELOPERS" type="fix">50440 - Support evaluating formulas with newlines in them, which XSSF may have (but HSSF may not)</action>
+ <action dev="POI-DEVELOPERS" type="add">Added inline string support to XSSF EventModel</action>
+ <action dev="POI-DEVELOPERS" type="fix">50246 - Properly position GutsRecord when reading HSSF workbooks</action>
+ <action dev="POI-DEVELOPERS" type="add">48539 - Added implementation for MROUND(), VAR() and VARP()</action>
+ <action dev="POI-DEVELOPERS" type="add">50446 - Code cleanup and optimizations to keep some IDE quiet</action>
+ <action dev="POI-DEVELOPERS" type="add">50437 - Support passing ranges to NPV()</action>
+ <action dev="POI-DEVELOPERS" type="add">50409 - Added implementation for IRR()</action>
+ <action dev="poi-developers" type="add">47405 - Improved performance of RowRecordsAggregate.getStartRowNumberForBlock / getEndRowNumberForBlock</action>
+ <action dev="poi-developers" type="fix">50315 - Avoid crashing Excel when sorting XSSFSheet autofilter</action>
+ <action dev="poi-developers" type="add">50076 - Allow access from XSSFReader to sheet comments and headers/footers</action>
+ <action dev="poi-developers" type="add">50076 - Refactor XSSFEventBasedExcelExtractor to make it easier for you to have control over outputting the cell contents</action>
+ <action dev="poi-developers" type="fix">50258 - avoid corruption of XSSFWorkbook after applying XSSFRichTextRun#applyFont</action>
+ <action dev="poi-developers" type="fix">50154 - Allow white spaces and unicode in OPC relationship targets </action>
+ <action dev="poi-developers" type="fix">50113 - Remove cell from Calculation Chain after setting cell type to blank </action>
+ <action dev="poi-developers" type="fix">49966 - Ensure that XSSFRow#removeCell cleares calculation chain entries </action>
+ <action dev="poi-developers" type="fix">50096 - Fixed evaluation of cell references with column index greater than 255 </action>
+ <action dev="poi-developers" type="fix">49761 - Tolerate Double.NaN when reading .xls files</action>
+ <action dev="poi-developers" type="fix">50211 - Use cached formula result when auto-sizing formula cells</action>
+ <action dev="poi-developers" type="fix">50118 - OLE2 does allow a directory with an empty name, so support this in POIFS</action>
+ <action dev="poi-developers" type="fix">50119 - avoid NPE when XSSFReader comes across chart sheets</action>
+ </release>
+ <release version="3.7" date="2010-10-29">
+ <action dev="poi-developers" type="fix">50075 - avoid NPE in ListLevel.getNumberText() when numberText is null </action>
+ <action dev="poi-developers" type="fix">50067 - marked commons-logging and log4j as optional dependencies in POI poms</action>
+ <action dev="poi-developers" type="add">49928 - allow overridden built-in formats in XSSFCellStyle</action>
+ <action dev="poi-developers" type="fix">49919 - support for BorderCode in HWPF</action>
+ <action dev="poi-developers" type="fix">49908 - support for processing of symbols in HWPF</action>
+ <action dev="poi-developers" type="fix">50022 - support for retrieving pictures from HSSF workbooks</action>
+ <action dev="poi-developers" type="fix">50020 - Avoid IllegalStateException when creating Data validation in sheet with macro</action>
+ <action dev="poi-developers" type="fix">50033 - Improved rounding in MOD</action>
+ <action dev="poi-developers" type="add">Generate SHA1 hashes of distribution files, alongside existing MD5 ones</action>
+ </release>
+ <release version="3.7-beta3" date="2010-09-24">
+ <action dev="poi-developers" type="fix">48325 - If a HSSF header or footer lacks left/right/centre information, assume it is a centre one</action>
+ <action dev="poi-developers" type="fix">49966 - Correctly remove calcChain entries for XSSF cells that stop holding formulas</action>
+ <action dev="poi-developers" type="add">47582 - XSSFCellStyle support for creating a style in one workbook based on a style from a different one</action>
+ <action dev="poi-developers" type="fix">49931 - Avoid concurrency problems when re-ordering multiple HSSF header records for a PageSettingsBlock</action>
+ <action dev="poi-developers" type="fix">49765 - Fix XWPFDocument.addPicture so that it correctly sets up relationships</action>
+ <action dev="poi-developers" type="fix">48018 - Improve HWPF handling of lists in documents read and then saved, by preserving order better</action>
+ <action dev="poi-developers" type="fix">49820 - Fix HWPF paragraph levels, so that outline levels can be properly fetched</action>
+ <action dev="poi-developers" type="fix">47271 - Avoid infinite loops on broken HWPF documents with a corrupt CHP style with a parent of itself</action>
+ <action dev="poi-developers" type="fix">49936 - Handle HWPF documents with problematic HeaderStories better</action>
+ <action dev="poi-developers" type="fix">49933 - Support sections in Word 6 and Word 95 files (HWPFOldDocument)</action>
+ <action dev="poi-developers" type="fix">49941 - Correctly handle space preservation of XSSFRichTextRuns when applying fonts to parts of the string</action>
+ <action dev="poi-developers" type="fix">Correct XWPFRun detection of bold/italic in a paragraph with multiple runs of different styles</action>
+ <action dev="poi-developers" type="add">Link XWPFPicture to XWPFRun, so that embedded pictures can be access from where they live in the text stream</action>
+ <action dev="poi-developers" type="fix">Improve handling of Hyperlinks inside XWPFParagraph objects through XWPFHyperlinkRun</action>
+ <action dev="poi-developers" type="fix">Make XWPFParagraph make more use of XWPFRun, and less on internal StringBuffers</action>
+ <action dev="poi-developers" type="add">Add a getBodyElements() method to XWPF IBody, to make access to embedded paragraphs and tables easier</action>
+ <action dev="poi-developers" type="add">More XSLFRelation entries for common .pptx file parts</action>
+ <action dev="poi-developers" type="fix">49872 - avoid exception in XSSFFormulaEvaluator.evaluateInCell when evaluating shared formulas</action>
+ <action dev="poi-developers" type="fix">49895 - avoid corruption of XSSFWorkbook after removing all merged cells from sheet</action>
+ <action dev="poi-developers" type="fix">49907 - fixed inconsistent behaviour between HSSF and XSSF when creating consecutive names</action>
+ <action dev="poi-developers" type="add">Add getMimeType() method to HWPF Picture, alongside existing file extension</action>
+ <action dev="poi-developers" type="add">Add code for reading Ole10Native data</action>
+ <action dev="poi-developers" type="add">Add getMimeType() method to HSSF/XSSF PictureData, alongside existing file extension</action>
+ <action dev="poi-developers" type="fix">49887 - allow sheet names longer than 31 chars in XSSF, enforce name uniqueness on the first 31 chars</action>
+ <action dev="poi-developers" type="fix">49878 - improved API for hiding sheets</action>
+ <action dev="poi-developers" type="fix">49875 - fixed XSSFWorkbook.createSheet to throw exception if sheet name begins or ends with a single quote (')</action>
+ <action dev="poi-developers" type="fix">49873 - fixed XSSFFormulaEvaluator to support blank cells</action>
+ <action dev="poi-developers" type="fix">49850 - added a getter for _iStartAt in ListFormatOverrideLevel</action>
+ <action dev="poi-developers" type="fix">49761 - change cell type to error when setting Double.NaN or Infinities</action>
+ <action dev="poi-developers" type="fix">49833 - ensure that CTNumPr is included in poi-ooxml-schemas.jar</action>
+ <action dev="POI-DEVELOPERS" type="fix">49841 - fixed LEFT and RIGHT to return #VALUE! when called with a negative operand </action>
+ <action dev="POI-DEVELOPERS" type="fix">49783 - fixed evaluation of XSSF workbooks containing formulas with reference errors (#REF!)</action>
+ <action dev="POI-DEVELOPERS" type="fix">49751 - fixed fetching names of user defined styles in HSSFCellStyle.getUserStyleName()</action>
+ <action dev="POI-DEVELOPERS" type="add">48900 - support for protecting a XSSF workbook</action>
+ <action dev="POI-DEVELOPERS" type="fix">49725 - fixed FormulaParser to correctly process defined names with underscore</action>
+ <action dev="POI-DEVELOPERS" type="add">48526 - added implementation for RANDBETWEEN()</action>
+ <action dev="POI-DEVELOPERS" type="fix">49725 - avoid exception in OperandResolver.parseDouble when input is minus ("-")</action>
+ <action dev="POI-DEVELOPERS" type="fix">49723 - fixed OperandResolver to correctly handle inputs with leading decimal place</action>
+ <action dev="POI-DEVELOPERS" type="add">initial support for Excel autofilter</action>
+ </release>
+ <release version="3.7-beta2" date="2010-08-09">
+ <action dev="POI-DEVELOPERS" type="add">47990 - Support for .msg attachments within a MAPIMessage .msg</action>
+ <action dev="POI-DEVELOPERS" type="fix">Improve handling and warnings when closing OPCPackage objects</action>
+ <action dev="POI-DEVELOPERS" type="fix">49702 - Correct XSSFWorkbook.getNumCellStyles to check the right styles list</action>
+ <action dev="POI-DEVELOPERS" type="add">49690 - Add WorkbookUtil, which provies a way of generating valid sheet names</action>
+ <action dev="POI-DEVELOPERS" type="fix">49694 - Use DataFormatter when autosizing columns, to better match the real display width of formatted cells</action>
+ <action dev="POI-DEVELOPERS" type="add">49441 - Allow overriding and guessing of HSMF non-unicode string encodings</action>
+ <action dev="POI-DEVELOPERS" type="fix">49689 - Allow the setting of user style names on newly created HSSF cell styles</action>
+ <action dev="POI-DEVELOPERS" type="add">Make it easier to tell which content types each POIXMLTextExtractor handles</action>
+ <action dev="POI-DEVELOPERS" type="fix">49649 - Added clone support for UserSView* and Feat* families of records</action>
+ <action dev="POI-DEVELOPERS" type="fix">49653 - Support for escaped unicode characters in Shared String Table</action>
+ <action dev="POI-DEVELOPERS" type="fix">49579 - prevent ArrayIndexOutOfBoundException in UnknowEscherRecord</action>
+ <action dev="POI-DEVELOPERS" type="fix">49593 - preserve leading and trailing white spaces in XWPFRun</action>
+ <action dev="POI-DEVELOPERS" type="add">49455 - Insert the content of fldSimple fields into the XWPFWordTextExtractor output</action>
+ <action dev="POI-DEVELOPERS" type="fix">49640 - Fixed parsing formulas containing defined names beginning with an underscore</action>
+ <action dev="POI-DEVELOPERS" type="add">49538 - Added implementation for POISSON()</action>
+ <action dev="POI-DEVELOPERS" type="add">49524 - Support for setting cell text to be vertically rotated, via style.setRotation(0xff)</action>
+ <action dev="POI-DEVELOPERS" type="fix">49609 - Case insensitive matching of OOXML part names</action>
+ <action dev="POI-DEVELOPERS" type="add">49581 - Ability to add, modify and remove series from HSSF Charts</action>
+ <action dev="POI-DEVELOPERS" type="add">49185 - Support for HSSFNames where the comment is stored in a NameCommentRecord</action>
+ <action dev="poi-developers" type="fix">49599 - correct writing of noterecord author text when switching between ascii and unicode</action>
+ <action dev="poi-developers" type="fix">hwpf: improve reading of auto-saved ("complex") documents</action>
+ <action dev="poi-developers" type="add">paragraph level as well as whole-file text extraction for word 6/95 files through hwpf</action>
+ <action dev="poi-developers" type="add">text extraction support for older word 6 and word 95 files via hwpf</action>
+ <action dev="poi-developers" type="add">49508 - allow the addition of paragraphs to xwpf table cells</action>
+ <action dev="poi-developers" type="fix">49446 - don't consider 17.16.23 field codes as properly part of the paragraph's text</action>
+ <action dev="poi-developers" type="fix">xslfslideshow shouldn't break on .thmx (theme) files. support for them is still very limited though</action>
+ </release>
+ <release version="3.7-beta1" date="2010-06-20">
+ <action dev="poi-developers" type="fix">49432 - lazy caching of xssfcomment ctcomment objects by reference, to make repeated comment searching faster</action>
+ <action dev="poi-developers" type="fix">better handling of outlook messages in hsmf when there's no recipient email address</action>
+ <action dev="poi-developers" type="fix">when formatting numbers with dataformatter, handle brackets following colours</action>
+ <action dev="poi-developers" type="add">48574 - further xwpf support for tables, paragraphs, including enhanced support for adding new ones</action>
+ <action dev="poi-developers" type="add">48245 - tweak hwpf table cell detection to work across more files</action>
+ <action dev="poi-developers" type="add">48996 - initial support for external name references in hssf formula evaluation</action>
+ <action dev="poi-developers" type="fix">46664 - fix up tab ids when adding new sheets, so that print areas don't end up invalid</action>
+ <action dev="poi-developers" type="fix">45269 - improve replacetext on hwpf ranges</action>
+ <action dev="poi-developers" type="fix">47815 - correct documentation on what happens when you request a string from a non-string formula cell</action>
+ <action dev="poi-developers" type="fix">49386 - avoid npe when extracting ooxml file properties which are dates</action>
+ <action dev="poi-developers" type="fix">49377 - only call decimalformat.setroundingmode on java 1.6 - it's needed to match excel's rendering of numbers</action>
+ <action dev="poi-developers" type="fix">49378 - correct 1.6ism</action>
+ <action dev="poi-developers" type="add">parse the hsmf headers chunk if present, and use it to find dates in text extraction if needed</action>
+ <action dev="poi-developers" type="fix">48494 - detect and support time formats like hh:mm;hh:mm</action>
+ <action dev="poi-developers" type="fix">48494 - have excelextractor make use of hssfdataformatter, so that numbers and dates come out closer to how excel would render them</action>
+ <action dev="poi-developers" type="fix">48494 - have eventbasedexcelextractor make use of hssfdataformatter, so that numbers and dates come out closer to how excel would render them</action>
+ <action dev="poi-developers" type="fix">49096 - add clone support to chart begin and end records, to allow cloning of more chart containing sheets</action>
+ <action dev="poi-developers" type="add">list attachment names in the output of outlooktextextractor (to get attachment contents, use extractorfactory as normal)</action>
+ <action dev="poi-developers" type="fix">48872 - allow dateformatter.formatrawcellcontents to handle 1904 as well as 1900 dates</action>
+ <action dev="poi-developers" type="fix">48872 - handle mmmmm and elapsed time formatting rules in dataformatter</action>
+ <action dev="poi-developers" type="fix">48872 - handle zero formatting rules, and better color detection in dataformatter</action>
+ <action dev="poi-developers" type="fix">48872 - support for more kinds of formatting in dataformatter</action>
+ <action dev="poi-developers" type="fix">43161 - fixed construction of the dib picture header</action>
+ <action dev="poi-developers" type="add">49311 - initial support for reading aes-encrypted/write-protected ooxml files</action>
+ <action dev="poi-developers" type="fix">48718 - make the creation of multiple, un-modified fonts in a row in xssf match the old hssf behaviour</action>
+ <action dev="poi-developers" type="fix">44916 - allow access to the hssfpatriarch from hssfsheet once created</action>
+ <action dev="poi-developers" type="add">48779 - allow you to get straight from a cellstyle to a color, irrespective of if the color is indexed or inline-defined</action>
+ <action dev="poi-developers" type="add">48924 - allow access of the hwpf dateandtime underlying date values</action>
+ <action dev="poi-developers" type="add">48926 - initial support for the hwpf revision marks authors list</action>
+ <action dev="poi-developers" type="fix">49160 - ensure that ctdigsigblob is included in poi-ooxml jar</action>
+ <action dev="poi-developers" type="fix">49189 - detect w:tab and w:cr entries in xwpf paragraphs, even when the xsd is silly and maps them to ctempty</action>
+ <action dev="poi-developers" type="fix">49273 - correct handling for font character sets with indicies greater than 127</action>
+ <action dev="poi-developers" type="add">49334 - track the valuerangerecords of charts in hssfchart, to allow the basic axis operations</action>
+ <action dev="poi-developers" type="add">49242 - track the linkdatarecords of charts in hssfchart</action>
+ <action dev="poi-developers" type="add">improved performance of xssfworkbook.write </action>
+ <action dev="poi-developers" type="fix">48846 - avoid npe when finding cell comments</action>
+ <action dev="poi-developers" type="fix">49325 - ensure that ctphoneticpr is included in poi-ooxml jar</action>
+ <action dev="poi-developers" type="fix">49191 - fixed tests failing in non-english locales</action>
+ <action dev="poi-developers" type="add">48432 - support for xssf themes</action>
+ <action dev="poi-developers" type="add">49244 - support for data validation for ooxml format</action>
+ <action dev="poi-developers" type="add">49066 - worksheet/cell formatting, with view and html converter</action>
+ <action dev="poi-developers" type="fix">49020 - workaround excel outputting invalid xml in button definitions by not closing br tags</action>
+ <action dev="poi-developers" type="fix">49050 - improve performance of abstractescherholderrecord when there are lots of continue records</action>
+ <action dev="poi-developers" type="fix">49194 - correct text size limit for ooxml .xlsx files</action>
+ <action dev="poi-developers" type="fix">49254 - fix cellutils.setfont to use the correct type internally</action>
+ <action dev="poi-developers" type="fix">49139 - properly support 4k big block size in poifs</action>
+ <action dev="poi-developers" type="fix">48936 - avoid writing malformed cdata blocks in sharedstrings.xml</action>
+ <action dev="poi-developers" type="add">49026 - added implementation for text() </action>
+ <action dev="poi-developers" type="add">49025 - added implementation for trunc() </action>
+ <action dev="poi-developers" type="fix">49147 - properly close internal inputstream in extractorfactory#createextractor(file)</action>
+ <action dev="poi-developers" type="fix">49138 - fixed locale-sensitive formatters in packagepropertiespart</action>
+ <action dev="poi-developers" type="fix">49153 - ensure that ctvectorvariant is included in poi-ooxml-schemas.jar</action>
+ <action dev="poi-developers" type="add">49146 - added accessors to coreproperties.keywords </action>
+ <action dev="poi-developers" type="fix">48916 - propagate parent to parent-aware records decoded from escher</action>
+ <action dev="poi-developers" type="fix">48485 - add extra paper size constans to printsetup, such as a3, b4 and b5</action>
+ <action dev="poi-developers" type="fix">make poifs.filesystem.directorynode preserve the original ordering of its files, which hsmf needs to be able to correctly match up chunks</action>
+ <action dev="poi-developers" type="add">support evaluation of indirect defined names in indirect</action>
+ <action dev="poi-developers" type="fix">43670 - improve hdgf chunkv11 separator detection, and short string detection, to solve the "negative length of chunkheader" problem</action>
+ <action dev="poi-developers" type="add">48617 - optionally allow the overriding of the locale used by dataformatter to control how the default number and date formats should look</action>
+ <action dev="poi-developers" type="add">new event based xssf text extractor (xssfeventbasedexcelextractor)</action>
+ <action dev="poi-developers" type="add">extractorfactory can now be told to prefer event based extractors (current excel only) on a per-thread or overall basis</action>
+ <action dev="poi-developers" type="fix">48544 - avoid failures in xlsx2csv when shared string table is missing</action>
+ <action dev="poi-developers" type="fix">48571 - properly close all io streams created in opcpackage</action>
+ <action dev="poi-developers" type="fix">48572 - always copy all declared inner classes and interfaces when generating poi-ooxml-schemas</action>
+ <action dev="poi-developers" type="add">low level record support for the extrst (phonetic text) part of unicode strings. no usermodel access to it as yet though.</action>
+ <action dev="poi-developers" type="fix">record.unicodestring has moved to record.common.unicodestring, to live with the other record-part classes, as it isn't a full record.</action>
+ <action dev="poi-developers" type="add">avoid creating temporary files when opening opc packages from input stream</action>
+ <action dev="poi-developers" type="add">improved how hsmf handles multiple recipients</action>
+ <action dev="poi-developers" type="add">add publishertextextractor support to extractorfactory</action>
+ <action dev="poi-developers" type="add">add xslf support for text extraction from tables</action>
+ <action dev="poi-developers" type="add">support attachments as embeded documents within the new outlooktextextractor</action>
+ <action dev="poi-developers" type="add">add a text extractor (outlooktextextractor) to hsmf for simpler extraction of text from .msg files</action>
+ <action dev="poi-developers" type="fix">some improvements to hsmf parsing of .msg files</action>
+ <action dev="poi-developers" type="fix">initialise the link type of hssfhyperlink, so that gettype() on it works</action>
+ <action dev="poi-developers" type="fix">48425 - improved performance of dateutil.iscelldateformatted() </action>
+ <action dev="poi-developers" type="fix">47215 - fixed interfaceendrecord to tolerate unexpected record contents </action>
+ <action dev="poi-developers" type="fix">48415 - improved javadoc on hsspicture.resize() </action>
+ <action dev="poi-developers" type="add">added ant target to install artifacts in local repository </action>
+ <action dev="poi-developers" type="fix">48026 - fixed pagesettingsblock to allow multiple headerfooterrecord records </action>
+ <action dev="poi-developers" type="fix">48202 - fixed cellrangeutil.mergecellranges to work for adjacent cell regions </action>
+ <action dev="poi-developers" type="fix">48339 - fixed externalnamerecord to properly distinguish dde data from ole data items </action>
+ <action dev="poi-developers" type="fix">47920 - allow editing workbooks embedded into powerpoint files</action>
+ <action dev="poi-developers" type="add">48343 - added implementation of subtotal function</action>
+ <action dev="poi-developers" type="fix">switch to compiling the ooxml schemas for java 1.5</action>
+ </release>
+ <release version="3.6" date="2009-12-14">
+ <action dev="poi-developers" type="fix">48332 - fixed xssfsheet autosizecolumn() to tolerate empty richtextstring</action>
+ <action dev="poi-developers" type="fix">48332 - fixed columninforecord to tolerate missing reserved field</action>
+ <action dev="poi-developers" type="fix">47701 - fixed recordformatexception when reading list subrecords (lbsdatasubrecord)</action>
+ <action dev="poi-developers" type="add"> memory usage optimization in xssf - avoid creating parentless xml beans</action>
+ <action dev="poi-developers" type="fix">47188 - avoid corruption of workbook when adding cell comments </action>
+ <action dev="poi-developers" type="fix">48106 - improved work with cell comments in xssf</action>
+ <action dev="poi-developers" type="add">add support for creating summaryinformation and documentsummaryinformation properties
+ on poidocuments that don't have them, via poidocument.createinformationproperties()</action>
+ <action dev="poi-developers" type="fix">48180 - be more forgiving of short chart records, which skip some unused fields</action>
+ <action dev="poi-developers" type="fix">48274 - fix erronious wrapping of byte colours in hssfpalette.findsimilarcolor</action>
+ <action dev="poi-developers" type="fix">48269 - fix fetching of error codes from xssf formula cells</action>
+ <action dev="poi-developers" type="fix">48229 - fixed javadoc for hssfsheet.setcolumnwidth and xssfsheet setcolumnwidth </action>
+ <action dev="poi-developers" type="fix">47757 - fixed xlsx2csv to avoid exception when processing cells with multiple "t" elements</action>
+ <action dev="poi-developers" type="add">48195 - short-circuit evaluation of if() and choose()</action>
+ <action dev="poi-developers" type="add">48161 - support for text extraction from ppt master slides</action>
+ <action dev="poi-developers" type="add">47970 - added a method to set arabic mode in hssfsheet</action>
+ <action dev="poi-developers" type="fix">48134 - release system resources when using picture.resize()</action>
+ <action dev="poi-developers" type="fix">48087 - avoid npe in xssfchartsheet when calling methods of the superclass</action>
+ <action dev="poi-developers" type="fix">48038 - handle reading hwpf stylesheets from non zero offsets</action>
+ <action dev="poi-developers" type="add">when running the "compile-ooxml-xsds" ant task, also generate the source jar for the ooxml schemas</action>
+ <action dev="poi-developers" type="fix">45672 - improve handling by missingrecordawarehssflistener of records that cover multiple cells (mulblankrecord and mulrkrecord)</action>
+ <action dev="poi-developers" type="fix">48096 - relaxed validation check in recalcidrecord</action>
+ <action dev="poi-developers" type="fix">48085 - improved error checking in blockallocationtablereader to trap unreasonable field values</action>
+ <action dev="poi-developers" type="fix">47924 - fixed logic for matching cells and comments in hssfcell.getcellcomment()</action>
+ <action dev="poi-developers" type="add">47942 - added implementation of protection features to xlsx and docx files</action>
+ <action dev="poi-developers" type="fix">48070 - preserve leading and trailing white spaces in xssfrichtextstring</action>
+ <action dev="poi-developers" type="add">48044 - added implementation for countblank function</action>
+ <action dev="poi-developers" type="fix">48036 - added intersectioneval to allow evaluation of the intersection formula operator</action>
+ <action dev="poi-developers" type="fix">47999 - avoid un-needed call to the jvm garbage collector when working on ooxml opc packages</action>
+ <action dev="poi-developers" type="add">47922 - added example hsmf application that converts a .msg file to text and extracts attachments</action>
+ <action dev="poi-developers" type="add">47903 - added ant target to compile scratchpad examples</action>
+ <action dev="poi-developers" type="add">47839 - improved api for ooxml custom properties</action>
+ <action dev="poi-developers" type="fix">47862 - fixed xssfsheet.setcolumnwidth to handle columns included in a column span</action>
+ <action dev="poi-developers" type="fix">47804 - fixed xssfsheet.setcolumnhidden to handle columns included in a column span</action>
+ <action dev="poi-developers" type="fix">47889 - fixed xssfcell.getstringcellvalue() to properly handle cached formula results</action>
+ </release>
+ <release version="3.5-final" date="2009-09-28">
+ <action dev="poi-developers" type="fix">47747 - fixed logic for locating shared formula records</action>
+ <action dev="poi-developers" type="add">47809 - improved work with user-defined functions</action>
+ <action dev="poi-developers" type="fix">47581 - fixed xssfsheet.setcolumnwidth to produce xml compatible with mac excel 2008</action>
+ <action dev="poi-developers" type="fix">47734 - removed unnecessary svn:executable flag from files in svn trunk</action>
+ <action dev="poi-developers" type="fix">47543 - added javadoc how to avoid excel crash when creating too many hssfrichtextstring cells</action>
+ <action dev="poi-developers" type="fix">47813 - fixed problems with xssfworkbook.removesheetat when workbook contains chart</action>
+ <action dev="poi-developers" type="fix">47737 - adjust sheet indices of named ranges when deleting sheets</action>
+ <action dev="poi-developers" type="fix">47770 - built-in positive formats don't need starting '('</action>
+ <action dev="poi-developers" type="add">47771 - added method setfunction(boolean) for defined names</action>
+ <action dev="poi-developers" type="add">47768 - implementation of excel "days360" and "npv" functions</action>
+ <action dev="poi-developers" type="fix">47751 - do not allow hssf's cell text longer than 32,767 characters</action>
+ <action dev="poi-developers" type="add">47757 - added an example demonstrating how to convert an xlsx workbook to csv</action>
+ <action dev="poi-developers" type="fix">44770 - fixed ppt parser to tolerate comment2000 containers with missing comment text</action>
+ <action dev="poi-developers" type="fix">47773 - fix for extraction paragraphs and sections from headers/footers with xwpfwordextractor</action>
+ <action dev="poi-developers" type="fix">47727 - support for extraction of header / footer images in hwpf</action>
+ <action dev="poi-developers" type="fix">moved all test data to a top-level directory</action>
+ <action dev="POI-DEVELOPERS" type="add">47721 - Added implementation for INDIRECT()</action>
+ <action dev="POI-DEVELOPERS" type="add">45583 - Avoid exception when reading ClipboardData packet in OLE property sets</action>
+ <action dev="POI-DEVELOPERS" type="add">47652 - Added support for reading encrypted workbooks</action>
+ <action dev="POI-DEVELOPERS" type="add">47604 - Implementation of an XML to XLSX Importer using Custom XML Mapping</action>
+ <action dev="POI-DEVELOPERS" type="fix">47620 - Avoid FormulaParseException in XSSFWorkbook.setRepeatingRowsAndColumns when removing repeated rows and columns</action>
+ <action dev="POI-DEVELOPERS" type="fix">47606 - Fixed XSSFCell to correctly parse column indexes greater than 702 (ZZ)</action>
+ <action dev="POI-DEVELOPERS" type="fix">47598 - Improved formula evaluator number comparison</action>
+ <action dev="POI-DEVELOPERS" type="fix">47571 - Fixed XWPFWordExtractor to extract inserted/deleted text</action>
+ <action dev="POI-DEVELOPERS" type="fix">47548 - Fixed RecordFactoryInputStream to properly read continued DrawingRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix">46419 - Fixed compatibility issue with OpenOffice 3.0</action>
+ <action dev="POI-DEVELOPERS" type="fix">47559 - Fixed compatibility issue with Excel 2008 Mac sp2. Please see
+ <link href="./spreadsheet/index.html"> the HSSF+XSSF project page</link> for more information. </action>
+ <action dev="POI-DEVELOPERS" type="fix">47540 - Fix for saving custom and extended OOXML properties</action>
+ <action dev="POI-DEVELOPERS" type="fix">47535 - Fixed WordExtractor to tolerate files with empty footnote block</action>
+ <action dev="POI-DEVELOPERS" type="fix">47517 - Fixed ExtractorFactory to support .xltx and .dotx files</action>
+ <action dev="POI-DEVELOPERS" type="add">45556 - Support for extraction of footnotes from docx files</action>
+ <action dev="POI-DEVELOPERS" type="add">45555 - Support for extraction of endnotes from docx files</action>
+ <action dev="POI-DEVELOPERS" type="add">47520 - Initial support for custom XML mappings in XSSF</action>
+ <action dev="POI-DEVELOPERS" type="fix">47460 - Fixed NPE when retrieving core properties from a newly created workbook</action>
+ <action dev="POI-DEVELOPERS" type="fix">47498 - Fixed HyperlinkRecord to properly handle URL monikers</action>
+ <action dev="POI-DEVELOPERS" type="fix">47504 - Fixed XSSFWorkbook to read files with hyperlinks to document locations</action>
+ <action dev="POI-DEVELOPERS" type="fix">47479 - Fix BoolErrRecord to tolerate incorrect format written by OOO</action>
+ <action dev="POI-DEVELOPERS" type="fix">47448 - Allow HSSFEventFactory to handle non-zero padding at the end of the workbook stream</action>
+ <action dev="POI-DEVELOPERS" type="add">47456 - Support for getting OLE object data in PowerPointExtractor</action>
+ <action dev="POI-DEVELOPERS" type="fix">47411 - Explicitly set the 1900 date system when creating XSSF workbooks</action>
+ <action dev="POI-DEVELOPERS" type="add">47400 - Support for text extraction of footnotes, endnotes and comments in HWPF</action>
+ <action dev="POI-DEVELOPERS" type="fix">47415 - Fixed PageSettingsBlock to allow multiple PLS records</action>
+ <action dev="POI-DEVELOPERS" type="fix">47412 - Fixed concurrency issue with EscherProperties.initProps()</action>
+ <action dev="POI-DEVELOPERS" type="fix">47143 - Fixed OOM in HSSFWorkbook#getAllPictures when reading .xls files containing metafiles</action>
+ <action dev="POI-DEVELOPERS" type="add">Added implementation for ISNA()</action>
+ <action dev="POI-DEVELOPERS" type="add">46793 - fixed SimpleShape#getLineWidth to handle default line width </action>
+ <action dev="POI-DEVELOPERS" type="add">47356 - removed unused private fields in HWPF BorderCode</action>
+ <action dev="POI-DEVELOPERS" type="add">47355 - Improved HWPF TableCell to expose TableCellDescriptor</action>
+ <action dev="POI-DEVELOPERS" type="fix">46610 - Improved HWPF to better handle unicode</action>
+ <action dev="POI-DEVELOPERS" type="fix">47261 - Fixed SlideShow#removeSlide to remove references to Notes</action>
+ <action dev="POI-DEVELOPERS" type="fix">47375 - Fixed HSSFHyperlink to correctly set inter-sheet and file links</action>
+ <action dev="POI-DEVELOPERS" type="fix">47384 - Fixed ExternalNameRecord to handle unicode names</action>
+ <action dev="POI-DEVELOPERS" type="fix">47372 - Fixed locale-sensitive unit tests to pass when running on non-US locale</action>
+ </release>
+ <release version="3.5-beta6" date="2009-06-22">
+ <action dev="POI-DEVELOPERS" type="fix">47363 - Fixed HSSFSheet to allow addition of data validations after sheet protection</action>
+ <action dev="POI-DEVELOPERS" type="fix">47294 - Fixed XSSFWorkbook#setRepeatingRowsAndColumns to tolerate sheet names with quotes</action>
+ <action dev="POI-DEVELOPERS" type="fix">47309 - Fixed logic in HSSFCell.getCellComment to handle sheets with more than 65536 comments</action>
+ <action dev="POI-DEVELOPERS" type="fix">46776 - Added clone() method to MulBlankRecord to fix crash in Sheet.cloneSheet()</action>
+ <action dev="POI-DEVELOPERS" type="fix">47244 - Fixed HSSFSheet to handle missing header / footer records</action>
+ <action dev="POI-DEVELOPERS" type="fix">47312 - Fixed formula parser to properly reject cell references with a '0' row component</action>
+ <action dev="POI-DEVELOPERS" type="fix">47199 - Fixed PageSettingsBlock/Sheet to tolerate margin records after other non-PSB records</action>
+ <action dev="POI-DEVELOPERS" type="fix">47069 - Fixed HSSFSheet#getFirstRowNum and HSSFSheet#getLastRowNum to return correct values after removal of all rows</action>
+ <action dev="POI-DEVELOPERS" type="fix">47278 - Fixed XSSFCell to avoid generating xsi:nil entries in shared string table</action>
+ <action dev="POI-DEVELOPERS" type="fix">47206 - Fixed XSSFCell to properly read inline strings</action>
+ <action dev="POI-DEVELOPERS" type="add">47250 - Fixed FontRecord to expect unicode flags even when name length is zero</action>
+ <action dev="POI-DEVELOPERS" type="add">47198 - Fixed formula evaluator comparison of -0.0 and 0.0</action>
+ <action dev="POI-DEVELOPERS" type="add">47229 - Fixed ExternalNameRecord to handle DDE links</action>
+ <action dev="POI-DEVELOPERS" type="add">46287 - Control of header and footer extraction in ExcelExtractor / XSSFExcelExtractor</action>
+ <action dev="POI-DEVELOPERS" type="add">46554 - New ant target "jar-examples"</action>
+ <action dev="POI-DEVELOPERS" type="add">46161 - Support in XSSF for setGroupColumnCollapsed and setGroupRowCollapsed</action>
+ <action dev="POI-DEVELOPERS" type="add">46806 - Allow columns greater than 255 and rows greater than 0x100000 in XSSF formulas</action>
+ <action dev="POI-DEVELOPERS" type="add">41711 - Base class for "old version" exceptions, and new HSLF detection + use of old versions exception</action>
+ <action dev="POI-DEVELOPERS" type="fix">47179 - Fix string encoding issues with HSMF chunks on non-windows platforms</action>
+ <action dev="POI-DEVELOPERS" type="add">47183 - Attachment support for HSMF</action>
+ <action dev="POI-DEVELOPERS" type="fix">47154 - Handle the cell format @ as the same as General</action>
+ <action dev="POI-DEVELOPERS" type="fix">47048 - Fixed evaluation of defined names with the 'complex' flag set</action>
+ <action dev="POI-DEVELOPERS" type="fix">46953 - More tweaks to PageSettingsBlock parsing logic in Sheet constructor</action>
+ <action dev="POI-DEVELOPERS" type="fix">47089 - Fixed XSSFWorkbook.createSheet to properly increment sheetId</action>
+ <action dev="POI-DEVELOPERS" type="fix">46568 - Fixed XSLFPowerPointExtractor to properly process line breaks</action>
+ <action dev="POI-DEVELOPERS" type="fix">39056 - Fixed POIFSFileSystem to set CLSID of root when constructing instances from InputStream</action>
+ <action dev="POI-DEVELOPERS" type="fix">47054 - Fixed cloneStyleFrom to avoid exception when cloning styles of the same family</action>
+ <action dev="POI-DEVELOPERS" type="fix">46186 - Fixed Sheet to read GutsRecord in the Sheet(RecordStream rs)</action>
+ <action dev="POI-DEVELOPERS" type="fix">46714 - Automatically call sheet.setAlternativeExpression when sheet.setRowSumsBelow is called </action>
+ <action dev="POI-DEVELOPERS" type="fix">46279 - Allow 255 arguments for excel functions in XSSF </action>
+ <action dev="POI-DEVELOPERS" type="fix">47028 - Fixed XSSFCell to preserve cell style when cell value is set to blank</action>
+ <action dev="POI-DEVELOPERS" type="fix">47026 - Avoid NPE in XSSFCell.setCellType() when workbook does not have SST</action>
+ <action dev="POI-DEVELOPERS" type="fix">46987 - Allow RecordFactory to handle non-zero padding at the end of the workbook stream</action>
+ <action dev="POI-DEVELOPERS" type="fix">47034 - Fix reading the name of a NameRecord when the name is very long</action>
+ <action dev="POI-DEVELOPERS" type="fix">47001 - Fixed WriteAccessRecord and LinkTable to handle unusual format written by Google Docs</action>
+ <action dev="POI-DEVELOPERS" type="fix">46973 - Fixed defined names to behave better when refersToFormula is unset</action>
+ <action dev="POI-DEVELOPERS" type="fix">46832 - Allow merged regions with columns greater than 255 or rows bigger than 65536 in XSSF</action>
+ <action dev="POI-DEVELOPERS" type="fix">46951 - Fixed formula parser to better handle range operators and whole row/column refs.</action>
+ <action dev="POI-DEVELOPERS" type="fix">46948 - Fixed evaluation of range operator to allow for area-ref operands</action>
+ <action dev="POI-DEVELOPERS" type="fix">46918 - Fixed ExtendedPivotTableViewFieldsRecord(SXVDEX) to allow shorter format</action>
+ <action dev="POI-DEVELOPERS" type="fix">46898 - Fixed formula evaluator to not cache intermediate circular-reference error results</action>
+ <action dev="POI-DEVELOPERS" type="fix">46917 - Fixed PageItemRecord(SXPI) to allow multiple field infos</action>
+ <action dev="POI-DEVELOPERS" type="fix">46904 - Fix POIFS issue with duplicate block 0 references on very old BIFF5/BIFF7 files</action>
+ <action dev="POI-DEVELOPERS" type="fix">46840 - PageSettingsBlock should include HEADERFOOTER record</action>
+ <action dev="POI-DEVELOPERS" type="fix">46885 - update cell type when setting cached formula result in XSSFCell</action>
+ <action dev="POI-DEVELOPERS" type="add">added modifiers for anchor type to XSSFClientAnchor</action>
+ <action dev="POI-DEVELOPERS" type="add">46772 - support built-in data formats in XSSFDataFormat</action>
+ <action dev="POI-DEVELOPERS" type="fix">46719 - fixed XSSFSheet.shiftRows to correctly preserve row heights</action>
+ <action dev="POI-DEVELOPERS" type="fix">46715 - preserve custom column widths across re-serialization of XSSFWorkbook</action>
+ <action dev="POI-DEVELOPERS" type="add">46703 - added setDisplayZeros / isDisplayZeros to common interface org.apache.poi.ss.usermodel.Sheet</action>
+ <action dev="POI-DEVELOPERS" type="add">46708 - added getMergedRegion(int) to common interface org.apache.poi.ss.usermodel.Sheet</action>
+ <action dev="POI-DEVELOPERS" type="fix">fixed Sheet.autoSizeColumn() to use cached formula values when processing formula cells </action>
+ <action dev="POI-DEVELOPERS" type="fix">Fixed formula parser to handle names with backslashes</action>
+ <action dev="POI-DEVELOPERS" type="add">46660 - added Workbook getHidden() and setHidden(boolean)</action>
+ <action dev="POI-DEVELOPERS" type="fix">46693 - Fixed bugs serialization bugs in records: CHARTFORMAT, SHTPROPS, SXVD and SXVDEX</action>
+ <action dev="POI-DEVELOPERS" type="fix">46627 - Fixed offset of added images if Pictures stream contains pictures with zero length</action>
+ </release>
+ <release version="3.5-beta5" date="2009-02-19">
+ <action dev="POI-DEVELOPERS" type="fix">46536 - When shifting rows, update formulas on that sheet to point to the new location of those rows</action>
+ <action dev="POI-DEVELOPERS" type="fix">46663 - Fixed XSSFSheet.shiftRows to properly update references of the shifted cells</action>
+ <action dev="POI-DEVELOPERS" type="fix">46535 - Remove reference from calculation chain when a formula is deleted</action>
+ <action dev="POI-DEVELOPERS" type="fix">46654 - HSSFRow/RowRecord to properly update cell boundary indexes</action>
+ <action dev="POI-DEVELOPERS" type="fix">46643 - Fixed formula parser to encode range operator with tMemFunc</action>
+ <action dev="POI-DEVELOPERS" type="fix">46647 - Fixed COUNTIF NE operator and other special cases involving type conversion</action>
+ <action dev="POI-DEVELOPERS" type="add">46635 - Added a method to remove slides</action>
+ <action dev="POI-DEVELOPERS" type="fix">40520 - Fixed HSSFFont.applyFont() to properly apply font to overlapping regions</action>
+ <action dev="POI-DEVELOPERS" type="fix">46545 - Fixed ObjRecord to ignore excessive padding written by previous POI versions</action>
+ <action dev="POI-DEVELOPERS" type="fix">46613 - Fixed evaluator to perform case insensitive string comparisons</action>
+ <action dev="POI-DEVELOPERS" type="add">46544 - command line interface for hssf ExcelExtractor</action>
+ <action dev="POI-DEVELOPERS" type="fix">46547 - Allow addition of conditional formatting after data validation</action>
+ <action dev="POI-DEVELOPERS" type="fix">46548 - Page Settings Block fixes - continued PLS records and PSB in sheet sub-streams</action>
+ <action dev="POI-DEVELOPERS" type="add">46523 - added implementation for SUMIF function</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for reading HSSF column styles</action>
+ <action dev="POI-DEVELOPERS" type="fix">Hook up POIXMLTextExtractor.getMetadataTextExtractor() to the already written POIXMLPropertiesTextExtractor</action>
+ <action dev="POI-DEVELOPERS" type="fix">46472 - Avoid NPE in HPSFPropertiesExtractor when no properties exist</action>
+ <action dev="POI-DEVELOPERS" type="fix">46479 - fixed bugs related to cached formula values and HSSFFormulaEvaluator.evaluateInCell()</action>
+ <action dev="POI-DEVELOPERS" type="add">45031 - added implementation for CHOOSE() function</action>
+ <action dev="POI-DEVELOPERS" type="fix">46361 - resolve licensing issues around the HDGF resource file, chunks_parse_cmds.tbl</action>
+ <action dev="POI-DEVELOPERS" type="add">46410 - added implementation for TIME() function</action>
+ <action dev="POI-DEVELOPERS" type="add">46320 - added HSSFPictureData.getFormat()</action>
+ <action dev="POI-DEVELOPERS" type="fix">46445 - fixed HSSFSheet.shiftRow to move hyperlinks</action>
+ <action dev="POI-DEVELOPERS" type="fix">fixed formula parser to correctly resolve sheet-level names</action>
+ <action dev="POI-DEVELOPERS" type="fix">46433 - support for shared formulas in XSSF</action>
+ <action dev="POI-DEVELOPERS" type="add">46299 - support for carriage return and line break in XWPFRun</action>
+ <action dev="POI-DEVELOPERS" type="add">46300 - support for line spacing in XWPFParagraph</action>
+ <action dev="POI-DEVELOPERS" type="add">46308 - initial support for creation of XWPFTable</action>
+ <action dev="POI-DEVELOPERS" type="add">Added getters to parent objects: HSSFSheet.getWorkbook(), HSSFRow.getSheet() and HSSFCell.getRow()</action>
+ <action dev="POI-DEVELOPERS" type="fix">46385 - (also patch 46362) fix serialization of StyleRecord with unicode name</action>
+ <action dev="POI-DEVELOPERS" type="fix">46368 - Fix HSSFRichTextRun and strings longer than 32768 characters</action>
+ <action dev="POI-DEVELOPERS" type="add">Support sheet-level names</action>
+ <action dev="POI-DEVELOPERS" type="fix">Fixed XSSFCell to properly handle cell references with column numbers up to XFD</action>
+ <action dev="POI-DEVELOPERS" type="fix">44914 - Fixed warning message "WARN. Unread n bytes of record 0xNN"</action>
+ <action dev="POI-DEVELOPERS" type="add">46156 - Improved number to text conversion to be closer to that of Excel</action>
+ <action dev="POI-DEVELOPERS" type="fix">46312 - Fixed ValueRecordsAggregate to handle removal of new empty row</action>
+ <action dev="POI-DEVELOPERS" type="add">46269 - Improved error message when attempting to read BIFF2 file</action>
+ <action dev="POI-DEVELOPERS" type="fix">46206 - Fixed Sheet to tolerate missing DIMENSION records</action>
+ <action dev="POI-DEVELOPERS" type="add">46301 - added pivot table records: SXDI, SXVDEX, SXPI, SXIDSTM, SXVIEW, SXVD, SXVS, et al</action>
+ <action dev="POI-DEVELOPERS" type="fix">46280 - Fixed RowRecordsAggregate etc to properly skip PivotTable records</action>
+ </release>
+ <release version="3.5-beta4" date="2008-11-29">
+ <action dev="POI-DEVELOPERS" type="fix">46213 - Fixed FormulaRecordAggregate to gracefully ignore extra StringRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix">46174 - Fixed HSSFName to handle general formulas (not just area references)</action>
+ <action dev="POI-DEVELOPERS" type="add">46189 - added chart records: CHARTFRTINFO, STARTBLOCK, ENDBLOCK, STARTOBJECT, ENDOBJECT, and CATLAB</action>
+ <action dev="POI-DEVELOPERS" type="fix">46199 - More tweaks to EmbeddedObjectRefSubRecord</action>
+ <action dev="POI-DEVELOPERS" type="add">Changes to formula evaluation allowing for reduced memory usage</action>
+ <action dev="POI-DEVELOPERS" type="fix">45290 - Support odd files where the POIFS header block comes after the data blocks, and is on the data blocks list</action>
+ <action dev="POI-DEVELOPERS" type="fix">46184 - More odd escaped date formats</action>
+ <action dev="POI-DEVELOPERS" type="add">Include the sheet number in the output of XLS2CSVmra</action>
+ <action dev="POI-DEVELOPERS" type="fix">46043 - correctly write out HPSF properties with HWPF</action>
+ <action dev="POI-DEVELOPERS" type="add">45973 - added CreationHelper.createFormulaEvaluator(), implemeted both for HSSF and XSSF</action>
+ <action dev="POI-DEVELOPERS" type="fix">46182 - fixed Slideshow.readPictures() to skip pictures with invalid headers</action>
+ <action dev="POI-DEVELOPERS" type="fix">46137 - Handle odd files with a ContinueRecord after EOFRecord</action>
+ <action dev="POI-DEVELOPERS" type="fix">Fixed problem with linking shared formulas when ranges overlap</action>
+ <action dev="POI-DEVELOPERS" type="fix">45784 - More fixes to SeriesTextRecord</action>
+ <action dev="POI-DEVELOPERS" type="fix">46033 - fixed TableCell to correctly set text type</action>
+ <action dev="POI-DEVELOPERS" type="fix">46122 - fixed Picture.draw to skip rendering if picture data was not found</action>
+ <action dev="POI-DEVELOPERS" type="fix">15716 - memory usage optimisation - converted Ptg arrays into Formula objects</action>
+ <action dev="POI-DEVELOPERS" type="add">46065 - added implementation for VALUE function</action>
+ <action dev="POI-DEVELOPERS" type="add">45966 - added implementation for FIND function</action>
+ <action dev="POI-DEVELOPERS" type="fix">45778 - fixed ObjRecord to read ftLbsData properly</action>
+ <action dev="POI-DEVELOPERS" type="fix">46053 - fixed evaluation cache dependency analysis when changing blank cells</action>
+ </release>
+ <release version="3.5-beta3" date="2008-09-26">
+ <action dev="POI-DEVELOPERS" type="fix">45518 - Fix up ColumnHelper to output valid col tags, by making 1 based and 0 based bits clearer, and using the right ones</action>
+ <action dev="POI-DEVELOPERS" type="fix">45676 - Handle very long cells in the XSSF EventUserModel example</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial ExtractorFactory support for building TextExtractors for embeded documents</action>
+ </release>
+ <release version="3.5-beta2" date="2008-08-20">
+ <action dev="POI-DEVELOPERS" type="add">Support stripping XSSF header and footer fields (eg page number) out of header and footer text if required</action>
+ <action dev="POI-DEVELOPERS" type="add">Add POIXMLPropertiesTextExtractor, which provides to the OOXML file formats a similar function to HPSF's HPSFPropertiesExtractor</action>
+ <action dev="POI-DEVELOPERS" type="add">45539 - Improve XWPFWordExtractor to extract headers and footers</action>
+ <action dev="POI-DEVELOPERS" type="fix">Improve how XWPF handles paragraph text</action>
+ <action dev="POI-DEVELOPERS" type="add">Support in XWPF handles headers and footers</action>
+ <action dev="POI-DEVELOPERS" type="add">45592 - Improve XWPF text extraction to include tables always, and picture text where possible</action>
+ <action dev="POI-DEVELOPERS" type="add">45545 - Improve XSLF usermodel support, and include XSLF comments in extracted text</action>
+ <action dev="POI-DEVELOPERS" type="add">45540 - Fix XSSF header and footer support, and include headers and footers in the output of XSSFExcelExtractor</action>
+ <action dev="POI-DEVELOPERS" type="add">45431 - Support for .xlsm files, sufficient for simple files to be loaded by excel without warning</action>
+ <action dev="POI-DEVELOPERS" type="add">New class org.apache.poi.hssf.record.RecordFormatException, which DDF uses instead of the HSSF version, and the HSSF version inherits from</action>
+ <action dev="POI-DEVELOPERS" type="add">45431 - Partial support for .xlm files. Not quite enough for excel to load them though</action>
+ <action dev="POI-DEVELOPERS" type="fix">45430 - Correct named range sheet reporting when no local sheet id is given in the xml</action>
+ </release>
+ <release version="3.5-beta1" date="2008-07-18">
+ <action dev="POI-DEVELOPERS" type="add">45018 - Support for fetching embeded documents from within an OOXML file</action>
+ <action dev="POI-DEVELOPERS" type="add">Port support for setting a policy on missing / blank cells when fetching, to XSSF too</action>
+ <action dev="POI-DEVELOPERS" type="add">Common text extraction factory, which returns the correct POITextExtractor for the supplied data</action>
+ <action dev="POI-DEVELOPERS" type="add">Text Extraction support for the new OOXML files (.xlsx, .docx and .pptx)</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial support for processing OOXML Excel files (.xlsx), both directly through XSSF, and also through the new common UserModel</action>
+ <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
+ <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
+ </release>
+ <release version="3.2-FINAL" date="2008-10-19">
+ <action dev="POI-DEVELOPERS" type="fix">45866 - allowed for change of unicode compression across Continue records</action>
+ <action dev="POI-DEVELOPERS" type="fix">45964 - support for link formulas in Text Objects</action>
+ <action dev="POI-DEVELOPERS" type="fix">43354 - support for evalating formulas with missing args</action>
+ <action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
+ <action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>
+ <action dev="POI-DEVELOPERS" type="add">Initial support for creating hyperlinks in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">45876 - fixed BoundSheetRecord to allow sheet names longer than 31 chars</action>
+ <action dev="POI-DEVELOPERS" type="add">45890 - fixed HSSFSheet.shiftRows to also update conditional formats</action>
+ <action dev="POI-DEVELOPERS" type="add">45865 modified Formula Parser/Evaluator to handle cross-worksheet formulas</action>
+ <action dev="POI-DEVELOPERS" type="add">Optimised the FormulaEvaluator to take cell dependencies into account</action>
+ <action dev="POI-DEVELOPERS" type="add">16936 - Initial support for whole-row cell styling</action>
+ <action dev="POI-DEVELOPERS" type="add">Update hssf.extractor.ExcelExtractor to optionally output blank cells too</action>
+ <action dev="POI-DEVELOPERS" type="add">Include the sheet name in the output of examples.XLS2CSVmra</action>
+ <action dev="POI-DEVELOPERS" type="fix">45784 - Support long chart titles in SeriesTextRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix">45777 - Throw an exception if HSSF Footer or Header is attemped to be set too long, rather than having it break during writing out</action>
+ <action dev="POI-DEVELOPERS" type="add">45844 - Addtional diagnostics for HSLF SlideShowRecordDumper</action>
+ <action dev="POI-DEVELOPERS" type="fix">45829 - HSSFPicture.getImageDimension() failed when DPI of image is zero</action>
+ <action dev="POI-DEVELOPERS" type="fix">45815 - Bit mask values in StyleTextPropAtom were not preserved across read-write</action>
+ <action dev="POI-DEVELOPERS" type="add">45814 - Specify RecordType for slide show Handout (4041)</action>
+ <action dev="POI-DEVELOPERS" type="fix">45805 - Fixed 16-bit signed/unsigned bug in HSSFSheet.getColWidth etc</action>
+ <action dev="POI-DEVELOPERS" type="fix">45780 - Fixed HSSFSheet.shiftRows to also update Area refs</action>
+ <action dev="POI-DEVELOPERS" type="fix">45804 - Update HSMF to handle Outlook 3.0 msg files, which have a different string chunk type</action>
+ <action dev="POI-DEVELOPERS" type="add">Expose the name of Named Cell Styles via HSSFCellStyle (normally held on the parent style though)</action>
+ <action dev="POI-DEVELOPERS" type="fix">45978 - Fixed IOOBE in Ref3DPtg.toFormulaString() due eager initialisation of SheetReferences</action>
+ <action dev="POI-DEVELOPERS" type="add">Made HSSFFormulaEvaluator no longer require initialisation with sheet or row</action>
+ <action dev="POI-DEVELOPERS" type="add">Extended support for cached results of formula cells</action>
+ <action dev="POI-DEVELOPERS" type="fix">45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate</action>
+ <action dev="POI-DEVELOPERS" type="fix">Fixed special cases of INDEX function (single column/single row, errors)</action>
+ <action dev="POI-DEVELOPERS" type="add">45761 - Support for Very Hidden excel sheets in HSSF</action>
+ <action dev="POI-DEVELOPERS" type="add">45738 - Initial HWPF support for Office Art Shapes</action>
+ <action dev="POI-DEVELOPERS" type="fix">45720 - Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings</action>
+ <action dev="POI-DEVELOPERS" type="fix">45728 - Fix for SlideShow.reorderSlide in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial support for embedded movies and controls in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF()</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for HPBF Publisher hyperlinks, including during text extraction</action>
+ <action dev="POI-DEVELOPERS" type="fix">26321 and 44958 - preserve position of ArrayRecords and TableRecords among cell value records</action>
+ <action dev="POI-DEVELOPERS" type="fix">Impove empty header or footer handling in HWPF HeaderStories</action>
+ <action dev="POI-DEVELOPERS" type="fix">Avoid NPE in hssf.usermodel.HeaderFooter when stripping fields out</action>
+ <action dev="POI-DEVELOPERS" type="fix">Avoid NPE in EscherBSERecord on older escher records</action>
+ <action dev="POI-DEVELOPERS" type="add">Basic text extractraction support in HPBF</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial, low level support for Publisher files, in the form of HPBF</action>
+ <action dev="POI-DEVELOPERS" type="fix">45699 - Fix RowRecordsAggregate to tolerate intervening MERGEDCELLS records</action>
+ <action dev="POI-DEVELOPERS" type="fix">45698 - Fix LinkTable to tolerate multiple EXTERNSHEET records</action>
+ <action dev="POI-DEVELOPERS" type="fix">45682 - Fix for cloning of CFRecordsAggregate</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial support for evaluating external add-in functions like YEARFRAC</action>
+ <action dev="POI-DEVELOPERS" type="fix">45672 - Fix for MissingRecordAwareHSSFListener to prevent multiple LastCellOfRowDummyRecords when shared formulas are present</action>
+ <action dev="POI-DEVELOPERS" type="fix">45645 - Fix for HSSFSheet.autoSizeColumn() for widths exceeding Short.MAX_VALUE</action>
+ <action dev="POI-DEVELOPERS" type="add">45623 - Support for additional HSSF header and footer fields, including bold and full file path</action>
+ <action dev="POI-DEVELOPERS" type="add">45623 - Support stripping HSSF header and footer fields (eg page number) out of header and footer text if required</action>
+ <action dev="POI-DEVELOPERS" type="add">45622 - Support stripping HWPF fields (eg macros) out of text, via Range.stripFields(text)</action>
+ <action dev="POI-DEVELOPERS" type="add">New HPSF based TextExtractor for document metadata, org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor</action>
+ <action dev="POI-DEVELOPERS" type="fix">Properly update the array of Slide's text runs in HSLF when new text shapes are added</action>
+ <action dev="POI-DEVELOPERS" type="fix">45590 - Fix for Header/footer extraction for .ppt files saved in Office 2007</action>
+ <action dev="POI-DEVELOPERS" type="fix">Big improvement in how HWPF handles unicode text, and more sanity checking of text ranges within HWPF</action>
+ <action dev="POI-DEVELOPERS" type="add">Include headers and footers int he extracted text from HWPF's WordExtractor</action>
+ <action dev="POI-DEVELOPERS" type="add">Added support to HWPF for headers and footers</action>
+ <action dev="POI-DEVELOPERS" type="fix">Improve how HWPF deals with unicode internally. Should avoid some odd behaviour when manipulating unicode text</action>
+ <action dev="POI-DEVELOPERS" type="add">45577 - Added implementations for Excel functions NOW and TODAY</action>
+ <action dev="POI-DEVELOPERS" type="fix">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action>
+ <action dev="POI-DEVELOPERS" type="add">45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">45472 - Fixed incorrect default row height in OpenOffice 2.3</action>
+ <action dev="POI-DEVELOPERS" type="fix">44692 - HSSFPicture.resize() stretched image when there was a text next to it</action>
+ <action dev="POI-DEVELOPERS" type="add">45543 - Optionally extract comment text with PowerPointExtractor, and initial hslf model support for comments</action>
+ <action dev="POI-DEVELOPERS" type="fix">45538 - Include excel headers and footers in the output of ExcelExtractor</action>
+ <action dev="POI-DEVELOPERS" type="fix">44894 - refactor duplicate logic from EventRecordFactory to RecordFactory</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for Headers / Footers in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">44953 - Extensive fixes for data validation</action>
+ <action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
+ <action dev="POI-DEVELOPERS" type="add">45466 - Partial support for removing excel comments (won't work for all excel versions yet)</action>
+ <action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>
+ <action dev="POI-DEVELOPERS" type="add">45404 - New class, hssf.usermodel.HSSFDataFormatter, for formatting numbers and dates in the same way that Excel does</action>
+ <action dev="POI-DEVELOPERS" type="fix">45414 - Don't add too many UncalcedRecords to sheets with charts in them</action>
+ <action dev="POI-DEVELOPERS" type="fix">45398 - Support detecting date formats containing "am/pm" as date times</action>
+ <action dev="POI-DEVELOPERS" type="fix">45410 - Removed dependency from contrib on commons beanutils,collections and lang</action>
+ <action dev="POI-DEVELOPERS" type="add">New helper, HSSFOptimiser, which handles removing duplicated font and style records, to avoid going over the limits in Excel</action>
+ <action dev="POI-DEVELOPERS" type="fix">45322 - Fixed NPE in HSSFSheet.autoSizeColumn() when cell number format was not found</action>
+ <action dev="POI-DEVELOPERS" type="add">45380 - Missing return keyword in ArrayPtg.toFormulaString()</action>
+ <action dev="POI-DEVELOPERS" type="add">44958 - Record level support for Data Tables. (No formula parser support though)</action>
+ <action dev="POI-DEVELOPERS" type="add">35583 - Include a version class, org.apache.poi.Version, to allow easy introspection of the POI version</action>
+ <action dev="POI-DEVELOPERS" type="add">Allow the cloning of one HSSFCellStyle onto another, including cloning styles from one HSSFWorkbook onto another</action>
+ <action dev="POI-DEVELOPERS" type="fix">45289 - finished support for special comparison operators in COUNTIF</action>
+ <action dev="POI-DEVELOPERS" type="fix">45126 - Avoid generating multiple NamedRanges with the same name, which Excel dislikes</action>
+ <action dev="POI-DEVELOPERS" type="fix">Fix cell.getRichStringCellValue() for formula cells with string results</action>
+ <action dev="POI-DEVELOPERS" type="fix">45365 - Handle more excel number formatting rules in FormatTrackingHSSFListener / XLS2CSVmra</action>
+ <action dev="POI-DEVELOPERS" type="fix">45373 - Improve the performance of HSSFSheet.shiftRows</action>
+ <action dev="POI-DEVELOPERS" type="fix">45367 - Fixed bug when last row removed from sheet is row zero</action>
+ <action dev="POI-DEVELOPERS" type="fix">45348 - Tweaks to RVA formula logic</action>
+ <action dev="POI-DEVELOPERS" type="fix">45354 - Fixed recognition of named ranges within formulas</action>
+ <action dev="POI-DEVELOPERS" type="fix">45338 - Fix HSSFWorkbook to give you the same HSSFFont every time, and then fix it to find newly added fonts</action>
+ <action dev="POI-DEVELOPERS" type="fix">45336 - Fix HSSFColor.getTripletHash()</action>
+ <action dev="POI-DEVELOPERS" type="fix">45334 - Fixed formula parser to handle dots in identifiers</action>
+ <action dev="POI-DEVELOPERS" type="fix">45252 - Improvement for HWPF Range.replaceText()</action>
+ <action dev="POI-DEVELOPERS" type="fix">45001 - Further fix for HWPF Range.delete() and unicode characters</action>
+ <action dev="POI-DEVELOPERS" type="add">45175 - Support for variable length operands in org.apache.poi.hwpf.sprm.SprmOperation</action>
+ <action dev="POI-DEVELOPERS" type="fix">Avoid spurious missing lines with the MissingRecordAware event code, and odd files that contain RowRecords in the middle of the cell Records.</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for parsing formulas during EventUserModel processing, via the new EventWorkbookBuilder</action>
+ </release>
+ <release version="3.1-final" date="2008-06-29">
+ <action dev="POI-DEVELOPERS" type="fix">30978 - Fixed re-serialization of tRefErr3d and tAreaErr3d</action>
+ <action dev="POI-DEVELOPERS" type="fix">45234 - Removed incorrect shared formula conversion in CFRuleRecord</action>
+ <action dev="POI-DEVELOPERS" type="fix">45001 - Improved HWPF Range.replaceText()</action>
+ <action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
+ <action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
+ <action dev="POI-DEVELOPERS" type="fix">45110 - Fixed TextShape.resizeToFitText() to properly resize TextShape</action>
+ <action dev="POI-DEVELOPERS" type="fix">45091 - Fixed serialization of RefN~ tokens. Simplified Ptg class hierarchy</action>
+ <action dev="POI-DEVELOPERS" type="fix">45133 - Fixed OBJ Record (5Dh) to pad the sub-record data to a 4-byte boundary</action>
+ <action dev="POI-DEVELOPERS" type="fix">45145 - Fixed Sheet to always enforce RowRecordsAggregate before ValueRecordsAggregate</action>
+ <action dev="POI-DEVELOPERS" type="fix">45123 - Fixed SharedFormulaRecord.convertSharedFormulas() to propagate token operand classes</action>
+ <action dev="POI-DEVELOPERS" type="fix">45087 - Correctly detect date formats like [Black]YYYY as being date based</action>
+ <action dev="POI-DEVELOPERS" type="add">45060 - Improved token class transformation during formula parsing</action>
+ <action dev="POI-DEVELOPERS" type="add">44840 - Improved handling of HSSFObjectData, especially for entries with data held not in POIFS</action>
+ <action dev="POI-DEVELOPERS" type="add">45043 - Support for getting excel cell comments when extracting text</action>
+ <action dev="POI-DEVELOPERS" type="add">Extend the support for specifying a policy to HSSF on missing / blank cells when fetching, to be able to specify the policy at the HSSFWorkbook level</action>
+ <action dev="POI-DEVELOPERS" type="fix">45025 - improved FormulaParser parse error messages</action>
+ <action dev="POI-DEVELOPERS" type="fix">45046 - allowed EXTERNALBOOK(0x01AE) to be optional in the LinkTable</action>
+ <action dev="POI-DEVELOPERS" type="fix">45066 - fixed sheet encoding size mismatch problems</action>
+ <action dev="POI-DEVELOPERS" type="add">45003 - Support embeded HDGF visio documents</action>
+ <action dev="POI-DEVELOPERS" type="fix">45001 - Partial fix for HWPF Range.insertBefore() and Range.delete() with unicode characters</action>
+ <action dev="POI-DEVELOPERS" type="fix">44977 - Support for AM/PM in excel date formats</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for specifying a policy to HSSF on missing / blank cells when fetching</action>
+ <action dev="POI-DEVELOPERS" type="add">44937 - Partial support for extracting Escher images from HWPF files</action>
+ <action dev="POI-DEVELOPERS" type="fix">44824 - Avoid an infinite loop when reading some HWPF pictures</action>
+ <action dev="POI-DEVELOPERS" type="fix">44898 - Correctly handle short last blocks in POIFS</action>
+ </release>
+ <release version="3.1-beta2" date="2008-05-26">
+ <action dev="POI-DEVELOPERS" type="fix">44306 - fixed reading/writing of AttrPtg(type=choose) and method toFormulaString() for CHOOSE formulas</action>
+ <action dev="POI-DEVELOPERS" type="fix">24207 - added HSSFName.isDeleted() to check if the name points to cell that no longer exists</action>
+ <action dev="POI-DEVELOPERS" type="fix">40414 - fixed selected/active sheet after removing sheet from workbook</action>
+ <action dev="POI-DEVELOPERS" type="fix">44523 - fixed workbook sheet selection and focus</action>
+ <action dev="POI-DEVELOPERS" type="fix">45000 - Fixed NPE in ListLevel when numberText is null</action>
+ <action dev="POI-DEVELOPERS" type="fix">44985 - Properly update TextSpecInfoAtom when the parent text is changed</action>
+ <action dev="POI-DEVELOPERS" type="fix">41187 - fixed HSSFSheet to properly read xls files without ROW records</action>
+ <action dev="POI-DEVELOPERS" type="fix">44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals</action>
+ <action dev="POI-DEVELOPERS" type="fix">42570 - fixed LabelRecord to use empty string instead of null when the length is zero.</action>
+ <action dev="POI-DEVELOPERS" type="fix">42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues.</action>
+ <action dev="POI-DEVELOPERS" type="fix">Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes</action>
+ <action dev="POI-DEVELOPERS" type="fix">44929 - Improved error handling in HSSFWorkbook when attempting to read a BIFF5 file</action>
+ <action dev="POI-DEVELOPERS" type="fix">44675 - Parameter operand classes (function metadata) required to encode SUM() etc properly. Added parse validation for number of parameters</action>
+ <action dev="POI-DEVELOPERS" type="fix">44921 - allow Ptg.writeBytes() to be called on relative ref Ptgs (RefN* and AreaN*)</action>
+ <action dev="POI-DEVELOPERS" type="fix">44914 - Fix/suppress warning message "WARN. Unread n bytes of record 0xNN"</action>
+ <action dev="POI-DEVELOPERS" type="fix">44892 - made HSSFWorkbook.getSheet(String) case insensitive</action>
+ <action dev="POI-DEVELOPERS" type="fix">44886] - Correctly process PICT metafile in EscherMetafileBlip</action>
+ <action dev="POI-DEVELOPERS" type="fix">44893 - Take into account indentation in HSSFSheet.autoSizeColumn</action>
+ </release>
+ <release version="3.1-beta1" date="2008-04-28">
+ <action dev="POI-DEVELOPERS" type="fix">44857 - Avoid OOM on unknown escher records when EscherMetafileBlip is incorrect</action>
+ <action dev="POI-DEVELOPERS" type="add">HSLF: Support for getting embedded sounds from slide show </action>
+ <action dev="POI-DEVELOPERS" type="add">HSLF: Initial support for rendering slides into images</action>
+ <action dev="POI-DEVELOPERS" type="add">HSLF: Support for getting OLE object data from slide show </action>
+ <action dev="POI-DEVELOPERS" type="add">HSLF: Implemented more methods in PPGraphics2D</action>
+ <action dev="POI-DEVELOPERS" type="add">HSLF: Added Freeform shape which can contain both lines and Bezier curves</action>
+ <action dev="POI-DEVELOPERS" type="fix">41071 - Improved text extraction in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="add">30311 - Conditional Formatting - improved API, added HSSFSheetConditionalFormatting</action>
+ <action dev="POI-DEVELOPERS" type="fix">Update the formula parser code to use a HSSFWorkbook, rather than the low level model.Workbook, to make things cleaner and make supporting XSSF formulas in future much easier</action>
+ <action dev="POI-DEVELOPERS" type="fix">Fix the logger used by POIFSFileSystem, so that commons-logging isn't required when not used</action>
+ <action dev="POI-DEVELOPERS" type="add">Update HSLFSlideShow and HSSFWorkbook to take advantage of POIFS updates, and allow reading embeded documents</action>
+ <action dev="POI-DEVELOPERS" type="add">Improve how POIFS works with directory entries, and update HWPFDocument to support reading an embeded word document</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial support for getting and changing chart and series titles</action>
+ <action dev="POI-DEVELOPERS" type="add">Implement a proxy HSSFListener which tracks the format records, and lets you lookup the format string for a given cell. Convert the xls to csv example to use it</action>
+ <action dev="POI-DEVELOPERS" type="fix">44792 - fixed encode/decode problems in ExternalNameRecord and CRNRecord.</action>
+ <action dev="POI-DEVELOPERS" type="fix">43670, 44501 - Fix how HDGF deals with trailing data in the list of chunk headers</action>
+ <action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action>
+ <action dev="POI-DEVELOPERS" type="fix">refactored all junits' usage of HSSF.testdata.path to one place</action>
+ <action dev="POI-DEVELOPERS" type="fix">44739 - Small fixes for conditional formatting (regions with max row/col index)</action>
+ <action dev="RK" type="add">44694 - HPSF: Support for property sets without sections</action>
+ <action dev="POI-DEVELOPERS" type="add">Implement Sheet.removeShape(Shape shape) in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="add">Various fixes: Recognising var-arg built-in functions #44675, ExternalNameRecord serialisation bug #44695, PMT() bug #44691</action>
+ <action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action>
+ <action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action>
+ <action dev="POI-DEVELOPERS" type="add">Move the missing record aware eventusermodel code out of scratchpad</action>
+ <action dev="POI-DEVELOPERS" type="add">44652 / 44603 - Improved handling of Pictures in Word Documents</action>
+ <action dev="POI-DEVELOPERS" type="fix">44636 - Fix formula parsing of RefVPtg, which was causing #VALUE to be shown on subsequent edits</action>
+ <action dev="POI-DEVELOPERS" type="fix">44627 - Improve the thread safety of POILogFactory</action>
+ <action dev="POI-DEVELOPERS" type="add">30311 - Initial support for Conditional Formatting</action>
+ <action dev="POI-DEVELOPERS" type="fix">44609 - Handle leading spaces in formulas, such as '= 4'</action>
+ <action dev="POI-DEVELOPERS" type="add">44608 - Support for PercentPtg in the formula evaluator</action>
+ <action dev="POI-DEVELOPERS" type="fix">44606 - Support calculated string values for evaluated formulas</action>
+ <action dev="POI-DEVELOPERS" type="add">Add accessors to horizontal and vertical alignment in HSSFTextbox</action>
+ <action dev="POI-DEVELOPERS" type="add">44593 - Improved handling of short DVRecords</action>
+ <action dev="POI-DEVELOPERS" type="add">28627 / 44580 - Fix Range.delete() in HWPF</action>
+ <action dev="POI-DEVELOPERS" type="add">44539 - Support for area references in formulas of rows >= 32768</action>
+ <action dev="POI-DEVELOPERS" type="add">44536 - Improved support for detecting read-only recommended files</action>
+ <action dev="POI-DEVELOPERS" type="fix">43901 - Correctly update the internal last cell number when adding and removing cells (previously sometimes off-by-one)</action>
+ <action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action>
+ <action dev="POI-DEVELOPERS" type="fix">44504 - Improvements to FormulaParser - operators, precedence, error literals, quotes in string literals, range checking on IntPtg, formulas with extra un-parsed stuff at the end, improved parse error handling</action>
+ <action dev="POI-DEVELOPERS" type="fix">44504 - Fixed number conversion inconsistencies in many functions, and improved RefEval</action>
+ <action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action>
+ <action dev="POI-DEVELOPERS" type="fix">44504 - Improvements to FormulaParser - operators, precedence, error literals, quotes in string literals, range checking on IntPtg, formulas with extra un-parsed stuff at the end, improved parse error handling</action>
+ <action dev="POI-DEVELOPERS" type="fix">44504 - Fixed number conversion inconsistencies in many functions, and improved RefEval</action>
+ <action dev="POI-DEVELOPERS" type="fix">44508 - Fix formula evaluation with evaluateInCell on boolean formulas</action>
+ <action dev="POI-DEVELOPERS" type="fix">44510 - Fix how DVALRecord works with dropdowns</action>
+ <action dev="POI-DEVELOPERS" type="fix">44495 - Handle named cell ranges in formulas that have lower case parts</action>
+ <action dev="POI-DEVELOPERS" type="fix">44491 - Don't have the new-style "HPSF properties are always available" affect the old-style use of HPSF alongside HSSF</action>
+ <action dev="POI-DEVELOPERS" type="fix">44471 - Crystal Reports generates files with short StyleRecords, which isn't allowed in the spec. Work around this</action>
+ <action dev="POI-DEVELOPERS" type="fix">44495 - Handle named cell ranges in formulas that have lower case parts</action>
+ <action dev="POI-DEVELOPERS" type="fix">44491 - Don't have the new-style "HPSF properties are always available" affect the old-style use of HPSF alongside HSSF</action>
+ <action dev="POI-DEVELOPERS" type="fix">44471 - Crystal Reports generates files with short StyleRecords, which isn't allowed in the spec. Work around this</action>
+ <action dev="POI-DEVELOPERS" type="add">44450 - Support for Lookup, HLookup and VLookup functions</action>
+ <action dev="POI-DEVELOPERS" type="fix">44449 - Avoid getting confused when two sheets have shared formulas for the same areas, and when the shared formula is set incorrectly</action>
+ <action dev="POI-DEVELOPERS" type="fix">44366 - InputStreams passed to POIFSFileSystem are now automatically closed. A warning is generated for people who might've relied on them not being closed before, and a wrapper to restore the old behaviour is supplied</action>
+ <action dev="POI-DEVELOPERS" type="add">44371 - Support for the Offset function</action>
+ <action dev="POI-DEVELOPERS" type="fix">38921 - Have HSSFPalette.findSimilar() work properly</action>
+ <action dev="POI-DEVELOPERS" type="fix">44456 - Fix the contrib SViewer / SViewerPanel to not fail on sheets with missing rows</action>
+ <action dev="POI-DEVELOPERS" type="fix">44403 - Further support for unusual, but valid, arguments to the Mid function</action>
+ <action dev="POI-DEVELOPERS" type="fix">44410 - Support for whole-column ranges, such as C:C, in formula strings and the formula evaluator</action>
+ <action dev="POI-DEVELOPERS" type="fix">44421 - Update Match function to properly support Area references</action>
+ <action dev="POI-DEVELOPERS" type="fix">44417 - Improved handling of references for the need to quote the sheet name for some formulas, but not when fetching a sheet by name</action>
+ <action dev="POI-DEVELOPERS" type="fix">44413 - Fix for circular references in INDEX, OFFSET, VLOOKUP formulas, where a cell is actually allowed to reference itself</action>
+ <action dev="POI-DEVELOPERS" type="fix">44403 - Fix for Mid function handling its arguments wrong</action>
+ <action dev="POI-DEVELOPERS" type="add">44364 - Support for Match, NA and SumProduct functions, as well as initial function error support</action>
+ <action dev="POI-DEVELOPERS" type="fix">44375 - Cope with a broken dictionary in Document Summary Information stream. RuntimeExceptions that occured when trying to read bogus data are now caught. Dictionary entries up to but not including the bogus one are preserved, the rest is ignored.</action>
+ <action dev="POI-DEVELOPERS" type="fix">38641 - Handle timezones better with cell.setCellValue(Calendar), so now 20:00-03:00, 20:00+00:00 and 20:00+03:00 will all be recorded as 20:00, and not 17:00 / 20:00 / 23:00 (pass a Date not a Calendar for old behaviour)</action>
+ <action dev="POI-DEVELOPERS" type="fix">44373 - Have HSSFDateUtil.isADateFormat recognize more formats as being dates</action>
+ <action dev="POI-DEVELOPERS" type="add">37923 - Support for Excel hyperlinks</action>
+ <action dev="POI-DEVELOPERS" type="add">Implement hashCode() and equals(obj) on HSSFFont and HSSFCellStyle</action>
+ <action dev="POI-DEVELOPERS" type="fix">44345 - Implement CountA, CountIf, Index, Rows and Columns functions</action>
+ <action dev="POI-DEVELOPERS" type="fix">44336 - Properly escape sheet names as required when figuring out the text of formulas</action>
+ <action dev="POI-DEVELOPERS" type="add">44326 - Improvements to how SystemOutLogger and CommonsLogger log messages with exceptions, and avoid an infinite loop with certain log messages with exceptions</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for a completed Record based "pull" stream, via org.apache.poi.hssf.eventusermodel.HSSFRecordStream, to complement the existing "push" Event User Model listener stuff</action>
+ </release>
+ <release version="3.0.2-FINAL" date="2008-02-04">
+ <action dev="POI-DEVELOPERS" type="fix">44297 - IntPtg must operate with unsigned short. Reading signed short results in incorrect formula calculation</action>
+ <action dev="POI-DEVELOPERS" type="fix">44296 - Fix for reading slide background images</action>
+ <action dev="POI-DEVELOPERS" type="fix">44293 - Avoid swapping AreaPtgs from relative to absolute</action>
+ <action dev="POI-DEVELOPERS" type="fix">44292 - Correctly process the last paragraph in a word file</action>
+ <action dev="POI-DEVELOPERS" type="fix">44254 - Avoid some unread byte warnings, and properly understand DVALRecord</action>
+ <action dev="POI-DEVELOPERS" type="add">Add another formula evaluation method, evaluateFormulaCell(cell), which will re-calculate the value for a formula, without affecting the formula itself.</action>
+ <action dev="POI-DEVELOPERS" type="fix">41726 - Fix how we handle signed cell offsets in relative areas and references</action>
+ <action dev="POI-DEVELOPERS" type="add">44233 - Support for getting and setting a flag on the sheet, which tells excel to re-calculate all formulas on it at next reload</action>
+ <action dev="POI-DEVELOPERS" type="fix">44201 - Enable cloning of sheets with data validation rules</action>
+ <action dev="POI-DEVELOPERS" type="fix">44200 - Enable cloning of sheets with notes</action>
+ <action dev="POI-DEVELOPERS" type="add">43008 - Add a moveCell method to HSSFRow, and deprecate setCellNum(), which didn't update things properly</action>
+ <action dev="POI-DEVELOPERS" type="fix">43058 - Support setting row grouping on files from CR IX, which lack GutsRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix">31795 - Support cloning of sheets with certain drawing objects on them</action>
+ <action dev="POI-DEVELOPERS" type="fix">43902 - Don't consider merged regions when auto-sizing columns</action>
+ <action dev="POI-DEVELOPERS" type="fix">42464 - Avoid "Expected ExpPtg to be converted from Shared to Non-Shared Formula" on large, formula heavy worksheets</action>
+ <action dev="POI-DEVELOPERS" type="add">42033 - Add support for named ranges with unicode names</action>
+ <action dev="POI-DEVELOPERS" type="add">34023 - When shifting rows, update formulas on that sheet to point to the new location of those rows</action>
+ <action dev="POI-DEVELOPERS" type="add">Support getting all the cells referenced by an AreaReference, not just the corner ones</action>
+ <action dev="POI-DEVELOPERS" type="add">43510 - Add support for named ranges in formulas, including non-contiguous named ranges</action>
+ <action dev="POI-DEVELOPERS" type="add">43937 - Add support for hiding and un-hiding sheets, and checking their current hidden status</action>
+ <action dev="POI-DEVELOPERS" type="fix">44167 - Fix for non-contiguous named ranges</action>
+ <action dev="POI-DEVELOPERS" type="fix">44070 - Fix for shifting comments when shifting rows</action>
+ </release>
+ <release version="3.0.2-BETA2" date="2008-01-12">
+ <action dev="POI-DEVELOPERS" type="add">Support for tables in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">43781 - Fix for extracting text from TextBoxes HSLF in</action>
+ <action dev="POI-DEVELOPERS" type="fix">Improve JavaDocs relating to hssf font and fill colourings</action>
+ <action dev="POI-DEVELOPERS" type="add">44095, 44097, 44099 - [PATCH] Support for Mid, Replace and Substitute excel functions</action>
+ <action dev="POI-DEVELOPERS" type="add">44055 - [PATCH] Support for getting the from field from HSMF messages</action>
+ <action dev="POI-DEVELOPERS" type="add">43551 - [PATCH] Support for 1904 date windowing in HSSF (previously only supported 1900 date windowing)</action>
+ <action dev="POI-DEVELOPERS" type="add">41064 - [PATCH] Support for String continue records</action>
+ <action dev="POI-DEVELOPERS" type="add">27511 - [PATCH] Support for data validation, via DVRecord and DVALRecord</action>
+ </release>
+ <release version="3.0.2-BETA1" date="2007-12-04">
+ <action dev="POI-DEVELOPERS" type="fix">43877 - Fix for handling mixed OBJ and CONTINUE records</action>
+ <action dev="POI-DEVELOPERS" type="fix">39512 - Fix for handling mixed OBJ and CONTINUE records</action>
+ <action dev="POI-DEVELOPERS" type="fix">43837 - [PATCH] Support for unicode NameRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix">43807 - Throw an IllegalArgumentException if asked to create a merged region with invalid columns or rows, rather than writing out a corrupt file</action>
+ <action dev="POI-DEVELOPERS" type="fix">43837 - [PATCH] Support for unicode NameRecords</action>
+ <action dev="POI-DEVELOPERS" type="add">43721 - [PATCH] Support for Chart Title Format records</action>
+ <action dev="POI-DEVELOPERS" type="fix">42794 - [PATCH] Fix for BOF records from things like Access</action>
+ <action dev="POI-DEVELOPERS" type="fix">43648 - Fix for IntPtg and short vs int</action>
+ <action dev="POI-DEVELOPERS" type="fix">43751 - [PATCH] - Fix for handling rotated text in HSSFSheet.autoSizeColumn</action>
+ <action dev="POI-DEVELOPERS" type="add">Include an Excel text extractor, and put all existing text extractors under a common superclass</action>
+ <action dev="POI-DEVELOPERS" type="add">Improvements to the LZW compression engine used by HDGF</action>
+ <action dev="POI-DEVELOPERS" type="add">HSSFPicture.resize() - a handy method to reset a picture to its original width and height</action>
+ <action dev="POI-DEVELOPERS" type="add">Add a getSheetIndex(HSSFSheet) method to HSSFWorkbook, and allow a HSSFSheet to get at its parent HSSFWorkbook</action>
+ <action dev="POI-DEVELOPERS" type="add">Move POIDocument out of Scratchpad, and update HSSFWorkbook to use it</action>
+ <action dev="POI-DEVELOPERS" type="fix">43399 - [PATCH] - Fix for Cell References for rows > 32678</action>
+ <action dev="POI-DEVELOPERS" type="fix">43410 - [PATCH] - Improved Formula Parser support for numbers and ranges</action>
+ <action dev="POI-DEVELOPERS" type="add">When writing HSLF files out, optionally preserve all OLE2 nodes (default is just the HSLF related nodes)</action>
+ <action dev="POI-DEVELOPERS" type="add">43323 - [PATCH] - Support for adding Pictures to ShapeGroups in HSLF.</action>
+ <action dev="POI-DEVELOPERS" type="add">43222 - [PATCH] - Support for getting OLE object data from HSSFWorkbook.</action>
+ <action dev="POI-DEVELOPERS" type="add">43247 - [PATCH] - Support for getting OLE object data from slideshows.</action>
+ <action dev="POI-DEVELOPERS" type="add">43125 - [PATCH] - Support for reading EMF, WMF and PICT images via HSSFWorkbook.getAllPictures()</action>
+ <action dev="POI-DEVELOPERS" type="fix">43088 - [PATCH] - Fix for reading files with long cell comments and text boxes</action>
+ <action dev="POI-DEVELOPERS" type="fix">42844 - [PATCH] - Fix for the EventUserModel and records that aren't immediately followed by their ContinueRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix">43055 - [PATCH] - Fix for saving Crystal Reports xls files when preserving nodes</action>
+ <action dev="POI-DEVELOPERS" type="fix">43116 - [PATCH] - Fix for Escher layer handling of embeded OLE2 documents</action>
+ <action dev="POI-DEVELOPERS" type="fix">43108 - [PATCH] - Where permissions deny fetching System Properties, use sensible defaults</action>
+ <action dev="POI-DEVELOPERS" type="fix">43093 - [PATCH] - Fix formula evaluator support for Area3D references to other sheets</action>
+ <action dev="POI-DEVELOPERS" type="fix">Improvements to HSSFDateUtils.isADateFormat, and have HSSFDateUtil.isCellDateFormatted use this</action>
+ <action dev="POI-DEVELOPERS" type="fix">42999 - [PATCH] - Fix for HSSFPatriarch positioning problems</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for write-protecting a HSSF workbook</action>
+ <action dev="POI-DEVELOPERS" type="add">Support for querying, setting and un-setting protection on sheets in a HSSF workbook</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial HSMF (outlook) support</action>
+ <action dev="POI-DEVELOPERS" type="fix">Tidy up the javadocs</action>
+ </release>
+
+ <release version="3.0.1-FINAL" date="2007-07-05">
+ <action dev="POI-DEVELOPERS" type="fix">Administrative updates to the Maven POMs, and the release artificat build process</action>
+ <action dev="POI-DEVELOPERS" type="fix">23951 - [PATCH] Fix for HSSF setSheetOrder and tab names</action>
+ <action dev="POI-DEVELOPERS" type="fix">42524 - [PATCH] Better HSLF support for problem shape groups</action>
+ <action dev="POI-DEVELOPERS" type="fix">42520 - [PATCH] Better HSLF support for corrupt picture records</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial support for a "missing record aware" HSSF event model</action>
+ <action dev="POI-DEVELOPERS" type="add">Additional HSLF support for Title and Slide Master Sheets</action>
+ <action dev="POI-DEVELOPERS" type="fix">42474 - [PATCH] Improved HSLF note to slide matching, and a NPE</action>
+ <action dev="POI-DEVELOPERS" type="fix">42481 - [PATCH] Tweak some HSLF exceptions, to make it clearer what you're catching</action>
+ <action dev="POI-DEVELOPERS" type="fix">42667 - [PATCH] Fix for HSLF writing of files with tables</action>
+ <action dev="POI-DEVELOPERS" type="add">Improved way of detecting HSSF cells that contain dates, isADateFormat</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial, read-only support for Visio documents, as HDGF</action>
+ </release>
+
+ <release version="3.0-FINAL" date="2007-05-18">
+ <action dev="POI-DEVELOPERS" type="fix">39977 - [PATCH] Fix POM for Maven users</action>
+ <action dev="POI-DEVELOPERS" type="fix">38976 - [PATCH] Add createPicture to HSSFShapeGroup</action>
+ <action dev="POI-DEVELOPERS" type="add">Detect Office 2007 XML documents, and throw a meaningful exception</action>
+ <action dev="POI-DEVELOPERS" type="add">Additional HSLF support for PowerPoint</action>
+ <action dev="POI-DEVELOPERS" type="add">Initial support for HWPF image extraction</action>
+ </release>
+
+ <release version="3.0-alpha3" date="2006-12-12">
+ <action dev="POI-DEVELOPERS" type="add">Additional HSLF support for PowerPoint</action>
+ </release>
+
+ <release version="3.0-alpha2" date="2006-06-16">
+ <action dev="POI-DEVELOPERS" type="add">HSSF Formula support</action>
+ <action dev="POI-DEVELOPERS" type="add">Additional HSLF support for PowerPoint</action>
+ <action dev="POI-DEVELOPERS" type="fix">39389 - [PATCH] Extended Ascii support for WingDings</action>
+ </release>
+
+ <release version="3.0-alpha1" date="2005-06-04">
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Bugzilla Bug 29976 [PATCH] HSSF hyperlink formula size problem</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Image writing support</action>
+ <action dev="NB" type="add" context="All">HSLF - Initial PowerPoint Support. Includes: Support for text extraction across the whole file; Support for getting individual slides, and their notes, and extracting text from those; Initial support for changing (but not adding) text</action>
+ </release>
+
+ <release version="2.5.1-FINAL" date="2004-02-29">
+ <action dev="POI-DEVELOPERS" type="add" context="All">Outlining support</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">27574 - [PATCH] HSSFDateUtil.getExcelDate() is one hour off when DST changes</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">26465 - [PATCH] wrong lastrow entry</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">28203 - [PATCH] Unable to open read-write excel file including forms</action>
+ </release>
+
+ <release version="2.5-FINAL" date="2004-02-29">
+ <action dev="POI-DEVELOPERS" type="add" context="All">Add support for the Escher file format</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">27005 java.lang.IndexOutOfBoundsException during Workbook.cloneSheet()</action>
+ </release>
+
+ <release version="2.0-FINAL" date="2004-01-26">
+ <action dev="POI-DEVELOPERS" type="update" context="All">No changes</action>
+ </release>
+
+ <release version="2.0-RC2" date="2004-01-11">
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Bug 25695 - HSSFCell.getStringCellValue() on cell which has string formula will return swap bye unicode characters.</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Updated website for upcoming release</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Formula Parser fixes with tests, by Peter M Murray Bug 25457</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Fixed cloning merge regions</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">The cloned reference for merged cells did not create a new collection, so deletes cascaded to the original.</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Fix to 24519 call to getCustomPalette() from a newly created workbook now works</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Fix supplied for bug 24397 where some compilation got ambiguous classes. Explicitly imports the classes. Patch supplied by Jean-Pierre Paris.</action>
+ </release>
+
+ <release version="2.0-RC1" date="2003-11-02">
+ <action dev="POI-DEVELOPERS" type="fix" context="All">12561 (Min) HSSFWorkbook throws Exceptions</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">12730 (Nor) values dont get copied to another sheet.</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">13224 (Maj) Exception thrown when cell has =Names call</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">13796 (Nor) Error Reading Formula Record (optimized if, external link)</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">13921 (Nor) Sheet name cannot exceed 31 characters and cannot contain :</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">14330 (Nor) Error reading FormulaRecord</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">14460 (Nor) Name in Formula - ArrayOutOfBoundsException</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">15228 (Cri) [Urgent] ArrayIndexoutofbounds Exception. POI - Version 1.8</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">16488 (Maj) Unable to open written spreadsheet in Excel, but can in Open</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">16559 (Nor) testCustomPalette.xls crashes Excel 97</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">16560 (Nor) testBoolErr.xls crashes Excel '97</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">17374 (Min) HSSFFont - BOLDWEIGHT_NORMAL</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">18800 (Maj) The sheet made by HSSFWorkbook#cloneSheet() doesn't work cor</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">18846 (Min) [PATCH][RFE]Refactor the transformation between byte array a</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">19599 (Min) java.lang.IllegalArgumentException</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">19961 (Nor) [PATCH] Sheet.getColumnWidth() returns wrong value</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">21066 (Blo) Can not modify a blank spreadsheet</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">21444 (Enh) [PATCH] Macro functions</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">21447 (Nor) [RFE]String Formula Cells</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">21674 (Enh) [PATCH] Documentation changes for @(Greater|Less|Not)EqualPt</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">21863 (Enh) [PATCH] build.xml fixes</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">22195 (Nor) [RFE] [PATCH] Support for Storage Class ID</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">22742 (Cri) Failed to create HSSFWorkbook!</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">22922 (Cri) HSSFSheet.shiftRows() throws java.lang.IndexOutOfBoundsExcep</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">22963 (Nor) org.apache.poi.hpsf.SummaryInformation.getEditTime() should</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">24149 (Maj) Error passing inputstream to POIFSFileSystem</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">21722 (Nor) [PATCH] Add a ProtectRecord to Sheets and give control over</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">9576 (Nor) [PATCH] DBCELL, INDEX EXTSST (was Acess 97 import)</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">13478 (Blo) [PATCH] [RFE] POIFS, RawDataBlock: Missing workaround for lo</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">14824 (Nor) Unable to modify empty sheets</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">12843 (Cri) [PATCH] Make POI handle chinese better</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">15353 (Nor) [RFE] creating a cell with a hyperlink</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">15375 (Blo) Post 1.5.1 POI causes spreadsheet to become unopenable.</action>
+ </release>
+
+ <release version="2.0-pre3" date="2003-07-29">
+ <action dev="POI-DEVELOPERS" type="add" context="All">HPSF is now able to read properties which are given in the property set stream but which don't have a value ("variant" type VT_EMPTY). The getXXX() methods of the PropertySet class return null if their return type is a reference (like a string) or 0 if the return type is numeric. Details about the return types and about how to distinguish between a property value of zero and a property value that is not present can be found in the API documentation.</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Gridlines can now be turned on and off</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">NamePTG refactoring/fixes</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">minor fixes to ExternSheet and formula strings</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Sheet comparisons now ignore case</action>
+ </release>
+
+ <release version="2.0-pre2" date="2003-07-06">
+ <action dev="POI-DEVELOPERS" type="fix" context="All" >A nasty concurrency problem has been fixed. Any users working in a multithreaded environment should seriously consider upgrading to this release.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">The EXTSST record has been implemented. This record is used by excel for optimized reading of strings.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">When rows are shifted, the merged regions now move with them. If a row contains 2 merged cells, the resulting shifted row should have those cells merged as well.</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">There were some issues when removing merged
+ regions (specifically, removing all of them and then adding some more) and have been resolved.</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">When a sheet contained shared formulas (when a formula is
+ dragged across greater than 6 cells), the clone would fail. We now support cloning of
+ sheets that contain this Excel optimization. </action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Support added for reading formulas with UnaryPlus and UnaryMinus operators.</action>
+ </release>
+ <release version="2.0-pre1" date="2003-05-17">
+ <action dev="POI-DEVELOPERS" type="add" context="All">Patch applied for deep cloning of worksheets was provided</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Patch applied to allow sheet reordering</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Added additional print area setting methods using row/column numbers</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">HDF: Negative Array size fix</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added argument pointers to support the IF formula</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Formulas: Added special character support for string literals, specifically for SUMIF formula support and addresses a bug as well</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">BlockingInputStream committed to help ensure reads</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Fixed problem with NaN values differing from the investigated value from file reads in FormulaRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Patch for getColumnWidth in HSSF</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Patch for dealing with mult-level numbered lists in HDF</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Due to named reference work, several named-ranged bugs were closed</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Patch applied to prevent sheet corruption after a template modification</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Shared Formulas now Supported</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added GreaterEqual, LessEqual and NotEqual to Formula Parser</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added GreaterThan and LessThan functionality to formulas</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Patches for i10n</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">POI Build System Updated</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">font names can now be null</action>
+ </release>
+ <release version="1.10-dev" date="2003-02-19">
+ <action dev="POI-DEVELOPERS" type="add" context="All">Support for zoom level</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Freeze and split pane support</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Row and column headers on printouts</action>
+ </release>
+ <release version="1.8-dev" date="2002-09-20">
+ <action dev="POI-DEVELOPERS" type="add" context="All">Custom Data Format Support</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Enhanced Unicode Support for Russian and Japanese</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Enhanced formula support including read-only for
+ "optimized if" statements.</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Support for cloning objects</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Fixes for header/footer</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Spanish Documentation translations</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Support for preserving VBA macros</action>
+ </release>
+ <release version="1.7-dev" date="Release date not recorded">
+ <action dev="NKB" type="update" context="All">Removed runtime dependency on commons logging.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Formula support</action>
+ </release>
+ <release version="1.5.1" date="2002-06-16">
+ <action dev="GJS" type="update" context="All">Removed depedency on commons logging. Now define poi.logging system property to enable logging to standard out.</action>
+ <action dev="GJS" type="fix" context="All">Fixed SST string handling so that spreadsheets with rich text or extended text will be read correctly.</action>
+ </release>
+ <release version="1.5" date="2002-05-06">
+ <action dev="NKB" type="update" context="All">New project build.</action>
+ <action dev="NKB" type="update" context="All">New project documentation system based on Cocoon.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Package rename</action>
+ <action dev="POI-DEVELOPERS" type="fix" context="All">Various bug fixes</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Early stages of HSF development (not ready for development)</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Initial low level record support for charting (not complete)</action>
+ </release>
+ <release version="1.2.0" date="2002-01-19">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Changes not recorded.</action>
+ </release>
+ <release version="1.1.0" date="2002-01-04">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Created new event model</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Optimizations made to HSSF including aggregate records for
+ values, rows, etc.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">predictive sizing, offset based writing (instead of lots of
+ array copies)</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">minor re-factoring and bug fixes.</action>
+ </release>
+ <release version="1.0.2" date="2002-01-11">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Changes not recorded.</action>
+ </release>
+ <release version="1.0.1" date="2002-01-04">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Changes not recorded.</action>
+ </release>
+ <release version="1.0.0" date="2001-12-30">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Minor documentation updates.</action>
+ </release>
+ <release version="0.14.0" date="2001-12-22">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added DataFormat helper class and exposed set and get format
+ on HSSFCellStyle</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Fixed column width apis (unit wise) and various javadoc on
+ the subject</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Fix for Dimensions record (again)... (one of these days I'll
+ write a unit test for this ;-p).</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Some optimization on sheet creation.</action>
+ </release>
+ <release version="0.13.0" date="2001-12-16">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Changes not recorded.</action>
+ </release>
+ <release version="0.12.0" date="2001-12-12">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added MulBlank, Blank, ColInfo</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added log4j facility and removed all sys.out type logging</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added support for adding font's, styles and corresponding
+ high level api for styling cells</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">added support for changing row height, cell width and default
+ row height/cell width.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added fixes for internationalization (UTF-16 should work now
+ from HSSFCell.setStringValue, etc when the encoding is set)</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">added support for adding/removing and naming sheets.</action>
+ </release>
+ <release version="0.11.0" date="2001-12-08">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Bugfix release. We were throwing an exception when reading
+ RKRecord objects.</action>
+ </release>
+ <release version="0.10.0" date="2001-12-02">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Got continuation records to work (read/write)</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added various pre-support for formulas</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Massive API reorganization, repackaging.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">BiffViewer class added for validating HSSF & POI and/or
+ HSSF Output.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Better API support for modification.</action>
+ </release>
+ <release version="0.7 (and interim releases)" date="2001-11-17">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Added encoding flag to high and low level api to use utf-16
+ when needed (HSSFCell.setEncoding())</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">added read only support for Label records (which are
+ reinterpreted as LabelSST when written)</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Broken continuation record implementation (oops)</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">BiffViewer class added for validating HSSF & POI and/or
+ HSSF Output.</action>
+ </release>
+ <release version="0.6" date="2001-11-11">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Support for read/write and modify.</action>
+ <action dev="POI-DEVELOPERS" type="update" context="All">Read only support for MulRK records (converted to Number when
+ writing)
+ </action>
+ </release>
+ <release version="0.5" date="2001-11-05">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Changes not recorded.</action>
+ </release>
+ <release version="0.4" date="2001-10-31">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Changes not recorded.</action>
+ </release>
+ <release version="0.3" date="2001-10-26">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Changes not recorded.</action>
+ </release>
+ <release version="0.2" date="2001-09-24">
+ <action dev="POI-DEVELOPERS" type="update" context="All">Changes not recorded.</action>
+ </release>
+ <release version="0.1" date="2001-08-28">
+ <action dev="POI-DEVELOPERS" type="update" context="All">First ever public release</action>
+ </release>
+
+ </changes>
+
+
+ <todo>
+<!-- <title>Things To Do for POI</title>-->
+
+ <actions context="all" priority="high">
+ <action context="code" dev="NKB">
+ Finish HDF
+ </action>
+ <action context="code" dev="GS">
+ Finish Charts
+ </action>
+ <action context="code" dev="open">
+ Finish Formulas.
+ </action>
+ </actions>
+
+ <actions context="all" priority="medium">
+ <action context="code" dev="open">
+ Expose functionality in low level records in higher level API
+ </action>
+ <action context="code" dev="open">
+ Implement more record types.
+ </action>
+ <action context="code" dev="open">
+ Add more dummy checks (for when API user's do things they
+ "can't" do). This will involve exploring the various
+ upper limits on the things Excel can handle.
+ </action>
+ <action context="code" dev="open">
+ Add support for embedded graphics and other objects.
+ </action>
+ <action context="code" dev="open">
+ Create new adapter object for handling MulBlank, MulRk, Rk
+ records.
+ </action>
+ <action context="code" dev="open">
+ Add a way to copy sheets.
+ </action>
+ </actions>
+
+ </todo>
+
+</status>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Source Code Repository</title>
+ <authors>
+ <person id="NB" name="Nick Burch" email="nick@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Download the Source</title>
+ <p>
+ Most users of the source code probably don't need to have day to
+ day access to the source code as it changes. Most users will want
+ to make use of our <link href="download.html">source release</link>
+ packages, which contain the complete source tree for each binary
+ release, suitable for browsing or debugging. These source releases
+ are available from our
+ <link href="download.html">download page.</link>
+ </p>
+ <p>
+ The Apache POI sourcecode is also available as source artifacts
+ in the Maven Central repository, which may be helpful for those
+ users who make use of POI and wish to inspect the source (eg when
+ debugging in an IDE).
+ </p>
+ </section>
+ <section><title>Access the Version Controlled Source Code</title>
+ <p>
+ For general information on connecting to the ASF Subversion,
+ repositories, see the
+ <link href="http://www.apache.org/dev/version-control.html">version control page.</link>
+ </p>
+ <p>Subversion is an open-source version control system. It has been contributed to the Apache Software Foundation and is
+ now available <link href="http://subversion.apache.org/">here</link>.
+ </p>
+ <p>
+ The root url of the ASF Subversion repository is
+ <link href="http://svn.apache.org/repos/asf/">http://svn.apache.org/repos/asf/</link>
+ for non-committers and
+ <link href="https://svn.apache.org/repos/asf/">https://svn.apache.org/repos/asf/</link>
+ for committers.
+ </p>
+
+ <p><strong>NOTE</strong>: When checking out a subproject using
+ subversion, ensure that you are checking out a tag, a branch or trunk
+ (the main-line) and not all tags and branches, to avoid filling up
+ your hard-disk and wasting bandwidth.
+ </p>
+
+ <ul>
+ <li>For read only access to the Apache POI svn, please use
+ <link href="http://svn.apache.org/repos/asf/poi/trunk/">http://svn.apache.org/repos/asf/poi/trunk/</link></li>
+ <li>For committers (write) access to the Apache POI svn, please use
+ <link href="https://svn.apache.org/repos/asf/poi/trunk/">https://svn.apache.org/repos/asf/poi/trunk/</link></li>
+ <li>To browse the svn repository in your web browser, please us
+ <link href="http://svn.apache.org/viewcvs.cgi/poi/">ViewSVN</link></li>
+ </ul>
+
+ <p>If you are not a <em>Committer</em>, but you want to submit patches
+ or even request commit privileges, please see our
+ <link href="guidelines.html">Guidelines</link> for more
+ information.</p>
+ </section>
+ <section><title>Git access to POI sources </title>
+ <p>
+ The master source repository for Apache POI is the Subversion
+ one listed above. To support those users and developers who prefer
+ to use the Git tooling, read-only access to the POI source tree is
+ also available via Git. The Git mirrors normally track SVN to
+ within a few minutes.
+ </p>
+ <p>
+ The official read-only Git repository for Apache POI is available
+ from <link href="http://git.apache.org/">git.apache.org/</link> .
+ The Git Clone URL is: <link href="git://git.apache.org/poi.git">git://git.apache.org/poi.git</link>
+ and Http Clone URL: <link href="http://git.apache.org/poi.git">http://git.apache.org/poi.git</link> .
+ Please see the <link href="http://git.apache.org/">Git at
+ Apache</link> page for more details on the service.
+ </p>
+ <p>
+ In addition to the <link href="http://git.apache.org/">git.apache.org/</link>
+ repository, changes are also mirrored in near-realtime to GitHub.
+ The GitHub repository is available at
+ <link href="https://github.com/apache/poi">https://github.com/apache/poi</link> .
+ Please note that the GitHub repository is read-only, and all
+ contributions should continue to be sent via Bugzilla for tracking.
+ (Git patches are fine though). Please see the
+ <link href="guidelines.html">contribution guidelines</link> for more
+ information on getting involved in the project.</p>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE tabs PUBLIC "-//APACHE//DTD Cocoon Documentation Tab V1.0//EN" "tab-cocoon-v10.dtd">
+
+<tabs software="POI"
+ title="POI"
+ copyright="Apache Foundation"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <!-- The rules are:
+ @dir will always have /index.html added.
+ @href is not modified unless it is root-relative and obviously specifies a
+ directory (ends in '/'), in which case /index.html will be added
+ -->
+
+
+ <tab label="Home" dir=""/>
+ <!-- Add new tabs here, eg:
+ <tab label="How-Tos" dir="community/howto/"/>
+ <tab label="XML Site" dir="xml-site/"/>
+ -->
+
+</tabs>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Text Extraction</title>
+ <authors>
+ <person id="NB" name="Nick Burch" email="nick@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Overview</title>
+ <p>For a number of years now, Apache POI has provided basic
+ text extraction for all the project supported file formats. In
+ addition, as well as the (plain) text, these provides access to
+ the metadata associated with a given file, such as title and
+ author.</p>
+ <p>For more advanced text extraction needs, including Rich Text
+ extraction (such as formatting and styling), along with XML and
+ HTML output, Apache POI works closely with
+ <link href="http://tika.apache.org/">Apache Tika</link> to deliver
+ POI-powered Tika Parsers for all the project supported file formats.</p>
+ <p>If you are after turn-key text extraction, including the latest
+ support, styles etc, you are strongly advised to make use of
+ <link href="http://tika.apache.org/">Apache Tika</link>, which builds
+ on top of POI to provide Text and Metadata extraction. If you wish
+ to have something very simple and stand-alone, or you wish to make
+ heavy modificiations, then the POI provided text extractors documented
+ below might be a better fit for your needs.</p>
+ </section>
+
+ <section><title>Common functionality</title>
+ <p>All of the POI text extractors extend from
+ <em>org.apache.poi.POITextExtractor</em>. This provides a common
+ method across all extractors, getText(). For many cases, the text
+ returned will be all you need. However, many extractors do provide
+ more targetted text extraction methods, so you may wish to use
+ these in some cases.</p>
+ <p>All POIFS / OLE 2 based text extractors also extend from
+ <em>org.apache.poi.POIOLE2TextExtractor</em>. This additionally
+ provides common methods to get at the <link href="hpfs/">HPFS
+ document metadata</link>.</p>
+ <p>All OOXML based text extractors (available in POI 3.5 and later)
+ also extend from
+ <em>org.apache.poi.POIOOXMLTextExtractor</em>. This additionally
+ provides common methods to get at the OOXML metadata.</p>
+ </section>
+
+ <section><title>Text Extractor Factory</title>
+ <p>As part of the addition of OOXML support in Apache POI 3.5, there
+ is a common class to select the appropriate POI text extractor for
+ you. <em>org.apache.poi.extractor.ExtractorFactory</em> provides a
+ similar function to WorkbookFactory. You simply pass it an
+ InputStream, a File, a POIFSFileSystem or a OOXML Package. It
+ figures out the correct text extractor for you, and returns it.</p>
+ <p>For complete detection and text extractor auto-selection, users
+ are strongly encouraged to investigate
+ <link href="http://tika.apache.org/">Apache Tika</link>.</p>
+ </section>
+
+ <section><title>Excel</title>
+ <p>For .xls files, there is
+ <em>org.apache.poi.hssf.extractor.ExcelExtractor</em>, which will
+ return text, optionally with formulas instead of their contents.
+ Those using POI 3.5 can also use
+ <em>org.apache.poi.xssf.extractor.XSSFExcelExtractor</em>, to perform
+ a similar task for .xlsx files.</p>
+ <p>In addition, there is a second text extractor for .xls files,
+ <em>org.apache.poi.hssf.extractor.EventBasedExcelExtractor</em>. This
+ is based on the streaming EventUserModel code, and will generally
+ deliver a lower memory footprint for extraction. However, it will
+ have problems correctly outputting more complex formulas, as it
+ works with records as they pass, and so doesn't have access to all
+ parts of complex and shared formulas.</p>
+ </section>
+
+ <section><title>Word</title>
+ <p>For .doc files from Word 97 - Word 2003, in scratchpad there is
+ <em>org.apache.poi.hwpf.extractor.WordExtractor</em>, which will
+ return text for your document.</p>
+ <p>Those using POI 3.7 can also extract simple textual content from
+ older Word 6 and Word 95 files, using the scratchpad class
+ <em>org.apache.poi.hwpf.extractor.Word6Extractor</em>.</p>
+ <p>Since POI 3.5, it is possible to use
+ <em>org.apache.poi.xwpf.extractor.XPFFWordExtractor</em>, to perform
+ text extraction for .docx files.</p>
+ </section>
+
+ <section><title>PowerPoint</title>
+ <p>For .ppt files, in scratchpad there is
+ <em>org.apache.poi.hslf.extractor.PowerPointExtractor</em>, which
+ will return text for your slideshow, optionally restricted to just
+ slides text or notes text. Those using POI 3.5 can also use
+ <em>org.apache.poi.xslf.extractor.XSLFPowerPointExtractor</em>, to
+ perform a similar task for .pptx files.</p>
+ </section>
+
+ <section><title>Publisher</title>
+ <p>For .pub files, in scratchpad there is
+ <em>org.apache.poi.hpbf.extractor.PublisherExtractor</em>, which
+ will return text for your file.</p>
+ </section>
+
+ <section><title>Visio</title>
+ <p>For .vsd files, in scratchpad there is
+ <em>org.apache.poi.hdgf.extractor.VisioTextExtractor</em>, which
+ will return text for your file.</p>
+ </section>
+
+ <section><title>Embedded Objects</title>
+ <p>Extractors already exist for Excel, Word, PowerPoint and Visio;
+ if one of these objects is embedded into a worksheet, the ExtractorFactory class can be used to recover an extractor for it.
+ </p>
+ <source>
+FileInputStream fis = new FileInputStream(inputFile);
+POIFSFileSystem fileSystem = new POIFSFileSystem(fis);
+// Firstly, get an extractor for the Workbook
+POIOLE2TextExtractor oleTextExtractor =
+ ExtractorFactory.createExtractor(fileSystem);
+// Then a List of extractors for any embedded Excel, Word, PowerPoint
+// or Visio objects embedded into it.
+POITextExtractor[] embeddedExtractors =
+ ExtractorFactory.getEmbededDocsTextExtractors(oleTextExtractor);
+for (POITextExtractor textExtractor : embeddedExtractors) {
+ // If the embedded object was an Excel spreadsheet.
+ if (textExtractor instanceof ExcelExtractor) {
+ ExcelExtractor excelExtractor = (ExcelExtractor) textExtractor;
+ System.out.println(excelExtractor.getText());
+ }
+ // A Word Document
+ else if (textExtractor instanceof WordExtractor) {
+ WordExtractor wordExtractor = (WordExtractor) textExtractor;
+ String[] paragraphText = wordExtractor.getParagraphText();
+ for (String paragraph : paragraphText) {
+ System.out.println(paragraph);
+ }
+ // Display the document's header and footer text
+ System.out.println("Footer text: " + wordExtractor.getFooterText());
+ System.out.println("Header text: " + wordExtractor.getHeaderText());
+ }
+ // PowerPoint Presentation.
+ else if (textExtractor instanceof PowerPointExtractor) {
+ PowerPointExtractor powerPointExtractor =
+ (PowerPointExtractor) textExtractor;
+ System.out.println("Text: " + powerPointExtractor.getText());
+ System.out.println("Notes: " + powerPointExtractor.getNotes());
+ }
+ // Visio Drawing
+ else if (textExtractor instanceof VisioTextExtractor) {
+ VisioTextExtractor visioTextExtractor =
+ (VisioTextExtractor) textExtractor;
+ System.out.println("Text: " + visioTextExtractor.getText());
+ }
+}
+ </source>
+ </section>
+ </body>
+
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<!DOCTYPE todo PUBLIC "-//APACHE//DTD Todo V1.3//EN" "./dtd/todo-v13.dtd">
+
+<todo><title>Things To Do for Poi</title>
+
+ <devs>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="GS" name="Glen Stampoultzis" email="user@poi.apache.org"/>
+ <person id="MJ" name="Marc Johnson" email="mjohnson at apache dot org"/>
+ <person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ <person id="RA" name="Ryan Ackley" email="dev@poi.apache.org"/>
+ <person id="AS" name="Avik Sengupta" email="dev@poi.apache.org"/>
+ <person id="open" name="POI Developers" email="dev@poi.apache.org"/>
+ <person id="Everyone" name="POI Developers" email="dev@poi.apache.org"/>
+ </devs>
+
+ <actions priority="high">
+ <action context="code" dev="RA">
+ Finish HWPF
+ </action>
+ <action context="code" dev="GS">
+ Finish Charts
+ </action>
+ <action context="code" dev="Everyone">
+ Evaluate and bugfix performance code in HEAD
+ </action>
+
+ </actions>
+
+ <actions priority="medium">
+ <action context="code" dev="open">
+ Implement more record types.
+ </action>
+ <action context="code" dev="open">
+ Add more dummy checks (for when API user's do things they
+ "can't" do). This will involve exploring the various
+ upper limits on the things Excel can handle.
+ </action>
+ <action context="code" dev="open">
+ Add support for embedded graphics and other objects.
+ </action>
+ <action context="code" dev="open">
+ Create new adapter object for handling MulBlank, MulRk, Rk
+ records.
+ </action>
+ <action context="code" dev="AS">
+ Improve formulas (Shared Formulas, Unkown PTG's)
+ </action>
+ </actions>
+
+</todo>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "./dtd/book-cocoon-v10.dtd">
+
+<book software="POI"
+ title="POI Documentation Translations"
+ copyright="@year@ POI Project"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <menu label="Translations">
+ <menu-item label="Main Index" href="../index.html"/>
+ <menu-item label="Guidelines" href="guidelines.html"/>
+ </menu>
+
+ <menu label="Languages">
+ <menu-item label="Spanish" href="es/index.html"/>
+ <menu-item label="German" href="de/index.html"/>
+ <menu-item label="Japanese" href="http://jakarta.terra-intl.com/poi/"/>
+ <menu-item label="Korean" href="http://jakarta.apache-korea.org/poi/"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../../dtd/book-cocoon-v10.dtd">
+
+<book software="POI"
+ title="Dokumentation des POI-Projekts"
+ copyright="@year@ POI Project"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <menu label="Marketing">
+ <menu-item label="Fallstudien" href="../../casestudies.html"/>
+ </menu>
+
+ <menu label="Projekt">
+ <menu-item label="Überblick" href="../../overview.html"/>
+ <menu-item label="POIFS" href="../../poifs/index.html"/>
+ <menu-item label="HSSF" href="../../spreadsheet/index.html"/>
+ <menu-item label="HWPF" href="../../hwpf/index.html"/>
+ <menu-item label="HPSF" href="../../hpsf/index.html"/>
+ <menu-item label="POI-Utils" href="../../utils/index.html"/>
+ <menu-item label="Download" href="http://jakarta.apache.org/builds/jakarta-poi/"/>
+ </menu>
+
+ <menu label="Gemeinschaft">
+ <menu-item label="Neuigkeiten" href="../../news.html"/>
+ <menu-item label="Änderungen" href="../../changes.html"/>
+ <menu-item label="Aufgaben" href="../../todo.html"/>
+ <menu-item label="Mitmachen" href="../../guidelines.html"/>
+ <menu-item label="Unsere Vision" href="../../plan/POI20Vision.html"/>
+ <menu-item label="Vergangenheit und Zukunft" href="../../historyandfuture.html"/>
+ <menu-item label="Wer wir sind" href="../../who.html"/>
+ <menu-item label="Beschlüsse" href="../../resolutions/index.html"/>
+ </menu>
+
+ <menu label="Dokumentation">
+ <menu-item label="Javadocs" href="http://jakarta.apache.org/poi/javadocs/"/>
+ <menu-item label="FAQ" href="../../faq.html"/>
+ <menu-item label="Referenzen" href="../../references/index.html"/>
+ </menu>
+
+ <menu label="Code">
+ <menu-item label="Quellcode" href="http://jakarta.apache.org/poi/javadocs/javasrc/"/>
+ <menu-item label="CVS" href="http://jakarta.apache.org/site/cvsindex.html"/>
+ <menu-item label="Die wichtigsten Fehler" href="http://issues.apache.org/bugzilla/buglist.cgi?votes=1&product=POI&order=bugs.votes"/>
+ <menu-item label="Fehlerdatenbank" href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI"/>
+ <menu-item label="Liste der Patches" href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI&short_desc=%5BPATCH%5D&short_desc_type=allwordssubstr"/>
+
+ <menu-item label="Ergebnis der JUnit-Funktionstests" href="http://jakarta.apache.org/poi/tests/junit/"/>
+ <menu-item label="Ergebnis des Abhängigkeitstests" href="http://jakarta.apache.org/poi/metrics/jdepend/"/>
+ <menu-item label="Ergebnis des Stiltests" href="http://jakarta.apache.org/poi/metrics/checkstyle/"/>
+ </menu>
+
+</book>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Willkommen bei POI</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="GJS" name="Glen Stampoultzis" email="poi-user@jakarta.apache.org"/>
+ <person id="JENS" name="Jens Lorenz" email="???"/>
+ <person id="RK" name="Rainer Klute" email="klute@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Nachrichten</title>
+ <section><title>Übersetzungen</title>
+ <p>
+ Das POI-Übersetzungsprojekt hat begonnen.
+ Den Anfang machen <link href="../es/index.html">spanisch</link>,
+ <link href="http://jakarta.terra-intl.com/poi/">japanisch</link>
+ und deutsch. Andere Sprachen sind herzlich willkommen.
+ Machen Sie mit!
+ </p>
+ </section>
+ <section><title>Logo-Wettbewerb </title>
+ <p>
+ Die Wahl für das POI-Logo ist beendet. Danke für Ihre Stimmen.
+ </p>
+<!-- <p>-->
+<!-- <link href="http://vote.sparklit.com/poll.spark/640946">Click here</link> to see the current results.-->
+<!-- </p>-->
+ </section>
+ </section>
+ <section><title>Zweck</title>
+ <p>
+ Das POI-Projekt besteht aus Java-APIs zum Erstellen und
+ Bearbeiten von Dateiformaten, die auf dem Microsoft-Dateiformat »OLE-2
+ Compound Document« beruhen. Dateien in diesem Format sind unter
+ anderem die meisten Microsoft-Office-Dateien, wie zum
+ Beispiel Excel- und Word-Dateien.
+ </p>
+ <p>
+ Grundsätzlich versuchen wir, möglichst viel mit anderen Projekten
+ zusammenzuarbeiten, um die gewünschten Funktionalitäten zur Verfügung
+ zu stellen. Einige Beispiele: Für
+ <link href="http://xml.apache.org/cocoon">Cocoon</link>
+ werden bald Generatoren und Serializer zur Verfügung stehen. Wir
+ arbeiten mit
+ <link href="http://www.openoffice.org/">Open Office.org</link>
+ zusammen, um das Excel-Dateiformat zu
+ dokumentieren.
+ Für <link href="http://jakarta.apache.org/lucene">Lucene</link>
+ werden bald Filtermodule zur Verfügung stehen. Wir stellen anderen
+ Projekten Teile des POI-Projektes zur Verfügung, damit diese
+ die POI-Funktionalitäten nutzen können.
+ </p>
+ <section><title>Warum und wann sollte man POI nutzen?</title>
+ <p>
+ Wir werden diese Frage komponentenweise beantworten. POI besteht aus
+ einer Reihe von Komponenten, die jeweils unterschiedliche Probleme
+ angehen. Das Kürzel »POI« steht für das gesamte Projekt.
+ </p>
+ <p>
+ Mit <strong>POIFS</strong> können Sie Dateien oder Dokumente, die im
+ OLE 2 Compound Document Format geschrieben wurden, mit Java
+ einlesen. Solche Dateien werden üblicherweise mit der
+ MFC-Klassenbibliothek erzeugt.
+ Außerdem können sie POIFS nutzen, um Dateien im OLE 2 Compound
+ Document Format zu schreiben. Damit können sie zum Beispiel
+ den Datenaustausch mit der Windows-Plattform sicherstellen.
+ Wir können guten Gewissens behaupten, daß POIFS die
+ vollständigste Implementierung dieses Dateiformates ist.
+ </p>
+ <p>
+ Mit <strong>HSSF</strong> können sie Excel-Dateien in Java lesen und
+ schreiben. Sie können auch Excel-Tabellen lesen und
+ modifizieren. Allerdings ist die Schreibfunktionalität im Moment am
+ ausgereiftesten.
+ </p>
+ </section>
+
+ <section><title>Wofür steht POI ?</title>
+ <p>
+ POI bedeutet »Poor Obfuscation Implementation« (Schlechte,
+ verschleiernde Implementierung).
+ Warum geben wir unserem Projekt einen so abschätzigen Namen?
+ Nun, das Microsoft OLE 2 Compound Document Format ist einfach
+ schlecht durchdacht. Von seiner Grundidee her ist es ein
+ Dateiarchiv mit einer Struktur, die dem alten DOS-FAT-Dateisystem
+ ähnelt. Die Redmonder haben kein bereits vorhandenes Archivformat
+ wie tar, gzip, zip oder arc genutzt, sondern stattdessen ein
+ eigenes Archivformat erfunden,
+ das keinerlei Standardverschlüsselung oder -komprimierung
+ bietet, das schlecht erweiterbar ist, und das zur
+ Fragmentierung neigt.
+ </p>
+ <p>POI ist außerdem eine Spezialität der hawaiianischen Küche. Sie wird
+ in <link href="http://www.m-w.com/">Merriam Webster's
+ Dictionary</link> beschrieben als: »Ein hawaiianisches Gericht aus
+ Taro-Wurzeln, die durch Stampfen, Kochen und Kneten zu einer Paste
+ geformt und oft noch ein wenig gegoren wird.« Dies ist witzigerweise
+ eine treffende Beschreibung des Dateiformats.</p>
+ <p>
+ POI ist also eine Abkürzung. Wenn Sie Abkürzungen nicht mögen,
+ dann denken sie einfach bei POI an das hawaiianischen Gericht.
+ Je nachdem, ob Sie Abkürzungen mögen oder nicht, nutzen sie
+ einfach POI oder Poi, wenn sie dieses Projekt meinen.
+ </p>
+ </section>
+ </section>
+
+
+ <section><title>Komponenten</title>
+ <section><title>Überblick</title>
+ <p>
+ POI besteht aus mehreren Komponenten, die jeweils unterschiedliche
+ Aufgaben angehen. Beispielsweise dient die Komponente HSSF dazu,
+ Excel-Dateien zu schreiben und zu lesen. Es folgt eine Liste aller
+ Komponenten des POI-Projektes mit einer sehr kurzen Zusammenfassung
+ ihres Zweckes.
+ </p>
+ </section>
+ <section><title>POIFS (POI Filesystem)</title>
+ <p>
+ POIFS ist der älteste und stabilste Teil des Projektes. POIFS
+ ist unsere Portierung des OLE 2 Compound Document Formats
+ in reinem Java. Es unterstützt Lesen und Schreiben. Alle
+ anderen Komponenten basieren auf POIFS. Mehr Informationen
+ gibt es auf der <link
+ href="../../poifs/index.html">POIFS-Seite</link>.
+ </p>
+ </section>
+ <section><title>HSSF</title>
+ <p>
+ HSSF ist unsere Portierung des Microsoft Excel 97(-2002)
+ Dateiformats in reinem Java. Es unterstützt Lesen und
+ Schreiben. Mehr Informationen gibt es auf der
+ <link href="../../spreadsheet/index.html">HSSF-Seite</link>.
+ </p>
+ </section>
+ <section><title>HWPF</title>
+ <p>
+ HWPF ist unsere Portierung des Microsoft Word 97 Datei-Formats
+ in reinem Java. Es unterstützt Lesen und Schreiben. Mehr
+ Informationen gibt es auf der
+ <link href="../../hwpf/index.html">HWPF-Seite</link>.
+ Diese Komponente ist noch nicht sehr weit fortgeschritten. Wir suchen
+ Entwickler, die mitmachen.
+ </p>
+ </section>
+ <section><title>HPSF</title>
+ <p>
+ HPSF ist unsere Portierung des OLE 2 Property Formats.
+ Property Sets nehmen die Metadaten eines
+ Dokuments auf, wie Titel, Autor und Datum. Sie
+ lassen sich aber auch für applikationsspezifische Aufgaben
+ nutzen. Mehr Informationen gibt es auf der
+ <link href="../../hpsf/index.html">HPSF-Seite</link>.
+ </p>
+ </section>
+ </section>
+ <section><title>Mitmachen</title>
+ <p>
+ Sie möchten bei diesem Projekt mitmachen? Hervorragend!
+ Wir brauchen immer begeisterte, fleißige und talentierte Leute, die
+ uns bei den verschiedenen Aufgaben des Projektes helfen. An erster
+ Stelle stehen Hinweise auf Fehler und Vorschläge für neue
+ Funktionen. Ebenso wichtig ist die Dokumentation.</p>
+ <p>Egal, ob sie Kritik oder Vorschläge haben,
+ oder ob Sie Beiträge in Form von Code oder Dokumentation liefern
+ möchten, immer werden Sie bei uns ein offenes Ohr
+ finden. Und nicht zuletzt brauchen wir Java-Programmierer, die
+ sich durch die zahlreichen Ecken und Kanten der Microsoft-Dateiformate
+ hindurchwühlen und uns dabei helfen, diese Formate auf die
+ Java-Plattform zu portieren.
+ </p>
+ <p>
+ Wenn Sie motiviert sind und Zeit haben, tragen Sie sich
+ in unsere Mailing-Listen ein, und machen sie mit! Bei der Einarbeitung
+ helfen wir Ihnen gerne.
+ </p>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: xml
+sgml-omittag:nil
+sgml-shorttag:nil
+sgml-namecase-general:nil
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Contribuciones de Terceras Partes</title>
+ <authors>
+ <person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ <person name="Agustín Martín Barbero" email="-"/>
+ </authors>
+ </header>
+
+ <body>
+
+ <section><title>Cómo Contribuir</title>
+ <p>
+ Vea <link href="contrib.xml">Cómo contribuir a Poi</link>.
+ </p>
+
+ </section>
+
+ <section><title>Componentes Contribuidos</title>
+ <p>
+ No es que estos tengan, necesariamente, suficiente calidad como para ser incluidos
+ en el núcleo de la distribución, pero han sido probados bajo <link href="contrib.xml">
+ varios entornos clave </link>, se proporcionan bajo la misma licencia que Poi, y se
+ incluyen en la distribución de POI bajo el directorio
+ <code>contrib/</code>.
+ </p>
+
+ <p>
+ <strong>¡Ninguno Todavía!</strong> - aunque pude esperarse que algunos de los enlaces
+ listados a continuación lleguen eventualmente a migrarse al nivel de "componentes contribuidos",
+ y posteriormente incluso a la mismísima distribución principal.
+ </p>
+ </section>
+
+ <section><title>Cola de Parches (Patch Queue)</title>
+ <p><link href="patches.html">Entregas de modificaciones (Submissions of modifications)</link>
+ a POI que esperan revisión. Cualquiera puede realizar comentarios sobre ellas en la lista
+ de desarrollo - ¡se necesitan revisores del código!
+ <strong>Su utilización cae bajo su responsabilidad</strong> - aunque POI no puede garantizarlo,
+ estos parches no han sido revisados, cuando menos aceptados.
+ </p>
+ </section>
+
+ <section><title>Otras Extensiones</title>
+ <p> Las otras extensiones listadas aquí <strong>tampoco están respaldadas</strong>
+ por el proyecto POI - se proporcionan sólo por comodidad. Pueden funcionar o no,
+ pueden ser de código abierto o no, etc.
+ </p>
+
+ <p> Para añadir un enlace a esta tabla, ver <link href="contrib.xml">Cómo contribuir
+ a POI</link>.</p>
+
+ <table>
+ <tr>
+ <th>Nombre y Enlace</th>
+ <th>Tipo</th>
+ <th>Descripción</th>
+ <th>Estado</th>
+ <th>Licencia</th>
+ <th>Contacto</th>
+ </tr>
+ </table>
+
+ </section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../../dtd/book-cocoon-v10.dtd">
+
+<book software="POI"
+ title="Documentación del Proyecto POI"
+ copyright="@year@ Proyecto POI"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <menu label="Apache POI">
+ <menu-item label="TOP" href="index.html"/>
+ </menu>
+
+ <menu label="Marketing">
+ <menu-item label="Casos" href="casestudies.html"/>
+ </menu>
+
+ <menu label="Proyecto">
+ <menu-item label="Descripción General" href="overview.html"/>
+ <menu-item label="POIFS [EN]" href="../../poifs/index.html"/>
+ <menu-item label="HSSF [EN]" href="../../spreadsheet/index.html"/>
+ <menu-item label="HWPF [EN]" href="../../hwpf/index.html"/>
+ <menu-item label="HPSF [EN]" href="../../hpsf/index.html"/>
+ <menu-item label="POI-Utils [EN]" href="../../utils/index.html"/>
+ <menu-item label="Descargas" href="ext:download"/>
+ </menu>
+
+ <menu label="Comunidad">
+ <menu-item label="Noticias" href="news.html"/>
+ <menu-item label="Espejos [EN]" href="../../mirrors.html"/>
+ <menu-item label="Cambios [EN]" href="../../changes.html"/>
+ <menu-item label="Tareas" href="todo.html"/>
+ <menu-item label="Contribuya [EN]" href="../../guidelines.html"/>
+ <menu-item label="Listas de Correo" href="http://jakarta.apache.org/site/mail2.html#poi"/>
+ <menu-item label="Visión [EN]" href="../../plan/POI20Vision.html"/>
+ <menu-item label="Historia y Futuro" href="historyandfuture.html"/>
+ <menu-item label="Quiénes Somos" href="who.html"/>
+ <menu-item label="Resoluciones [EN]" href="../../resolutions/index.html"/>
+ </menu>
+
+ <menu label="Documentación">
+ <menu-item label="Javadocs" href="http://jakarta.apache.org/poi/javadocs/"/>
+ <menu-item label="FAQ" href="faq.html"/>
+ <menu-item label="Referencias" href="../../references/index.html"/>
+ </menu>
+
+ <menu label="Traducciones">
+ <menu-item label="Índice" href="../../trans/index.html"/>
+ <menu-item label="Procedimientos" href="../../trans/guidelines.html"/>
+ <menu-item label="Alemán (DE)" href="../de/index.html"/>
+ <menu-item label="Español" href="index.html"/>
+ <menu-item label="Japonés (Web)" href="http://jakarta.terra-intl.com/poi/"/>
+ <menu-item label="Coreano(Web)" href="http://jakarta.apache-korea.org/poi/"/>
+ </menu>
+
+ <menu label="Código">
+ <!-- <menu-item label="El Código" href="http://jakarta.apache.org/poi/javadocs/javasrc/"/> -->
+ <menu-item label="CVS" href="http://jakarta.apache.org/site/cvsindex.html"/>
+ <!-- <menu-item label="CVS Changelog" href="changelog.html"/> -->
+ <menu-item label="Fallos (Bugs) Más Votados" href="http://issues.apache.org/bugzilla/buglist.cgi?votes=1&product=POI&order=bugs.votes"/>
+ <menu-item label="Base de Datos de Fallos" href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI"/>
+ <menu-item label="Parches" href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI&short_desc=%5BPATCH%5D&short_desc_type=allwordssubstr"/>
+
+ <menu-item label="Resultados de Pruebas Junit" href="ext:junit"/>
+ <menu-item label="Métricas de Dependencia" href="ext:jdepend"/>
+ <!-- <menu-item label="Métricas de Comprobación de Estilo" href="http://jakarta.apache.org/poi/metrics/checkstyle/"/> -->
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Estudio de Casos</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="CR" name="Cameron Riley" email="crileyNO@SPAMekmail.com"/>
+ <person id="AMB" name="Agustín Martín Barbero" email="-"/>
+ </authors>
+ </header>
+
+ <body>
+ <section>
+ <title>Introducción</title>
+ <p>
+ Mucha gente está utilizando POI para distintos propósitos. Como con cualquier
+ nueva API o tecnologia, la primera pregunta que la gente pregunta normalmente
+ no es "cómo puedo" sino "Quién más está haciendo lo que yo estoy a punto de
+ hacer?" Esto es comprensible con el abismal porcentage de éxito en el negocio
+ del software. Estos Casos pretenden ayudar a crear
+ confianza y comprensión.
+ </p>
+ </section>
+ <section>
+ <title>Enviando un Estudio de un Caso</title>
+ <p>
+ Estamos buscando activamente estudios de casos para esta página (después de todo
+ acaba de comenzarse). Andrew C. Oliver (acoliver at apache dot org) ha
+ accedido a entregar unas cuantas Camisetas con el logotipo de POI para
+ los primeros y mejores envíos. Para enviar un estudio de un caso, puedes
+ <link href="http://jakarta.apache.org/poi/guidelines.html">
+ enviar un parche para esta página</link> o enviarlo por correo electrónico
+ a la <link href="http://jakarta.apache.org/site/mail2.html#poi">lista de correo
+ </link> (con [PATCH] como prefijo en el asunto, por favor).
+ </p>
+ </section>
+ <section>
+ <title>Estudios de Casos</title>
+ <section><title>Sunshine Systems</title>
+ <p>
+ <link href="http://www.sunshinesys.com/">Sunshine Systems</link> desarrolló una
+ solución de informes basada en POI para un paquete software de optimización de precios
+ que se usa en grandes cadenas de venta.
+ </p>
+ <p> La solución permitió a los planificadores y gestores de la mercancía mercancía pedir
+ unos informes de soporte a la decisión e informes de cambios de precios utilizando un
+ navegador estándar. Los usuarios pueden especificar el tipo de informe, las opciones, así
+ como criterios de filtros como la división de la compañía
+ o departamento. La generación de informes se llevó a cabo en el
+ servidor de aplicaciones multi-hilo
+ y fue capaz de soportar muchas peticiones de informe simultáneas.
+ </p>
+ <p>La aplicación de informes recogía información del negocio de la base
+ de datos Oracle de la aplicación de optimización de precios.
+ Los datos se agregaban y resumían basándose en el tipo específico
+ de informe y los criterios de filtro pedidos por el usuario. El
+ informe final se generaba como una hoja de cálculo de Microsoft Excel utilizando
+ el API de POI HSSF y se almacenaba en el
+ servidor de base de datos de informes para ese usuario específico como un BLOB.
+ Los informes pueden ser vistos
+ fácilmente y bien integrados utilizando el mismo navegador.
+ </p>
+ <p>A los vendedores les gusto la solución porque así tenían acceso instantáneo
+ a datos del negocio críticios
+ a través de una interfaz basada en navegador extremadamente fácil de usar.
+ No necesitaban entrenar a su amplia comunidad de usuarios en las complejidades de la
+ aplicación de optimización. Lo que es más, los informes se generaban en un formato de
+ hoja de cálculo Excel,
+ que todo el mundo conocía y que también permitía análisis
+ de datos adicionales utilizando
+ características estándares de Excel.
+ </p>
+ <p>Rob Stevenson (rstevenson at sunshinesys dot com)
+ </p>
+ </section>
+ <section>
+ <title>Banco de Lituania</title>
+ <p>
+ El
+ <link href="http://www.lbank.lt/">Banco de Lituania</link>
+ genera informes de datos estadísticos financieros en formato Excel
+ utilizando el API <link href="http://jakarta.apache.org/poi/spreadsheet/">
+ HSSF</link> del proyecto
+ <link href="http://jakarta.apache.org/poi/">Jakarta POI</link>
+ El sistema está basado en Oracle JServer y utiliza
+ un procedimiento almacenado Java que utilizando el API HSSF
+ responde en formato XLS. - Arian Lashkov (alaskov at lbank.lt)
+ </p>
+ </section>
+<!-- <section>-->
+<!-- <title>Bit Tracker by Tracker Inc., and ThinkVirtual</title>-->
+<!-- <p>-->
+<!-- Bit Tracker (http://www.bittracker.com/) es el primer sistema a nivel mundial -->
+<!-- basado en web de registro de brocas (drill bit) para gestionar la información crítica -->
+<!-- de brocas de la compañía y sacar el mayor partido a esos datos. Gestiona todos los datos -->
+<!-- relacionados con las brocas, incluyendo su uso, localización, cómo se utilizan, y -->
+<!-- resultados como su relación de penetración y grado de desgaste con el uso. Estos datos -->
+<!-- necesitan estar disponibles en formato Excel para obtener compatibilidad hacia atrás -->
+<!-- y otros usos en la industria. Después de utilizar los formatos CSV y HTML, necesitábamos-->
+<!-- algo mejor para la creación de hojas de cálculo y POI es la respuesta. Funciona fenomenal-->
+<!-- y fue muy sencillo de implementar. Gracias al equipo de POI.-->
+<!-- </p>-->
+<!-- <p>-->
+<!-- Travis Reeder (travis at thinkvirtual dot com)-->
+<!-- </p>-->
+<!-- </section>-->
+ <section>
+ <title>Edwards And Kelcey Technology</title>
+ <p>
+ Edwards and Kelcey Technology (http://www.ekcorp.com/) desarrolló
+ un Sistema de Mantenimiento y Gestión de Instalaciones
+ para la industria de las Telecomunicaciones.
+ basado en Turbine y Velocity.
+ Originalmente la factura se hacía con una sencilla
+ hoja CVS que era entonces
+ marcada por cada cuenta y particularizada para cada cliente.
+ Como el crecimiento ha sido consistente con la aplicación, las necesidades de
+ facturas que no necesitasen ser retocadas a mano aumentaron. POI proporcionó la
+ solución a este problema, integrandose fácil y transparentemente en el sistema.
+ Se utilizó POI HSSF para crear las facturas directamente desde el servidor
+ en formato Excel 97
+ y ahora sirve más de 150 facturas diferentes cada mes.
+ </p>
+ <p>
+ Cameron Riley (crileyNO@ SPAMekmail.com)
+ </p>
+ </section>
+ <section>
+ <title>ClickFind</title>
+ <p>
+ <link href="http://www.clickfind.com/">ClickFind Inc.</link> utilizó el API
+ HSSF del proyecto POI para proporcionar a sus clientes
+ de investigación médica la capacidad de exportar a Excel desde su servicio
+ web de recolección de datos electrónicos Data Collector 3.0. La asistencia del equipo de POI
+ permitió que ClickFind proporcionara a sus clientes un formato de datos que requiere menos
+ conocimentos técnicos que el formato XML utilizado por la aplicación Data Collector.
+ Esto era importante para ClickFind ya que muchos de sus clientes actuales y potenciales
+ estaban utilizando Excel en sus operaciones del día-a-día
+ así como en procedimientos establecidos para el manejo de sus datos clínicos
+ generados. - Jared Walker (jared.walker at clickfind.com)
+ </p>
+ </section>
+ <section>
+ <title>IKAN Software NV</title>
+ <p>Además de Gestión del Cambio y Modelado de Base de Datos, IKAN Software NV
+ (http://www.ikan.be/) desarrolla y da soporte a su propia herramienta ETL
+ (Extrae/Transforma/Carga ó Extract/Transform/Load).</p>
+
+ <p>El último producto de IKAN en este dominio se llama ETL4ALL
+ (http://www.ikan.be/etl4all/). ETL4ALL es una herramienta de código abierto
+ que permite la transferencia de datos desde y hacia virtualmente cualquier
+ orígen de datos. Los usuarios pueden combinar y examinar datos almacenados en
+ base de datos relacionales, bases de datos XML, PDF, ficheros, EDI, CSV, etc.
+ </p>
+
+ <p>Es evidente que los ficheros de Microsoft Excel también estan soportados.
+ POI se ha utilizado para implementar con éxito este soporte en ETL4ALL.</p>
+ </section>
+
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE changes PUBLIC "-//APACHE//DTD Changes V1.1//EN" "../../dtd/changes-v11.dtd">
+
+<changes>
+
+ <title>Historial de Cambios</title>
+
+ <devs>
+ <!-- in strict alphabetical order -->
+ <person id="AO" name="Andrew C. Oliver" email="acoliver2@users.sourceforge.net"/>
+ <person id="GJS" name="Glen Stampoultzis" email="poi-user@jakarta.apache.org"/>
+ <person id="MJ" name="Marc Johnson" email="mjohnson@apache.org"/>
+ <person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ <person id="POI-DEVELOPERS" name="POI Developers" email="poi-dev@jakarta.apache.org"/>
+ </devs>
+ <release version="2.0-pre1" date="no publicada">
+ <action dev="POI-DEVELOPERS" type="add">Parche aplicado para el clonado en profundidad de hojas.</action>
+ <action dev="POI-DEVELOPERS" type="add">Parche aplicado para permitir la reordenación de la hoja</action>
+ <action dev="POI-DEVELOPERS" type="add">Se añaden métodos adicionales para definir el área de impresión utilizando números de fila/columna</action>
+ <action dev="POI-DEVELOPERS" type="fix">HWPF: arreglado un error de tamaño negativo del Array</action>
+ <action dev="POI-DEVELOPERS" type="update">Se añaden punteros a argumento para soportar la fórmula IF</action>
+ <action dev="POI-DEVELOPERS" type="update">Formulas: Se añade soporte de caracteres especiales para cadenas literales, específicamente para soporte de fórmulas SUMIF y tratar un error tambien</action>
+ <action dev="POI-DEVELOPERS" type="fix">BlockingInputStream subido para ayudar a asegurar las lecturas</action>
+ <action dev="POI-DEVELOPERS" type="fix">Se arregló un problema con valores NaN (No es Número) que diferían del valor investigado de lectura en ficheros de FormulaRecords</action>
+ <action dev="POI-DEVELOPERS" type="fix">Parche para getColumnWidth en HSSF</action>
+ <action dev="POI-DEVELOPERS" type="add">Parche para tratar con listas multi-nivel numeradas en HWPF</action>
+ <action dev="POI-DEVELOPERS" type="fix">Debido a los trabajos en las referencias con nombre, varios errores de nombres de rango se cerraron</action>
+ <action dev="POI-DEVELOPERS" type="fix">Parche aplicado para prevenir la corrupción de la hoja tras la modificación de una plantilla (template)</action>
+ <action dev="POI-DEVELOPERS" type="update">Soporte para fórmulas compartidas</action>
+ <action dev="POI-DEVELOPERS" type="update">Añadidos GreaterEqual, LessEqual y NotEqual al Evaluador de Fórmulas (Parser)</action>
+ <action dev="POI-DEVELOPERS" type="update">Añadida la funcionalidad GreaterThan y LessThan a las fórmulas</action>
+ <action dev="POI-DEVELOPERS" type="fix">Parches para i10n</action>
+ <action dev="POI-DEVELOPERS" type="update">POI Build System Actualizado</action>
+ <action dev="POI-DEVELOPERS" type="fix">nombres de fuentes pueden ser nulos</action>
+ </release>
+ <release version="1.10-dev" date="19 Febrero 2003">
+ <action dev="POI-DEVELOPERS" type="add">Soporte para el nivel de ampliación (zoom)</action>
+ <action dev="POI-DEVELOPERS" type="add">Soporte para el congelado y división del panel</action>
+ <action dev="POI-DEVELOPERS" type="add">Cabeceras de fila y columna en impresiones</action>
+ </release>
+ <release version="1.8-dev" date="20 Septiembre 2002">
+ <action dev="POI-DEVELOPERS" type="add">Soporte para Formato de Datos Personalizado (Custom)</action>
+ <action dev="POI-DEVELOPERS" type="add">Soporte Unicode Mejorado para Ruso y Japonés</action>
+ <action dev="POI-DEVELOPERS" type="add">Soporte para Fórmulas Mejorado, incluyendo
+ sólo-lectura para sentencias tipo "optimizado si" (optimized if).</action>
+ <action dev="POI-DEVELOPERS" type="add">Soporte para la clonación de objetos</action>
+ <action dev="POI-DEVELOPERS" type="add">Arreglos en la cabecera/pie</action>
+ <action dev="POI-DEVELOPERS" type="add">Traducciones de la documentación al Español</action>
+ <action dev="POI-DEVELOPERS" type="add">Soporte para preservar macros VBA</action>
+ </release>
+ <release version="1.7-dev" date="???">
+ <action dev="NKB" type="update">Se quita la dependencia en tiempo de ejecución del registro
+ (logging) de "commons".</action>
+ <action dev="POI-DEVELOPERS" type="update">Soporte para fórmulas</action>
+ </release>
+ <release version="1.5.1" date="16 Junio 2002">
+ <action dev="GJS" type="update">Se quita la dependencia del registro de "commons". Ahora hay que definir la propiedad del sistema poi.loggin para permitir
+ que los registros (logs) vayan a la salida estándar.</action>
+ <action dev="GJS" type="fix">Se arregla la gestión de la cadena SST para que las hojas de cálculo con texto rico (rich text) o texto
+ extendido se lean correctamente.</action>
+ </release>
+ <release version="1.5" date="06 Mayo 2002">
+ <action dev="NKB" type="update">Nueva versión (build) del proyecto.</action>
+ <action dev="NKB" type="update">Nuevo sistema de documentación del proyecto basada en Cocoon.</action>
+ <action dev="POI-DEVELOPERS" type="update">Cambio de nombre del paquete</action>
+ <action dev="POI-DEVELOPERS" type="fix">Varios errores (bugs) corregidos</action>
+ <action dev="POI-DEVELOPERS" type="add">Etapas preliminares del desarrollo de HFS (no esta listo para el desarrollo)</action>
+ <action dev="POI-DEVELOPERS" type="add">Soporte inicial de registros de bajo nivel para gráficas (no está completo)</action>
+ </release>
+<!-- type attribute should be changed below properly -->
+ <release version="1.1.0" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Se crea un nuevo modelo de eventos</action>
+ <action dev="POI-DEVELOPERS" type="add">Se optimiza HSSF, incluyendo registros (records) para
+ valores, filas, etc.</action>
+ <action dev="POI-DEVELOPERS" type="add">predicción de tamaño, escritura basada en desplazamiento (en lugar de
+ multitud de copias de arrays)</action>
+ <action dev="POI-DEVELOPERS" type="add">un poco de re-factoring (¿re-factorización? mejor no) y corrección de errores.</action>
+ </release>
+ <release version="1.0.0" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Actualizaciones menores a la documentación.</action>
+ </release>
+ <release version="0.14.0" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Se añade la clase de ayuda DataFormat y se expone el formato set y get en
+ HSSFCellStyle</action>
+ <action dev="POI-DEVELOPERS" type="add">Correcciones a las apis de anchura de columna (en cuanto a las unidades) y
+ varios comentarios javadoc al respecto</action>
+ <action dev="POI-DEVELOPERS" type="add">Corrección para el registro de "Dimensions" (de nuevo)... (uno de estos días
+ escribiré una prueba unitaria (unit test) para esto ;-p).</action>
+ <action dev="POI-DEVELOPERS" type="add">Alguna optimización en la creación de páginas.</action>
+ </release>
+ <release version="0.13.0" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Mejoras no registradas</action>
+ </release>
+ <release version="0.12.0" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Se añaden MulBlank, Blank, ColInfo</action>
+ <action dev="POI-DEVELOPERS" type="add">Se añade facilidad log4j y se quitan las anotaciones (logs) del tipo sys.out</action>
+ <action dev="POI-DEVELOPERS" type="add">Se añade soporte para la adición de fuentes, estilos y el api de alto
+ nivel correspondiente para dar estilo a las celdas</action>
+ <action dev="POI-DEVELOPERS" type="add">Se añade soporte para cambiar el alto de una fila, el ancho de una celda, y
+ sus valores por defecto.</action>
+ <action dev="POI-DEVELOPERS" type="add">Correcciones para internacionalización (UTF-16 debería funcionar ahora
+ desde HSSFCell.setStringValue, etc cuando se define la codificación)</action>
+ <action dev="POI-DEVELOPERS" type="add">Soporte para la adición / eliminación y cambio de nombre de hojas.</action>
+ </release>
+ <release version="0.11.0" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Distribución de corrección de errores.
+ Lanzamos una excepción cuando leemos objetos de tipo RKRecord.</action>
+ </release>
+ <release version="0.10.0" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Registros de continuación ya funcionan (lectura/escritura)</action>
+ <action dev="POI-DEVELOPERS" type="add">Se añade soporte previo para fórmulas</action>
+ <action dev="POI-DEVELOPERS" type="add">Reorganización del API masiva, re-enpaquetado.</action>
+ <action dev="POI-DEVELOPERS" type="add">Se añade la clase BiffViewer para validar HSSF & POI y/o la
+ salida de HSSF.</action>
+ <action dev="POI-DEVELOPERS" type="add">Se mejora el soporte a la modificación del API.</action>
+ </release>
+ <release version="0.7 (y distribuciones internas)" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Se añade una bandera de codificación para que las apis de alto
+ y bajo nivel utilicen utf-16 cuando sea necesario (HSSFCell.setEncoding())</action>
+ <action dev="POI-DEVELOPERS" type="add">Se añade soporte de sólo lectura a registros de Etiqueta
+ (que son reinterpretados como LabelSST cuando se escriben)</action>
+ <action dev="POI-DEVELOPERS" type="add">Se rompe la implementación del registro de continuación (oops)</action>
+ <action dev="POI-DEVELOPERS" type="add">Se añade la clase BiffViewer
+ para validar HSSF & POI y/o la
+ salida de HSSF.</action>
+ </release>
+ <release version="0.6 (distribución/release)" date="Fecha de distribución no registrada">
+ <action dev="POI-DEVELOPERS" type="add">Soporte para lectura/escritura y modificación.</action>
+ <action dev="POI-DEVELOPERS" type="add">Soporte de sólo lectura para registros de tipo MulRK
+ (convertidos a Number cuando se escriben)
+ </action>
+ </release>
+
+</changes>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE faqs PUBLIC "-//APACHE//DTD FAQ V1.1//EN" "../../dtd/faq-v11.dtd">
+
+<faqs title="Preguntas M Frecuentes (FAQ)">
+ <faq>
+ <question>
+ or qula lectura de una hoja de cculo simple lleva tanto tiempo?
+ </question>
+ <answer>
+ <p>
+ Probablemente hayas habilitado el registro (logging). Dicho registro es
+ una herramienta il para la bqueda de errores (debug). Tenerlo habilitado
+ reducirel rendimiento en un factor de al menos 100. El registro es il para
+ comprender por quPOI no puede leer alg fichero o para el propio desarrollo
+ de POI.
+ Los errores importantes se lanzan como excepciones, lo cual significa que
+ probablemente no necesites el registro (log).
+ </p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ ues el "eventmodel" (modelo de evento) de HSSF?
+ </question>
+ <answer>
+ <p> El paquete "eventmodel" de HSSF es un nuevo API para la lectura m eficiente de ficheros
+ XML. Requiere mayor conocimiento por parte del usuario, pero reduce el consumo de memoria a
+ una dima parte. Estbasado en el modelo de eventos AWT en combinaci con SAX. Si necesita
+ acceso de so-lectura a un fichero XML determinado, esta es la mejor manera de hacerlo.</p>
+ </answer>
+
+ </faq>
+ <faq>
+ <question>
+ or quno puedo leer el documento que creutilizando Star Office 5.1?
+ </question>
+ <answer>
+ <p>Star Office 5.1 escribe algunos registros utilizando el viejo estdar BIFF.
+ Esto provoca algunos problemas con POI que so soporta BIFF8.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ or qurecibo una excepci cada vez que intento leer mi hoja de cculo?
+ </question>
+ <answer>
+ <p>Es posible que su hoja de cculo contenga alguna caractertica que no est
+ soportada actualmente por HSSF. Por ejemplo - hojas de cculo que contengan
+ celdas con formato RTF (rich text) no est soportadas actualmente.</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ oporta HSSF hojas de cculo protegidas?
+ </question>
+ <answer>
+ <p>Al proteger una hoja de cculo, ta se cifra. No tocaremos el cifrado, porque no
+ tenemos el suficiente conocimiento legal y no estamos seguros de las implicaciones que
+ conllevar el intentar implementar esto. Si desea intentarlo, es libre de hacerlo y
+ de adirlo como un mulo enchufable (plugin). Sin embargo, no lo guardaremos aqu</p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ o se sabe si un campo contiene una fecha con HSSF?
+ </question>
+ <answer>
+ <p>Excel almacena las fechas como neros. Asla ica manera para determinar
+ si una celda estrealmente almacenada como una fecha consiste en mirar su formato.
+ Hay un modo de ayuda (helper) en HSSFDateUtil (desde la distribuci 1.7.0-dev)
+ que lo comprueba. Gracias a Jason Hoffman por proporcionar la soluci.</p>
+ <source>
+
+case HSSFCell.CELL_TYPE_NUMERIC:
+ double d = cell.getNumericCellValue();
+ // test if a date!
+ if (HSSFDateUtil.isCellDateFormatted(cell)) {
+ // format in form of M/D/YY
+ cal.setTime(HSSFDateUtil.getJavaDate(d));
+ cellText =
+ (String.valueOf(cal.get(Calendar.YEAR))).substring(2);
+ cellText = cal.get(Calendar.MONTH)+1 + "/" +
+ cal.get(Calendar.DAY_OF_MONTH) + "/" +
+ cellText;
+ }
+
+ </source>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ Estoy intentando ver un fichero XLS enviado como flujo (stream) desde un servlet y tengo
+ complicaciones. u es el problema?
+ </question>
+ <answer>
+ <p>
+ El problema normalmente se manifiesta como un mont de caracteres basura
+ en la pantalla. El problema persiste incluso aunque hayas configurado el tipo mime
+ correcto.
+ </p>
+ <p>
+ La respuesta breve es: no dependas de IE para mostrar un fichero binario.
+ Escribe un documento adjunto como es debido si lo envs a trav de un servlet.
+ Toda versi de IE tiene diferentes fallos (bugs) en este sentido.
+ </p>
+ <p>
+ El problema en la mayor de las versiones de IE reside en que no utiliza el tipo mime
+ de la respuesta HTTP para determinar el tipo de fichero; en su lugar utiliza la extensi
+ del fichero en la petici. Aspodr adir un <strong>.xls</strong> a su cadena de petici.
+ Por ejemplo: <em>http://yourserver.com/myServelet.xls?param1=xx</em>. Esto se consigue
+ filmente a trav del mapeo de URL en cualquier contenedor servlet. A veces una
+ petici como
+ <em>http://yourserver.com/myServelet?param1=xx&dummy=file.xls</em>
+ tambi funciona.
+ </p>
+ <p>
+ Para garantizar la correcta apertura del fichero en Excel desde IE, escribe
+ tu fichero a un fichero temporal bajo su raiz web desde tu servlet. Env entonces
+ una respuesta http al navegador para que haga una redirecci en el lado del cliente
+ a tu fichero temporal. (Si haces una redirecci en el lado del servidor utilizando
+ RequestDispatcher, tendr que adir .xls a la petici como se ha mendionado m
+ arriba)
+ </p>
+ <p>
+ Date cuenta de que cuando pides un documento que se abre con un manejador externo,
+ IE a veces realiza dos peticiones al servidor web. Asque si tu proceso generador
+ es pesado, tiene sentido escribir a un fichero temporal, para que peticiones
+ mtiples utilicen el fichero estico.
+ </p>
+ <p>
+ Nada de esto pertenece a Excel. El mismo problema ocurre cuando intentas general
+ cualquier fichero binario dinicamente a un cliente IE. Por ejemplo, si generas
+ ficheros pdf utilizando
+ <link href="http://xml.apache.org/fop">FOP</link>,
+ te encontrar con los mismos problemas.
+ </p>
+ <!-- Gracias a Avik por la respuesta -->
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ Quiero dar formato a una celda (Data format of a cell) de una hoja excel como
+ ###,###,###.#### o ###,###,###.0000. s posible hacer esto con POI?
+ </question>
+ <answer>
+ <p>
+ HSSF no soporta todav formatos de datos personalizados, sin embargo,
+ deber ser una facilidad razonablemente sencilla de adir y aceptaremos
+ gustosos contribuciones en este ea.
+ </p>
+ <p>
+ Estos son los formatos incluidos que soporta:
+ </p>
+ <p>
+ <link href="http://jakarta.apache.org/poi/javadocs/javasrc/org/apache/poi/hssf/usermodel/HSSFDataFormat_java.html#HSSFDataFormat">http://jakarta.apache.org/poi/javadocs/javasrc/org/apache/poi/hssf/usermodel/HSSFDataFormat_java.html#HSSFDataFormat</link>
+ </p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ o ado un borde alrededor de una celda unida (merged)?
+ </question>
+ <answer>
+ <p>
+ Ade celdas vacs alrededor de donde las celdas hubieran estado normalmente y
+ configura los bordes individualmente para cada celda.
+ Probablemente mejoraremos HSSF en el futuro para facilitar este proceso.
+ </p>
+ </answer>
+ </faq>
+ <faq>
+ <question>
+ Intentescribir valores en celdas ascomo cambiar el nombre de la hoja Excel
+ en mi lengua nativa, pero no pude hacerlo. :(
+ </question>
+ <answer>
+ <p>
+ Por defecto HSSF utiliza valores de celdas y nombres de hoja en unicode comprimido,
+ asi que para soportar la localizaci debers utilizar Unicode.
+ Para hacerlo debers configurarlo manualmente:
+ </p>
+ <source>
+
+ //
+ // para el nombre de la hoja
+ //
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet s = wb.createSheet();
+ wb.setSheetName( 0, "SomeUnicodeName", HSSFWorkbook.ENCODING_UTF_16 );
+
+
+ //
+ // para el valor de la celda
+ //
+ HSSFRow r = s.createRow( 0 );
+ HSSFCell c = r.createCell( (short)0 );
+ c.setCellType( HSSFCell.CELL_TYPE_STRING );
+ c.setEncoding( HSSFCell.ENCODING_UTF_16 );
+ c.setCellValue( "\u0422\u0435\u0441\u0442\u043E\u0432\u0430\u044F" );
+
+ </source>
+ <p>
+ Asegate de que haces la llamada a setEncoding() antes de llamar a setCellValue(),
+ si no, lo que le pases no serinterpretado correctamente.
+ </p>
+ </answer>
+ </faq>
+</faqs>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Historia del Proyecto</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="AMB" name="Agustín Martín Barbero" email="-"/>
+ </authors>
+ </header>
+
+ <body>
+
+
+ <section><title>Breve Historia del Proyecto</title>
+
+ <p>
+ El proyecto POI se gesttiempo atr, cerca de abril de 2001,
+ cuando Andrew Oliver obtuvo un contrato de corta duraci para realizar
+ informes Excel basados en Java. Ya hab realizado este proyecto unas
+ cuantas veces antes, y sab exactamente dde buscar las herramientas
+ que necesitar.
+ Iricamente, el API que sol utilizar se hab disparado en precio
+ desde unos $300 ($US) hasta unos $10K ($US). Calculque a dos personas
+ les llevar unos seis meses el portar Excel asque le recomendal
+ cliente que pagase los $10K.
+ </p>
+
+ <p>
+ Cerca de junio de 2001, Andrew empeza pensar lo genial que ser
+ tener una herramienta Java de cigo abierto para hacer esto y,
+ mientras tuvo algo de tiempo libre, comenzel proyecto y aprendis
+ cosas sobre el Formato de Documento Compuesto OLE2. Tras chocarse
+ con varios obstulos insalvables, se dio cuenta de que necesitar ayuda.
+ Publicun mensaje en su Grupo de Usuarios Java local (JUG) y
+ preguntsi alguien estaba interesado. Tuvo mucha suerte y el
+ programador Java de mayor talento que hab conocido nunca,
+ Marc Johnson, se unial proyecto. A Marc le llevunas pocas
+ iteraciones el obtener algo con lo que estaban contentos.
+ </p>
+
+ <p>
+ Mientras Marc trabajaba en eso, Andrew portXLS a Java, basdose
+ en la biblioteca de Marc. Varios usuarios escribieron peticiones
+ para poder leer XLS (no so escribirlo como hab sido planeado
+ originalmente) y un usuario ten peticiones especiales para
+ un uso diferente de POIFS. Antes de que pasara mucho tiempo,
+ el alcance del proyecto se hab triplicado. POI 1.0 se distribuys
+ un mes m tarde de lo planeado, pero con muchas m caracterticas.
+ Marc escribiridamente el marco del serializador y el
+ Serializador HSSF en tiempo rord y Andrew generm documentaci
+ y trabajen hacer que la gente conociera este proyecto.
+ </p>
+
+ <p>
+ Poco antes de la distribuci, POI tuvo la fortuna de entrar
+ en contacto con Nicola -Ken- Barrozzi quien proporcionejemplos
+ para el Serializador HSSF y ayuda descrubir sus desafortunados
+ fallos (que fueron arreglados de inmediato). Recientemente, Ken
+ portla mayor de la documentaci del proyecto POI a XML
+ partiendo de los documentos HTML cutres que Andrew hab escrito
+ con Star Office.
+ </p>
+
+ <p>
+ M o menos al mismo tiempo de la primera distribuci, Glen Stampoultzis
+ se unial proyecto. A Glen le molestaba la actitud impertinente de Andrew
+ en lo que adir capacidades gricas a HSSF se refer. Glen se molests
+ tanto que decidicoger un martillo y hacerlo mismo. Glen ya se ha
+ convertido en parte integral de la comunidad de desarrollo de POI; sus
+ contribuciones a HSSF ya han comenzado a producir olas.
+ </p>
+
+ <p>
+ En algíì momento decidimos finalmente remitir el proyecto a
+ <link href="http://cocoon.apache.org/">El Proyecto Cocoon
+ de Apache</link>, so para descubrir que el proyecto hab
+ crecido encajando perfectamente con Cocoon hac tiempo.
+ Lo que es m, Andrew comenza ojear otros proyectos a los que
+ le gustar que se adiera la funcionalidad de POI. Asque
+ se decididonar los Serializadores y Generadores a Cocoon, otros
+ componentes de integraci con POI a otros proyectos, y los APIs
+ de POI pasarn a formar parte de Jakarta. Fue un camino con
+ baches, ¡ðero parece que todo salibien puesto que ahora est
+ leyendo esto!
+ </p>
+
+ </section>
+
+ <section><title>¿Èacia dde va POI?</title>
+ <p>
+ Primero abordaremos esto desde el punto de vista del proyecto:
+ Bueno, les hicimos la oferta a Microsoft y Actuate (de co
+ ... en su mayor parte) de que dejarmos el proyecto y nos
+ retirarmos si simplemente nos firmaban a cada uno un cheque
+ con muchos ceros. Todav estoy esperando una llamada o correo
+ electrico, asque de momento asumo que no nos van a pagar
+ para quitarnos de en medio.
+ </p>
+ <p>
+ Despu, tenemos algo de trabajo que hacer aquen Jakarta
+ para terminar de integrar POI en la comunidad. Lo que es m,
+ todav estamos realizando la transici del Serializador a
+ Cocoon.
+ </p>
+ <p>
+ HSSF, durante el ciclo 2.0, sufrirvarias optimizaciones.
+ Tambi adiremos nuevas caracterticas como una implementaci
+ completa de Fmulas y formatos de texto personalizados. Esperamos
+ ser capaces de generar ficheros m peques adiendo soporte de
+ escritura para registros RK, MulRK y MulBlank. A d de hoy, la
+ lectura en HSSF no es muy eficiente. Esto se debe sobre todo a que
+ para escribir o modificar, uno necesita ser capaz de actualizar
+ punteros del flujo de subida (upstream pointers) a datos del flujo
+ de bajada. Para hacer esto hay que tener todo lo que haya en
+ medio en memoria. En vez de eso, un Generador permitir que se
+ procesaran eventos SAX. (Esto se basaren las estructuras de
+ bajo nivel). Una de las mejores cosas sobre esto es que asno so
+ tendremos una manera m eficiente de leer el fichero, tambi
+ tendremos una magnica forma de utilizar hojas de cculo como
+ fuentes de datos XML.
+ </p>
+ <p>
+ El Serializador HSSF, se separarm aíì en un marco genico
+ para la creaci de serializadores para otras plataformas y
+ en la implementaci especica del serializador HSSF. (Esto ya
+ es cierto en gran medida). Tambi adiremos soporte para
+ caracterticas ya soportadas por HSSF (estilos, fuentes, formatos
+ de texto). Esperamos adir soporte para fmulas durante este ciclo.
+ </p>
+ <p>
+ Estamos empezando a expandir nuestro alcance de nuevo. Si pudimos
+ hacer todo esto para ficheros XLS, ¿ñuhay de ficheros Doc o PPT?
+ Pensamos que nuestro siguiente componente (HWPF)
+ deber seguir el mismo patr. Esperamos
+ que se nos una sangre nueva al equipo y que nos permita abordar
+ esto con mayor celeridad (en parte porque POIFS ya estterminado).
+ ¡Ðero a lo mejor lo que m necesitamos es a ti!
+ </p>
+ </section>
+
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+
+
+</document>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="El Proyecto de POI"
+ title="HSSF"
+ copyright="El Proyecto de POI de @year@"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <menu label="Navegación">
+ <menu-item label="Página Principal" href="../index.html"/>
+ </menu>
+
+ <menu label="HSSF">
+ <menu-item label="Referencia Rápida" href="quick-guide.html"/>
+ <menu-item label="Como Se Hace" href="how-to.html"/>
+ <menu-item label="Apoyo Con Fórmulas" href="formula.html" />
+ <menu-item label="Use Case" href="use-case.html"/>
+ <menu-item label="Diagramas" href="diagrams.html"/>
+ <menu-item label="Limitaciones" href="limitations.html"/>
+ </menu>
+
+ <menu label="Guía para el Contribuyente">
+ <menu-item label="Hack-eando HSSF" href="hacking-hssf.html"/>
+ <menu-item label="Generador de Registros" href="record-generator.html"/>
+ </menu>
+
+</book>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - HSSF</title>
+ <subtitle>Vista General</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>Diagrama de Clases del Usermodel por Matthew Young</title>
+ <p>
+ <img alt="usermodel" src="images/usermodel.gif"/>
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - HSSF</title>
+ <subtitle>Vista General</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>Vista General</title>
+ <p>
+ Se espera usar esta sección para diagramas (UML/etc) que ayudan a
+ explicar HSSF.
+ </p>
+ <ul>
+ <li>
+ <link href="diagram1.html">Diagrama de Clases del UserModel</link> -
+ por Matthew Young (myoung at westernasset dot com)
+ </li>
+ </ul>
+ <p>
+ Tiene más? Agrega un nuevo "bug" al archivo de bugs con la
+ palabra [DOCUMENTATION] antes de la descripción y un link al file en algun webserver. Si no tiene su propio webserver, mandaselo por email a (acoliver at apache dot org) siempre y cuando el tamaño del archivo es menor a 5 Mb. Diagramas deben estar en algun formato compatible, por lo menos, con Linux y Windows. Se prefieren diagramas que se pueden cambiar o modificar pero entendemos que hay pocos programas para crear UML que están a buen precio. Y no, no TIENEN que ser UML... solo tienen que ser utiles.
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Formula Support</title>
+ <authors>
+ <person email="avik@apache.org" name="Avik Sengupta" id="AS"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Introduction</title>
+ <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</title>
+ <p>
+ In org.apache.poi.hssf.usermodel.HSSFCell
+ <strong> setCellFormula("formulaString") </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 <em> setCellFormula </em> 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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Hacking HSSF</title>
+ <authors>
+ <person email="poi-user@jakarta.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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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?</title>
+ <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?</title>
+ <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>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - The New Halloween Document</title>
+ <authors>
+ <person email="acoliver2@users.sourceforge.net" name="Andrew C. Oliver" id="AO"/>
+ <person email="poi-user@jakarta.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</title>
+
+ <section><title>Capabilities</title>
+ <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</title>
+ <section><title>User API</title>
+ <section><title>Writing a new one</title>
+
+ <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,"SheetName",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</title>
+
+<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</title>
+
+ <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("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>
+<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</title>
+
+<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>
+ </section>
+ <section><title>HSSF Class/Test Application</title>
+
+<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>"myxls.xls"</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</title>
+ <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</title>
+
+<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>
+
+ </section>
+ <section><title>What's Next?</title>
+
+<p>This release contains code that supports "internationalization"
+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>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - 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</title>
+
+ <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://cocoon.apache.org/">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>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Limitations</title>
+ <authors>
+ <person email="poi-user@jakarta.apache.org" name="Glen Stampoultzis" id="GJS"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Version 1.5 limitations</title>
+ <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>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Busy Developers' Guide to HSSF Features</title>
+ <authors>
+ <person email="poi-user@jakarta.apache.org" name="Glen Stampoultzis" id="CO"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>Busy Developers' Guide to Features</title>
+ <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</title>
+ <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</title>
+ <anchor id="NewWorkbook"/>
+ <section><title>New Workbook</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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.getBuiltinFormat("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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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</title>
+ <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>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Record Generator HOWTO</title>
+ <authors>
+ <person email="poi-user@jakarta.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</title>
+
+ <section><title>History</title>
+ <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</title>
+ <p>
+ The record generator takes XML as input and produced the following
+ output:
+ </p>
+ <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>
+ </section>
+ <section><title>Usage</title>
+ <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</title>
+ <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</title>
+ <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>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - HSSF Use Cases</title>
+ <authors>
+ <person email="marc.johnson@yahoo.com" name="Marc Johnson" id="MJ"/>
+ </authors>
+ </header>
+ <body>
+ <section><title>HSSF Use Cases</title>
+ <section><title>Use Case 1: Read existing HSSF</title>
+
+<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 "Workbook"
+ 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</title>
+
+<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 "Workbook" 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</title>
+
+<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</title>
+<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 "Workbook" 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</title>
+
+
+<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 "Workbook"
+ file (POIFS use case 8, read file system directory)</li>
+ <li>If "Workbook" 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 "Workbook" (POIFS use case 6,
+ write new file to file system)</li>
+</ol>
+<p><strong>Extensions:</strong>None</p>
+</section>
+
+</section>
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - API Java Para Acceder Ficheros con Formato Microsoft</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="GJS" name="Glen Stampoultzis" email="poi-user@jakarta.apache.org"/>
+ <person id="AS" name="Avik Sengupta" email="poi-user@jakarta.apache.org"/>
+ <person id="AMB" name="Agustín Martín Barbero" email="poi-user@jakarta.apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Propósito</title>
+ <p>
+ El proyecto POI consiste en APIs para manipular varios formatos de ficheros
+ basados en el formato de Documento Compuesto OLE 2 de Microsoft, utilizando Java puro. En concreto, se pueden
+ leer y escribir ficheros MS Excel utilizando Java. Pronto se podrá leer y escribir
+ ficheros Word utilizando Java. POI es su solución Java Excel así como su solución Java Word.
+ En cualquier caso, tenemos un API completo para portar otros formatos de Documento Compuesto OLE 2 y todo aquel
+ que quiera participar será bienvenido.
+ </p>
+ <p>
+ Entre los ficheros basados en el formato de Documento Compuesto OLE 2 de Microsoft se incluyen la mayor parte de los
+ ficheros de Microsoft Office tales como XLS y DOC así como formatos de fichero basados en el API de serialización MFC.
+ </p>
+ <p>
+ Como regla general intentamos colaborar lo más posible con otros proyectos para proporcionar esta
+ funcionalidad. Algunos ejemplos: <link href="http://xml.apache.org/cocoon">Cocoon</link> para
+ el que hay serializadores para HSSF;
+ <link href="http://www.openoffice.org">Open Office.org</link> con quienes colaboramos en la documentación del
+ formato XLS; y <link href="http://jakarta.apache.org/lucene">Lucene</link> para el que pronto tendremos intérpretes del
+ formato de fichero. Cuando es práctico, donamos componentes directamente a los proyectos para dotarles de capacidad-POI.
+ </p>
+ <section><title>¿Por qué/cuándo utilizar POI?</title>
+ <p>
+ Abordaremos esto a nivel de componente. POI se refiere al proyecto completo.
+ </p>
+ <p>
+ Así que, ¿por qué debería utilizar POIFS o HSSF?
+ </p>
+ <p>
+ Utilizarías POIFS si tuvieras un documento escrito en el Formato de Documento Compuesto OLE 2, probablemente escrito utilizando
+ MFC, que necesitaras leer en Java. Alternativamente, utilizarías POI para escribir en el Formato de Documento Compuesto OLE 2
+ si necesitaras inter-operar con programas ejecutándose en la plataforma Windows. No nos estamos jactando cuando decimos que
+ ¡POIFS es la adaptación más completa y correcta de este formato de fichero hasta la fecha!
+ </p>
+ <p>
+ Utilizarías HSSF si necesitaras leer o escribir un fichero Excel utilizando Java (XLS). También se pueden leer y modificar
+ hojas de cálculo utilizando este API, aunque ahora mismo la escritura está más madura.
+ </p>
+ </section>
+ </section>
+
+
+ <section><title>Componentes a Día de Hoy</title>
+ <section><title>Visión General</title>
+ <p>Un pensamiento erróneo generalizado es que POI escribe ficheros Excel. POI es el nombre del proyecto. POI contiene varios
+ componentes, uno de los cuales, HSSF, escribe ficheros Excel. Siguen a continuación los componentes del
+ proyecto POI completo y un pequeño sumario de su propósito.</p>
+ </section>
+ <section><title>POIFS</title>
+ <p>POIFS es la parte más vieja y más estable del proyecto. Es nuestra adaptación del Formato de Documento Compuesto
+ OLE 2 a Java puro. Soporta funcionalidad de lectura y escritura. Todos nuestros componentes se sirven de él por
+ definición. Por favor, vea <link href="../../poifs/index.html">la página del proyecto POIFS [EN]</link> para más información.</p>
+ </section>
+ <section><title>HSSF</title>
+ <p>HSSF es nuestra adaptación del formato de fichero de Microsoft Excel 97(-2002) (BIFF8) a Java puro. Soporta lectura y
+ escritura. Por favor, vea <link href="../../spreadsheet/index.html">la página del proyecto HSSF [EN]</link> para más información.</p>
+ </section>
+ <section><title>HWPF</title>
+ <p>HWPF es nuestra adaptación del formato de fichero de Microsoft Word 97 a Java puro. Soporta lectura y escritura.
+ Por favor, vea <link href="../../hwpf/index.html">la página del proyecto HWPF [EN] para más información</link>. Este
+ componente está en la fase inicial de diseño. Ya puede leer y escribir ficheros sencillos. ¡Entra!</p>
+ </section>
+ <section><title>HPSF</title>
+ <p>HPSF es nuestra adaptación del formato de conjunto de propiedades OLE 2 a java puro.
+ Los conjuntos de propiedades se utilizan mayoritariamente para almacenar las propiedades
+ de un documento (título, autor, fecha de la última modificación etc.), pero también pueden ser
+ utilizados para propósitos específicos de una aplicación. Actualmente HPSF soporta
+ sólo funcionalidad de lectura. Por favor, vea
+ <link href="../../hpsf/index.html">la página del proyecto HPSF [EN]</link> para más
+ información.</p>
+ </section>
+
+ </section>
+
+ <section><title>Contribuyendo </title>
+ <p>
+ Así que ¿te gustaría contribuir al proyecto? ¡Genial! Necesitamos gente entusiasta, que trabaje duro, que tenga talento para ayudarnos
+ con el proyecto en varias áreas. ¡La primera es petición de nuevas funciones y aviso de errores! La segunda es documentación -
+ estaremos a tu entera disposición si tienes alguna crítica o te gustaría contribuir o mejorar de alguna forma la documentación.
+ ¡Especialmente no nos vendría mal algo de ayuda en documentar el formato de fichero HSSF! ¡Por último, aunque no por ello
+ menos importante, nos vendría bien algunos programadores Java que mastiquen binario, para que le echen el diente a la convolución que caracteriza
+ los formatos de fichero de Microsoft y para que nos ayude a adaptar nuevos formatos a una plataforma Java superior!
+ </p>
+ <p> ¡Así que si estás motivado, listo, y tienes tiempo, únete a las listas de correo y estaremos encantados de ayudarte a
+ empezar en el proyecto!
+ </p>
+
+
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - En las Noticias del mundo</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="TK" name="Tetsuya Kitahata" email="tetsuya@apache.org"/>
+ <person id="AMB" name="Agustín Martín Barbero" email="-"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>POI en los medios de comunicación</title>
+ <p>
+ Estos son artículos/etc. sobre POI publicados en la red. Si ves
+ alguna noticia sobre POI o algún sitio en el que se le menciona
+ de manera notable (no en tu propia página en la que pones la palabra
+ POI para que enlacemos contigo y en la que casualmente hay una foto
+ de tu mujer e hijos) entonces envía un parche a la lista. En general
+ dedicaremos el mismo tiempo así que no tengáis reparos en enviar
+ difamaciones coléricas así como comentarios favorables, técnicos y
+ objetivos. No mencionaremos mensajes realmente estúpidos (lo sentimos).
+ </p>
+ </section>
+ <section><title>Inglés</title>
+ <ul>
+ <li>
+ <link href="http://archive.midrange.com/web400/200204/msg00023.html">Discusión sobre el uso de POI en AS/400s</link>
+ </li>
+ <li>
+ <link href="http://www.somelist.com/mails/23819.html">Discusión de cuando casi tuvimos POI como el filtro para KOffice si asuntos de política y licencias no lo hubieran condenado al fracaso</link>
+ </li>
+ <li>
+ <link href="http://www.oreillynet.com/pub/wlg/1552?page=last&x-showcontent=text">Discusión Java en O'Reilly Network incluyendo discusión sobre POI</link> - O'Reilly.net
+ </li>
+ <li>
+ <link href="http://www.rollerweblogger.org/page/roller/20020715">Poor Obfuscation Implementation (Implementación Pobre de Ofuscación).</link> - Blog de David M. Johnson
+ </li>
+ <li>
+ <link href="http://www.jsurfer.org/article.php?sid=322">
+ Descarga POI 1.5-dev-rc2 </link> - JSurfer
+ </li>
+
+ <li>
+ <link href="http://directory.google.com/Top/Computers/Programming/Languages/Java/Class_Libraries/Data_Formats/Microsoft_Formats/"> Google dice que somos los más importantes en nuestra categoría </link>
+ </li>
+ <li>
+ <link href="http://www.javaworld.com/javaworld/javaqa/2002-05/01-qa-0503-excel3.html">It's POI-fect</link> - Tony Sintes, Javaworld
+ </li>
+ <li>
+ <link href="http://www.need-a-cake.com/categories/cocoonWeblog/2002/03/07.html">
+ Nicola anuncia código de serialización POI
+ </link> - Matthew Langham's Radio Weblog
+ </li>
+ <li>
+ <link href="http://javalobby.org/discussionContext/showThreaded/frm/javalobby?folderId=20&discussionContextId=11523">
+ Descarga Jakarta POI 1.4583</link> - JavaLobby
+ </li>
+ <li>
+ <link href="http://javalobby.org/discussionContext/showThreaded/frm/javalobby?discussionContextId=11442&folderId=20">
+ El proyecto POI se mueve a Jakarta (OLE 2 CDF/Excel/Word en
+ java puro)</link> - JavaLobby
+ </li>
+ <li>
+ <link
+ href="http://www.geocities.com/marcoschmidt.geo/java-image-coding.html">
+ Listado de bibliotecas Java para leer y escribir ficheros de imágenes y documentos
+ </link> - Página de Marco Schmidt (normalmente no anunciaríamos
+ la página personal de nadie, pero es un listado extensivo de información
+ que incluye "alternativas a POI" (para aquellos que son muy ricos). ¡Pero, qué
+ l3ch3s, creo que voy a marcar esta página para mí puesto que tiene enlaces a
+ direcciones que en conjunto contienen o enlazan con todo el conocimiento de la humanidad!)
+ </li>
+ <li>
+ <link href="http://radio.weblogs.com/0101350/">
+ Experiencias de un Operador (Måns af Klercker)
+ </link> - radio.weblogs.com
+ </li>
+ <li>
+ <link href="http://dataconv.org/apps_office.html">
+ DATACONV - Herramientas de Conversión de Datos: Office
+ </link> DATACONV
+ </li>
+ <li>
+ <link href="http://chicago.sourceforge.net/devel/">
+ Página del Desarrollador de Chicago
+ </link>
+ </li>
+ <li>
+ <link href="http://www.onjava.com/pub/d/1157">
+ POI/Proyecto de Serialización de POI
+ </link> - Tío, sabes que estás en lo alto cuando le gustas a
+ O'Reilly. ;-)
+ </li>
+ <li>
+ <link
+ href="http://www.javaworld.com/netnews/index.shtml">
+ Noticias en la Red
+ </link> - Java World
+ </li>
+
+ </ul>
+ </section>
+ <section><title>Nederlandstalige (Holandés)</title>
+ <ul>
+ <li>
+ <link
+ href="http://www.ster.be/java/java9.html">
+ Een Excel-werkboek maken vanuit Java - Lieven Smits
+ </link>
+ </li>
+ </ul>
+ </section>
+ <section><title>Deutsch (Alemán)</title>
+ <ul>
+ <li> <link
+ href="http://www.entwickler.com/itr/news/show.php3?id=6132&nodeid=82 ">Apache POI verffentlicht</link> - entwicker.com
+ </li>
+ <li>
+ <link
+ href="http://www.jsp-develop.de/newsletter/10/">
+ Apache Jakarta-Projekt bringt Word und Excel in die Java-Welt </link> - jsp-develop.de (for the misguided who use JSP ;-) )
+ </li>
+ <li>
+ <link
+ href="http://www.entwickler.com/news/2002/02/5718/news.shtml">
+ Neues Apache-Projekt bringt Word- und Excel nach Java
+ </link> - entwickler.com
+ </li>
+ </ul>
+ </section>
+ <section><title>Español (Spanish)</title>
+ <ul>
+ <li>
+ <link href="http://www.javahispano.com/noticias/todas.jsp">
+ OLE2 desde Java nativo
+ </link> - javaHispano
+ </li>
+ <li>
+ <link href="http://p2p.wrox.com/archive/java_espanol/2002-08/3.asp">Discusión sobre Excel y Java incluyendo POI de los foros de Wrox</link>
+ </li>
+ </ul>
+ </section>
+ <section><title>Francais (Francés)</title>
+ <ul>
+ <li>
+ <link href="http://linuxfr.org/section/D%E9veloppeur,0,1,8,0.html">
+ Excel/OLE accessibles
+ </link> - Da Linux French Page
+ </li>
+ <li>
+ <link href="http://www.sogid.com/javalist/f2002/traiter_word_java.html">Discusión sobre POI en francés</link>
+ </li>
+ </ul>
+ </section>
+ <section><title>Nihongo (Japonés)</title>
+ <ul>
+ <li>
+ <link href="http://drpanda.freezope.org/Memo/docs/jakarta/poi/poi_sample">100% PureJava...</link> - Dr. Panda Portal
+ </li>
+ <li>
+ <link
+ href="http://www.gimlay.org/~andoh/java/javanew.html">
+ What's new with java?
+ </link> - gimlay.org
+ </li>
+ <li><link href="http://taka-2.com/jclass/POI/">Java?Excel?????</link> - appears to show how to use Japanese with POI</li>
+ <li><link href="http://www.tech-arts.co.jp/macosx/webobjects-jp/htdocs/3200/3218.html">Various discussion in Japanese including on POI</link></li>
+ <li><link href="http://muimi.com/j/jakarta/">Japanese resources on Jakarta projects including POI</link></li>
+ <li><link href="http://www.fk.urban.ne.jp/home/kishida/">Kishida's site</link> -- Weekly Forte Lectures -- includes a snip about POI and Japanese.</li>
+ </ul>
+ </section>
+ <section><title>Russkii Yazyk (Ruso)</title>
+ <ul>
+ <li>
+ <link href="http://www.nestor.minsk.by/kg/kg02/21/kg22108.html">
+ Probably a translation of the Javalobby announcement of 1.5-final
+ </link> -- Computer News (What's New)
+ </li>
+ </ul>
+ </section>
+ <section><title>Hangul (Coreano)</title>
+ <ul>
+ <li>
+ <link href="http://www.javabrain.co.kr/AnswerView?questionId=1189&categoryId=8">Various discussion in Korean about Excel output/APIs including POI</link>
+ </li>
+ </ul>
+ </section>
+ <section><title>Ni idea</title>
+ <p>
+ ¡Si entiendes alguno de estos idiomas, envía un correo a la lista
+ diciéndonos en qué idioma está escrito y lo pondremos donde corresponda!
+ </p>
+ <ul>
+ <li>
+ <link
+ href="http://www.javacentrix.com/index.htm">
+ Si tuviera que adivinar, diría que es Tailandés, pero a lo mejor
+ alguno de vosotros lo sabe con seguridad.</link> - javacentrix.com
+ </li>
+ </ul>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Descripción General</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="AMB" name="Agustín Martín Barbero" email="-"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>¿Qué es?</title>
+ <p>El proyecto POI es el proyecto principal para el desarrollo de adaptaciones (ports)
+ en Java puro de los formatos de fichero basados en el Formato de Documento Compuesto OLE 2
+ de Microsoft. El Formato de Documento Compuesto OLE 2 lo utilizan los Documentos Office de
+ Microsoft, así como por los programas que utilizan conjuntos de propiedades MFC para serializar
+ sus objetos de tipo documento.
+ </p>
+ </section>
+ <section><title>Sub-Proyectos</title>
+ <p>
+ Los siguientes son adaptaciones, paquetes o componentes contenidos en el proyecto POI.
+ </p>
+ <section><title>POIFS</title>
+ <p>
+ <link href="../../poifs/index.html">POIFS [EN]</link> es el conjunto de APIs (Interfaces de Aplicación)
+ para la lectura y escritura del Formato de Documento Compuesto OLE 2 utilizando (únicamente) Java.
+ </p>
+ </section>
+
+ <section><title>HSSF</title>
+ <p>
+ <link href="../../spreadsheet/index.html">HSSF [EN]</link> es el conjunto de APIs para la lectura y
+ escritura de hojas de cálculo de Microsoft Excel 97(-XP) utilizando (únicamente) Java.
+ </p>
+ </section>
+
+ <section><title>HWPF</title>
+ <p>
+ <link href="../../hwpf/index.html">HWPF [EN]</link> es el conjunto de APIs para la lectura y
+ escritura de documentos Word 97(-XP) de Microsoft utilizando (únicamente) Java.
+ </p>
+ </section>
+
+ <section><title>HPSF</title>
+ <p>
+ <link href="../../hpsf/index.html">HPSF [EN]</link> es el conjunto de APIs para la lectura
+ de conjuntos de propiedades utilizando (únicamente) Java.
+ </p>
+ </section>
+
+ <section><title>Utilidades-POI (POI-Utils)</title>
+ <p>
+ <link href="../../utils/index.html">POI-Utils [EN]</link> son artefactos de propósito
+ general surgidos en el desarrollo de POI que no han sido implementados en ningún otro sitio.
+ Siempre buscamos donarlos y mantenerlos como parte de una biblioteca general utilizada en
+ algún otro proyecto. Estas son cosas que necesitamos para completar nuestra misión pero que
+ generalmente estan fuera de ella.
+ </p>
+ </section>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The POI Project All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Patch Queue</title>
+ <authors>
+ <person email="greenrd@hotmail.com" name="Robin Green"/>
+ <person email="barozzi@nicolaken.com" name="Nicola Ken Barozzi"/>
+ </authors>
+ </header>
+ <body>
+ <section>
+ <title>Introduction</title>
+ <p>
+ This is an
+ <strong>informal</strong> list - in chronological order -
+ of some of the noteworthy patches that have been posted
+ to the
+ <code>developers</code> mailing list.
+ These patches are not (yet) part of the POI project, but need reviewing for possible
+ inclusion. This system was instituted because, due to the large volume of mail and
+ the lack of time of the committers, some patches tended to get forgotten about. This
+ queue does not guarantee that any patch will be reviewed within a reasonable time frame,
+ but it does at least make them easier to find!
+ </p>
+ <p>
+ <strong>Reviewers wanted!</strong> - If you have time to review and/or test these patches,
+ we would be grateful for your time. Please post comments to the dev mailing lists.
+ </p>
+ <p>
+ Before submitting a patch, please read the page on
+ <link href="contrib.xml">Third-Party
+ Contributions</link>. The preferred submission method for patches is:
+ </p>
+ <ul>
+ <li>Post to POI developers list</li>
+ <li>Describe the patch, the reason for it and (if necessary) why this is important.</li>
+ <li>Generate the patch in
+ <code>diff -u</code> format from CVS
+ </li>
+ <li>Also generate a documentation patch or new file, if this is something that should be documented.
+ </li>
+ <li>Post as an attachment rather than inline (unless it is trivially small).</li>
+ </ul>
+ <p>Following the above guidelines will facilitate your patch being reviewed
+ and applied efficiently.</p>
+ </section>
+ <section>
+ <title>Patch Queue</title>
+ <p>
+ <strong> [Under Construction] </strong> Archive links will be added later.
+ <strong>Please do not bother the patch submitters/authors</strong> without first reading the
+ relevant post(s) in the
+ <link href="mail-archives.xml">mailing list archives.</link>
+ </p>
+ <p>Vapourware will not be listed.</p>
+ <table>
+ <tr>
+ <th>id</th>
+ <th>Summary</th>
+ <th>Reviewer</th>
+ <th>Resolution</th>
+ <th>Status</th>
+ </tr>
+ </table>
+ <p>See also additional list of patches to be added in
+ <link href="todo.xml">To Do</link>.
+ </p>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<!DOCTYPE todo PUBLIC "-//APACHE//DTD Todo V1.1//EN" "../../dtd/todo-v11.dtd">
+
+<todo><title>Jakarta POI - Tareas Pendientes para POI</title>
+
+ <devs>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="GS" name="Glen Stampoultzis" email="poi-user@jakarta.apache.org"/>
+ <person id="MJ" name="Marc Johnson" email="mjohnson at apache dot org"/>
+ <person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ <person id="RA" name="Ryan Ackley" email="poi-dev@jakarta.apache.org"/>
+ <person id="AS" name="Avik Sengupta" email="poi-dev@jakarta.apache.org"/>
+ <person id="open" name="Desarrolladores de POI" email="poi-dev@jakarta.apache.org"/>
+ <person id="Everyone" name="Desarrolladores de POI" email="poi-dev@jakarta.apache.org"/>
+ </devs>
+
+ <actions priority="high">
+ <action context="code" dev="RA">
+ Terminar HWPF
+ </action>
+ <action context="code" dev="GS">
+ Terminar Gráficas (Charts)
+ </action>
+ <action context="code" dev="Everyone">
+ Evaluar y arreglar el código de rendimiento en HEAD.
+ </action>
+
+ </actions>
+
+ <actions priority="medium">
+ <action context="code" dev="open">
+ Implementar más tipos de registros.
+ </action>
+ <action context="code" dev="open">
+ Añadir más comprobaciones evidentes (para cuando los usuarios del API
+ hagan cosas que "no pueden" hacer). Esto conllevará la exploración de varios
+ límites superiores en las cosas que puede manejar Excel.
+ </action>
+ <action context="code" dev="open">
+ Añadir soporte para gráficos embebidos y otros objetos.
+ </action>
+ <action context="code" dev="open">
+ Crear un nuevo objeto adaptador para manejar registros
+ MulBlank, MulRk, Rk.
+ </action>
+ <action context="code" dev="AS">
+ Mejorar las fórmulas (Fórmulas Compartidas, PTGs Desconocidos).
+ </action>
+ </actions>
+
+</todo>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Jakarta POI - Quiénes somos</title>
+ <authors>
+ <person name="Jakarta POI Documentation Team" email="poi-dev@jakarta.apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+
+ <section><title>Jakarta POI - Quiénes somos</title>
+ <p>
+ El Proyecto POI opera mediante una meritocracia: cuanto más haga uno,
+ mas responsabilidad tendrá. Esta página lista toda la gente que ha recorrido
+ el último kilómetro y son Committers. Si quieres involucrarte,
+ el primer paso sería unirse a las <link href="http://jakarta.apache.org/site/mail2.html#poi">listas de correo</link>.
+ </p>
+
+ <p>
+ Pedimos que por favor no nos envíen correos electrónicos privados pidiendo soporte.
+ Somos voluntarios no-pagados que ayudan con el proyecto pero que no tenemos
+ necesariamente el tiempo o las energías para ayudar a la gente a nivel individual.
+ En su lugar, hemos montado listas de correo que a menudo contienen cientos de
+ individuos que ayudarán a contestar peticiones detalladas de ayuda. El beneficio de
+ utilizar listas de correo sobre la comunicación privada reside en que se trata de un
+ recurso compartido donde otros pueden aprender de errores frecuentes y donde podamos
+ crecer juntos como una comunidad.
+ </p>
+
+<!-- <section><title>Consejeros</title>-->
+<!-- <ul>-->
+<!-- <li><link href="http://www.betaversion.org/~stefano/">Stefano Mazzocchi</link> (stefano at apache dot org)-->
+<!-- </li>-->
+<!-- </ul>-->
+<!-- </section>-->
+
+ <section><title>Emeritus Committers</title>
+ <ul>
+ <li>Nicola Ken Barozzi (barozzi at nicolaken dot com)</li>
+ </ul>
+ </section>
+
+ <section><title>Committers</title>
+ <ul>
+ <li><link href="http://cvs.apache.org/~acoliver/">Andrew C. Oliver</link> (acoliver at apache dot org)</li>
+ <li><link href="http://www.marcj.com/">Marc Johnson</link> (mjohnson at apache dot org)</li>
+ <li><link href="http://members.iinet.net.au/~gstamp/glen/">Glen Stampoultzis</link> (glens at apache.org)</li>
+ <li><link href="http://www.rainer-klute.de/">Rainer Klute</link> (klute at apache dot org)</li>
+ <li>Ryan Ackley (sackley at apache dot org)</li>
+ <li>Avik Sengupta (avik at apache dot org)</li>
+ <li>Shawn Laubach (slaubach at apache dot org)</li>
+ <li>Danny Mui (dmui at apache dot org)</li>
+ <li>Jason Height (jheight at apache dot org)</li>
+ <li><link href="http://www.apache.org/~tetsuya/">Tetsuya Kitahata</link> (tetsuya at apache dot org)</li>
+ </ul>
+ </section>
+ <section><title>Desarrolladores</title>
+ <ul>
+ <li>Todos los Committers, por supuesto</li>
+ <li>Agustín Martín (agusmba at terra dot es)</li>
+ </ul>
+ </section>
+ <section><title>Translators</title>
+ <ul>
+ <li>Agustín Martín (agusmba at terra dot es)</li>
+ </ul>
+ </section>
+ </section>
+
+</body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>Welcome to POI -- POI Website Translation Guildeline</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="TK" name="Tetsuya Kitahata" email="tetsuya@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Purpose</title>
+ <p>This document hopes to serve as a general introduction and helpful set of
+ guidelines for translating POI documentation into other languages. We hope
+ to capture both general information here (such as "how do I test my changes")
+ as well as language specific guidelines and translation conventions.</p>
+ </section>
+ <section><title>Introduction</title>
+ <p>
+ POI's XML based documentation is built along side the sources. To build poi's documentation
+ you run "./build.sh docs" (UNIX/cygwin) or "build docs" (Windows) from the jakarta-poi
+ directory. This will put the documentation under the build/docs directory, you can navigate
+ there using your browser generally by typing in the path name or File -> Open new web location
+ (or some similar wording)
+ and browsing to the "index.html" file. You may also want to run "./build.sh clean docs" or
+ "build clean docs" so that all documentation previously built is erased before running the build.
+ The words "clean" and "docs" are called "targets", from here on out we will refer to them as
+ "targets" in which case you may assume you type "./build.sh" or "build" before them in order to
+ execute them.
+ </p>
+ <p>
+ To generate all of the documentation such as it would appear on the
+ <link href="http://poi.apache.org/">POI Website</link> you can execute the "site" target (optionally
+ preceeded by the "clean" target. See "<link href="../howtobuild.html">How to Build</link>" page for more detail (Now, POI build uses <link href="http://xml.apache.org/forrest/">Forrest</link>).
+ </p>
+ <p>
+ The source for POI's XML documentation is in src/documentation/content/xdocs. To edit one of these files you can use
+ a standard text editor. Translated documentation is under src/documentation/content/xdocs/trans/xx, where xx is a
+ two to three letter country code, in general this should match the internet domain suffix of the country where
+ that language generally evolved or just be generally recognizable and unique. The directory structure under
+ build/site/trans/xx should match the structure of build/site (the English edition) minus the
+ trans directory.
+ </p>
+ <p>
+ The translated documentation should match the content and meaning of the "master" or English documentation.
+ All documentation should originate in English (this is for simplicity). While documentation written in other
+ languages is certainly welcome, it must first be translated (perhaps by posting it to the mail list and
+ requesting it be translated) into English and applied to the master before being applied to a translation.
+ </p>
+ <p>
+ We prefer you donate translations directly to the <link href="http://poi.apache.org/">Apache POI</link>
+ project rather than hosting them offsite. We will make every effort to accomidate you as we greatly appreciate your
+ efforts. However, we understand that sites located within a country are the fastest and most searchable. Therefore,
+ we recommend and welcome folks mirroring the POI site and making the translated page the home page. You can do this
+ either via an HTML copy with some <link href="http://httpd.apache.org/info/how-to-mirror.html">appropriate software</link>
+ or the preferred method of executing the POI build directly. You can contact us via the mail list for both push and
+ pull options. The same scripts which regenerate the POI website every 2 hours, should work for others. These are not
+ yet in CVS as they are nasty dirty shell scripts ;-). If you mirror us, tell us so we can link you. (This will help google
+ associate you strongly with the project)
+ </p>
+ <p>
+ Submitting translations is simple, you follow the same
+ <link href="/guidelines.html">instructions</link> as you would for submitting a code patch.
+ Remeber to always generate patchs in diff -u format preserving the context relative to the jakarta-poi directory. Also remember
+ to submit any new files in a directory preserving archive format. Never post these to the list, always use
+ <link href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI&short_desc=%5BPATCH%5D&short_desc_type=allwordssubstr">Bugzilla</link>
+ and create attachments per the above linked instructions.
+ </p>
+ </section>
+ <section><title>Credits</title>
+ <p>
+ Some people feel uncomfortable putting themselves in the <authors> tags at the top of the documentation as they feel that
+ translation does not give them the right to claim authorship. Please don't feel this way, please add yourself to the authors
+ tags. It can be assumed that authors on the master documentation are all content creators and any additional authors listed
+ on the translation that are not on the master document are translators of the documentation. You authored the xx language
+ version of the document and should freely add yourself there. Additionally, please supply a patch to the
+ <link href="../who.html">Who We Are</link> page noting you as a developer once you've submitted a few translation patches. You deserve
+ credit and it helps the project to give you credit. Remember documentation is on par with code contribution.
+ </p>
+ </section>
+ <section><title>Starting a new translation</title>
+ <p>
+ To start a translation for a language not already in existance you must create a directory under src/documentation/content/xdocs/trans with a
+ two or three letter designation of the country where the language originated. (For example es = Spanish, de = German)
+ Copy the book.xml and index.xml file from src/documentation/content/xdocs directory into the src/documentation/content/xdocs/trans/xx directory.
+ Change all paths in the book.xml and index.xml to match the relative location of the English version. For example if there is a
+ link in index.html that references ./poifs/index.html, you'd change that to ../../poifs/index.html (up 2 directories from trans/xx).
+ Create a link from the book.xml file in the src/documentation/content/trans directory (this is necessary or the build will ignore your
+ documentation) similar to the other languages.
+ Run the clean target followed by the docs target. If the build is successful, congratulations! If it fails, you probably got one of
+ the relative paths incorrect! Go fix it (the first error message generally contains the most useful information). If you need help
+ post to the poi-dev list and ask for it (send the output from the build).
+ </p>
+ <p>
+ So now you have a directory with a copy of the index from the master documentation...so what? Well now translate book.xml and index.xml.
+ Try to build again. It probably won't work. Why? The encoding. At the top of every file there is an encoding="UTF-8" (in general).
+ This encoding will work for many Western European languages, but not for others, or will require some nasty escape sequencing. This is
+ where trial and error + guess work come in. This <link
+ href="http://www.ibiblio.org/xml/books/xmljava/chapters/ch03s03.html#encoding_table">Table of encodings</link> may help. There is a
+ catch. Your encoding should work on a Linux system under Java 1.3.1 and of course with the build in general. If in doubt, ask.
+ (This is a practical consideration as thats the setup of the machine currently running the nightly/site builds.)
+ </p>
+ </section>
+ <section><title>Need help?</title>
+ <p>
+ Andy Oliver is the cofounder of the POI project and one of its most active documentation contributers. Well, Andy used to think he
+ spoke very clearly until he traveled abroad and discovered his speech was composed almost entirely of coloquialisms. This can make some
+ of the POI documentation difficult to translate, if in doubt...ask. Its also appropriate to eliminate these from the master documentation
+ where it makes it clearer.
+ </p>
+ </section>
+ <section><title>Translation Conventions</title>
+ <p>
+ In addition to the above practical guidelines we hope to come up with a set of translation guidelines here (or linked from here) for
+ general use as well as language specific translation guidelines and conventions. We assume that the POI translators will document
+ them here as they develop.
+ </p>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>The Apache POI Documentation Translations</title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Introduction</title>
+ <p>
+ The POI project has always had a very international following. In fact even today POI is
+ more popular in Europe than in the US where the original founders reside. Today POI is
+ developed by people from all over the world including India, Austrailia, Japan, and Russia.
+ We recognize and welcome our geographically and culturally diverse users and contributors and
+ wish to accomidate you as best as we can.
+ </p>
+ <p>
+ Documentation has always been a cornerstone to POI's success. No matter how fluent one is in
+ a second language, it is always easier to comprehend concepts explained in one's native language,
+ therefore, we encourage volunteers to come and help us translate the documentation into other
+ languages. Below is a list of the translations that are currently in progress and their status.
+ </p>
+ </section>
+ <section><title>Languages</title>
+ <table>
+ <tr><td>xx</td><td>Language</td><td>Status</td><td>On/Offsite</td><td>Link</td></tr>
+ <tr><td>de</td><td>German</td><td>Just beginning (help!)</td><td>On</td>
+ <td><link href="de/index.html">link</link></td></tr>
+ <tr><td>es</td><td>Spanish</td><td>Index page, some auxiliary pages translated</td><td>On</td>
+ <td><link href="es/index.html">link</link></td></tr>
+ <tr><td>jp</td><td>Japanese</td><td>Complete XML translations and built with FORREST</td><td>Off</td>
+ <td><link href="http://jakarta.terra-intl.com/poi/">link</link></td></tr>
+ <tr><td>kr</td><td>Korean</td><td>Conducted by <link href="http://jakarta.apache-korea.org/">Jakarta-Seoul-Project</link>.</td><td>Off</td>
+ <td><link href="http://jakarta.apache-korea.org/poi/">link</link></td></tr>
+ </table>
+ </section>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ <br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </legal>
+ </footer>
+</document>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
+
+<book software="POI Project"
+ title="POI Utils"
+ copyright="@year@ POI Project">
+
+ <menu label="Apache POI">
+ <menu-item label="Top" href="../index.html"/>
+ </menu>
+
+ <menu label="POI Util">
+ <menu-item label="Overview" href="index.html"/>
+ <menu-item label="Logging" href="logging.html"/>
+ </menu>
+
+</book>
+
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI Utils</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Overview</title>
+
+ <p>The POI Utils are classes we're looking to donate elsewhere and include.
+ These are usually classes that while are required for our mission,
+ are somehow outside of it. General utilities that could be used in
+ any project are what we would normally put here. If you see one, and you
+ think "gee that would be great as part of X project" then let us know.
+ While we wish to put these in their rightful place, we also don't want to
+ include a 40mb jar file just to process text strings, so that will
+ be a consideraton.
+ </p>
+ <p>
+ Currently, we're looking into which subprojects in the Jakarta Commons project
+ to donate these too. The "POI Utils" package won't go away, as there may
+ be later classes. The idea is that "go ahead and add it, we'll merge it or
+ find an alternative later, just keep pounding out that poi!"
+ </p>
+
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
+
+<document>
+ <header>
+ <title>POI Utils</title>
+ <subtitle>Overview</subtitle>
+ <authors>
+ <person name="Nicola Ken Barozzi" email="nicolaken@apache.org"/>
+ <person name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section><title>Logging</title>
+
+ <p>
+ Logging in POI is used only as a debugging mechanism, not a normal runtime
+ logging system. Logging is ONLY for autopsie type debugging, and should
+ NEVER be enabled on a production system. Enabling logging will reduce
+ performance by at least a factor of 100. If you are not developing
+ POI or trying to debug why POI isn't reading a file correctly, then DO
+ NOT enable logging. You've been warned.
+ </p>
+
+ <p>
+ Hence, we need to be able to easily disable it entirely and make POI not dependent
+ on any logging package.
+ </p>
+
+ <warning>
+ POI is not dependent on commons-logging for running, but not for compiling.
+ </warning>
+
+ <section><title>Logging Overview</title>
+ <p>
+ Every class uses a <code>POILogger</code> to log, and gets it using a static method
+ of the <code>POILogFactory</code> .
+ </p>
+ <p>
+ The <code>POILogFactory</code> uses the <code>NullLogger</code> by default;
+ it can be instructed to use any other <code>POILogger</code> implementation
+ by setting the system property <code>org.apache.poi.util.POILogger</code>.
+ </p>
+ <note> java -Dorg.apache.poi.util.POILogger=the.package.of.MyPoiLoggerImpl ProgramThatUsesPoi
+ </note>
+ <fixme author="nicolaken"> Still needs testing.
+ </fixme>
+ </section>
+
+ <section><title>POILogFactory</title>
+ <p>
+ Each class in POI can get its <code>POILogger</code> by calling a static method
+ of the <code>POILogFactory</code> .
+ </p>
+ </section>
+
+ <section><title>POILogger</title>
+ <p>
+ Each class in POI can log using a <code>POILogger</code>, which is an abstract class.
+ We decided to make our own logging facade because:</p>
+ <ol>
+ <li>we need to log many values and we put many methods in this class to facilitate the
+ programmer, without having him write string concatenations;</li>
+ <li>we need to be able to use POI without any logger package present.</li>
+ </ol>
+ <p>There are three implementations available, and you can roll out your own, just
+ extend <code>org.apache.poi.util.POILogger</code>.
+ </p>
+ <section><title>NullLogger</title>
+ <p>Discards every logging request.</p>
+ </section>
+ <section><title>SystemOutLogger</title>
+ <p>Sends every logging request to System.out.</p>
+ </section>
+ <section><title>CommonsLogger</title>
+ <p>Sends every logging request to the Commons Logging package. This can use JDK1.4 logging,
+ log4j, logkit, and is an actively maintained Jakarta Project.</p>
+ </section>
+
+ </section>
+ </section>
+ </body>
+</document>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "./dtd/document-v13.dtd">
+
+<document>
+ <header>
+ <title>Apache POI - Who We Are</title>
+ <authors>
+ <person name="Apache POI Developers" email="dev@poi.apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+
+ <section><title>Apache POI - Who we are</title>
+ <p>
+ The Apache POI Project operates on a meritocracy: the more you do, the more
+ responsibility you will obtain. This page lists all of the people who have
+ gone the extra mile and are Committers. If you would like to get involved,
+ the first step is to join the <link href="mailinglists.html">mailing lists</link>.
+ </p>
+
+ <p>
+ We ask that you please do not send us emails privately asking for support.
+ We are non-paid volunteers who help out with the project and we do not
+ necessarily have the time or energy to help people on an individual basis.
+ The <link href="mailinglists.html">mailing lists</link> have many individuals
+ who will help answer detailed requests for help. The benefit of
+ using mailing lists over private communication is that they are a shared
+ resource where others can also learn from common questions.
+ </p>
+ <p>
+ POI Developers count on feedback from the mailing lists. Many developers do take
+ an active role on the lists.
+ </p>
+
+<!-- <section><title>Advisors</title>-->
+<!-- <ul>-->
+<!-- <li><link href="http://www.betaversion.org/~stefano/">Stefano Mazzocchi</link> (stefano at apache dot org)-->
+<!-- </li>-->
+<!-- </ul>-->
+<!-- </section>-->
+
+ <section><title>Project Chair</title>
+ <ul>
+ <li>Yegor Kozlov (yegor at apache dot org)</li>
+ </ul>
+ </section>
+ <section><title>Committers</title>
+ <ul>
+ <!-- Alphabetical by surname -->
+ <li>Nick Burch (nick at apache dot org)</li>
+ <li>Amol S Deshmukh (amol at apache dot org)</li>
+ <li>David Fisher (wave at apache dot org)</li>
+ <li>Jason Height (jheight at apache dot org)</li>
+ <li>Marc Johnson (mjohnson at apache dot org)</li>
+ <li><link href="http://www.rainer-klute.de/">Rainer Klute</link> (klute at apache dot org)</li>
+ <li>Yegor Kozlov (yegor at apache dot org)</li>
+ <li>Shawn Laubach (slaubach at apache dot org)</li>
+ <li>Josh Micich (josh at apache dot org)</li>
+ <li>Danny Mui (dmui at apache dot org)</li>
+ <li>Avik Sengupta (avik at apache dot org)</li>
+ <li>Dominik Stadler (centic at apache dot org)</li>
+ <li><link href="http://members.iinet.net.au/~gstamp/glen/">Glen Stampoultzis</link> (glens at apache.org)</li>
+ <li>Jon Svede (jsvede at apache dot org)</li>
+ <li>Maxim Valyanskiy (maxcom at apache dot org)</li>
+ <li>Sergey Vladimirov (sergey at apache dot org)</li>
+ </ul>
+ </section>
+ <section><title>Translators</title>
+ <ul>
+ <li>(Please add your name here!!)</li>
+ </ul>
+ </section>
+ <section><title>Emeritus Committers</title>
+ <ul>
+ <li>Andrew C. Oliver (acoliver at gmail dot com)</li>
+ <li>Nicola Ken Barozzi (barozzi at nicolaken dot com)</li>
+ <li>Ryan Ackley (sackley at apache dot org)</li>
+ <li>Tetsuya Kitahata (ai at spa dot nifty dot com)</li>
+ </ul>
+ </section>
+ </section>
+
+</body>
+</document>
--- /dev/null
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+ ==============================
+ POI Release Guide
+ ==============================
+
+
+(I) Prerequisites
+
+ 1. You should read the <a href="http://apache.org/dev/release.html">Apache Release FAQ</a>
+ 2a. You must have shell access to people.apache.org; and you should
+ have key-based authentication set up
+ (e.g. <a href="http://www.linuxproblem.org/art_9.html">how to</a>.
+ 2b. You must be a member of the committee group
+ 3. Release manager must have his public key appended to the KEYS file checked in to SVN and the key published on one of the public key servers.
+ More info can be found here: <a href="http://www.apache.org/dev/release-signing.html">http://www.apache.org/dev/release-signing.html</a>
+ 4. You must have <a href="java.sun.com">JDK 1.5</a>
+ 5. You must have the following utilities installed on your local machine and available in your path:
+ * <a href="www.openssh.com">ssh</a>
+ * <a href="www.gnupg.org">gnupg</a>
+ * <a href="www.openssl.org">openssl</a>
+ For Windows users, install Cygwin and make sure you have the above utilities
+ 6a. The POI build system requires two components to perform a build
+ * <a href="ant.apache.org">Ant</a>
+ * <a href="http://forrest.apache.org/">Forrest</a>.
+ POI 3.0.2 and 3.1 were built using Ant 1.6.2 and Forrest 0.5
+ Currently, Forrest needs to be 0.5.1, Ant 1.7+ should be fine
+
+ 6b. To deploy with Maven, you should have the latest stable Maven 2.x.
+ POI 3.10-beta2 was deployed with Maven 2.2.1.
+
+ 7. Before building, you should run the "rat-check" build task, which
+ uses <a href="http://incubator.apache.org/rat/">Apache Rat</a>
+ to check the source tree for files lacking license headers. Files
+ without headers should be either fixed, or added to the exlude list
+
+ 8. Check file permissions are correct in SVN.
+ There can be files in the SVN tree marked executable (have the
+ svn:executable property set), but which should not be. Checking them
+ out will cause the executable bit to be set for them on filesystems
+ which support it. The flag can be removed in batch using
+
+$ svn pd 'svn:executable' $(find -name .svn -prune -or -type f ! -name \*.sh \
+ -print0 | xargs -0 svn pg 'svn:executable' | cut -d ' ' -f 1)
+
+
+(II) Making release artefacts
+ 1. Update version id in build.xml
+{code:xml}
+ <property name="version.id" value="3.1-beta1"/>
+{code}
+
+ 2. Update the date in src/documentation/content/xdocs/status.xml with
+ the expected release date, and create a commented out entry for the
+ next release. (Must be commented out, as there are no actions
+ for it yet)
+
+ 3. Pin the documentation explicitly to the current version, rather
+ than trunk. Run "svn up" to get the current version number, then
+ edit the svn:externals property on src and add to the definition, eg
+
+ documentation -r1496657 https://svn.apache.org/repos/asf/poi/site/src/documentation
+
+ 4. Tag current version. Include the current revision number in the comment
+
+{code}
+$ TAG=REL_3_8_FINAL
+$ TAG=REL_3_12_ALPHA5
+$ svn cp https://svn.apache.org/repos/asf/poi/trunk \
+https://svn.apache.org/repos/asf/poi/tags/$TAG \
+-m "tag r649911 as 3.1-beta1"
+{code}
+
+where $TAG is the release tag, for example, REL_3_1_BETA1
+
+ 5. On trunk, update "version.id" to be the next version in status.xml,
+ and remove the version pinning on the documentation external definition.
+
+ 6. Checkout the tagged version
+{code}
+cd tags
+svn checkout https://svn.apache.org/repos/asf/poi/tags/$TAG
+{code}
+
+ 7. Merge (if required)
+
+{code}
+cd $TAG
+$ svn merge https://svn.apache.org/repos/asf/poi/tags/$TAG \
+https://svn.apache.org/repos/asf/poi/trunk
+{code}
+
+ Note that if there's set to be lots of merging, you may be best
+ to create a branch for the release, then create tags from there
+ rather than trunk
+
+ 8. Build as if the vote had passed. The build date must be +7 days from current.
+{code}
+# eg ant -DDSTAMP=20100924 dist
+ant -DDSTAMP=YYYYMMDD dist
+{code}
+
+where $TAG is the release tag specified in build.xml in the version.id property, $DATE is the release date (typically +7 days from the actual build date).
+
+ 9. Signing the release artifacts:
+{code}
+cd build/dist
+./multisign.sh
+{code}
+
+ 10. Upload to the dev svn dist repo,
+ https://dist.apache.org/repos/dist/dev/poi/ eg
+ https://dist.apache.org/repos/dist/dev/poi/3.8-RC3/
+
+How to upload:
+
+{code}
+svn co https://dist.apache.org/repos/dist/dev/poi
+mkdir 3.8-RC3/
+svn add 3.8-RC3
+{code}
+
+may need --force as in:
+{code}
+svn add 3.8-RC3 --force
+{code}
+
+then add .gz and .zip packages along with checksums.
+
+ binaries should be in ./bin, sources in ./src sub-directories
+
+8c. commit
+After commit the files should be accessible at https://dist.apache.org/repos/dist/dev/poi/3.8-RC2/
+
+
+ (III) After the vote:
+
+In the release area of the dist repo:
+ https://dist.apache.org/repos/dist/release/poi/release/ (FINAL)
+ https://dist.apache.org/repos/dist/release/poi/dev/ (Alpha/Beta)
+Remove the previous release
+
+Next, svn move the files from the /dist/dev/ area to the appropriate
+/dist/release/ area
+
+example:
+$ svn rm -m "remove the previous release" \
+ https://dist.apache.org/repos/dist/release/poi/dev/src
+ https://dist.apache.org/repos/dist/release/poi/dev/bin
+
+$ svn mv -m "move staging files to the release area" \
+ https://dist.apache.org/repos/dist/dev/poi/bin \
+ https://dist.apache.org/repos/dist/dev/poi/src/ \
+ https://dist.apache.org/repos/dist/release/poi/dev/
+
+
+deploy Maven artifacts
+{code}
+cd build/dist
+./mvn-deploy.sh
+{code}
+
+2. Wait for the distributions to appear on your favourite mirror
+
+3. Edit the website homepage and list the new release there. If a full release,
+ remove older full releases and all beta releases. If a beta release, keep
+ the last full release, and replace any other beta releases
+
+4. Edit the website download page, and list the new release there. This should
+ reference the checksums, so take care when updating
+
+5. Build site using a recent version of Java 1.6 or 1.7 (must be after the fix
+ for TA13-169A).
+ Commit the site changes to svn, and publish live
+
+6. test maven
+create a simple project and make sure the release artifacts are accessible by maven:
+
+{code}
+$ mvn archetype:create -DgroupId=org.apache.poi.scratchpad -DartifactId=maven-test
+cd maven-test
+{code}
+edit pom.xml and add the release artefacts to the project dependencies:
+
+{code:xml}
+ <dependency>
+ <groupId>org.apache.poi</groupId>
+ <artifactId>poi</artifactId>
+ <version>3.1-beta1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.poi</groupId>
+ <artifactId>poi-scratchpad</artifactId>
+ <version>3.1-beta1</version>
+ </dependency>
+{code}
+
+{code}
+mvn compile
+{code}
+
+You should see [INFO] BUILD SUCCESSFUL in the end.
+
+Before the package is fully replicated, you may get a BUILD SUCCESSFUL, but you'll also receive a
+warning that the .jar can't be downloaded. Wait until you get BUILD SUCCESSFUL and no warnings.
+
+7. Don't forget to upload the latest version of the site and javadocs
+
+8. Send announcements:
+ - to poi-user and poi-dev lists
+ - to announcements@apache.org, announcements@jakarta.apache.org
+
+Note, announcements should be sent from your @apache.org e-mail address.
+
+9. Add a new project version in Bugzilla
+
+10. Delete directory that held RC.
+
+e.g.
+{code}
+svn delete -m "delete empty RC directory for 3.10-beta2" https://dist.apache.org/repos/dist/dev/poi/3.10-beta2-RC1
+{code}
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<!--
+Skin configuration file. This file contains details of your project, which will
+be used to configure the chosen Forrest skin.
+-->
+
+<!DOCTYPE skinconfig [
+
+ <!ENTITY % links.att 'name CDATA #REQUIRED'>
+ <!ENTITY % link.att 'name CDATA #REQUIRED href CDATA #REQUIRED'>
+ <!ELEMENT skinconfig (disable-lucene?, disable-search?, disable-print-link?, disable-pdf-link?,
+ disable-xml-link?, disable-compliance-links?, obfuscate-mail-links?, searchsite-domain?, searchsite-name?,
+ project-name, project-description?, project-url, project-logo, group-name?, group-description?, group-url?, group-logo?,
+ host-url?, host-logo?, year?, vendor?, trail?, toc?, credits?)*>
+ <!ELEMENT credits (credit*)>
+ <!ELEMENT credit (name, url, image?, width?, height?)>
+ <!-- id uniquely identifies the tool, and role indicates its function -->
+ <!ATTLIST credit id CDATA #IMPLIED
+ role CDATA #IMPLIED>
+ <!ELEMENT disable-lucene (#PCDATA)>
+ <!ELEMENT disable-search (#PCDATA)>
+ <!ELEMENT disable-print-link (#PCDATA)>
+ <!ELEMENT disable-pdf-link (#PCDATA)>
+ <!ELEMENT disable-xml-link (#PCDATA)>
+ <!ELEMENT disable-compliance-links (#PCDATA)>
+ <!ELEMENT obfuscate-mail-links (#PCDATA)>
+ <!ELEMENT searchsite-domain (#PCDATA)>
+ <!ELEMENT searchsite-name (#PCDATA)>
+ <!ELEMENT project-name (#PCDATA)>
+ <!ELEMENT project-description (#PCDATA)>
+ <!ELEMENT project-url (#PCDATA)>
+ <!ELEMENT project-logo (#PCDATA)>
+ <!ELEMENT group-name (#PCDATA)>
+ <!ELEMENT group-description (#PCDATA)>
+ <!ELEMENT group-url (#PCDATA)>
+ <!ELEMENT group-logo (#PCDATA)>
+ <!ELEMENT host-url (#PCDATA)>
+ <!ELEMENT host-logo (#PCDATA)>
+ <!ELEMENT year (#PCDATA)>
+ <!ELEMENT vendor (#PCDATA)>
+ <!ELEMENT trail (link1, link2)>
+ <!ELEMENT link1 EMPTY>
+ <!-- Seems we can't use param entity refs until this is DTDified -->
+ <!ATTLIST link1 name CDATA #REQUIRED href CDATA #IMPLIED>
+ <!ELEMENT link2 EMPTY>
+ <!ATTLIST link2 name CDATA #REQUIRED href CDATA #IMPLIED>
+ <!ELEMENT link3 EMPTY>
+ <!ATTLIST link3 name CDATA #REQUIRED href CDATA #IMPLIED>
+ <!ELEMENT name (#PCDATA)>
+ <!ELEMENT url (#PCDATA)>
+ <!ELEMENT image (#PCDATA)>
+ <!ELEMENT width (#PCDATA)>
+ <!ELEMENT height (#PCDATA)>
+ <!ELEMENT toc EMPTY>
+ <!ATTLIST toc level CDATA #IMPLIED>
+ ]>
+
+<skinconfig>
+ <!-- Do we want to disable the Lucene search box? -->
+ <disable-lucene>true</disable-lucene>
+ <!-- Do we want to disable the Google search box? -->
+ <disable-search>false</disable-search>
+ <!-- Do we want to disable the print link? If enabled, invalid HTML 4.0.1 -->
+ <disable-print-link>false</disable-print-link>
+ <!-- Do we want to disable the PDF link? -->
+ <disable-pdf-link>true</disable-pdf-link>
+ <!-- Do we want to disable the xml source link? yes, it avoids disclosing author emails -->
+ <disable-xml-link>true</disable-xml-link>
+ <!-- Do we want to disable w3c compliance links? -->
+ <disable-compliance-links>false</disable-compliance-links>
+ <!-- Whether to render mailto: links unrecognisable by spam harvesters
+ if we turn this on then mailinglists.html is broken.-->
+ <obfuscate-mail-links>false</obfuscate-mail-links>
+
+ <searchsite-domain>poi.apache.org</searchsite-domain>
+ <searchsite-name>Apache POI</searchsite-name>
+
+ <!-- mandatory project logo
+ skin: forrest-site renders it at the top -->
+ <project-name>POI</project-name>
+ <project-description>POI</project-description>
+ <project-url>http://poi.apache.org/</project-url>
+ <project-logo>resources/images/project-logo.jpg</project-logo>
+
+ <!-- optional group logo
+ skin: forrest-site renders it at the top-left corner -->
+ <group-name>Apache POI</group-name>
+ <group-description>Apache POI</group-description>
+ <group-url>http://poi.apache.org</group-url>
+ <group-logo>resources/images/group-logo.jpg</group-logo>
+
+ <!-- optional host logo (e.g. sourceforge logo)
+ skin: forrest-site renders it at the bottom-left corner -->
+ <host-url></host-url>
+ <host-logo></host-logo>
+
+ <!-- The following are used to construct a copyright statement -->
+ <year>2002-2012</year>
+ <vendor>The Apache Software Foundation</vendor>
+
+ <!-- Some skins use this to form a 'breadcrumb trail' of links. If you don't
+ want these, set the attributes to blank. The DTD purposefully requires them.
+ -->
+ <trail>
+ <link1 name="Apache" href="http://www.apache.org/"/>
+ <link2 name="POI" href="http://poi.apache.org/"/>
+ </trail>
+
+ <!-- Credits are typically rendered as a set of small clickable images in the
+ page footer -->
+ <credits>
+ <credit>
+ <name>Built with Apache Forrest</name>
+ <url>http://forrest.apache.org/</url>
+ <image>skin/images/built-with-forrest-button.png</image>
+ <width>88</width>
+ <height>31</height>
+ </credit>
+ <!-- A credit with @role='pdf' will have its name and url displayed in the
+ PDF page's footer. -->
+ </credits>
+
+</skinconfig>
--- /dev/null
+This directory is currently useless, as the sitemap only looks in
+skins/{forrest:skin}, so files must be kept in synch manually until this is
+fixed.
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ version="1.0">
+
+ <xsl:output method="xml"/>
+ <xsl:param name="numbersections" select="'true'"/>
+
+ <!-- Section depth at which we stop numbering and just indent -->
+ <xsl:param name="numbering-max-depth" select="'3'"/>
+ <xsl:param name="ctxbasedir" select="."/>
+ <xsl:param name="xmlbasedir"/>
+ <xsl:include href="pdfoutline.xsl"/>
+ <xsl:include href="footerinfo.xsl"/>
+
+ <xsl:template match="/">
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+
+ <fo:simple-page-master master-name="first-page"
+ page-height="11in"
+ page-width="8.5in"
+ margin-top="1in"
+ margin-bottom="1in"
+ margin-left="1.25in"
+ margin-right="1in">
+ <fo:region-body
+ margin-top="0.5in"
+ margin-bottom=".5in"/>
+ <fo:region-after
+ region-name="first-footer"
+ extent=".5in"
+ display-align="before"/>
+ </fo:simple-page-master>
+
+ <fo:simple-page-master master-name="even-page"
+ page-height="11in"
+ page-width="8.5in"
+ margin-top="1in"
+ margin-bottom="1in"
+ margin-left="1.25in"
+ margin-right="1in">
+ <fo:region-before
+ region-name="even-header"
+ extent="0.5in"
+ border-bottom="0.5pt solid"/>
+ <fo:region-body
+ margin-top="0.5in"
+ margin-bottom=".5in"/>
+ <fo:region-after
+ region-name="even-footer"
+ extent=".5in"
+ display-align="before"/>
+ </fo:simple-page-master>
+
+ <fo:simple-page-master master-name="odd-page"
+ page-height="11in"
+ page-width="8.5in"
+ margin-top="1in"
+ margin-bottom="1in"
+ margin-left="1.25in"
+ margin-right="1in">
+ <fo:region-before
+ region-name="odd-header"
+ extent="0.5in"
+ border-bottom="0.5pt solid"/>
+ <fo:region-body
+ margin-top="0.5in"
+ margin-bottom=".5in"/>
+ <fo:region-after
+ region-name="odd-footer"
+ extent=".5in"
+ display-align="before"/>
+ </fo:simple-page-master>
+
+ <fo:page-sequence-master master-name="book">
+ <fo:repeatable-page-master-alternatives>
+ <fo:conditional-page-master-reference
+ page-position="first"
+ master-reference="first-page"/>
+ <fo:conditional-page-master-reference
+ odd-or-even="odd"
+ master-reference="odd-page"/>
+ <fo:conditional-page-master-reference
+ odd-or-even="even"
+ master-reference="even-page"/>
+ </fo:repeatable-page-master-alternatives>
+ </fo:page-sequence-master>
+ </fo:layout-master-set>
+
+ <xsl:apply-templates select="/document" mode="outline"/>
+
+ <fo:page-sequence master-reference="book">
+ <fo:title><xsl:value-of select="document/header/title"/></fo:title>
+ <xsl:apply-templates/>
+ </fo:page-sequence>
+
+ </fo:root>
+ </xsl:template>
+
+ <xsl:template match="document">
+ <fo:title><xsl:value-of select="header/title"/></fo:title>
+
+ <fo:static-content flow-name="first-footer">
+ <fo:block
+ border-top="0.25pt solid"
+ padding-before="6pt"
+ text-align="center">
+ <xsl:apply-templates select="footer"/>
+ </fo:block>
+ <fo:block
+ text-align="start">
+ Page <fo:page-number/>
+ </fo:block>
+ <xsl:call-template name="info"/>
+ </fo:static-content>
+
+ <fo:static-content flow-name="even-header">
+ <fo:block
+ text-align="end"
+ font-style="italic">
+ <xsl:value-of select="header/title"/>
+ </fo:block>
+ </fo:static-content>
+
+ <fo:static-content flow-name="even-footer">
+ <fo:block
+ border-top="0.25pt solid"
+ padding-before="6pt"
+ text-align="center">
+ <xsl:apply-templates select="footer"/>
+ </fo:block>
+ <fo:block
+ text-align="end">
+ Page <fo:page-number/>
+ </fo:block>
+ <xsl:call-template name="info"/>
+ </fo:static-content>
+
+ <fo:static-content flow-name="odd-header">
+ <fo:block
+ text-align="start"
+ font-style="italic">
+ <xsl:value-of select="header/title"/>
+ </fo:block>
+ </fo:static-content>
+
+ <fo:static-content flow-name="odd-footer">
+ <fo:block
+ border-top="0.25pt solid"
+ padding-before="6pt"
+ text-align="center">
+ <xsl:apply-templates select="footer"/>
+ </fo:block>
+ <fo:block
+ text-align="start">
+ Page <fo:page-number/>
+ </fo:block>
+ <xsl:call-template name="info"/>
+ </fo:static-content>
+
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block
+ padding-before="24pt"
+ padding-after="24pt"
+ font-size="24pt"
+ font-weight="bold"
+ id="{generate-id()}">
+
+ <xsl:value-of select="header/title"/>
+ </fo:block>
+
+ <fo:block
+ text-align="justify"
+ padding-before="18pt"
+ padding-after="18pt">
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:flow>
+ </xsl:template>
+
+ <xsl:template match="abstract">
+ <fo:block
+ font-size="12pt"
+ text-align="center"
+ space-before="20pt"
+ space-after="25pt"
+ width="7.5in"
+ font-family="serif"
+ font-style="italic">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="notice">
+ <fo:block
+ font-size="10pt"
+ text-align="left"
+ space-before="20pt"
+ width="7.5in"
+ font-family="serif"
+ border-top="0.25pt solid"
+ border-bottom="0.25pt solid"
+ padding-before="6pt"
+ padding-after="6pt">
+ NOTICE: <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="anchor">
+ <fo:block id="{@id}"/>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="section">
+
+ <xsl:param name="level">0</xsl:param>
+
+ <xsl:variable name="size">
+ <xsl:choose>
+ <xsl:when test="number($level) = 1">
+ <xsl:value-of select="14"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="12"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <fo:block
+ font-family="serif"
+ font-size="{$size}pt"
+ font-weight="bold"
+ space-before="12pt"
+ space-after="4pt">
+
+ <xsl:attribute name="id">
+ <xsl:choose>
+ <xsl:when test="normalize-space(@id)!=''">
+ <xsl:value-of select="@id"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="generate-id()"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+
+ <xsl:if test="$numbersections = 'true' and number($level) < $numbering-max-depth+1">
+ <xsl:number format="1.1.1.1.1.1.1" count="section" level="multiple"/>
+ <xsl:text>. </xsl:text>
+ </xsl:if>
+
+ <!-- For sections 4 or more nestings deep, indent instead of number -->
+ <xsl:if test="number($level) > $numbering-max-depth+1">
+ <xsl:attribute name="start-indent">
+ <xsl:value-of select="4+number($level)"/><xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+
+ <xsl:value-of select="title"/>
+ </fo:block>
+ <xsl:apply-templates>
+ <xsl:with-param name="level" select="number($level)+1"/>
+ </xsl:apply-templates>
+
+ </xsl:template>
+
+ <xsl:template match="title">
+ <!-- do nothing as titles are handled in their parent templates -->
+ </xsl:template>
+
+ <xsl:template match="subtitle">
+ <xsl:param name="level">0</xsl:param>
+ <xsl:variable name="size" select="16-(number($level)*1.5)"/>
+
+ <fo:block
+ font-weight="bold"
+ font-size="{$size}pt">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="authors">
+ <fo:block
+ space-before="20pt"
+ font-weight="bold"
+ font-size="9pt">
+ by
+ <xsl:for-each select="person">
+ <xsl:value-of select="@name"/>
+ <xsl:if test="not(position() = last())">, </xsl:if>
+ </xsl:for-each>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="p">
+ <fo:block
+ space-before="4pt"
+ space-after="4pt"
+ font-family="serif">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+
+ <xsl:template match="source">
+ <fo:block
+ font-family="monospace"
+ font-size="10pt"
+ background-color="#f0f0f0"
+ white-space-collapse="false"
+ linefeed-treatment="preserve"
+ white-space-treatment="preserve"
+ wrap-option="no-wrap"
+ text-align="start">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+
+ <xsl:template match="ol|ul">
+ <fo:list-block
+ provisional-distance-between-starts="18pt"
+ provisional-label-separation="3pt"
+ text-align="start">
+ <xsl:apply-templates/>
+ </fo:list-block>
+ </xsl:template>
+
+ <xsl:template match="ol/li">
+ <fo:list-item>
+ <fo:list-item-label
+ end-indent="label-end()">
+ <fo:block>
+ <xsl:number format="1."/>
+ </fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body
+ start-indent="body-start()">
+ <fo:block
+ font-family="serif">
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </xsl:template>
+
+ <!-- Emulate browser handling of these invalid combinations that our DTD
+ unfortunately allows -->
+ <xsl:template match="ul/ul | ul/ol | ol/ul | ol/ol">
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block></fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block font-family="serif">
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </xsl:template>
+
+ <xsl:template match="ul/li">
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block
+ font-family="serif">
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </xsl:template>
+
+ <xsl:template match="dl">
+ <fo:list-block
+ provisional-distance-between-starts="18pt"
+ provisional-label-separation="3pt"
+ text-align="start">
+ <xsl:apply-templates/>
+ </fo:list-block>
+ </xsl:template>
+
+ <xsl:template match="dt">
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block></fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block
+ font-weight="bold">
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </xsl:template>
+
+ <xsl:template match="dd">
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block></fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </xsl:template>
+
+ <xsl:template match="strong">
+ <fo:inline font-weight="bold"><xsl:apply-templates/></fo:inline>
+ </xsl:template>
+
+ <xsl:template match="em">
+ <fo:inline font-style="italic"><xsl:apply-templates/></fo:inline>
+ </xsl:template>
+
+ <xsl:template match="code">
+ <fo:inline font-family="monospace"><xsl:apply-templates/></fo:inline>
+ </xsl:template>
+
+ <xsl:template match="warning">
+ <fo:block
+ margin-left="0.25in"
+ margin-right="0.25in"
+ font-weight="bold"
+ font-size="10pt"
+ font-family="serif"
+ space-before="10pt"
+ border-before-style="solid"
+ border-start-style="solid"
+ border-end-style="solid"
+ border-color="#D00000"
+ background-color="#D00000"
+ color="#ffffff">
+ <xsl:choose>
+ <xsl:when test="@label"><xsl:value-of select="@label"/></xsl:when>
+ <xsl:otherwise>Note: </xsl:otherwise>
+ </xsl:choose><xsl:value-of select="title"/>
+ </fo:block>
+ <fo:block
+ margin-left="0.25in"
+ margin-right="0.25in"
+ font-family="serif"
+ font-size="8pt"
+ border-after-style="solid"
+ border-start-style="solid"
+ border-end-style="solid"
+ border-color="#D00000"
+ background-color="#fff0f0"
+ padding-start="3pt"
+ padding-end="3pt"
+ padding-before="3pt"
+ padding-after="3pt"
+ space-after="10pt">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="note">
+ <fo:block
+ margin-left="0.25in"
+ margin-right="0.25in"
+ font-weight="bold"
+ font-size="10pt"
+ color="#ffffff"
+ font-family="serif"
+ space-before="10pt"
+ border-before-style="solid"
+ border-start-style="solid"
+ border-end-style="solid"
+ border-color="#A0C9F5"
+ background-color="#A0C9F5">
+ <xsl:choose>
+ <xsl:when test="@label"><xsl:value-of select="@label"/></xsl:when>
+ <xsl:otherwise>Note: </xsl:otherwise>
+ </xsl:choose><xsl:value-of select="title"/>
+ </fo:block>
+ <fo:block
+ margin-left="0.25in"
+ margin-right="0.25in"
+ font-family="serif"
+ font-size="8pt"
+ space-after="10pt"
+ border-after-style="solid"
+ border-start-style="solid"
+ border-end-style="solid"
+ border-color="#A0C9F5"
+ background-color="#F0F0FF"
+ padding-start="3pt"
+ padding-end="3pt"
+ padding-before="3pt"
+ padding-after="3pt">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="fixme">
+ <fo:block
+ margin-left="0.25in"
+ margin-right="0.25in"
+ font-weight="bold"
+ font-size="10pt"
+ color="#FFFFFF"
+ font-family="serif"
+ space-before="10pt"
+ border-before-style="solid"
+ border-start-style="solid"
+ border-end-style="solid"
+ border-color="#C6C650"
+ background-color="#C6C650">
+ FIXME (<xsl:value-of select="@author"/>): <xsl:value-of select="title"/>
+ </fo:block>
+ <fo:block
+ margin-left="0.25in"
+ margin-right="0.25in"
+ font-family="serif"
+ font-size="8pt"
+ space-after="10pt"
+ border-after-style="solid"
+ border-start-style="solid"
+ border-end-style="solid"
+ border-color="#C6C650"
+ background-color="#FFF0F0"
+ padding-start="3pt"
+ padding-end="3pt"
+ padding-before="3pt"
+ padding-after="3pt">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="link">
+ <xsl:choose>
+ <xsl:when test="starts-with(@href, '#')">
+ <fo:basic-link color="blue" text-decoration="underline" internal-destination="{substring(@href,2)}">
+ <xsl:apply-templates/>
+ </fo:basic-link>
+ </xsl:when>
+ <xsl:otherwise>
+ <fo:basic-link color="blue" text-decoration="underline" external-destination="{@href}"><xsl:apply-templates/></fo:basic-link>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="figure|img">
+ <fo:block text-align="center">
+ <xsl:if test="normalize-space(@id)!=''">
+ <xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
+ </xsl:if>
+
+ <!-- Make relative paths absolute -->
+ <xsl:variable name="imgpath">
+ <xsl:choose>
+ <xsl:when test="starts-with(string(@src), 'images/') or contains(string(@src), '../images')">
+ <xsl:value-of select="concat($ctxbasedir, 'resources/images/' , substring-after(@src, 'images'))"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="concat($ctxbasedir, $xmlbasedir, @src)"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <fo:external-graphic src="{$imgpath}">
+ <xsl:if test="@height">
+ <xsl:attribute name="height"><xsl:value-of select="@height"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="@width">
+ <xsl:attribute name="width"><xsl:value-of select="@width"/></xsl:attribute>
+ </xsl:if>
+ </fo:external-graphic>
+ <!-- alt text -->
+ <xsl:if test="normalize-space(@alt)!=''">
+ <fo:block><xsl:value-of select="@alt"/></fo:block>
+ </xsl:if>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="table">
+ <!-- FIXME: Apache FOP must have column widths specified at present,
+ this section can be removed when this limitation is removed from Fop.
+ Unfortunately, this means that each column is a fixed width,
+ but at least the table displays! -->
+
+ <xsl:variable name="max-number-columns">
+ <xsl:for-each select="tr">
+ <xsl:sort select="count(td|th)" data-type="number" order="descending"/>
+ <xsl:if test="position() = 1">
+ <xsl:value-of select="count(td|th)"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+
+ <xsl:variable name="column-width">
+ <xsl:value-of select="6.25 div number($max-number-columns)"/>in
+ </xsl:variable>
+
+ <fo:table>
+
+ <fo:table-column>
+ <xsl:attribute name="column-width">
+ <xsl:value-of select="$column-width"/>
+ </xsl:attribute>
+
+ <xsl:attribute name="number-columns-repeated">
+ <xsl:value-of select="number($max-number-columns)"/>
+ </xsl:attribute>
+ </fo:table-column>
+
+ <!-- End of hack for Fop support (if removing this hack, remember
+ you need the <fo:table> element) -->
+
+ <fo:table-body
+ font-size="10pt"
+ font-family="sans-serif">
+ <xsl:apply-templates select="tr"/>
+ </fo:table-body>
+ </fo:table>
+
+ <!-- FIXME: Apache Fop does not support the caption element yet.
+ This hack will display the table caption accordingly. -->
+ <xsl:if test="caption">
+ <fo:block
+ text-align="center"
+ font-weight="bold">
+ Table
+ <xsl:text> </xsl:text>
+ <xsl:number count="table" level="multiple"/>
+ <xsl:text>: </xsl:text>
+ <xsl:value-of select="caption"/>
+ </fo:block>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="tr">
+ <fo:table-row>
+ <xsl:apply-templates/>
+ </fo:table-row>
+ </xsl:template>
+
+ <xsl:template match="th">
+ <fo:table-cell
+ padding-before="4pt"
+ padding-after="4pt"
+ padding-start="4pt"
+ padding-end="4pt"
+ background-color="#A0C9F5">
+ <xsl:attribute name="number-columns-spanned">
+ <xsl:value-of select="@colspan"/>
+ </xsl:attribute>
+ <xsl:attribute name="number-rows-spanned">
+ <xsl:value-of select="@rowspan"/>
+ </xsl:attribute>
+ <fo:block
+ text-align="center">
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:table-cell>
+ </xsl:template>
+
+ <xsl:template match="td">
+ <fo:table-cell
+ padding-before="4pt"
+ padding-after="4pt"
+ padding-start="4pt"
+ padding-end="4pt"
+ border="1pt solid #A0C9F5">
+ <xsl:attribute name="number-columns-spanned">
+ <xsl:value-of select="@colspan"/>
+ </xsl:attribute>
+ <xsl:attribute name="number-rows-spanned">
+ <xsl:value-of select="@rowspan"/>
+ </xsl:attribute>
+ <fo:block>
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:table-cell>
+ </xsl:template>
+
+ <xsl:template match="br">
+ <fo:block></fo:block>
+ </xsl:template>
+
+ <xsl:template match="legal">
+ <fo:inline
+ font-size="8pt">
+ <xsl:apply-templates/>
+ </fo:inline>
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- Local Extensions section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="citation">
+ <fo:inline>
+ [<xsl:value-of select="@def"/>]
+ </fo:inline>
+ </xsl:template>
+
+
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ version="1.0">
+
+<!--
+Named template to generate a short message in the PDF footer, from text in
+skinconf.xml. By default, the message is a copyright statement. If a credit
+with @role='pdf' is present, that is used instead. Eg:
+
+<credit role="pdf">
+ <name>Generated by Apache FOP 1.0-dev</name>
+ <url>http://xml.apache.org/forrest/fop/dev/</url>
+</credit>
+-->
+
+ <xsl:param name="config-file" select="'../../../../skinconf.xml'"/>
+ <xsl:variable name="config" select="document($config-file)/skinconfig"/>
+
+ <xsl:template name="info">
+ <xsl:variable name="pdfcredit" select="$config/credits/credit[@role = 'pdf']"/>
+ <xsl:variable name="text">
+ <xsl:if test="$pdfcredit">
+ <xsl:value-of select="$pdfcredit/name"/>
+ </xsl:if>
+ <xsl:if test="not($pdfcredit)">
+ <xsl:text>Copyright © </xsl:text><xsl:value-of select="$config/year"/> <xsl:value-of
+ select="$config/vendor"/><xsl:text> All rights reserved.</xsl:text>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:variable name="url" select="$pdfcredit/url"/>
+
+ <fo:block-container font-style="italic" absolute-position="absolute"
+ left="0pt" top="0pt" right="6.25in" bottom="150pt"
+ font-size="10pt">
+ <xsl:if test="not($url)">
+ <fo:block text-align="center" color="lightgrey">
+ <xsl:value-of select="$text"/>
+ </fo:block>
+ </xsl:if>
+ <xsl:if test="$url">
+ <fo:block text-align="center">
+ <fo:basic-link color="lightgrey"
+ external-destination="{$url}">
+ <xsl:value-of select="$text"/>
+ </fo:basic-link>
+ </fo:block>
+ <fo:block text-align="center">
+ <fo:basic-link color="lightgrey"
+ external-destination="{$url}">
+ <xsl:value-of select="$url"/>
+ </fo:basic-link>
+ </fo:block>
+ </xsl:if>
+ </fo:block-container>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ xmlns:fox="http://xml.apache.org/fop/extensions"
+ version="1.0">
+
+<xsl:template match="document" mode="outline">
+ <xsl:apply-templates select="body/section" mode="outline"/>
+</xsl:template>
+
+<xsl:template match="section" mode="outline">
+ <fox:outline>
+ <xsl:attribute name="internal-destination">
+ <xsl:choose>
+ <xsl:when test="normalize-space(@id)!=''">
+ <xsl:value-of select="@id"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="generate-id()"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <fox:label>
+ <xsl:number format="1.1.1.1.1.1.1" count="section" level="multiple"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="title"/>
+
+ </fox:label>
+ <xsl:apply-templates select="section" mode="outline"/>
+ </fox:outline>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!--
+book2menu.xsl generates the HTML menu. It outputs XML/HTML of the form:
+ <div class="menu">
+ ...
+ </div>
+which is then merged with other HTML by site2xhtml.xsl
+
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <!-- ================================================================ -->
+ <!-- These templates SHOULD be overridden -->
+ <!-- ================================================================ -->
+
+ <xsl:template name="selected">
+ <xsl:value-of select="@label"/>
+ </xsl:template>
+
+ <xsl:template name="unselected">
+ <a href="{@href}">
+ <xsl:if test="@description">
+ <xsl:attribute name="title">
+ <xsl:value-of select="@description"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="@label"/>
+ </a>
+ </xsl:template>
+
+ <xsl:template name="print-external">
+ <!-- Use apply-imports when overriding -->
+ <xsl:value-of select="@label"/>
+ </xsl:template>
+
+
+ <!-- ================================================================ -->
+ <!-- These templates CAN be overridden -->
+ <!-- ================================================================ -->
+
+ <!-- Eg, if tab href is 'index.html#foo', this will be called when index.html
+ is selected -->
+ <xsl:template name="selected-anchor">
+ <!-- By default, render as unselected so that it is clickable (takes user
+ to the anchor) -->
+ <xsl:call-template name="unselected"/>
+ </xsl:template>
+
+ <xsl:template name="unselected-anchor">
+ <xsl:call-template name="unselected"/>
+ </xsl:template>
+
+
+ <xsl:template match="book">
+ <xsl:apply-templates select="menu"/>
+ </xsl:template>
+
+
+ <xsl:template match="menu">
+ <div class="menu">
+ <xsl:call-template name="base-menu"/>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="menu-item">
+ <!-- Use apply-imports when overriding -->
+
+ <xsl:variable name="href-nofrag">
+ <xsl:call-template name="path-nofrag">
+ <xsl:with-param name="path" select="@href"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="node-path">
+ <xsl:call-template name="normalize">
+ <xsl:with-param name="path" select="concat($dirname, $href-nofrag)"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <!-- Compare with extensions stripped -->
+ <xsl:when test="$node-path = $path-nofrag">
+ <xsl:choose>
+ <xsl:when test="contains(@href, '#')">
+ <xsl:call-template name="selected-anchor"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="selected"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="contains(@href, '#')">
+ <xsl:call-template name="unselected-anchor"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="unselected"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- ================================================================ -->
+ <!-- These templates SHOULD NOT be overridden -->
+ <!-- ================================================================ -->
+
+
+ <xsl:param name="path"/>
+
+ <xsl:include href="pathutils.xsl"/>
+
+ <xsl:variable name="filename">
+ <xsl:call-template name="filename">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="path-nofrag">
+ <xsl:call-template name="path-nofrag">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="path-nofrag">
+ <xsl:call-template name="path-nofrag">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="dirname">
+ <xsl:call-template name="dirname">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:template match="external">
+ <li>
+ <xsl:choose>
+ <xsl:when test="starts-with(@href, $path-nofrag)">
+ <span class="externalSelected">
+ <xsl:call-template name="print-external"/>
+ </span>
+ </xsl:when>
+ <xsl:otherwise>
+ <a href="{@href}" target="_blank"><xsl:value-of select="@label"/></a>
+ </xsl:otherwise>
+ </xsl:choose>
+ </li>
+ </xsl:template>
+
+ <xsl:template match="menu-item[@type='hidden']"/>
+
+ <xsl:template match="external[@type='hidden']"/>
+
+ <xsl:template name="base-menu">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!--
+This stylesheet contains the majority of templates for converting documentv11
+to HTML. It renders XML as HTML in this form:
+
+ <div class="content">
+ ...
+ </div>
+
+..which site2xhtml.xsl then combines with HTML from the index (book2menu.xsl)
+and tabs (tab2menu.xsl) to generate the final HTML.
+
+Section handling
+ - <a name/> anchors are added if the id attribute is specified
+
+-->
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <!-- the skinconf file -->
+ <xsl:param name="config-file" select="'../../../../skinconf.xml'"/>
+ <xsl:variable name="config" select="document($config-file)/skinconfig"/>
+
+ <!-- If true, a PDF link for this page will not be generated -->
+ <xsl:variable name="disable-pdf-link" select="$config/disable-pdf-link"/>
+ <!-- If true, a "print" link for this page will not be generated -->
+ <xsl:variable name="disable-print-link" select="$config/disable-print-link"/>
+ <!-- If true, an XML link for this page will not be generated -->
+ <xsl:variable name="disable-xml-link" select="$config/disable-xml-link"/>
+ <!-- Get the section depth to use when generating the minitoc (default is 2) -->
+ <xsl:variable name="config-max-depth" select="$config/toc/@level"/>
+ <!-- Whether to obfuscate email links -->
+ <xsl:variable name="obfuscate-mail-links" select="$config/obfuscate-mail-links"/>
+
+ <xsl:variable name="max-depth">
+ <xsl:choose>
+ <xsl:when test="string-length($config-max-depth)>0">
+ <xsl:value-of select="$config-max-depth"/>
+ </xsl:when>
+ <xsl:otherwise>2</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:param name="notoc"/>
+ <xsl:param name="path"/>
+ <!-- <xsl:include href="split.xsl"/> -->
+ <xsl:include href="dotdots.xsl"/>
+ <xsl:include href="pathutils.xsl"/>
+
+ <!-- Path to site root, eg '../../' -->
+ <xsl:variable name="root">
+ <xsl:call-template name="dotdots">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="filename-noext">
+ <xsl:call-template name="filename-noext">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="skin-img-dir" select="concat(string($root), 'skin/images')"/>
+
+ <xsl:template match="document">
+ <div class="content">
+ <table summary="" class="title">
+ <tr>
+ <td valign="middle">
+ <xsl:if test="normalize-space(header/title)!=''">
+ <h1>
+ <xsl:value-of select="header/title"/>
+ </h1>
+ </xsl:if>
+ </td>
+ <xsl:call-template name="printlink"/>
+ <xsl:call-template name="pdflink"/>
+ <xsl:call-template name="xmllink"/>
+ </tr>
+ </table>
+ <xsl:if test="normalize-space(header/subtitle)!=''">
+ <h3>
+ <xsl:value-of select="header/subtitle"/>
+ </h3>
+ </xsl:if>
+ <xsl:apply-templates select="header/type"/>
+ <xsl:apply-templates select="header/notice"/>
+ <xsl:apply-templates select="header/abstract"/>
+ <xsl:apply-templates select="body"/>
+ <div class="attribution">
+ <xsl:apply-templates select="header/authors"/>
+ <xsl:if test="header/authors and header/version">
+ <xsl:text>; </xsl:text>
+ </xsl:if>
+ <xsl:apply-templates select="header/version"/>
+ </div>
+ </div>
+ </xsl:template>
+
+ <!-- Generates the "printer friendly version" link -->
+ <xsl:template name="printlink">
+ <xsl:if test="$disable-print-link = 'false'">
+<script type="text/javascript" language="Javascript">
+function printit() {
+if (window.print) {
+ window.print() ;
+} else {
+ var WebBrowser = '<OBJECT ID="WebBrowser1" WIDTH="0" HEIGHT="0" CLASSID="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>';
+document.body.insertAdjacentHTML('beforeEnd', WebBrowser);
+ WebBrowser1.ExecWB(6, 2);//Use a 1 vs. a 2 for a prompting dialog box WebBrowser1.outerHTML = "";
+}
+}
+</script>
+
+<script type="text/javascript" language="Javascript">
+var NS = (navigator.appName == "Netscape");
+var VERSION = parseInt(navigator.appVersion);
+if (VERSION > 3) {
+ document.write('<td align="center" width="40" nowrap="nowrap">');
+ document.write(' <a href="javascript:printit()" class="dida">');
+ document.write(' <img class="skin" src="{$skin-img-dir}/printer.gif" alt="Print this Page"/><br />');
+ document.write(' print</a>');
+ document.write('</td>');
+}
+</script>
+
+ </xsl:if>
+ </xsl:template>
+
+ <!-- Generates the PDF link -->
+ <xsl:template name="pdflink">
+ <xsl:if test="not($config/disable-pdf-link) or $disable-pdf-link = 'false'">
+ <td align="center" width="40" nowrap="nowrap"><a href="{$filename-noext}.pdf" class="dida">
+ <img class="skin" src="{$skin-img-dir}/pdfdoc.gif" alt="PDF"/><br/>
+ PDF</a>
+ </td>
+ </xsl:if>
+ </xsl:template>
+
+
+ <!-- Generates the XML link -->
+ <xsl:template name="xmllink">
+ <xsl:if test="$disable-xml-link = 'false'">
+ <td align="center" width="40" nowrap="nowrap"><a href="{$filename-noext}.xml" class="dida">
+ <img class="skin" src="{$skin-img-dir}/xmldoc.gif" alt="xml"/><br/>
+ xml</a>
+ </td>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="body">
+ <xsl:if test="$max-depth>0 and not($notoc='true')" >
+ <xsl:call-template name="minitoc">
+ <xsl:with-param name="tocroot" select="."/>
+ <xsl:with-param name="depth">1</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+
+ <!-- Generate a <a name="..."> tag for an @id -->
+ <xsl:template match="@id">
+ <xsl:if test="normalize-space(.)!=''">
+ <a name="{.}"/>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="section">
+ <!-- count the number of section in the ancestor-or-self axis to compute
+ the title element name later on -->
+ <xsl:variable name="sectiondepth" select="count(ancestor-or-self::section)"/>
+ <a name="{generate-id()}"/>
+ <xsl:apply-templates select="@id"/>
+ <!-- generate a title element, level 1 -> h3, level 2 -> h4 and so on... -->
+ <xsl:element name="{concat('h',$sectiondepth + 2)}">
+ <xsl:value-of select="title"/>
+ <xsl:if test="$notoc='true' and $sectiondepth = 3">
+ <span style="float: right"><a href="#{@id}-menu">^</a></span>
+ </xsl:if>
+ </xsl:element>
+
+ <!-- Indent FAQ entry text 15 pixels -->
+ <xsl:variable name="indent">
+ <xsl:choose>
+ <xsl:when test="$notoc='true' and $sectiondepth = 3">
+ <xsl:text>15</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>0</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <div style="margin-left: {$indent} ; border: 2px">
+ <xsl:apply-templates select="*[not(self::title)]"/>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="note | warning | fixme">
+ <xsl:apply-templates select="@id"/>
+ <div class="frame {local-name()}">
+ <div class="label">
+ <xsl:choose>
+ <xsl:when test="@label"><xsl:value-of select="@label"/></xsl:when>
+ <xsl:when test="local-name() = 'note'">Note</xsl:when>
+ <xsl:when test="local-name() = 'warning'">Warning</xsl:when>
+ <xsl:otherwise>Fixme (<xsl:value-of select="@author"/>)</xsl:otherwise>
+ </xsl:choose>
+ </div>
+ <div class="content">
+ <xsl:apply-templates/>
+ </div>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="notice">
+ <div class="notice">
+ <!-- FIXME: i18n Transformer here -->
+ <xsl:text>Notice: </xsl:text>
+ <xsl:apply-templates/>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="link">
+ <xsl:apply-templates select="@id"/>
+ <xsl:choose>
+ <xsl:when test="$obfuscate-mail-links='true' and starts-with(@href, 'mailto:') and contains(@href, '@')">
+ <xsl:variable name="mailto-1" select="substring-before(@href,'@')"/>
+ <xsl:variable name="mailto-2" select="substring-after(@href,'@')"/>
+ <a href="{$mailto-1}.at.{$mailto-2}">
+ <xsl:apply-templates/>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <a href="{@href}">
+ <xsl:apply-templates/>
+ </a>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="jump">
+ <xsl:apply-templates select="@id"/>
+ <a href="{@href}" target="_top">
+ <xsl:apply-templates/>
+ </a>
+ </xsl:template>
+
+ <xsl:template match="fork">
+ <xsl:apply-templates select="@id"/>
+ <a href="{@href}" target="_blank">
+ <xsl:apply-templates/>
+ </a>
+ </xsl:template>
+
+ <xsl:template match="p[@xml:space='preserve']">
+ <xsl:apply-templates select="@id"/>
+ <div class="pre">
+ <xsl:apply-templates/>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="source">
+ <xsl:apply-templates select="@id"/>
+ <pre class="code">
+<!-- Temporarily removed long-line-splitter ... gives out-of-memory problems -->
+ <xsl:apply-templates/>
+<!--
+ <xsl:call-template name="format">
+ <xsl:with-param select="." name="txt" />
+ <xsl:with-param name="width">80</xsl:with-param>
+ </xsl:call-template>
+-->
+ </pre>
+ </xsl:template>
+
+ <xsl:template match="anchor">
+ <a name="{@id}"/>
+ </xsl:template>
+
+ <xsl:template match="icon">
+ <xsl:apply-templates select="@id"/>
+ <img src="{@src}" alt="{@alt}" class="icon">
+ <xsl:if test="@height">
+ <xsl:attribute name="height"><xsl:value-of select="@height"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="@width">
+ <xsl:attribute name="width"><xsl:value-of select="@width"/></xsl:attribute>
+ </xsl:if>
+ </img>
+ </xsl:template>
+
+ <xsl:template match="code">
+ <xsl:apply-templates select="@id"/>
+ <span class="codefrag"><xsl:value-of select="."/></span>
+ </xsl:template>
+
+ <xsl:template match="figure">
+ <xsl:apply-templates select="@id"/>
+ <div align="center">
+ <img src="{@src}" alt="{@alt}" class="figure">
+ <xsl:if test="@height">
+ <xsl:attribute name="height"><xsl:value-of select="@height"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="@width">
+ <xsl:attribute name="width"><xsl:value-of select="@width"/></xsl:attribute>
+ </xsl:if>
+ </img>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="table">
+ <xsl:apply-templates select="@id"/>
+ <table cellpadding="4" cellspacing="1" class="ForrestTable">
+ <xsl:if test="@cellspacing"><xsl:attribute name="cellspacing"><xsl:value-of select="@cellspacing"/></xsl:attribute></xsl:if>
+ <xsl:if test="@cellpadding"><xsl:attribute name="cellpadding"><xsl:value-of select="@cellpadding"/></xsl:attribute></xsl:if>
+ <xsl:if test="@border"><xsl:attribute name="border"><xsl:value-of select="@border"/></xsl:attribute></xsl:if>
+ <xsl:if test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:if>
+ <xsl:if test="@bgcolor"><xsl:attribute name="bgcolor"><xsl:value-of select="@bgcolor"/></xsl:attribute></xsl:if>
+ <xsl:apply-templates/>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="acronym/@title">
+ <xsl:attribute name="title">
+ <xsl:value-of select="normalize-space(.)"/>
+ </xsl:attribute>
+ </xsl:template>
+
+ <xsl:template name="minitoc">
+ <xsl:param name="tocroot"/>
+ <xsl:param name="depth"/>
+ <xsl:if test="count($tocroot/section) > 0">
+ <ul class="minitoc">
+ <xsl:for-each select="$tocroot/section">
+ <li>
+ <xsl:call-template name="toclink"/>
+ <xsl:if test="$depth<$max-depth">
+ <xsl:call-template name="minitoc">
+ <xsl:with-param name="tocroot" select="."/>
+ <xsl:with-param name="depth" select="$depth + 1"/>
+ </xsl:call-template>
+ </xsl:if>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="toclink">
+ <xsl:variable name="tocitem" select="normalize-space(title)"/>
+ <xsl:if test="string-length($tocitem)>0">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:text>#</xsl:text>
+ <xsl:if test="@id">
+ <xsl:value-of select="@id"/>
+ </xsl:if>
+ </xsl:attribute>
+ <xsl:value-of select="$tocitem"/>
+ </a>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="header/authors">
+ <xsl:for-each select="person">
+ <xsl:choose>
+ <xsl:when test="position()=1">by </xsl:when>
+ <xsl:otherwise>, </xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="@name"/>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="version">
+ <span class="version">
+ <xsl:apply-templates select="@major"/>
+ <xsl:apply-templates select="@minor"/>
+ <xsl:apply-templates select="@fix"/>
+ <xsl:apply-templates select="@tag"/>
+ <xsl:choose>
+ <xsl:when test="starts-with(., '$Revision: ')">
+ version <xsl:value-of select="substring(., 12, string-length(.) -11-2)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </span>
+ </xsl:template>
+
+ <xsl:template match="@major">
+ v<xsl:value-of select="."/>
+ </xsl:template>
+
+ <xsl:template match="@minor">
+ <xsl:value-of select="concat('.',.)"/>
+ </xsl:template>
+
+ <xsl:template match="@fix">
+ <xsl:value-of select="concat('.',.)"/>
+ </xsl:template>
+
+ <xsl:template match="@tag">
+ <xsl:value-of select="concat('-',.)"/>
+ </xsl:template>
+
+ <xsl:template match="type">
+ <p class="type">
+ <!-- FIXME: i18n Transformer here -->
+ <xsl:text>Type: </xsl:text>
+ <xsl:value-of select="."/>
+ </p>
+ </xsl:template>
+
+ <xsl:template match="abstract">
+ <p>
+ <xsl:apply-templates/>
+ </p>
+ </xsl:template>
+
+ <xsl:template name="email">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <xsl:when test="$obfuscate-mail-links='true'">
+ <xsl:variable name="user" select="substring-before(@email,'@')"/>
+ <xsl:variable name="host" select="substring-after(@email,'@')"/>
+ <xsl:value-of select="concat('mailto:',$user,'.at.',$host)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('mailto:',@email)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </xsl:template>
+
+ <xsl:template match="node()|@*" priority="-1">
+ <xsl:copy>
+ <xsl:apply-templates select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<!--
+Contains the 'dotdots' template, which, given a path, will output a set of
+directory traversals to get back to the source directory. Handles both '/' and
+'\' directory separators.
+
+Examples:
+ Input Output
+ index.html ""
+ dir/index.html "../"
+ dir/subdir/index.html "../../"
+ dir//index.html "../"
+ dir/ "../"
+ dir// "../"
+ \some\windows\path "../../"
+ \some\windows\path\ "../../../"
+ \Program Files\mydir "../"
+
+Cannot handle ..'s in the path, so don't expect 'dir/subdir/../index.html' to
+work.
+
+jefft@apache.org
+-->
+
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:template name="dotdots">
+ <xsl:param name="path"/>
+ <xsl:variable name="dirs" select="normalize-space(translate(concat($path, 'x'), ' /\', '_ '))"/>
+ <!-- The above does the following:
+ o Adds a trailing character to the path. This prevents us having to deal
+ with the special case of ending with '/'
+ o Translates all directory separators to ' ', and normalize spaces,
+ cunningly eliminating duplicate '//'s. We also translate any real
+ spaces into _ to preserve them.
+ -->
+ <xsl:variable name="remainder" select="substring-after($dirs, ' ')"/>
+ <xsl:if test="$remainder">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="dotdots">
+ <xsl:with-param name="path" select="translate($remainder, ' ', '/')"/>
+ <!-- Translate back to /'s because that's what the template expects. -->
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
+<!--
+ Uncomment to test.
+ Usage: saxon dotdots.xsl dotdots.xsl path='/my/test/path'
+
+ <xsl:param name="path"/>
+ <xsl:template match="/">
+ <xsl:message>Path: <xsl:value-of select="$path"/></xsl:message>
+ <xsl:call-template name="dotdots">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:template>
+ -->
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!--
+PathUtils.xsl
+
+A set of XSLT templates useful for parsing URI paths:
+
+dirname: return the directory part of a path
+filename: return the file part of a path
+ext: return the last extension of the filename in a path
+filename-noext: return the file part of a path without its last extension
+
+@author Jeff Turner <jefft@apache.org>
+-->
+
+<!-- Returns the directory part of a path. Equivalent to Unix 'dirname'.
+Examples:
+'' -> ''
+'foo/index.html' -> 'foo/'
+-->
+<xsl:template name="dirname">
+ <xsl:param name="path" />
+ <xsl:if test="contains($path, '/')">
+ <xsl:value-of select="concat(substring-before($path, '/'), '/')" />
+ <xsl:call-template name="dirname">
+ <xsl:with-param name="path"
+ select="substring-after($path, '/')" />
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+<!-- Normalized (..'s eliminated) version of 'dirname' -->
+<xsl:template name="dirname-nz">
+ <xsl:param name="path" />
+ <xsl:call-template name="normalize">
+ <xsl:with-param name="path">
+ <xsl:call-template name="dirname">
+ <xsl:with-param name="path" select="$path" />
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+</xsl:template>
+
+
+<!-- Returns the filename part of a path. Equivalent to Unix 'basename'
+Examples:
+'index.html' -> 'index.html'
+'foo/bar/' -> ''
+'foo/bar/index.html' -> 'index.html'
+-->
+<xsl:template name="filename">
+ <xsl:param name="path"/>
+ <xsl:choose>
+ <xsl:when test="contains($path, '/')">
+ <xsl:call-template name="filename">
+ <xsl:with-param name="path" select="substring-after($path, '/')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$path"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- Returns the last extension of a filename in a path.
+Examples:
+'index.html' -> '.html'
+'index.dtdx.html' -> '.html'
+'foo/bar/' -> ''
+'foo/bar/index.html' -> '.html'
+'foo/bar/index' -> ''
+-->
+<xsl:template name="ext">
+ <xsl:param name="path"/>
+ <xsl:param name="subflag"/> <!-- Outermost call? -->
+ <xsl:choose>
+ <xsl:when test="contains($path, '.')">
+ <xsl:call-template name="ext">
+ <xsl:with-param name="path" select="substring-after($path, '.')"/>
+ <xsl:with-param name="subflag" select="'sub'"/>
+ </xsl:call-template>
+ </xsl:when>
+ <!-- Handle extension-less filenames by returning '' -->
+ <xsl:when test="not($subflag) and not(contains($path, '.'))">
+ <xsl:text/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('.', $path)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- Returns a filename of a path stripped of its last extension.
+Examples:
+'foo/bar/index.dtdx.html' -> 'index.dtdx'
+-->
+<xsl:template name="filename-noext">
+ <xsl:param name="path"/>
+ <xsl:variable name="filename">
+ <xsl:call-template name="filename">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="ext">
+ <xsl:call-template name="ext">
+ <xsl:with-param name="path" select="$filename"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="substring($filename, 1, string-length($filename) - string-length($ext))"/>
+</xsl:template>
+
+<!-- Returns a path with the filename stripped of its last extension.
+Examples:
+'foo/bar/index.dtdx.html' -> 'foo/bar/index.dtdx'
+-->
+<xsl:template name="path-noext">
+ <xsl:param name="path"/>
+ <xsl:variable name="ext">
+ <xsl:call-template name="ext">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="substring($path, 1, string-length($path) - string-length($ext))"/>
+</xsl:template>
+
+<!-- Normalized (..'s eliminated) version of 'path-noext' -->
+<xsl:template name="path-noext-nz">
+ <xsl:param name="path" />
+ <xsl:call-template name="normalize">
+ <xsl:with-param name="path">
+ <xsl:call-template name="path-noext">
+ <xsl:with-param name="path" select="$path" />
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+</xsl:template>
+
+<!-- Returns a path with any fragment identifier ('#...') stripped off
+Examples:
+'foo/bar/index.dtdx.html#blah' -> 'foo/bar/index.dtdx.html'
+-->
+<xsl:template name="path-nofrag">
+ <xsl:param name="path"/>
+ <xsl:if test="not(contains($path, '#'))">
+ <xsl:value-of select="$path"/>
+ </xsl:if>
+ <xsl:if test="contains($path, '#')">
+ <xsl:value-of select="substring-before($path, '#')"/>
+ </xsl:if>
+</xsl:template>
+
+
+
+<!-- Normalizes a path, converting '/' to '\' and eliminating ..'s
+Examples:
+'foo/bar/../baz/index.html' -> foo/baz/index.html'
+-->
+<xsl:template name="normalize">
+ <xsl:param name="path"/>
+ <xsl:variable name="path-" select="translate($path, '\', '/')"/>
+ <xsl:choose>
+ <xsl:when test="contains($path-, '/../')">
+
+ <xsl:variable name="pa" select="substring-before($path-, '/../')"/>
+ <xsl:variable name="th" select="substring-after($path-, '/../')"/>
+ <xsl:variable name="pa-">
+ <xsl:call-template name="dirname">
+ <xsl:with-param name="path" select="$pa"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="pa-th" select="concat($pa-, $th)"/>
+ <xsl:call-template name="normalize">
+ <xsl:with-param name="path" select="$pa-th"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:value-of select="$path-"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+</xsl:template>
+
+<!--
+Uncomment this to test.
+Usage: saxon pathutils.xsl pathutils.xsl path=foo/bar
+
+<xsl:param name="path" select="'/foo/bar/../baz/index.html'"/>
+<xsl:template match="/">
+ <xsl:message>
+ path = <xsl:value-of select="$path"/>
+ normalize = <xsl:call-template name="normalize">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ dirname = <xsl:call-template name="dirname">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ dirname-nz = <xsl:call-template name="dirname-nz">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ filename = <xsl:call-template name="filename">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ ext = <xsl:call-template name="ext">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ filename-noext = <xsl:call-template name="filename-noext">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ path-noext = <xsl:call-template name="path-noext">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ path-noext-nz = <xsl:call-template name="path-noext-nz">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ path-nofrag = <xsl:call-template name="path-nofrag">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+
+ </xsl:message>
+</xsl:template>
+-->
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<!--
+A simple callable template that renders a logo for an entity. The logo will
+be a hyperlink and may include an image (with width and height if specified)
+or else it will just include the specified text.
+
+Note that text and image are mandatory parts of the template.
+-->
+
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:template name="renderlogo">
+ <xsl:param name="name"/>
+ <xsl:param name="url"/>
+ <xsl:param name="logo"/>
+ <xsl:param name="width"/>
+ <xsl:param name="height"/>
+ <xsl:param name="root"/>
+ <xsl:param name="description"/>
+ <a href="{$url}">
+ <xsl:choose>
+ <xsl:when test="$logo and not($logo = '')">
+ <img alt="{$name}" class="logoImage" border="0">
+ <xsl:attribute name="src">
+ <xsl:if test="not(starts-with($logo, 'http://'))"><xsl:value-of select="$root"/></xsl:if>
+ <xsl:value-of select="$logo"/>
+ </xsl:attribute>
+ <xsl:if test="$width">
+ <xsl:attribute name="width"><xsl:value-of select="$width"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="$height">
+ <xsl:attribute name="height"><xsl:value-of select="$height"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="$description">
+ <xsl:attribute name="title"><xsl:value-of select="$description"/></xsl:attribute>
+ </xsl:if>
+ </img>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$name"/></xsl:otherwise>
+ </xsl:choose>
+ </a>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!--
+site2xhtml.xsl is the final stage in HTML page production. It merges HTML from
+document2html.xsl, tab2menu.xsl and book2menu.xsl, and adds the site header,
+footer, searchbar, css etc. As input, it takes XML of the form:
+
+<site>
+ <div class="menu">
+ ...
+ </div>
+ <div class="tab">
+ ...
+ </div>
+ <div class="content">
+ ...
+ </div>
+</site>
+
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <!-- Default skinconf.xml in the skins/ directory -->
+ <xsl:param name="config-file" select="'../../../../skinconf.xml'"/>
+ <xsl:variable name="config" select="document($config-file)/skinconfig"/>
+ <xsl:param name="path"/>
+
+ <xsl:include href="dotdots.xsl"/>
+ <xsl:include href="pathutils.xsl"/>
+ <xsl:include href="renderlogo.xsl"/>
+
+ <!-- Path (..'s) to the root directory -->
+ <xsl:variable name="root">
+ <xsl:call-template name="dotdots">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <!-- Source filename (eg 'foo.xml') of current page -->
+ <xsl:variable name="filename">
+ <xsl:call-template name="filename">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="skin-img-dir" select="concat(string($root), 'skin/images')"/>
+ <xsl:variable name="spacer" select="concat($root, 'skin/images/spacer.gif')"/>
+
+ <xsl:template match="site">
+ <html>
+ <head>
+ <title><xsl:value-of select="div[@class='content']/table/tr/td/h1"/></title>
+ </head>
+ <body>
+ <xsl:if test="$config/group-url">
+ <xsl:call-template name="renderlogo">
+ <xsl:with-param name="name" select="$config/group-name"/>
+ <xsl:with-param name="url" select="$config/group-url"/>
+ <xsl:with-param name="logo" select="$config/group-logo"/>
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="description" select="$config/group-description"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:call-template name="renderlogo">
+ <xsl:with-param name="name" select="$config/project-name"/>
+ <xsl:with-param name="url" select="$config/project-url"/>
+ <xsl:with-param name="logo" select="$config/project-logo"/>
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="description" select="$config/project-description"/>
+ </xsl:call-template>
+ <xsl:comment>================= start Tabs ==================</xsl:comment>
+ <xsl:apply-templates select="div[@class='tab']"/>
+ <xsl:comment>================= end Tabs ==================</xsl:comment>
+ <xsl:comment>================= start Menu items ==================</xsl:comment>
+ <xsl:apply-templates select="div[@class='menu']"/>
+ <xsl:comment>================= end Menu items ==================</xsl:comment>
+ <xsl:comment>================= start Content==================</xsl:comment>
+ <xsl:apply-templates select="div[@class='content']"/>
+ <xsl:comment>================= end Content==================</xsl:comment>
+
+ <xsl:comment>================= start Footer ==================</xsl:comment>
+ Copyright © <xsl:value-of select="$config/year"/> <xsl:value-of
+ select="$config/vendor"/> All rights reserved.<br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ <script language="JavaScript" type="text/javascript"><![CDATA[<!--
+ document.write(" - "+"Last Published: " + document.lastModified);
+ // -->]]></script>
+ <xsl:if test="$config/host-logo and not($config/host-logo = '')">
+ <a href="{$config/host-url}">
+ <xsl:call-template name="renderlogo">
+ <xsl:with-param name="name" select="$config/host-name"/>
+ <xsl:with-param name="url" select="$config/host-url"/>
+ <xsl:with-param name="logo" select="$config/host-logo"/>
+ <xsl:with-param name="root" select="$root"/>
+ </xsl:call-template>
+ </a>
+ </xsl:if>
+ <xsl:if test="$filename = 'index.html' and $config/credits">
+ <xsl:for-each select="$config/credits/credit[not(@role='pdf')]">
+ <xsl:call-template name="renderlogo">
+ <xsl:with-param name="name" select="name"/>
+ <xsl:with-param name="url" select="url"/>
+ <xsl:with-param name="logo" select="image"/>
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="width" select="width"/>
+ <xsl:with-param name="height" select="height"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:if>
+ <a href="http://validator.w3.org/check/referer"><img class="skin" border="0"
+ src="http://www.w3.org/Icons/valid-html401"
+ alt="Valid HTML 4.01!" height="31" width="88"/></a>
+ </body>
+ </html>
+ </xsl:template>
+
+ <!-- Add links to any standards-compliance logos -->
+ <xsl:template name="compliancy-logos">
+ <xsl:if test="$config/disable-compliance-links = 'false'">
+ <a href="http://validator.w3.org/check/referer"><img class="logoImage"
+ src="{$skin-img-dir}/valid-html401.png"
+ alt="Valid HTML 4.01!" height="31" width="88"/></a>
+
+ <a href="http://jigsaw.w3.org/css-validator/"><img class="logoImage"
+ src="{$skin-img-dir}/vcss.png"
+ alt="Valid CSS!" height="31" width="88"/></a>
+ </xsl:if>
+ </xsl:template>
+
+
+ <xsl:template match="node()|@*" priority="-1">
+ <xsl:copy>
+ <xsl:apply-templates select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!--
+ This stylesheet was taken from the XSLT FAQ http://www.dpawson.co.uk/xsl/
+
+ Comments and adaption to be used without normalize-space()
+ by Nicola Ken Barozzi nicolaken@apache.org
+-->
+
+<!--
+ Input:
+
+<doc>
+
+<para>
+ 123456 2345 343434 545454 43434 343
+ 12345 343434 545454 43434 343
+ 32345645 343434 545454 43434 343
+ 3422222225 343434 545454 43434 343
+ llllllllllllllllllllllooooooooooooooonnnnnnnnnnnggggggggg
+ 345 343434 545454 43434 343
+</para>
+
+</doc>
+
+Output:
+
+<HTML>
+<BODY>
+<PRE>123456 2345 343434 545454
+43434 343 12345 343434 545454
+43434 343 32345645 343434
+545454 43434 343 3422222225
+343434 545454 43434 343
+lllllllllllllllllllllloooooooo
+ooooooonnnnnnnnnnnggggggggg
+345 343434 545454 43434
+343
+</PRE>
+</BODY>
+</HTML>
+
+Fragment ised:
+
+ <xsl:template match="/doc">
+ <HTML><BODY><PRE>
+ <xsl:call-template name="format">
+ <xsl:with-param select="normalize-space(para)" name="txt" />
+ <xsl:with-param name="width">30</xsl:with-param>
+ </xsl:call-template>
+ </PRE></BODY></HTML>
+ </xsl:template>
+
+
+-->
+
+ <xsl:template match="/body">
+ <body>
+ <xsl:call-template name="format">
+ <xsl:with-param select="source" name="txt" />
+ <xsl:with-param name="width">40</xsl:with-param>
+ </xsl:call-template>
+ </body>
+ </xsl:template>
+
+ <xsl:template name="format">
+ <xsl:param name="txt" />
+ <xsl:param name="width" />
+
+ <!-- if there is still text left -->
+ <xsl:if test="$txt">
+
+ <xsl:variable name = "pretxt" select = "substring($txt,0, $width)" />
+
+ <xsl:choose>
+ <xsl:when test="contains($pretxt, '
')">
+ <xsl:value-of select="substring-before($pretxt, '
')"/>
+ <xsl:text>
</xsl:text>
+ <xsl:call-template name="format">
+ <xsl:with-param name="txt" select="substring-after($txt,'
')"/>
+ <xsl:with-param select="$width" name="width" />
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- get the width at which to break-->
+ <xsl:variable name="real-width">
+ <xsl:call-template name="tune-width">
+ <xsl:with-param select="$txt" name="txt" />
+ <xsl:with-param select="$width" name="width" />
+ <xsl:with-param select="$width" name="def" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <!-- output the first part of the broken string -->
+ <xsl:value-of select="substring($txt, 1, $real-width)" />
+
+ <!-- output a newline -->
+ <xsl:text>
</xsl:text>
+
+ <!-- call itself with the remaining part of the text -->
+ <xsl:call-template name="format">
+ <xsl:with-param select="substring($txt,$real-width + 1)" name="txt" />
+ <xsl:with-param select="$width" name="width" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:template>
+
+
+ <!-- used by template "format", it calculates the width at the given def
+
+ It starts at def length and comes back till it finds a space -->
+ <xsl:template name="tune-width">
+ <xsl:param name="txt" />
+ <xsl:param name="width" />
+ <xsl:param name="def" />
+
+ <xsl:choose>
+ <xsl:when test="$width = 0">
+ <xsl:value-of select="$def" />
+ </xsl:when>
+
+ <xsl:when test="substring($txt, $width, 1 ) = ' '">
+ <xsl:value-of select="$width" />
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- otherwise need to tune again, trying with $width - 1 -->
+ <xsl:call-template name="tune-width">
+ <xsl:with-param select="$width - 1" name="width" />
+ <xsl:with-param select="$txt" name="txt" />
+ <xsl:with-param select="$def" name="def" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ </xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!--
+This stylesheet generates 'tabs' at the top left of the screen. Tabs are
+visual indicators that a certain subsection of the URI space is being browsed.
+For example, if we had tabs with paths:
+
+Tab1: ''
+Tab2: 'community'
+Tab3: 'community/howto'
+Tab4: 'community/howto/xmlform/index.html'
+
+Then if the current path was 'community/howto/foo', Tab3 would be highlighted.
+The rule is: the tab with the longest path that forms a prefix of the current
+path is enabled.
+
+The output of this stylesheet is HTML of the form:
+ <div class="tab">
+ ...
+ </div>
+
+which is then merged by site2xhtml.xsl
+
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <!-- ================================================================ -->
+ <!-- These templates SHOULD be overridden -->
+ <!-- ================================================================ -->
+
+ <!-- Called before first tag -->
+ <xsl:template name="pre-separator">
+ </xsl:template>
+
+ <!-- Called after last tag -->
+ <xsl:template name="post-separator">
+ </xsl:template>
+
+ <!-- Called between tags -->
+ <xsl:template name="separator">
+ <xsl:text> | </xsl:text>
+ </xsl:template>
+
+ <!--
+ Note: sub-stylesheets can't do apply-imports here, because it would choose
+ the 'tags' template and infinitely recurse. Hence call-template used instead.
+ -->
+
+ <!-- Display a selected tab node -->
+ <xsl:template name="selected">
+ <xsl:call-template name="base-selected"/>
+ </xsl:template>
+
+ <!-- Display an unselected tab node -->
+ <xsl:template name="not-selected">
+ <xsl:call-template name="base-not-selected"/>
+ </xsl:template>
+
+
+ <!-- ================================================================ -->
+ <!-- These templates CAN be overridden -->
+ <!-- ================================================================ -->
+
+ <xsl:template match="tabs">
+ <div class="tab">
+ <xsl:call-template name="base-tabs"/>
+ </div>
+ </xsl:template>
+
+
+ <!-- ================================================================ -->
+ <!-- These templates SHOULD NOT be overridden -->
+ <!-- ================================================================ -->
+
+ <xsl:param name="path"/>
+
+ <xsl:include href="dotdots.xsl"/>
+ <xsl:include href="tabutils.xsl"/>
+
+ <!-- NOTE: Xalan has a bug (race condition?) where sometimes $root is only half-evaluated -->
+ <xsl:variable name="root">
+ <xsl:call-template name="dotdots">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="skin-img-dir" select="concat(string($root), 'skin/images')"/>
+
+ <!--
+ The longest path of any tab, whose path is a subset of the current URL. Ie,
+ the path of the 'current' tab.
+ -->
+ <xsl:variable name="longest-dir">
+ <xsl:call-template name="longest-dir">
+ <xsl:with-param name="tabfile" select="/"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="matching-id">
+ <xsl:call-template name="matching-id">
+ <xsl:with-param name="tabfile" select="/"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+
+ <!-- Called from tabs, after it has written the outer 'div class=tabs' and
+ any other HTML -->
+ <xsl:template name="base-tabs">
+ <xsl:call-template name="pre-separator"/>
+ <xsl:for-each select="//tab">
+ <xsl:if test="position()!=1"><xsl:call-template name="separator"/></xsl:if>
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ <xsl:call-template name="post-separator"/>
+ </xsl:template>
+
+
+ <xsl:template match="tab">
+ <xsl:choose>
+ <xsl:when test="@id and @id = $matching-id">
+ <xsl:call-template name="selected"/>
+ </xsl:when>
+ <xsl:when test="not(@id) and @dir = $longest-dir or @href = $longest-dir">
+ <xsl:call-template name="selected"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="not-selected"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Called from 'selected' -->
+ <xsl:template name="base-selected">
+ <a class="base-selected">
+ <xsl:attribute name="href">
+ <xsl:call-template name="calculate-tab-href">
+ <xsl:with-param name="tab" select="."/>
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:value-of select="@label"/>
+ </a>
+ </xsl:template>
+
+ <!-- Called from 'not-selected' -->
+ <xsl:template name="base-not-selected">
+ <a class="base-not-selected">
+ <xsl:attribute name="href">
+ <xsl:call-template name="calculate-tab-href">
+ <xsl:with-param name="tab" select="."/>
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:value-of select="@label"/>
+ </a>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<!--
+Some callable templates useful when dealing with tab paths. Mostly used in
+tab2menu.xsl
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:param name="site-file" select="'cocoon://abs-menulinks'"/>
+ <xsl:variable name="site" select="document($site-file)"/>
+
+ <!-- Given the current path and a tabs.xml entry, returns a relative path to
+ the specified tab's URL. When rendering a set of tabs, this template will be
+ called once per tab.
+ -->
+ <xsl:template name="calculate-tab-href">
+
+ <xsl:param name="dir_index" select="'index.html'"/>
+
+ <xsl:param name="tab"/> <!-- current 'tab' node -->
+ <xsl:param name="path" select="$path"/>
+
+ <xsl:if test="starts-with($tab/@href, 'http')"> <!-- Absolute URL -->
+ <xsl:value-of select="$tab/@href"/>
+ </xsl:if>
+ <xsl:if test="not(starts-with($tab/@href, 'http'))"> <!-- Root-relative path -->
+ <xsl:variable name="backpath">
+ <xsl:call-template name="dotdots">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ <xsl:text>/</xsl:text>
+ <xsl:value-of select="$tab/@dir | $tab/@href"/>
+ <!-- If we obviously have a directory, add /index.html -->
+ <xsl:if test="$tab/@dir or substring($tab/@href, string-length($tab/@href),
+ string-length($tab/@href)) = '/'">
+ <xsl:text>/</xsl:text>
+ <xsl:if test="$tab/@indexfile">
+ <xsl:value-of select="$tab/@indexfile"/>
+ </xsl:if>
+ <xsl:if test="not(@indexfile)">
+ <xsl:value-of select="$dir_index"/>
+ </xsl:if>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:value-of
+ select="translate(normalize-space(translate($backpath, ' /', '/ ')), ' /', '/ ')"/>
+ <!-- Link to backpath, normalizing slashes -->
+ </xsl:if>
+ </xsl:template>
+
+ <!--
+ The id of any tab, whose path is a subset of the current URL. Ie,
+ the path of the 'current' tab.
+ -->
+ <xsl:template name="matching-id" xmlns:l="http://apache.org/forrest/linkmap/1.0">
+ <xsl:value-of select="$site//*[starts-with(@href, $path)]/@tab"/>
+ </xsl:template>
+
+ <!--
+ The longest path of any tab, whose path is a subset of the current URL. Ie,
+ the path of the 'current' tab.
+ -->
+ <xsl:template name="longest-dir">
+ <xsl:param name="tabfile"/>
+ <xsl:for-each select="$tabfile/tabs/tab[starts-with($path, @dir|@href)]">
+ <xsl:sort select="string-length(@dir|@href)"
+ data-type="number" order="descending"/>
+ <xsl:if test="position()=1">
+ <xsl:value-of select="@dir|@href"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+
+</xsl:stylesheet>
+
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Other colors:
+ * - dark blue: #036
+ * - bluish: #269
+ *
+ */
+
+/*
+ * The Banner section.
+ */
+.banner, .projectLogo, .groupLogo, .projectLogo a, .groupLogo a,
+ .groupLogo a:visited, .projectLogo a:visited,
+ .groupLogo a:link, .projectLogo a:link {
+}
+
+/*
+ * The Status + Footer section.
+ */
+.status, .breadcrumb, .searcher, .tabs {
+}
+
+.selectedTab {
+}
+
+/*
+ * The Menu section.
+ */
+.menuColumn {
+}
+.menubar {
+}
+.menu {
+}
+.menuLabel {
+}
+.menuItem {
+}
+
+/*
+ * The Content section.
+ */
+.contentColumn {
+}
+
+h1, h2, h3, h4 {
+}
+
+h3, h4 {
+ }
+h3 {
+ }
+h4 {
+}
+
+.code {
+}
+
+.section {
+}
+
+.subsection {
+}
+
+/*
+ * The Footer section.
+ */
+.footer, .copyright, .host, .credit {
+}
+
+/*
+ * General Settings
+ */
+body {
+}
+
+a:link, .menuItem a:visited, .status a:visited {
+ color: #036;
+}
+
+a:active, a:hover {
+
+}
+
+body, th, td {
+}
+
+.logoImage {
+}
+
+.frame {
+ border: solid black 1px;
+ margin: 1em 3em;
+}
+
+.frame .label {
+ background: #369;
+ color: white;
+ font-weight: bold;
+ padding: 5px 10px;
+}
+.frame .content {
+ padding: 5px 10px;
+ background: #F0F0FF;
+ color: black;
+ line-height: 120%;
+ font-size: 90%;
+}
+.warning .label {
+ background: #C00;
+ color: white;
+}
+.warning .content {
+ background: #FFF0F0;
+ color: black;
+}
+.fixme .label {
+ background: #C6C600;
+}
+
+.codefrag {
+ font-family: "Courier New", Courier, monospace;
+ font-size: 110%;
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks {
+ display: none;
+ }
+body.docs div.docs {
+ margin: 0 !important;
+ border: none !important
+ }
+
+/* just to be sure */
+#navcolumn {
+ width: 0px;
+}
+
+#leftcol {
+ width: 0px;
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+div#banner {
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #aaa;
+}
+
+p img.ontheright {
+ float: right;
+}
+
+#banner, #banner td {
+ background: #fff;
+ color: #036;
+}
+
+#tabs {
+ text-align: right;
+}
+
+.selectedTab {
+ color: #036;
+}
+
+ a.unselectedTab {
+ color: #888888;
+}
+
+#source {
+ background-color: #fff;
+ color: #000;
+ border-right: 1px solid #888;
+ border-left: 1px solid #888;
+ border-top: 1px solid #888;
+ border-bottom: 1px solid #888;
+ margin-right: 7px;
+ margin-left: 7px;
+ margin-top: 1em;
+}
+
+#source pre {
+ margin-right: 7px;
+ margin-left: 7px;
+}
+
+/* make the whole column grey */
+#navcolumn {
+ width: 180px;
+ }
+
+#leftcol {
+ width: 180px;
+}
+
+/*
+ * The Menu section.
+ */
+.menuColumn {
+}
+
+.menu {
+ padding-bottom: .2em;
+ font-size: x-small;
+ text-decoration: none;
+}
+.menuLabel { font-weight: bold; }
+.menuItem {
+ padding-left: 12px;
+ text-decoration: none;
+}
+
+/* breadcrumbs */
+#breadcrumbs
+{
+ font-weight: bold;
+}
+.breadcrumbTrail
+{
+ padding-left: 5px;
+}
+.breadcrumb
+{
+ font-weight: bold;
+}
+.crumbSeparator
+{
+}
+#authors {
+ font-size: x-small;
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/* contains rules unsuitable for Netscape 4.x; simpler rules are in ns4_only.css. see <http://style.tigris.org/> */
+
+/* colors, backgrounds, borders, link indication */
+
+body {
+ background: #fff;
+ color: #000;
+ }
+.app h3, .app h4, .app th, .tabs td, .tabs th, .functnbar {
+ background-image: url(images/nw_maj_rond.gif);
+ background-repeat: no-repeat;
+ }
+#navcolumn div div, body.docs #toc li li {
+ background-image: url(images/strich.gif);
+ background-repeat: no-repeat;
+ background-position: .5em .5em;
+ }
+#navcolumn div div.heading {
+ background-image: none;
+ }
+.app h3, .app h4 {
+ color: #fff;
+ }
+.app h3 {
+ background-color: #036;
+ }
+.app h4 {
+ background-color: #888;
+ }
+.a td {
+ background: #ddd;
+ }
+.b td {
+ background: #efefef;
+ }
+table, th, td {
+ border: none
+ }
+.mtb {
+ border-top: solid 1px #ddd;
+ }
+div.colbar {
+ background: #bbb;
+ }
+div#banner {
+ border-top: 1px solid #369;
+ border-bottom: 1px solid #003;
+ }
+div#helptext th {
+ border-bottom: 1px solid #996;
+ border-right: 1px solid #996;
+ }
+div#helptext td {
+ border-bottom: 1px solid #cc9;
+ border-right: 1px solid #cc9;
+ }
+.tabs {
+ border-bottom: .75em #888 solid;
+ }
+.tabs th, .tabs td {
+ border-right: 1px solid #333;
+ }
+.tabs td {
+ border-bottom: 1px solid #ddd;
+ }
+#navcolumn {
+ background: #eee;
+ border-right: 1px solid #aaa;
+ border-bottom: 1px solid #aaa;
+ }
+#breadcrumbs {
+ border-bottom: 1px solid #aaa;
+ background-color: #ddd;
+ }
+#navcolumn, #breadcrumbs {
+ border-top: 1px solid #fff;
+ }
+#rightcol div.www, #rightcol div.help {
+ border: 1px solid #ddd;
+ }
+div#navcolumn div.focus {
+ border-top: 1px solid #aaa;
+ border-left: 1px solid #aaa;
+ background-color: #fff;
+ }
+body.docs div.docs {
+ background: #fff;
+ border-left: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ }
+body.docs {
+ background: #eee url(images/help_logo.gif) top right no-repeat !important;
+ }
+.docs h3, .docs h4 {
+ border-top: solid 1px #000;
+ }
+#alerterrormessage {
+ background: url(images/icon_alert.gif) top left no-repeat !important;
+ }
+.functnbar {
+ background-color: #aaa;
+ }
+.functnbar2, .functnbar3 {
+ background: #aaa;
+ }
+.functnbar3 {
+ background-color: #ddd;
+ }
+.functnbar, .functnbar2, .functnbar3 {
+ color: #000;
+ }
+.functnbar a, .functnbar2 a, .functnbar3 a {
+ color: #000;
+ text-decoration: underline;
+ }
+#topmodule {
+ background: #ddd;
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #aaa;
+ border-right: 1px solid #aaa;
+ }
+#topmodule #issueid {
+ border-right: 1px solid #aaa;
+ }
+a:link, #navcolumn a:visited, .app a:visited, .tasknav a:visited {
+ color: blue;
+ }
+a:active, a:hover, #leftcol a:active, #leftcol a:hover {
+ color: #f30 !important;
+ }
+#login a:link, #login a:visited {
+ color: white;
+ text-decoration: underline;
+ }
+#banner a:active, #banner a:hover {
+ color: #f90 !important;
+ }
+#leftcol a, #breadcrumbs a {
+ text-decoration: none;
+ }
+a:link.selfref, a:visited.selfref {
+ color: #555 !important;
+ text-decoration: none;
+ }
+h2 .lastchild {
+ color: #777
+ }
+.tabs td, .tabs th {
+ background-color: #ddd;
+ }
+.app th {
+ background-color: #bbb;
+ }
+.tabs th {
+ background-color: #888;
+ color: #fff;
+ }
+.axial th {
+ background-color: #ddd;
+ color: black
+ }
+.tabs td {
+ background-color: #ddd;
+ }
+.alert {
+ color: #c00;
+ }
+.confirm {
+ color: green;
+ }
+.info {
+ color: blue;
+ }
+.selection {
+ background: #ffc;
+ }
+#login {
+ color: #fff;
+ }
+#helptext th {
+ background: #cc9;
+ }
+#helptext td {
+ background: #ffc;
+ }
+.tabs a {
+ text-decoration: none;
+ }
+#navcolumn div strong {
+ color: #000;
+ }
+#banner, #banner td {
+ background: #036;
+ color: #fff;
+ }
+body #banner #login a {
+ color: #fff;
+ }
+
+
+/* font and text properties, exclusive of link indication, alignment, text-indent */
+
+body, th, td, input, select, textarea, h2 small {
+ font-family: Verdana, Helvetica, Arial, sans-serif;
+ }
+code, pre {
+ font-family: 'Andale Mono', Courier, monospace;
+ }
+html body, body th, body td, textarea, h2 small, .app h3, .app h4, #rightcol h3, #bodycol pre, #bodycol code {
+ font-size: x-small;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ font-size: small
+ }
+html>body, html>body th, html>body td, html>body input, html>body select, html>body textarea, html>body h2 small, html>body .app h3, html>body .app h4, html>body #rightcol h3, html>body #bodycol pre, html>body #bodycol code {
+ font-size: small
+ }
+small, div#footer td, div#login, div.tabs th, div.tabs td, input, select, .paginate, .functnbar, .functnbar2, .functnbar3, #breadcrumbs td, .courtesylinks, #rightcol div.help, .colbar, .tasknav, body.docs div#toc, #leftcol {
+ font-size: x-small;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ font-size: x-small
+ }
+html>body small, html>body div#footer td, html>body div#login, html>body div#helptext td, html>body div#helptext th, html>body div.tabs th, html>body div.tabs td, html>body input, html>body select, html>body .paginate, html>body .functnbar, html>body .functnbar2, html>body .functnbar3, html>body #breadcrumbs td, html>body .courtesylinks, html>body #rightcol div.help, html>body .colbar, html>body .tasknav, html>body.docs #toc {
+ font-size: x-small
+ }
+#bodycol h2 {
+ font-family: Tahoma, Verdana, Helvetica, Arial, sans-serif;
+ font-size: 1.5em;
+ font-weight: normal;
+ }
+h2 small {
+ font-weight: bold;
+ letter-spacing: .06em;
+ }
+dt {
+ font-weight: bold
+ }
+#login .username {
+ font-weight: bold;
+ }
+h4 {
+ font-size: 1em;
+ }
+#breadcrumbs td {
+ font-weight: bold;
+ }
+.selection {
+ font-weight: bold
+ }
+
+
+/* box properties (exclusive of borders), positioning, alignments, list types, text-indent */
+
+#bodycol h2 {
+ margin-top: .3em;
+ margin-bottom: .5em;
+ }
+p, ul, ol, dl {
+ margin-top: .67em;
+ margin-bottom: .67em;
+ }
+h3, h4 {
+ margin-bottom: 0;
+ }
+form {
+ margin-top: 0;
+ margin-bottom: 0;
+ }
+#bodycol {
+ padding-left: 12px;
+ padding-right: 12px;
+ width: 100%;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ width: auto;
+ }
+html>body #bodycol {
+ width: auto;
+ }
+.docs {
+ line-height: 1.4;
+ }
+.app h3, .app h4 {
+ padding: 5px;
+ margin-right: 2px;
+ margin-left: 2px;
+ }
+.h3 p, .h4 p, .h3 dt, .h4 dt {
+ margin-right: 7px;
+ margin-left: 7px;
+ }
+.tasknav {
+ margin-bottom: 1.33em
+ }
+div.colbar {
+ padding: 4px;
+ margin: 2px 2px 0;
+ }
+.tabs {
+ margin-top: .67em;
+ margin-right: 2px;
+ margin-left: 2px;
+ }
+#leftcol {
+ padding-bottom: .5em;
+ }
+#breadcrumbs td {
+ vertical-align: middle;
+ padding: 2px 8px;
+ }
+#rightcol div.www, #rightcol div.help {
+ padding: 0 .5em
+ }
+#navcolumn {
+ margin: -8px -8px 0 -8px;
+ padding: 4px;
+ }
+#navcolumn div {
+ padding-left: 5px
+ }
+div#navcolumn div div {
+ margin-top: .3em;
+ margin-bottom: .3em;
+ }
+div#navcolumn div.focus {
+ margin-top: -.1em;
+ padding: .2em 4px;
+ }
+body.docs #toc {
+ position: absolute;
+ top: 15px;
+ left: 0px;
+ width: 120px;
+ padding: 0 20px 0 0
+ }
+body.docs #toc ul, #toc ol {
+ margin-left: 0;
+ padding-left: 0;
+ }
+body.docs #toc li {
+ margin-top: 7px;
+ padding-left: 10px;
+ list-style-type: none;
+ }
+body.docs div.docs {
+ margin: 61px 0 0 150px;
+ padding: 1em 2em 1em 1em !important;
+ }
+.docs p+p {
+ text-indent: 5%;
+ margin-top: -.67em
+ }
+.docs h3, .docs h4 {
+ margin-bottom: .1em;
+ padding-top: .3em;
+ }
+#alerterrormessage {
+ padding-left: 100px;
+ }
+.functnbar, .functnbar2, .functnbar3 {
+ padding: 5px;
+ margin: .67em 2px;
+ }
+#topmodule td {
+ vertical-align: middle;
+ padding: 2px 8px
+ }
+body {
+ padding: 1em;
+ }
+body.composite, body.docs {
+ margin: 0;
+ padding: 0;
+ }
+th, td {
+ text-align: left;
+ vertical-align: top
+ }
+.right {
+ text-align: right !important;
+ }
+.center {
+ text-align: center !important;
+ }
+.tabs td, .tabs th {
+ padding-left: 7px;
+ padding-right: 7px;
+ }
+.axial th {
+ text-align: right;
+ }
+.app .axial td th {
+ text-align: left;
+ }
+body td .stb {
+ margin-top: 1em;
+ text-indent: 0;
+ }
+body td .mtb {
+ margin-top: 2em;
+ text-indent: 0;
+ }
+dd {
+ margin-bottom: .67em;
+ }
+#footer {
+ margin: 4px
+ }
+#helptext {
+ margin-top: 1em
+ }
+#helptext td div {
+ margin: .5em
+ }
+.courtesylinks {
+ margin-top: 1em;
+ padding-top: 1em
+ }
+#navcolumn div {
+ margin-bottom: .5em;
+ }
+#navcolumn div div {
+ margin-top: .3em
+ }
+#navcolumn div div {
+ padding-left: 1em;
+ }
+#banner, #banner td {
+ vertical-align: middle;
+ }
+body.docs, body.nonav {
+ margin: 1em
+ }
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ version="1.0">
+
+<xsl:import href="../../../common/xslt/fo/document2fo.xsl"/>
+
+ <xsl:template match="legal">
+ </xsl:template>
+
+</xsl:stylesheet>
+
+
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!--
+book2menu.xsl generates the HTML menu. See the imported book2menu.xsl for
+details.
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:import href="../../../common/xslt/html/book2menu.xsl"/>
+
+ <xsl:template match="book">
+ <div class="menuBar">
+ <xsl:apply-templates select="menu"/>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="menu">
+ <div class="menu">
+ <span class="menuLabel"><xsl:value-of select="@label"/></span>
+ <xsl:call-template name="base-menu"/>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="menu-item[@type='hidden']"/>
+
+ <xsl:template match="menu-item">
+ <div class="menuItem">
+ <xsl:apply-imports/>
+ </div>
+ </xsl:template>
+
+ <xsl:template name="selected">
+ <span class="menuSelected">
+ <xsl:value-of select="@label"/>
+ </span>
+ </xsl:template>
+
+ <xsl:template name="print-external">
+ <font color="#ffcc00">
+ <span class="externalSelected">
+ <xsl:apply-imports/>
+ </span>
+ </font>
+ </xsl:template>
+
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!--
+This stylesheet contains the majority of templates for converting documentv11
+to HTML. It renders XML as HTML in this form:
+
+ <div class="content">
+ ...
+ </div>
+
+..which site2xhtml.xsl then combines with HTML from the index (book2menu.xsl)
+and tabs (tab2menu.xsl) to generate the final HTML.
+
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:import href="../../../common/xslt/html/document2html.xsl"/>
+
+<!-- ====================================================================== -->
+<!-- document section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="document">
+ <!-- checks if this is the included document to avoid neverending loop -->
+ <xsl:if test="not(book)">
+ <document>
+ <xsl:choose>
+ <xsl:when test="header/title">
+ <title><xsl:value-of select="header/title"/></title>
+ </xsl:when>
+ <xsl:otherwise>
+ <title>NO TITLE</title>
+ </xsl:otherwise>
+ </xsl:choose>
+ <body>
+ <xsl:apply-templates/>
+ <xsl:if test="header/authors">
+ <div align="right" id="authors">
+ <xsl:for-each select="header/authors/person">
+ <xsl:choose>
+ <xsl:when test="position()=1">by </xsl:when>
+
+ <xsl:otherwise>, </xsl:otherwise>
+ </xsl:choose>
+ <!-- <a href="mailto:{@email}"> -->
+ <xsl:value-of select="@name" />
+ <!-- </a> -->
+ </xsl:for-each>
+ </div>
+ </xsl:if>
+ <!--xsl:call-template name="pdflink"/-->
+ </body>
+ </document>
+ </xsl:if>
+
+
+
+ <xsl:if test="book">
+ <xsl:apply-templates/>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="body">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+
+<!-- ====================================================================== -->
+<!-- header section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="header">
+ <!-- ignore on general document -->
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- body section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="section">
+
+ <xsl:variable name = "level" select = "count(ancestor::section)+1" />
+ <xsl:apply-templates select="@id"/>
+ <xsl:choose>
+ <xsl:when test="$level=1">
+ <div class="h3"><h3><xsl:value-of select="title"/></h3></div>
+ <xsl:apply-templates/>
+ </xsl:when>
+ <xsl:when test="$level=2">
+ <div class="h4"><h4><xsl:value-of select="title"/></h4></div>
+ <xsl:apply-templates/>
+ </xsl:when>
+ <xsl:when test="$level=3">
+ <div class="h2"><h2><xsl:value-of select="title"/></h2></div>
+ <xsl:apply-templates/>
+ </xsl:when>
+ <xsl:otherwise>
+ <div class="h5"><h5><xsl:value-of select="title"/></h5></div>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <xsl:template match="title">
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- footer section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="footer">
+ <!-- ignore on general documents -->
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- paragraph section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="p">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="note">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="source">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="//source/font">
+ <font color="{@color}"><xsl:apply-templates/></font>
+ </xsl:template>
+
+ <xsl:template match="fixme">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- list section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="ul|ol|dl">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="li">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="sl">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="dt">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- table section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="table">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="tr">
+ <xsl:variable name="index"><xsl:number/></xsl:variable>
+ <tr>
+ <xsl:choose>
+ <xsl:when test="($index mod 2) = 0">
+ <xsl:attribute name="class">a</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="class">b</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:apply-templates/>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="th">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="td">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="tn">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="caption">
+ <!-- ignore since already used -->
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- markup section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="strong">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="em">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="code">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- images section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="figure">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="img">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="icon">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- links section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="link">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="connect">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="jump">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="fork">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <xsl:template match="anchor">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+<!-- ====================================================================== -->
+<!-- specials section -->
+<!-- ====================================================================== -->
+
+ <xsl:template match="br">
+ <xsl:apply-imports/>
+ </xsl:template>
+
+ <!-- Generates the PDF link -->
+ <xsl:template name="pdflink">
+ <xsl:if test="not($config/disable-pdf-link) or $disable-pdf-link = 'false'">
+ <div align="right" id="pdf"><a href="{$filename-noext}.pdf">
+ <img class="skin" src="{$skin-img-dir}/pdfdoc.gif" alt="PDF"/><br/>
+ PDF</a>
+ </div>
+ </xsl:if>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!--
+site2xhtml.xsl is the final stage in HTML page production. It merges HTML from
+document2html.xsl, tab2menu.xsl and book2menu.xsl, and adds the site header,
+footer, searchbar, css etc. As input, it takes XML of the form:
+
+<site>
+ <div class="menu">
+ ...
+ </div>
+ <div class="tab">
+ ...
+ </div>
+ <div class="content">
+ ...
+ </div>
+</site>
+
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:import href="../../../common/xslt/html/site2xhtml.xsl"/>
+
+ <xsl:template match="site">
+ <html>
+ <head>
+ <xsl:comment>*** This is a generated file. Do not edit. ***</xsl:comment>
+ <link type="text/css" href="{$root}skin/tigris.css" rel="stylesheet" />
+ <link type="text/css" href="{$root}skin/mysite.css" rel="stylesheet" />
+ <link type="text/css" href="{$root}skin/site.css" rel="stylesheet" />
+ <link type="text/css" href="{$root}skin/print.css" rel="stylesheet" media="print" />
+
+ <title>
+ <xsl:value-of select="/site/document/title" />
+ </title>
+ </head>
+
+ <body class="composite" bgcolor="white">
+
+ <xsl:comment>================= start Banner ==================</xsl:comment>
+ <div id="banner">
+ <table border="0" summary="banner" cellspacing="0" cellpadding="8" width="100%">
+ <tbody>
+ <tr>
+ <xsl:comment>================= start Group Logo ==================</xsl:comment>
+ <xsl:if test="$config/group-name">
+ <td align="left" width="50%">
+ <div class="groupLogo">
+ <xsl:call-template name="renderlogo">
+ <xsl:with-param name="name" select="$config/group-name"/>
+ <xsl:with-param name="url" select="$config/group-url"/>
+ <xsl:with-param name="logo" select="$config/group-logo"/>
+ <xsl:with-param name="root" select="$root"/>
+ </xsl:call-template>
+ </div>
+ </td>
+ </xsl:if>
+ <xsl:comment>================= end Group Logo ==================</xsl:comment>
+ <xsl:comment>================= start Project Logo ==================</xsl:comment>
+ <td align="right" width="50%">
+ <div class="projectLogo" align="right">
+ <xsl:call-template name="renderlogo">
+ <xsl:with-param name="name" select="$config/project-name"/>
+ <xsl:with-param name="url" select="$config/project-url"/>
+ <xsl:with-param name="logo" select="$config/project-logo"/>
+ <xsl:with-param name="root" select="$root"/>
+ </xsl:call-template>
+ </div>
+ </td>
+ <xsl:comment>================= end Project Logo ==================</xsl:comment>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <xsl:comment>================= end Banner ==================</xsl:comment>
+
+ <xsl:comment>================= start Main ==================</xsl:comment>
+ <table id="breadcrumbs" summary="nav" border="0" cellspacing="0" cellpadding="0" width="100%">
+ <tbody>
+ <xsl:comment>================= start Status ==================</xsl:comment>
+ <tr class="status">
+ <td>
+ <xsl:comment>================= start BreadCrumb ==================</xsl:comment>
+ <a href="{$config/trail/link1/@href}"><xsl:value-of select="$config/trail/link1/@name" /></a>
+ <xsl:if test = "($config/trail/link2/@name)and(normalize-space($config/trail/link2/@name)!='')"><xsl:text> | </xsl:text></xsl:if>
+ <a href="{$config/trail/link2/@href}"><xsl:value-of select="$config/trail/link2/@name" /></a>
+ <xsl:if test = "($config/trail/link3/@name)and(normalize-space($config/trail/link3/@name)!='')"><xsl:text> | </xsl:text></xsl:if>
+ <a href="{$config/trail/link3/@href}"><xsl:value-of select="$config/trail/link3/@name" /></a>
+ <!-- useful when we have <link> elements instead of link(n:=1..3)
+ <xsl:for-each select="$config/trail/link">
+ <xsl:if test="position()!=1">|</xsl:if>
+ <a href="{@href}"><xsl:value-of select="@name"/></a>
+ </xsl:for-each>
+ -->
+ <xsl:comment>================= end BreadCrumb ==================</xsl:comment>
+ </td>
+ <td id="tabs">
+ <xsl:comment>================= start Tabs ==================</xsl:comment>
+ <xsl:apply-templates select="div[@class='tab']"/>
+ <xsl:comment>================= end Tabs ==================</xsl:comment>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <xsl:comment>================= end Status ==================</xsl:comment>
+
+
+ <table border="0" summary="" cellspacing="0" cellpadding="8" width="100%" id="main">
+ <tbody>
+ <tr valign="top">
+ <xsl:comment>================= start Menu ==================</xsl:comment>
+ <td id="leftcol">
+ <div id="navcolumn">
+ <xsl:apply-templates select="div[@class='menuBar']"/>
+ </div>
+ <xsl:if test="not($config/disable-search) or
+ $config/disable-search='false' and $config/searchsite-domain and
+ $config/searchsite-name">
+ <form method="get" action="http://www.google.com/search" target="_blank">
+ <table cellpadding="0" cellspacing="0" border="0" summary="search">
+ <tr>
+ <td><img class="spacer" src="{$spacer}" alt="" width="1" height="1" /></td>
+ <td nowrap="nowrap">
+ Search <xsl:value-of select="$config/searchsite-name"/>
+ <br />
+ <input type="hidden" name="sitesearch" value="{$config/searchsite-domain}"/>
+ <input type="text" id="query" name="q" size="10"/>
+ <img class="spacer" src="{$spacer}" alt="" width="5" height="1" />
+ <input type="submit" value="GO" name="Search"/>
+ <!-- setting search options off for the moment -->
+ <!--
+ <input type="radio" name="web" value="web"/>web site  <input type="radio" name="mail" value="mail"/>mail lists
+ -->
+ </td>
+ <td><img class="spacer" src="{$spacer}" alt="" width="1" height="1" /></td>
+ </tr>
+
+ <tr>
+ <td colspan="3"><img class="spacer" src="{$spacer}" alt="" width="1" height="7" /></td>
+ </tr>
+
+ <tr>
+ <td class="bottom-left-thick"></td>
+ <td bgcolor="#a5b6c6"><img class="spacer" src="{$spacer}" alt="" width="1" height="1" /></td>
+ <td class="bottom-right-thick"></td>
+ </tr>
+ </table>
+ </form>
+ </xsl:if>
+ </td>
+ <xsl:comment>================= end Menu ==================</xsl:comment>
+
+ <xsl:comment>================= start Content ==================</xsl:comment>
+ <td>
+ <div id="bodycol">
+ <div class="app">
+ <div align="center">
+ <h1><xsl:value-of select="/site/document/title" /></h1>
+ <xsl:if test="/site/document/subtitle">
+ <h2><xsl:value-of select="/site/document/subtitle" /></h2>
+ </xsl:if>
+ </div>
+ <div class="h3">
+ <xsl:copy-of select="/site/document/body/node()|@*" />
+ </div>
+ </div>
+ </div>
+ </td>
+ <xsl:comment>================= end Content ==================</xsl:comment>
+ </tr>
+ </tbody>
+ </table>
+ <xsl:comment>================= end Main ==================</xsl:comment>
+
+ <xsl:comment>================= start Footer ==================</xsl:comment>
+ <div id="footer">
+ <table border="0" width="100%" cellpadding="4" cellspacing="0" summary="footer">
+ <tbody>
+ <tr>
+ <xsl:comment>================= start Copyright ==================</xsl:comment>
+ <td colspan="2">
+ <div align="center">
+ <div class="copyright">
+ Copyright © <xsl:value-of select="$config/year"/> <xsl:value-of
+ select="$config/vendor"/>. All rights reserved.<br />
+ Apache POI, POI, Apache, the Apache feather logo, and the Apache
+ POI project logo are trademarks of The Apache Software Foundation.
+ </div>
+ </div>
+ </td>
+ <xsl:comment>================= end Copyright ==================</xsl:comment>
+ </tr>
+ <tr>
+ <td align="left">
+ <xsl:comment>================= start Host ==================</xsl:comment>
+ <xsl:if test="$config/host-logo and not($config/host-logo = '')">
+ <div align="left">
+ <div class="host">
+ <xsl:call-template name="renderlogo">
+ <xsl:with-param name="name" select="$config/host-name"/>
+ <xsl:with-param name="url" select="$config/host-url"/>
+ <xsl:with-param name="logo" select="$config/host-logo"/>
+ <xsl:with-param name="root" select="$root"/>
+ </xsl:call-template>
+ </div>
+ </div>
+ </xsl:if>
+ <xsl:comment>================= end Host ==================</xsl:comment>
+ </td>
+ <td align="right">
+ <xsl:comment>================= start Credits ==================</xsl:comment>
+ <div align="right">
+ <div class="credit">
+ <xsl:if test="$filename = 'index.html'">
+ <xsl:call-template name="compliancy-logos"/>
+ <xsl:if test="$config/credits">
+ <xsl:for-each select="$config/credits/credit[not(@role='pdf')]">
+ <xsl:call-template name="renderlogo">
+ <xsl:with-param name="name" select="name"/>
+ <xsl:with-param name="url" select="url"/>
+ <xsl:with-param name="logo" select="image"/>
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="width" select="width"/>
+ <xsl:with-param name="height" select="height"/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:if>
+ </div>
+ </div>
+ <xsl:comment>================= end Credits ==================</xsl:comment>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <xsl:comment>================= end Footer ==================</xsl:comment>
+
+ </body>
+ </html>
+ </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<!--
+This stylesheet generates 'tabs' at the top left of the screen.
+See the imported tab2menu.xsl for details.
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:import href="../../../common/xslt/html/tab2menu.xsl"/>
+ <xsl:param name="config-file" select="'../../../../skinconf.xml'"/>
+ <xsl:variable name="config" select="document($config-file)/skinconfig"/>
+
+ <xsl:param name="notoc"/>
+ <xsl:param name="path"/>
+ <!-- <xsl:include href="split.xsl"/> -->
+ <xsl:include href="../../../common/xslt/html/dotdots.xsl"/>
+ <xsl:include href="../../../common/xslt/html/pathutils.xsl"/>
+
+ <!-- If true, a PDF link for this page will not be generated -->
+ <xsl:variable name="disable-pdf-link" select="$config/disable-pdf-link"/>
+ <!-- If true, a "print" link for this page will not be generated -->
+ <xsl:variable name="disable-print-link" select="$config/disable-print-link"/>
+ <!-- If true, an XML link for this page will not be generated -->
+ <xsl:variable name="disable-xml-link" select="$config/disable-xml-link"/>
+ <!-- Get the section depth to use when generating the minitoc (default is 2) -->
+ <xsl:variable name="config-max-depth" select="$config/toc/@level"/>
+ <!-- Whether to obfuscate email links -->
+ <xsl:variable name="obfuscate-mail-links" select="$config/obfuscate-mail-links"/>
+
+ <!-- Path to site root, eg '../../' -->
+ <xsl:variable name="root">
+ <xsl:call-template name="dotdots">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="filename-noext">
+ <xsl:call-template name="filename-noext">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:template name="pre-separator">
+ </xsl:template>
+
+ <xsl:template name="post-separator">
+
+ <xsl:if test="not($config/disable-print-link) or $disable-print-link = 'false'">
+ <xsl:text> | </xsl:text>
+<script type="text/javascript" language="Javascript">
+function printit() {
+if (window.print) {
+ window.print() ;
+} else {
+ var WebBrowser = '<OBJECT ID="WebBrowser1" WIDTH="0" HEIGHT="0" CLASSID="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>';
+document.body.insertAdjacentHTML('beforeEnd', WebBrowser);
+ WebBrowser1.ExecWB(6, 2);//Use a 1 vs. a 2 for a prompting dialog box WebBrowser1.outerHTML = "";
+}
+}
+</script>
+
+<script type="text/javascript" language="Javascript">
+var NS = (navigator.appName == "Netscape");
+var VERSION = parseInt(navigator.appVersion);
+if (VERSION > 3) {
+ document.write(' <a href="javascript:printit()" title="PRINT this page OUT">PRINT</a>');
+}
+</script>
+ </xsl:if>
+
+ <xsl:if test="not($config/disable-xml-link) or $disable-xml-link = 'false'">
+ <xsl:text> | </xsl:text><a href="{$filename-noext}.xml" title="XML file of this page">XML</a>
+ </xsl:if>
+
+
+ <xsl:if test="not($config/disable-pdf-link) or $disable-pdf-link = 'false'">
+ <xsl:text> | </xsl:text><a href="{$filename-noext}.pdf" title="PDF file of this page">PDF</a>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="separator">
+ <xsl:text> | </xsl:text>
+ </xsl:template>
+
+ <xsl:template name="selected" mode="print">
+ <span class="selectedTab">
+ <xsl:call-template name="base-selected"/>
+ </span>
+ </xsl:template>
+
+ <xsl:template name="not-selected" mode="print">
+ <span class="unselectedTab">
+ <!-- Called from 'not-selected' -->
+ <a>
+ <xsl:attribute name="href">
+ <xsl:call-template name="calculate-tab-href">
+ <xsl:with-param name="tab" select="."/>
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:value-of select="@label"/>
+ </a>
+ </span>
+ </xsl:template>
+</xsl:stylesheet>