Compare commits

..

2 Commits

Author SHA1 Message Date
Joe Schaefer
811c08c88d move poi to top level
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/NIO_BRANCH@550311 13f79535-47bb-0310-9956-ffa450edef68
2007-06-25 01:51:34 +00:00
No Author
226afe58c2 This commit was manufactured by cvs2svn to create branch 'NIO_BRANCH'.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/branches/NIO_BRANCH@353680 13f79535-47bb-0310-9956-ffa450edef68
2005-05-13 14:52:42 +00:00
2261 changed files with 266517 additions and 172903 deletions

42
.ci/Jenkinsfile vendored
View File

@ -1,42 +0,0 @@
properties(
[
disableConcurrentBuilds()
]
)
node('linux && docker') {
try {
stage('Checkout') {
//branch name from Jenkins environment variables
echo "My branch is: ${env.BRANCH_NAME}"
// this doesn't grab tags pointing to this branch
//checkout scm
// this hack does... https://issues.jenkins.io/browse/JENKINS-45164
checkout([
$class: 'GitSCM',
branches: [[name: 'refs/heads/'+env.BRANCH_NAME]],
extensions: [[$class: 'CloneOption', noTags: false, shallow: false, depth: 0, reference: '']],
userRemoteConfigs: scm.userRemoteConfigs,
])
sh '''
set -euxo pipefail
git checkout "$BRANCH_NAME" --
git reset --hard "origin/$BRANCH_NAME"
'''
}
stage('Build + Deploy') {
sh 'curl --compressed -sL https://code.moparisthebest.com/moparisthebest/self-ci/raw/branch/master/build-ci.sh | bash'
}
currentBuild.result = 'SUCCESS'
} catch (Exception err) {
currentBuild.result = 'FAILURE'
} finally {
stage('Email') {
step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: 'admin.jenkins@moparisthebest.com', sendToIndividuals: true])
}
deleteDir()
}
}

View File

@ -1,36 +0,0 @@
#!/bin/bash
set -euxo pipefail
# Java 14+ java.lang.Record is ambiguous with hssf.Record :'(
[ $JAVA_VERSION -lt 7 -o $JAVA_VERSION -gt 13 ] && echo "build does not support JAVA_VERSION: $JAVA_VERSION" && exit 0
echo "starting build for JAVA_VERSION: $JAVA_VERSION"
# grab all deps with java 8
[ $JAVA_VERSION -eq 7 ] && run-java 8 mvn dependency:go-offline
# install deps
mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
if [ $JAVA_VERSION -lt 12 ]
then
# clean and test
mvn clean test -B
else
# clean and test
mvn clean test -B -Djava.version=7 # java12+ minimum target is 7, not 6
fi
# publish only from java 6 and master branch
if [ "$BRANCH_NAME" == "master" -a $JAVA_VERSION -eq 7 ]
then
echo 'deploying to maven'
# java 7 cannot do modern SSL, use java 8 to deploy
run-java 8 mvn deploy -Dmaven.test.skip=true -B
mkdir -p release
find -type f -name '*.jar' -print0 | xargs -0n1 -I {} mv '{}' 'release/'
fi
echo 'build success!'
exit 0

16
.cvsignore Normal file
View File

@ -0,0 +1,16 @@
dist
scripts
*.el
*.ipr
*.iws
*.iml
build.number
log*.*
*.log
build
.classpath
.project
workbook.xls
bak
classes
untitled1.jpx

22
.gitignore vendored
View File

@ -1,22 +0,0 @@
classes
workbook.xls
bak
*.iws
build.number
*.el
TEST-org.apache.poi*.xml
build
.settings
scripts
*.ipr
untitled1.jpx
*.iml
log*.*
dist
*.log
bin
.ant-targets-build.xml
out
.idea
.gradle
target

29
KEYS Normal file
View File

@ -0,0 +1,29 @@
pub 1024D/12DAE9BE 2004-01-25 Glen Stampoultzis <glens@apache.org>
sig 3 12DAE9BE 2004-01-25 Glen Stampoultzis <glens@apache.org>
sub 1024g/2BBB28EA 2004-01-25
sig 12DAE9BE 2004-01-25 Glen Stampoultzis <glens@apache.org>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.2 (Cygwin)
mQGiBEATU6gRBACo3iUkfku4/G2q8ldWFiiCekHK5oqx0U1N6fyO+Xgs+6V6btEZ
drF2DUCyto6ig4FJT81L34HUQ6l9bPnpa4nNsl2EMBknY42LjmC55x7Q5rsQbiRj
+2JkoQJk2Jc3hneuh4Wsv49stOCDQMOV5BtjZs31t7rr+wuKPMkIw/Nf1wCgngI9
ZWFyLxspoi9bL1/xBID18jsD/RxGBep4F8HwXEdHTeHnmjEuJSlYhmAKQ6Fd7bdb
ex16a54Gsg7fVD0rIIsytzVUACQMi7V6tmE4Wf/XaY7+ma5w4gCsxUCIeujU4Y7i
WUDwtlTkr2IudmoxSIDDpS12NPZqCP7PbU2RK+KwnnITjs80a+QlHYaO9te7HVcL
F6YIA/9YZkYp5TpoMO1ISnlv0gXMcIaznbNMoRgeXZHvYyEvy014jArHmG41LVBj
6TnBHFLQi4xA7Ql98oIgfszaRr/9GshvoL6Iu1x1SoV7dMrqFBC6e2JD9N/IgBtZ
EGg7US3nIJnlCjJSIkXKfPJL4FyYWwt6IEZcF6Mi/USsyLA6wrQkR2xlbiBTdGFt
cG91bHR6aXMgPGdsZW5zQGFwYWNoZS5vcmc+iFsEExECABsFAkATU6gGCwkIBwMC
AxUCAwMWAgECHgECF4AACgkQONrI4hLa6b48RgCaAqQg0wtiOQ8jqX6S7tZi1OMg
CQAAn2Ty1d/UdGLqlGkCPMkaB6otTMhZuQENBEATU6kQBADUbn5pT2D8vi64RU5E
SeTn/rNzLglJ4nzoOfeIcHm7p3hppjT0Q1YbHvdOSaigYApzxoiSf+0Mt8NSCfDf
B/wjfndHlrcdPkiJi4fBkQHihcuJtEgOkAwXfSJ+MUXG+fEgEuGdYm7tNV3n/eOY
gn9Vzs/LofrQ7nY3+WkNOUia/wADBwQAnqZ4wPm0VY/fjCWJ34wvSfPk6Qg8m502
MfHIGY/UZ+BY5DK3iQR8hrIu6FU0tn0qoF7PCNehOtd2cR9kA7I2gyfaVR8JY2Ek
F18jungrNRrNuNx3rJeUD6ViQjC44K4vf6y8CkxmkHTmB9ZC2+uGdMeOdDvbck/u
JA+XB2tykJWIRgQYEQIABgUCQBNTqQAKCRA42sjiEtrpvpy3AJ4trdVLGCzJwB2R
Z/zxD3xBnTdY5QCeNUdw2VcsrzAF541sawFRxOmL3eY=
=la1N
-----END PGP PUBLIC KEY BLOCK-----

3
NOTICE Normal file
View File

@ -0,0 +1,3 @@
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).

View File

@ -1,24 +0,0 @@
POI Fast Calc
======================
[![Build Status](https://ci.moparisthe.best/job/moparisthebest/job/poi/job/master/badge/icon%3Fstyle=plastic)](https://ci.moparisthe.best/job/moparisthebest/job/poi/job/master/)
A Java library to calculate Excel formulas quickly.
This is a fork of [Apache POI](https://poi.apache.org/) version [3.16](https://github.com/apache/poi/tree/REL_3_16_FINAL)
that serves simply to calculate formulas quickly, it supports XLSX (Excel 2007) row/column limits in the HSSF engine for
much faster evaluation than XML-backed XSSF is capable of, with the drawback that it can't read or write XLS/XLSX files
from or to disk. Read the [email thread](https://lists.apache.org/thread.html/0bc90a3ed386edddfcb9b93ce6c262ad145a6b0433d0fcfe70ef10a2@%3Cdev.poi.apache.org%3E)
with my original proposed patch to upstream poi for background.
To use, add this to your maven pom.xml:
```xml
<dependency>
<groupId>com.moparisthebest.poi</groupId>
<artifactId>poi-fast-calc</artifactId>
<version>3.16-SNAPSHOT</version>
</dependency>
```
The `org.apache.poi` package has been renamed `com.moparisthebest.poi` and all dependencies removed,
so this can cleanly live aside modern/newer upstream poi forever, and shouldn't ever need to change.

5271
ant.dtd Normal file

File diff suppressed because it is too large Load Diff

928
build.xml Normal file
View File

@ -0,0 +1,928 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE project PUBLIC "-//Ant//Project 1.5//EN" "ant.dtd">
<!--
POI Build System. Written by:
Glen Stampoultzis glens at apache.org
Modified by:
Rainer Klute klute@rainer-klute.de
This build was tested with ant 1.6.2 although it will probably work with
other versions. The following jar files should be available on the
classpath when running ant:
LIBRARY LOCATION
======= ========
junit(3.8+) http://www.ibiblio.org/maven/junit/jars/
xerces http://www.ibiblio.org/maven/xerces/jars/
jdepend http://www.ibiblio.org/maven/jdepend/jars/
xalan http://www.ibiblio.org/maven/xalan/jars/
The ant jar "optional.jar" should also be available otherwise the
build will fail.
To build the documentation you will need to install forrest and set
the FORREST_HOME environment variable. Forrest 0.5.1 required.
TO BE COMPLETED:
Convert book.xml files to a sitemap.
-->
<project name="POI Build" default="help" basedir=".">
<description>
The POI project Ant build.
</description>
<property environment="env"/>
<property name="repository" value="http://www.ibiblio.org/maven"/>
<property name="forrest.home" value="${env.FORREST_HOME}"/>
<!-- Main: -->
<property name="main.resource1.dir" value="src/resources/fontmetrics"/>
<property name="main.src" location="src/java"/>
<property name="main.src.test" location="src/testcases"/>
<property name="main.documentation" value="src/documentation"/>
<property name="main.output.dir" location="build/classes"/>
<property name="main.output.test.dir" location="build/test-classes"/>
<property name="main.lib" location="lib"/>
<property name="main.reports.test" location="build/test-results"/>
<property name="main.jar1.dir" location="${main.lib}/commons-logging-1.0.1.jar"/>
<property name="main.jar1.url" value="${repository}/commons-logging/jars/commons-logging-1.0.1.jar"/>
<property name="main.jar2.dir" location="${main.lib}/log4j-1.2.8.jar"/>
<property name="main.jar2.url" value="${repository}/log4j/jars/log4j-1.2.8.jar"/>
<property name="main.testokfile" location="build/main-testokfile.txt"/>
<!-- Scratchpad: -->
<property name="scratchpad.src" location="src/scratchpad/src"/>
<property name="scratchpad.src.test" location="src/scratchpad/testcases"/>
<property name="scratchpad.lib" location="src/scratchpad/lib"/>
<property name="scratchpad.reports.test" location="build/scratchpad-test-results"/>
<property name="scratchpad.output.dir" location="build/scratchpad-classes"/>
<property name="scratchpad.output.test.dir" location="build/scratchpad-test-classes"/>
<property name="scratchpad.testokfile" location="build/scratchpad-testokfile.txt"/>
<!-- Contributed software: -->
<property name="contrib.src" location="src/contrib/src"/>
<property name="contrib.src.test" location="src/contrib/testcases"/>
<property name="contrib.lib" location="src/contrib/lib"/>
<property name="contrib.reports.test" location="build/contrib-test-results"/>
<property name="contrib.output.dir" location="build/contrib-classes"/>
<property name="contrib.output.test.dir" location="build/contrib-test-classes"/>
<property name="contrib.jar1.dir" location="${contrib.lib}/commons-beanutils-1.6.jar"/>
<property name="contrib.jar1.url" value="${repository}/commons-beanutils/jars/commons-beanutils-1.6.jar"/>
<property name="contrib.jar2.dir" location="${contrib.lib}/commons-collections-2.1.jar"/>
<property name="contrib.jar2.url" value="${repository}/commons-collections/jars/commons-collections-2.1.jar"/>
<property name="contrib.jar3.dir" location="${contrib.lib}/commons-lang-1.0-b1.jar"/>
<property name="contrib.jar3.url" value="${repository}/commons-lang/jars/commons-lang-1.0-b1.jar"/>
<property name="contrib.testokfile" location="build/contrib-testokfile.txt"/>
<!-- Examples: -->
<property name="examples.src" location="src/examples/src"/>
<property name="examples.src.test" location="src/examples/testcases"/>
<property name="examples.lib" location="src/examples/lib"/>
<property name="examples.reports.test" location="build/examples-test-results"/>
<property name="examples.output.dir" location="build/examples-classes"/>
<property name="examples.output.test.dir" location="build/examples-test-classes"/>
<property name="examples.jar1.dir" location="${examples.lib}/commons-beanutils-1.6.jar"/>
<property name="examples.jar1.url" value="${repository}/commons-beanutils/jars/commons-beanutils-1.6.jar"/>
<property name="examples.jar2.dir" location="${examples.lib}/commons-collections-2.1.jar"/>
<property name="examples.jar2.url" value="${repository}/commons-collections/jars/commons-collections-2.1.jar"/>
<property name="examples.jar3.dir" location="${examples.lib}/commons-lang-1.0-b1.jar"/>
<property name="examples.jar3.url" value="${repository}/commons-lang/jars/commons-lang-1.0-b1.jar"/>
<property name="examples.testokfile" location="build/examples-testokfile.txt"/>
<property name="junit.jar1.dir" location="${main.lib}/junit-3.8.1.jar"/>
<property name="junit.jar1.url" value="${repository}/junit/jars/junit-3.8.1.jar"/>
<property name="build.site" location="build/tmp/site/build/site"/>
<property name="build.site.src" location="build/tmp/site"/>
<property name="junit.report.dir" location="${build.site}/junit"/>
<property name="jdepend.report.dir" location="${build.site}/jdepend"/>
<property name="jdepend.report.out.dir" location="${build.site.src}/src/documentation/content/jdepend"/>
<property name="apidocs.report.dir" location="${build.site}/apidocs"/>
<property name="changelog.file" location="${build.site}/changelog.html"/>
<property name="dist.dir" location="build/dist"/>
<property name="jar.name" value="poi"/>
<property name="version.id" value="2.1"/>
<property name="halt.on.test.failure" value="true"/>
<path id="main.classpath">
<pathelement location="${main.jar1.dir}"/>
<pathelement location="${main.jar2.dir}"/>
<pathelement location="${main.resource1.dir}"/>
</path>
<path id="scratchpad.classpath">
<path refid="main.classpath"/>
<pathelement location="${main.output.dir}"/>
</path>
<path id="contrib.classpath">
<path refid="main.classpath"/>
<pathelement location="${contrib.jar1.dir}"/>
<pathelement location="${contrib.jar2.dir}"/>
<pathelement location="${contrib.jar3.dir}"/>
<pathelement location="${main.output.dir}"/>
<pathelement location="${main.output.test.dir}"/>
<pathelement location="${scratchpad.output.dir}"/>
<pathelement location="${scratchpad.output.test.dir}"/>
<pathelement location="${contrib.output.dir}"/>
<pathelement location="${contrib.output.test.dir}"/>
</path>
<path id="examples.classpath">
<path refid="main.classpath"/>
<pathelement location="${main.output.dir}"/>
</path>
<!-- Prints POI's Ant usage help -->
<target name="help" description="Prints POI's Ant usage help">
<echo>
- Execute "ant -projecthelp" to view a listing of the main build
targets.
- Execute "ant help-properties" to view a listing of some properties
controlling the build process.
</echo>
</target>
<target name="help-properties"
description="Prints a listing of build controlling properties">
<echo>
The following properties control the build process:
-Ddisconnected="true": Do not execute any targets that require an online
connection to the Internet.
WARNING: This list is not exhaustive.
</echo>
</target>
<target name="with.clover" if="clover.present">
<taskdef resource="clovertasks"/>
<clover-setup initString="mycoverage.db"/>
</target>
<target name="clover.html" depends="with.clover" if="clover.present">
<echo>Generating clover report</echo>
<clover-report>
<current outfile="build/tmp/site/build/site/clover_html">
<format type="html"/>
</current>
</clover-report>
</target>
<target name="init" depends="check-jars,fetch-jars">
<tstamp>
<format property="tstamp.year" pattern="yyyy"/>
</tstamp>
<available resource="clovertasks" property="clover.present"/>
<antcall target="with.clover"/>
<mkdir dir="build"/>
<mkdir dir="${main.output.dir}"/>
<mkdir dir="${scratchpad.output.dir}"/>
<mkdir dir="${contrib.output.dir}"/>
<mkdir dir="${examples.output.dir}"/>
<mkdir dir="${main.output.test.dir}"/>
<mkdir dir="${contrib.output.test.dir}"/>
<mkdir dir="${scratchpad.output.test.dir}"/>
<mkdir dir="${main.reports.test}"/>
<mkdir dir="${scratchpad.reports.test}"/>
<mkdir dir="${contrib.reports.test}"/>
<mkdir dir="${junit.report.dir}"/>
<mkdir dir="${jdepend.report.dir}"/>
<mkdir dir="${jdepend.report.out.dir}"/>
<mkdir dir="${apidocs.report.dir}"/>
<mkdir dir="${dist.dir}"/>
<mkdir dir="${build.site.src}/${main.documentation}"/>
<copy todir="${build.site.src}/${main.documentation}">
<fileset dir="${main.documentation}"/>
</copy>
<copy file="forrest.properties" tofile="${build.site.src}/forrest.properties"/>
</target>
<target name="clean">
<delete dir="build"/>
</target>
<target name="check-jars">
<condition property="jars.present">
<or>
<and>
<available file="${main.jar1.dir}"/>
<available file="${main.jar2.dir}"/>
<available file="${contrib.jar1.dir}"/>
<available file="${contrib.jar2.dir}"/>
<available file="${contrib.jar3.dir}"/>
<available file="${junit.jar1.dir}"/>
</and>
<isset property="disconnected"/>
</or>
</condition>
</target>
<target name="fetch-jars" unless="jars.present"
description="Fetches needed JAR files from the Internet">
<get src="${main.jar1.url}" dest="${main.jar1.dir}"/>
<get src="${main.jar2.url}" dest="${main.jar2.dir}"/>
<get src="${contrib.jar1.url}" dest="${contrib.jar1.dir}"/>
<get src="${contrib.jar2.url}" dest="${contrib.jar2.dir}"/>
<get src="${contrib.jar3.url}" dest="${contrib.jar3.dir}"/>
<get src="${junit.jar1.url}" dest="${junit.jar1.dir}"/>
</target>
<target name="compile" depends="init, compile-main, compile-scratchpad,
compile-contrib, compile-examples"
description="Compiles the POI main classes, scratchpad, contrib, and examples"/>
<target name="compile-main" depends="init">
<copy todir="${main.output.dir}">
<fileset dir="${main.resource1.dir}"/>
</copy>
<javac srcdir="${main.src}" destdir="${main.output.dir}" debug="on" fork="yes" includeAntRuntime="no" failonerror="true">
<classpath refid="main.classpath"/>
</javac>
<javac srcdir="${main.src.test}" destdir="${main.output.test.dir}" debug="on" fork="yes" includeAntRuntime="no" failonerror="true">
<classpath>
<path refid="main.classpath"/>
<pathelement location="${main.output.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
</javac>
</target>
<target name="compile-scratchpad" depends="init">
<javac srcdir="${scratchpad.src}" destdir="${scratchpad.output.dir}" debug="on" fork="yes" includeAntRuntime="no" failonerror="true">
<classpath refid="scratchpad.classpath"/>
</javac>
<javac srcdir="${scratchpad.src.test}" destdir="${scratchpad.output.test.dir}" debug="on" fork="yes" includeAntRuntime="no" failonerror="true">
<classpath>
<path refid="scratchpad.classpath"/>
<pathelement location="${scratchpad.output.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
</javac>
</target>
<target name="compile-contrib" depends="init">
<javac srcdir="${contrib.src}" destdir="${contrib.output.dir}" debug="on" fork="yes" includeAntRuntime="no" failonerror="true">
<classpath refid="contrib.classpath"/>
</javac>
<javac srcdir="${contrib.src.test}" destdir="${contrib.output.test.dir}" debug="on" fork="yes" includeAntRuntime="no" failonerror="true">
<classpath>
<path refid="contrib.classpath"/>
<pathelement location="${contrib.output.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
</javac>
</target>
<target name="compile-examples" depends="init">
<javac srcdir="${examples.src}" destdir="${examples.output.dir}" debug="on">
<classpath refid="examples.classpath"/>
</javac>
</target>
<target name="test" depends="test-main,test-scratchpad,test-contrib"
description="Tests main, contrib and scratchpad"/>
<target name="-test-main-check">
<uptodate property="main.test.notRequired" targetfile="${main.testokfile}">
<srcfiles dir="${main.src}"/>
<srcfiles dir="${main.src.test}"/>
</uptodate>
</target>
<path id="test.classpath">
<path refid="main.classpath"/>
<pathelement location="${main.output.dir}"/>
<pathelement location="${main.output.test.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</path>
<target
name="test-main"
depends="compile-main, -test-main-check, is-available-junit"
unless="main.test.notRequired">
<junit printsummary="no" showoutput="true" fork="no"
haltonfailure="${halt.on.test.failure}" failureproperty="main.test.failed">
<classpath refid="test.classpath"/>
<sysproperty key="HSSF.testdata.path" file="${main.src.test}/org/apache/poi/hssf/data"/>
<sysproperty key="HPSF.testdata.path" file="${main.src.test}/org/apache/poi/hpsf/data"/>
<sysproperty key="java.awt.headless" value="true"/>
<formatter type="plain"/>
<formatter type="xml"/>
<batchtest todir="${main.reports.test}">
<fileset dir="${main.src.test}">
<include name="**/Test*.java"/>
<exclude name="**/AllTests.java"/>
<exclude name="**/TestEmptyDocument.java"/>
<exclude name="**/TestUnfixedBugs.java"/>
</fileset>
</batchtest>
</junit>
<delete file="${main.testokfile}"/>
<antcall target="-test-main-write-testfile"/>
</target>
<target name="test-fail" depends = "compile-main, is-available-junit" description="run tests that are known to fail">
<junit printsummary="yes" showoutput="true" filtertrace="no" haltonfailure="false" >
<classpath refid="test.classpath"/>
<classpath>
<path refid="scratchpad.classpath"/>
<pathelement location="${main.output.dir}"/>
<pathelement location="${scratchpad.output.dir}"/>
<pathelement location="${scratchpad.output.test.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
<sysproperty key="HSSF.testdata.path" file="${main.src.test}/org/apache/poi/hssf/data"/>
<sysproperty key="HPSF.testdata.path" file="${main.src.test}/org/apache/poi/hpsf/data"/>
<sysproperty key="HWPF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hwpf/data"/>
<sysproperty key="java.awt.headless" value="true"/>
<formatter type="plain" usefile="no"/>
<batchtest todir="${main.reports.test}">
<fileset dir="${main.src.test}">
<include name="**/TestEmptyDocument.java"/>
<include name="**/TestUnfixedBugs.java"/>
</fileset>
</batchtest>
</junit>
</target>
<target name="single-test" depends="-test-property-check,compile-main" description="Runs a single test case specified with -Dtestcase=classname">
<junit printsummary="yes" showoutput="true" filtertrace="no" haltonfailure="false" >
<classpath refid="test.classpath"/>
<classpath>
<path refid="scratchpad.classpath"/>
<pathelement location="${main.output.dir}"/>
<pathelement location="${scratchpad.output.dir}"/>
<pathelement location="${scratchpad.output.test.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
<sysproperty key="HSSF.testdata.path" file="${main.src.test}/org/apache/poi/hssf/data"/>
<sysproperty key="HPSF.testdata.path" file="${main.src.test}/org/apache/poi/hpsf/data"/>
<sysproperty key="HWPF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hwpf/data"/>
<sysproperty key="java.awt.headless" value="true"/>
<formatter type="plain" usefile="no"/>
<formatter type="xml"/>
<test name="${testcase}"/>
</junit>
</target>
<target name="debug-test" depends="-test-property-check,compile-main" description="Runs a single test case specified with -Dtestcase=classname with remote debug options turned on." >
<junit printsummary="no" showoutput="true" filtertrace="no" fork="yes" haltonfailure="${halt.on.test.failure}" failureproperty="main.test.failed">
<jvmarg value="-Xdebug"/>
<jvmarg value="-Xrunjdwp:transport=dt_socket,address=5001,server=y,suspend=y"/>
<sysproperty key="java.compiler" value="NONE"/>
<classpath refid="test.classpath"/>
<sysproperty key="HSSF.testdata.path" file="${main.src.test}/org/apache/poi/hssf/data"/>
<sysproperty key="HPSF.testdata.path" file="${main.src.test}/org/apache/poi/hpsf/data"/>
<sysproperty key="java.awt.headless" value="true"/>
<formatter type="plain" usefile="no"/>
<test name="${testcase}"/>
</junit>
</target>
<target name="-test-property-check" unless="testcase">
<echo message="Please use -Dtestcase=org.your.testcase to run a single test"/>
<fail/>
</target>
<target name="-test-main-write-testfile" unless="main.test.failed">
<echo file="${main.testokfile}" append="false" message="testok"/>
</target>
<target name="-test-scratchpad-check">
<uptodate property="scratchpad.test.notRequired" targetfile="${scratchpad.testokfile}">
<srcfiles dir="${scratchpad.src}"/>
<srcfiles dir="${scratchpad.src.test}"/>
</uptodate>
</target>
<target name="test-scratchpad" depends="compile-scratchpad,-test-scratchpad-check" unless="scratchpad.test.notRequired">
<junit printsummary="no" fork="no" haltonfailure="${halt.on.test.failure}" failureproperty="scratchpad.test.failed">
<classpath>
<path refid="scratchpad.classpath"/>
<pathelement location="${main.output.dir}"/>
<pathelement location="${scratchpad.output.dir}"/>
<pathelement location="${scratchpad.output.test.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
<sysproperty key="HSSF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hssf/data"/>
<sysproperty key="HPSF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hpsf/data"/>
<sysproperty key="HDF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hdf/data"/>
<sysproperty key="HWPF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hwpf/data"/>
<sysproperty key="java.awt.headless" value="true"/>
<formatter type="plain"/>
<formatter type="xml"/>
<batchtest todir="${scratchpad.reports.test}">
<fileset dir="${scratchpad.src.test}">
<include name="**/Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
<delete file="${scratchpad.testokfile}"/>
<antcall target="-test-scratchpad-write-testfile"/>
</target>
<target name="-test-scratchpad-write-testfile" unless="scratchpad.test.failed">
<echo file="${scratchpad.testokfile}" append="false" message="testok"/>
</target>
<target name="-test-contrib-check">
<uptodate property="contrib.test.notRequired" targetfile="${contrib.testokfile}">
<srcfiles dir="${contrib.src}"/>
<srcfiles dir="${contrib.src.test}"/>
</uptodate>
</target>
<target name="test-contrib" depends="compile-contrib,-test-contrib-check" unless="contrib.test.notRequired">
<junit printsummary="yes" fork="no" haltonfailure="${halt.on.test.failure}" failureproperty="contrib.test.failed">
<classpath>
<path refid="contrib.classpath"/>
<pathelement location="${main.output.dir}"/>
<pathelement location="${contrib.output.dir}"/>
<pathelement location="${contrib.output.test.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
<sysproperty key="HSSF.testdata.path" file="${contrib.src.test}/org/apache/poi/hssf/data"/>
<sysproperty key="HPSF.testdata.path" file="${contrib.src.test}/org/apache/poi/hpsf/data"/>
<sysproperty key="java.awt.headless" value="true"/>
<formatter type="plain"/>
<formatter type="xml"/>
<batchtest todir="${contrib.reports.test}">
<fileset dir="${contrib.src.test}">
<include name="**/Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
<delete file="${contrib.testokfile}"/>
<antcall target="-test-contrib-write-testfile"/>
</target>
<target name="-test-contrib-write-testfile" unless="contrib.test.failed">
<echo file="${contrib.testokfile}" append="false" message="testok"/>
</target>
<target name="-check-docs">
<uptodate property="main.docs.notRequired" targetfile="${build.site}/index.html">
<srcfiles dir="${build.site.src}"/>
</uptodate>
</target>
<target name="-check-forrest-installed" unless="env.FORREST_HOME">
<echo>Please install Apache Forrest (see
&lt;http://xml.apache.org/forrest/index.html&gt;) and set the
FORREST_HOME environment variable!</echo>
<fail message="Apache Forrest is not installed."/>
</target>
<!-- <target name="check-docs">-->
<!-- <uptodate property="main.docs.notRequired" targetfile="${build.site}/index.html" >-->
<!-- <srcfiles dir= "${build.site.src}"/>-->
<!-- </uptodate>-->
<!-- </target>-->
<target name="docs" depends="init, -check-forrest-installed, -check-docs"
unless="main.docs.notRequired" description="Builds the POI website">
<mkdir dir="${build.site.src}/src/documentation/content/apidocs"/>
<copy todir="${build.site.src}/src/documentation/content/apidocs">
<fileset dir="${apidocs.report.dir}"/>
</copy>
<copy
tofile="${build.site.src}/src/documentation/content/jdepend.ehtml"
file="${jdepend.report.dir}/index.html" failonerror="false"/>
<mkdir dir="${build.site.src}/src/documentation/content/junit"/>
<copy todir="${build.site.src}/src/documentation/content/junit">
<fileset dir="${junit.report.dir}"/>
</copy>
<move
file="${build.site.src}/src/documentation/content/xdocs/status.xml"
tofile="${build.site.src}/status.xml"/>
<ant antfile="${forrest.home}/forrest.antproxy.xml" target="site">
<property name="project.home" location="${build.site.src}"/>
</ant>
<echo>Broken links:</echo>
<echo file="${build.site}/../tmp/brokenlinks.txt"/>
<touch>
<fileset dir="${build.site}"/>
</touch>
</target>
<!-- Checks whether reports are required to be run. If nothing has changed then they dont. -->
<target name="-check-reports">
<condition property="reports.notRequired">
<and>
<equals arg1="${main.test.notRequired}" arg2="true"/>
<equals arg1="${scratchpad.test.notRequired}" arg2="true"/>
<equals arg1="${contrib.test.notRequired}" arg2="true"/>
</and>
</condition>
</target>
<!-- Generates a log of the latest changes in the CVS repository. -->
<target name="cvschangelog" unless="disconnected" depends="is-available-xslt"
description="Generates a CVS change log report">
<antcall target="cvs-rsh-warning"/>
<cvschangelog destfile="${changelog.file}" daysinpast="30"/>
<style in="${changelog.file}"
out="${build.site.src}/src/documentation/content/changelog.html"
style="changelog.xsl">
<param name="title" expression="POI Change Log"/>
<param name="module" expression="jakarta-poi"/>
<param name="cvsweb" expression="http://cvs.apache.org/viewcvs/"/>
</style>
</target>
<target name="cvs-rsh-warning" unless="env.CVS_RSH">
<echo>
WARNING: The environment variable CVS_RSH is not set. If you cannot
access the CVS repository this could be one of the reasons for the
failure.
</echo>
</target>
<!-- Creates reports and API documentation -->
<target name="reports" unless="reports.notRequired" depends="-check-reports,
is-available-xslt, is-available-junit, is-available-jdepend,
test-ignore-failures, junitreport, jdepend, cvschangelog, javadocs,
clover.html"
description="Creates various reports and the API documentation">
</target>
<!-- Runs all JUnit tests without aborting if one of the tests fails. -->
<target name="test-ignore-failures" depends="init">
<antcall target="test">
<param name="halt.on.test.failure" value="false"/>
</antcall>
</target>
<!-- Produces a report of the JUnit test results -->
<target name="junitreport" depends="is-available-xslt, test-ignore-failures"
description="Produces a report of the JUnit test results">
<junitreport todir="${junit.report.dir}">
<fileset dir="${main.reports.test}">
<include name="TEST-*.xml"/>
</fileset>
<fileset dir="${scratchpad.reports.test}">
<include name="TEST-*.xml"/>
</fileset>
<fileset dir="${contrib.reports.test}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${junit.report.dir}"/>
</junitreport>
</target>
<!-- Generates the API documentation. -->
<target name="javadocs" depends="init"
description="Generates the API documentation">
<javadoc
destdir="${apidocs.report.dir}"
author="true"
version="true"
use="true"
verbose="false"
windowtitle="POI API Documentation">
<packageset dir="${main.src}" defaultexcludes="yes">
<include name="org/apache/poi/**"/>
</packageset>
<packageset dir="${scratchpad.src}" defaultexcludes="yes">
<include name="org/apache/poi/**"/>
</packageset>
<packageset dir="${contrib.src}" defaultexcludes="yes">
<include name="org/apache/poi/**"/>
</packageset>
<packageset dir="${examples.src}" defaultexcludes="yes">
<include name="org/apache/poi/**"/>
</packageset>
<classpath>
<path refid="main.classpath"/>
<path refid="scratchpad.classpath"/>
<path refid="contrib.classpath"/>
<path refid="examples.classpath"/>
</classpath>
<doctitle><![CDATA[<h1>POI API Documentation</h1>]]></doctitle>
<bottom>
<![CDATA[<i>Copyright ${tstamp.year} The Apache Software Foundation or
its licensors, as applicable.</i>]]>
</bottom>
<group title="HDF" packages="org.apache.poi.hdf*"/>
<group title="HPSF" packages="org.apache.poi.hpsf*"/>
<group title="HSSF" packages="org.apache.poi.hssf*"/>
<group title="HWPF" packages="org.apache.poi.hwpf*"/>
<group title="POIFS" packages="org.apache.poi.poifs*"/>
<group title="Record Generator" packages="org.apache.poi.record*"/>
<group title="Utils" packages="org.apache.poi.util*"/>
<group>
<title>Examples</title>
<package name="org.apache.poi.hpsf.examples*"/>
<package name="org.apache.poi.hssf.usermodel.examples*"/>
</group>
</javadoc>
<antcall target="clover.html"/>
</target>
<!-- ================================== -->
<!-- Generate records -->
<!-- ================================== -->
<target name="generate-records" depends="init"
description="Generates HSSF records">
<java classname="org.apache.poi.dev.RecordGenerator" fork="yes">
<arg location="src/records/definitions"/>
<arg location="src/records/styles"/>
<arg location="src/java"/>
<arg location="src/testcases"/>
<classpath>
<path refid="scratchpad.classpath">
</path>
<pathelement location="${main.output.dir}"/>
<pathelement location="${scratchpad.output.dir}"/>
</classpath>
</java>
</target>
<!-- ================================== -->
<!-- Generate types -->
<!-- ================================== -->
<target name="generate-types" depends="init"
description="Generates word types">
<java classname="org.apache.poi.dev.RecordGenerator" fork="yes">
<arg location="src/types/definitions"/>
<arg location="src/types/styles"/>
<arg location="src/scratchpad/src"/>
<arg location="src/scratchpad/testcases"/>
<classpath>
<path refid="scratchpad.classpath">
</path>
<pathelement location="${main.output.dir}"/>
<pathelement location="${scratchpad.output.dir}"/>
</classpath>
</java>
</target>
<!-- Generates documentation and reports -->
<target name="site" depends="reports, docs"
description="Generates POI's website's contents"/>
<target name="jar" depends="compile" description="Creates jar files for distribution">
<jar basedir="${main.output.dir}" destfile="${dist.dir}/${jar.name}-${version.id}-${DSTAMP}.jar">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<section name="common">
<attribute name="Specification-Title" value="Jakarta POI"/>
<attribute name="Specification-Version" value="${version.id}-${DSTAMP}"/>
<attribute name="Specification-Vendor" value="Apache"/>
<attribute name="Implementation-Title" value="Jakarta POI"/>
<attribute name="Implementation-Version" value="${version.id}-${DSTAMP}"/>
<attribute name="Implementation-Vendor" value="Apache"/>
</section>
</manifest>
</jar>
<jar basedir="${contrib.output.dir}" destfile="${dist.dir}/${jar.name}-contrib-${version.id}-${DSTAMP}.jar">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<section name="common">
<attribute name="Specification-Title" value="Jakarta POI"/>
<attribute name="Specification-Version" value="${version.id}-${DSTAMP}"/>
<attribute name="Specification-Vendor" value="Apache"/>
<attribute name="Implementation-Title" value="Jakarta POI"/>
<attribute name="Implementation-Version" value="${version.id}-${DSTAMP}"/>
<attribute name="Implementation-Vendor" value="Apache"/>
</section>
</manifest>
</jar>
<jar basedir="${scratchpad.output.dir}" destfile="${dist.dir}/${jar.name}-scratchpad-${version.id}-${DSTAMP}.jar">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<section name="common">
<attribute name="Specification-Title" value="Jakarta POI"/>
<attribute name="Specification-Version" value="${version.id}-${DSTAMP}"/>
<attribute name="Specification-Vendor" value="Apache"/>
<attribute name="Implementation-Title" value="Jakarta POI"/>
<attribute name="Implementation-Version" value="${version.id}-${DSTAMP}"/>
<attribute name="Implementation-Vendor" value="Apache"/>
</section>
</manifest>
</jar>
</target>
<target name="dist" depends="compile,site,jar" description="Creates the entire distribution into build/dist">
<zip destfile="${dist.dir}/${jar.name}-bin-${version.id}-${DSTAMP}.zip">
<zipfileset dir="${build.site}" prefix="docs"/>
<zipfileset file="${dist.dir}/${jar.name}-${version.id}-${DSTAMP}.jar"/>
<zipfileset file="${dist.dir}/${jar.name}-contrib-${version.id}-${DSTAMP}.jar"/>
<zipfileset file="${dist.dir}/${jar.name}-scratchpad-${version.id}-${DSTAMP}.jar"/>
<zipfileset dir="legal" prefix="legal"/>
</zip>
<zip destfile="${dist.dir}/${jar.name}-src-${version.id}-${DSTAMP}.zip">
<zipfileset dir="${build.site}" prefix="docs"/>
<zipfileset dir=".">
<exclude name="build/**"/>
<exclude name="scripts/**"/>
<exclude name="*.ipr"/>
<exclude name="*.iml"/>
<exclude name="*.iws"/>
</zipfileset>
</zip>
<tar destfile="${dist.dir}/${jar.name}-bin-${version.id}-${DSTAMP}.tar.gz" compression="gzip">
<tarfileset dir="${build.site}" prefix="docs"/>
<tarfileset file="${dist.dir}/${jar.name}-${version.id}-${DSTAMP}.jar"/>
<tarfileset file="${dist.dir}/${jar.name}-contrib-${version.id}-${DSTAMP}.jar"/>
<tarfileset file="${dist.dir}/${jar.name}-scratchpad-${version.id}-${DSTAMP}.jar"/>
<tarfileset dir="legal" prefix="legal"/>
</tar>
<tar destfile="${dist.dir}/${jar.name}-src-${version.id}-${DSTAMP}.tar.gz" compression="gzip">
<tarfileset dir="${build.site}" prefix="docs"/>
<tarfileset dir=".">
<exclude name="build/**"/>
<exclude name="scripts/**"/>
<exclude name="*.ipr"/>
<exclude name="*.iml"/>
<exclude name="*.iws"/>
</tarfileset>
</tar>
<echo>Distribution located in build/dist</echo>
</target>
<target name="clean-compile" depends="clean,compile"/>
<target name="clean-dist" depends="clean,dist"
description="Cleans the build directory then creates a distribution"/>
<target name="gump" depends="test,jar"/>
<!-- Generates the ANT document type definition (DTD) -->
<target name="dtd"
description="Generates the Ant document type definition (DTD)">
<antstructure output="ant.dtd"/>
</target>
<!-- Still experimental targets: -->
<!-- Abort the build if JUnit is missing. -->
<target name="is-available-junit" depends="init">
<condition property="isAvailable.junit">
<available classname="junit.framework.TestCase"/>
</condition>
<antcall target="check-junit"/>
</target>
<target name="check-junit" unless="isAvailable.junit">
<echo>
JUnit is not available. You must download JUnit from
&lt;http://www.junit.org/&gt; and include the JAR file in your
classpath.
</echo>
<fail message="JUnit is not available."/>
</target>
<!-- Abort the build if JDepend is missing. -->
<target name="is-available-jdepend" depends="init">
<condition property="isAvailable.jdepend">
<available classname="jdepend.framework.JDepend"/>
</condition>
<antcall target="check-jdepend"/>
</target>
<target name="check-jdepend" unless="isAvailable.jdepend">
<echo>
JDepend is not available. You must download JDepend from
&lt;http://www.clarkware.com/software/JDepend.html&gt; and include the
JAR file in your classpath.
</echo>
<fail message="JDepend is not available."/>
</target>
<!-- Abort the build if the Xalan XSLT processor is missing. The
"junitreport" task seems to explicitly require Xalan instead of being
able to cope with any XSLT processor. -->
<target name="is-available-xslt" depends="init">
<condition property="isAvailable.xslt">
<and>
<available
classname="javax.xml.transform.TransformerFactory"/>
<available
classname="org.apache.xalan.processor.TransformerFactoryImpl"/>
</and>
</condition>
<antcall target="check-xslt"/>
</target>
<target name="check-xslt" unless="isAvailable.xslt">
<echo>
The Xalan XSLT processor is not available. You must download Xalan from
&lt;http://xml.apache.org/xalan-j/&gt; and include the JAR file in your
classpath.
</echo>
<fail message="The Xalan XSLT processor is not available."/>
</target>
<!-- Runs jdepend to produce a report about package dependencies -->
<target name="jdepend" depends="is-available-jdepend"
description="Runs jdepend to produce a report about package dependencies">
<jdepend outputfile="${jdepend.report.dir}/jdepend.xml" format="xml">
<classespath>
<pathelement location="${main.output.dir}"/>
<pathelement location="${contrib.output.dir}"/>
<pathelement location="${scratchpad.output.dir}"/>
</classespath>
<classpath>
<path refid="main.classpath"/>
<path refid="contrib.classpath"/>
<path refid="scratchpad.classpath"/>
</classpath>
</jdepend>
<style basedir="${jdepend.report.dir}"
in="${jdepend.report.dir}/jdepend.xml"
out="${jdepend.report.out.dir}/index.html"
style="jdepend.xsl"/>
</target>
</project>
<!-- 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:
-->

144
changelog.xsl Normal file
View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<xsl:stylesheet
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
version='1.0'>
<!--
/* ====================================================================
Copyright 2003-2004 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.
==================================================================== */
-->
<xsl:param name="title"/>
<xsl:param name="module"/>
<xsl:param name="cvsweb"/>
<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
<!-- Copy standard document elements. Elements that
should be ignored must be filtered by apply-templates
tags. -->
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="attribute::*[. != '']"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="changelog">
<HTML>
<HEAD>
<TITLE><xsl:value-of select="$title"/></TITLE>
</HEAD>
<BODY link="#000000" alink="#000000" vlink="#000000" text="#000000">
<style type="text/css">
body, p {
font-family: verdana,arial,helvetica;
font-size: 100%;
color:#000000;
}
.dateAndAuthor {
font-family: verdana,arial,helvetica;
font-size: 100%;
font-weight: bold;
text-align:left;
background:#a6caf0;
}
tr, td{
font-family: verdana,arial,helvetica;
font-size: 120%;
background:#eeeee0;
}
</style>
<h1>
<a name="top"><xsl:value-of select="$title"/></a>
</h1>
<hr size="2"/>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="3" CELLSPACING="1">
<xsl:apply-templates select=".//entry">
<xsl:sort select="date" data-type="text" order="descending"/>
<xsl:sort select="time" data-type="text" order="descending"/>
</xsl:apply-templates>
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="entry">
<TR>
<TD colspan="2" class="dateAndAuthor">
<xsl:value-of select="date"/><xsl:text> </xsl:text><xsl:value-of select="time"/><xsl:text> </xsl:text><xsl:value-of select="author"/>
</TD>
</TR>
<TR>
<TD width="20">
<xsl:text> </xsl:text>
</TD>
<TD>
<pre>
<xsl:apply-templates select="msg"/></pre>
<ul>
<xsl:apply-templates select="file"/>
</ul>
</TD>
</TR>
</xsl:template>
<xsl:template match="date">
<i><xsl:value-of select="."/></i>
</xsl:template>
<xsl:template match="time">
<i><xsl:value-of select="."/></i>
</xsl:template>
<xsl:template match="author">
<i>
<a>
<xsl:attribute name="href">mailto:<xsl:value-of select="."/></xsl:attribute>
<xsl:value-of select="."/>
</a>
</i>
</xsl:template>
<xsl:template match="file">
<li>
<a>
<xsl:choose>
<xsl:when test="string-length(prevrevision) = 0 ">
<xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" />?rev=<xsl:value-of select="revision" />&amp;content-type=text/x-cvsweb-markup</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" />?r1=<xsl:value-of select="revision" />&amp;r2=<xsl:value-of select="prevrevision"/></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="name" /> (<xsl:value-of select="revision"/>)
</a>
</li>
</xsl:template>
<!-- Any elements within a msg are processed,
so that we can preserve HTML tags. -->
<xsl:template match="msg">
<b><xsl:apply-templates/></b>
</xsl:template>
</xsl:stylesheet>

96
forrest.properties Normal file
View File

@ -0,0 +1,96 @@
##############
# Properties used by forrest.build.xml for building the website
##############
# Prints out a summary of Forrest settings for this project
#forrest.echo=true
# Project name (used to name .war file)
#project.name=my-project
# Specifies name of Forrest skin to use
#project.skin=forrest-site
#project.skin=avalon-tigris
#project.skin=krysalis-site
project.skin=poi-site
##############
# layout properties
# Properties that must be set to override the default locations
#
# Parent properties must be set. This usually means uncommenting
# project.content-dir if any other property using it is uncommented
#project.status=status.xml
#project.content-dir=src/documentation
#project.conf-dir=${project.content-dir}/conf
#project.sitemap=${project.content-dir}/sitemap.xmap
#project.xdocs-dir=${project.content-dir}/content/xdocs
#project.stylesheets-dir=${project.content-dir}/resources/stylesheets
#project.images-dir=${project.content-dir}/resources/images
#project.schema-dir=${project.content-dir}/resources/schema
#project.skins-dir=${project.content-dir}/skins
#project.skinconf=${project.content-dir}/skinconf.xml
#project.lib-dir=${project.content-dir}/lib
#project.classes-dir=${project.content-dir}/classes
##############
# Cocoon catalog entity resolver properties
# A local catalog to supplement the default Forrest catalog
#project.catalog=${project.schema-dir}/catalog
# The verbosity level for the entity resolver (1..10)
#forrest.catalog.verbosity=1
##############
# validation properties
# These props determine if validation is performed at all
# Values are inherited unless overridden.
# Eg, if forrest.validate=false, then all others are false unless set to true.
#forrest.validate=true
#forrest.validate.xdocs=${forrest.validate}
#forrest.validate.skinconf=${forrest.validate}
#forrest.validate.sitemap=${forrest.validate}
#forrest.validate.stylesheets=${forrest.validate}
#forrest.validate.skins=${forrest.validate}
#forrest.validate.skins.stylesheets=${forrest.validate.skins}
# Key:
# *.failonerror=(true|false) stop when an XML file is invalid
# *.includes=(pattern) Comma-separated list of path patterns to validate
# *.excludes=(pattern) Comma-separated list of path patterns to not validate
#forrest.validate.failonerror=true
#forrest.validate.includes=**/*
#forrest.validate.excludes=
#
#forrest.validate.xdocs.failonerror=${forrest.validate.failonerror}
#
#forrest.validate.xdocs.includes=**/*.x*
#forrest.validate.xdocs.excludes=site.xml
#
#forrest.validate.skinconf.includes=${skinconf-file}
#forrest.validate.skinconf.excludes=
#forrest.validate.skinconf.failonerror=${forrest.validate.failonerror}
#
#forrest.validate.sitemap.includes=${sitemap-file}
#forrest.validate.sitemap.excludes=
#forrest.validate.sitemap.failonerror=${forrest.validate.failonerror}
#
#forrest.validate.stylesheets.includes=**/*.xsl
#forrest.validate.stylesheets.excludes=
#forrest.validate.stylesheets.failonerror=${forrest.validate.failonerror}
#
#forrest.validate.skins.includes=**/*
#forrest.validate.skins.excludes=**/*.xsl
#forrest.validate.skins.failonerror=${forrest.validate.failonerror}
#
#forrest.validate.skins.stylesheets.includes=**/*.xsl
#forrest.validate.skins.stylesheets.excludes=
#forrest.validate.skins.stylesheets.failonerror=${forrest.validate.skins.failonerror}

277
jdepend.xsl Normal file
View File

@ -0,0 +1,277 @@
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--
/* ====================================================================
Copyright 2003-2004 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.
==================================================================== */
-->
<xsl:output method="html" indent="yes"/>
<xsl:template match="JDepend">
<html>
<head>
<title>JDepend Analysis</title>
<style type="text/css">
body {
font:normal 68% verdana,arial,helvetica;
color:#000000;
}
table tr td, tr th {
font-size: 68%;
}
table.details tr th{
font-weight: bold;
text-align:left;
background:#a6caf0;
}
table.details tr td{
background:#eeeee0;
}
p {
line-height:1.5em;
margin-top:0.5em; margin-bottom:1.0em;
margin-left:2em;
margin-right:2em;
}
h1 {
margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
}
h2 {
margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
}
h3 {
margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
}
h4 {
margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
}
h5 {
margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
}
h6 {
margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
}
.Error {
font-weight:bold; color:red;
}
.Failure {
font-weight:bold; color:purple;
}
.Properties {
text-align:right;
}
</style>
</head>
<body>
<!--h1>JDepend Report</h1>
<ul>
<xsl:for-each select="./Packages/Package">
<xsl:sort select="@name"/>
<li><xsl:value-of select="@name"/></li>
</xsl:for-each>
</ul-->
<h1><a name="top">JDepend Analysis</a></h1>
<p align="right">Designed for use with <a href="http://www.clarkware.com/software/JDepend.html">JDepend</a> and <a href="http://jakarta.apache.org">Ant</a>.</p>
<hr size="2" />
<table width="100%"><tr><td>
<a name="NVsummary"><h2>Summary</h2></a>
</td><td align="right">
[<a href="#NVsummary">summary</a>]
[<a href="#NVpackages">packages</a>]
[<a href="#NVcycles">cycles</a>]
[<a href="#NVexplanations">explanations</a>]
</td></tr></table>
<table width="100%" class="details">
<tr>
<th>Package</th>
<th>Total Classes</th>
<th><a href="#EXnumber">Abstract Classes</a></th>
<th><a href="#EXnumber">Concrete Classes</a></th>
<th><a href="#EXafferent">Afferent Couplings</a></th>
<th><a href="#EXefferent">Efferent Couplings</a></th>
<th><a href="#EXabstractness">Abstractness</a></th>
<th><a href="#EXinstability">Instability</a></th>
<th><a href="#EXdistance">Distance</a></th>
</tr>
<xsl:for-each select="./Packages/Package">
<xsl:if test="count(error) = 0">
<tr>
<td align="left">
<a>
<xsl:attribute name="href">#PK<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:value-of select="@name"/>
</a>
</td>
<td align="right"><xsl:value-of select="Stats/TotalClasses"/></td>
<td align="right"><xsl:value-of select="Stats/AbstractClasses"/></td>
<td align="right"><xsl:value-of select="Stats/ConcreteClasses"/></td>
<td align="right"><xsl:value-of select="Stats/Ca"/></td>
<td align="right"><xsl:value-of select="Stats/Ce"/></td>
<td align="right"><xsl:value-of select="Stats/A"/></td>
<td align="right"><xsl:value-of select="Stats/I"/></td>
<td align="right"><xsl:value-of select="Stats/D"/></td>
</tr>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="./Packages/Package">
<xsl:if test="count(error) &gt; 0">
<tr>
<td align="left">
<xsl:value-of select="@name"/>
</td>
<td align="left" colspan="8"><xsl:value-of select="error"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
<table width="100%"><tr><td>
<a name="NVpackages"><h2>Packages</h2></a>
</td><td align="right">
[<a href="#NVsummary">summary</a>]
[<a href="#NVpackages">packages</a>]
[<a href="#NVcycles">cycles</a>]
[<a href="#NVexplanations">explanations</a>]
</td></tr></table>
<xsl:for-each select="./Packages/Package">
<xsl:if test="count(error) = 0">
<h3><a><xsl:attribute name="name">PK<xsl:value-of select="@name"/></xsl:attribute>
<xsl:value-of select="@name"/></a></h3>
<table width="100%"><tr>
<td><a href="#EXafferent">Afferent Couplings</a>: <xsl:value-of select="Stats/Ca"/></td>
<td><a href="#EXefferent">Efferent Couplings</a>: <xsl:value-of select="Stats/Ce"/></td>
<td><a href="#EXabstractness">Abstractness</a>: <xsl:value-of select="Stats/A"/></td>
<td><a href="#EXinstability">Instability</a>: <xsl:value-of select="Stats/I"/></td>
<td><a href="#EXdistance">Distance</a>: <xsl:value-of select="Stats/D"/></td>
</tr></table>
<table width="100%" class="details">
<tr>
<th>Abstract Classes</th>
<th>Concrete Classes</th>
<th>Used by Packages</th>
<th>Uses Packages</th>
</tr>
<tr>
<td valign="top" width="25%">
<xsl:if test="count(AbstractClasses/Class)=0">
<i>None</i>
</xsl:if>
<xsl:for-each select="AbstractClasses/Class">
<xsl:value-of select="node()"/><br/>
</xsl:for-each>
</td>
<td valign="top" width="25%">
<xsl:if test="count(ConcreteClasses/Class)=0">
<i>None</i>
</xsl:if>
<xsl:for-each select="ConcreteClasses/Class">
<xsl:value-of select="node()"/><br/>
</xsl:for-each>
</td>
<td valign="top" width="25%">
<xsl:if test="count(UsedBy/Package)=0">
<i>None</i>
</xsl:if>
<xsl:for-each select="UsedBy/Package">
<a>
<xsl:attribute name="href">#PK<xsl:value-of select="node()"/></xsl:attribute>
<xsl:value-of select="node()"/>
</a><br/>
</xsl:for-each>
</td>
<td valign="top" width="25%">
<xsl:if test="count(DependsUpon/Package)=0">
<i>None</i>
</xsl:if>
<xsl:for-each select="DependsUpon/Package">
<a>
<xsl:attribute name="href">#PK<xsl:value-of select="node()"/></xsl:attribute>
<xsl:value-of select="node()"/>
</a><br/>
</xsl:for-each>
</td>
</tr>
</table>
</xsl:if>
</xsl:for-each>
<table width="100%"><tr><td>
<a name="NVcycles"><h2>Cycles</h2></a>
</td><td align="right">
[<a href="#NVsummary">summary</a>]
[<a href="#NVpackages">packages</a>]
[<a href="#NVcycles">cycles</a>]
[<a href="#NVexplanations">explanations</a>]
</td></tr></table>
<xsl:if test="count(Cycles/Package) = 0">
<p>There are no cyclic dependancies.</p>
</xsl:if>
<xsl:for-each select="Cycles/Package">
<h3><xsl:value-of select="@Name"/></h3><p>
<xsl:for-each select="Package">
<xsl:value-of select="."/><br/>
</xsl:for-each></p>
</xsl:for-each>
<table width="100%"><tr><td>
<a name="NVexplanations"><h2>Explanations</h2></a>
</td><td align="right">
[<a href="#NVsummary">summary</a>]
[<a href="#NVpackages">packages</a>]
[<a href="#NVcycles">cycles</a>]
[<a href="#NVexplanations">explanations</a>]
</td></tr></table>
<p>The following explanations are for quick reference and are lifted directly from the original <a href="http://www.clarkware.com/software/JDepend.html">JDepend documentation</a>.</p>
<h3><a name="EXnumber">Number of Classes</a></h3>
<p>The number of concrete and abstract classes (and interfaces) in the package is an indicator of the extensibility of the package.</p>
<h3><a name="EXafferent">Afferent Couplings</a></h3>
<p>The number of other packages that depend upon classes within the package is an indicator of the package's responsibility. </p>
<h3><a name="EXefferent">Efferent Couplings</a></h3>
<p>The number of other packages that the classes in the package depend upon is an indicator of the package's independence. </p>
<h3><a name="EXabstractness">Abstractness</a></h3>
<p>The ratio of the number of abstract classes (and interfaces) in the analyzed package to the total number of classes in the analyzed package. </p>
<p>The range for this metric is 0 to 1, with A=0 indicating a completely concrete package and A=1 indicating a completely abstract package. </p>
<h3><a name="EXinstability">Instability</a></h3>
<p>The ratio of efferent coupling (Ce) to total coupling (Ce / (Ce + Ca)). This metric is an indicator of the package's resilience to change. </p>
<p>The range for this metric is 0 to 1, with I=0 indicating a completely stable package and I=1 indicating a completely instable package. </p>
<h3><a name="EXdistance">Distance</a></h3>
<p>The perpendicular distance of a package from the idealized line A + I = 1. This metric is an indicator of the package's balance between abstractness and stability. </p>
<p>A package squarely on the main sequence is optimally balanced with respect to its abstractness and stability. Ideal packages are either completely abstract and stable (x=0, y=1) or completely concrete and instable (x=1, y=0). </p>
<p>The range for this metric is 0 to 1, with D=0 indicating a package that is coincident with the main sequence and D=1 indicating a package that is as far from the main sequence as possible. </p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

528
legal/LICENSE Normal file → Executable file
View File

@ -1,193 +1,5 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
/* ====================================================================
Copyright 2002-2004 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.
@ -200,338 +12,4 @@
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 POI SUBCOMPONENTS:
Apache POI includes subcomponents with separate copyright notices and
license terms. Your use of these subcomponents is subject to the terms
and conditions of the following licenses:
Office Open XML schemas (ooxml-schemas-1.*.jar)
The Office Open XML schema definitions used by Apache POI are
a part of the Office Open XML ECMA Specification (ECMA-376, [1]).
As defined in section 9.4 of the ECMA bylaws [2], this specification
is available to all interested parties without restriction:
9.4 All documents when approved shall be made available to
all interested parties without restriction.
Furthermore, both Microsoft and Adobe have granted patent licenses
to this work [3,4,5].
[1] http://www.ecma-international.org/publications/standards/Ecma-376.htm
[2] http://www.ecma-international.org/memento/Ecmabylaws.htm
[3] http://www.microsoft.com/openspecifications/en/us/programs/osp/default.aspx
[4] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/
Patent%20statements%20ok/ECMA-376%20Edition%202%20Microsoft%20Patent%20Declaration.pdf
[5] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/
Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf
Bouncy Castle library (bcprov-*.jar, bcpg-*.jar, bcpkix-*.jar)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
JUnit test library (junit-4.*.jar) & JaCoCo (*jacoco*)
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and documentation
distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates' from
a Contributor if it was added to the Program by such Contributor itself or
anyone acting on such Contributor's behalf. Contributions do not include
additions to the Program which: (i) are separate modules of software
distributed in conjunction with the Program under their own license agreement,
and (ii) are not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents" mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright license to
reproduce, prepare derivative works of, publicly display, publicly
perform, distribute and sublicense the Contribution of such Contributor,
if any, and such derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent license under
Licensed Patents to make, use, sell, offer to sell, import and otherwise
transfer the Contribution of such Contributor, if any, in source code
and object code form. This patent license shall apply to the combination
of the Contribution and the Program if, at the time the Contribution is
added by the Contributor, such addition of the Contribution causes such
combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Contribution.
No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses
to its Contributions set forth herein, no assurances are provided by any
Contributor that the Program does not infringe the patent or other
intellectual property rights of any other entity. Each Contributor
disclaims any liability to Recipient for claims brought by any other
entity based on infringement of intellectual property rights or
otherwise. As a condition to exercising the rights and licenses granted
hereunder, each Recipient hereby assumes sole responsibility to secure
any other intellectual property rights needed, if any. For example, if
a third party patent license is required to allow Recipient to distribute
the Program, it is Recipient's responsibility to acquire that license
before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright
license set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under
its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties and
conditions, express and implied, including warranties or conditions of
title and non-infringement, and implied warranties or conditions of
merchantability and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for
damages, including direct, indirect, special, incidental and
consequential damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are
offered by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such
Contributor, and informs licensees how to obtain it in a reasonable
manner on or through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained
within the Program.
Each Contributor must identify itself as the originator of its Contribution,
if any, in a manner that reasonably allows subsequent Recipients to identify
the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with
respect to end users, business partners and the like. While this license is
intended to facilitate the commercial use of the Program, the Contributor
who includes the Program in a commercial product offering should do so in a
manner which does not create potential liability for other Contributors.
Therefore, if a Contributor includes the Program in a commercial product
offering, such Contributor ("Commercial Contributor") hereby agrees to
defend and indemnify every other Contributor ("Indemnified Contributor")
against any losses, damages and costs (collectively "Losses") arising from
claims, lawsuits and other legal actions brought by a third party against
the Indemnified Contributor to the extent caused by the acts or omissions
of such Commercial Contributor in connection with its distribution of the
Program in a commercial product offering. The obligations in this section
do not apply to any claims or Losses relating to any actual or alleged
intellectual property infringement. In order to qualify, an Indemnified
Contributor must: a) promptly notify the Commercial Contributor in writing
of such claim, and b) allow the Commercial Contributor to control, and
cooperate with the Commercial Contributor in, the defense and any related
settlement negotiations. The Indemnified Contributor may participate in any
such claim at its own expense.
For example, a Contributor might include the Program in a commercial product
offering, Product X. That Contributor is then a Commercial Contributor. If
that Commercial Contributor then makes performance claims, or offers
warranties related to Product X, those performance claims and warranties are
such Commercial Contributor's responsibility alone. Under this section, the
Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a
court requires any other Contributor to pay any damages as a result, the
Commercial Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
appropriateness of using and distributing the Program and assumes all risks
associated with its exercise of rights under this Agreement , including but
not limited to the risks and costs of program errors, compliance with
applicable laws, damage to or loss of data, programs or equipment, and
unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of the
remainder of the terms of this Agreement, and without further action by the
parties hereto, such provision shall be reformed to the minimum extent
necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
(excluding combinations of the Program with other software or hardware)
infringes such Recipient's patent(s), then such Recipient's rights granted
under Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails to
comply with any of the material terms or conditions of this Agreement and
does not cure such failure in a reasonable period of time after becoming
aware of such noncompliance. If all Recipient's rights under this Agreement
terminate, Recipient agrees to cease use and distribution of the Program as
soon as reasonably practicable. However, Recipient's obligations under this
Agreement and any licenses granted by Recipient relating to the Program
shall continue and survive.
Everyone is permitted to copy and distribute copies of this Agreement, but
in order to avoid inconsistency the Agreement is copyrighted and may only
be modified in the following manner. The Agreement Steward reserves the
right to publish new versions (including revisions) of this Agreement from
time to time. No one other than the Agreement Steward has the right to
modify this Agreement. The Eclipse Foundation is the initial Agreement
Steward. The Eclipse Foundation may assign the responsibility to serve as
the Agreement Steward to a suitable separate entity. Each new version of
the Agreement will be given a distinguishing version number. The Program
(including Contributions) may always be distributed subject to the version
of the Agreement under which it was received. In addition, after a new
version of the Agreement is published, Contributor may elect to distribute
the Program (including its Contributions) under the new version. Except as
expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
rights or licenses to the intellectual property of any Contributor under
this Agreement, whether expressly, by implication, estoppel or otherwise.
All rights in the Program not expressly granted under this Agreement are
reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to this
Agreement will bring a legal action under this Agreement more than one year
after the cause of action arose. Each party waives its rights to a jury
trial in any resulting litigation.
Hamcrest library (hamcrest-*.jar) & CuvesAPI / Curve API
BSD License
Copyright (c) 2000-2006, www.hamcrest.org
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. Redistributions in binary
form must reproduce the above copyright notice, this list of conditions and
the following disclaimer in the documentation and/or other materials
provided with the distribution.
Neither the name of Hamcrest nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
SLF4J library (slf4j-api-*.jar)
Copyright (c) 2004-2013 QOS.ch
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
inbot-utils (https://github.com/Inbot/inbot-utils)
The MIT License (MIT)
Copyright (c) 2015 Inbot
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
==================================================================== */

48
legal/LICENSE.ant Normal file
View File

@ -0,0 +1,48 @@
/*
* ============================================================================
* The Apache Software License, Version 1.1
* ============================================================================
*
* Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment: "This product includes software
* developed by the Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Ant" and "Apache Software Foundation" must not be used to
* endorse or promote products derived from this software without prior
* written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache", nor may
* "Apache" appear in their name, without prior written permission of the
* Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
* DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* on behalf of the Apache Software Foundation. For more information on the
* Apache Software Foundation, please see <http://www.apache.org/>.
*
*/

15
legal/LICENSE.apache Executable file
View File

@ -0,0 +1,15 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */

View File

@ -0,0 +1,65 @@
/*
* $Header$
* $Revision$
* $Date$
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/

55
legal/LICENSE.xalan Normal file
View File

@ -0,0 +1,55 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

56
legal/LICENSE.xerces Normal file
View File

@ -0,0 +1,56 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

10
legal/LICENSE.xml-apis Normal file
View File

@ -0,0 +1,10 @@
xml-apis is covered by The Apache Software License, Version 1.1
FIXME: Put license text in here once it is available at
http://cvs.apache.org/viewcvs.cgi/xml-commons/

View File

@ -1,27 +0,0 @@
Apache POI
Copyright 2003-2017 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (https://www.apache.org/).
This product contains parts that were originally based on software from BEA.
Copyright (c) 2000-2003, BEA Systems, <http://www.bea.com/> (dead link),
which was acquired by Oracle Corporation in 2008.
<http://www.oracle.com/us/corporate/Acquisitions/bea/index.html>
<https://en.wikipedia.org/wiki/BEA_Systems>
This product contains W3C XML Schema documents. Copyright 2001-2003 (c)
World Wide Web Consortium (Massachusetts Institute of Technology, European
Research Consortium for Informatics and Mathematics, Keio University)
This product contains the Piccolo XML Parser for Java
(http://piccolo.sourceforge.net/). Copyright 2002 Yuval Oren.
This product contains the chunks_parse_cmds.tbl file from the vsdump program.
Copyright (C) 2006-2007 Valek Filippov (frob@df.ru)
This product contains parts of the eID Applet project
<http://eid-applet.googlecode.com> and <https://github.com/e-Contract/eid-applet>.
Copyright (c) 2009-2014
FedICT (federal ICT department of Belgium), e-Contract.be BVBA (https://www.e-contract.be),
Bart Hanssens from FedICT

1
lib/.cvsignore Normal file
View File

@ -0,0 +1 @@
*.jar

101
pom.xml
View File

@ -1,101 +0,0 @@
<?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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>9</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.moparisthebest.poi</groupId>
<artifactId>poi-fast-calc</artifactId>
<version>3.17-SNAPSHOT</version>
<packaging>jar</packaging>
<name>POI Fast Calc</name>
<url>https://code.moparisthebest.com/moparisthebest/poi</url>
<description>POI Fast Calc - Java API To Calculate Excel formulas quickly</description>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<organization>
<name>moparisthebest.com</name>
<url>https://www.moparisthebest.com</url>
</organization>
<scm>
<connection>scm:git:https://code.moparisthebest.com/moparisthebest/poi.git</connection>
<developerConnection>scm:git:https://code.moparisthebest.com/moparisthebest/poi.git</developerConnection>
<url>https://code.moparisthebest.com/moparisthebest/poi</url>
</scm>
<properties>
<java.version>1.6</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<pushChanges>false</pushChanges>
<localCheckout>true</localCheckout>
<!-- default argline for junit tests, java 9+ requires much less memory than 6/7/8, but more runs faster -->
<test.argLine>-Xmx4096m</test.argLine>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<argLine>${test.argLine}</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.5</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
</project>

0
src/.cvsignore Normal file
View File

View File

@ -0,0 +1 @@
*.jar

View File

@ -0,0 +1,316 @@
#Adapted from the Makefile for PyLucene, by the OSAF
# Makefile for building Poi4R
#
# Supported operating systems: Linux, Mac OS X and Windows.
# See INSTALL file for requirements.
#
# Steps to build
# 1. Edit the sections below as documented
# 2. make all
# 3. make install
#
# The install target installs the Poi4R python extension in python's
# site-packages directory. On Mac OS X, it also installs the gcj runtime
# libraries into $(PREFIX)/lib.
#
# To successfully import the Poi4R extension into Ruby, all required
# libraries need to be found. If the locations you chose are non-standard,
# the relevant DYLD_LIBRARY_PATH (Mac OS X), LD_LIBRARY_PATH (Linux), or
# PATH (Windows) need to be set accordingly.
#
#
#
VERSION=0.1.0
POI_VER=2.0-final-20040126
RUBY_VER=1.8
POI4R:=$(shell pwd)
POI=$(POI4R)/poi-$(POI_VER)
#DEBUG=1
#
# You need to uncomment and edit the variables below in the section
# corresponding to your operating system.
#
# PREFIX: where programs are normally installed on your system (Unix).
# PREFIX_RUBY: where your version of python is installed.
# GCJ_HOME: where GCC/GCJ is installed.
# Windows drive-absolute paths need to be expressed cygwin style.
#
# Mac OS X (Darwin)
#PREFIX=/usr/local
#PREFIX_RUBY=/Library/Frameworks/Ruby.framework/Versions/$(RUBY_VER)
#SWIG=$(PREFIX)/bin/swig
#GCJ_HOME=/usr/local/gcc-3.4.1
#DB=$(POI4R)/db-$(DB_VER)
#PREFIX_DB=/usr/local/BerkeleyDB.$(DB_LIB_VER)
# Linux
PREFIX=/usr
PREFIX_RUBY=$(PREFIX)
SWIG=$(PREFIX)/bin/swig
GCJ_HOME=/usr
#DB=$(POI4R)/db-$(DB_VER)
#PREFIX_DB=$(PREFIX)/BerkeleyDB.$(DB_LIB_VER)
# Windows
#PREFIX_RUBY=/cygdrive/o/Python-2.3.2
#SWIG=/cygdrive/c/utils/bin/swig.exe
#GCJ_HOME=/cygdrive/o/mingw-3.1
#DB=/cygdrive/o/db-$(DB_VER)
#PREFIX_DB=$(DB)
#
# No edits required below
#
OS=$(shell uname)
ifeq ($(findstring CYGWIN,$(OS)),CYGWIN)
OS=Cygwin
endif
ifeq ($(findstring WINNT,$(OS)),WINNT)
OS=Cygwin
endif
ifeq ($(DEBUG),1)
COMP_OPT=DEBUG=1
SUFFIX=d
_SUFFIX=_d
BINDIR=debug
else
COMP_OPT=
SUFFIX=
_SUFFIX=
BINDIR=release
endif
SWIG_OPT=-DSWIG_COBJECT_TYPES -DPOI4R_VER="'$(VERSION)'" -DPOI_VER="'$(POI_VER)'"
JCCFLAGS=--encoding=UTF-8
#JCCFLAGS=--encoding=UTF-8 -findirect-dispatch
ifeq ($(OS),Darwin)
RUBY_SITE=$(PREFIX_RUBY)/lib/ruby$(RUBY_VER)/site-packages
RUBY_INC=$(PREFIX_RUBY)/lib/ruby$(RUBY_VER)
POI4R=$(BINDIR)/poi4r.so
ifeq ($(DEBUG),1)
CCFLAGS=-O0 -g
LDFLAGS=-g
else
CCFLAGS=-O2
LDFLAGS=
endif
else
ifeq ($(OS),Linux)
RUBY_SITE=$(PREFIX_RUBY)/lib/ruby/site-ruby/$(RUBY_VER)/
RUBY_INC=$(PREFIX_RUBY)/lib/ruby/$(RUBY_VER)/i686-linux
POI4R_LIB=$(BINDIR)/poi4r.so
ifeq ($(DEBUG),1)
CCFLAGS=-O0 -g -fPIC
LDFLAGS=-g
else
CCFLAGS=-O2 -fPIC
LDFLAGS=
endif
else
ifeq ($(OS),Cygwin)
RUBY_SITE=`cygpath -aw $(PREFIX_RUBY)/Lib/site-packages`
RUBY_INC=`cygpath -aw $(PREFIX_RUBY)/Include`
RUBY_PC=`cygpath -aw $(PREFIX_RUBY)/PC`
POI4R_LIB=$(BINDIR)/poi4r$(_SUFFIX).so
ifeq ($(DEBUG),1)
CCFLAGS=-O -g
LDFLAGS=-g
else
CCFLAGS=-O2
LDFLAGS=
endif
else
RUBY=unknown
RUBY_SITE=unknown
endif
endif
endif
CLASSES=$(BINDIR)/classes
JAR_CLASSES=$(CLASSES)/jar
CC=$(GCJ_HOME)/bin/gcc
CXX=$(GCJ_HOME)/bin/g++
JCC=$(GCJ_HOME)/bin/gcj
JCCH=$(GCJ_HOME)/bin/gcjh
JAR=$(GCJ_HOME)/bin/jar
POI_ZIP=poi-$(POI_VER).jar
POI_JAR=poi-$(POI_VER).jar
POI4R_CP:=$(BINDIR)/$(POI_JAR):$(CLASSES)
OBJS=$(BINDIR)/poi.o $(BINDIR)/io.java.o $(BINDIR)/io.cpp.o
LIBS=$(POI4R_LIB)
default: all
patches:
env:
ifndef PREFIX_RUBY
@echo Operating system is $(OS)
@echo You need to edit that section of the Makefile
@false
else
@true
endif
$(BINDIR):
mkdir -p $(BINDIR)/classes/jar
DISTRIB=Poi-$(VERSION)
ifeq ($(OS),Cygwin)
POI4R_CP:=`cygpath -awp $(POI4R_CP)`
endif
ifeq ($(OS),Cygwin)
_poi=`cygpath -aw $(POI)`
else
_poi=$(POI)
endif
$(BINDIR)/$(POI_JAR):
cp $(POI4R)/$(POI_JAR) $(BINDIR)/$(POI_JAR)
cd $(JAR_CLASSES); $(JAR) -xf $(POI4R)/$(POI_JAR)
$(BINDIR)/io.java.o: java/org/apache/poi/RubyOutputStream.java
$(JCC) $(JCCFLAGS) -C -d $(CLASSES) java/org/apache/poi/RubyOutputStream.java
$(JCC) $(JCCFLAGS) $(CCFLAGS) -I$(GCJ_HOME)/include -c -o $@ java/org/apache/poi/RubyOutputStream.java
$(CLASSES)/org/apache/poi/RubyOutputStream.h: $(BINDIR)/io.java.o Makefile
mkdir -p $(CLASSES)/org/apache/poi/hssf/usermodel
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFWorkbook
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFSheet
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFRow
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFCell
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFHeader
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFFooter
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFFont
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFDataFormat
$(JCCH) -d $(CLASSES) --classpath=$(JAR_CLASSES) org.apache.poi.hssf.usermodel.HSSFCellStyle
$(JCCH) -d $(CLASSES) --classpath=$(CLASSES) org.apache.poi.RubyOutputStream
$(BINDIR)/io.cpp.o: $(CLASSES)/org/apache/poi/RubyOutputStream.h cpp/RubyIO.cpp $(BINDIR)/io.java.o
$(JCC) -I$(RUBY_INC) -I$(GCJ_HOME)/include -I$(CLASSES) $(CCFLAGS) -c -o $@ cpp/RubyIO.cpp
$(BINDIR)/poi.o: $(BINDIR)/$(POI_JAR)
$(JCC) $(JCCFLAGS) $(CCFLAGS) -c -o $@ $(BINDIR)/$(POI_JAR)
Poi4R_wrap.cxx: $(BINDIR)/io.cpp.o Poi4R.i
ifdef SWIG
$(SWIG) $(SWIG_OPT) -I$(CLASSES) -c++ -ruby Poi4R.i
endif
ifeq ($(OS),Darwin)
$(POI4R_LIB): $(OBJS) Poi4R_wrap.cxx
$(CXX) -shared -bundle -o $@ $(CCFLAGS) $(SWIG_OPT) $(DB_INC) -I$(GCJ_HOME)/include -I$(CLASSES) -I$(RUBY_INC) Poi4R_wrap.cxx $(OBJS) -L$(GCJ_HOME)/lib -lgcj -liconv -undefined suppress -flat_namespace -multiply_defined suppress
else
ifeq ($(OS),Linux)
$(POI4R_LIB): $(OBJS) Poi4R_wrap.cxx
$(CXX) -shared -o $@ $(CCFLAGS) $(SWIG_OPT) $(DB_INC) -I$(CLASSES) -I$(RUBY_INC) Poi4R_wrap.cxx $(OBJS) -lgcj
else
ifeq ($(OS),Cygwin)
$(POI4R_LIB): $(OBJS) Poi4R_wrap.cxx
$(CXX) -c $(CCFLAGS) $(PYDBG) -D_NO_OLDNAMES -D_off_t=off_t $(SWIG_OPT) $(DB_INC) -I$(CLASSES) -I$(RUBY_PC) -I$(RUBY_INC) -o $(BINDIR)/Poi4R_wrap.o Poi4R_wrap.cxx
$(CXX) -shared $(LDFLAGS) -o $@ $(OBJS) `cygpath -aw $(PREFIX_RUBY)/python23$(_SUFFIX).dll` $(BINDIR)/Poi4R_wrap.o -lgcj -lwin32k -lws2_32
endif
endif
endif
all: env $(BINDIR) $(LIBS)
@echo build of $(POI4R_LIB) complete
install:: all
install Poi4R.rb $(RUBY_SITE)
install $(POI4R_LIB) $(RUBY_SITE)
ifeq ($(OS),Darwin)
install::
install $(GCJ_HOME)/lib/libgcj.5.dylib $(PREFIX)/lib
install $(GCJ_HOME)/lib/libstdc++.6.dylib $(PREFIX)/lib
install $(GCJ_HOME)/lib/libgcc_s.1.0.dylib $(PREFIX)/lib
else
ifeq ($(OS),Linux)
install::
else
ifeq ($(OS),Cygwin)
install::
endif
endif
endif
clean:
rm -rf $(BINDIR) Poi4R.rb* Poi4R_wrap.cxx
realclean: clean
rm -rf $(POI) $(STORE) $(DISTRIB)
distrib::
mkdir -p $(DISTRIB)/python
install Poi4R.rb $(DISTRIB)/python
install $(POI4R_LIB) $(DISTRIB)/python
install README $(DISTRIB)
ifeq ($(OS),Darwin)
distrib::
ifdef DB
mkdir -p $(DISTRIB)/db
install $(LIBDB_JAVA_LIB) $(DISTRIB)/db
install libdb_java-$(DB_LIB_VER).la.osx $(DISTRIB)/db
endif
mkdir -p $(DISTRIB)/gcj
install $(GCJ_HOME)/lib/libgcj.5.dylib $(DISTRIB)/gcj
install $(GCJ_HOME)/lib/libstdc++.6.dylib $(DISTRIB)/gcj
install $(GCJ_HOME)/lib/libgcc_s.1.0.dylib $(DISTRIB)/gcj
else
ifeq ($(OS),Linux)
distrib::
ifdef DB
mkdir -p $(DISTRIB)/db
install $(LIBDB_JAVA_LIB) $(DISTRIB)/db
endif
mkdir -p $(DISTRIB)/gcj
install $(GCJ_HOME)/lib/libgcj.so.5 $(DISTRIB)/gcj
install $(GCJ_HOME)/lib/libstdc++.so.6 $(DISTRIB)/gcj
install $(GCJ_HOME)/lib/libgcc_s.so.1 $(DISTRIB)/gcj
else
ifeq ($(OS),Cygwin)
distrib::
ifdef DB
mkdir -p $(DISTRIB)/db
install $(LIBDB_JAVA_LIB) $(DISTRIB)/db
endif
endif
endif
endif

View File

@ -0,0 +1,613 @@
/* ====================================================================
Copyright 2005 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.
==================================================================== */
%module poi4r
%{
#include <gcj/cni.h>
#include <java/lang/Object.h>
#include <java/lang/Thread.h>
#include <java/lang/ThreadGroup.h>
#include <java/lang/Runnable.h>
#include <java/lang/String.h>
#include <java/lang/Throwable.h>
#include <java/lang/Comparable.h>
#include <java/lang/Integer.h>
#include <java/lang/Long.h>
#include <java/lang/Float.h>
#include <java/lang/Double.h>
#include <java/io/StringWriter.h>
#include <java/io/PrintWriter.h>
#include <java/util/Hashtable.h>
#include <java/util/Date.h>
#include <java/util/Calendar.h>
#include <java/lang/System.h>
#include "org/apache/poi/hssf/usermodel/HSSFWorkbook.h"
#include "org/apache/poi/hssf/usermodel/HSSFSheet.h"
#include "org/apache/poi/hssf/usermodel/HSSFRow.h"
#include "org/apache/poi/hssf/usermodel/HSSFCell.h"
#include "org/apache/poi/hssf/usermodel/HSSFFont.h"
#include "org/apache/poi/hssf/usermodel/HSSFCellStyle.h"
#include "org/apache/poi/hssf/usermodel/HSSFDataFormat.h"
#include "org/apache/poi/hssf/usermodel/HSSFHeader.h"
#include "org/apache/poi/hssf/usermodel/HSSFFooter.h"
#include "org/apache/poi/RubyOutputStream.h"
typedef ::org::apache::poi::hssf::usermodel::HSSFWorkbook *jhworkbook;
typedef ::org::apache::poi::hssf::usermodel::HSSFSheet *jhsheet;
typedef ::org::apache::poi::hssf::usermodel::HSSFRow *jhrow;
typedef ::org::apache::poi::hssf::usermodel::HSSFCell *jhcell;
typedef ::org::apache::poi::hssf::usermodel::HSSFCellStyle *jhcellstyle;
typedef ::org::apache::poi::hssf::usermodel::HSSFFont *jhfont;
typedef ::org::apache::poi::hssf::usermodel::HSSFFooter *jhfooter;
typedef ::org::apache::poi::hssf::usermodel::HSSFHeader *jhheader;
typedef ::org::apache::poi::hssf::usermodel::HSSFDataFormat *jhdataformat;
typedef ::java::util::Date *jdate;
typedef ::java::util::Calendar *jcalendar;
typedef ::java::io::OutputStream *joutputstream;
typedef ::java::io::InputStream *jinputstream;
typedef ::java::util::Collection *jstringCollection;
typedef ::java::util::Collection *jtermCollection;
typedef ::java::util::Locale *jlocale;
typedef ::java::lang::Comparable *jcomparable;
typedef JArray<jobject> *jobjectArray;
typedef JArray<jstring> *jstringArray;
static java::lang::Thread *nextThread;
static java::util::Hashtable *objects;
static void store_reference(jobject object) {
java::lang::Integer *ji =new java::lang::Integer(java::lang::System::identityHashCode(object));
jobject jo = objects->get(ji);
if (!jo) {
// printf("put object in hash\n");
objects->put(ji,object);
}
}
static VALUE jo2rv(jobject object, swig_type_info *descriptor)
{
if (object == NULL)
{
return Qnil;
}
else
{
return SWIG_NewPointerObj((void *) object, descriptor, 0);
}
}
static int cvtptr(VALUE value, void **jo, swig_type_info *info)
{
if (SWIG_ConvertPtr(value, jo, info, 0) == 0)
return 0;
else
{
return -1;
}
}
static int rv2jo(VALUE rv, jobject *jo, swig_type_info *descriptor)
{
if (NIL_P(rv))
*jo = NULL;
else
{
java::lang::Object *javaObj;
if (cvtptr(rv, (void **) &javaObj, descriptor) == -1)
return 0;
*jo = javaObj;
}
return 1;
}
static jstring r2j(VALUE object)
{
if (NIL_P(object)){
return NULL;
}
else {
char *ps = STR2CSTR(object);
jstring js = JvNewStringLatin1(ps);
if (!js)
{
rb_raise(rb_eRuntimeError, "ruby str cannot be converted to java: %s",ps);
}
return js;
}
}
VALUE j2r(jstring js)
{
if (!js)
{
return Qnil;
}
else
{
jint len = JvGetStringUTFLength(js);
char buf[len + 1];
JvGetStringUTFRegion(js, 0, len, buf);
buf[len] = '\0';
return rb_str_new2(buf);
}
}
static void free_java_obj(void* arg1) {
jobject object =(jobject) arg1;
java::lang::Integer *ji =new java::lang::Integer(java::lang::System::identityHashCode(object));
jobject jo = objects->get(ji);
if (jo) {
// printf("removed object from hash\n");
objects->remove(ji);
}
}
static void raise_ruby_error(java::lang::Throwable *e) {
java::io::StringWriter *buffer = new java::io::StringWriter();
java::io::PrintWriter *writer = new java::io::PrintWriter(buffer);
e->printStackTrace(writer);
writer->close();
jstring message = buffer->toString();
jint len = JvGetStringUTFLength(message);
char buf[len + 1];
JvGetStringUTFRegion(message, 0, len, buf);
buf[len] = '\0';
rb_raise(rb_eRuntimeError, "error calling poi \n %s", buf);
}
%}
typedef long jint;
typedef long long jlong;
typedef char jbyte;
typedef float jfloat;
typedef float jdouble;
typedef int jshort;
typedef bool jboolean;
%typemap(in) SWIGTYPE * {
if (!rv2jo($input, (jobject *) &$1, $1_descriptor))
rb_raise(rb_eRuntimeError, "Unrecoverable error in SWIG typemapping");
}
%typemap(out) SWIGTYPE * {
$result = jo2rv($1, $1_descriptor);
}
%typemap(in) org::apache::poi::hssf::usermodel::HSSFWorkbook{
if (!rv2jo($input, (jobject *) &$1,
$descriptor(org::apache::poi::hssf::usermodel::HSSFWorkbook *)))
SWIG_fail;
}
%typemap(out) org::apache::poi::hssf::usermodel::HSSFWorkbook {
$result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFWorkbook *));
}
%typemap(in) jhsheet{
if (!rv2jo($input, (jobject *) &$1,
$descriptor(org::apache::poi::hssf::usermodel::HSSFSheet *)))
SWIG_fail;
}
%typemap(out) jhsheet {
$result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFSheet *));
}
%typemap(in) jhrow{
if (!rv2jo($input, (jobject *) &$1,
$descriptor(org::apache::poi::hssf::usermodel::HSSFRow *)))
SWIG_fail;
}
%typemap(out) jhrow {
$result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFRow *));
}
%typemap(in) jhcell{
if (!rv2jo($input, (jobject *) &$1,
$descriptor(org::apache::poi::hssf::usermodel::HSSFCell *)))
SWIG_fail;
}
%typemap(out) jhcell {
$result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFCell *));
}
%typemap(in) jhfont{
if (!rv2jo($input, (jobject *) &$1,
$descriptor(org::apache::poi::hssf::usermodel::HSSFFont *)))
rb_raise(rb_eRuntimeError, "Unrecoverable error in SWIG typemapping of HSSFFont");
}
%typemap(out) jhfont {
$result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFFont *));
}
%typemap(in) jhcellstyle{
if (!rv2jo($input, (jobject *) &$1,
$descriptor(org::apache::poi::hssf::usermodel::HSSFCellStyle *)))
rb_raise(rb_eRuntimeError, "Unrecoverable error in SWIG typemapping of HSSFCellStyle");
}
%typemap(out) jhcellstyle {
$result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFCellStyle *));
}
%typemap(in) jhdataformat{
if (!rv2jo($input, (jobject *) &$1,
$descriptor(org::apache::poi::hssf::usermodel::HSSFDataFormat *)))
rb_raise(rb_eRuntimeError, "Unrecoverable error in SWIG typemapping of HSSFDataFormat");
}
%typemap(out) jhdataformat {
$result = jo2rv($1, $descriptor(org::apache::poi::hssf::usermodel::HSSFDataFormat *));
}
%typemap(in) jstring {
$1 = r2j($input);
}
%typemap(out) jstring {
$result = j2r($1);
}
%typecheck(SWIG_TYPECHECK_STRING) jstring {
$1 = ( NIL_P($input) || TYPE($input)==T_STRING );
}
%typemap(in) joutputstream {
jlong ptr;
if (!rb_respond_to($input, rb_intern("putc"))) rb_raise(rb_eTypeError,"Expected IO");
*(VALUE *) &ptr = (VALUE) $input;
$1 = new org::apache::poi::RubyOutputStream(ptr);
}
%typemap(in) jcalendar {
$1 = java::util::Calendar::getInstance();
//$1->setTimeInMillis((long long) NUM2DBL(rb_funcall($input,rb_intern("to_i"),0,NULL))*1000.0);
$1->set(FIX2INT(rb_funcall($input,rb_intern("year"),0,NULL)),
FIX2INT(rb_funcall($input,rb_intern("mon"),0,NULL))-1,
FIX2INT(rb_funcall($input,rb_intern("day"),0,NULL)),
FIX2INT(rb_funcall($input,rb_intern("hour"),0,NULL)),
FIX2INT(rb_funcall($input,rb_intern("min"),0,NULL)),
FIX2INT(rb_funcall($input,rb_intern("sec"),0,NULL))
);
}
%typecheck(SWIG_TYPECHECK_POINTER) jcalendar {
$1 = rb_respond_to($input, rb_intern("asctime"));
}
%typemap(out) jdate {
jlong t = ((jdate) $1)->getTime();
//TODO: separate seconds and microsecs
int ts=t/1000;
$result=rb_time_new((time_t) ts, 0 );
}
%freefunc org::apache::poi::hssf::usermodel::HSSFWorkbook "free_java_obj";
%exception {
try {
$action
} catch (java::lang::Throwable *e) {
raise_ruby_error(e);
}
}
%exception org::apache::poi::hssf::usermodel::HSSFWorkbook::HSSFWorkbook {
try {
$action
store_reference(result);
} catch (java::lang::Throwable *e) {
raise_ruby_error(e);
}
}
namespace java {
namespace lang {
class Object {
jstring toString();
};
%nodefault;
class System : public Object {
public:
static jstring getProperty(jstring);
static jstring getProperty(jstring, jstring);
static void load(jstring);
static void loadLibrary(jstring);
static void mapLibraryName(jstring);
static void runFinalization();
static void setProperty(jstring, jstring);
};
%makedefault;
}
namespace io {
%nodefault;
class InputStream : public ::java::lang::Object {
};
class OutputStream : public ::java::lang::Object {
};
%makedefault;
}
namespace util {
class Date : public ::java::lang::Object {
public:
Date();
Date(jlong);
void setTime(jlong);
jstring toString();
};
}
}
namespace org {
namespace apache {
namespace poi {
namespace hssf {
namespace usermodel {
%nodefault;
class HSSFWorkbook : public ::java::lang::Object {
public:
HSSFWorkbook();
jstring getSheetName(jint);
jint getNumberOfSheets();
void setSheetOrder(jstring,jint);
void setSheetName(jint,jstring);
void setSheetName(jint,jstring,jshort);
jint getSheetIndex(jstring);
jhsheet createSheet();
jhsheet cloneSheet(jint);
jhsheet createSheet(jstring);
jhsheet getSheetAt(jint);
jhsheet getSheet(jstring);
void removeSheetAt(jint);
jhcellstyle createCellStyle();
jhfont createFont();
jhdataformat createDataFormat();
void write(joutputstream);
};
class HSSFSheet : public ::java::lang::Object {
public:
jhrow createRow(jint);
jhrow getRow(jint);
jhfooter getFooter();
jhheader getHeader();
};
class HSSFRow : public ::java::lang::Object {
public:
jhcell createCell(jshort);
jhcell getCell(jshort);
//jboolean getProtect(); //only in 2.5
};
class HSSFCell : public ::java::lang::Object {
public:
void setCellValue(jdouble);
void setCellValue(jstring);
void setCellValue(jboolean);
void setCellValue(jcalendar);
void setCellFormula(jstring);
jstring getStringCellValue();
jdouble getNumericCellValue();
jdate getDateCellValue();
jstring getCellFormula();
jboolean getBooleanCellValue();
jint getCellType();
jshort getEncoding();
void setAsActiveCell();
void setCellStyle(jhcellstyle);
void setEncoding(jshort encoding);
static const jint CELL_TYPE_BLANK;
static const jint CELL_TYPE_BOOLEAN;
static const jint CELL_TYPE_ERROR;
static const jint CELL_TYPE_FORMULA;
static const jint CELL_TYPE_NUMERIC;
static const jint CELL_TYPE_STRING;
static const jshort ENCODING_COMPRESSED_UNICODE;
static const jshort ENCODING_UTF_16;
};
class HSSFCellStyle : public ::java::lang::Object {
public:
static const jshort ALIGN_CENTER;
static const jshort ALIGN_CENTER_SELECTION;
static const jshort ALIGN_FILL;
static const jshort ALIGN_GENERAL;
static const jshort ALIGN_JUSTIFY;
static const jshort ALIGN_LEFT;
static const jshort ALIGN_RIGHT;
static const jshort ALT_BARS;
static const jshort BIG_SPOTS;
static const jshort BORDER_DASH_DOT;
static const jshort BORDER_DASH_DOT_DOT;
static const jshort BORDER_DASHED;
static const jshort BORDER_DOTTED;
static const jshort BORDER_DOUBLE;
static const jshort BORDER_HAIR;
static const jshort BORDER_MEDIUM;
static const jshort BORDER_MEDIUM_DASH_DOT;
static const jshort BORDER_MEDIUM_DASH_DOT_DOT;
static const jshort BORDER_MEDIUM_DASHED;
static const jshort BORDER_NONE;
static const jshort BORDER_SLANTED_DASH_DOT;
static const jshort BORDER_THICK;
static const jshort BORDER_THIN;
static const jshort BRICKS;
static const jshort DIAMONDS;
static const jshort FINE_DOTS;
static const jshort NO_FILL;
static const jshort SOLID_FOREGROUND;
static const jshort SPARSE_DOTS;
static const jshort SQUARES;
static const jshort THICK_BACKWARD_DIAG;
static const jshort THICK_FORWARD_DIAG;
static const jshort THICK_HORZ_BANDS;
static const jshort THICK_VERT_BANDS;
static const jshort THIN_BACKWARD_DIAG;
static const jshort THIN_FORWARD_DIAG;
static const jshort THIN_HORZ_BANDS;
static const jshort THIN_VERT_BANDS;
static const jshort VERTICAL_BOTTOM;
static const jshort VERTICAL_CENTER;
static const jshort VERTICAL_JUSTIFY;
static const jshort VERTICAL_TOP;
jshort getAlignment();
jshort getBorderBottom();
jshort getBorderLeft();
jshort getBorderRight();
jshort getBorderTop();
jshort getBottomBorderColor();
jshort getDataFormat();
jshort getFillBackgroundColor();
jshort getFillForegroundColor();
jshort getFillPattern();
jshort getFontIndex();
jboolean getHidden();
jshort getIndention();
jshort getIndex();
jshort getLeftBorderColor();
jboolean getLocked();
jshort getRightBorderColor();
jshort getRotation();
jshort getTopBorderColor();
jshort getVerticalAlignment();
jboolean getWrapText();
void setAlignment(jshort) ;
void setBorderBottom(jshort );
void setBorderLeft(jshort );
void setBorderRight(jshort );
void setBorderTop(jshort );
void setBottomBorderColor(jshort );
void setDataFormat(jshort );
void setFillBackgroundColor(jshort );
void setFillForegroundColor(jshort );
void setFillPattern(jshort );
void setFont(jhfont );
void setHidden(jboolean );
void setIndention(jshort );
void setLeftBorderColor(jshort );
void setLocked(jboolean );
void setRightBorderColor(jshort );
void setRotation(jshort );
void setTopBorderColor(jshort );
void setVerticalAlignment(jshort );
void setWrapText(jboolean );
};
class HSSFDataFormat : public ::java::lang::Object {
public:
static jstring getBuiltinFormat(jshort);
static jshort getBuiltinFormat(jstring);
jstring getFormat(jshort);
jshort getFormat(jstring);
static jint getNumberOfBuiltinBuiltinFormats();
//TODO static jlist getBuiltinFormats();
};
class HSSFFont : public ::java::lang::Object {
public:
static const jshort BOLDWEIGHT_BOLD;
static const jshort BOLDWEIGHT_NORMAL;
static const jshort COLOR_NORMAL;
static const jshort COLOR_RED;
static const jstring FONT_ARIAL;
static const jshort SS_NONE;
static const jshort SS_SUB;
static const jshort SS_SUPER;
static const jshort U_DOUBLE;
static const jshort U_DOUBLE_ACCOUNTING;
static const jshort U_NONE;
static const jshort U_SINGLE;
static const jshort U_SINGLE_ACCOUNTING;
jshort getBoldweight();
jshort getColor();
jshort getFontHeight();
jshort getFontHeightInPoints();
jstring getFontName();
jshort getIndex();
jboolean getItalic();
jboolean getStrikeout();
jshort getTypeOffset();
jshort getUnderline();
void setBoldweight(jshort );
void setColor(jshort );
void setFontHeight(jshort );
void setFontHeightInPoints(jshort );
void setFontName(jstring );
void setItalic(jboolean );
void setStrikeout(jboolean );
void setTypeOffset(jshort );
void setUnderline(jshort );
};
%makedefault;
}
}
}
}
}
%init %{
JvCreateJavaVM(NULL);
JvAttachCurrentThread(NULL, NULL);
nextThread = new java::lang::Thread();
objects = new java::util::Hashtable();
java::util::Hashtable *props = (java::util::Hashtable *)
java::lang::System::getProperties();
props->put(JvNewStringUTF("inRuby"), objects);
JvInitClass(&org::apache::poi::hssf::usermodel::HSSFFont::class$);
JvInitClass(&org::apache::poi::hssf::usermodel::HSSFCell::class$);
JvInitClass(&org::apache::poi::hssf::usermodel::HSSFSheet::class$);
JvInitClass(&org::apache::poi::hssf::usermodel::HSSFCellStyle::class$);
%}

View File

@ -0,0 +1,43 @@
/* ====================================================================
Copyright 2005 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.
==================================================================== */
#include <gcj/cni.h>
#include "ruby.h"
#include "org/apache/poi/RubyOutputStream.h"
/**
* The native functions declared in org.apache.poi.RubyoutputStream
*
* @author aviks
*/
namespace org {
namespace apache {
namespace poi {
void RubyOutputStream::close(void)
{
rb_funcall3((VALUE ) rubyIO, rb_intern("close"), 0, NULL);
}
void RubyOutputStream::write(jint toWrite)
{
rb_funcall((VALUE ) rubyIO, rb_intern("putc"),1,INT2FIX(toWrite));
}
}
}
}

View File

@ -0,0 +1,58 @@
/* ====================================================================
Copyright 2005 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.
==================================================================== */
package org.apache.poi;
import java.io.OutputStream;
import java.io.IOException;
/**
* @author aviks
* Wrap a java.io.OutputStream around a Ruby IO object
*/
public class RubyOutputStream extends OutputStream {
//pointer to native ruby VALUE
protected long rubyIO;
public RubyOutputStream (long rubyIO)
{
this.rubyIO = rubyIO;
// incRef();
}
protected void finalize()
throws Throwable
{
// decRef();
}
// protected native void incRef();
// protected native void decRef();
public native void close()
throws IOException;
/* (non-Javadoc)
* @see java.io.OutputStream#write(int)
*/
public native void write(int arg0) throws IOException;
}

Binary file not shown.

View File

@ -0,0 +1,83 @@
require 'test/unit'
require 'release/poi4r'
class TC_base_tests < Test::Unit::TestCase
def setup()
end
def test_get_constant
h=Poi4r::HSSFWorkbook.new
s=h.createSheet("Sheet1")
r=s.createRow(0)
c=r.createCell(0)
assert_equal(3,Poi4r::HSSFCell.CELL_TYPE_BLANK,"Constant CELL_TYPE_BLANK")
end
def test_base
system("rm test.xls")
h=Poi4r::HSSFWorkbook.new
#Test Sheet Creation
s=h.createSheet("Sheet1")
s=h.createSheet("Sheet2")
assert_equal(2,h.getNumberOfSheets(),"Number of sheets is 2")
#Test setting cell values
s=h.getSheetAt(0)
r=s.createRow(0)
c=r.createCell(0)
c.setCellValue(1.5)
assert_equal(c.getNumericCellValue(),1.5,"Numeric Cell Value")
c=r.createCell(1)
c.setCellValue("Ruby")
assert_equal(c.getStringCellValue(),"Ruby","String Cell Value")
#Test error handling
assert_raise (RuntimeError) {c.getNumericCellValue()}
#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
assert_equal(t1.year,t2.year,"year")
assert_equal(t1.mon,t2.mon,"month")
assert_equal(t1.day,t2.day,"day")
assert_equal(t1.hour,t2.hour,"hour")
assert_equal(t1.min,t2.min,"min")
assert_equal(t1.sec,t2.sec,"sec")
st=h.createCellStyle();
st.setDataFormat(Poi4r::HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"))
c.setCellStyle(st)
#Fonts
c=r.createCell(4)
font = h.createFont();
font.setFontHeightInPoints(24);
font.setFontName("Courier New");
font.setItalic(true);
font.setStrikeout(true);
style = h.createCellStyle();
style.setFont(font);
c.setCellValue("This is a test of fonts");
c.setCellStyle(style);
#Formulas
c=r.createCell(5)
c.setCellFormula("A1*2")
assert_equal("A1*2",c.getCellFormula,"formula")
#Test writing
h.write(File.new("test.xls","w"))
assert_nothing_raised {File.new("test.xls","r")}
#h.write(0.1)
end
end

View File

@ -0,0 +1,15 @@
require 'test/unit'
require 'release/poi4r'
class TC_gc < Test::Unit::TestCase
def test_premature_collection
h=Poi4r::HSSFWorkbook.new
h.createSheet("Sheet1");
5000.times do
hh=Poi4r::HSSFWorkbook.new
GC.start()
end
assert_equal(1,h.getNumberOfSheets(),"Number of sheets")
end
end

View File

@ -0,0 +1,3 @@
require 'test/unit'
require 'tests/tc_base_tests'
require 'tests/tc_gc'

View File

@ -0,0 +1,82 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.metrics;
import java.awt.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class FontMetricsDumper
{
public static void main( String[] args ) throws IOException
{
Properties props = new Properties();
Font[] allFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for ( int i = 0; i < allFonts.length; i++ )
{
String fontName = allFonts[i].getFontName();
Font font = new Font(fontName, Font.BOLD, 10);
FontMetrics fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
int fontHeight = fontMetrics.getHeight();
props.setProperty("font." + fontName + ".height", fontHeight+"");
StringBuffer characters = new StringBuffer();
for (char c = 'a'; c <= 'z'; c++)
{
characters.append( c + ", " );
}
for (char c = 'A'; c <= 'Z'; c++)
{
characters.append( c + ", " );
}
for (char c = '0'; c <= '9'; c++)
{
characters.append( c + ", " );
}
StringBuffer widths = new StringBuffer();
for (char c = 'a'; c <= 'z'; c++)
{
widths.append( fontMetrics.getWidths()[c] + ", " );
}
for (char c = 'A'; c <= 'Z'; c++)
{
widths.append( fontMetrics.getWidths()[c] + ", " );
}
for (char c = '0'; c <= '9'; c++)
{
widths.append( fontMetrics.getWidths()[c] + ", " );
}
props.setProperty("font." + fontName + ".characters", characters.toString());
props.setProperty("font." + fontName + ".widths", widths.toString());
}
FileOutputStream fileOut = new FileOutputStream("font_metrics.properties");
try
{
props.store(fileOut, "Font Metrics");
}
finally
{
fileOut.close();
}
}
}

View File

@ -0,0 +1,244 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.poi.hpsf.ClassID;
/**
* <p>Provides utility methods for encoding and decoding hexadecimal
* data.</p>
*
* @author Rainer Klute (klute@rainer-klute.de) - with portions from Tomcat
* @version $Id$
* @since 2002-01-24
*/
public class Codec
{
/**
* <p>The nibbles' hexadecimal values. A nibble is a half byte.</p>
*/
protected static final byte hexval[] =
{(byte) '0', (byte) '1', (byte) '2', (byte) '3',
(byte) '4', (byte) '5', (byte) '6', (byte) '7',
(byte) '8', (byte) '9', (byte) 'A', (byte) 'B',
(byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F'};
/**
* <p>Converts a string into its hexadecimal notation.</p>
*/
public static String hexEncode(final String s)
{
return hexEncode(s.getBytes());
}
/**
* <p>Converts a byte array into its hexadecimal notation.</p>
*/
public static String hexEncode(final byte[] s)
{
return hexEncode(s, 0, s.length);
}
/**
* <p>Converts a part of a byte array into its hexadecimal
* notation.</p>
*/
public static String hexEncode(final byte[] s, final int offset,
final int length)
{
StringBuffer b = new StringBuffer(length * 2);
for (int i = offset; i < offset + length; i++)
{
int c = s[i];
b.append((char) hexval[(c & 0xF0) >> 4]);
b.append((char) hexval[(c & 0x0F) >> 0]);
}
return b.toString();
}
/**
* <p>Converts a single byte into its hexadecimal notation.</p>
*/
public static String hexEncode(final byte b)
{
StringBuffer sb = new StringBuffer(2);
sb.append((char) hexval[(b & 0xF0) >> 4]);
sb.append((char) hexval[(b & 0x0F) >> 0]);
return sb.toString();
}
/**
* <p>Converts a short value (16-bit) into its hexadecimal
* notation.</p>
*/
public static String hexEncode(final short s)
{
StringBuffer sb = new StringBuffer(4);
sb.append((char) hexval[(s & 0xF000) >> 12]);
sb.append((char) hexval[(s & 0x0F00) >> 8]);
sb.append((char) hexval[(s & 0x00F0) >> 4]);
sb.append((char) hexval[(s & 0x000F) >> 0]);
return sb.toString();
}
/**
* <p>Converts an int value (32-bit) into its hexadecimal
* notation.</p>
*/
public static String hexEncode(final int i)
{
StringBuffer sb = new StringBuffer(8);
sb.append((char) hexval[(i & 0xF0000000) >> 28]);
sb.append((char) hexval[(i & 0x0F000000) >> 24]);
sb.append((char) hexval[(i & 0x00F00000) >> 20]);
sb.append((char) hexval[(i & 0x000F0000) >> 16]);
sb.append((char) hexval[(i & 0x0000F000) >> 12]);
sb.append((char) hexval[(i & 0x00000F00) >> 8]);
sb.append((char) hexval[(i & 0x000000F0) >> 4]);
sb.append((char) hexval[(i & 0x0000000F) >> 0]);
return sb.toString();
}
/**
* <p>Converts a long value (64-bit) into its hexadecimal
* notation.</p>
*/
public static String hexEncode(final long l)
{
StringBuffer sb = new StringBuffer(16);
sb.append(hexEncode((int) (l & 0xFFFFFFFF00000000L) >> 32));
sb.append(hexEncode((int) (l & 0x00000000FFFFFFFFL) >> 0));
return sb.toString();
}
/**
* <p>Converts a class ID into its hexadecimal notation.</p>
*/
public static String hexEncode(final ClassID classID)
{
return hexEncode(classID.getBytes());
}
/**
* <p>Decodes the hexadecimal representation of a sequence of
* bytes into a byte array. Each character in the string
* represents a nibble (half byte) and must be one of the
* characters '0'-'9', 'A'-'F' or 'a'-'f'.</p>
*
* @param s The string to be decoded
*
* @return The bytes
*
* @throws IllegalArgumentException if the string does not contain
* a valid representation of a byte sequence.
*/
public static byte[] hexDecode(final String s)
{
final int length = s.length();
/* The string to be converted must have an even number of
characters. */
if (length % 2 == 1)
throw new IllegalArgumentException
("String has odd length " + length);
byte[] b = new byte[length / 2];
char[] c = new char[length];
s.toUpperCase().getChars(0, length, c, 0);
for (int i = 0; i < length; i += 2)
b[i/2] = (byte) (decodeNibble(c[i]) << 4 & 0xF0 |
decodeNibble(c[i+1]) & 0x0F);
return b;
}
/**
* <p>Decodes a nibble.</p>
*
* @param c A character in the range '0'-'9' or 'A'-'F'. Lower
* case is not supported here.
*
* @return The decoded nibble in the range 0-15
*
* @throws IllegalArgumentException if <em>c</em> is not a
* permitted character
*/
protected static byte decodeNibble(final char c)
{
for (byte i = 0; i < hexval.length; i++)
if ((byte) c == hexval[i])
return i;
throw new IllegalArgumentException("\"" + c + "\"" +
" does not represent a nibble.");
}
/**
* <p>For testing.</p>
*/
public static void main(final String args[])
throws IOException
{
final BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
String s;
do
{
s = in.readLine();
if (s != null)
{
String bytes = hexEncode(s);
System.out.print("Hex encoded (String): ");
System.out.println(bytes);
System.out.print("Hex encoded (byte[]): ");
System.out.println(hexEncode(s.getBytes()));
System.out.print("Re-decoded (byte[]): ");
System.out.println(new String(hexDecode(bytes)));
}
}
while (s != null);
}
}

View File

@ -0,0 +1,84 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.io.*;
import org.apache.poi.poifs.filesystem.*;
/**
* <p>Describes the most important (whatever that is) features of a
* {@link POIFSDocument}.</p>
*
* @author Rainer Klute (klute@rainer-klute.de)
* @version $Id$
* @since 2002-02-05
* *
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
*/
public class DocumentDescriptor
{
String name;
POIFSDocumentPath path;
DocumentInputStream stream;
int size;
byte[] bytes;
/**
* <p>Creates a {@link DocumentDescriptor}.</p>
*
* @param name The stream's name.
*
* @param path The stream's path in the POI filesystem hierarchy.
*
* @param stream The stream.
*
* @param nrOfBytes The maximum number of bytes to display in a
* dump starting at the beginning of the stream.
*/
public DocumentDescriptor(final String name,
final POIFSDocumentPath path,
final DocumentInputStream stream,
final int nrOfBytes)
{
this.name = name;
this.path = path;
this.stream = stream;
try
{
size = stream.available();
if (stream.markSupported())
{
stream.mark(nrOfBytes);
final byte[] b = new byte[nrOfBytes];
final int read = stream.read(b, 0, Math.min(size, b.length));
bytes = new byte[read];
System.arraycopy(b, 0, bytes, 0, read);
stream.reset();
}
}
catch (IOException ex)
{
System.out.println(ex);
}
}
}

View File

@ -0,0 +1,81 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
/**
* <p>{@link TreeCellRenderer} for a {@link DocumentDescriptor}. The
* renderer is extremly rudimentary since displays only the document's
* name, its size and its fist few bytes.</p>
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
* @version $Id$
* @since 2002-02-05
*/
public class DocumentDescriptorRenderer extends DefaultTreeCellRenderer
{
public Component getTreeCellRendererComponent(final JTree tree,
final Object value,
final boolean selected,
final boolean expanded,
final boolean leaf,
final int row,
final boolean hasFocus)
{
final DocumentDescriptor d = (DocumentDescriptor)
((DefaultMutableTreeNode) value).getUserObject();
final JPanel p = new JPanel();
final JTextArea text = new JTextArea();
text.append(renderAsString(d));
text.setFont(new Font("Monospaced", Font.PLAIN, 10));
p.add(text);
if (selected)
Util.invert(text);
return p;
}
/**
* <p>Renders {@link DocumentDescriptor} as a string.</p>
*/
protected String renderAsString(final DocumentDescriptor d)
{
final StringBuffer b = new StringBuffer();
b.append("Name: ");
b.append(d.name);
b.append(" (");
b.append(Codec.hexEncode(d.name));
b.append(") \n");
b.append("Size: ");
b.append(d.size);
b.append(" bytes\n");
b.append("First bytes: ");
b.append(Codec.hexEncode(d.bytes));
return b.toString();
}
}

View File

@ -0,0 +1,148 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.util.*;
/**
* <p>This is a {@link TreeCellRenderer} implementation which is able
* to render arbitrary objects. The {@link ExtendableTreeCellRenderer}
* does not do the rendering itself but instead dispatches to
* class-specific renderers. A class/renderer pair must be registered
* using the {@link #register} method. If a class has no registered
* renderer, the renderer of its closest superclass is used. Since the
* {@link ExtendableTreeCellRenderer} always has a default renderer
* for the {@link Object} class, rendering is always possible. The
* default {@link Object} renderer can be replaced by another renderer
* but it cannot be unregistered.</p>
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
* @version $Id$
* @since 2002-01-22
*/
public class ExtendableTreeCellRenderer implements TreeCellRenderer
{
/**
* <p>Maps classes to renderers.</p>
*/
protected Map renderers;
public ExtendableTreeCellRenderer()
{
renderers = new HashMap();
register(Object.class, new DefaultTreeCellRenderer()
{
public Component getTreeCellRendererComponent
(JTree tree, Object value, boolean selected,
boolean expanded, boolean leaf, int row, boolean hasFocus)
{
final String s = value.toString();
final JLabel l = new JLabel(s + " ");
if (selected)
{
Util.invert(l);
l.setOpaque(true);
}
return l;
}
});
}
/**
* <p>Registers a renderer for a class.</p>
**/
public void register(final Class c, final TreeCellRenderer renderer)
{
renderers.put(c, renderer);
}
/**
* <p>Unregisters a renderer for a class. The renderer for the
* {@link Object} class cannot be unregistered.</p>
*/
public void unregister(final Class c)
{
if (c == Object.class)
throw new IllegalArgumentException
("Renderer for Object cannot be unregistered.");
renderers.put(c, null);
}
/**
* <p>Renders an object in a tree cell depending of the object's
* class.</p>
*
* @see TreeCellRenderer#getTreeCellRendererComponent
*/
public Component getTreeCellRendererComponent
(final JTree tree, final Object value, final boolean selected,
final boolean expanded, final boolean leaf, final int row,
final boolean hasFocus)
{
final String NULL = "null";
TreeCellRenderer r;
Object userObject;
if (value == null)
userObject = NULL;
else
{
userObject = ((DefaultMutableTreeNode) value).getUserObject();
if (userObject == null)
userObject = NULL;
}
r = findRenderer(userObject.getClass());
return r.getTreeCellRendererComponent
(tree, value, selected, expanded, leaf, row,
hasFocus);
}
/**
* <p>Find the renderer for the specified class.</p>
*/
protected TreeCellRenderer findRenderer(final Class c)
{
final TreeCellRenderer r = (TreeCellRenderer) renderers.get(c);
if (r != null)
/* The class has a renderer. */
return r;
/* The class has no renderer, try the superclass, if any. */
final Class superclass = c.getSuperclass();
if (superclass != null)
return findRenderer(superclass);
else
return null;
}
}

View File

@ -0,0 +1,135 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
/**
* <p>The main class of the POI Browser. It shows the structure of POI
* filesystems (Microsoft Office documents) in a {@link
* JTree}. Specify their filenames on the command line!</p>
*
* @see POIFSReader
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
* @version $Id$
* @since 2002-01-19
*/
public class POIBrowser extends JFrame
{
/**
* <p>The tree's root node must be visible to all methods.</p>
*/
protected MutableTreeNode rootNode;
/**
* <p>Takes a bunch of file names as command line parameters,
* opens each of them as a POI filesystem and displays their
* internal structures in a {@link JTree}.</p>
*/
public static void main(String[] args)
{
new POIBrowser().run(args);
}
protected void run(String[] args)
{
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
/* Create the tree model with a root node. The latter is
* invisible but it must be present because a tree model
* always needs a root. */
rootNode = new DefaultMutableTreeNode("POI Filesystems");
DefaultTreeModel treeModel = new DefaultTreeModel(rootNode);
/* Create the tree UI element. */
final JTree treeUI = new JTree(treeModel);
getContentPane().add(new JScrollPane(treeUI));
/* Add the POI filesystems to the tree. */
int displayedFiles = 0;
for (int i = 0; i < args.length; i++)
{
final String filename = args[i];
try
{
POIFSReader r = new POIFSReader();
r.registerListener(new TreeReaderListener(filename, rootNode));
r.read(new FileInputStream(filename));
displayedFiles++;
}
catch (IOException ex)
{
System.err.println(filename + ": " + ex);
}
catch (Throwable t)
{
System.err.println("Unexpected exception while reading \"" +
filename + "\":");
t.printStackTrace(System.err);
}
}
/* Exit if there is no file to display (none specified or only
* files with problems). */
if (displayedFiles == 0)
{
System.out.println("No POI filesystem(s) to display.");
System.exit(0);
}
/* Make the tree UI element visible. */
treeUI.setRootVisible(true);
treeUI.setShowsRootHandles(true);
ExtendableTreeCellRenderer etcr = new ExtendableTreeCellRenderer();
etcr.register(DocumentDescriptor.class,
new DocumentDescriptorRenderer());
etcr.register(PropertySetDescriptor.class,
new PropertySetDescriptorRenderer());
treeUI.setCellRenderer(etcr);
setSize(600, 450);
setTitle("POI Browser 0.08");
setVisible(true);
}
}

View File

@ -0,0 +1,81 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.poi.hpsf.MarkUnsupportedException;
import org.apache.poi.hpsf.NoPropertySetStreamException;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.UnexpectedPropertySetTypeException;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
/**
* <p>Describes the most important (whatever that is) features of a
* stream containing a {@link PropertySet}.</p>
*
* @author Rainer Klute (klute@rainer-klute.de)
* @version $Id$
* @since 2002-02-05
*/
public class PropertySetDescriptor extends DocumentDescriptor
{
protected PropertySet propertySet;
/**
* <p>Returns this {@link PropertySetDescriptor}'s {@link
* PropertySet}.</p>
*/
public PropertySet getPropertySet()
{
return propertySet;
}
/**
* <p>Creates a {@link PropertySetDescriptor} by reading a {@link
* PropertySet} from a {@link DocumentInputStream}.</p>
*
* @param name The stream's name.
*
* @param path The stream's path in the POI filesystem hierarchy.
*
* @param stream The stream.
*
* @param nrOfBytesToDump The maximum number of bytes to display in a
* dump starting at the beginning of the stream.
*/
public PropertySetDescriptor(final String name,
final POIFSDocumentPath path,
final DocumentInputStream stream,
final int nrOfBytesToDump)
throws UnexpectedPropertySetTypeException, NoPropertySetStreamException,
MarkUnsupportedException, UnsupportedEncodingException,
IOException
{
super(name, path, stream, nrOfBytesToDump);
propertySet = PropertySetFactory.create(stream);
}
}

View File

@ -0,0 +1,165 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.Iterator;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import org.apache.poi.hpsf.Property;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.Section;
import org.apache.poi.hpsf.SummaryInformation;
/**
* <p>Renders a {@link PropertySetDescriptor} by more or less dumping
* the stuff into a {@link JTextArea}.</p>
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
* @version $Id$
* @since 2002-02-05
*/
public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer
{
public Component getTreeCellRendererComponent(final JTree tree,
final Object value,
final boolean selected,
final boolean expanded,
final boolean leaf,
final int row,
final boolean hasFocus)
{
final PropertySetDescriptor d = (PropertySetDescriptor)
((DefaultMutableTreeNode) value).getUserObject();
final PropertySet ps = d.getPropertySet();
final JPanel p = new JPanel();
final JTextArea text = new JTextArea();
text.setBackground(new Color(200, 255, 200));
text.setFont(new Font("Monospaced", Font.PLAIN, 10));
text.append(renderAsString(d));
text.append("\nByte order: " +
Codec.hexEncode((short) ps.getByteOrder()));
text.append("\nFormat: " +
Codec.hexEncode((short) ps.getFormat()));
text.append("\nOS version: " +
Codec.hexEncode(ps.getOSVersion()));
text.append("\nClass ID: " +
Codec.hexEncode(ps.getClassID()));
text.append("\nSection count: " + ps.getSectionCount());
text.append(sectionsToString(ps.getSections()));
p.add(text);
if (ps instanceof SummaryInformation)
{
/* Use the convenience methods. */
final SummaryInformation si = (SummaryInformation) ps;
text.append("\n");
text.append("\nTitle: " + si.getTitle());
text.append("\nSubject: " + si.getSubject());
text.append("\nAuthor: " + si.getAuthor());
text.append("\nKeywords: " + si.getKeywords());
text.append("\nComments: " + si.getComments());
text.append("\nTemplate: " + si.getTemplate());
text.append("\nLast Author: " + si.getLastAuthor());
text.append("\nRev. Number: " + si.getRevNumber());
text.append("\nEdit Time: " + si.getEditTime());
text.append("\nLast Printed: " + si.getLastPrinted());
text.append("\nCreate Date/Time: " + si.getCreateDateTime());
text.append("\nLast Save Date/Time: " + si.getLastSaveDateTime());
text.append("\nPage Count: " + si.getPageCount());
text.append("\nWord Count: " + si.getWordCount());
text.append("\nChar Count: " + si.getCharCount());
// text.append("\nThumbnail: " + si.getThumbnail());
text.append("\nApplication Name: " + si.getApplicationName());
text.append("\nSecurity: " + si.getSecurity());
}
if (selected)
Util.invert(text);
return p;
}
/**
* <p>Returns a string representation of a list of {@link
* Section}s.</p>
*/
protected String sectionsToString(final List sections)
{
final StringBuffer b = new StringBuffer();
int count = 1;
for (Iterator i = sections.iterator(); i.hasNext();)
{
Section s = (Section) i.next();
String d = toString(s, "Section " + count++);
b.append(d);
}
return b.toString();
}
/**
* <p>Returns a string representation of a {@link Section}.</p>
*/
protected String toString(final Section s, final String name)
{
final StringBuffer b = new StringBuffer();
b.append("\n" + name + " Format ID: ");
b.append(Codec.hexEncode(s.getFormatID()));
b.append("\n" + name + " Offset: " + s.getOffset());
b.append("\n" + name + " Section size: " + s.getSize());
b.append("\n" + name + " Property count: " + s.getPropertyCount());
final Property[] properties = s.getProperties();
for (int i = 0; i < properties.length; i++)
{
final Property p = properties[i];
final Object value = p.getValue();
b.append("\n" + name + " ");
b.append("PID_");
b.append(p.getID());
b.append(' ');
b.append(s.getPIDString(p.getID()) + ": ");
if (value instanceof byte[])
{
byte[] b2 = (byte[]) value;
b.append("0x" + Codec.hexEncode(b2, 0, 4));
b.append(' ');
b.append("0x" + Codec.hexEncode(b2, 4, b2.length - 4));
}
else if (value != null)
b.append(value.toString());
else
b.append("null");
}
return b.toString();
}
}

View File

@ -0,0 +1,237 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import org.apache.poi.hpsf.HPSFException;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
/**
* <p>Organizes document information in a tree model in order to be
* e.g. displayed in a Swing {@link javax.swing.JTree}. An instance of this
* class is created with a root tree node ({@link MutableTreeNode}) and
* registered as a {@link POIFSReaderListener} with a {@link
* org.apache.poi.poifs.eventfilesystem.POIFSReader}. While the latter processes
* a POI filesystem it calls this class' {@link #processPOIFSReaderEvent} for
* each document it has been registered for. This method appends the document it
* processes at the appropriate position into the tree rooted at the
* above mentioned root tree node.</p>
*
* <p>The root tree node should be the root tree node of a {@link
* javax.swing.tree.TreeModel}.</p>
*
* <p>A top-level element in the tree model, i.e. an immediate child
* node of the root node, describes a POI filesystem as such. It is
* suggested to use the file's name (as seen by the operating system)
* but it could be any other string.</p>
*
* <p>The value of a tree node is a {@link DocumentDescriptor}. Unlike
* a {@link org.apache.poi.poifs.filesystem.POIFSDocument} which may be as heavy
* as many megabytes, an instance of {@link DocumentDescriptor} is a
* light-weight object and contains only some meta-information about a
* document.</p>
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
* @version $Id$
* @since 2002-01-24
*/
public class TreeReaderListener implements POIFSReaderListener
{
/**
* <p>The tree's root node. POI filesystems get attached to this
* node as children.</p>
*/
protected MutableTreeNode rootNode;
/**
* <p>Maps filenames and POI document paths to their associated
* tree nodes.</p>
*/
protected Map pathToNode;
/**
* <p>The name of the file this {@link TreeReaderListener}
* processes. It is used to identify a top-level element in the
* tree. Alternatively any other string can be used. It is just a
* label which should identify a POI filesystem.</p>
*/
protected String filename;
/**
* <p>Creates a {@link TreeReaderListener} which should then be
* registered with a
* {@link org.apache.poi.poifs.eventfilesystem.POIFSReader}.</p>
*
* @param filename The name of the POI filesystem, i.e. the name
* of the file the POI filesystem resides in. Alternatively any
* other string can be used.
*
* @param rootNode All document information will be attached as
* descendands to this tree node.
*/
public TreeReaderListener(final String filename,
final MutableTreeNode rootNode)
{
this.filename = filename;
this.rootNode = rootNode;
pathToNode = new HashMap(15); // Should be a reasonable guess.
}
/** <p>The number of bytes to dump.</p> */
private int nrOfBytes = 50;
public void setNrOfBytes(final int nrOfBytes)
{
this.nrOfBytes = nrOfBytes;
}
public int getNrOfBytes()
{
return nrOfBytes;
}
/**
* <p>A document in the POI filesystem has been opened for
* reading. This method retrieves properties of the document and
* adds them to a tree model.</p>
*/
public void processPOIFSReaderEvent(final POIFSReaderEvent event)
{
DocumentDescriptor d;
final DocumentInputStream is = event.getStream();
if (!is.markSupported())
throw new UnsupportedOperationException(is.getClass().getName() +
" does not support mark().");
/* Try do handle this document as a property set. We receive
* an exception if is no property set and handle it as a
* document of some other format. We are not concerned about
* that document's details. */
try
{
d = new PropertySetDescriptor(event.getName(), event.getPath(),
is, nrOfBytes);
}
catch (HPSFException ex)
{
d = new DocumentDescriptor(event.getName(), event.getPath(),
is, nrOfBytes);
}
catch (Throwable t)
{
System.err.println
("Unexpected exception while processing " +
event.getName() + " in " + event.getPath().toString());
t.printStackTrace(System.err);
throw new RuntimeException(t.getMessage());
}
try
{
is.close();
}
catch (IOException ex)
{
System.err.println
("Unexpected exception while closing " +
event.getName() + " in " + event.getPath().toString());
ex.printStackTrace(System.err);
}
final MutableTreeNode parentNode = getNode(d.path, filename, rootNode);
final MutableTreeNode nameNode = new DefaultMutableTreeNode(d.name);
parentNode.insert(nameNode, 0);
final MutableTreeNode dNode = new DefaultMutableTreeNode(d);
nameNode.insert(dNode, 0);
}
/**
* <p>Locates the parent node for a document entry in the tree
* model. If the parent node does not yet exist it will be
* created, too. This is done recursively, if needed.</p>
*
* @param path The tree node for this path is located.
*
* @param fsName The name of the POI filesystem. This is just a
* string which is displayed in the tree at the top lovel.
*
* @param root The root node.
*/
private MutableTreeNode getNode(final POIFSDocumentPath path,
final String fsName,
final MutableTreeNode root)
{
MutableTreeNode n = (MutableTreeNode) pathToNode.get(path);
if (n != null)
/* Node found in map, just return it. */
return n;
if (path.length() == 0)
{
/* This is the root path of the POI filesystem. Its tree
* node is resp. must be located below the tree node of
* the POI filesystem itself. This is a tree node with the
* POI filesystem's name (this the operating system file's
* name) as its key it the path-to-node map. */
n = (MutableTreeNode) pathToNode.get(fsName);
if (n == null)
{
/* A tree node for the POI filesystem does not yet
* exist. */
n = new DefaultMutableTreeNode(fsName);
pathToNode.put(fsName, n);
root.insert(n, 0);
}
return n;
}
else
{
/* The path is somewhere down in the POI filesystem's
* hierarchy. We need the tree node of this path's parent
* and attach our new node to it. */
final String name = path.getComponent(path.length() - 1);
final POIFSDocumentPath parentPath = path.getParent();
final MutableTreeNode parentNode =
getNode(parentPath, fsName, root);
n = new DefaultMutableTreeNode(name);
pathToNode.put(path, n);
parentNode.insert(n, 0);
return n;
}
}
}

View File

@ -0,0 +1,50 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.contrib.poibrowser;
import java.awt.*;
import javax.swing.*;
/**
* <p>Contains various (well, just one at the moment) static utility
* methods.</p>
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
* @version $Id$
* @since 2002-01-25
*/
public class Util
{
/**
* <p>Makes a Swing component inverted by swapping its foreground
* and background colors. Hint: Depending on your needs it might
* also be a good idea to call <tt>c.setOpaque(true)</tt>.</p>
*/
public static void invert(final JComponent c)
{
final Color invBackground = c.getForeground();
final Color invForeground = c.getBackground();
c.setBackground(invBackground);
c.setForeground(invForeground);
}
}

View File

@ -0,0 +1,110 @@
<!doctype html public "-//W3C//DTD HTML 4.0//EN//">
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<html>
<head>
<title></title>
</head>
<body>
<div>
<p>The <strong>POI Browser</strong> is a very simple Swing GUI tool that
displays the internal structure of a Microsoft Office file. It concentrates
on streams in the <em>Horrible Property Set Format (HPSF)</em>. In order to
access these streams the POI Browser uses the package
<tt>org.apache.poi.hpsf</tt>.</p>
<p>A file in Microsoft's Office format can be seen as a filesystem within a
file. For example, a Word document like <var>sample.doc</var> is just a
simple file from the operation system's point of view. However, internally
it is organized into various directories and files. For example,
<var>sample.doc</var> might consist of the three internal files (or
"streams", as Microsoft calls them) <tt>\001CompObj</tt>,
<tt>\005SummaryInformation</tt>, and <tt>WordDocument</tt>. (In these names
\001 and \005 denote the unprintable characters with the character codes 1
and 5, respectively.) A more complicated Word file typically contains a
directory named <tt>ObjectPool</tt> with more directories and files nested
within it.</p>
<p>The POI Browser makes these internal structures visible. It takes one or
more Microsoft files as input on the command line and shows directories and
files in a tree-like structure. On the top-level POI Browser displays the
(operating system) filenames. An internal file (i.e. a "stream" or a
"document") is shown with its name, its size and a hexadecimal dump of its
first bytes.</p>
</div>
<div>
<h3>Property Set Streams</h3>
<p>The POI Browser pays special attention to property set streams. For
example, the <tt>\005SummaryInformation</tt> stream contains information
like title and author of the document. The POI Browser opens every stream
in a POI filesystem. If it encounters a property set stream, it displays
not just its first bytes but analyses the whole stream and displays its
contents in a more or less readable manner.</p>
</div>
<div>
<h3>Running POI Browser</h3>
<p>Running the POI Browser requires you to start a Java Virtual Machine
(JVM) and to set up a valid classpath so that the JVM can find all the Java
classes it needs. These are the main POI classes and the "contrib" POI
classes.</p>
<p>The following instructions assume that you have set up your Java
enviromnent variables properly, i.e. the variable JAVA_HOME contains the
name of your Java installation directory and the variable PATH includes the
<var>bin</var> subdirectory of the Java installation directory. At the time
of this writing the current POI version was 2.5.1-final dating from August
4th, 2004. The example statements reflect version numbering and
date. Change the commands accordingly if you are running the POI Browser of
a later or earlier than this!</p>
<div>
<h4>Running POI Browser on Unix</h4>
<p>Suppose you have unpacked the POI&nbsp;2.5.1 release in the
<var>/opt/local/poi</var> directory of your Unix box. Then the following
command starts the POI Browser and displays the structure of the files
<var>MyWord.doc</var>, <var>MyExcel.xls</var> and
<var>MyPowerpoint.ppt</var>:</p>
<pre>java -classpath /opt/local/poi/poi-2.5.1-final-20040804.jar:/opt/local/poi/poi-contrib-2.5.1-final-20040804.jar org.apache.poi.contrib.poibrowser.POIBrowser MyWord.doc MyExcel.xls MyPowerpoint.ppt</pre>
</div>
<div>
<h4>Running POI Browser on Windows</h4>
<p>Suppose you have unpacked the POI&nbsp;2.5.1 release in the
<var>C:\Programs\POI</var> directory of your Windows box. Then the following
command starts the POI Browser and displays the structure of the files
<var>MyWord.doc</var>, <var>MyExcel.xls</var> and
<var>MyPowerpoint.ppt</var>:</p>
<pre>java -classpath C:\Programs\POI\poi-2.5.1-final-20040804.jar;C:\Programs\POI\poi-contrib-2.5.1-final-20040804.jar org.apache.poi.contrib.poibrowser.POIBrowser MyWord.doc MyExcel.xls MyPowerpoint.ppt</pre>
</div>
</div>
</body>
</html>
<!-- Keep this comment at the end of the file
Local variables:
sgml-default-dtd-file:"HTML_4.0_Strict.ced"
mode: html
sgml-omittag:t
sgml-shorttag:nil
sgml-namecase-general:t
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:
-->

View File

@ -0,0 +1,563 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.awt.*;
import javax.swing.border.AbstractBorder;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
/**
* This is an attempt to implement Excel style borders for the SheetViewer.
* Mostly just overrides stuff so the javadoc won't appear here but will
* appear in the generated stuff.
*
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Jason Height
*/
public class SVBorder extends AbstractBorder {
private Color northColor = null;
private Color eastColor = null;
private Color southColor = null;
private Color westColor = null;
private int northBorderType = HSSFCellStyle.BORDER_NONE;
private int eastBorderType =HSSFCellStyle.BORDER_NONE;
private int southBorderType = HSSFCellStyle.BORDER_NONE;
private int westBorderType = HSSFCellStyle.BORDER_NONE;
private boolean northBorder=false;
private boolean eastBorder=false;
private boolean southBorder=false;
private boolean westBorder=false;
private boolean selected = false;
public void setBorder(Color northColor, Color eastColor,
Color southColor, Color westColor,
int northBorderType, int eastBorderType,
int southBorderType, int westBorderType,
boolean selected) {
this.eastColor = eastColor;
this.southColor = southColor;
this.westColor = westColor;
this.northBorderType = northBorderType;
this.eastBorderType = eastBorderType;
this.southBorderType = southBorderType;
this.westBorderType = westBorderType;
this.northBorder=northBorderType != HSSFCellStyle.BORDER_NONE;
this.eastBorder=eastBorderType != HSSFCellStyle.BORDER_NONE;
this.southBorder=southBorderType != HSSFCellStyle.BORDER_NONE;
this.westBorder=westBorderType != HSSFCellStyle.BORDER_NONE;
this.selected = selected;
}
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) {
Color oldColor = g.getColor();
paintSelectedBorder(g, x, y, width, height);
paintNormalBorders(g, x, y, width, height);
paintDottedBorders(g, x, y, width, height);
paintDashedBorders(g, x, y, width, height);
paintDoubleBorders(g, x, y, width, height);
paintDashDotDotBorders(g, x, y, width, height);
g.setColor(oldColor);
}
/**
* Called by paintBorder to paint the border of a selected cell.
* The paramaters are the Graphics object, location and dimensions of the
* cell.
*/
private void paintSelectedBorder(Graphics g, int x, int y, int width,
int height) {
if (selected) {
//Need to setup thickness of 2
g.setColor(Color.black);
//paint the border
g.drawRect(x,y,width-1,height-1);
//paint the filled rectangle at the bottom left hand position
g.fillRect(x+width-5, y+height-5, 5, 5);
}
}
/**
* Called by paintBorder to paint the various versions of normal line
* borders for a cell.
*/
private void paintNormalBorders(Graphics g, int x, int y, int width,
int height) {
if (northBorder &&
((northBorderType == HSSFCellStyle.BORDER_THIN) ||
(northBorderType == HSSFCellStyle.BORDER_MEDIUM) ||
(northBorderType == HSSFCellStyle.BORDER_THICK)
)
) {
int thickness = getThickness(northBorderType);
g.setColor(northColor);
for (int k=0; k < thickness; k++) {
g.drawLine(x,y+k,width,y+k);
}
}
if (eastBorder &&
((eastBorderType == HSSFCellStyle.BORDER_THIN) ||
(eastBorderType == HSSFCellStyle.BORDER_MEDIUM) ||
(eastBorderType == HSSFCellStyle.BORDER_THICK)
)
) {
int thickness = getThickness(eastBorderType);
g.setColor(eastColor);
for (int k=0; k < thickness; k++) {
g.drawLine(width-k,y,width-k,height);
}
}
if (southBorder &&
((southBorderType == HSSFCellStyle.BORDER_THIN) ||
(southBorderType == HSSFCellStyle.BORDER_MEDIUM) ||
(southBorderType == HSSFCellStyle.BORDER_THICK)
)
) {
int thickness = getThickness(southBorderType);
g.setColor(southColor);
for (int k=0; k < thickness; k++) {
g.drawLine(x,height - k,width,height - k);
}
}
if (westBorder &&
((westBorderType == HSSFCellStyle.BORDER_THIN) ||
(westBorderType == HSSFCellStyle.BORDER_MEDIUM) ||
(westBorderType == HSSFCellStyle.BORDER_THICK)
)
) {
int thickness = getThickness(westBorderType);
g.setColor(westColor);
for (int k=0; k < thickness; k++) {
g.drawLine(x+k,y,x+k,height);
}
}
}
/**
* Called by paintBorder to paint the dotted line
* borders for a cell.
*/
private void paintDottedBorders(Graphics g, int x, int y, int width,
int height) {
if (northBorder &&
northBorderType == HSSFCellStyle.BORDER_DOTTED) {
int thickness = getThickness(northBorderType);
g.setColor(northColor);
for (int k=0; k < thickness; k++) {
for (int xc = x; xc < width; xc=xc+2) {
g.drawLine(xc,y+k,xc,y+k);
}
}
}
if (eastBorder &&
eastBorderType == HSSFCellStyle.BORDER_DOTTED
) {
int thickness = getThickness(eastBorderType);
thickness++; //need for dotted borders to show up east
g.setColor(eastColor);
for (int k=0; k < thickness; k++) {
for (int yc=y;yc < height; yc=yc+2) {
g.drawLine(width-k,yc,width-k,yc);
}
}
}
if (southBorder &&
southBorderType == HSSFCellStyle.BORDER_DOTTED
) {
int thickness = getThickness(southBorderType);
thickness++;
g.setColor(southColor);
for (int k=0; k < thickness; k++) {
for (int xc = x; xc < width; xc=xc+2) {
g.drawLine(xc,height-k,xc,height-k);
}
}
}
if (westBorder &&
westBorderType == HSSFCellStyle.BORDER_DOTTED
) {
int thickness = getThickness(westBorderType);
// thickness++;
g.setColor(westColor);
for (int k=0; k < thickness; k++) {
for (int yc=y;yc < height; yc=yc+2) {
g.drawLine(x+k,yc,x+k,yc);
}
}
}
}
/**
* Called by paintBorder to paint the various versions of dotted line
* borders for a cell.
*/
private void paintDashedBorders(Graphics g, int x, int y, int width,
int height) {
if (northBorder &&
((northBorderType == HSSFCellStyle.BORDER_DASHED) ||
(northBorderType == HSSFCellStyle.BORDER_HAIR))
) {
int thickness = getThickness(northBorderType);
int dashlength = 1;
if (northBorderType == HSSFCellStyle.BORDER_DASHED)
dashlength = 2;
g.setColor(northColor);
for (int k=0; k < thickness; k++) {
for (int xc = x; xc < width; xc=xc+5) {
g.drawLine(xc,y+k,xc+dashlength,y+k);
}
}
}
if (eastBorder &&
((eastBorderType == HSSFCellStyle.BORDER_DASHED) ||
(eastBorderType == HSSFCellStyle.BORDER_HAIR))
) {
int thickness = getThickness(eastBorderType);
thickness++; //need for dotted borders to show up east
int dashlength = 1;
if (eastBorderType == HSSFCellStyle.BORDER_DASHED)
dashlength = 2;
g.setColor(eastColor);
for (int k=0; k < thickness; k++) {
for (int yc=y;yc < height; yc=yc+5) {
g.drawLine(width-k,yc,width-k,yc+dashlength);
}
}
}
if (southBorder &&
((southBorderType == HSSFCellStyle.BORDER_DASHED) ||
(southBorderType == HSSFCellStyle.BORDER_HAIR))
) {
int thickness = getThickness(southBorderType);
thickness++;
int dashlength = 1;
if (southBorderType == HSSFCellStyle.BORDER_DASHED)
dashlength = 2;
g.setColor(southColor);
for (int k=0; k < thickness; k++) {
for (int xc = x; xc < width; xc=xc+5) {
g.drawLine(xc,height-k,xc+dashlength,height-k);
}
}
}
if (westBorder &&
((westBorderType == HSSFCellStyle.BORDER_DASHED) ||
(westBorderType == HSSFCellStyle.BORDER_HAIR))
) {
int thickness = getThickness(westBorderType);
// thickness++;
int dashlength = 1;
if (westBorderType == HSSFCellStyle.BORDER_DASHED)
dashlength = 2;
g.setColor(westColor);
for (int k=0; k < thickness; k++) {
for (int yc=y;yc < height; yc=yc+5) {
g.drawLine(x+k,yc,x+k,yc+dashlength);
}
}
}
}
/**
* Called by paintBorder to paint the double line
* borders for a cell.
*/
private void paintDoubleBorders(Graphics g, int x, int y, int width,
int height) {
if (northBorder &&
northBorderType == HSSFCellStyle.BORDER_DOUBLE) {
g.setColor(northColor);
int leftx=x;
int rightx=width;
// if there are borders on the west or east then
// the second line shouldn't cross them
if (westBorder)
leftx = x+3;
if (eastBorder)
rightx = width-3;
g.drawLine(x,y,width,y);
g.drawLine(leftx,y+2,rightx,y+2);
}
if (eastBorder &&
eastBorderType == HSSFCellStyle.BORDER_DOUBLE
) {
int thickness = getThickness(eastBorderType);
thickness++; //need for dotted borders to show up east
g.setColor(eastColor);
int topy=y;
int bottomy=height;
if (northBorder)
topy=y+3;
if (southBorder)
bottomy=height-3;
g.drawLine(width-1,y,width-1,height);
g.drawLine(width-3,topy,width-3,bottomy);
}
if (southBorder &&
southBorderType == HSSFCellStyle.BORDER_DOUBLE
) {
g.setColor(southColor);
int leftx=y;
int rightx=width;
if (westBorder)
leftx=x+3;
if (eastBorder)
rightx=width-3;
g.drawLine(x,height - 1,width,height - 1);
g.drawLine(leftx,height - 3,rightx,height - 3);
}
if (westBorder &&
westBorderType == HSSFCellStyle.BORDER_DOUBLE
) {
int thickness = getThickness(westBorderType);
// thickness++;
g.setColor(westColor);
int topy=y;
int bottomy=height-3;
if (northBorder)
topy=y+2;
if (southBorder)
bottomy=height-3;
g.drawLine(x,y,x,height);
g.drawLine(x+2,topy,x+2,bottomy);
}
}
/**
* Called by paintBorder to paint the various versions of dash dot dot line
* borders for a cell.
*/
private void paintDashDotDotBorders(Graphics g, int x, int y, int width,
int height) {
if (northBorder &&
((northBorderType == HSSFCellStyle.BORDER_DASH_DOT_DOT) ||
(northBorderType == HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT))
) {
int thickness = getThickness(northBorderType);
g.setColor(northColor);
for (int l=x; l < width;) {
l=l+drawDashDotDot(g, l, y, thickness, true, true);
}
}
if (eastBorder &&
((eastBorderType == HSSFCellStyle.BORDER_DASH_DOT_DOT) ||
(eastBorderType == HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT))
) {
int thickness = getThickness(eastBorderType);
g.setColor(eastColor);
for (int l=y;l < height;) {
//System.err.println("drawing east");
l=l+drawDashDotDot(g,width-1,l,thickness,false,false);
}
}
if (southBorder &&
((southBorderType == HSSFCellStyle.BORDER_DASH_DOT_DOT) ||
(southBorderType == HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT))
) {
int thickness = getThickness(southBorderType);
g.setColor(southColor);
for (int l=x; l < width;) {
//System.err.println("drawing south");
l=l+drawDashDotDot(g, l, height-1, thickness, true, false);
}
}
if (westBorder &&
((westBorderType == HSSFCellStyle.BORDER_DASH_DOT_DOT) ||
(westBorderType == HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT))
) {
int thickness = getThickness(westBorderType);
g.setColor(westColor);
for (int l=y;l < height;) {
//System.err.println("drawing west");
l=l+drawDashDotDot(g,x,l,thickness,false,true);
}
}
}
/**
* Draws one dash dot dot horizontally or vertically with thickness drawn
* incrementally to either the right or left.
*
* @param g graphics object for drawing with
* @param x the x origin of the line
* @param y the y origin of the line
* @param thickness the thickness of the line
* @param horizontal or vertical (true for horizontal)
* @param right/bottom or left/top thickness (true for right or top),
* if true then the x or y origin will be incremented to provide
* thickness, if false, they'll be decremented. For vertical
* borders, x is incremented or decremented, for horizontal its y.
* Just set to true for north and west, and false for east and
* south.
* @returns length - returns the length of the line.
*/
private int drawDashDotDot(Graphics g,int x, int y, int thickness,
boolean horizontal,
boolean rightBottom) {
for (int t=0; t < thickness; t++) {
if (!rightBottom) {
t = 0 - t; //add negative thickness so we go the other way
//then we'll decrement instead of increment.
}
if (horizontal) {
g.drawLine(x,y+t,x+5,y+t);
g.drawLine(x+8,y+t,x+10,y+t);
g.drawLine(x+13,y+t,x+15,y+t);
} else {
g.drawLine(x+t,y,x+t,y+5);
g.drawLine(x+t,y+8,x+t,y+10);
g.drawLine(x+t,y+13,x+t,y+15);
}
}
return 18;
}
/**
* @returns the line thickness for a border based on border type
*/
private int getThickness(int thickness) {
int retval=1;
switch (thickness) {
case HSSFCellStyle.BORDER_THIN:
retval=2;
break;
case HSSFCellStyle.BORDER_MEDIUM:
retval=3;
break;
case HSSFCellStyle.BORDER_THICK:
retval=4;
break;
case HSSFCellStyle.BORDER_DASHED:
retval=1;
break;
case HSSFCellStyle.BORDER_DASH_DOT_DOT:
retval=1;
break;
case HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT:
retval=3;
break;
case HSSFCellStyle.BORDER_HAIR:
retval=1;
break;
default:
retval=1;
}
return retval;
}
}

View File

@ -0,0 +1,219 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.text.*;
/**
* This class is used to format cells into their fractional format.
*
* I cant be 100% sure that the same fractional value will be displayed as in
* excel but then again it is a lossy formating mode anyway
*
* @author Jason Height
* @since 15 July 2002
*/
public class SVFractionalFormat extends Format {
private short ONE_DIGIT = 1;
private short TWO_DIGIT = 2;
private short THREE_DIGIT = 3;
private short UNITS = 4;
private int units = 1;
private short mode = -1;
/** Constructs a new FractionalFormatter
*
* The formatStr defines how the number will be formatted
* # ?/? Up to one digit
* # ??/?? Up to two digits
* # ???/??? Up to three digits
* # ?/2 In halves
* # ?/4 In quarters
* # ?/8 In eighths
* # ?/16 In sixteenths
* # ?/10 In tenths
* # ?/100 In hundredths
*/
public SVFractionalFormat(String formatStr) {
if ("# ?/?".equals(formatStr))
mode = ONE_DIGIT;
else if ("# ??/??".equals(formatStr))
mode = TWO_DIGIT;
else if ("# ???/???".equals(formatStr))
mode = THREE_DIGIT;
else if ("# ?/2".equals(formatStr)) {
mode = UNITS;
units = 2;
} else if ("# ?/4".equals(formatStr)) {
mode = UNITS;
units = 4;
} else if ("# ?/8".equals(formatStr)) {
mode = UNITS;
units = 8;
} else if ("# ?/16".equals(formatStr)) {
mode = UNITS;
units = 16;
} else if ("# ?/10".equals(formatStr)) {
mode = UNITS;
units = 10;
} else if ("# ?/100".equals(formatStr)) {
mode = UNITS;
units = 100;
}
}
/**
* Returns a fractional string representation of a double to a maximum denominator size
*
* This code has been translated to java from the following web page.
* http://www.codeproject.com/cpp/fraction.asp
* Originally coded in c++ By Dean Wyant dwyant@mindspring.com
* The code on the web page is freely available.
*
* @param f Description of the Parameter
* @param MaxDen Description of the Parameter
* @return Description of the Return Value
*/
private String format(final double f, final int MaxDen) {
long Whole = (long)f;
int sign = 1;
if (f < 0) {
sign = -1;
}
double Precision = 0.00001;
double AllowedError = Precision;
double d = Math.abs(f);
d -= Whole;
double Frac = d;
double Diff = Frac;
long Num = 1;
long Den = 0;
long A = 0;
long B = 0;
long i = 0;
if (Frac > Precision) {
while (true) {
d = 1.0 / d;
i = (long) (d + Precision);
d -= i;
if (A > 0) {
Num = i * Num + B;
}
Den = (long) (Num / Frac + 0.5);
Diff = Math.abs((double) Num / Den - Frac);
if (Den > MaxDen) {
if (A > 0) {
Num = A;
Den = (long) (Num / Frac + 0.5);
Diff = Math.abs((double) Num / Den - Frac);
} else {
Den = MaxDen;
Num = 1;
Diff = Math.abs((double) Num / Den - Frac);
if (Diff > Frac) {
Num = 0;
Den = 1;
// Keeps final check below from adding 1 and keeps Den from being 0
Diff = Frac;
}
}
break;
}
if ((Diff <= AllowedError) || (d < Precision)) {
break;
}
Precision = AllowedError / Diff;
// This calcualtion of Precision does not always provide results within
// Allowed Error. It compensates for loss of significant digits that occurs.
// It helps to round the inprecise reciprocal values to i.
B = A;
A = Num;
}
}
if (Num == Den) {
Whole++;
Num = 0;
Den = 0;
} else if (Den == 0) {
Num = 0;
}
if (sign < 0) {
if (Whole == 0) {
Num = -Num;
} else {
Whole = -Whole;
}
}
return new StringBuffer().append(Whole).append(" ").append(Num).append("/").append(Den).toString();
}
/** This method formats the double in the units specified.
* The usints could be any number but in this current implementation it is
* halves (2), quaters (4), eigths (8) etc
*/
private String formatUnit(double f, int units) {
long Whole = (long)f;
f -= Whole;
long Num = Math.round(f * units);
return new StringBuffer().append(Whole).append(" ").append(Num).append("/").append(units).toString();
}
public final String format(double val) {
if (mode == ONE_DIGIT) {
return format(val, 9);
} else if (mode == TWO_DIGIT) {
return format(val, 99);
} else if (mode == THREE_DIGIT) {
return format(val, 999);
} else if (mode == UNITS) {
return formatUnit(val , units);
}
throw new RuntimeException("Unexpected Case");
}
public StringBuffer format(Object obj,
StringBuffer toAppendTo,
FieldPosition pos) {
if (obj instanceof Number) {
toAppendTo.append(format(((Number)obj).doubleValue()));
return toAppendTo;
}
else throw new IllegalArgumentException("Can only handle Numbers");
}
public Object parseObject(String source,
ParsePosition status) {
//JMH TBD
return null;
}
public Object parseObject(String source)
throws ParseException {
//JMH TBD
return null;
}
public Object clone() {
//JMH TBD
return null;
}
}

View File

@ -0,0 +1,90 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import org.apache.poi.hssf.usermodel.*;
/**
* This class presents the row header to the table.
*
*
* @author Jason Height
*/
public class SVRowHeader extends JList {
/** This model simply returns an integer number up to the number of rows
* that are present in the sheet.
*
*/
private class SVRowHeaderModel extends AbstractListModel {
private HSSFSheet sheet;
public SVRowHeaderModel(HSSFSheet sheet) {
this.sheet = sheet;
}
public int getSize() { return sheet.getPhysicalNumberOfRows(); }
public Object getElementAt(int index) {
return Integer.toString(index+1);
}
}
/** Renderes the row number*/
private class RowHeaderRenderer extends JLabel implements ListCellRenderer {
private HSSFSheet sheet;
private int extraHeight;
RowHeaderRenderer(HSSFSheet sheet, JTable table, int extraHeight) {
this.sheet = sheet;
this.extraHeight = extraHeight;
JTableHeader header = table.getTableHeader();
setOpaque(true);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setHorizontalAlignment(CENTER);
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
public Component getListCellRendererComponent( JList list,
Object value, int index, boolean isSelected, boolean cellHasFocus) {
Dimension d = getPreferredSize();
int rowHeight = (int)sheet.getRow(index).getHeightInPoints();
d.height = rowHeight+extraHeight;
setPreferredSize(d);
setText((value == null) ? "" : value.toString());
return this;
}
}
public SVRowHeader(HSSFSheet sheet, JTable table, int extraHeight) {
ListModel lm = new SVRowHeaderModel(sheet);
this.setModel(lm);
setFixedCellWidth(50);
setCellRenderer(new RowHeaderRenderer(sheet, table, extraHeight));
}
}

View File

@ -0,0 +1,206 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
/**
* Sheet Viewer Table Cell Editor -- not commented via javadoc as it
* nearly completely consists of overridden methods.
*
* @author Jason Height
* @since 16 July 2002
*/
public class SVTableCellEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {
private static final Color black = getAWTColor(new HSSFColor.BLACK());
private static final Color white = getAWTColor(new HSSFColor.WHITE());
private Hashtable colors = HSSFColor.getIndexHash();
private HSSFWorkbook wb;
private JTextField editor;
private HSSFCell editorValue;
public SVTableCellEditor(HSSFWorkbook wb) {
this.wb = wb;
this.editor = new JTextField();
}
/**
* Gets the cellEditable attribute of the SVTableCellEditor object
*
* @return The cellEditable value
*/
public boolean isCellEditable(java.util.EventObject e) {
if (e instanceof MouseEvent) {
return ((MouseEvent) e).getClickCount() >= 2;
}
return false;
}
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
public boolean startCellEditing(EventObject anEvent) {
System.out.println("Start Cell Editing");
return true;
}
public boolean stopCellEditing() {
System.out.println("Stop Cell Editing");
fireEditingStopped();
return true;
}
public void cancelCellEditing() {
System.out.println("Cancel Cell Editing");
fireEditingCanceled();
}
public void actionPerformed(ActionEvent e) {
System.out.println("Action performed");
stopCellEditing();
}
/**
* Gets the cellEditorValue attribute of the SVTableCellEditor object
*
* @return The cellEditorValue value
*/
public Object getCellEditorValue() {
System.out.println("GetCellEditorValue");
//JMH Look at when this method is called. Should it return a HSSFCell?
return editor.getText();
}
/**
* Gets the tableCellEditorComponent attribute of the SVTableCellEditor object
*
* @return The tableCellEditorComponent value
*/
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected,
int row,
int column) {
System.out.println("GetTableCellEditorComponent");
HSSFCell cell = (HSSFCell) value;
if (cell != null) {
HSSFCellStyle style = cell.getCellStyle();
HSSFFont f = wb.getFontAt(style.getFontIndex());
boolean isbold = f.getBoldweight() > HSSFFont.BOLDWEIGHT_NORMAL;
boolean isitalics = f.getItalic();
int fontstyle = Font.PLAIN;
if (isbold) fontstyle = Font.BOLD;
if (isitalics) fontstyle = fontstyle | Font.ITALIC;
int fontheight = f.getFontHeightInPoints();
if (fontheight == 9) fontheight = 10; //fix for stupid ol Windows
Font font = new Font(f.getFontName(),fontstyle,fontheight);
editor.setFont(font);
if (style.getFillPattern() == HSSFCellStyle.SOLID_FOREGROUND) {
editor.setBackground(getAWTColor(style.getFillForegroundColor(), white));
} else editor.setBackground(white);
editor.setForeground(getAWTColor(f.getColor(), black));
//Set the value that is rendered for the cell
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BLANK:
editor.setText("");
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
if (cell.getBooleanCellValue()) {
editor.setText("true");
} else {
editor.setText("false");
}
break;
case HSSFCell.CELL_TYPE_NUMERIC:
editor.setText(Double.toString(cell.getNumericCellValue()));
break;
case HSSFCell.CELL_TYPE_STRING:
editor.setText(cell.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
default:
editor.setText("?");
}
switch (style.getAlignment()) {
case HSSFCellStyle.ALIGN_LEFT:
case HSSFCellStyle.ALIGN_JUSTIFY:
case HSSFCellStyle.ALIGN_FILL:
editor.setHorizontalAlignment(SwingConstants.LEFT);
break;
case HSSFCellStyle.ALIGN_CENTER:
case HSSFCellStyle.ALIGN_CENTER_SELECTION:
editor.setHorizontalAlignment(SwingConstants.CENTER);
break;
case HSSFCellStyle.ALIGN_GENERAL:
case HSSFCellStyle.ALIGN_RIGHT:
editor.setHorizontalAlignment(SwingConstants.RIGHT);
break;
default:
editor.setHorizontalAlignment(SwingConstants.LEFT);
break;
}
}
return editor;
}
/** This method retrieves the AWT Color representation from the colour hash table
*
*/
private final Color getAWTColor(int index, Color deflt) {
HSSFColor clr = (HSSFColor)colors.get(new Integer(index));
if (clr == null) return deflt;
return getAWTColor(clr);
}
private static final Color getAWTColor(HSSFColor clr) {
short[] rgb = clr.getTriplet();
return new Color(rgb[0],rgb[1],rgb[2]);
}
}

View File

@ -0,0 +1,278 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.util.Hashtable;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import javax.swing.border.*;
import java.awt.Component;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Font;
import java.io.Serializable;
import java.text.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
/**
* Sheet Viewer Table Cell Render -- not commented via javadoc as it
* nearly completely consists of overridden methods.
*
* @author Andrew C. Oliver
*/
public class SVTableCellRenderer extends JLabel
implements TableCellRenderer, Serializable
{
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
protected SVBorder cellBorder = new SVBorder();
private HSSFWorkbook wb = null;
/** This class holds the references to the predefined cell formats.
*/
private class CellFormatter {
private Format[] textFormatter;
private DecimalFormat generalNumberFormat = new DecimalFormat("0");
public CellFormatter() {
textFormatter = new Format[0x31];
textFormatter[0x01] = new DecimalFormat("0");
textFormatter[0x02] = new DecimalFormat("0.00");
textFormatter[0x03] = new DecimalFormat("#,##0");
textFormatter[0x04] = new DecimalFormat("#,##0.00");
textFormatter[0x05] = new DecimalFormat("$#,##0;$#,##0");
textFormatter[0x06] = new DecimalFormat("$#,##0;$#,##0");
textFormatter[0x07] = new DecimalFormat("$#,##0.00;$#,##0.00");
textFormatter[0x08] = new DecimalFormat("$#,##0.00;$#,##0.00");
textFormatter[0x09] = new DecimalFormat("0%");
textFormatter[0x0A] = new DecimalFormat("0.00%");
textFormatter[0x0B] = new DecimalFormat("0.00E0");
textFormatter[0x0C] = new SVFractionalFormat("# ?/?");
textFormatter[0x0D] = new SVFractionalFormat("# ??/??");
textFormatter[0x0E] = new SimpleDateFormat("M/d/yy");
textFormatter[0x0F] = new SimpleDateFormat("d-MMM-yy");
textFormatter[0x10] = new SimpleDateFormat("d-MMM");
textFormatter[0x11] = new SimpleDateFormat("MMM-yy");
textFormatter[0x12] = new SimpleDateFormat("h:mm a");
textFormatter[0x13] = new SimpleDateFormat("h:mm:ss a");
textFormatter[0x14] = new SimpleDateFormat("h:mm");
textFormatter[0x15] = new SimpleDateFormat("h:mm:ss");
textFormatter[0x16] = new SimpleDateFormat("M/d/yy h:mm");
// 0x17 - 0x24 reserved for international and undocumented 0x25, "(#,##0_);(#,##0)"
//start at 0x26
//jmh need to do colour
//"(#,##0_);[Red](#,##0)"
textFormatter[0x26] = new DecimalFormat("#,##0;#,##0");
//jmh need to do colour
//(#,##0.00_);(#,##0.00)
textFormatter[0x27] = new DecimalFormat("#,##0.00;#,##0.00");
textFormatter[0x28] = new DecimalFormat("#,##0.00;#,##0.00");
//?? textFormatter[0x29] = new DecimalFormat("_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)");
//?? textFormatter[0x2A] = new DecimalFormat("_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)");
//?? textFormatter[0x2B] = new DecimalFormat("_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)");
//?? textFormatter[0x2C] = new DecimalFormat("_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)");
textFormatter[0x2D] = new SimpleDateFormat("mm:ss");
//?? textFormatter[0x2E] = new SimpleDateFormat("[h]:mm:ss");
textFormatter[0x2F] = new SimpleDateFormat("mm:ss.0");
textFormatter[0x30] = new DecimalFormat("##0.0E0");
}
public String format(short index, Object value) {
if (index == 0)
return value.toString();
if (textFormatter[index] == null)
throw new RuntimeException("Sorry. I cant handle the format code :"+Integer.toHexString(index));
return textFormatter[index].format(value);
}
public String format(short index, double value) {
if (index == 0)
return generalNumberFormat.format(value);
if (textFormatter[index] == null)
throw new RuntimeException("Sorry. I cant handle the format code :"+Integer.toHexString(index));
if (textFormatter[index] instanceof DecimalFormat) {
return ((DecimalFormat)textFormatter[index]).format(value);
}
if (textFormatter[index] instanceof SVFractionalFormat) {
return ((SVFractionalFormat)textFormatter[index]).format(value);
}
throw new RuntimeException("Sorry. I cant handle a non decimal formatter for a decimal value :"+Integer.toHexString(index));
}
public boolean useRedColor(short index, double value) {
return (((index == 0x06)||(index == 0x08)||(index == 0x26) || (index == 0x27)) && (value < 0));
}
}
private final CellFormatter cellFormatter = new CellFormatter();
public SVTableCellRenderer(HSSFWorkbook wb) {
super();
setOpaque(true);
setBorder(noFocusBorder);
this.wb = wb;
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
boolean isBorderSet = false;
//If the JTables default cell renderer has been setup correctly the
//value will be the HSSFCell that we are trying to render
HSSFCell c = (HSSFCell)value;
if (c != null) {
HSSFCellStyle s = c.getCellStyle();
HSSFFont f = wb.getFontAt(s.getFontIndex());
setFont(SVTableUtils.makeFont(f));
if (s.getFillPattern() == HSSFCellStyle.SOLID_FOREGROUND) {
setBackground(SVTableUtils.getAWTColor(s.getFillForegroundColor(), SVTableUtils.white));
} else setBackground(SVTableUtils.white);
setForeground(SVTableUtils.getAWTColor(f.getColor(), SVTableUtils.black));
cellBorder.setBorder(SVTableUtils.getAWTColor(s.getTopBorderColor(), SVTableUtils.black),
SVTableUtils.getAWTColor(s.getRightBorderColor(), SVTableUtils.black),
SVTableUtils.getAWTColor(s.getBottomBorderColor(), SVTableUtils.black),
SVTableUtils.getAWTColor(s.getLeftBorderColor(), SVTableUtils.black),
s.getBorderTop(), s.getBorderRight(),
s.getBorderBottom(), s.getBorderLeft(),
hasFocus);
setBorder(cellBorder);
isBorderSet=true;
//Set the value that is rendered for the cell
switch (c.getCellType()) {
case HSSFCell.CELL_TYPE_BLANK:
setValue("");
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
if (c.getBooleanCellValue()) {
setValue("true");
} else {
setValue("false");
}
break;
case HSSFCell.CELL_TYPE_NUMERIC:
short format = s.getDataFormat();
double numericValue = c.getNumericCellValue();
if (cellFormatter.useRedColor(format, numericValue))
setForeground(Color.red);
else setForeground(null);
setValue(cellFormatter.format(format, c.getNumericCellValue()));
break;
case HSSFCell.CELL_TYPE_STRING:
setValue(c.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
default:
setValue("?");
}
//Set the text alignment of the cell
switch (s.getAlignment()) {
case HSSFCellStyle.ALIGN_LEFT:
case HSSFCellStyle.ALIGN_JUSTIFY:
case HSSFCellStyle.ALIGN_FILL:
setHorizontalAlignment(SwingConstants.LEFT);
break;
case HSSFCellStyle.ALIGN_CENTER:
case HSSFCellStyle.ALIGN_CENTER_SELECTION:
setHorizontalAlignment(SwingConstants.CENTER);
break;
case HSSFCellStyle.ALIGN_GENERAL:
case HSSFCellStyle.ALIGN_RIGHT:
setHorizontalAlignment(SwingConstants.RIGHT);
break;
default:
setHorizontalAlignment(SwingConstants.LEFT);
break;
}
} else {
setValue("");
setBackground(SVTableUtils.white);
}
if (hasFocus) {
if (!isBorderSet) {
//This is the border to paint when there is no border
//and the cell has focus
cellBorder.setBorder(SVTableUtils.black,
SVTableUtils.black,
SVTableUtils.black,
SVTableUtils.black,
HSSFCellStyle.BORDER_NONE,
HSSFCellStyle.BORDER_NONE,
HSSFCellStyle.BORDER_NONE,
HSSFCellStyle.BORDER_NONE,
isSelected);
setBorder(cellBorder);
}
if (table.isCellEditable(row, column)) {
setForeground( UIManager.getColor("Table.focusCellForeground") );
setBackground( UIManager.getColor("Table.focusCellBackground") );
}
} else if (!isBorderSet) {
setBorder(noFocusBorder);
}
// ---- begin optimization to avoid painting background ----
Color back = getBackground();
boolean colorMatch = (back != null) && ( back.equals(table.getBackground()) ) && table.isOpaque();
setOpaque(!colorMatch);
// ---- end optimization to aviod painting background ----
return this;
}
public void validate() {}
public void revalidate() {}
public void repaint(long tm, int x, int y, int width, int height) {}
public void repaint(Rectangle r) { }
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
// Strings get interned...
if (propertyName=="text") {
super.firePropertyChange(propertyName, oldValue, newValue);
}
}
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
/**
* Sets the string to either the value or "" if the value is null.
*
*/
protected void setValue(Object value) {
setText((value == null) ? "" : value.toString());
}
}

View File

@ -0,0 +1,86 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.util.Iterator;
import javax.swing.table.*;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFCell;
/**
* Sheet Viewer Table Model - The model for the Sheet Viewer just overrides things.
* @author Andrew C. Oliver
*/
public class SVTableModel extends AbstractTableModel {
private HSSFSheet st = null;
int maxcol = 0;
public SVTableModel(HSSFSheet st, int maxcol) {
this.st = st;
this.maxcol=maxcol;
}
public SVTableModel(HSSFSheet st) {
this.st = st;
Iterator i = st.rowIterator();
while (i.hasNext()) {
HSSFRow row = (HSSFRow)i.next();
if (maxcol < (row.getLastCellNum()+1)) {
this.maxcol = row.getLastCellNum();
}
}
}
public int getColumnCount() {
return this.maxcol+1;
}
public Object getValueAt(int row, int col) {
HSSFRow r = st.getRow(row);
HSSFCell c = null;
if (r != null) {
c = r.getCell((short)col);
}
return c;
}
public int getRowCount() {
return st.getLastRowNum() + 1;
}
public Class getColumnClass(int c) {
return HSSFCell.class;
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (aValue != null)
System.out.println("SVTableModel.setValueAt. value type = "+aValue.getClass().getName());
else System.out.println("SVTableModel.setValueAt. value type = null");
}
}

View File

@ -0,0 +1,94 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.util.*;
import java.awt.*;
import javax.swing.border.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.*;
/**
* SVTableCell Editor and Renderer helper functions.
*
* @author Jason Height
* @since 16 July 2002
*/
public class SVTableUtils {
private final static Hashtable colors = HSSFColor.getIndexHash();
/** Description of the Field */
public final static Color black = getAWTColor(new HSSFColor.BLACK());
/** Description of the Field */
public final static Color white = getAWTColor(new HSSFColor.WHITE());
/** Description of the Field */
public static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
/**
* Creates a new font for a specific cell style
*/
public static Font makeFont(HSSFFont font) {
boolean isbold = font.getBoldweight() > HSSFFont.BOLDWEIGHT_NORMAL;
boolean isitalics = font.getItalic();
int fontstyle = Font.PLAIN;
if (isbold) {
fontstyle = Font.BOLD;
}
if (isitalics) {
fontstyle = fontstyle | Font.ITALIC;
}
int fontheight = font.getFontHeightInPoints();
if (fontheight == 9) {
//fix for stupid ol Windows
fontheight = 10;
}
return new Font(font.getFontName(), fontstyle, fontheight);
}
/**
* This method retrieves the AWT Color representation from the colour hash table
*
* @param index Description of the Parameter
* @param deflt Description of the Parameter
* @return The aWTColor value
*/
public final static Color getAWTColor(int index, Color deflt) {
HSSFColor clr = (HSSFColor) colors.get(new Integer(index));
if (clr == null) {
return deflt;
}
return getAWTColor(clr);
}
/**
* Gets the aWTColor attribute of the SVTableUtils class
*
* @param clr Description of the Parameter
* @return The aWTColor value
*/
public final static Color getAWTColor(HSSFColor clr) {
short[] rgb = clr.getTriplet();
return new Color(rgb[0], rgb[1], rgb[2]);
}
}

View File

@ -0,0 +1,170 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.applet.*;
import java.io.*;
import javax.swing.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFCell;
/**
* Sheet Viewer - Views XLS files via HSSF. Can be used as an applet with
* filename="" or as a applications (pass the filename as the first parameter).
* Or you can pass it a URL in a "url" parameter when run as an applet or just
* that first parameter must start with http:// and it will guess its a url. I
* only tested it as an applet though, so it probably won't work...you fix it.
*
* @author Andrew C. Oliver
* @author Jason Height
*/
public class SViewer extends JApplet {
private SViewerPanel panel;
boolean isStandalone = false;
String filename = null;
/**Get a parameter value*/
public String getParameter(String key, String def) {
return isStandalone ? System.getProperty(key, def) :
(getParameter(key) != null ? getParameter(key) : def);
}
/**Construct the applet*/
public SViewer() {
}
/**Initialize the applet*/
public void init() {
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
}
/**Component initialization*/
private void jbInit() throws Exception {
InputStream i = null;
boolean isurl = false;
if (filename == null) filename = getParameter("filename");
if (filename == null || filename.substring(0,7).equals("http://")) {
isurl = true;
if (filename == null) filename = getParameter("url");
i = getXLSFromURL(filename);
}
HSSFWorkbook wb = null;
if (isurl) {
wb = constructWorkbook(i);
} else {
wb = constructWorkbook(filename);
}
panel = new SViewerPanel(wb, false);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(panel, BorderLayout.CENTER);
}
private HSSFWorkbook constructWorkbook(String filename) throws FileNotFoundException, IOException {
HSSFWorkbook wb = null;
FileInputStream in = new FileInputStream(filename);
wb = new HSSFWorkbook(in);
in.close();
return wb;
}
private HSSFWorkbook constructWorkbook(InputStream in) throws IOException {
HSSFWorkbook wb = null;
wb = new HSSFWorkbook(in);
in.close();
return wb;
}
/**Start the applet*/
public void start() {
}
/**Stop the applet*/
public void stop() {
}
/**Destroy the applet*/
public void destroy() {
}
/**Get Applet information*/
public String getAppletInfo() {
return "Applet Information";
}
/**Get parameter info*/
public String[][] getParameterInfo() {
return null;
}
/**
* opens a url and returns an inputstream
*
*/
private InputStream getXLSFromURL(String urlstring) throws MalformedURLException, IOException {
URL url = new URL(urlstring);
URLConnection uc = url.openConnection();
String field = uc.getHeaderField(0);
for (int i=0;field != null; i++) {
System.out.println(field);
field = uc.getHeaderField(i);
}
BufferedInputStream is = new BufferedInputStream(uc.getInputStream());
return is;
}
/**Main method*/
public static void main(String[] args) {
SViewer applet = new SViewer();
applet.isStandalone = true;
applet.filename = args[0];
Frame frame;
frame = new Frame() {
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
public synchronized void setTitle(String title) {
super.setTitle(title);
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
}
};
frame.setTitle("Applet Frame");
frame.add(applet, BorderLayout.CENTER);
applet.init();
applet.start();
frame.setSize(400,320);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
frame.setVisible(true);
}
}

View File

@ -0,0 +1,292 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.contrib.view;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import org.apache.poi.hssf.usermodel.*;
/**
* This class presents the sheets to the user.
*
*
* @author Andrew C. Oliver
* @author Jason Height
*/
public class SViewerPanel extends JPanel {
/** This field is the magic number to convert from a Character width to a
* java pixel width.
*
* When the "normal" font size in a workbook changes, this effects all
* of the heights and widths. Unfortunately there is no way to retrieve this
* information, hence the MAGIC number.
*
* This number may only work for the normal style font size of Arial size 10.
*
*/
private static final int magicCharFactor = 7;
/** Reference to the woorkbook that is being displayed*/
private HSSFWorkbook wb;
/** Reference to the tabs component*/
private JTabbedPane sheetPane;
/** Reference to the cell renderer that is used to render all cells*/
private SVTableCellRenderer cellRenderer;
/** Reference to the cell editor that is used to edit all cells.
* Only constructed if editing is allowed
*/
private SVTableCellEditor cellEditor;
/** Flag indicating if editing is allowed. Otherwise the viewer is in
* view only mode.
*/
private boolean allowEdits;
/**Construct the representation of the workbook*/
public SViewerPanel(HSSFWorkbook wb, boolean allowEdits) {
this.wb = wb;
this.allowEdits = allowEdits;
initialiseGui();
}
private void initialiseGui() {
cellRenderer = new SVTableCellRenderer(this.wb);
if (allowEdits)
cellEditor = new SVTableCellEditor(this.wb);
//Initialise the Panel
sheetPane = new JTabbedPane(JTabbedPane.BOTTOM);
if (allowEdits)
sheetPane.addMouseListener(createTabListener());
int sheetCount = wb.getNumberOfSheets();
for (int i=0; i<sheetCount;i++) {
String sheetName = wb.getSheetName(i);
//Add the new sheet to the tabbed pane
sheetPane.addTab(sheetName, makeSheetView(wb.getSheetAt(i)));
}
setLayout(new BorderLayout());
add(sheetPane, BorderLayout.CENTER);
}
protected JComponent makeSheetView(HSSFSheet sheet) {
JTable sheetView = new JTable(new SVTableModel(sheet));
sheetView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
sheetView.setDefaultRenderer(HSSFCell.class, cellRenderer);
if (allowEdits)
sheetView.setDefaultEditor(HSSFCell.class, cellEditor);
JTableHeader header = sheetView.getTableHeader();
//Dont allow column reordering
header.setReorderingAllowed(false);
//Only allow column resizing if editing is allowed
header.setResizingAllowed(allowEdits);
//Set the columns the correct size
TableColumnModel columns = sheetView.getColumnModel();
for (int i=0; i< columns.getColumnCount(); i++) {
TableColumn column = columns.getColumn(i);
short width = sheet.getColumnWidth((short)i);
//256 is because the width is in 256ths of a character
column.setPreferredWidth(width/256*magicCharFactor);
}
//Set the rows to the correct size
int rows = sheet.getPhysicalNumberOfRows();
Insets insets = cellRenderer.getInsets();
//Need to include the insets in the calculation of the row height to use.
int extraHeight = insets.bottom+insets.top;
for (int i=0; i< rows; i++) {
HSSFRow row = sheet.getRow(i);
if (row == null) {
sheetView.setRowHeight(i, (int)sheet.getDefaultRowHeightInPoints()+extraHeight);
} else {
sheetView.setRowHeight(i, (int)row.getHeightInPoints()+extraHeight);
}
}
//Add the row header to the sheet
SVRowHeader rowHeader = new SVRowHeader(sheet, sheetView, extraHeight);
JScrollPane scroll = new JScrollPane( sheetView );
scroll.setRowHeaderView(rowHeader);
return scroll;
}
public void paint(Graphics g) {
//JMH I am only overriding this to get a picture of the time taken to paint
long start = System.currentTimeMillis();
super.paint(g);
long elapsed = System.currentTimeMillis()-start;
System.out.println("Paint time = "+elapsed);
}
protected MouseListener createTabListener() {
return new TabListener();
}
/** This class defines the default MouseListener that listens to
* mouse events in the tabbed pane
*
* The default is to popup a menu when the event occurs over a tab
*/
private class TabListener implements MouseListener {
public JPopupMenu popup;
public TabListener() {
popup = new JPopupMenu("Sheet");
popup.add(createInsertSheetAction());
popup.add(createDeleteSheetAction());
popup.add(createRenameSheetAction());
}
protected Action createInsertSheetAction() {
return new InsertSheetAction();
}
protected Action createDeleteSheetAction() {
return new DeleteSheetAction();
}
protected Action createRenameSheetAction() {
return new RenameSheetAction();
}
/** This method will display the popup if the mouseevent is a popup event
* and the event occurred over a tab
*/
protected void checkPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
int tab = sheetPane.getUI().tabForCoordinate(sheetPane, e.getX(), e.getY());
if (tab != -1) {
popup.show(sheetPane, e.getX(), e.getY());
}
}
}
public void mouseClicked(MouseEvent e) {
checkPopup(e);
}
public void mousePressed(MouseEvent e) {
checkPopup(e);
}
public void mouseReleased(MouseEvent e) {
checkPopup(e);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
/** This class defines the action that is performed when the sheet is renamed*/
private class RenameSheetAction extends AbstractAction {
public RenameSheetAction() {
super("Rename");
}
public void actionPerformed(ActionEvent e) {
int tabIndex = sheetPane.getSelectedIndex();
if (tabIndex != -1) {
String newSheetName = (String)JOptionPane.showInputDialog(sheetPane, "Enter a new Sheetname", "Rename Sheet", JOptionPane.QUESTION_MESSAGE);
if (newSheetName != null) {
wb.setSheetName(tabIndex, newSheetName);
sheetPane.setTitleAt(tabIndex, newSheetName);
}
}
}
}
/** This class defines the action that is performed when a sheet is inserted*/
private class InsertSheetAction extends AbstractAction {
public InsertSheetAction() {
super("Insert");
}
public void actionPerformed(ActionEvent e) {
//Create a new sheet then search for the sheet and make sure that the
//sheetPane shows it.
HSSFSheet newSheet = wb.createSheet();
for (int i=0; i<wb.getNumberOfSheets();i++) {
HSSFSheet sheet = wb.getSheetAt(i);
if (newSheet == sheet) {
sheetPane.insertTab(wb.getSheetName(i), null, makeSheetView(sheet), null, i);
}
}
}
}
/** This class defines the action that is performed when the sheet is deleted*/
private class DeleteSheetAction extends AbstractAction {
public DeleteSheetAction() {
super("Delete");
}
public void actionPerformed(ActionEvent e) {
int tabIndex = sheetPane.getSelectedIndex();
if (tabIndex != -1) {
if (JOptionPane.showConfirmDialog(sheetPane, "Are you sure that you want to delete the selected sheet", "Delete Sheet?", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
wb.removeSheetAt(tabIndex);
sheetPane.remove(tabIndex);
}
}
}
}
public boolean isEditable() {
return allowEdits;
}
/**Main method*/
public static void main(String[] args) {
try {
FileInputStream in = new FileInputStream(args[0]);
HSSFWorkbook wb = new HSSFWorkbook(in);
in.close();
SViewerPanel p = new SViewerPanel(wb, true);
JFrame frame;
frame = new JFrame() {
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
public synchronized void setTitle(String title) {
super.setTitle(title);
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
}
};
frame.setTitle("Viewer Frame");
frame.getContentPane().add(p, BorderLayout.CENTER);
frame.setSize(800,640);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
}
}
}

View File

@ -0,0 +1,264 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.usermodel.contrib;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.NestableException;
import org.apache.poi.hssf.usermodel.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Various utility functions that make working with a cells and rows easier. The various
* methods that deal with style's allow you to create your HSSFCellStyles as you need them.
* When you apply a style change to a cell, the code will attempt to see if a style already
* exists that meets your needs. If not, then it will create a new style. This is to prevent
* creating too many styles. there is an upper limit in Excel on the number of styles that
* can be supported.
*
*@author Eric Pugh epugh@upstate.com
*/
public class HSSFCellUtil
{
private static HashMap unicodeMappings = new HashMap();
/**
* Get a row from the spreadsheet, and create it if it doesn't exist.
*
*@param rowCounter The 0 based row number
*@param sheet The sheet that the row is part of.
*@return The row indicated by the rowCounter
*/
public static HSSFRow getRow( int rowCounter, HSSFSheet sheet )
{
HSSFRow row = sheet.getRow( (short) rowCounter );
if ( row == null )
{
row = sheet.createRow( (short) rowCounter );
}
return row;
}
/**
* Get a specific cell from a row. If the cell doesn't exist, then create it.
*
*@param row The row that the cell is part of
*@param column The column index that the cell is in.
*@return The cell indicated by the column.
*/
public static HSSFCell getCell( HSSFRow row, int column )
{
HSSFCell cell = row.getCell( (short) column );
if ( cell == null )
{
cell = row.createCell( (short) column );
}
return cell;
}
/**
* Creates a cell, gives it a value, and applies a style if provided
*
* @param row the row to create the cell in
* @param column the column index to create the cell in
* @param value The value of the cell
* @param style If the style is not null, then set
* @return A new HSSFCell
*/
public static HSSFCell createCell( HSSFRow row, int column, String value, HSSFCellStyle style )
{
HSSFCell cell = getCell( row, column );
cell.setCellValue( value );
if ( style != null )
{
cell.setCellStyle( style );
}
return cell;
}
/**
* Create a cell, and give it a value.
*
*@param row the row to create the cell in
*@param column the column index to create the cell in
*@param value The value of the cell
*@return A new HSSFCell.
*/
public static HSSFCell createCell( HSSFRow row, int column, String value )
{
return createCell( row, column, value, null );
}
/**
* Take a cell, and align it.
*
*@param cell the cell to set the alignment for
*@param workbook The workbook that is being worked with.
*@param align the column alignment to use.
*@exception NestableException Thrown if an error happens.
*
* @see HSSFCellStyle for alignment options
*/
public static void setAlignment( HSSFCell cell, HSSFWorkbook workbook, short align ) throws NestableException
{
setCellStyleProperty( cell, workbook, "alignment", new Short( align ) );
}
/**
* Take a cell, and apply a font to it
*
*@param cell the cell to set the alignment for
*@param workbook The workbook that is being worked with.
*@param font The HSSFFont that you want to set...
*@exception NestableException Thrown if an error happens.
*/
public static void setFont( HSSFCell cell, HSSFWorkbook workbook, HSSFFont font ) throws NestableException
{
setCellStyleProperty( cell, workbook, "font", font );
}
/**
* This method attempt to find an already existing HSSFCellStyle that matches
* what you want the style to be. If it does not find the style, then it
* creates a new one. If it does create a new one, then it applyies the
* propertyName and propertyValue to the style. This is nessasary because
* Excel has an upper limit on the number of Styles that it supports.
*
*@param workbook The workbook that is being worked with.
*@param propertyName The name of the property that is to be
* changed.
*@param propertyValue The value of the property that is to be
* changed.
*@param cell The cell that needs it's style changes
*@exception NestableException Thrown if an error happens.
*/
public static void setCellStyleProperty( HSSFCell cell, HSSFWorkbook workbook, String propertyName, Object propertyValue )
throws NestableException
{
try
{
HSSFCellStyle originalStyle = cell.getCellStyle();
HSSFCellStyle newStyle = null;
Map values = PropertyUtils.describe( originalStyle );
values.put( propertyName, propertyValue );
values.remove( "index" );
// index seems like what index the cellstyle is in the list of styles for a workbook.
// not good to compare on!
short numberCellStyles = workbook.getNumCellStyles();
for ( short i = 0; i < numberCellStyles; i++ )
{
HSSFCellStyle wbStyle = workbook.getCellStyleAt( i );
Map wbStyleMap = PropertyUtils.describe( wbStyle );
wbStyleMap.remove( "index" );
if ( wbStyleMap.equals( values ) )
{
newStyle = wbStyle;
break;
}
}
if ( newStyle == null )
{
newStyle = workbook.createCellStyle();
newStyle.setFont( workbook.getFontAt( originalStyle.getFontIndex() ) );
PropertyUtils.copyProperties( newStyle, originalStyle );
PropertyUtils.setProperty( newStyle, propertyName, propertyValue );
}
cell.setCellStyle( newStyle );
}
catch ( Exception e )
{
e.printStackTrace();
throw new NestableException( "Couldn't setCellStyleProperty.", e );
}
}
/**
* Looks for text in the cell that should be unicode, like &alpha; and provides the
* unicode version of it.
*
*@param cell The cell to check for unicode values
*@return transalted to unicode
*/
public static HSSFCell translateUnicodeValues( HSSFCell cell )
{
String s = cell.getStringCellValue();
boolean foundUnicode = false;
for ( Iterator i = unicodeMappings.entrySet().iterator(); i.hasNext(); )
{
Map.Entry entry = (Map.Entry) i.next();
String key = (String) entry.getKey();
if ( s.toLowerCase().indexOf( key ) != -1 )
{
s = StringUtils.replace( s, key, "" + entry.getValue().toString() + "" );
foundUnicode = true;
}
}
if ( foundUnicode )
{
cell.setEncoding( HSSFCell.ENCODING_UTF_16 );
cell.setCellValue( s );
}
return cell;
}
static {
unicodeMappings.put( "&alpha;", "\u03B1" );
unicodeMappings.put( "&beta;", "\u03B2" );
unicodeMappings.put( "&gamma;", "\u03B3" );
unicodeMappings.put( "&delta;", "\u03B4" );
unicodeMappings.put( "&epsilon;", "\u03B5" );
unicodeMappings.put( "&zeta;", "\u03B6" );
unicodeMappings.put( "&eta;", "\u03B7" );
unicodeMappings.put( "&theta;", "\u03B8" );
unicodeMappings.put( "&iota;", "\u03B9" );
unicodeMappings.put( "&kappa;", "\u03BA" );
unicodeMappings.put( "&lambda;", "\u03BB" );
unicodeMappings.put( "&mu;", "\u03BC" );
unicodeMappings.put( "&nu;", "\u03BD" );
unicodeMappings.put( "&xi;", "\u03BE" );
unicodeMappings.put( "&omicron;", "\u03BF" );
}
}

View File

@ -0,0 +1,226 @@
/* ====================================================================
Copyright 2002-2004 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.
==================================================================== */
package org.apache.poi.hssf.usermodel.contrib;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.Region;
import org.apache.commons.lang.exception.NestableException;
/**
* Various utility functions that make working with a region of cells easier.
*
*@author Eric Pugh epugh@upstate.com
*@since July 29, 2002
*/
public class HSSFRegionUtil
{
/** Constructor for the HSSFRegionUtil object */
private HSSFRegionUtil() { }
/**
* Sets the left border for a region of cells by manipulating the cell style
* of the indidual cells on the left
*
*@param border The new border
*@param region The region that should have the border
*@param workbook The workbook that the region is on.
*@param sheet The sheet that the region is on.
*@exception NestableException Thrown if the CellStyle can't be changed
*/
public static void setBorderLeft( short border, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
throws NestableException {
int rowStart = region.getRowFrom();
int rowEnd = region.getRowTo();
int column = region.getColumnFrom();
for ( int i = rowStart; i <= rowEnd; i++ ) {
HSSFRow row = HSSFCellUtil.getRow( i, sheet );
HSSFCell cell = HSSFCellUtil.getCell( row, column );
HSSFCellUtil.setCellStyleProperty( cell, workbook, "borderLeft", new Short( border ) );
}
}
/**
* Sets the leftBorderColor attribute of the HSSFRegionUtil object
*
*@param color The color of the border
*@param region The region that should have the border
*@param workbook The workbook that the region is on.
*@param sheet The sheet that the region is on.
*@exception NestableException Thrown if the CellStyle can't be changed
* properly.
*/
public static void setLeftBorderColor( short color, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
throws NestableException {
int rowStart = region.getRowFrom();
int rowEnd = region.getRowTo();
int column = region.getColumnFrom();
for ( int i = rowStart; i <= rowEnd; i++ ) {
HSSFRow row = HSSFCellUtil.getRow( i, sheet );
HSSFCell cell = HSSFCellUtil.getCell( row, column );
HSSFCellUtil.setCellStyleProperty( cell, workbook, "leftBorderColor", new Short( color ) );
}
}
/**
* Sets the borderRight attribute of the HSSFRegionUtil object
*
*@param border The new border
*@param region The region that should have the border
*@param workbook The workbook that the region is on.
*@param sheet The sheet that the region is on.
*@exception NestableException Thrown if the CellStyle can't be changed
*/
public static void setBorderRight( short border, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
throws NestableException {
int rowStart = region.getRowFrom();
int rowEnd = region.getRowTo();
int column = region.getColumnTo();
for ( int i = rowStart; i <= rowEnd; i++ ) {
HSSFRow row = HSSFCellUtil.getRow( i, sheet );
HSSFCell cell = HSSFCellUtil.getCell( row, column );
HSSFCellUtil.setCellStyleProperty( cell, workbook, "borderRight", new Short( border ) );
}
}
/**
* Sets the rightBorderColor attribute of the HSSFRegionUtil object
*
*@param color The color of the border
*@param region The region that should have the border
*@param workbook The workbook that the region is on.
*@param sheet The sheet that the region is on.
*@exception NestableException Thrown if the CellStyle can't be changed
* properly.
*/
public static void setRightBorderColor( short color, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
throws NestableException {
int rowStart = region.getRowFrom();
int rowEnd = region.getRowTo();
int column = region.getColumnTo();
for ( int i = rowStart; i <= rowEnd; i++ ) {
HSSFRow row = HSSFCellUtil.getRow( i, sheet );
HSSFCell cell = HSSFCellUtil.getCell( row, column );
HSSFCellUtil.setCellStyleProperty( cell, workbook, "rightBorderColor", new Short( color ) );
}
}
/**
* Sets the borderBottom attribute of the HSSFRegionUtil object
*
*@param border The new border
*@param region The region that should have the border
*@param workbook The workbook that the region is on.
*@param sheet The sheet that the region is on.
*@exception NestableException Thrown if the CellStyle can't be changed
*/
public static void setBorderBottom( short border, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
throws NestableException {
int colStart = region.getColumnFrom();
int colEnd = region.getColumnTo();
int rowIndex = region.getRowTo();
HSSFRow row = HSSFCellUtil.getRow( rowIndex, sheet );
for ( int i = colStart; i <= colEnd; i++ ) {
HSSFCell cell = HSSFCellUtil.getCell( row, i );
HSSFCellUtil.setCellStyleProperty( cell, workbook, "borderBottom", new Short( border ) );
}
}
/**
* Sets the bottomBorderColor attribute of the HSSFRegionUtil object
*
*@param color The color of the border
*@param region The region that should have the border
*@param workbook The workbook that the region is on.
*@param sheet The sheet that the region is on.
*@exception NestableException Thrown if the CellStyle can't be changed
* properly.
*/
public static void setBottomBorderColor( short color, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
throws NestableException {
int colStart = region.getColumnFrom();
int colEnd = region.getColumnTo();
int rowIndex = region.getRowTo();
HSSFRow row = HSSFCellUtil.getRow( rowIndex, sheet );
for ( int i = colStart; i <= colEnd; i++ ) {
HSSFCell cell = HSSFCellUtil.getCell( row, i );
HSSFCellUtil.setCellStyleProperty( cell, workbook, "bottomBorderColor", new Short( color ) );
}
}
/**
* Sets the borderBottom attribute of the HSSFRegionUtil object
*
*@param border The new border
*@param region The region that should have the border
*@param workbook The workbook that the region is on.
*@param sheet The sheet that the region is on.
*@exception NestableException Thrown if the CellStyle can't be changed
*/
public static void setBorderTop( short border, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
throws NestableException {
int colStart = region.getColumnFrom();
int colEnd = region.getColumnTo();
int rowIndex = region.getRowFrom();
HSSFRow row = HSSFCellUtil.getRow( rowIndex, sheet );
for ( int i = colStart; i <= colEnd; i++ ) {
HSSFCell cell = HSSFCellUtil.getCell( row, i );
HSSFCellUtil.setCellStyleProperty( cell, workbook, "borderTop", new Short( border ) );
}
}
/**
* Sets the topBorderColor attribute of the HSSFRegionUtil object
*
*@param color The color of the border
*@param region The region that should have the border
*@param workbook The workbook that the region is on.
*@param sheet The sheet that the region is on.
*@exception NestableException Thrown if the CellStyle can't be changed
* properly.
*/
public static void setTopBorderColor( short color, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
throws NestableException {
int colStart = region.getColumnFrom();
int colEnd = region.getColumnTo();
int rowIndex = region.getRowFrom();
HSSFRow row = HSSFCellUtil.getRow( rowIndex, sheet );
for ( int i = colStart; i <= colEnd; i++ ) {
HSSFCell cell = HSSFCellUtil.getCell( row, i );
HSSFCellUtil.setCellStyleProperty( cell, workbook, "topBorderColor", new Short( color ) );
}
}
}

View File

View File

@ -0,0 +1,10 @@
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.

View File

@ -0,0 +1,21 @@
Release Checklist
-----------------
- build distributions
- sign distributions
- Generate announcements and HEADER.html
- upload distributions to correct dir
- tag CVS
- generate www pages and upload
- bump release ID
- send announcements to announcement@apache.org, announcements@xml.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)

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.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>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!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="Marketing">
<menu-item label="Case Studies" href="casestudies.html"/>
</menu>
<menu label="Project">
<menu-item label="Overview" href="overview.html"/>
<menu-item label="POIFS" href="poifs/index.html"/>
<menu-item label="HSSF" href="hssf/index.html"/>
<menu-item label="HWPF" href="hwpf/index.html"/>
<menu-item label="HPSF" href="hpsf/index.html"/>
<menu-item label="POI-Ruby" href="poi-ruby.html"/>
<menu-item label="POI-Utils" href="utils/index.html"/>
<menu-item label="Download" href="ext:download"/>
</menu>
<menu label="Community">
<menu-item label="News" href="news.html"/>
<menu-item label="Mirrors" href="mirrors.html"/>
<menu-item label="Changes" href="changes.html"/>
<menu-item label="To Do" href="todo.html"/>
<menu-item label="Get Involved" href="getinvolved/index.html"/>
<menu-item label="Mailing Lists" href="http://jakarta.apache.org/site/mail2.html#poi"/>
<menu-item label="Vision" href="plan/POI20Vision.html"/>
<menu-item label="History and Future" href="historyandfuture.html"/>
<menu-item label="Who We Are" href="who.html"/>
<menu-item label="Resolutions" href="resolutions/index.html"/>
</menu>
<menu label="Docs">
<menu-item label="Javadocs" href="ext:javadoc"/>
<menu-item label="FAQ" href="faq.html"/>
<menu-item label="Legal" href="legal.html"/>
<menu-item label="References" href="references/index.html"/>
<menu-item label="How to Build" href="howtobuild.html"/>
</menu>
<menu label="Translations">
<menu-item label="Index" href="trans/index.html"/>
<menu-item label="Guidelines" href="trans/guidelines.html"/>
<menu-item label="German (DE)" href="trans/de/index.html"/>
<menu-item label="Spanish (ES)" href="trans/es/index.html"/>
<menu-item label="Japanese (Web)" href="http://jakarta.terra-intl.com/poi/"/>
<menu-item label="Korean (Web)" href="http://jakarta.apache-korea.org/poi/"/>
</menu>
<menu label="Code">
<!-- <menu-item label="Source Code" 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="Top Voted Bugs" href="http://issues.apache.org/bugzilla/buglist.cgi?votes=1&amp;product=POI&amp;order=bugs.votes"/>
<menu-item label="Bug Database" href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI"/>
<menu-item label="Patches" href="http://issues.apache.org/bugzilla/buglist.cgi?product=POI&amp;short_desc=%5BPATCH%5D&amp;short_desc_type=allwordssubstr"/>
<menu-item label="Junit Test Results" href="ext:junit"/>
<menu-item label="Dependency Metrics" href="ext:jdepend"/>
<!-- <menu-item label="Checkstyle Metrics" href="http://jakarta.apache.org/poi/metrics/checkstyle/"/> -->
</menu>
</book>

View File

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
<document>
<header>
<title>Jakarta 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"/>
</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). Andrew C. Oliver (acoliver at apache dot org) has
agreed to have a few T-Shirts printed with the POI logo (once its
chosen) for the first
few best submissions. To submit a case study, either
<link href="http://jakarta.apache.org/poi/getinvolved/index.html">
submit a patch for this page</link> or email it to the
<link href="http://jakarta.apache.org/site/mail2.html#poi">mailing list
</link> (with [PATCH] prefixed subject, please).
</p>
</section>
<section>
<title>Case Studies</title>
<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 Jakarta-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://jakarta.apache.org/poi/">Jakarta POI</link>
project's
<link href="http://jakarta.apache.org/poi/hssf/">
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
CVS
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>
</body>
<footer>
<legal>
Copyright (c) @year@ The Apache Software Foundation All rights reserved.
$Revision$ $Date$
</legal>
</footer>
</document>

View File

@ -0,0 +1,134 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE changes PUBLIC "-//APACHE//DTD Changes V1.1//EN" "./dtd/changes-v11.dtd">
<changes>
<title>History of Changes</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"/>
<person id="RK" name="Rainer Klute" email="klute@apache.org"/>
</devs>
<release version="2.0-pre3" date="unreleased">
<action dev="RK" type="add">HPSF: Much better codepage support</action>
</release>
<release version="2.0-pre1" date="unreleased">
<action dev="POI-DEVELOPERS" type="add">Patch applied for deep cloning of worksheets was provided</action>
<action dev="POI-DEVELOPERS" type="add">Patch applied to allow sheet reordering</action>
<action dev="POI-DEVELOPERS" type="add">Added additional print area setting methods using row/column numbers</action>
<action dev="POI-DEVELOPERS" type="fix">HWPF: Negative Array size fix</action>
<action dev="POI-DEVELOPERS" type="update">Added argument pointers to support the IF formula</action>
<action dev="POI-DEVELOPERS" type="update">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">BlockingInputStream committed to help ensure reads</action>
<action dev="POI-DEVELOPERS" type="fix">Fixed problem with NaN values differing from the investigated value from file reads in FormulaRecords</action>
<action dev="POI-DEVELOPERS" type="fix">Patch for getColumnWidth in HSSF</action>
<action dev="POI-DEVELOPERS" type="add">Patch for dealing with mult-level numbered lists in HWPF</action>
<action dev="POI-DEVELOPERS" type="fix">Due to named reference work, several named-ranged bugs were closed</action>
<action dev="POI-DEVELOPERS" type="fix">Patch applied to prevent sheet corruption after a template modification</action>
<action dev="POI-DEVELOPERS" type="update">Shared Formulas now Supported</action>
<action dev="POI-DEVELOPERS" type="update">Added GreaterEqual, LessEqual and NotEqual to Formula Parser</action>
<action dev="POI-DEVELOPERS" type="update">Added GreaterThan and LessThan functionality to formulas</action>
<action dev="POI-DEVELOPERS" type="fix">Patches for i10n</action>
<action dev="POI-DEVELOPERS" type="update">POI Build System Updated</action>
<action dev="POI-DEVELOPERS" type="fix">font names can now be null</action>
</release>
<release version="1.10-dev" date="19 Feb 2003">
<action dev="POI-DEVELOPERS" type="add">Support for zoom level</action>
<action dev="POI-DEVELOPERS" type="add">Freeze and split pane support</action>
<action dev="POI-DEVELOPERS" type="add">Row and column headers on printouts</action>
</release>
<release version="1.8-dev" date="20 Sep 2002">
<action dev="POI-DEVELOPERS" type="add">Custom Data Format Support</action>
<action dev="POI-DEVELOPERS" type="add">Enhanced Unicode Support for Russian and Japanese</action>
<action dev="POI-DEVELOPERS" type="add">Enhanced formula support including read-only for
"optimized if" statements.</action>
<action dev="POI-DEVELOPERS" type="add">Support for cloning objects</action>
<action dev="POI-DEVELOPERS" type="add">Fixes for header/footer</action>
<action dev="POI-DEVELOPERS" type="add">Spanish Documentation translations</action>
<action dev="POI-DEVELOPERS" type="add">Support for preserving VBA macros</action>
</release>
<release version="1.7-dev" date="???">
<action dev="NKB" type="update">Removed runtime dependency on commons logging.</action>
<action dev="POI-DEVELOPERS" type="update">Formula support</action>
</release>
<release version="1.5.1" date="16 June 2002">
<action dev="GJS" type="update">Removed depedency on commons logging. Now define poi.logging system property to enable logging to standard out.</action>
<action dev="GJS" type="fix">Fixed SST string handling so that spreadsheets with rich text or extended text will be read correctly.</action>
</release>
<release version="1.5" date="06 May 2002">
<action dev="NKB" type="update">New project build.</action>
<action dev="NKB" type="update">New project documentation system based on Cocoon.</action>
<action dev="POI-DEVELOPERS" type="update">Package rename</action>
<action dev="POI-DEVELOPERS" type="fix">Various bug fixes</action>
<action dev="POI-DEVELOPERS" type="add">Early stages of HSF development (not ready for development)</action>
<action dev="POI-DEVELOPERS" type="add">Initial low level record support for charting (not complete)</action>
</release>
<release version="1.1.0" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Created new event model</action>
<action dev="POI-DEVELOPERS">Optimizations made to HSSF including aggregate records for
values, rows, etc.</action>
<action dev="POI-DEVELOPERS">predictive sizing, offset based writing (instead of lots of
array copies)</action>
<action dev="POI-DEVELOPERS">minor re-factoring and bug fixes.</action>
</release>
<release version="1.0.0" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Minor documentation updates.</action>
</release>
<release version="0.14.0" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Added DataFormat helper class and exposed set and get format
on HSSFCellStyle</action>
<action dev="POI-DEVELOPERS">Fixed column width apis (unit wise) and various javadoc on
the subject</action>
<action dev="POI-DEVELOPERS">Fix for Dimensions record (again)... (one of these days I'll
write a unit test for this ;-p).</action>
<action dev="POI-DEVELOPERS">Some optimization on sheet creation.</action>
</release>
<release version="0.13.0" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Changes not recorded.</action>
</release>
<release version="0.12.0" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Added MulBlank, Blank, ColInfo</action>
<action dev="POI-DEVELOPERS">Added log4j facility and removed all sys.out type logging</action>
<action dev="POI-DEVELOPERS">Added support for adding font's, styles and corresponding
high level api for styling cells</action>
<action dev="POI-DEVELOPERS">added support for changing row height, cell width and default
row height/cell width.</action>
<action dev="POI-DEVELOPERS">Added fixes for internationalization (UTF-16 should work now
from HSSFCell.setStringValue, etc when the encoding is set)</action>
<action dev="POI-DEVELOPERS">added support for adding/removing and naming sheets.</action>
</release>
<release version="0.11.0" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Bugfix release. We were throwing an exception when reading
RKRecord objects.</action>
</release>
<release version="0.10.0" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Got continuation records to work (read/write)</action>
<action dev="POI-DEVELOPERS">Added various pre-support for formulas</action>
<action dev="POI-DEVELOPERS">Massive API reorganization, repackaging.</action>
<action dev="POI-DEVELOPERS">BiffViewer class added for validating HSSF &amp; POI and/or
HSSF Output.</action>
<action dev="POI-DEVELOPERS">Better API support for modification.</action>
</release>
<release version="0.7 (and interim releases)" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Added encoding flag to high and low level api to use utf-16
when needed (HSSFCell.setEncoding())</action>
<action dev="POI-DEVELOPERS">added read only support for Label records (which are
reinterpreted as LabelSST when written)</action>
<action dev="POI-DEVELOPERS">Broken continuation record implementation (oops)</action>
<action dev="POI-DEVELOPERS">BiffViewer class added for validating HSSF &amp; POI and/or
HSSF Output.</action>
</release>
<release version="0.6 (release)" date="Release date not recorded">
<action dev="POI-DEVELOPERS">Support for read/write and modify.</action>
<action dev="POI-DEVELOPERS">Read only support for MulRK records (converted to Number when
writing)
</action>
</release>
</changes>

View File

@ -0,0 +1,70 @@
<!-- ===================================================================
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 -->
<!-- =============================================================== -->

View File

@ -0,0 +1,93 @@
<!-- ===================================================================
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 -->
<!-- =============================================================== -->

View File

@ -0,0 +1,541 @@
<!-- ===================================================================
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 -->
<!-- =============================================================== -->

View File

@ -0,0 +1,76 @@
<!-- ===================================================================
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 -->
<!-- =============================================================== -->

View File

@ -0,0 +1,254 @@
<!-- ===================================================================
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 -->
<!-- =============================================================== -->

View File

@ -0,0 +1,92 @@
<!-- ===================================================================
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 -->
<!-- =============================================================== -->

View File

@ -0,0 +1,93 @@
<!-- ===================================================================
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 document 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.
AUTHORS:
Stefano Mazzocchi <stefano@apache.org>
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)
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 % priorities "showstopper|high|medium|low|wish|dream">
<!ENTITY % contexts "build|docs|code|admin|design">
<!-- =============================================================== -->
<!-- Document Type Definition -->
<!-- =============================================================== -->
<!ELEMENT todo (devs, actions*)>
<!ATTLIST todo %common.att;
%title.att;>
<!ELEMENT devs (person+)>
<!ATTLIST devs %common.att;>
<!ELEMENT actions (action+)>
<!ATTLIST actions %common.att;
priority (%priorities;) #IMPLIED>
<!ELEMENT action (%content.mix;)*>
<!ATTLIST action %common.att;
assigned-to IDREF #IMPLIED
context (%contexts;) #REQUIRED>
<!-- =============================================================== -->
<!-- End of DTD -->
<!-- =============================================================== -->

View File

@ -0,0 +1,287 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE faqs PUBLIC "-//APACHE//DTD FAQ V1.1//EN" "./dtd/faq-v11.dtd">
<faqs title="Frequently Asked Questions">
<faq>
<question>
Why is reading a simple sheet taking so long?
</question>
<answer>
<p>You've probably enabled logging. Logging is intended only for
autopsie 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 HSSF eventmodel package is a new API for reading XLS files more efficiently. 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 to a given XLS file, 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 HSSF.
For example - spreadsheets containing cells with rich text are not currently supported.</p>
</answer>
</faq>
<faq>
<question>
Does HSSF support protected spreadsheets?
</question>
<answer>
<p>Protecting a spreadsheet encrypts it. We wont touch encryption because we're not legally educated
and don't understand the full implications of trying to implement this. If you wish to have a go
at this feel free to add it as a plugin module. We wont be hosting it here however.</p>
</answer>
</faq>
<faq>
<question>
How do you tell if a field contains a date with HSSF?
</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 (since the 1.7.0-dev release) 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&amp;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 HSSFDataFormat object from the workbook and call getFormat with the desired format. Some examples are <link href="hssf/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 HSSFDataFormat 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 tried to set cell values and Excel sheet name on my native language,
but I failed to do it. :(
</question>
<answer>
<p>By default HSSF uses cell values and sheet names as compressed unicode,
so to support localization you should use Unicode.
To do it you should set it manually:</p>
<source>
// for sheet name
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet();
wb.setSheetName( 0, "SomeUnicodeName", HSSFWorkbook.ENCODING_UTF_16 );
// for cell value
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>
Make sure you make the call to setEncoding() before calling setCellValue(), otherwise what you pass in won't be interpreted properly.
</p>
</answer>
</faq>
<faq>
<question>
I'm having trouble creating a spreadsheet using POI using
websphere 3.5.
</question>
<answer>
<p>Make sure you have fix pack 4 installed.</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 &lt; 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 &lt; 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 &lt; 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 &lt; 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>
Will POI read any spreadsheet and rewrite it with modifications.
</question>
<answer>
<p>POI is not guanteed to read the contents of any spreadsheet.
Certain features may cause spreadsheets to fail to read. More
problematic is rewriting spreadsheets. POI tried hard to
preserve the records of the original spreadsheet but some
features may cause problems. We advise that you limit the
formatting of spreadsheets you process so as to not be
unpleasantly suprised at a later stage.</p>
</answer>
</faq>
</faqs>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!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="Jakarta POI">
<menu-item label="Top" href="../index.html"/>
</menu>
<menu label="Get Involved">
<menu-item label="Contributing" href="index.html"/>
<menu-item label="Branching" href="branching.html"/>
<menu-item label="Mail Lists" href="http://jakarta.apache.org/site/mail2.html#poi"/>
</menu>
</book>

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
<document>
<header>
<title>Branching</title>
<authors>
<person id="GJS" name="Glen Stampoultzis" email="poi-user@jakarta.apache.org"/>
</authors>
</header>
<body>
<section><title>Branching Conventions</title>
<p>
Branches are tagged in the following way:
</p>
<ul>
<li>REL_1_5_BRANCH</li>
<li>REL_2_0_BRANCH</li>
</ul>
<p>
Merge points should be tagged as follows:
</p>
<ul>
<li>REL_1_5_BRANCH_MERGE1</li>
<li>REL_1_5_BRANCH_MERGE2</li>
<li>etc...</li>
</ul>
<p>
Releases should be tagged as:
</p>
<ul>
<li>REL_1_5</li>
<li>REL_1_5_1</li>
<li>REL_1_5_2</li>
<li>etc...</li>
</ul>
</section>
<section><title>Branching Advise</title>
<p>
Don't forget which branch you are currently on. This is critically
important. Committing stuff to the wrong branch causes all sorts of
headaches. Best to name your checkout after the branch you are on.
</p>
</section>
<section><title>Who Manages Branching?</title>
<p>
All branching is currently managed by Glen Stampoultzis. If you wish
to create your own branch please let him know. Merging is also
handled by Glen. Just pop him a mail if you feel it's necessary to
create a branch or perform a merge.
</p>
<p>
The reason to go through a single point for branching is that it can be
an easy thing to get wrong. Having a single person managing branches
means there is less chance of getting getting our wires crossed with this
difficult area of CVS.
</p>
</section>
<section><title>Currently Active Branches</title>
<p>
The following branches are currently active:
</p>
<table>
<tr>
<th>
Branch
</th>
<th>
Description
</th>
</tr>
<tr>
<td>
HEAD
</td>
<td>
This is the trunk and is always active. Currently it is being used to continue development
of the 2.0 release.
</td>
</tr>
<tr>
<td>
REL_1_5_BRANCH
</td>
<td>
All bug fixes not specifically relevant to the 2.0 work should be placed in this branch.
From here they will merged back to the trunk and the merge point marked.
</td>
</tr>
</table>
</section>
</body>
</document>

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
<document>
<header>
<title>Contribution to POI</title>
<authors>
<person name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
<person name="Marc Johnson" email="mjohnson@apache.org"/>
<person name="Andrew C. Oliver" email="acoliver@apache.org"/>
<person name="Tetsuya Kitahata" email="tetsuya.kitahata@nifty.com"/>
</authors>
</header>
<body>
<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/licence-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>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. 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
(probably illegally) received such information from a person bound by
such an agreement, you cannot participate in this project. (Sorry)
</p>
<p>
Those submitting patches that show insight into the file format may be
asked to state explicitly that they are eligible or possibly sign an
agreement.
</p>
</section>
</section>
<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 mail lists and share your knowledge with others.</li>
<li>Get <link href="http://jakarta.apache.org/site/cvsindex.html">CVS</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>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>(HSSF)Get the Excel 97 Developer's Kit - its out of print but its dirt cheap (seen copies for under $15 (US)) used on <link href="http://www.amazon.com">amazon</link>. It explains the Excel file format.</li>
<li>Submit patches (see below) of your contributions, modifications.</li>
<li>Fill out new features, see <link href="http://jakarta.apache.org/site/bugs.html">Bug database</link> for suggestions.</li>
</ul>
</section>
<section><title>Submitting Patches</title>
<p>
Create patches by getting the latest sources from CVS (the HEAD).
Alter or add files as appropriate. Then, from the jakarta-poi directiory,
type cvs diff -u > mypatch.patch. This will capture all of your changes
in a patch file of the appropriate format. Next, if you've added any
files, create an archive (tar.bz2 preferred as its the smallest) in a
path-preserving archive format, relative to your jakarta-poi directory.
(Note: If you use <link href="http://www.wincvs.org/">WinCVS</link>, move to
[Admin] -&gt; [Command Line] Menu and type "cvs diff -u" at
[Enter a cvs line command] input field ([Commandline Settings] Tab),
while selecting the target directories or files, in order to create
unified diffs.
In other words, [Alt+A]+[Alt+C]+[Alt+C] and type "cvs diff -u".)
You'll attach both files in the next step.
</p>
<p>
Patches are submitted via the <link href="http://jakarta.apache.org/site/bugs.html">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>
Make sure your patches include the @author tag on any files you've altered
or created. Make sure you've documented your changes and altered the
examples/etc to reflect them. Any new additions should have unit tests.
Lastly, ensure that you've provided approriate javadoc. (see
<link href="http://jakarta.apache.org/poi/resolutions/res001.html">Coding
Standards</link>). Patches that are of low quality may be rejected or
the contributer may be asked to bring them up to spec.
</p>
</section>
</body>
</document>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
<document>
<header>
<title>Jakarta POI - Project History</title>
<authors>
<person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
</authors>
</header>
<body>
<section><title>Jakarta 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>
</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.
$Revision$ $Date$
</legal>
</footer>
</document>

View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>How To Build POI</title>
<authors>
<person email="poi-user@jakarta.apache.org" name="Glen Stampoultzis" id="GS"/>
<person email="tetsuya@apache.org" name="Tetsuya Kitahata" id="TK"/>
</authors>
</header>
<body>
<section>
<title>Installing Ant</title>
<p>
The POI build system requires two components to perform a
build.
<link href="ext:jakarta.apache.org/ant">Ant</link> and
<link href="ext:xml.apache.org/forrest">forrest</link>.
</p>
<p>
Specifically the build has been tested to work with Ant version
1.5.3 and Forrest 0.4. To install these products download
the distributions and follow the instructions in their
documentation. Make sure you don't forget to set the
environment variables FORREST_HOME and ANT_HOME. The
ANT_HOME/bin directory should be in the path.
</p>
<p>
One these products are installed you will also need to
download some extra jar files required by the build.
</p>
<table>
<tr>
<th>Library</th>
<th>Location</th>
</tr>
<tr>
<td>junit</td>
<td>http://www.ibiblio.org/maven/junit/jars/</td>
</tr>
<tr>
<td>xerces</td>
<td>http://www.ibiblio.org/maven/xerces/jars/</td>
</tr>
<tr>
<td>jdepend</td>
<td>http://www.ibiblio.org/maven/jdepend/jars/</td>
</tr>
<tr>
<td>xalan</td>
<td>http://www.ibiblio.org/maven/xalan/jars/</td>
</tr>
</table>
<p>
Just pick the latest versions of these jars and place
them in ANT_HOME/lib and make sure that optional.jar is
in ANT_HOME/lib .
</p>
</section>
<section>
<title>Running the Build</title>
<p>
On the first run the ant build system will download all
the jars required by the project to build ant. If you're
behind a firewall this may cause some problems. Should you
need to it's possible to manually put the jars in the
correct directories. These can be obtained from here:
</p>
<table>
<tr>
<th>JAR</th>
<th>Location</th>
</tr>
<tr>
<td>/commons-logging/jars/commons-logging-1.0.1.jar</td>
<td>lib</td>
</tr>
<tr>
<td>/log4j/jars/log4j-1.2.8.jar</td>
<td>lib</td>
</tr>
<tr>
<td>/commons-beanutils/jars/commons-beanutils-1.6.jar</td>
<td>src/contrib/lib</td>
</tr>
<tr>
<td>/commons-collections/jars/commons-collections-2.1.jar</td>
<td>src/contrib/lib</td>
</tr>
<tr>
<td>/commons-lang/jars/commons-lang-1.0-b1.jar</td>
<td>src/contrib/lib</td>
</tr>
<tr>
<td>/junit/jars/junit-3.8.1.jar</td>
<td>lib</td>
</tr>
</table>
<p>
The main targets of interest to our users are:
</p>
<table>
<tr>
<th>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, contrib and scratchpad</td>
</tr>
<tr>
<td>test</td>
<td>Run all unit tests from main, contrib and scratchpad</td>
</tr>
<tr>
<td>docs</td>
<td>Generate all documentation for the system</td>
</tr>
<tr>
<td>generate-records</td>
<td>Generate records from the XML record defintitions</td>
</tr>
<tr>
<td>generate-types</td>
<td>Generate types from the XML type definitions (this is
for HWPF).</td>
</tr>
<tr>
<td>jar</td>
<td>Produce jar files</td>
</tr>
<tr>
<td>dist</td>
<td>Create a distribution.</td>
</tr>
<tr>
<td>clean-dist</td>
<td>Runs clean before creating the distribution.</td>
</tr>
</table>
</section>
</body>
</document>

View File

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
<!-- $Id$ -->
<book software="POI Project"
title="HPSF"
copyright="@year@ POI Project">
<menu label="Jakarta 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>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<!-- $Id$ -->
<document>
<header>
<title>Jakarta 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:
-->

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
"../dtd/document-v11.dtd">
<!-- $Id$ -->
<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&copy; 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:
-->

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<!-- $Id$ -->
<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:
-->

View File

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

View File

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
<book software="POI Project"
title="HSSF"
copyright="@year@ POI Project">
<menu label="Jakarta POI">
<menu-item label="Top" href="../index.html"/>
</menu>
<menu label="HSSF">
<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="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="Use Case" href="use-case.html"/>
<menu-item label="Pictorial Docs" href="diagrams.html"/>
<menu-item label="Alternatives" href="alternatives.html"/>
<menu-item label="Limitations" href="limitations.html"/>
</menu>
<menu label="Contributer's Guide">
<menu-item label="Hacking HSSF" href="hacking-hssf.html"/>
<menu-item label="Record Generator" href="record-generator.html"/>
<menu-item label="Charts" href="chart.html"/>
</menu>
</book>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!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>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!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 &quot;bug&quot; to the bug database with [DOCUMENTATION]
prefacing the description and a link to the file on an http server
somewhere. If you don't have your own webserver, then you can email it
to (acoliver at apache dot org) provided its &lt; 5MB. Diagrams should be
in some format that can be read at least on Linux and Windows. Diagrams
that can be edited are preferrable, but lets face it, there aren't too
many good affordable UML tools yet! And no they don't HAVE to be UML...
just useful.
</p>
</section>
</body>
</document>

View File

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2005 The Apache Software Foundation. All rights reserved. -->
<!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"/>
</authors>
</header>
<body>
<section><title>Introduction</title>
<p>This document is for developers wishing to contribute to the
FormulaEvaluator API functionality.</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 in POI-HSSF main.
(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>Ofcourse 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
basic testing has been done </p>
</section>
<section><title> FunctionEval and FuncVarEval</title>
<p>FunctionEval is an abstract super class of FuncVarEval. The reason for this is that in the FormulaParser Ptg classes, there are two Ptgs, FuncPtg and FuncVarPtg. In my tests, I did not see FuncPtg being used so there is no corresponding FuncEval right now. But in case the need arises for a FuncVal class, FuncEval and FuncVarEval need to be isolated with a common interface/abstract class, hence FunctionEval.</p>
<p>FunctionEval also contains the mapping of which function class maps to which function index. This mapping has been done for all the functions, so all you really have to do is implement the evaluate method in the function class that has not already been implemented. The Function indexes are defined in AbstractFunctionPtg class in POI main.</p>
</section>
</section>
<section><title>Walkthrough of an "evaluate()" implementation.</title>
<p>So here is the fun part - lets walk through the implementation of the excel
function... <strong>AVERAGE()</strong> </p>
<section><title>The Code</title>
<source>
public Eval evaluate(Eval[] operands) {
double d = 0;
int count = 0;
ValueEval retval = null;
for (int i = 0, iSize = operands.length; i &lt; iSize; i++) {
if (operands[i] == null) continue;
if (operands[i] instanceof AreaEval) {
AreaEval ap = (AreaEval) operands[i];
Object[] values = ap.getValues();
for (int j = 0, jSize = values.length; j &lt; jSize; j++) {
if (values[j] == null) continue;
if (values[j] instanceof NumberEval) {
//inside areas, ignore bools
d += ((NumberEval) values[j]).getNumberValue();
count++;
}
else if (values[j] instanceof RefEval) {
RefEval re = (RefEval) values[j];
ValueEval ve = re.getInnerValueEval();
if (ve != null &amp;&amp; ve instanceof NumberEval) {
d += ((NumberEval) ve).getNumberValue();
count++;
}
}
}
}
else if (operands[i] instanceof NumericValueEval) {
// for direct operands evaluate bools
NumericValueEval np = (NumericValueEval) operands[i];
d += np.getNumberValue();
count++;
}
else if (operands[i] instanceof RefEval) {
RefEval re = (RefEval) operands[i];
ValueEval ve = re.getInnerValueEval();
if (ve instanceof NumberEval) {
//if it is a reference, ignore bools
NumberEval ne = (NumberEval) ve;
d += ne.getNumberValue();
count++;
}
}
}
if (retval == null) {
retval = (Double.isNaN(d)) ?
(ValueEval) ErrorEval.ERROR_503 : new NumberEval(d/count);
}
return retval;
}
</source>
</section>
<section><title>Implementation Details</title>
<ul>
<li>The implementation of the AVERAGE function lives in package
o.a.p.hssf.record.formula.functions named Average.java.
(Every excel function has a corresponding java source file
in the above package) </li>
<li>If you open the file for a function thats not yet implemented, you will see one un-implemented method:
<code>public Eval evaluate(Eval[] operands) {}</code> </li>
<li>Since the excel Average() function can take 1 or more operands, we iterate over all operands that are passed in the evaluate method:
<code>for (int i=0, iSize=operands.length; i&lt;iSize; i++) {...}</code></li>
<li>inside the loop, you will do the following
<ol>
<li>Do a null check: <code>if (operands[i] == null) continue;</code></li>
<li>Figure out the actual subtype of ValueEval that the operands
implements. The possible types that you will encounter in an
evaluate() are: NumberEval, BoolEval, StringEval, ErrorEval,
AreaEval, RefEval, BlankEval.</li>
<li>Implement the function. See the next section for some
caveats on implementing the Excel semantics. </li>
</ol>
</li>
<li>Finally before returning the NumberEval wrapping the double value that
you computed, do one final check to see if the double is a NaN,
if it is return ErrorEval.ERROR_503 (see the javadoc in ErrorEval.java
for description of error codes - it is html so you might as well
generate the javadocs)</li>
</ul>
</section>
<section><title>Modelling Excel Semantics</title>
<p>Strings are ignored. Booleans are ignored!!! (damn Oo.o! I was almost misled here - nevermind). Actually here's the info on Bools:
if you have formula: "=TRUE+1", it evaluates to 2.
So also, when you use TRUE like this: "=SUM(1,TRUE)", you see the result is: 2.
So TRUE means 1 when doing numeric calculations, right?
Wrong!
Because when you use TRUE in referenced cells with arithmetic functions, it evaluates to blank - meaning it is not evaluated - as if it was string or a blank cell.
eg. "=SUM(1,A1)" when A1 is TRUE evaluates to 1.
So you have to do this kind of check for every possible data type as a function argument for any function before you understand the behaviour of the function. The operands can be entered in excel as comma separated or as a region specified like: A2:D4. Regions are treated as a single token by the parser hence we have AreaEval which stores the ValueEval at each cell in a region in a 1D array. So in our function if the operand is of type AreaEval we need to get the array of ValueEvals in the region of the AreaEval and iterate over each of them as if each of them were individual operands to the AVERAGE function.
</p>
<p>Thus, since sometimes, Excel treats
Booleans as the numbers 0 and 1 (for F and T respectively).
Hence BoolEval and NumberEval both implement a common interface:
NumericValueEval (since numbers and bools are also valid string
values, they also implement StringValueEval interface which is
also implemented by StringEval).</p>
<p>
The ValueEval inside an AreaEval can be one of:
NumberEval, BoolEval, StringEval, ErrorEval, BlankEval.
So you must handle each of these cases.
Similarly, RefEvals have a property: innerValueEval that returns the ValueEval at the referenced cell. The ValueEval inside a RefEval can be one of: NumberEval, BoolEval, StringEval, ErrorEval, BlankEval. So you must handle each of these cases - see how excel treats each one of them.
</p>
</section>
</section>
<section><title>Testing Framework</title>
<fixme author="AD">TODO! FormulaEval comes with a testing framework, where you add
formula's and their expected values to an Excel sheet, and the test code
automatically validates them. Since this is still in flux, the docs
will be put online once the system is stable </fixme>
</section>
</body>
</document>

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2005 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Formula Evaluation</title>
<authors>
<person email="amoweb@yahoo.com" name="Amol Deshmukh" id="AD"/>
</authors>
</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>
<warning> This code currently lives in Bugzilla as
<link href="http://issues.apache.org/bugzilla/show_bug.cgi?id=34828">
bug 34828 </link>. It is expected to land in POI CVS in the scratchpad
area soon.
</warning>
</section>
<section><title>Status</title>
<p> The code currently provides implementations for all the arithmatic operators.
It also provides implementations for about 30 built in
functions in Excel. The framework however makes is easy to add
implementation of new functions. See the <link href="eval-devguide.html"> Formula
evaluation development guide</link> for details. </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 HSSFFormulaEvaluator
in the context of other POI excel reading code.
</p>
<p>There are two ways in which you can use the HSSFFormulaEvalutator API.</p>
<section><title>Using HSSFFormulaEvaluator.<strong>evaluate</strong>(HSSFCell cell)</title>
<source>
FileInputStream fis = new FileInputStream("c:/temp/test.xls");
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
// suppose your formula is in B3
CellReference cellReference = new CellReference("B3");
HSSFRow row = sheet.getRow(cellReference.getRow());
HSSFCell cell = row.getCell(cellReference.getCol());
String formulaString = c.getCellFormula();
HSSFFormulaEvaluator.CellValue cellValue =
evaluator.evaluate(formulaString);
switch (cellValue.getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
System.out.println(cellValue.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
System.out.println(cellValue.getNumberCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
System.out.println(cellValue.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
break;
case HSSFCell.CELL_TYPE_ERROR:
break;
// CELL_TYPE_FORMULA will never happen
case HSSFCell.CELL_TYPE_FORMULA:
break;
}
</source>
<p>Thus using the retrieved value (of type
HSSFFormulaEvaluator.CellValue - a nested class) returned
by HSSFFormulaEvaluator is similar to using a HSSFCell 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>
<section><title>Using HSSFFormulaEvaluator.<strong>evaluateInCell</strong>(HSSFCell cell)
</title>
<source>
FileInputStream fis = new FileInputStream("c:/temp/test.xls");
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
// suppose your formula is in B3
CellReference cellReference = new CellReference("B3");
HSSFRow row = sheet.getRow(cellReference.getRow());
HSSFCell cell = row.getCell(cellReference.getCol());
String formulaString = c.getCellFormula();
if (cell!=null) {
switch (<strong>evaluator.evaluateInCell</strong>(cell).getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
System.out.println(cell.getNumberCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
System.out.println(cell.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
break;
case HSSFCell.CELL_TYPE_ERROR:
System.out.println(cell.getErrorCellValue());
break;
// CELL_TYPE_FORMULA will never occur
case HSSFCell.CELL_TYPE_FORMULA:
break;
}
}
</source>
</section>
</section>
<section><title></title>
</section>
<section><title>Performance Notes</title>
<ul>
<li>Generally you should have to create only one HSSFFormulaEvaluator
instance per sheet, but there really is no overhead in creating
multiple HSSFFormulaEvaluators per sheet other than that of the
HSSFFormulaEvaluator object creation.
</li>
<li>Also note that HSSFFormulaEvaluator 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
HSSFFormulaEvaluator 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
HSSFCell or the sheet or workbook, so these can be long-lived
objects without any adverse effect on performance.
</li>
</ul>
</section>
</body>
</document>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!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 2.0 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(&quot;formulaString&quot;) </strong> is used to add a formula to sheet and
<strong> getCellFormula() </strong> is used to retrieve the string representation of a formula.
</p>
<p>
We aim to support the complete excel grammer for formulas. Thus, the string that you pass in
to the <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 and logical operators</li>
<li>Sheet or Macro Functions (inlcuding logical functions)</li>
<li>Sheet References</li>
<li>Formual return values (number or string)</li>
</ul>
</section>
<section><title>Partially supported</title>
<ul>
<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>Unary Operators</li>
<li>3D References</li>
<li>Error Values (cells containing #REF's or #VALUE's)</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>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>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>

View File

@ -0,0 +1,491 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!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="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 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>
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>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,&quot;SheetName&quot;,encoding).
The name may be in 8bit format (HSSFWorkbook.ENCODING_COMPRESSED_UNICODE)
or Unicode (HSSFWorkbook.ENCODING_UTF_16). Default encoding is 8bit per char.
</p>
<p>Rows are created by calling createRow(rowNumber) from an existing
instance of HSSFSheet. Only rows that have cell values should be
added to the sheet. To set the row's height, you just call
setRowHeight(height) on the row object. The height must be given in
twips, or 1/20th of a point. If you prefer, there is also a
setRowHeightInPoints method.
</p>
<p>Cells are created by calling createCell(column, type) from an
existing HSSFRow. Only cells that have values should be added to the
row. Cells should have their cell type set to either
HSSFCell.CELL_TYPE_NUMERIC or HSSFCell.CELL_TYPE_STRING depending on
whether they contain a numeric or textual value. Cells must also have
a value set. Set the value by calling setCellValue with either a
String or double as a parameter. Individual cells do not have a
width; you must call setColumnWidth(colindex, width) (use units of
1/256th of a character) on the HSSFSheet object. (You can't do it on
an individual basis in the GUI either).</p>
<p>Cells are styled with HSSFCellStyle objects which in turn contain
a reference to an HSSFFont object. These are created via the
HSSFWorkbook object by calling createCellStyle() and createFont().
Once you create the object you must set its parameters (colors,
borders, etc). To set a font for an HSSFCellStyle call
setFont(fontobj).
</p>
<p>Once you have generated your workbook, you can write it out by
calling write(outputStream) from your instance of Workbook, passing
it an OutputStream (for instance, a FileOutputStream or
ServletOutputStream). You must close the OutputStream yourself. HSSF
does not close it for you.
</p>
<p>Here is some example code (excerpted and adapted from
org.apache.poi.hssf.dev.HSSF test class):</p>
<source><![CDATA[
short rownum;
// create a new file
FileOutputStream out = new FileOutputStream("workbook.xls");
// create a new workbook
HSSFWorkbook wb = new HSSFWorkbook();
// create a new sheet
HSSFSheet s = wb.createSheet();
// declare a row object reference
HSSFRow r = null;
// declare a cell object reference
HSSFCell c = null;
// create 3 cell styles
HSSFCellStyle cs = wb.createCellStyle();
HSSFCellStyle cs2 = wb.createCellStyle();
HSSFCellStyle cs3 = wb.createCellStyle();
HSSFDataFormat df = wb.createDataFormat();
// 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
cs.setDataFormat(df.getFormat("#,##0.0"));
//set a thin border
cs2.setBorderBottom(cs2.BORDER_THIN);
//fill w fg fill color
cs2.setFillPattern((short) HSSFCellStyle.SOLID_FOREGROUND);
//set the cell format to text see HSSFDataFormat 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",
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(&quot;Workbook&quot;) and pass
it to HSSFEventFactory.processEvents(request, inputStream). Once you
make this call, the listeners that you constructed receive calls to
their processRecord(Record) methods with each Record they are
registered to listen for until the file has been completely read.
</p>
<p>A code excerpt from org.apache.poi.hssf.dev.EFHSSF (which is
in CVS or the source distribution) is reprinted below with excessive
comments:</p>
<source><![CDATA[
/**
* This example shows how to use the event API for reading a file.
*/
public class EventExample
implements HSSFListener
{
private SSTRecord sstrec;
/**
* This method listens for incoming records and handles them as required.
* @param record The record that was found while reading.
*/
public void processRecord(Record record)
{
switch (record.getSid())
{
// the BOFRecord can represent either the beginning of a sheet or the workbook
case BOFRecord.sid:
BOFRecord bof = (BOFRecord) record;
if (bof.getType() == bof.TYPE_WORKBOOK)
{
System.out.println("Encountered workbook");
// assigned to the class level member
} else if (bof.getType() == bof.TYPE_WORKSHEET)
{
System.out.println("Encountered sheet reference");
}
break;
case BoundSheetRecord.sid:
BoundSheetRecord bsr = (BoundSheetRecord) record;
System.out.println("New sheet named: " + bsr.getSheetname());
break;
case RowRecord.sid:
RowRecord rowrec = (RowRecord) record;
System.out.println("Row found, first column at "
+ rowrec.getFirstCol() + " last column at " + rowrec.getLastCol());
break;
case NumberRecord.sid:
NumberRecord numrec = (NumberRecord) record;
System.out.println("Cell found with value " + numrec.getValue()
+ " at row " + numrec.getRow() + " and column " + numrec.getColumn());
break;
// SSTRecords store a array of unique strings used in Excel.
case SSTRecord.sid:
sstrec = (SSTRecord) record;
for (int k = 0; k < sstrec.getNumUniqueStrings(); k++)
{
System.out.println("String table value " + k + " = " + sstrec.getString(k));
}
break;
case LabelSSTRecord.sid:
LabelSSTRecord lrec = (LabelSSTRecord) record;
System.out.println("String cell found with value "
+ sstrec.getString(lrec.getSSTIndex()));
break;
}
}
/**
* Read an excel file and spit out what we find.
*
* @param args Expect one argument that is the file to read.
* @throws IOException When there is an error processing the file.
*/
public static void main(String[] args) throws IOException
{
// create a new file input stream with the input file specified
// at the command line
FileInputStream fin = new FileInputStream(args[0]);
// create a new org.apache.poi.poifs.filesystem.Filesystem
POIFSFileSystem poifs = new POIFSFileSystem(fin);
// get the Workbook (excel part) stream in a InputStream
InputStream din = poifs.createDocumentInputStream("Workbook");
// construct out HSSFRequest object
HSSFRequest req = new HSSFRequest();
// lazy listen for ALL records with the listener shown above
req.addListenerForAllRecords(new EventExample());
// create our event factory
HSSFEventFactory factory = new HSSFEventFactory();
// process our events based on the document input stream
factory.processEvents(req, din);
// once all the events are processed close our file input stream
fin.close();
// and our document input stream (don't want to leak these!)
din.close();
System.out.println("done.");
}
}
]]></source>
</section>
<section><title>Low Level APIs</title>
<p>The low level API is not much to look at. It consists of lots of
&quot;Records&quot; in the org.apache.poi.hssf.record.* package,
and set of helper classes in org.apache.poi.hssf.model.*. The
record classes are consistent with the low level binary structures
inside a BIFF8 file (which is embedded in a POIFS file system). You
probably need the book: &quot;Microsoft Excel 97 Developer's Kit&quot;
from Microsoft Press in order to understand how these fit together
(out of print but easily obtainable from Amazon's used books). In
order to gain a good understanding of how to use the low level APIs
should view the source in org.apache.poi.hssf.usermodel.* and
the classes in org.apache.poi.hssf.model.*. You should read the
documentation for the POIFS libraries as well.</p>
</section>
<section><title>HSSF Class/Test Application</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>&quot;myxls.xls&quot;</code>. </p>
<ul>
<li>Type:
<code>java org.apache.poi.hssf.dev.HSSF ~/input.xls output.xls</code>
<br/>
<br/>
This is the read/write/modify test. It reads in the spreadsheet, modifies a cell, and writes it back out.
Failing this test is not necessarily a bad thing. If HSSF tries to modify a non-existant sheet then this will
most likely fail. No big deal. </li>
</ul>
</section>
<section><title>Logging facility</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 &quot;biffview&quot;. To do this you run it (assumes
you have everything setup in your classpath and that you know what
you're doing enough to be thinking about this) with an xls file as a
parameter. It will give you a listing of all understood records with
their data and a list of not-yet-understood records with no data
(because it doesn't know how to interpret them). This listing is
useful for several things. First, you can look at the values and SEE
what is wrong in quasi-English. Second, you can send the output to a
file and compare it.
</p>
<p>The second function is &quot;big freakin dump&quot;, just pass a
file and a second argument matching &quot;bfd&quot; exactly. This
will just make a big hexdump of the file.
</p>
<p>Lastly, there is &quot;mixed&quot; mode which does the same as
regular biffview, only it includes hex dumps of certain records
intertwined. To use that just pass a file with a second argument
matching &quot;on&quot; exactly.</p>
<p>In the next release cycle we'll also have something called a
FormulaViewer. The class is already there, but its not very useful
yet. When it does something, we'll document it.</p>
</section>
<section><title>What's Next?</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="../getinvolved/index.html"> So jump in! </link> </p>
</section>
</section>
</section>
</body>
</document>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>POI-HSSF - 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(-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>
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 the org.apache.poi.hssf.eventusermodel package.
</p>
<p>
If you're modifying spreadsheet data then use the usermodel api. You
can also generate spreadsheets this way.
</p>
</section>
</body>
</document>

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Limitations</title>
<authors>
<person email="poi-user@jakarta.apache.org" name="Glen Stampoultzis" id="GJS"/>
</authors>
</header>
<body>
<section><title>Version 2.0 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>
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. 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>

View File

@ -0,0 +1,974 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Busy Developers' Guide to HSSF Features</title>
<authors>
<person email="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="#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>
</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="CustomColors"/>
<section><title>Custom colors</title>
<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>
</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="NewLinesInCells"/>
<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="FitTo"/>
<section><title>Fit Sheet 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="PrintArea2"/>
<section><title>Set Print Area</title>
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Sheet1");
wb.setPrintArea(0, "$A$1:$C$2");
//sets the print area for the first sheet
//Alternatively:
//wb.setPrintArea(0, 0, 1, 0, 0) is equivalent to using the name reference (See the JavaDocs for more details)
// 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>
<anchor id="ConvenienceFunctions"/>
<section><title>Using the Convenience Functions</title>
<p>
The convenience functions live in contrib and provide
utility features such as setting borders around merged
regions and changing style attributes without explicitly
creating new styles.
</p>
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet( "new sheet" );
// Create a merged region
HSSFRow row = sheet1.createRow( (short) 1 );
HSSFRow row2 = sheet1.createRow( (short) 2 );
HSSFCell cell = row.createCell( (short) 1 );
cell.setCellValue( "This is a test of merging" );
Region region = new Region( 1, (short) 1, 4, (short) 4 );
sheet1.addMergedRegion( region );
// Set the border and border colors.
final short borderMediumDashed = HSSFCellStyle.BORDER_MEDIUM_DASHED;
HSSFRegionUtil.setBorderBottom( borderMediumDashed,
region, sheet1, wb );
HSSFRegionUtil.setBorderTop( borderMediumDashed,
region, sheet1, wb );
HSSFRegionUtil.setBorderLeft( borderMediumDashed,
region, sheet1, wb );
HSSFRegionUtil.setBorderRight( borderMediumDashed,
region, sheet1, wb );
HSSFRegionUtil.setBottomBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);
HSSFRegionUtil.setTopBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);
HSSFRegionUtil.setLeftBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);
HSSFRegionUtil.setRightBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);
// Shows some usages of HSSFCellUtil
HSSFCellStyle style = wb.createCellStyle();
style.setIndention((short)4);
HSSFCellUtil.createCell(row, 8, "This is the value of the cell", style);
HSSFCell cell2 = HSSFCellUtil.createCell( row2, 8, "This is the value of the cell");
HSSFCellUtil.setAlignment(cell2, wb, HSSFCellStyle.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>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet 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);
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</source>
</section>
<anchor id="SelectSheet"/>
<section><title>Set a sheet as selected</title>
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("row sheet");
sheet.setSelected(true);
// Create various cells and rows for spreadsheet.
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</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>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
sheet1.setZoom(3,4); // 75 percent magnification
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
</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, HSSFSheet.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 HSSFSheet.PANE_LOWER_LEFT,
PANE_LOWER_RIGHT, PANE_UPPER_RIGHT or PANE_UPPER_LEFT.
</p>
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
HSSFSheet sheet2 = wb.createSheet("second sheet");
HSSFSheet sheet3 = wb.createSheet("third sheet");
HSSFSheet 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, HSSFSheet.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 setRepeatingRowsAndColumns()
function in the HSSFWorkbook class.
</p>
<p>
This function Contains 5 parameters.
The first parameter is the index to the sheet (0 = first sheet).
The second and third parameters specify the range for the columns to repreat.
To stop the columns from repeating pass in -1 as the start and end column.
The fourth and fifth parameters specify the range for the rows to repeat.
To stop the columns from repeating pass in -1 as the start and end rows.
</p>
<source>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
HSSFSheet sheet2 = wb.createSheet("second sheet");
// Set the columns to repeat from column 0 to 2 on the first sheet
wb.setRepeatingRowsAndColumns(0,0,2,-1,-1);
// Set the the repeating rows and columns on the second sheet.
wb.setRepeatingRowsAndColumns(1,4,5,1,2);
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>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFHeader 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>
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet 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 is not currently possible to read existing images and it
should be noted that any existing drawings may be erased
once you add a image to a sheet.
</p>
<source>
// Create the drawing patriarch. This is the top level container for
// all shapes. This will clear out any existing shapes for that sheet.
HSSFPatriarch patriarch = sheet5.createDrawingPatriarch();
HSSFClientAnchor anchor;
anchor = new HSSFClientAnchor(0,0,0,255,(short)2,2,(short)4,7);
anchor.setAnchorType( 2 );
patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4.png", wb ));
</source>
</section>
</body>
</document>

View File

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>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 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 &quot;type&quot; 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>

View File

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!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 &quot;Workbook&quot;
file (use case 4, read workbook entry)</li>
</ol>
<p><strong>Extensions:</strong></p>
<p>2a. Exceptions
thrown by POIFS will be passed on to the HSSF client.</p>
</section>
<section><title>Use Case 2: Write HSSF file</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 &quot;Workbook&quot; to its associated POIFS file system (use case
5, write workbook entry)</li>
<li>HSSF
requests POIFS to write its file system out, using the OutputStream
obtained from the HSSF client (POIFS use case 2, write file system).</li>
</ol>
<p><strong>Extensions:</strong></p>
<p>3a. Exceptions
from POIFS are passed to the HSSF client.</p>
</section>
<section><title>Use Case 3:Create HSSF file</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 &quot;Workbook&quot; file</li>
<li>POIFS returns
an InputStream for the file.</li>
<li>HSSF reads
from the InputStream provided by POIFS</li>
<li>HSSF closes
the InputStream provided by POIFS</li>
</ol>
<p><strong>Extensions:</strong></p>
<p>3a. Exceptions
thrown by POIFS will be passed on</p>
</section>
<section><title>Use Case 5: Write workbook entry</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 &quot;Workbook&quot;
file (POIFS use case 8, read file system directory)</li>
<li>If &quot;Workbook&quot; is in the directory, HSSF requests POIFS to
replace it with the new workbook entry (POIFS use case 4, replace file
in file system). Otherwise, HSSF requests POIFS to write the new
workbook file, with the name &quot;Workbook&quot; (POIFS use case 6,
write new file to file system)</li>
</ol>
<p><strong>Extensions:</strong>None</p>
</section>
</section>
</body>
</document>

View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!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="Jakarta POI">
<menu-item label="Top" href="../index.html"/>
</menu>
<menu label="HWPF">
<menu-item label="Overview" href="index.html"/>
<menu-item label="HWPF Format" href="docoverview.html"/>
<menu-item label="HWPF Project plan" href="projectplan.html"/>
</menu>
</book>

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Jakarta 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 Binary
File Format freely available at <link href="http://wotsit.org">Wotsit.org</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>

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
<document>
<header>
<title>Jakarta 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(-2002) file format
to pure Java.</p>
<p>HWPF is still in early development. It is in the <link
href="http://cvs.apache.org/viewcvs/jakarta-poi/src/scratchpad/">
scratchpad section of the CVS.</link> Source code in the
<em>org.apache.poi.hwpf.extractor</em> tree is legacy code. Source in the
<em>org.apache.poi.hwpf.model</em> tree is the old legacy code refactored
into an object model.</p>
<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>. This document contains a link to
a detailled Word format description you can find somewhere at
<link href="http://www.wotsit.org/">http://www.wotsit.org/</link>. Please
do not contact Ryan Ackley directly, because he is working for a company
now that signed a NDA with Microsoft and thus he will be no longer able to
answer questions.</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 start coding, you will not yet have write access to the
CVS repository. Please submit your patches to <link
href="http://issues.apache.org/">Bugzilla</link> and nag <link
href="mailto:klute@apache.org">Rainer Klute</link> until he commits
them. Besides the actual checking in of HWPF patches Rainer 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.</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 CVS commit
access.</p>
<p><strong>Important:</strong> It is legally vital for POI that you have
never seen any documentation or specification from Microsoft that required
you or your employer to sign an NDA to get it. Please do read the <link
href="../getinvolved/index.html">"Contribution to POI" page</link> for
details! This page also contains further information for you to start POI
development.</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>
</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:
-->

View File

@ -0,0 +1,375 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!-- 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>Jakarta 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>
&#160;
</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&#8217;s
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
</body>
</document>

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2004 The Apache Software Foundation. All rights reserved. -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
<document>
<header>
<title>Jakarta POI - Java API To Access Microsoft Format Files</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="RK" name="Rainer Klute" email="klute@apache.org"/>
</authors>
</header>
<body>
<!-- <section><title>POI News</title>-->
<!-- <p>All POI news can now be found at the <link href="http://nagoya.apache.org/poi/news/">poi news weblog</link>.</p>-->
<!-- </section>-->
<section><title>Purpose</title>
<p>
The POI project consists of APIs for manipulating various file formats
based upon Microsoft's OLE 2 Compound Document format using pure Java. In short, you can
read and write MS Excel files using Java. Soon, you'll be able to read and write
Word files using Java. POI is your Java Excel solution as well as your Java Word solution.
However, we have a complete API for porting other OLE 2 Compound Document formats and welcome
others to participate.
</p>
<p>
OLE 2 Compound Document Format based files include most Microsoft Office
files such as XLS and DOC as well as MFC serialization API based file formats.
</p>
<p>
As a general policy we try to 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://jakarta.apache.org/lucene">Lucene</link> for which we'll soon have file
format interpretors. When practical, we donate components directly to those projects for POI-enabling them.
</p>
<section><title>Why/when would I use POI?</title>
<p>
We'll tackle this on a component level. POI refers to the whole project.
</p>
<p>
So why should you use POIFS or HSSF?
</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 can also read and modify
spreadsheets using this API, although right now writing is more mature.
</p>
</section>
</section>
<section><title>Components To Date</title>
<section><title>Overview</title>
<p>The following are components of the entire POI project and a brief
summary of their purpose.</p>
</section>
<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 for Excel Documents</title>
<p>HSSF is our port of the Microsoft Excel 97(-2002) file format (BIFF8) to pure Java. It supports read and write
capability. Please see <link href="./hssf/index.html">the HSSF project page</link> for more information.</p>
</section>
<section><title>HWPF for Word Documents</title>
<p>HWPF is our port of the Microsoft Word 97 file format to pure
Java. It supports read and write capability. Please see <link
href="./hwpf/index.html">the HWPF project page for more
information</link>. This component is in the early stages of
development. It can already read and write simple files.</p>
<p>Presently we are looking for a contributor to foster the HWPF
development. Jump in!</p>
</section>
<section><title>HPSF for 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 reading and writing of properties. However, with the
current POI release only reading is possible. In order to write
properties, you'll have to fetch the latest POI version <link
href="http://jakarta.apache.org/site/cvsindex.html">from the CVS
repository</link>.</p>
<p>Please see <link href="./hpsf/index.html">the HPSF project
page</link> for more information.</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 in several areas. The first is bug reports and feature requests! The second is documentation -
we'll be at your every beck and call if you've got a critique or you'd like to contribute or otherwise improve
the documentation. We could especially use some help documenting the HSSF file format! Last, but not least, we
could use some binary crunching Java coders to chew through the complexity that characterizes Microsoft's file
formats and help us port new ones to a superior Java platform!
</p>
<p>So if you're motivated, ready, and have the time, join the mail lists and we'll be happy to help you get started on the
project!
</p>
</section>
</body>
<footer>
<legal>
Copyright (c) @year@ The Apache Software Foundation. All rights reserved.
$Revision$ $Date$
</legal>
</footer>
</document>

Some files were not shown because too many files have changed in this diff Show More