<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="ooxml.lib" location="ooxml-lib"/>
<property name="main.reports.test" location="build/test-results"/>
<property name="main.jar1.dir" location="${main.lib}/commons-logging-1.1.jar"/>
<property name="main.jar1.url" value="${repository}/commons-logging/jars/commons-logging-1.1.jar"/>
<property name="main.jar2.url" value="${repository}/log4j/jars/log4j-1.2.13.jar"/>
<property name="main.testokfile" location="build/main-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"/>
+
<!-- Scratchpad: -->
<property name="scratchpad.src" location="src/scratchpad/src"/>
<property name="scratchpad.src.test" location="src/scratchpad/testcases"/>
<property name="examples.jar3.url" value="${repository}/commons-lang/jars/commons-lang-2.1.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"/>
+ <!-- Experimental OOXML support: -->
+ <property name="ooxml.src" location="src/scratchpad/ooxml-src"/>
+ <property name="ooxml.src.test" location="src/scratchpad/ooxml-testcases"/>
+ <property name="ooxml.reports.test" location="build/ooxml-test-results"/>
+ <property name="ooxml.output.dir" location="build/ooxml-classes"/>
+ <property name="ooxml.output.test.dir" location="build/ooxml-test-classes"/>
+ <property name="ooxml.testokfile" location="build/ooxml-testokfile.txt"/>
+
+ <property name="ooxml.jar1.dir" location="${ooxml.lib}/dom4j-1.6.1.jar"/>
+ <property name="ooxml.jar1.url" value="${repository}/dom4j/jars/dom4j-1.6.1.jar"/>
+ <property name="ooxml.jar2.dir" location="${ooxml.lib}/jaxen-1.1.jar"/>
+ <property name="ooxml.jar2.url" value="${repository}/jaxen/jars/jaxen-1.1.jar"/>
+ <property name="ooxml.jar3.dir" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/>
+ <property name="ooxml.jar3.url" value="${repository}/org.apache.xmlbeans/jars/xmlbeans-2.3.0.jar"/>
+ <property name="ooxml.jar4.dir" location="${ooxml.lib}/jsr173_1.0_api.jar"/>
+ <property name="ooxml.jar4.url" value="${repository}/xmlbeans/jars/jsr173_1.0_api.jar"/>
+ <!-- No official release of openxml4j yet -->
+ <property name="ooxml.jar5.dir" location="${ooxml.lib}/openxml4j-bin-prealpha-071224.jar"/>
+ <property name="ooxml.jar5.url" value="http://people.apache.org/~nick/openxml4j-bin-prealpha-071224.jar"/>
+
+ <!-- See http://www.ecma-international.org/publications/standards/Ecma-376.htm -->
+ <!-- "Copy these file(s), free of charge" -->
+ <property name="ooxml.xsds.ozip" location="${ooxml.lib}/OfficeOpenXML-Part4.zip"/>
+ <property name="ooxml.xsds.izip" location="${ooxml.lib}/OfficeOpenXML-XMLSchema.zip"/>
+ <property name="ooxml.xsds.url" value="http://www.ecma-international.org/publications/files/ECMA-ST/Office%20Open%20XML%20Part%204%20(DOCX).zip" />
+ <property name="ooxml.xsds.jar" location="${ooxml.lib}/ooxml-schemas.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="mavendist.poi.dir" location="build/maven-dist/poi"/>
<property name="mavendist.oap.dir" location="build/maven-dist/org.apache.poi"/>
<property name="jar.name" value="poi"/>
- <property name="version.id" value="3.0.2-beta1"/>
+ <property name="version.id" value="3.0.2-beta2"/>
<property name="halt.on.test.failure" value="true"/>
<property name="jdk.version.source" value="1.3"
description="JDK version of source code"/>
<pathelement location="${contrib.output.test.dir}"/>
</path>
+ <path id="ooxml.classpath">
+ <path refid="main.classpath"/>
+ <path refid="scratchpad.classpath"/>
+ <fileset dir="${ooxml.lib}">
+ <include name="*.jar" />
+ </fileset>
+ </path>
+
+
<path id="examples.classpath">
<path refid="main.classpath"/>
<pathelement location="${main.output.dir}"/>
<mkdir dir="${scratchpad.output.dir}"/>
<mkdir dir="${contrib.output.dir}"/>
<mkdir dir="${examples.output.dir}"/>
+ <mkdir dir="${ooxml.output.dir}"/>
<mkdir dir="${main.output.test.dir}"/>
<mkdir dir="${contrib.output.test.dir}"/>
<mkdir dir="${scratchpad.output.test.dir}"/>
+ <mkdir dir="${ooxml.output.test.dir}"/>
<mkdir dir="${main.reports.test}"/>
<mkdir dir="${scratchpad.reports.test}"/>
<mkdir dir="${contrib.reports.test}"/>
+ <mkdir dir="${ooxml.reports.test}"/>
<mkdir dir="${junit.report.dir}"/>
<mkdir dir="${jdepend.report.dir}"/>
<mkdir dir="${jdepend.report.out.dir}"/>
<get src="${junit.jar1.url}" dest="${junit.jar1.dir}"/>
</target>
+ <target name="check-ooxml-xsds">
+ <condition property="ooxml-xsds.present">
+ <or>
+ <and>
+ <available file="${ooxml.xsds.izip}"/>
+ </and>
+ <isset property="disconnected"/>
+ </or>
+ </condition>
+ </target>
+ <target name="fetch-ooxml-xsds" unless="ooxml-xsds.present"
+ description="Fetches needed OOXML xsd files from the Internet">
+ <get src="${ooxml.xsds.url}" dest="${ooxml.xsds.ozip}"/>
+ <unzip src="${ooxml.xsds.ozip}" dest="${ooxml.lib}">
+ <patternset>
+ <include name="OfficeOpenXML-XMLSchema.zip" />
+ </patternset>
+ </unzip>
+ </target>
+ <target name="check-compiled-ooxml-xsds">
+ <condition property="ooxml-compiled-xsds.present">
+ <or>
+ <and>
+ <available file="${ooxml.xsds.jar}"/>
+ </and>
+ <isset property="disconnected"/>
+ </or>
+ </condition>
+ </target>
+ <target name="compile-ooxml-xsds" unless="ooxml-compiled-xsds.present"
+ depends="check-jars,fetch-jars,check-ooxml-xsds,fetch-ooxml-xsds,check-compiled-ooxml-xsds"
+ description="Unpacks the OOXML xsd files, and compiles them into XmlBeans">
+ <taskdef name="xmlbean"
+ classname="org.apache.xmlbeans.impl.tool.XMLBean"
+ classpath="${ooxml.jar3.dir}:${ooxml.jar4.dir}" />
+
+ <unzip src="${ooxml.xsds.izip}" dest="build/ooxml-xsds/" />
+ <!--
+ schema="build/ooxml-xsds/"
+ schema="build/ooxml-xsds/sml-workbook.xsd"
+ -->
+ <xmlbean
+ schema="build/ooxml-xsds/"
+ destfile="${ooxml.xsds.jar}"
+ javasource="1.4"
+ failonerror="false"
+ >
+ <classpath refid="ooxml.classpath"/>
+ </xmlbean>
+ </target>
+
<target name="compile" depends="init, compile-main, compile-scratchpad,
compile-contrib, compile-examples"
description="Compiles the POI main classes, scratchpad, contrib, and examples"/>
</javac>
</target>
- <target name="compile-scratchpad" depends="init">
+ <target name="compile-scratchpad" depends="init,compile-main">
<javac target="${jdk.version.class}" source="${jdk.version.source}"
failonerror="true" destdir="${scratchpad.output.dir}" debug="on"
fork="yes" srcdir="${scratchpad.src}">
</javac>
</target>
+ <target name="compile-ooxml" depends="init, check-ooxml-xsds, fetch-ooxml-xsds, compile-ooxml-xsds, compile-main">
+ <!-- openxml4j requires java 1.5, so so must we, for now -->
+ <javac target="1.5" source="1.5"
+ destdir="${ooxml.output.dir}" debug="on" srcdir="${ooxml.src}">
+ <classpath refid="ooxml.classpath"/>
+ </javac>
+ </target>
+
<target name="test" depends="test-main,test-scratchpad,test-contrib"
description="Tests main, contrib and scratchpad"/>
<echo file="${contrib.testokfile}" append="false" message="testok"/>
</target>
+ <target name="-test-ooxml-check">
+ <uptodate property="ooxml.test.notRequired" targetfile="${ooxml.testokfile}">
+ <srcfiles dir="${ooxml.src}"/>
+ <srcfiles dir="${ooxml.src.test}"/>
+ </uptodate>
+ </target>
+
+ <target name="test-ooxml" depends="compile-main,compile-ooxml,-test-ooxml-check" unless="ooxml.test.notRequired">
+ <junit printsummary="yes" fork="no" haltonfailure="${halt.on.test.failure}" failureproperty="ooxml.test.failed">
+ <classpath>
+ <path refid="ooxml.classpath"/>
+ <pathelement location="${main.output.dir}"/>
+ <pathelement location="${ooxml.output.dir}"/>
+ <pathelement location="${ooxml.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="HWPF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hwpf/data"/>
+ <sysproperty key="HSLF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hslf/data"/>
+ <sysproperty key="java.awt.headless" value="true"/>
+ <formatter type="plain"/>
+ <formatter type="xml"/>
+ <batchtest todir="${ooxml.reports.test}">
+ <fileset dir="${ooxml.src.test}">
+ <include name="**/Test*.java"/>
+ <exclude name="**/AllTests.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ <delete file="${ooxml.testokfile}"/>
+ <antcall target="-test-ooxml-write-testfile"/>
+ </target>
+
+ <target name="-test-ooxml-write-testfile" unless="ooxml.test.failed">
+ <echo file="${ooxml.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}"/>
</manifest>
</jar>
</target>
+ <target name="jar-ooxml" depends="compile-ooxml" description="Creates the ooxml jar files for distribution">
+ <jar destfile="${dist.dir}/${jar.name}-ooxml-${version.id}-${DSTAMP}.jar">
+ <fileset dir="${ooxml.output.dir}" />
+ <fileset dir="legal/" />
+ <manifest>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="Specification-Title" value="Apache POI"/>
+ <attribute name="Specification-Version" value="${version.id}-${DSTAMP}"/>
+ <attribute name="Specification-Vendor" value="Apache"/>
+ <attribute name="Implementation-Title" value="Apache POI"/>
+ <attribute name="Implementation-Version" value="${version.id}-${DSTAMP}"/>
+ <attribute name="Implementation-Vendor" value="Apache"/>
+ </manifest>
+ </jar>
+ </target>
<target name="dist" depends="clean, fail-unless-tools-are-available, compile, site, jar"
description="Creates the entire distribution into build/dist, from scratch">
</license>
</licenses>
<scm>
- <url>http://svn.apache.org/viewvc/jakarta/poi/trunk</url>
- <connection>scm:svn:http://svn.apache.org/repos/asf/jakarta/poi/trunk</connection>
+ <url>http://svn.apache.org/viewvc/poi/trunk</url>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/poi/trunk</connection>
</scm>
<issueManagement>
<system>bugzilla</system>
<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-item label="Sponsors" href="http://www.apache.org/foundation/thanks.html" />
</menu>
<menu label="Docs">
</devs>
<!-- Don't forget to update status.xml too! -->
- <release version="3.0.2-FINAL" date="2007-??-??">
- <action dev="POI-DEVELOPERS" type="fix">43877 and 39512 - Fix for handling mixed OBJ and CONTINUE records.</action>
+ <release version="3.0.2-FINAL" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="add">Support for tables in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">43781 - Fix for extracting text from TextBoxes HSLF in</action>
+ <action dev="POI-DEVELOPERS" type="fix">Improve JavaDocs relating to hssf font and fill colourings</action>
+ <action dev="POI-DEVELOPERS" type="add">44095, 44097, 44099 - [PATCH] Support for Mid, Replace and Substitute excel functions</action>
+ <action dev="POI-DEVELOPERS" type="add">44055 - [PATCH] Support for getting the from field from HSMF messages</action>
+ <action dev="POI-DEVELOPERS" type="add">43551 - [PATCH] Support for 1904 date windowing in HSSF (previously only supported 1900 date windowing)</action>
+ <action dev="POI-DEVELOPERS" type="add">41064 - [PATCH] Support for String continue records</action>
+ <action dev="POI-DEVELOPERS" type="add">27511 - [PATCH] Support for data validation, via DVRecord and DVALRecord</action>
+ </release>
+
+ <release version="3.0.2-BETA1" date="2007-12-04">
+ <action dev="POI-DEVELOPERS" type="fix">43877 and 39512 - Fix for handling mixed OBJ and CONTINUE records.</action>
<action dev="POI-DEVELOPERS" type="fix">43807 - Throw an IllegalArgumentException if asked to create a merged region with invalid columns or rows, rather than writing out a corrupt file</action>
<action dev="POI-DEVELOPERS" type="fix">43837 - [PATCH] Support for unicode NameRecords</action>
<action dev="POI-DEVELOPERS" type="add">43721 - [PATCH] Support for Chart Title Format records</action>
<li><link href="#Fill">How to work with slide/shape background</link></li>
<li><link href="#Bullets">How to create bulleted lists</link></li>
<li><link href="#Hyperlinks">Hyperlinks</link></li>
+ <li><link href="#Tables">Tables</link></li>
</ul>
</section>
<section><title>Features</title>
}
</source>
</section>
+ <anchor id="Tables"/>
+ <section><title>How to create tables</title>
+ <source>
+ //table data
+ String[][] data = {
+ {"INPUT FILE", "NUMBER OF RECORDS"},
+ {"Item File", "11,559"},
+ {"Vendor File", "300"},
+ {"Purchase History File", "10,000"},
+ {"Total # of requisitions", "10,200,038"}
+ };
+
+ SlideShow ppt = new SlideShow();
+
+ Slide slide = ppt.createSlide();
+ //create a table of 5 rows and 2 columns
+ Table table = new Table(5, 2);
+ for (int i = 0; i < data.length; i++) {
+ for (int j = 0; j < data[i].length; j++) {
+ TableCell cell = table.getCell(i, j);
+ cell.setText(data[i][j]);
+
+ RichTextRun rt = cell.getTextRun().getRichTextRuns()[0];
+ rt.setFontName("Arial");
+ rt.setFontSize(10);
+
+ cell.setVerticalAlignment(TextBox.AnchorMiddle);
+ cell.setHorizontalAlignment(TextBox.AlignCenter);
+ }
+ }
+
+ //set table borders
+ Line border = table.createBorder();
+ border.setLineColor(Color.black);
+ border.setLineWidth(1.0);
+ table.setAllBorders(border);
+
+ //set width of the 1st column
+ table.setColumnWidth(0, 300);
+ //set width of the 2nd column
+ table.setColumnWidth(1, 150);
+
+ slide.addShape(table);
+ table.moveTo(100, 100);
+
+ FileOutputStream out = new FileOutputStream("hslf-table.ppt");
+ ppt.write(out);
+ out.close();
+
+ </source>
+ </section>
</section>
</section>
CellReference cellReference = new CellReference("B3");
HSSFRow row = sheet.getRow(cellReference.getRow());
HSSFCell cell = row.getCell(cellReference.getCol());
+
+evaluator.setCurrentRow(row);
HSSFFormulaEvaluator.CellValue cellValue = evaluator.evaluate(cell);
switch (cellValue.getCellType()) {
CellReference cellReference = new CellReference("B3");
HSSFRow row = sheet.getRow(cellReference.getRow());
HSSFCell cell = row.getCell(cellReference.getCol());
-
+evaluator.setCurrentRow(row);
if (cell!=null) {
switch (<strong>evaluator.evaluateInCell</strong>(cell).getCellType()) {
<li><link href="#CreateCells">How to create cells</link></li>
<li><link href="#CreateDateCells">How to create date cells</link></li>
<li><link href="#CellTypes">Working with different types of cells</link></li>
+ <li><link href="#Iterator">Iterate over rows and cells</link></li>
<li><link href="#TextExtraction">Text Extraction</link></li>
<li><link href="#Alignment">Aligning cells</link></li>
<li><link href="#Borders">Working with borders</link></li>
fileOut.close();
</source>
</section>
+ <anchor id="Iterator"/>
+ <section><title>Iterate over rows and cells (including Java 5 foreach loops)</title>
+ <p>Sometimes, you'd like to just iterate over all the rows in
+ a sheet, or all the cells in a row. If you are using Java
+ 5 or later, then this is especially handy, as it'll allow the
+ new foreach loop support to work.</p>
+ <p>Luckily, this is very easy. HSSFRow defines a
+ <em>CellIterator</em> inner class to handle iterating over
+ the cells (get one with a call to <em>row.cellIterator()</em>),
+ and HSSFSheet provides a <em>rowIterator()</em> method to
+ give an iterator over all the rows.</p>
+ <source>
+ HSSFSheet sheet = wb.getSheetAt(0);
+ for (HSSFRow row : sheet.rowIterator()) {
+ for (HSSFCell cell : row.cellIterator()) {
+ // Do something here
+ }
+ }
+ </source>
+ </section>
<anchor id="TextExtraction"/>
<section><title>Text Extraction</title>
<p>For most text extraction requirements, the standard
</header>
<body>
- <section><title>POI 3.0.1 Release</title>
+ <section><title>POI 3.0.2 BETA1 Release</title>
+ <p>The latest release of Apache POI is 3.0.2 BETA1 which was promoted to "Beta" on 04 December 2007. It contains a mixture of
+ new features and bug fixes, compared to 3.0.1. A full list of changes
+ is available in
+ <link href="./changes.html">the changelog</link>, and
+ <link href="http://www.apache.org/dyn/closer.cgi/poi/release/">download</link>
+ the source and binaries from your
+ <link href="http://www.apache.org/dyn/closer.cgi/poi/release/">local mirror</link>.
+ The release is also available from the central Maven repository under Group ID "org.apache.poi".
+ </p>
+ </section>
+
+ <section><title>POI 3.0.1 Release</title>
<p>The latest release of Apache POI (formerly Apache Jakarta POI),
version 3.0.1, has now been released. It contains a mixture of
new features and bug fixes, compared to 3.0. A full list of changes
<!-- Don't forget to update changes.xml too! -->
<changes>
- <release version="3.0.2-FINAL" date="2007-??-??">
+ <release version="3.0.2-FINAL" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="add">Support for tables in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">43781 - Fix for extracting text from TextBoxes HSLF in</action>
+ <action dev="POI-DEVELOPERS" type="fix">Improve JavaDocs relating to hssf font and fill colourings</action>
+ <action dev="POI-DEVELOPERS" type="add">44095, 44097, 44099 - [PATCH] Support for Mid, Replace and Substitute excel functions</action>
+ <action dev="POI-DEVELOPERS" type="add">44055 - [PATCH] Support for getting the from field from HSMF messages</action>
+ <action dev="POI-DEVELOPERS" type="add">43551 - [PATCH] Support for 1904 date windowing in HSSF (previously only supported 1900 date windowing)</action>
+ <action dev="POI-DEVELOPERS" type="add">41064 - [PATCH] Support for String continue records</action>
+ <action dev="POI-DEVELOPERS" type="add">27511 - [PATCH] Support for data validation, via DVRecord and DVALRecord</action>
+ </release>
+ <release version="3.0.2-BETA1" date="2007-12-04">
<action dev="POI-DEVELOPERS" type="fix">43877 - Fix for handling mixed OBJ and CONTINUE records</action>
<action dev="POI-DEVELOPERS" type="fix">39512 - Fix for handling mixed OBJ and CONTINUE records</action>
<action dev="POI-DEVELOPERS" type="fix">43837 - [PATCH] Support for unicode NameRecords</action>
--- /dev/null
+
+/* ====================================================================
+ 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.record;
+
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * Title: DVAL Record<P>
+ * Description: used in data validation ;
+ * This record is the list header of all data validation records in the current sheet.
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ * @version 2.0-pre
+ */
+
+public class DVALRecord extends Record
+{
+ public final static short sid = 0x01B2;
+
+ //unknown field ; it's size should be 10
+ private short field_unknown = 0x0000;
+
+ //Object ID of the drop down arrow object for list boxes ;
+ //in our case this will be always FFFF , until
+ //MSODrawingGroup and MSODrawing records are implemented
+ private int field_cbo_id = 0xFFFFFFFF;
+
+ //Number of following DV records
+ //Default value is 1
+ private int field_3_dv_no = 0x00000000;
+
+ public DVALRecord()
+ {
+ }
+
+ /**
+ * Constructs a DVAL record and sets its fields appropriately.
+ *
+ * @param in the RecordInputstream to read the record from
+ */
+
+ public DVALRecord(RecordInputStream in)
+ {
+ super(in);
+ }
+
+ protected void validateSid(short id)
+ {
+ if (id != sid)
+ {
+ throw new RecordFormatException("NOT A valid DVAL RECORD");
+ }
+ }
+
+ protected void fillFields(RecordInputStream in)
+ {
+ for ( int i=0; i<5; i++)
+ {
+ this.field_unknown = in.readShort();
+ }
+ this.field_cbo_id = in.readInt();
+ this.field_3_dv_no = in.readInt();
+ }
+
+ /**
+ * set the object ID of the drop down arrow object for list boxes
+ * @param cboID - Object ID
+ */
+ public void setObjectID(int cboID)
+ {
+ this.field_cbo_id = cboID;
+ }
+
+ /**
+ * Set the number of following DV records
+ * @param dvNo - the DV records number
+ */
+ public void setDVRecNo(int dvNo)
+ {
+ this.field_3_dv_no = dvNo;
+ }
+
+ /**
+ * get Object ID of the drop down arrow object for list boxes
+ */
+ public int getObjectID( )
+ {
+ return this.field_cbo_id;
+ }
+
+ /**
+ * Get number of following DV records
+ */
+ public int getDVRecNo( )
+ {
+ return this.field_3_dv_no;
+ }
+
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[DVAL]\n");
+ buffer.append(" .comboObjectID = ").append(Integer.toHexString(this.getObjectID())).append("\n");
+ buffer.append(" .DVRecordsNumber = ").append(Integer.toHexString(this.getDVRecNo())).append("\n");
+ buffer.append("[/DVAL]\n");
+ return buffer.toString();
+ }
+
+ public int serialize(int offset, byte [] data)
+ {
+ LittleEndian.putShort(data, 0 + offset, this.sid);
+ LittleEndian.putShort(data, 2 + offset, ( short)(this.getRecordSize()-4));
+ for ( int i=0; i<5; i++)
+ {
+ LittleEndian.putShort(data, 4 + i*2 + offset, (short)this.field_unknown);
+ }
+ LittleEndian.putInt(data, 14 + offset, this.getObjectID());
+ LittleEndian.putInt(data, 18 + offset, this.getDVRecNo());
+ return getRecordSize();
+ }
+
+ //with 4 bytes header
+ public int getRecordSize()
+ {
+ return 22;
+ }
+
+ public short getSid()
+ {
+ return this.sid;
+ }
+
+ public Object clone()
+ {
+ DVALRecord rec = new DVALRecord();
+ rec.field_unknown = this.field_unknown;
+ rec.field_cbo_id = this.field_cbo_id;
+ rec.field_3_dv_no = this.field_3_dv_no;
+ return rec;
+ }
+}
\ No newline at end of file
--- /dev/null
+/* ====================================================================
+ 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.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.StringUtil;
+import org.apache.poi.hssf.util.HSSFCellRangeAddress;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+import java.io.IOException;
+import java.util.Stack;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/**
+ * Title: DV Record<P>
+ * Description: This record stores data validation settings and a list of cell ranges
+ * which contain these settings. The data validation settings of a sheet
+ * are stored in a sequential list of DV records. This list is followed by
+ * DVAL record(s)
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ * @version 2.0-pre
+ */
+public class DVRecord extends Record
+{
+ public final static short sid = 0x01BE;
+
+ /**
+ * Option flags
+ */
+ private int field_option_flags;
+
+ /**
+ * Title of the prompt box
+ */
+ private String field_title_prompt;
+
+ /**
+ * Title of the error box
+ */
+ private String field_title_error;
+
+ /**
+ * Text of the prompt box
+ */
+ private String field_text_prompt;
+
+ /**
+ * Text of the error box
+ */
+ private String field_text_error;
+
+ /**
+ * Size of the formula data for first condition
+ */
+ private short field_size_first_formula;
+
+ /**
+ * Not used
+ */
+ private short field_not_used_1 = 0x3FE0;
+
+ /**
+ * Formula data for first condition (RPN token array without size field)
+ */
+ private Stack field_rpn_token_1 ;
+
+ /**
+ * Size of the formula data for second condition
+ */
+ private short field_size_sec_formula;
+
+ /**
+ * Not used
+ */
+ private short field_not_used_2 = 0x0000;
+
+ /**
+ * Formula data for second condition (RPN token array without size field)
+ */
+ private Stack field_rpn_token_2 ;
+
+ /**
+ * Cell range address list with all affected ranges
+ */
+ private HSSFCellRangeAddress field_regions;
+
+ public static final Integer STRING_PROMPT_TITLE = new Integer(0);
+ public static final Integer STRING_ERROR_TITLE = new Integer(1);
+ public static final Integer STRING_PROMPT_TEXT = new Integer(2);
+ public static final Integer STRING_ERROR_TEXT = new Integer(3);
+ private Hashtable _hash_strings ;
+
+ /**
+ * Option flags field
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ private BitField opt_data_type = new BitField(0x0000000F);
+ private BitField opt_error_style = new BitField(0x00000070);
+ private BitField opt_string_list_formula = new BitField(0x00000080);
+ private BitField opt_empty_cell_allowed = new BitField(0x00000100);
+ private BitField opt_surppres_dropdown_arrow = new BitField(0x00000200);
+ private BitField opt_show_prompt_on_cell_selected = new BitField(0x00040000);
+ private BitField opt_show_error_on_invalid_value = new BitField(0x00080000);
+ private BitField opt_condition_operator = new BitField(0x00F00000);
+
+ public DVRecord()
+ {
+ }
+
+ /**
+ * Constructs a DV record and sets its fields appropriately.
+ *
+ * @param in the RecordInputstream to read the record from
+ */
+
+ public DVRecord(RecordInputStream in)
+ {
+ super(in);
+ }
+
+ protected void validateSid(short id)
+ {
+ if (id != sid)
+ {
+ throw new RecordFormatException("NOT a valid DV RECORD");
+ }
+ }
+
+ protected void fillFields(RecordInputStream in)
+ {
+ field_rpn_token_1 = new Stack();
+ field_rpn_token_2 = new Stack();
+
+ this.field_option_flags = in.readInt();
+ this._hash_strings = new Hashtable(4);
+
+ StringHandler strHandler_prompt_title = new StringHandler( in );
+ this.field_title_prompt = strHandler_prompt_title.getStringData();
+ this._hash_strings.put(DVRecord.STRING_PROMPT_TITLE, strHandler_prompt_title);
+
+ StringHandler strHandler_error_title = new StringHandler( in );
+ this.field_title_error = strHandler_error_title.getStringData();
+ this._hash_strings.put(DVRecord.STRING_ERROR_TITLE, strHandler_error_title);
+
+ StringHandler strHandler_prompt_text = new StringHandler( in );
+ this.field_text_prompt = strHandler_prompt_text.getStringData();
+ this._hash_strings.put(DVRecord.STRING_PROMPT_TEXT, strHandler_prompt_text);
+
+ StringHandler strHandler_error_text = new StringHandler( in );
+ this.field_text_error = strHandler_error_text.getStringData();
+ this._hash_strings.put(DVRecord.STRING_ERROR_TEXT, strHandler_error_text);
+
+ this.field_size_first_formula = in.readShort();
+ this.field_not_used_1 = in.readShort();
+
+ //read first formula data condition
+ // Not sure if this was needed or not...
+// try {
+// in.skip(this.field_size_first_formula);
+// } catch(IOException e) { throw new IllegalStateException(e); }
+
+ int token_pos = 0;
+ while (token_pos < this.field_size_first_formula)
+ {
+ Ptg ptg = Ptg.createPtg(in);
+ token_pos += ptg.getSize();
+ field_rpn_token_1.push(ptg);
+ }
+
+ this.field_size_sec_formula = in.readShort();
+ this.field_not_used_2 = in.readShort();
+
+ //read sec formula data condition
+ // Not sure if this was needed or not...
+ try {
+ in.skip(this.field_size_sec_formula);
+ } catch(IOException e) { throw new IllegalStateException(e); }
+
+ token_pos = 0;
+ while (token_pos < this.field_size_sec_formula)
+ {
+ Ptg ptg = Ptg.createPtg(in);
+ token_pos += ptg.getSize();
+ field_rpn_token_2.push(ptg);
+ }
+
+ //read cell range address list with all affected ranges
+ this.field_regions = new HSSFCellRangeAddress(in);
+ }
+
+
+ // --> start option flags
+ /**
+ * set the condition data type
+ * @param type - condition data type
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public void setDataType(int type)
+ {
+ this.field_option_flags = this.opt_data_type.setValue(this.field_option_flags, type);
+ }
+
+ /**
+ * get the condition data type
+ * @return the condition data type
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public int getDataType()
+ {
+ return this.opt_data_type.getValue(this.field_option_flags);
+ }
+
+ /**
+ * set the condition error style
+ * @param type - condition error style
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public void setErrorStyle(int style)
+ {
+ this.field_option_flags = this.opt_error_style.setValue(this.field_option_flags, style);
+ }
+
+ /**
+ * get the condition error style
+ * @return the condition error style
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public int getErrorStyle()
+ {
+ return this.opt_error_style.getValue(this.field_option_flags);
+ }
+
+ /**
+ * set if in list validations the string list is explicitly given in the formula
+ * @param type - true if in list validations the string list is explicitly given in the formula; false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public void setListExplicitFormula(boolean explicit)
+ {
+ this.field_option_flags = this.opt_string_list_formula.setBoolean(this.field_option_flags, explicit);
+ }
+
+ /**
+ * return true if in list validations the string list is explicitly given in the formula, false otherwise
+ * @return true if in list validations the string list is explicitly given in the formula, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public boolean getListExplicitFormula()
+ {
+ return (this.opt_string_list_formula.isSet(this.field_option_flags));
+ }
+
+ /**
+ * set if empty values are allowed in cells
+ * @param type - true if empty values are allowed in cells, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public void setEmptyCellAllowed(boolean allowed)
+ {
+ this.field_option_flags = this.opt_empty_cell_allowed.setBoolean(this.field_option_flags, allowed);
+ }
+
+ /**
+ * return true if empty values are allowed in cells, false otherwise
+ * @return if empty values are allowed in cells, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public boolean getEmptyCellAllowed()
+ {
+ return (this.opt_empty_cell_allowed.isSet(this.field_option_flags));
+ }
+
+ /**
+ * set if drop down arrow should be surppressed when list validation is used
+ * @param type - true if drop down arrow should be surppressed when list validation is used, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public void setSurppresDropdownArrow(boolean surppress)
+ {
+ this.field_option_flags = this.opt_surppres_dropdown_arrow.setBoolean(this.field_option_flags, surppress);
+ }
+
+ /**
+ * return true if drop down arrow should be surppressed when list validation is used, false otherwise
+ * @return if drop down arrow should be surppressed when list validation is used, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public boolean getSurppresDropdownArrow()
+ {
+ return (this.opt_surppres_dropdown_arrow.isSet(this.field_option_flags));
+ }
+
+ /**
+ * set if a prompt window should appear when cell is selected
+ * @param type - true if a prompt window should appear when cell is selected, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public void setShowPromptOnCellSelected(boolean show)
+ {
+ this.field_option_flags = this.opt_show_prompt_on_cell_selected.setBoolean(this.field_option_flags, show);
+ }
+
+ /**
+ * return true if a prompt window should appear when cell is selected, false otherwise
+ * @return if a prompt window should appear when cell is selected, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public boolean getShowPromptOnCellSelected()
+ {
+ return (this.opt_show_prompt_on_cell_selected.isSet(this.field_option_flags));
+ }
+
+ /**
+ * set if an error window should appear when an invalid value is entered in the cell
+ * @param type - true if an error window should appear when an invalid value is entered in the cell, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public void setShowErrorOnInvalidValue(boolean show)
+ {
+ this.field_option_flags = this.opt_show_error_on_invalid_value.setBoolean(this.field_option_flags, show);
+ }
+
+ /**
+ * return true if an error window should appear when an invalid value is entered in the cell, false otherwise
+ * @return if an error window should appear when an invalid value is entered in the cell, false otherwise
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public boolean getShowErrorOnInvalidValue()
+ {
+ return (this.opt_show_error_on_invalid_value.isSet(this.field_option_flags));
+ }
+
+ /**
+ * set the condition operator
+ * @param type - condition operator
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public void setConditionOperator(int operator)
+ {
+ this.field_option_flags = this.opt_condition_operator.setValue(this.field_option_flags, operator);
+ }
+
+ /**
+ * get the condition operator
+ * @return the condition operator
+ * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
+ */
+ public int getConditionOperator()
+ {
+ return this.opt_condition_operator.getValue(this.field_option_flags);
+ }
+ // <-- end option flags
+
+ public void setFirstFormulaRPN( Stack rpn )
+ {
+ this.field_rpn_token_1 = rpn;
+ }
+
+ public void setFirstFormulaSize( short size )
+ {
+ this.field_size_first_formula = size;
+ }
+
+ public void setSecFormulaRPN( Stack rpn )
+ {
+ this.field_rpn_token_2 = rpn;
+ }
+
+ public void setSecFormulaSize( short size )
+ {
+ this.field_size_sec_formula = size;
+ }
+
+ public void setStringField( Integer type, String str_data )
+ {
+ if ( this._hash_strings == null )
+ {
+ this._hash_strings = new Hashtable();
+ }
+ StringHandler strHandler = new StringHandler();
+ if ( str_data == null )
+ {
+ str_data = "";
+ }
+ else
+ {
+ strHandler.setStringLength(str_data.length());
+ }
+ strHandler.setStringData(str_data);
+
+ strHandler.setUnicodeFlag((byte)0x00);
+ this._hash_strings.put( type, strHandler);
+ }
+
+ public String getStringField( Integer type )
+ {
+ return ((StringHandler)this._hash_strings.get(type)).getStringData();
+ }
+
+ public void setCellRangeAddress( HSSFCellRangeAddress range )
+ {
+ this.field_regions = range;
+ }
+
+ public HSSFCellRangeAddress getCellRangeAddress( )
+ {
+ return this.field_regions;
+ }
+
+ /**
+ * gets the option flags field.
+ * @return options - the option flags field
+ */
+ public int getOptionFlags()
+ {
+ return this.field_option_flags;
+ }
+
+ public String toString()
+ {
+ /** @todo DVRecord string representation */
+ StringBuffer buffer = new StringBuffer();
+
+ return buffer.toString();
+ }
+
+ public int serialize(int offset, byte [] data)
+ {
+ int size = this.getRecordSize();
+ LittleEndian.putShort(data, 0 + offset, sid);
+ LittleEndian.putShort(data, 2 + offset, ( short ) (size-4));
+
+ int pos = 4;
+ LittleEndian.putInt(data, pos + offset, this.getOptionFlags());
+ pos += 4;
+ pos += ((StringHandler)this._hash_strings.get( DVRecord.STRING_PROMPT_TITLE )).serialize(pos+offset, data);
+ pos += ((StringHandler)this._hash_strings.get( DVRecord.STRING_ERROR_TITLE )).serialize(pos+offset, data);
+ pos += ((StringHandler)this._hash_strings.get( DVRecord.STRING_PROMPT_TEXT )).serialize(pos+offset, data);
+ pos += ((StringHandler)this._hash_strings.get( DVRecord.STRING_ERROR_TEXT )).serialize(pos+offset, data);
+ LittleEndian.putShort(data, offset+pos, this.field_size_first_formula);
+ pos += 2;
+ LittleEndian.putShort(data, offset+pos, this.field_not_used_1);
+ pos += 2;
+
+ for (int k = 0; k < this.field_rpn_token_1.size(); k++)
+ {
+ Ptg ptg = ( Ptg ) this.field_rpn_token_1.get(k);
+ ptg.writeBytes(data, pos+offset);
+ pos += ptg.getSize();
+ }
+
+ LittleEndian.putShort(data, offset+pos, this.field_size_sec_formula);
+ pos += 2;
+ LittleEndian.putShort(data, offset+pos, this.field_not_used_2);
+ pos += 2;
+ if ( this.field_size_sec_formula > 0 )
+ {
+ for (int k = 0; k < this.field_rpn_token_2.size(); k++)
+ {
+ Ptg ptg = ( Ptg ) this.field_rpn_token_2.get(k);
+ ptg.writeBytes(data, pos+offset);
+ pos += ptg.getSize();
+ }
+ }
+ this.field_regions.serialize(pos+offset, data);
+ return size;
+ }
+
+ public int getRecordSize()
+ {
+ int size = 4+4+2+2+2+2;//header+options_field+first_formula_size+first_unused+sec_formula_size+sec+unused;
+ if ( this._hash_strings != null )
+ {
+ Enumeration enum_keys = this._hash_strings.keys();
+ while ( enum_keys.hasMoreElements() )
+ {
+ size += ((StringHandler)this._hash_strings.get( (Integer)enum_keys.nextElement() )).getSize();
+ }
+ }
+ size += this.field_size_first_formula+ this.field_size_sec_formula;
+ size += this.field_regions.getSize();
+ return size;
+ }
+
+ public short getSid()
+ {
+ return this.sid;
+ }
+
+ /**@todo DVRecord = Serializare */
+
+ private class StringHandler
+ {
+ private int _string_length = 0x0001;
+ private byte _string_unicode_flag = 0x00;
+ private String _string_data = "0x00";
+ private int _start_offset;
+ private int _end_offset;
+
+ StringHandler()
+ {
+
+ }
+
+ StringHandler(RecordInputStream in)
+ {
+ this.fillFields(in);
+ }
+
+ protected void fillFields(RecordInputStream in)
+ {
+ this._string_length = in.readUShort();
+ this._string_unicode_flag = in.readByte();
+ if (this._string_unicode_flag == 1)
+ {
+ this._string_data = in.readUnicodeLEString(this._string_length);
+ }
+ else
+ {
+ this._string_data = in.readCompressedUnicode(this._string_length);
+ }
+ }
+
+ private void setStringData( String string_data )
+ {
+ this._string_data = string_data;
+ }
+
+ private String getStringData()
+ {
+ return this._string_data;
+ }
+
+ private int getEndOffset()
+ {
+ return this._end_offset;
+ }
+
+ public int serialize( int offset, byte[] data )
+ {
+ LittleEndian.putUShort(data, offset, this._string_length );
+ data[2 + offset] = this._string_unicode_flag;
+ if (this._string_unicode_flag == 1)
+ {
+ StringUtil.putUnicodeLE(this._string_data, data, 3 + offset);
+ }
+ else
+ {
+ StringUtil.putCompressedUnicode(this._string_data, data, 3 + offset);
+ }
+ return getSize();
+ }
+
+ private void setUnicodeFlag( byte flag )
+ {
+ this._string_unicode_flag = flag;
+ }
+
+ private void setStringLength( int len )
+ {
+ this._string_length = len;
+ }
+
+ private int getStringByteLength()
+ {
+ return (this._string_unicode_flag == 1) ? this._string_length * 2 : this._string_length;
+ }
+
+ public int getSize()
+ {
+ return 2 + 1 + getStringByteLength();
+ }
+ }
+}
HorizontalPageBreakRecord.class, VerticalPageBreakRecord.class,
WriteProtectRecord.class, FilePassRecord.class, PaneRecord.class,
NoteRecord.class, ObjectProtectRecord.class, ScenarioProtectRecord.class,
- FileSharingRecord.class, ChartTitleFormatRecord.class
+ FileSharingRecord.class, ChartTitleFormatRecord.class,
+ DVRecord.class, DVALRecord.class
};
}
private static Map recordsMap = recordsToMap(records);
} else if (record.getSid() == ContinueRecord.sid &&
(lastRecord instanceof DrawingGroupRecord)) {
((DrawingGroupRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
+ } else if (record.getSid() == ContinueRecord.sid &&
+ (lastRecord instanceof StringRecord)) {
+ ((StringRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
} else if (record.getSid() == ContinueRecord.sid) {
if (lastRecord instanceof UnknownRecord) {
//Gracefully handle records that we dont know about,
field_3_string = StringUtil.getFromCompressedUnicode(data, 0, field_1_string_length);
}
}
+
+ public void processContinueRecord(byte[] data) {
+ if(isUnCompressedUnicode()) {
+ field_3_string += StringUtil.getFromUnicodeLE(data, 0, field_1_string_length - field_3_string.length());
+ } else {
+ field_3_string += StringUtil.getFromCompressedUnicode(data, 0, field_1_string_length - field_3_string.length());
+ }
+ }
public boolean isInValueSection()
{
*/
public void setCellValue(Date value)
{
- setCellValue(HSSFDateUtil.getExcelDate(value));
+ setCellValue(HSSFDateUtil.getExcelDate(value, this.book.isUsing1904DateWindowing()));
}
/**
format.setFontIndex(fontindex);
}
+ /**
+ * gets the index of the font for this style
+ * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(short)
+ */
public short getFontIndex()
{
return format.getFontIndex();
}
+
+ /**
+ * gets the font for this style
+ * @param parentWorkbook The HSSFWorkbook that this style belongs to
+ * @see org.apache.poi.hssf.usermodel.HSSFCellStyle#getFontIndex()
+ * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(short)
+ */
+ public HSSFFont getFont(HSSFWorkbook parentWorkbook) {
+ return parentWorkbook.getFontAt(getFontIndex());
+ }
/**
* set the cell's using this style to be hidden
* @see #BORDER_MEDIUM_DASH_DOT_DOT
* @see #BORDER_SLANTED_DASH_DOT
*/
-
public short getBorderBottom()
{
return format.getBorderBottom();
/**
* set the color to use for the left border
- * @param color
+ * @param color The index of the color definition
*/
-
public void setLeftBorderColor(short color)
{
format.setLeftBorderPaletteIdx(color);
/**
* get the color to use for the left border
- * @return color
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
+ * @param color The index of the color definition
*/
-
public short getLeftBorderColor()
{
return format.getLeftBorderPaletteIdx();
/**
* set the color to use for the right border
- * @param color
+ * @param color The index of the color definition
*/
-
public void setRightBorderColor(short color)
{
format.setRightBorderPaletteIdx(color);
/**
* get the color to use for the left border
- * @return color
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
+ * @param color The index of the color definition
*/
-
public short getRightBorderColor()
{
return format.getRightBorderPaletteIdx();
/**
* set the color to use for the top border
- * @param color
+ * @param color The index of the color definition
*/
-
public void setTopBorderColor(short color)
{
format.setTopBorderPaletteIdx(color);
/**
* get the color to use for the top border
- * @return color
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
+ * @param color The index of the color definition
*/
-
public short getTopBorderColor()
{
return format.getTopBorderPaletteIdx();
/**
* set the color to use for the bottom border
- * @param color
+ * @param color The index of the color definition
*/
-
public void setBottomBorderColor(short color)
{
format.setBottomBorderPaletteIdx(color);
/**
* get the color to use for the left border
- * @return color
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
+ * @param color The index of the color definition
*/
-
public short getBottomBorderColor()
{
return format.getBottomBorderPaletteIdx();
/**
* get the background fill color
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
* @return fill color
*/
-
public short getFillBackgroundColor()
{
short result = format.getFillBackground();
* <i>Note: Ensure Foreground color is set prior to background color.</i>
* @param bg color
*/
-
public void setFillForegroundColor(short bg)
{
format.setFillForeground(bg);
/**
* get the foreground fill color
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
* @return fill color
*/
-
public short getFillForegroundColor()
{
return format.getFillForeground();
}
-
}
*/
public float getAnchorHeightInPoints(HSSFSheet sheet )
{
- int y1 = Math.min( getDy1(), getDy2() );
- int y2 = Math.max( getDy1(), getDy2() );
+ int y1 = getDy1();
+ int y2 = getDy2();
int row1 = Math.min( getRow1(), getRow2() );
int row2 = Math.max( getRow1(), getRow2() );
* @author Glen Stampoultzis (glens at apache.org)
* @author Dan Sherman (dsherman at isisph.com)
* @author Hack Kampbjorn (hak at 2mba.dk)
+ * @author Alex Jacoby (ajacoby at gmail.com)
+ * @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
*/
public class HSSFDateUtil
* @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1)
* @param date the Date
*/
-
- public static double getExcelDate(Date date)
- {
+ public static double getExcelDate(Date date) {
+ return getExcelDate(date, false);
+ }
+ /**
+ * Given a Date, converts it into a double representing its internal Excel representation,
+ * which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds.
+ *
+ * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1)
+ * @param date the Date
+ * @param use1904windowing Should 1900 or 1904 date windowing be used?
+ */
+ public static double getExcelDate(Date date, boolean use1904windowing) {
Calendar calStart = new GregorianCalendar();
-
- calStart.setTime(
- date); // If date includes hours, minutes, and seconds, set them to 0
- if (calStart.get(Calendar.YEAR) < 1900)
+ calStart.setTime(date); // If date includes hours, minutes, and seconds, set them to 0
+
+ if ((!use1904windowing && calStart.get(Calendar.YEAR) < 1900) ||
+ (use1904windowing && calStart.get(Calendar.YEAR) < 1904))
{
return BAD_DATE;
- }
- else
- {
+ } else {
// Because of daylight time saving we cannot use
// date.getTime() - calStart.getTimeInMillis()
// as the difference in milliseconds between 00:00 and 04:00
) * 1000 + calStart.get(Calendar.MILLISECOND)
) / ( double ) DAY_MILLISECONDS;
calStart = dayStart(calStart);
-
- double value = fraction + absoluteDay(calStart);
- if (value >= 60) {
- value += 1;
+ double value = fraction + absoluteDay(calStart, use1904windowing);
+
+ if (!use1904windowing && value >= 60) {
+ value++;
+ } else if (use1904windowing) {
+ value--;
}
return value;
}
}
-
+
/**
- * Given a excel date, converts it into a Date.
- * Assumes 1900 date windowing.
+ * Given an Excel date with using 1900 date windowing, and
+ * converts it to a java.util.Date.
*
- * @param date the Excel Date
- *
- * @return Java representation of a date (null if error)
- * @see #getJavaDate(double,boolean)
+ * NOTE: If the default <code>TimeZone</code> in Java uses Daylight
+ * Saving Time then the conversion back to an Excel date may not give
+ * the same value, that is the comparison
+ * <CODE>excelDate == getExcelDate(getJavaDate(excelDate,false))</CODE>
+ * is not always true. For example if default timezone is
+ * <code>Europe/Copenhagen</code>, on 2004-03-28 the minute after
+ * 01:59 CET is 03:00 CEST, if the excel date represents a time between
+ * 02:00 and 03:00 then it is converted to past 03:00 summer time
+ *
+ * @param date The Excel date.
+ * @return Java representation of the date, or null if date is not a valid Excel date
+ * @see java.util.TimeZone
*/
-
- public static Date getJavaDate(double date)
- {
- return getJavaDate(date,false);
+ public static Date getJavaDate(double date) {
+ return getJavaDate(date, false);
}
-
/**
* Given an Excel date with either 1900 or 1904 date windowing,
* converts it to a java.util.Date.
GregorianCalendar calendar = new GregorianCalendar(startYear,0,
wholeDays + dayAdjust);
int millisecondsInDay = (int)((date - Math.floor(date)) *
- (double) DAY_MILLISECONDS + 0.5);
+ DAY_MILLISECONDS + 0.5);
calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay);
return calendar.getTime();
}
* Check if a cell contains a date
* Since dates are stored internally in Excel as double values
* we infer it is a date if it is formatted as such.
- * @see #isADateFormat(int,string)
+ * @see #isADateFormat(int, String)
* @see #isInternalDateFormat(int)
*/
public static boolean isCellDateFormatted(HSSFCell cell) {
* excel date formats.
* As Excel stores a great many of its dates in "non-internal"
* date formats, you will not normally want to use this method.
- * @see #isADateFormat(int,string)
+ * @see #isADateFormat(int,String)
* @see #isInternalDateFormat(int)
*/
public static boolean isCellInternalDateFormatted(HSSFCell cell) {
* @exception IllegalArgumentException if date is invalid
*/
- private static int absoluteDay(Calendar cal)
+ static int absoluteDay(Calendar cal, boolean use1904windowing)
{
return cal.get(Calendar.DAY_OF_YEAR)
- + daysInPriorYears(cal.get(Calendar.YEAR));
+ + daysInPriorYears(cal.get(Calendar.YEAR), use1904windowing);
}
/**
*
* @return days number of days in years prior to yr.
* @param yr a year (1900 < yr < 4000)
+ * @param use1904windowing
* @exception IllegalArgumentException if year is outside of range.
*/
- private static int daysInPriorYears(int yr)
+ private static int daysInPriorYears(int yr, boolean use1904windowing)
{
- if (yr < 1900) {
- throw new IllegalArgumentException(
- "'year' must be 1900 or greater");
+ if ((!use1904windowing && yr < 1900) || (use1904windowing && yr < 1900)) {
+ throw new IllegalArgumentException("'year' must be 1900 or greater");
}
int yr1 = yr - 1;
+ yr1 / 400 // plus years divisible by 400
- 460; // leap days in previous 1900 years
- return 365 * (yr - 1900) + leapDays;
+ return 365 * (yr - (use1904windowing ? 1904 : 1900)) + leapDays;
}
// set HH:MM:SS fields of cal to 00:00:00:000
* @return color to use
* @see #COLOR_NORMAL
* @see #COLOR_RED
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
*/
-
public short getColor()
{
return font.getColorPaletteIndex();
package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.util.HSSFCellRangeAddress;
+import org.apache.poi.hssf.util.HSSFDataValidation;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.hssf.util.PaneInformation;
import org.apache.poi.util.POILogFactory;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Stack;
import java.util.TreeMap;
import java.text.AttributedString;
import java.text.NumberFormat;
{
return lastrow;
}
+
+ /**
+ * Creates a data validation object
+ * @param obj_validation The Data validation object settings
+ */
+ public void addValidationData(HSSFDataValidation obj_validation)
+ {
+ if ( obj_validation == null )
+ {
+ return;
+ }
+ DVALRecord dvalRec = (DVALRecord)sheet.findFirstRecordBySid( DVALRecord.sid );
+ int eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
+ if ( dvalRec == null )
+ {
+ dvalRec = new DVALRecord();
+ sheet.getRecords().add( eofLoc, dvalRec );
+ }
+ int curr_dvRecNo = dvalRec.getDVRecNo();
+ dvalRec.setDVRecNo(curr_dvRecNo+1);
+
+ //create dv record
+ DVRecord dvRecord = new DVRecord();
+
+ //dv record's option flags
+ dvRecord.setDataType( obj_validation.getDataValidationType() );
+ dvRecord.setErrorStyle(obj_validation.getErrorStyle());
+ dvRecord.setEmptyCellAllowed(obj_validation.getEmptyCellAllowed());
+ dvRecord.setSurppresDropdownArrow(obj_validation.getSurppressDropDownArrow());
+ dvRecord.setShowPromptOnCellSelected(obj_validation.getShowPromptBox());
+ dvRecord.setShowErrorOnInvalidValue(obj_validation.getShowErrorBox());
+ dvRecord.setConditionOperator(obj_validation.getOperator());
+
+ //string fields
+ dvRecord.setStringField( DVRecord.STRING_PROMPT_TITLE,obj_validation.getPromptBoxTitle());
+ dvRecord.setStringField( DVRecord.STRING_PROMPT_TEXT, obj_validation.getPromptBoxText());
+ dvRecord.setStringField( DVRecord.STRING_ERROR_TITLE, obj_validation.getErrorBoxTitle());
+ dvRecord.setStringField( DVRecord.STRING_ERROR_TEXT, obj_validation.getErrorBoxText());
+
+ //formula fields ( size and data )
+ String str_formula = obj_validation.getFirstFormula();
+ FormulaParser fp = new FormulaParser(str_formula+";",book);
+ fp.parse();
+ Stack ptg_arr = new Stack();
+ Ptg[] ptg = fp.getRPNPtg();
+ int size = 0;
+ for (int k = 0; k < ptg.length; k++)
+ {
+ if ( ptg[k] instanceof org.apache.poi.hssf.record.formula.AreaPtg )
+ {
+ //we should set ptgClass to Ptg.CLASS_REF and explicit formula string to false
+ ptg[k].setClass(Ptg.CLASS_REF);
+ obj_validation.setExplicitListFormula(false);
+ }
+ size += ptg[k].getSize();
+ ptg_arr.push(ptg[k]);
+ }
+ dvRecord.setFirstFormulaRPN(ptg_arr);
+ dvRecord.setFirstFormulaSize((short)size);
+
+ dvRecord.setListExplicitFormula(obj_validation.getExplicitListFormula());
+
+ if ( obj_validation.getSecondFormula() != null )
+ {
+ str_formula = obj_validation.getSecondFormula();
+ fp = new FormulaParser(str_formula+";",book);
+ fp.parse();
+ ptg_arr = new Stack();
+ ptg = fp.getRPNPtg();
+ size = 0;
+ for (int k = 0; k < ptg.length; k++)
+ {
+ size += ptg[k].getSize();
+ ptg_arr.push(ptg[k]);
+ }
+ dvRecord.setSecFormulaRPN(ptg_arr);
+ dvRecord.setSecFormulaSize((short)size);
+ }
+
+ //dv records cell range field
+ HSSFCellRangeAddress cell_range = new HSSFCellRangeAddress();
+ cell_range.addADDRStructure(obj_validation.getFirstRow(), obj_validation.getFirstColumn(), obj_validation.getLastRow(), obj_validation.getLastColumn());
+ dvRecord.setCellRangeAddress(cell_range);
+
+ //add dv record
+ eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
+ sheet.getRecords().add( eofLoc, dvRecord );
+ }
/**
* Get the visibility state for a given column.
--- /dev/null
+/* ====================================================================
+ 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.util;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndian;
+import java.util.ArrayList;
+
+/**
+ * <p>Title: HSSFCellRangeAddress</p>
+ * <p>Description:
+ * Implementation of the cell range address lists,like is described in
+ * OpenOffice.org's Excel Documentation .
+ * In BIFF8 there is a common way to store absolute cell range address
+ * lists in several records (not formulas). A cell range address list
+ * consists of a field with the number of ranges and the list of the range
+ * addresses. Each cell range address (called an ADDR structure) contains
+ * 4 16-bit-values.</p>
+ * <p>Copyright: Copyright (c) 2004</p>
+ * <p>Company: </p>
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ * @version 2.0-pre
+ */
+
+public class HSSFCellRangeAddress
+{
+ /**
+ * Number of following ADDR structures
+ */
+ private short field_addr_number;
+
+ /**
+ * List of ADDR structures. Each structure represents a cell range
+ */
+ private ArrayList field_regions_list;
+
+ public HSSFCellRangeAddress()
+ {
+
+ }
+
+ /**
+ * Construct a new HSSFCellRangeAddress object and sets its fields appropriately .
+ * Even this isn't an Excel record , I kept the same behavior for reading/writing
+ * the object's data as for a regular record .
+ *
+ * @param in the RecordInputstream to read the record from
+ */
+ public HSSFCellRangeAddress(RecordInputStream in)
+ {
+ this.fillFields(in);
+ }
+
+ public void fillFields(RecordInputStream in)
+ {
+ this.field_addr_number = in.readShort();
+ this.field_regions_list = new ArrayList(this.field_addr_number);
+
+ for (int k = 0; k < this.field_addr_number; k++)
+ {
+ short first_row = in.readShort();
+ short first_col = in.readShort();
+ short last_row = in.readShort();
+ short last_col = in.readShort();
+
+ AddrStructure region = new AddrStructure(first_row, first_col, last_row, last_col);
+ this.field_regions_list.add(region);
+ }
+ }
+
+ /**
+ * Get the number of following ADDR structures.
+ * The number of this structures is automatically set when reading an Excel file
+ * and/or increased when you manually add a new ADDR structure .
+ * This is the reason there isn't a set method for this field .
+ * @return number of ADDR structures
+ */
+ public short getADDRStructureNumber()
+ {
+ return this.field_addr_number;
+ }
+
+ /**
+ * Add an ADDR structure .
+ * @param first_row - the upper left hand corner's row
+ * @param first_col - the upper left hand corner's col
+ * @param last_row - the lower right hand corner's row
+ * @param last_col - the lower right hand corner's col
+ * @return the index of this ADDR structure
+ */
+ public int addADDRStructure(short first_row, short first_col, short last_row, short last_col)
+ {
+ if (this.field_regions_list == null)
+ {
+ //just to be sure :-)
+ this.field_addr_number= 0;
+ this.field_regions_list = new ArrayList(10);
+ }
+ AddrStructure region = new AddrStructure(first_row, last_row, first_col, last_col);
+
+ this.field_regions_list.add(region);
+ this.field_addr_number++;
+ return this.field_addr_number;
+ }
+
+ /**
+ * Remove the ADDR structure stored at the passed in index
+ * @param index The ADDR structure's index
+ */
+ public void removeADDRStructureAt(int index)
+ {
+ this.field_regions_list.remove(index);
+ this.field_addr_number--;
+ }
+
+ /**
+ * return the ADDR structure at the given index.
+ * @return AddrStructure representing
+ */
+ public AddrStructure getADDRStructureAt(int index)
+ {
+ return ( AddrStructure ) this.field_regions_list.get(index);
+ }
+
+ public int serialize(int offset, byte [] data)
+ {
+ int pos = 2;
+
+ LittleEndian.putShort(data, offset, this.getADDRStructureNumber());
+ for (int k = 0; k < this.getADDRStructureNumber(); k++)
+ {
+ AddrStructure region = this.getADDRStructureAt(k);
+ LittleEndian.putShort(data, offset + pos, region.getFirstRow());
+ pos += 2;
+ LittleEndian.putShort(data, offset + pos, region.getLastRow());
+ pos += 2;
+ LittleEndian.putShort(data, offset + pos, region.getFirstColumn());
+ pos += 2;
+ LittleEndian.putShort(data, offset + pos, region.getLastColumn());
+ pos += 2;
+ }
+ return this.getSize();
+ }
+
+ public int getSize()
+ {
+ return 2 + this.field_addr_number*8;
+ }
+
+ public class AddrStructure
+ {
+ private short _first_row;
+ private short _first_col;
+ private short _last_row;
+ private short _last_col;
+
+ public AddrStructure(short first_row, short last_row, short first_col, short last_col)
+ {
+ this._first_row = first_row;
+ this._last_row = last_row;
+ this._first_col = first_col;
+ this._last_col = last_col;
+ }
+
+ /**
+ * get the upper left hand corner column number
+ * @return column number for the upper left hand corner
+ */
+ public short getFirstColumn()
+ {
+ return this._first_col;
+ }
+
+ /**
+ * get the upper left hand corner row number
+ * @return row number for the upper left hand corner
+ */
+ public short getFirstRow()
+ {
+ return this._first_row;
+ }
+
+ /**
+ * get the lower right hand corner column number
+ * @return column number for the lower right hand corner
+ */
+ public short getLastColumn()
+ {
+ return this._last_col;
+ }
+
+ /**
+ * get the lower right hand corner row number
+ * @return row number for the lower right hand corner
+ */
+ public short getLastRow()
+ {
+ return this._last_row;
+ }
+
+ /**
+ * set the upper left hand corner column number
+ * @param this._first_col column number for the upper left hand corner
+ */
+ public void setFirstColumn(short first_col)
+ {
+ this._first_col = first_col;
+ }
+
+ /**
+ * set the upper left hand corner row number
+ * @param rowFrom row number for the upper left hand corner
+ */
+ public void setFirstRow(short first_row)
+ {
+ this._first_row = first_row;
+ }
+
+ /**
+ * set the lower right hand corner column number
+ * @param colTo column number for the lower right hand corner
+ */
+ public void setLastColumn(short last_col)
+ {
+ this._last_col = last_col;
+ }
+
+ /**
+ * get the lower right hand corner row number
+ * @param rowTo row number for the lower right hand corner
+ */
+ public void setLastRow(short last_row)
+ {
+ this._last_row = last_row;
+ }
+ }
+}
+
+
--- /dev/null
+/* ====================================================================
+ 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.util;
+
+/**
+ * <p>Title: HSSFDataValidation</p>
+ * <p>Description: Utilty class for creating data validation cells</p>
+ * <p>Copyright: Copyright (c) 2004</p>
+ * <p>Company: </p>
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ * @version 2.0-pre
+ */
+
+public class HSSFDataValidation
+{
+ /**
+ * Validation data type constants
+ */
+ /**
+ * Any type
+ */
+ public static final int DATA_TYPE_ANY = 0x00;
+ /**
+ * Integer type
+ */
+ public static final int DATA_TYPE_INTEGER = 0x01;
+ /**
+ * Decimal type
+ */
+ public static final int DATA_TYPE_DECIMAL = 0x02;
+ /**
+ * List type ( combo box type )
+ */
+ public static final int DATA_TYPE_LIST = 0x03;
+ /**
+ * Date type
+ */
+ public static final int DATA_TYPE_DATE = 0x04;
+ /**
+ * Time type
+ */
+ public static final int DATA_TYPE_TIME = 0x05;
+ /**
+ * String length type
+ */
+ public static final int DATA_TYPE_TEXT_LENGTH = 0x06;
+ /**
+ * Formula ( custom ) type
+ */
+ public static final int DATA_TYPE_FORMULA = 0x07;
+
+ /**
+ * Error style constants for error box
+ */
+ /**
+ * STOP style like
+ */
+ public static final int ERROR_STYLE_STOP = 0x00;
+ /**
+ * WARNING style like
+ */
+ public static final int ERROR_STYLE_WARNING = 0x01;
+ /**
+ * INFO style like
+ */
+ public static final int ERROR_STYLE_INFO = 0x02;
+
+ /**
+ * Condition operator
+ */
+ public static final int OPERATOR_BETWEEN = 0x00;
+ public static final int OPERATOR_NOT_BETWEEN = 0x01;
+ public static final int OPERATOR_EQUAL = 0x02;
+ public static final int OPERATOR_NOT_EQUAL = 0x03;
+ public static final int OPERATOR_GREATER_THAN = 0x04;
+ public static final int OPERATOR_LESS_THAN = 0x05;
+ public static final int OPERATOR_GREATER_OR_EQUAL = 0x06;
+ public static final int OPERATOR_LESS_OR_EQUAL = 0x07;
+
+ private short _first_row = 0;
+ private short _first_col = 0;
+ private short _last_row = 0;
+ private short _last_col = 0;
+
+ private String _prompt_title = null;
+ private String _prompt_text = null;
+ private String _error_title = null;
+ private String _error_text = null;
+ private String _string_first_formula = null;
+ private String _string_sec_formula = null;
+
+ private int _data_type = HSSFDataValidation.DATA_TYPE_ANY;
+ private int _error_style = HSSFDataValidation.ERROR_STYLE_STOP;
+ private boolean _list_explicit_formula = true;
+ private boolean _empty_cell_allowed = true;
+ private boolean _surpress_dropdown_arrow = false;
+ private boolean _show_prompt_box = true;
+ private boolean _show_error_box = true;
+ private int _operator = HSSFDataValidation.OPERATOR_BETWEEN;
+
+
+ /**
+ * Empty constructor
+ */
+ public HSSFDataValidation( )
+ {
+ }
+
+ /**
+ * Constructor wich initializes the cell range on wich this object will be applied
+ * @param first_row First row
+ * @param first_col First column
+ * @param last_row Last row
+ * @param last_col Last column
+ */
+ public HSSFDataValidation( short first_row, short first_col, short last_row, short last_col )
+ {
+ this._first_row = first_row;
+ this._first_col = first_col;
+ this._last_row = last_row;
+ this._last_col = last_col;
+ }
+
+ /**
+ * Set the type of this object
+ * @param data_type The type
+ * @see DATA_TYPE_ANY, DATA_TYPE_INTEGER, DATA_TYPE_DECIMNAL, DATA_TYPE_LIST, DATA_TYPE_DATE,
+ * DATA_TYPE_TIME, DATA_TYPE_TEXT_LENTGH, DATA_TYPE_FORMULA
+ */
+ public void setDataValidationType( int data_type )
+ {
+ this._data_type = data_type;
+ }
+
+ /**
+ * The data type of this object
+ * @return The type
+ * @see DATA_TYPE_ANY, DATA_TYPE_INTEGER, DATA_TYPE_DECIMNAL, DATA_TYPE_LIST, DATA_TYPE_DATE,
+ * DATA_TYPE_TIME, DATA_TYPE_TEXT_LENTGH, DATA_TYPE_FORMULA
+ */
+ public int getDataValidationType()
+ {
+ return this._data_type;
+ }
+
+ /**
+ * Sets the error style for error box
+ * @param error_style Error style constant
+ * @see ERROR_STYLE_STOP, ERROR_STYLE_WARNING, ERROR_STYLE_INFO
+ */
+ public void setErrorStyle( int error_style )
+ {
+ this._error_style = error_style;
+ }
+
+ /**
+ * returns the error style of errror box
+ * @return the style constant
+ * @see ERROR_STYLE_STOP, ERROR_STYLE_WARNING, ERROR_STYLE_INFO
+ */
+ public int getErrorStyle( )
+ {
+ return this._error_style;
+ }
+
+ /**
+ * If this object has an explicit formula . This is useful only for list data validation object
+ * @param explicit True if use an explicit formula
+ */
+ public void setExplicitListFormula( boolean explicit )
+ {
+ this._list_explicit_formula = explicit;
+ }
+
+ /**
+ * Returns the settings for explicit formula . This is useful only for list data validation objects.
+ * This method always returns false if the object isn't a list validation object
+ * @see setDataValidationType( int data_type )
+ * @return
+ */
+ public boolean getExplicitListFormula( )
+ {
+ if ( this._data_type != HSSFDataValidation.DATA_TYPE_LIST )
+ {
+ return false;
+ }
+ return this._list_explicit_formula ;
+ }
+
+ /**
+ * Sets if this object allows empty as a valid value
+ * @param allowed True if this object should treats empty as valid value , false otherwise
+ */
+ public void setEmptyCellAllowed( boolean allowed )
+ {
+ this._empty_cell_allowed = allowed;
+ }
+
+ /**
+ * Retrieve the settings for empty cells allowed
+ * @return True if this object should treats empty as valid value , false otherwise
+ */
+ public boolean getEmptyCellAllowed( )
+ {
+ return this._empty_cell_allowed ;
+ }
+
+ /**
+ * Useful for list validation objects .
+ * @param surppres True if a list should display the values into a drop down list , false otherwise .
+ * In other words , if a list should display the arrow sign on its right side
+ */
+ public void setSurppressDropDownArrow( boolean surppres )
+ {
+ this._surpress_dropdown_arrow = surppres;
+ }
+
+ /**
+ * Useful only list validation objects .
+ * This method always returns false if the object isn't a list validation object
+ * @return True if a list should display the values into a drop down list , false otherwise .
+ * @see setDataValidationType( int data_type )
+ */
+ public boolean getSurppressDropDownArrow( )
+ {
+ if ( this._data_type != HSSFDataValidation.DATA_TYPE_LIST )
+ {
+ return false;
+ }
+ return this._surpress_dropdown_arrow ;
+ }
+
+ /**
+ * Sets the behaviour when a cell which belongs to this object is selected
+ * @param show True if an prompt box should be displayed , false otherwise
+ */
+ public void setShowPromptBox( boolean show )
+ {
+ this._show_prompt_box = show;
+ }
+
+ /**
+ * @param show True if an prompt box should be displayed , false otherwise
+ */
+ public boolean getShowPromptBox( )
+ {
+ if ( (this.getPromptBoxText() == null) && (this.getPromptBoxTitle() == null) )
+ {
+ return false;
+ }
+ return this._show_prompt_box ;
+ }
+
+ /**
+ * Sets the behaviour when an invalid value is entered
+ * @param show True if an error box should be displayed , false otherwise
+ */
+ public void setShowErrorBox( boolean show )
+ {
+ this._show_error_box = show;
+ }
+
+ /**
+ * @return True if an error box should be displayed , false otherwise
+ */
+ public boolean getShowErrorBox( )
+ {
+ if ( (this.getErrorBoxText() == null) && (this.getErrorBoxTitle() == null) )
+ {
+ return false;
+ }
+ return this._show_error_box ;
+ }
+
+ /**
+ * Sets the operator involved in the formula whic governs this object
+ * Example : if you wants that a cell to accept only values between 1 and 5 , which
+ * mathematically means 1 <= value <= 5 , then the operator should be OPERATOR_BETWEEN
+ * @param operator A constant for operator
+ * @see OPERATOR_BETWEEN, OPERATOR_NOT_BETWEEN, OPERATOR_EQUAL, OPERATOR_NOT_EQUAL
+ * OPERATOR_GREATER_THAN, OPERATOR_LESS_THAN, OPERATOR_GREATER_OR_EQUAL,
+ * OPERATOR_LESS_OR_EQUAL
+ */
+ public void setOperator( int operator )
+ {
+ this._operator = operator;
+ }
+
+ /**
+ * Retrieves the operator used for this object's formula
+ * @return
+ * @see OPERATOR_BETWEEN, OPERATOR_NOT_BETWEEN, OPERATOR_EQUAL, OPERATOR_NOT_EQUAL
+ * OPERATOR_GREATER_THAN, OPERATOR_LESS_THAN, OPERATOR_GREATER_OR_EQUAL,
+ * OPERATOR_LESS_OR_EQUAL
+ */
+ public int getOperator()
+ {
+ return this._operator;
+ }
+
+ /**
+ * Sets the title and text for the prompt box . Prompt box is displayed when the user
+ * selects a cell which belongs to this validation object . In order for a prompt box
+ * to be displayed you should also use method setShowPromptBox( boolean show )
+ * @param title The prompt box's title
+ * @param text The prompt box's text
+ * @see setShowPromptBox( boolean show )
+ */
+ public void createPromptBox( String title, String text )
+ {
+ this._prompt_title = title;
+ this._prompt_text = text;
+ this.setShowPromptBox(true);
+ }
+
+ /**
+ * Returns the prompt box's title
+ * @return Prompt box's title or null
+ */
+ public String getPromptBoxTitle( )
+ {
+ return this._prompt_title;
+ }
+
+ /**
+ * Returns the prompt box's text
+ * @return Prompt box's text or null
+ */
+ public String getPromptBoxText( )
+ {
+ return this._prompt_text;
+ }
+
+ /**
+ * Sets the title and text for the error box . Error box is displayed when the user
+ * enters an invalid value int o a cell which belongs to this validation object .
+ * In order for an error box to be displayed you should also use method
+ * setShowErrorBox( boolean show )
+ * @param title The error box's title
+ * @param text The error box's text
+ * @see setShowErrorBox( boolean show )
+ */
+ public void createErrorBox( String title, String text )
+ {
+ this._error_title = title;
+ this._error_text = text;
+ this.setShowErrorBox(true);
+ }
+
+ /**
+ * Returns the error box's title
+ * @return Error box's title or null
+ */
+ public String getErrorBoxTitle( )
+ {
+ return this._error_title;
+ }
+
+ /**
+ * Returns the error box's text
+ * @return Error box's text or null
+ */
+ public String getErrorBoxText( )
+ {
+ return this._error_text;
+ }
+
+ /**
+ * Sets the first formula for this object .
+ * A formula is divided into three parts : first formula , operator and second formula .
+ * In other words , a formula contains a left oprand , an operator and a right operand.
+ * This is the general rule . An example is 1<= value <= 5 . In this case ,
+ * the left operand ( or the first formula ) is the number 1 . The operator is
+ * OPERATOR_BETWEEN and the right operand ( or the second formula ) is 5 .
+ * @param formula
+ */
+ public void setFirstFormula( String formula )
+ {
+ this._string_first_formula = formula;
+ }
+
+ /**
+ * Returns the first formula
+ * @return
+ */
+ public String getFirstFormula( )
+ {
+ return this._string_first_formula;
+ }
+
+ /**
+ * Sets the first formula for this object .
+ * A formula is divided into three parts : first formula , operator and second formula .
+ * In other words , a formula contains a left oprand , an operator and a right operand.
+ * This is the general rule . An example is 1<= value <=5 . In this case ,
+ * the left operand ( or the first formula ) is the number 1 . The operator is
+ * OPERATOR_BETWEEN and the right operand ( or the second formula ) is 5 .
+ * But there are cases when a second formula isn't needed :
+ * You want somethink like : all values less than 5 . In this case , there's only a first
+ * formula ( in our case 5 ) and the operator OPERATOR_LESS_THAN
+ * @param formula
+ */
+ public void setSecondFormula( String formula )
+ {
+ this._string_sec_formula = formula;
+ }
+
+ /**
+ * Returns the second formula
+ * @return
+ */
+ public String getSecondFormula( )
+ {
+ return this._string_sec_formula;
+ }
+
+ public void setFirstRow( short first_row )
+ {
+ this._first_row = first_row;
+ }
+
+ public void setFirstColumn( short first_column )
+ {
+ this._first_col = first_column;
+ }
+
+ public void setLastRow( short last_row )
+ {
+ this._last_row = last_row;
+ }
+
+ public void setLastColumn( short last_column )
+ {
+ this._last_col = last_column;
+ }
+
+ public short getFirstRow()
+ {
+ return this._first_row;
+ }
+
+ public short getFirstColumn()
+ {
+ return this._first_col;
+ }
+
+ public short getLastRow()
+ {
+ return this._last_row;
+ }
+
+ public short getLastColumn()
+ {
+ return this._last_col;
+ }
+
+}
\ No newline at end of file
package org.apache.poi.poifs.storage;
+import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.filesystem.BATManaged;
import org.apache.poi.poifs.filesystem.POIFSDocument;
import org.apache.poi.poifs.property.RootProperty;
{
_small_blocks.add(blocks[ j ]);
}
+ } else {
+ doc.setStartBlock(POIFSConstants.END_OF_CHAIN);
}
}
_sbat.simpleCreateBlocks();
package org.apache.poi.util;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
{
}
+ /**
+ * Reads all the data from the input stream, and returns
+ * the bytes read.
+ */
+ public static byte[] toByteArray(InputStream stream) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ byte[] buffer = new byte[4096];
+ int read = 0;
+ while(read != -1) {
+ read = stream.read(buffer);
+ if(read > 0) {
+ baos.write(buffer, 0, read);
+ }
+ }
+
+ return baos.toByteArray();
+ }
+
/**
* Helper method, just calls <tt>readFully(in, b, 0, b.length)</tt>
*/
final int offset,
final int len) {
try {
- return new String(string, offset, len, "ISO-8859-1");
+ int len_to_use = Math.min(len, string.length - offset);
+ return new String(string, offset, len_to_use, "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
throw new InternalError(); /* unreachable */
}
--- /dev/null
+\r
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.examples;\r
+\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+import org.apache.poi.hslf.usermodel.RichTextRun;\r
+import org.apache.poi.hslf.model.*;\r
+\r
+import java.awt.*;\r
+import java.io.FileOutputStream;\r
+\r
+/**\r
+ * Demonstrates how to create tables\r
+ * \r
+ * @author Yegor Kozlov\r
+ */\r
+public class TableDemo {\r
+\r
+ public static void main(String[] args) throws Exception {\r
+\r
+ //test data for the first taable\r
+ String[][] txt1 = {\r
+ {"INPUT FILE", "NUMBER OF RECORDS"},\r
+ {"Item File", "11,559"},\r
+ {"Vendor File", "502"},\r
+ {"Purchase History File - # of PO\u2019s\r(12/01/04 - 05/31/06)", "12,852"},\r
+ {"Purchase History File - # of PO Lines\r(12/01/04 - 05/31/06)", "53,523" },\r
+ {"Total PO History Spend", "$10,172,038"}\r
+ };\r
+\r
+ SlideShow ppt = new SlideShow();\r
+\r
+ Slide slide = ppt.createSlide();\r
+\r
+ //six rows, two columns\r
+ Table table1 = new Table(6, 2);\r
+ for (int i = 0; i < txt1.length; i++) {\r
+ for (int j = 0; j < txt1[i].length; j++) {\r
+ TableCell cell = table1.getCell(i, j);\r
+ cell.setText(txt1[i][j]);\r
+ RichTextRun rt = cell.getTextRun().getRichTextRuns()[0];\r
+ rt.setFontName("Arial");\r
+ rt.setFontSize(10);\r
+ if(i == 0){\r
+ cell.getFill().setForegroundColor(new Color(227, 227, 227));\r
+ } else {\r
+ rt.setBold(true);\r
+ }\r
+ cell.setVerticalAlignment(TextBox.AnchorMiddle);\r
+ cell.setHorizontalAlignment(TextBox.AlignCenter);\r
+ }\r
+ }\r
+\r
+ Line border1 = table1.createBorder();\r
+ border1.setLineColor(Color.black);\r
+ border1.setLineWidth(1.0);\r
+ table1.setAllBorders(border1);\r
+\r
+ table1.setColumnWidth(0, 300);\r
+ table1.setColumnWidth(1, 150);\r
+\r
+ slide.addShape(table1);\r
+ int pgWidth = ppt.getPageSize().width;\r
+ table1.moveTo((pgWidth - table1.getAnchor().width)/2, 100);\r
+\r
+ //test data for the second taable\r
+ String[][] txt2 = {\r
+ {"Data Source"},\r
+ {"CAS Internal Metrics - Item Master Summary\r" +\r
+ "CAS Internal Metrics - Vendor Summary\r" +\r
+ "CAS Internal Metrics - PO History Summary"}\r
+ };\r
+\r
+ //two rows, one column\r
+ Table table2 = new Table(2, 1);\r
+ for (int i = 0; i < txt2.length; i++) {\r
+ for (int j = 0; j < txt2[i].length; j++) {\r
+ TableCell cell = table2.getCell(i, j);\r
+ cell.setText(txt2[i][j]);\r
+ RichTextRun rt = cell.getTextRun().getRichTextRuns()[0];\r
+ rt.setFontSize(10);\r
+ rt.setFontName("Arial");\r
+ if(i == 0){\r
+ cell.getFill().setForegroundColor(new Color(0, 51, 102));\r
+ rt.setFontColor(Color.white);\r
+ rt.setBold(true);\r
+ rt.setFontSize(14);\r
+ cell.setHorizontalAlignment(TextBox.AlignCenter);\r
+ } else {\r
+ rt.setBullet(true);\r
+ rt.setFontSize(12);\r
+ cell.setHorizontalAlignment(TextBox.AlignLeft);\r
+ }\r
+ cell.setVerticalAlignment(TextBox.AnchorMiddle);\r
+ }\r
+ }\r
+ table2.setColumnWidth(0, 300);\r
+ table2.setRowHeight(0, 30);\r
+ table2.setRowHeight(1, 70);\r
+\r
+ Line border2 = table2.createBorder();\r
+ table2.setOutsideBorders(border2);\r
+\r
+ slide.addShape(table2);\r
+ table2.moveTo(200, 400);\r
+\r
+ FileOutputStream out = new FileOutputStream("hslf-table.ppt");\r
+ ppt.write(out);\r
+ out.close();\r
+\r
+ }\r
+}\r
format = format.replaceAll("\\\\-","-");
// Format as a date
- Date d = HSSFDateUtil.getJavaDate(value);
+ Date d = HSSFDateUtil.getJavaDate(value, false);
DateFormat df = new SimpleDateFormat(format);
return df.format(d);
} else {
EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
if (color == null) {
Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, -1);
+ Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150010);
}
else {
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb);
+ Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011);
}
}
*/
protected static void findTextRuns(Record[] records, Vector found) {
// Look for a TextHeaderAtom
- for (int i = 0; i < (records.length - 1); i++) {
+ for (int i = 0, slwtIndex=0; i < (records.length - 1); i++) {
if (records[i] instanceof TextHeaderAtom) {
TextRun trun = null;
TextHeaderAtom tha = (TextHeaderAtom) records[i];
// TextSpecInfoAtom - Safe to ignore
} else {
System.err.println("Found a TextHeaderAtom not followed by a TextBytesAtom or TextCharsAtom: Followed by " + records[i + 1].getRecordType());
- continue;
}
if (trun != null) {
Record[] recs = new Record[lst.size()];
lst.toArray(recs);
trun._records = recs;
+ trun.setIndex(slwtIndex);
found.add(trun);
i++;
} else {
// Not a valid one, so skip on to next and look again
}
+ slwtIndex++;
}
}
}
int rgb = p1.getPropertyValue();
if (rgb >= 0x8000000) {
int idx = rgb % 0x8000000;
- ColorSchemeAtom ca = getSheet().getColorScheme();
- if(idx >= 0 && idx <= 7) rgb = ca.getColor(idx);
+ if(getSheet() != null) {
+ ColorSchemeAtom ca = getSheet().getColorScheme();
+ if(idx >= 0 && idx <= 7) rgb = ca.getColor(idx);
+ }
}
Color tmp = new Color(rgb, true);
clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());
int rgb = p1.getPropertyValue();
if (rgb >= 0x8000000) {
int idx = rgb % 0x8000000;
- ColorSchemeAtom ca = getSheet().getColorScheme();
- rgb = ca.getColor(idx);
+ if(getSheet() != null) {
+ ColorSchemeAtom ca = getSheet().getColorScheme();
+ rgb = ca.getColor(idx);
+ }
}
Color tmp = new Color(rgb, true);
clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());
--- /dev/null
+\r
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.model;\r
+\r
+import org.apache.poi.ddf.*;\r
+import org.apache.poi.util.LittleEndian;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Iterator;\r
+import java.awt.*;\r
+\r
+/**\r
+ * Represents a table in a PowerPoint presentation\r
+ * \r
+ * @author Yegor Kozlov\r
+ */\r
+public class Table extends ShapeGroup {\r
+\r
+ protected static final int BORDER_TOP = 1;\r
+ protected static final int BORDER_RIGHT = 2;\r
+ protected static final int BORDER_BOTTOM = 3;\r
+ protected static final int BORDER_LEFT = 4;\r
+\r
+ protected static final int BORDERS_ALL = 5;\r
+ protected static final int BORDERS_OUTSIDE = 6;\r
+ protected static final int BORDERS_INSIDE = 7;\r
+ protected static final int BORDERS_NONE = 8;\r
+\r
+\r
+ protected TableCell[][] cells;\r
+\r
+ /**\r
+ * Create a new Table of the given number of rows and columns\r
+ *\r
+ * @param numrows the number of rows\r
+ * @param numcols the number of columns\r
+ */\r
+ public Table(int numrows, int numcols) {\r
+ super();\r
+\r
+ int x=0, y=0, tblWidth=0, tblHeight=0;\r
+ cells = new TableCell[numrows][numcols];\r
+ for (int i = 0; i < cells.length; i++) {\r
+ x = 0;\r
+ for (int j = 0; j < cells[i].length; j++) {\r
+ cells[i][j] = new TableCell(this);\r
+ Rectangle anchor = new Rectangle(x, y, TableCell.DEFAULT_WIDTH, TableCell.DEFAULT_HEIGHT);\r
+ cells[i][j].setAnchor(anchor);\r
+ x += TableCell.DEFAULT_WIDTH;\r
+ }\r
+ y += TableCell.DEFAULT_HEIGHT;\r
+ }\r
+ tblWidth = x;\r
+ tblHeight = y;\r
+ setAnchor(new Rectangle(0, 0, tblWidth, tblHeight));\r
+\r
+ EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0);\r
+ List lst = spCont.getChildRecords();\r
+ EscherOptRecord opt = new EscherOptRecord();\r
+ opt.setRecordId((short)0xF122);\r
+ opt.addEscherProperty(new EscherSimpleProperty((short)0x39F, 1));\r
+ EscherArrayProperty p = new EscherArrayProperty((short)0x43A0, false, null);\r
+ p.setSizeOfElements(0x0004);\r
+ p.setNumberOfElementsInArray(numrows);\r
+ p.setNumberOfElementsInMemory(numrows);\r
+ opt.addEscherProperty(p);\r
+ lst.add(lst.size()-1, opt);\r
+\r
+ }\r
+\r
+ /**\r
+ * Create a Table object and initilize it from the supplied Record container.\r
+ *\r
+ * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape\r
+ * @param parent the parent of the shape\r
+ */\r
+ protected Table(EscherContainerRecord escherRecord, Shape parent) {\r
+ super(escherRecord, parent);\r
+ }\r
+\r
+ /**\r
+ * Gets a cell\r
+ *\r
+ * @param row the row index (0-based)\r
+ * @param col the column index (0-based)\r
+ * @return the cell\r
+ */\r
+ public TableCell getCell(int row, int col) {\r
+ return cells[row][col];\r
+ }\r
+\r
+ public int getNumberOfColumns() {\r
+ return cells[0].length;\r
+ }\r
+ public int getNumberOfRows() {\r
+ return cells.length;\r
+ }\r
+\r
+ protected void afterInsert(Sheet sh){\r
+ EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0);\r
+ List lst = spCont.getChildRecords();\r
+ EscherOptRecord opt = (EscherOptRecord)lst.get(lst.size()-2);\r
+ EscherArrayProperty p = (EscherArrayProperty)opt.getEscherProperty(1);\r
+ for (int i = 0; i < cells.length; i++) {\r
+ TableCell cell = cells[i][0];\r
+ int rowHeight = cell.getAnchor().height*MASTER_DPI/POINT_DPI;\r
+ byte[] val = new byte[4];\r
+ LittleEndian.putInt(val, rowHeight);\r
+ p.setElement(i, val);\r
+ for (int j = 0; j < cells[i].length; j++) {\r
+ TableCell c = cells[i][j];\r
+ addShape(c);\r
+\r
+ Line bt = c.getBorderTop();\r
+ if(bt != null) addShape(bt);\r
+\r
+ Line br = c.getBorderRight();\r
+ if(br != null) addShape(br);\r
+\r
+ Line bb = c.getBorderBottom();\r
+ if(bb != null) addShape(bb);\r
+\r
+ Line bl = c.getBorderLeft();\r
+ if(bl != null) addShape(bl);\r
+\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Sets the row height.\r
+ *\r
+ * @param row the row index (0-based)\r
+ * @param height the height to set (in pixels)\r
+ */\r
+ public void setRowHeight(int row, int height){\r
+ int currentHeight = cells[row][0].getAnchor().height;\r
+ int dy = height - currentHeight;\r
+\r
+ for (int i = row; i < cells.length; i++) {\r
+ for (int j = 0; j < cells[i].length; j++) {\r
+ Rectangle anchor = cells[i][j].getAnchor();\r
+ if(i == row) anchor.height = height;\r
+ else anchor.y += dy;\r
+ cells[i][j].setAnchor(anchor);\r
+ }\r
+ }\r
+ Rectangle tblanchor = getAnchor();\r
+ tblanchor.height += dy;\r
+ setAnchor(tblanchor);\r
+\r
+ }\r
+\r
+ /**\r
+ * Sets the column width.\r
+ *\r
+ * @param col the column index (0-based)\r
+ * @param width the width to set (in pixels)\r
+ */\r
+ public void setColumnWidth(int col, int width){\r
+ int currentWidth = cells[0][col].getAnchor().width;\r
+ int dx = width - currentWidth;\r
+ for (int i = 0; i < cells.length; i++) {\r
+ Rectangle anchor = cells[i][col].getAnchor();\r
+ anchor.width = width;\r
+ cells[i][col].setAnchor(anchor);\r
+\r
+ if(col < cells[i].length - 1) for (int j = col+1; j < cells[i].length; j++) {\r
+ anchor = cells[i][j].getAnchor();\r
+ anchor.x += dx;\r
+ cells[i][j].setAnchor(anchor);\r
+ }\r
+ }\r
+ Rectangle tblanchor = getAnchor();\r
+ tblanchor.width += dx;\r
+ setAnchor(tblanchor);\r
+ }\r
+\r
+ /**\r
+ * Format the table and apply the specified Line to all cell boundaries,\r
+ * both outside and inside\r
+ *\r
+ * @param line the border line\r
+ */\r
+ public void setAllBorders(Line line){\r
+ for (int i = 0; i < cells.length; i++) {\r
+ for (int j = 0; j < cells[i].length; j++) {\r
+ TableCell cell = cells[i][j];\r
+ cell.setBorderTop(cloneBorder(line));\r
+ cell.setBorderLeft(cloneBorder(line));\r
+ if(j == cells[i].length - 1) cell.setBorderRight(cloneBorder(line));\r
+ if(i == cells.length - 1) cell.setBorderBottom(cloneBorder(line));\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Format the outside border using the specified Line object\r
+ *\r
+ * @param line the border line\r
+ */\r
+ public void setOutsideBorders(Line line){\r
+ for (int i = 0; i < cells.length; i++) {\r
+ for (int j = 0; j < cells[i].length; j++) {\r
+ TableCell cell = cells[i][j];\r
+\r
+ if(j == 0) cell.setBorderLeft(cloneBorder(line));\r
+ if(j == cells[i].length - 1) cell.setBorderRight(cloneBorder(line));\r
+ else {\r
+ cell.setBorderLeft(null);\r
+ cell.setBorderLeft(null);\r
+ }\r
+\r
+ if(i == 0) cell.setBorderTop(cloneBorder(line));\r
+ else if(i == cells.length - 1) cell.setBorderBottom(cloneBorder(line));\r
+ else {\r
+ cell.setBorderTop(null);\r
+ cell.setBorderBottom(null);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Format the inside border using the specified Line object\r
+ *\r
+ * @param line the border line\r
+ */\r
+ public void setInsideBorders(Line line){\r
+ for (int i = 0; i < cells.length; i++) {\r
+ for (int j = 0; j < cells[i].length; j++) {\r
+ TableCell cell = cells[i][j];\r
+\r
+ if(j != cells[i].length - 1)\r
+ cell.setBorderRight(cloneBorder(line));\r
+ else {\r
+ cell.setBorderLeft(null);\r
+ cell.setBorderLeft(null);\r
+ }\r
+ if(i != cells.length - 1) cell.setBorderBottom(cloneBorder(line));\r
+ else {\r
+ cell.setBorderTop(null);\r
+ cell.setBorderBottom(null);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private Line cloneBorder(Line line){\r
+ Line border = createBorder();\r
+ border.setLineWidth(line.getLineWidth());\r
+ border.setLineStyle(line.getLineStyle());\r
+ border.setLineDashing(line.getLineDashing());\r
+ border.setLineColor(line.getLineColor());\r
+ return border;\r
+ }\r
+\r
+ /**\r
+ * Create a border to format this table\r
+ *\r
+ * @return the created border\r
+ */\r
+ public Line createBorder(){\r
+ Line line = new Line(this);\r
+\r
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(line.getSpContainer(), EscherOptRecord.RECORD_ID);\r
+ setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, -1);\r
+ setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, -1);\r
+ setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);\r
+ setEscherProperty(opt, EscherProperties.THREED__LIGHTFACE, 0x80000);\r
+\r
+ return line;\r
+ }\r
+}\r
--- /dev/null
+\r
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.model;\r
+\r
+import org.apache.poi.ddf.*;\r
+import org.apache.poi.hslf.record.EscherTextboxWrapper;\r
+import org.apache.poi.hslf.record.TextHeaderAtom;\r
+import org.apache.poi.hslf.usermodel.RichTextRun;\r
+\r
+import java.awt.*;\r
+\r
+/**\r
+ * Represents a cell in a ppt table\r
+ * \r
+ * @author Yegor Kozlov\r
+ */\r
+public class TableCell extends TextBox {\r
+ protected static final int DEFAULT_WIDTH = 100;\r
+ protected static final int DEFAULT_HEIGHT = 40;\r
+\r
+ private Line borderLeft;\r
+ private Line borderRight;\r
+ private Line borderTop;\r
+ private Line borderBottom;\r
+\r
+ /**\r
+ * Create a TableCell object and initialize it from the supplied Record container.\r
+ *\r
+ * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape\r
+ * @param parent the parent of the shape\r
+ */\r
+ protected TableCell(EscherContainerRecord escherRecord, Shape parent){\r
+ super(escherRecord, parent);\r
+ }\r
+\r
+ /**\r
+ * Create a new TableCell. This constructor is used when a new shape is created.\r
+ *\r
+ * @param parent the parent of this Shape. For example, if this text box is a cell\r
+ * in a table then the parent is Table.\r
+ */\r
+ public TableCell(Shape parent){\r
+ super(parent);\r
+\r
+ setShapeType(ShapeTypes.Rectangle);\r
+ _txtrun.setRunType(TextHeaderAtom.HALF_BODY_TYPE);\r
+ _txtrun.getRichTextRuns()[0].setFlag(false, 0, false);\r
+ }\r
+\r
+ protected EscherContainerRecord createSpContainer(boolean isChild){\r
+ EscherContainerRecord spContainer = super.createSpContainer(isChild);\r
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(spContainer, EscherOptRecord.RECORD_ID);\r
+ setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0);\r
+ setEscherProperty(opt, EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x20000);\r
+ setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150001);\r
+ setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);\r
+ setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x40000);\r
+\r
+ return spContainer;\r
+ }\r
+\r
+ protected void anchorBorder(int type, Line line){\r
+ Rectangle cellAnchor = getAnchor();\r
+ Rectangle lineAnchor = new Rectangle();\r
+ switch(type){\r
+ case Table.BORDER_TOP:\r
+ lineAnchor.x = cellAnchor.x;\r
+ lineAnchor.y = cellAnchor.y;\r
+ lineAnchor.width = cellAnchor.width;\r
+ lineAnchor.height = 0;\r
+ break;\r
+ case Table.BORDER_RIGHT:\r
+ lineAnchor.x = cellAnchor.x + cellAnchor.width;\r
+ lineAnchor.y = cellAnchor.y;\r
+ lineAnchor.width = 0;\r
+ lineAnchor.height = cellAnchor.height;\r
+ break;\r
+ case Table.BORDER_BOTTOM:\r
+ lineAnchor.x = cellAnchor.x;\r
+ lineAnchor.y = cellAnchor.y + cellAnchor.height;\r
+ lineAnchor.width = cellAnchor.width;\r
+ lineAnchor.height = 0;\r
+ break;\r
+ case Table.BORDER_LEFT:\r
+ lineAnchor.x = cellAnchor.x;\r
+ lineAnchor.y = cellAnchor.y;\r
+ lineAnchor.width = 0;\r
+ lineAnchor.height = cellAnchor.height;\r
+ break;\r
+ default:\r
+ throw new IllegalArgumentException("Unknown border type: " + type);\r
+ }\r
+ line.setAnchor(lineAnchor);\r
+ }\r
+\r
+ public Line getBorderLeft() {\r
+ return borderLeft;\r
+ }\r
+\r
+ public void setBorderLeft(Line line) {\r
+ if(line != null) anchorBorder(Table.BORDER_LEFT, line);\r
+ this.borderLeft = line;\r
+ }\r
+\r
+ public Line getBorderRight() {\r
+ return borderRight;\r
+ }\r
+\r
+ public void setBorderRight(Line line) {\r
+ if(line != null) anchorBorder(Table.BORDER_RIGHT, line);\r
+ this.borderRight = line;\r
+ }\r
+\r
+ public Line getBorderTop() {\r
+ return borderTop;\r
+ }\r
+\r
+ public void setBorderTop(Line line) {\r
+ if(line != null) anchorBorder(Table.BORDER_TOP, line);\r
+ this.borderTop = line;\r
+ }\r
+\r
+ public Line getBorderBottom() {\r
+ return borderBottom;\r
+ }\r
+\r
+ public void setBorderBottom(Line line) {\r
+ if(line != null) anchorBorder(Table.BORDER_BOTTOM, line);\r
+ this.borderBottom = line;\r
+ }\r
+\r
+ public void setAnchor(Rectangle anchor){\r
+ super.setAnchor(anchor);\r
+\r
+ if(borderTop != null) anchorBorder(Table.BORDER_TOP, borderTop);\r
+ if(borderRight != null) anchorBorder(Table.BORDER_RIGHT, borderRight);\r
+ if(borderBottom != null) anchorBorder(Table.BORDER_BOTTOM, borderBottom);\r
+ if(borderLeft != null) anchorBorder(Table.BORDER_LEFT, borderLeft);\r
+ }\r
+}\r
} catch (IOException e){
throw new HSLFException(e);
}
- if(getAnchor().equals(new java.awt.Rectangle())) resizeToFitText();
+ if(getAnchor().equals(new java.awt.Rectangle()) && !"".equals(getText())) resizeToFitText();
}
/**
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
setEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT, align);
}
+
+ public void setHorizontalAlignment(int align){
+ _txtrun.getRichTextRuns()[0].setAlignment(align);
+ }
+ public int getHorizontalAlignment(){
+ return _txtrun.getRichTextRuns()[0].getAlignment();
+ }
+
/**
* Returns the distance (in points) between the bottom of the text frame
* and the bottom of the inscribed rectangle of the shape that contains the text.
TextRun[] runs = sheet.getTextRuns();
if (ota != null) {
int idx = ota.getTextIndex();
- if(idx < runs.length) _txtrun = runs[idx];
+ for (int i = 0; i < runs.length; i++) {
+ if(runs[i].getIndex() == idx){
+ _txtrun = runs[i];
+ }
+ }
if(_txtrun == null) {
logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
}
break;
}
}
- if(_txtrun == null) {
- logger.log(POILogger.WARN, "text run not found for shapeId=" + shapeId);
- }
}
}
private SlideShow slideShow;
private Sheet sheet;
private int shapeId;
+ private int slwtIndex; //position in the owning SlideListWithText
/**
* all text run records that follow TextHeaderAtom.
* (there can be misc InteractiveInfo, TxInteractiveInfo and other records)
shapeId = id;
}
+ /**
+ * @return 0-based index of the text run in the SLWT container
+ */
+ protected int getIndex(){
+ return slwtIndex;
+ }
+
+ /**
+ * @param id 0-based index of the text run in the SLWT container
+ */
+ protected void setIndex(int id){
+ slwtIndex = id;
+ }
+
/**
* Returns the array of all hyperlinks in this text run
*
setFlag(true, index, value);
}
- private void setFlag(boolean isCharacter, int index, boolean value) {
+ public void setFlag(boolean isCharacter, int index, boolean value) {
TextPropCollection props;
String propname;
if (isCharacter){
* @param propName The name of the Character TextProp
* @param val The value to set for the TextProp
*/
- private void setParaTextPropVal(String propName, int val) {
+ public void setParaTextPropVal(String propName, int val) {
// Ensure we have the StyleTextProp atom we're going to need
if(paragraphStyle == null) {
parentRun.ensureStyleAtomPresent();
* @param propName The name of the Paragraph TextProp
* @param val The value to set for the TextProp
*/
- private void setCharTextPropVal(String propName, int val) {
+ public void setCharTextPropVal(String propName, int val) {
// Ensure we have the StyleTextProp atom we're going to need
if(characterStyle == null) {
parentRun.ensureStyleAtomPresent();
/**
- * Constructor for reading MSG Files.
+ * Constructor for reading MSG Files from the file system.
* @param filename
* @throws IOException
*/
public MAPIMessage(String filename) throws IOException {
- InputStream in = new FileInputStream(new File(filename));
+ this(new FileInputStream(new File(filename)));
+ }
+
+ /**
+ * Constructor for reading MSG Files from an input stream.
+ * @param in
+ * @throws IOException
+ */
+ public MAPIMessage(InputStream in) throws IOException {
this.fs = new POIFSFileSystem(in);
chunkParser = new POIFSChunkParser(this.fs);
}
+
/**
* Gets a string value based on the passed chunk.
return getStringFromChunk(Chunks.getInstance().displayToChunk);
}
+ /**
+ * Gets the display value of the "FROM" line of the outlook message
+ * This is not the actual address that was sent from but the formated display of the user name.
+ * @return
+ * @throws ChunkNotFoundException
+ */
+ public String getDisplayFrom() throws ChunkNotFoundException {
+ return getStringFromChunk(Chunks.getInstance().displayFromChunk);
+ }
+
/**
* Gets the display value of the "TO" line of the outlook message
* This is not the actual list of addresses/values that will be sent to if you click Reply in the email.
public StringChunk textBodyChunk = new StringChunk(0x1000); //BODY Chunk, for plain/text messages
public StringChunk subjectChunk = new StringChunk(0x0037); //Subject link chunk, in plain/text
public StringChunk displayToChunk = new StringChunk(0x0E04); //Value that is in the TO field (not actually the addresses as they are stored in recip directory nodes
+ public StringChunk displayFromChunk = new StringChunk(0x0C1A); //Value that is in the FROM field
public StringChunk displayCCChunk = new StringChunk(0x0E03); //value that shows in the CC field
public StringChunk displayBCCChunk = new StringChunk(0x0E02); //Value that shows in the BCC field
public StringChunk conversationTopic = new StringChunk(0x0070); //Sort of like the subject line, but without the RE: and FWD: parts.
c.set(year, month, day, 0, 0, 0);
c.set(Calendar.MILLISECOND, 0);
- return new NumberEval(HSSFDateUtil.getExcelDate(c.getTime()));
+ return new NumberEval(HSSFDateUtil.getExcelDate(c.getTime(), false)); // XXX fix 1900/1904 problem
}
}
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
- java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue());
+ java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
java.util.Calendar c = java.util.Calendar.getInstance();
c.setTime(d);
retval = new NumberEval(c.get(java.util.Calendar.DAY_OF_MONTH));
*/
package org.apache.poi.hssf.record.formula.functions;
-public class Mid extends NotImplementedFunction {
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * An implementation of the MID function:
+ * Returns a specific number of characters from a text string,
+ * starting at the position you specify, based on the number
+ * of characters you specify.
+ * @author Manda Wilson < wilson at c bio dot msk cc dot org >
+ */
+public class Mid extends TextFunction {
+ /**
+ * Returns a specific number of characters from a text string,
+ * starting at the position you specify, based on the number
+ * of characters you specify.
+ *
+ * @see org.apache.poi.hssf.record.formula.eval.Eval
+ */
+ public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+ Eval retval = null;
+ String str = null;
+ int startNum = 0;
+ int numChars = 0;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ case 3:
+ // first operand is text string containing characters to extract
+ // second operand is position of first character to extract
+ // third operand is the number of characters to return
+ ValueEval firstveval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+ ValueEval secondveval = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol);
+ ValueEval thirdveval = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol);
+ if (firstveval instanceof StringValueEval
+ && secondveval instanceof NumericValueEval
+ && thirdveval instanceof NumericValueEval) {
+
+ StringValueEval strEval = (StringValueEval) firstveval;
+ str = strEval.getStringValue();
+
+ NumericValueEval startNumEval = (NumericValueEval) secondveval;
+ // NOTE: it is safe to cast to int here
+ // because in Excel =MID("test", 1, 1.7) returns t
+ // so 1.7 must be truncated to 1
+ // and =MID("test", 1.9, 2) returns te
+ // so 1.9 must be truncated to 1
+ startNum = (int) startNumEval.getNumberValue();
+
+ NumericValueEval numCharsEval = (NumericValueEval) thirdveval;
+ numChars = (int) numCharsEval.getNumberValue();
+
+ } else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+
+ if (retval == null) {
+ if (startNum < 1 || numChars < 0) {
+ retval = ErrorEval.VALUE_INVALID;
+ } else if (startNum > str.length() || numChars == 0) {
+ retval = BlankEval.INSTANCE;
+ } else if (startNum + numChars > str.length()) {
+ retval = new StringEval(str.substring(startNum - 1));
+ } else {
+ retval = new StringEval(str.substring(startNum - 1, numChars));
+ }
+ }
+ return retval;
+ }
}
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
- java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue());
+ java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
retval = new NumberEval(d.getMonth()+1);
} else {
retval = ErrorEval.NUM_ERROR;
*/
package org.apache.poi.hssf.record.formula.functions;
-public class Replace extends NotImplementedFunction {
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * An implementation of the REPLACE function:
+ * Replaces part of a text string based on the number of characters
+ * you specify, with another text string.
+ * @author Manda Wilson < wilson at c bio dot msk cc dot org >
+ */
+public class Replace extends TextFunction {
+
+ /**
+ * Replaces part of a text string based on the number of characters
+ * you specify, with another text string.
+ *
+ * @see org.apache.poi.hssf.record.formula.eval.Eval
+ */
+ public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+ Eval retval = null;
+ String oldStr = null;
+ String newStr = null;
+ int startNum = 0;
+ int numChars = 0;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ case 4:
+ // first operand is text string containing characters to replace
+ // second operand is position of first character to replace
+ // third operand is the number of characters in the old string
+ // you want to replace with new string
+ // fourth operand is the new string
+ ValueEval firstveval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+ ValueEval secondveval = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol);
+ ValueEval thirdveval = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol);
+ ValueEval fourthveval = singleOperandEvaluate(operands[3], srcCellRow, srcCellCol);
+ if (firstveval instanceof StringValueEval
+ && secondveval instanceof NumericValueEval
+ && thirdveval instanceof NumericValueEval
+ && fourthveval instanceof StringValueEval) {
+
+ StringValueEval oldStrEval = (StringValueEval) firstveval;
+ oldStr = oldStrEval.getStringValue();
+
+ NumericValueEval startNumEval = (NumericValueEval) secondveval;
+ // NOTE: it is safe to cast to int here
+ // because in Excel =REPLACE("task", 2.7, 3, "est")
+ // returns test
+ // so 2.7 must be truncated to 2
+ // and =REPLACE("task", 1, 1.9, "") returns ask
+ // so 1.9 must be truncated to 1
+ startNum = (int) startNumEval.getNumberValue();
+
+ NumericValueEval numCharsEval = (NumericValueEval) thirdveval;
+ numChars = (int) numCharsEval.getNumberValue();
+
+ StringValueEval newStrEval = (StringValueEval) fourthveval;
+ newStr = newStrEval.getStringValue();
+ } else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+
+ if (retval == null) {
+ if (startNum < 1 || numChars < 0) {
+ retval = ErrorEval.VALUE_INVALID;
+ } else {
+ StringBuffer strBuff = new StringBuffer(oldStr);
+ // remove any characters that should be replaced
+ if (startNum <= oldStr.length() && numChars != 0) {
+ strBuff.delete(startNum - 1, startNum - 1 + numChars);
+ }
+ // now insert (or append) newStr
+ if (startNum > strBuff.length()) {
+ strBuff.append(newStr);
+ } else {
+ strBuff.insert(startNum - 1, newStr);
+ }
+ retval = new StringEval(strBuff.toString());
+ }
+ }
+ return retval;
+ }
}
*/
package org.apache.poi.hssf.record.formula.functions;
-public class Substitute extends NotImplementedFunction {
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+/**
+ * An implementation of the SUBSTITUTE function:
+ * Substitutes text in a text string with new text, some number of times.
+ * @author Manda Wilson < wilson at c bio dot msk cc dot org >
+ */
+public class Substitute extends TextFunction {
+ private static final int REPLACE_ALL = -1;
+
+ /**
+ *Substitutes text in a text string with new text, some number of times.
+ *
+ * @see org.apache.poi.hssf.record.formula.eval.Eval
+ */
+ public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+ Eval retval = null;
+ String oldStr = null;
+ String searchStr = null;
+ String newStr = null;
+ int numToReplace = REPLACE_ALL;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ case 4:
+ ValueEval fourthveval = singleOperandEvaluate(operands[3], srcCellRow, srcCellCol);
+ if (fourthveval instanceof NumericValueEval) {
+ NumericValueEval numToReplaceEval = (NumericValueEval) fourthveval;
+ // NOTE: it is safe to cast to int here
+ // because in Excel =SUBSTITUTE("teststr","t","T",1.9)
+ // returns Teststr
+ // so 1.9 must be truncated to 1
+ numToReplace = (int) numToReplaceEval.getNumberValue();
+ } else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ case 3:
+ // first operand is text string containing characters to replace
+ // second operand is text to find
+ // third operand is replacement text
+ ValueEval firstveval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+ ValueEval secondveval = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol);
+ ValueEval thirdveval = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol);
+ if (firstveval instanceof StringValueEval
+ && secondveval instanceof StringValueEval
+ && thirdveval instanceof StringValueEval) {
+
+ StringValueEval oldStrEval = (StringValueEval) firstveval;
+ oldStr = oldStrEval.getStringValue();
+
+ StringValueEval searchStrEval = (StringValueEval) secondveval;
+ searchStr = searchStrEval.getStringValue();
+
+ StringValueEval newStrEval = (StringValueEval) thirdveval;
+ newStr = newStrEval.getStringValue();
+ } else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+
+ if (retval == null) {
+ if (numToReplace != REPLACE_ALL && numToReplace < 1) {
+ retval = ErrorEval.VALUE_INVALID;
+ } else if (searchStr.length() == 0) {
+ retval = new StringEval(oldStr);
+ } else {
+ StringBuffer strBuff = new StringBuffer();
+ int startIndex = 0;
+ int nextMatch = -1;
+ for (int leftToReplace = numToReplace;
+ (leftToReplace > 0 || numToReplace == REPLACE_ALL)
+ && (nextMatch = oldStr.indexOf(searchStr, startIndex)) != -1;
+ leftToReplace--) {
+ // store everything from end of last match to start of this match
+ strBuff.append(oldStr.substring(startIndex, nextMatch));
+ strBuff.append(newStr);
+ startIndex = nextMatch + searchStr.length();
+ }
+ // store everything from end of last match to end of string
+ if (startIndex < oldStr.length()) {
+ strBuff.append(oldStr.substring(startIndex));
+ }
+ retval = new StringEval(strBuff.toString());
+ }
+ }
+ return retval;
+ }
+
}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * Created on May 15, 2005
- *
- */
package org.apache.poi.hssf.record.formula.functions;
-public class Trim extends NotImplementedFunction {
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * An implementation of the TRIM function:
+ * Removes leading and trailing spaces from value if evaluated operand
+ * value is string.
+ * @author Manda Wilson < wilson at c bio dot msk cc dot org >
+ */
+public class Trim extends TextFunction {
+ /**
+ * Removes leading and trailing spaces from value if evaluated
+ * operand value is string.
+ * Returns StringEval only if evaluated operand is of type string
+ * (and is not blank or null) or number. If evaluated operand is
+ * of type string and is blank or null, or if evaluated operand is
+ * of type blank, returns BlankEval. Otherwise returns ErrorEval.
+ *
+ * @see org.apache.poi.hssf.record.formula.eval.Eval
+ */
+ public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+ Eval retval = ErrorEval.VALUE_INVALID;
+ String str = null;
+
+ switch (operands.length) {
+ default:
+ break;
+ case 1:
+ ValueEval veval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+ if (veval instanceof StringValueEval) {
+ StringValueEval sve = (StringValueEval) veval;
+ str = sve.getStringValue();
+ if (str == null || str.trim().equals("")) {
+ return BlankEval.INSTANCE;
+ }
+ }
+ else if (veval instanceof NumberEval) {
+ NumberEval neval = (NumberEval) veval;
+ str = neval.getStringValue();
+ }
+ else if (veval instanceof BlankEval) {
+ return BlankEval.INSTANCE;
+ }
+ }
+
+ if (str != null) {
+ retval = new StringEval(str.trim());
+ }
+ return retval;
+ }
}
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
- java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue());
+ java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
retval = new NumberEval(d.getYear()+1900);
} else {
retval = ErrorEval.NUM_ERROR;
package org.apache.poi.hwpf.model;
import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
import org.apache.poi.hwpf.model.io.*;
{
private static final int LIST_DATA_SIZE = 28;
private static final int LIST_FORMAT_OVERRIDE_SIZE = 16;
+ private static POILogger log = POILogFactory.getLogger(ListTables.class);
HashMap _listMap = new HashMap();
ArrayList _overrideList = new ArrayList();
public ListLevel getLevel(int listID, int level)
{
ListData lst = (ListData)_listMap.get(new Integer(listID));
- ListLevel lvl = lst.getLevels()[level];
- return lvl;
+ if(level < lst.numLevels()) {
+ ListLevel lvl = lst.getLevels()[level];
+ return lvl;
+ } else {
+ log.log(POILogger.WARN, "Requested level " + level + " which was greater than the maximum defined (" + lst.numLevels() + ")");
+ return null;
+ }
}
public ListData getListData(int listID)
for (int x = 0; x < itcMac; x++)
{
- if(hasTCs) rgtc[x] = TableCellDescriptor.convertBytesToTC(grpprl,
- offset + (1 + ( (itcMac + 1) * 2) + (x * 20)));
+ // Sometimes, the grpprl does not contain data at every offset. I have no idea why this happens.
+ if(hasTCs && offset + (1 + ( (itcMac + 1) * 2) + (x * 20)) < grpprl.length)
+ rgtc[x] = TableCellDescriptor.convertBytesToTC(grpprl,
+ offset + (1 + ( (itcMac + 1) * 2) + (x * 20)));
else
rgtc[x] = new TableCellDescriptor();
}
import org.apache.poi.hwpf.model.ListLevel;
import org.apache.poi.hwpf.model.ListTables;
import org.apache.poi.hwpf.model.PAPX;
-
-import org.apache.poi.hwpf.sprm.SprmBuffer;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
public class ListEntry
extends Paragraph
{
- ListLevel _level;
- ListFormatOverrideLevel _overrideLevel;
+ private static POILogger log = POILogFactory.getLogger(ListEntry.class);
+
+ ListLevel _level;
+ ListFormatOverrideLevel _overrideLevel;
ListEntry(PAPX papx, Range parent, ListTables tables)
{
super(papx, parent);
- ListFormatOverride override = tables.getOverride(_props.getIlfo());
- _overrideLevel = override.getOverrideLevel(_props.getIlvl());
- _level = tables.getLevel(override.getLsid(), _props.getIlvl());
+
+ if(tables != null) {
+ ListFormatOverride override = tables.getOverride(_props.getIlfo());
+ _overrideLevel = override.getOverrideLevel(_props.getIlvl());
+ _level = tables.getLevel(override.getLsid(), _props.getIlvl());
+ } else {
+ log.log(POILogger.WARN, "No ListTables found for ListEntry - document probably partly corrupt, and you may experience problems");
+ }
}
public int type()
import java.io.*;\r
import java.util.HashSet;\r
import java.util.HashMap;\r
+import java.util.ArrayList;\r
import java.awt.*;\r
\r
/**\r
\r
}\r
\r
+ /**\r
+ * Bug 38256: RuntimeException: Couldn't instantiate the class for type with id 0.\r
+ * ( also fixed followup: getTextRuns() returns no text )\r
+ */\r
+ public void test43781 () throws Exception {\r
+ FileInputStream is = new FileInputStream(new File(cwd, "43781.ppt"));\r
+ SlideShow ppt = new SlideShow(is);\r
+ is.close();\r
+\r
+ assertTrue("No Exceptions while reading file", true);\r
+\r
+ Slide slide = ppt.getSlides()[0];\r
+ TextRun[] tr1 = slide.getTextRuns();\r
+\r
+ ArrayList lst = new ArrayList();\r
+ Shape[] shape = slide.getShapes();\r
+ for (int i = 0; i < shape.length; i++) {\r
+ if( shape[i] instanceof TextBox){\r
+ TextRun textRun = ((TextBox)shape[i]).getTextRun();\r
+ if(textRun != null) lst.add(textRun);\r
+ }\r
+\r
+ }\r
+ TextRun[] tr2 = new TextRun[lst.size()];\r
+ lst.toArray(tr2);\r
+\r
+ assertEquals(tr1.length, tr2.length);\r
+ for (int i = 0; i < tr1.length; i++) {\r
+ assertEquals(tr1[i].getText(), tr2[i].getText());\r
+ }\r
+ }\r
}\r
TestCase.assertEquals(obtained, expected);
}
+ /**
+ * Test to see if we can read the FROM Chunk.
+ * @throws ChunkNotFoundException
+ *
+ */
+ public void testReadDisplayFrom() throws ChunkNotFoundException {
+ try {
+ mapiMessage.getDisplayFrom();
+ } catch(ChunkNotFoundException exp) {
+ return;
+ }
+
+ TestCase.fail("Should have thrown a ChunkNotFoundException but didn't");
+ }
+
/**
* Test to see if we can read the CC Chunk.
* @throws ChunkNotFoundException
TestCase.assertEquals(obtained, expected);
}
+ /**
+ * Test to see if we can read the From Chunk.
+ * @throws ChunkNotFoundException
+ *
+ */
+ public void testReadDisplayFrom() throws ChunkNotFoundException {
+ String obtained = mapiMessage.getDisplayFrom();
+ String expected = "Travis Ferguson";
+
+ TestCase.assertEquals(obtained, expected);
+ }
+
/**
* Test to see if we can read the CC Chunk.
* @throws ChunkNotFoundException
import junit.framework.TestSuite;
/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ * This is a test of all the Eval functions we have implemented.
+ * Add newly implemented Eval functions in here to have them
+ * tested.
+ * For newly implemented functions,
+ * @see org.apache.poi.hssf.record.formula.functions.TestEverything
*
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*/
public class TestEverything extends TestSuite {
public static TestSuite suite() throws Exception {
TestSuite suite = new TestSuite("Tests for OperationEval concrete implementation classes.");
- suite.addTest(new GenericFormulaTestCase("D23"));
- suite.addTest(new GenericFormulaTestCase("D27"));
- suite.addTest(new GenericFormulaTestCase("D31"));
- suite.addTest(new GenericFormulaTestCase("D35"));
- suite.addTest(new GenericFormulaTestCase("D39"));
- suite.addTest(new GenericFormulaTestCase("D43"));
- suite.addTest(new GenericFormulaTestCase("D47"));
- suite.addTest(new GenericFormulaTestCase("D51"));
- suite.addTest(new GenericFormulaTestCase("D55"));
- suite.addTest(new GenericFormulaTestCase("D59"));
- suite.addTest(new GenericFormulaTestCase("D63"));
- suite.addTest(new GenericFormulaTestCase("D67"));
- suite.addTest(new GenericFormulaTestCase("D71"));
- suite.addTest(new GenericFormulaTestCase("D75"));
+ suite.addTest(new GenericFormulaTestCase("D23")); // Add
+ suite.addTest(new GenericFormulaTestCase("D27")); // ConcatEval
+ suite.addTest(new GenericFormulaTestCase("D31")); // DivideEval
+ suite.addTest(new GenericFormulaTestCase("D35")); // EqualEval
+ suite.addTest(new GenericFormulaTestCase("D39")); // GreaterEqualEval
+ suite.addTest(new GenericFormulaTestCase("D43")); // GreaterThanEval
+ suite.addTest(new GenericFormulaTestCase("D47")); // LessEqualEval
+ suite.addTest(new GenericFormulaTestCase("D51")); // LessThanEval
+ suite.addTest(new GenericFormulaTestCase("D55")); // MultiplyEval
+ suite.addTest(new GenericFormulaTestCase("D59")); // NotEqualEval
+ suite.addTest(new GenericFormulaTestCase("D63")); // PowerEval
+ suite.addTest(new GenericFormulaTestCase("D67")); // SubtractEval
+ suite.addTest(new GenericFormulaTestCase("D71")); // UnaryMinusEval
+ suite.addTest(new GenericFormulaTestCase("D75")); // UnaryPlusEval
+
+ // Add newly implemented Eval functions here
+ // (Formula functions go in
+ // @see org.apache.poi.hssf.record.formula.functions.TestEverything )
+
return suite;
}
}
import junit.framework.TestSuite;
/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ * This is a test of all the normal formula functions we have implemented.
+ * It should pick up newly implemented functions which are correctly added
+ * to the test formula excel file, but tweak the rows below if you
+ * add any past the end of what's currently checked.
+ * For newly implemented eval functions,
+ * @see org.apache.poi.hssf.record.formula.eval.TestEverything
*
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*/
public class TestEverything extends TestSuite {
-
public static TestSuite suite() throws Exception {
TestSuite suite = new TestSuite("Tests for individual function classes");
String s;
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.poi.hwpf.usermodel;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.hwpf.HWPFDocument;
+import org.apache.poi.hwpf.model.StyleSheet;
+import org.apache.poi.hwpf.model.TextPiece;
+import org.apache.poi.hwpf.usermodel.Paragraph;
+import org.apache.poi.hwpf.usermodel.Range;
+import org.apache.poi.util.LittleEndian;
+
+import junit.framework.TestCase;
+
+/**
+ * Test various problem documents
+ *
+ * @author Nick Burch (nick at torchbox dot com)
+ */
+public class TestProblems extends TestCase {
+ private String dirname = System.getProperty("HWPF.testdata.path");
+
+ protected void setUp() throws Exception {
+ }
+
+ /**
+ * ListEntry passed no ListTable
+ */
+ public void testListEntryNoListTable() throws Exception {
+ HWPFDocument doc = new HWPFDocument(new FileInputStream(dirname + "/ListEntryNoListTable.doc"));
+
+ Range r = doc.getRange();
+ StyleSheet styleSheet = doc.getStyleSheet();
+ for (int x = 0; x < r.numSections(); x++) {
+ Section s = r.getSection(x);
+ for (int y = 0; y < s.numParagraphs(); y++) {
+ Paragraph paragraph = s.getParagraph(y);
+ //System.out.println(paragraph.getCharacterRun(0).text());
+ }
+ }
+ }
+
+ /**
+ * AIOOB for TableSprmUncompressor.unCompressTAPOperation
+ */
+ public void testSprmAIOOB() throws Exception {
+ HWPFDocument doc = new HWPFDocument(new FileInputStream(dirname + "/AIOOB-Tap.doc"));
+
+ Range r = doc.getRange();
+ StyleSheet styleSheet = doc.getStyleSheet();
+ for (int x = 0; x < r.numSections(); x++) {
+ Section s = r.getSection(x);
+ for (int y = 0; y < s.numParagraphs(); y++) {
+ Paragraph paragraph = s.getParagraph(y);
+ //System.out.println(paragraph.getCharacterRun(0).text());
+ }
+ }
+ }
+}
);
}
+ public void testwithContinueRecords() throws Exception {
+ String path = System.getProperty("HSSF.testdata.path");
+ FileInputStream fin = new FileInputStream(path + File.separator + "StringContinueRecords.xls");
+
+ ExcelExtractor extractor = new ExcelExtractor(new POIFSFileSystem(fin));
+
+ extractor.getText();
+
+ // Has masses of text
+ // Until we fixed bug #41064, this would've
+ // failed by now
+ assertTrue(extractor.getText().length() > 40960);
+ }
public void testStringConcat() throws Exception {
String path = System.getProperty("HSSF.testdata.path");
--- /dev/null
+/* ====================================================================
+ 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;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.hssf.util.*;
+
+import java.io.*;
+import java.util.*;
+import java.text.SimpleDateFormat;
+
+/**
+ * <p>Title: TestDataValidation</p>
+ * <p>Description: Class for testing Excel's data validation mechanism
+ * Second test :
+ * -
+ * </p>
+ * @author Dragos Buleandra ( dragos.buleandra@trade2b.ro )
+ */
+public class TestDataValidation extends TestCase
+{
+ public TestDataValidation(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp()
+ {
+ String filename = System.getProperty("HSSF.testdata.path");
+ if (filename == null)
+ {
+ System.setProperty("HSSF.testdata.path", "src/testcases/org/apache/poi/hssf/data");
+ }
+ }
+
+ public void testDataValidation() throws Exception
+ {
+ System.out.println("\nTest no. 2 - Test Excel's Data validation mechanism");
+ String resultFile = System.getProperty("HSSF.testdata.path")+"/TestDataValidation.xls";
+ HSSFWorkbook wb = new HSSFWorkbook();
+
+ HSSFCellStyle style_1 = this.createStyle( wb, HSSFCellStyle.ALIGN_LEFT );
+ HSSFCellStyle style_2 = this.createStyle( wb, HSSFCellStyle.ALIGN_CENTER );
+ HSSFCellStyle style_3 = this.createStyle( wb, HSSFCellStyle.ALIGN_CENTER, HSSFColor.GREY_25_PERCENT.index, true );
+ HSSFCellStyle style_4 = this.createHeaderStyle(wb);
+ HSSFDataValidation data_validation = null;
+
+ //data validation's number types
+ System.out.print(" Create sheet for Data Validation's number types ... ");
+ HSSFSheet fSheet = wb.createSheet("Number types");
+
+ //"Whole number" validation type
+ this.createDVTypeRow( wb, 0, style_3, "Whole number");
+ this.createHeaderRow( wb, 0, style_4 );
+
+ short start_row = (short)fSheet.getPhysicalNumberOfRows();
+ data_validation = new HSSFDataValidation((short)(start_row),(short)0,(short)(start_row),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_INTEGER);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_BETWEEN);
+ data_validation.setFirstFormula("2");
+ data_validation.setSecondFormula("6");
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Between 2 and 6 ", true, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)(start_row+1));
+ data_validation.setLastRow((short)(start_row+1));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_BETWEEN);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_INFO);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not between 2 and 6 ", false, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = INFO" );
+
+ data_validation.setFirstRow((short)(start_row+2));
+ data_validation.setLastRow((short)(start_row+2));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_EQUAL);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_WARNING);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Equal to 3", false, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = WARNING" );
+
+ data_validation.setFirstRow((short)(start_row+3));
+ data_validation.setLastRow((short)(start_row+3));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not equal to 3", false, false, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+4));
+ data_validation.setLastRow((short)(start_row+4));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than 3", true, false, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+5));
+ data_validation.setLastRow((short)(start_row+5));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than 3", true, true, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+6));
+ data_validation.setLastRow((short)(start_row+6));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_STOP);
+ data_validation.setShowErrorBox(true);
+ data_validation.setFirstFormula("4");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than or equal to 4", true, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)(start_row+7));
+ data_validation.setLastRow((short)(start_row+7));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("4");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than or equal to 4", false, true, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ //"Decimal" validation type
+ this.createDVTypeRow( wb, 0, style_3, "Decimal");
+ this.createHeaderRow( wb, 0, style_4 );
+
+ start_row += (short)(8+4);
+ data_validation = new HSSFDataValidation((short)(start_row),(short)0,(short)(start_row),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_DECIMAL);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_BETWEEN);
+ data_validation.setFirstFormula("2");
+ data_validation.setSecondFormula("6");
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Between 2 and 6 ", true, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)(start_row+1));
+ data_validation.setLastRow((short)(start_row+1));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_BETWEEN);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_INFO);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not between 2 and 6 ", false, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = INFO" );
+
+ data_validation.setFirstRow((short)(start_row+2));
+ data_validation.setLastRow((short)(start_row+2));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_EQUAL);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_WARNING);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Equal to 3", false, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = WARNING" );
+
+ data_validation.setFirstRow((short)(start_row+3));
+ data_validation.setLastRow((short)(start_row+3));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not equal to 3", false, false, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+4));
+ data_validation.setLastRow((short)(start_row+4));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than 3", true, false, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+5));
+ data_validation.setLastRow((short)(start_row+5));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than 3", true, true, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+6));
+ data_validation.setLastRow((short)(start_row+6));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_STOP);
+ data_validation.setShowErrorBox(true);
+ data_validation.setFirstFormula("4");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than or equal to 4", true, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)(start_row+7));
+ data_validation.setLastRow((short)(start_row+7));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("4");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than or equal to 4", false, true, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ System.out.println("done !");
+
+ //"List" Data Validation type
+ /** @todo List*/
+ System.out.print(" Create sheet for 'List' Data Validation type ... ");
+ fSheet = wb.createSheet("Lists");
+
+ this.createDVTypeRow( wb, 1, style_3, "Explicit lists - list items are explicitly provided");
+ this.createDVDeescriptionRow( wb, 1, style_3, "Disadvantage - sum of item's length should be less than 255 characters");
+ this.createHeaderRow( wb, 1, style_4 );
+
+ start_row = (short)fSheet.getPhysicalNumberOfRows();
+ data_validation = new HSSFDataValidation((short)(start_row),(short)0,(short)(start_row),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_LIST);
+ data_validation.setFirstFormula("1+2+3");
+ data_validation.setSecondFormula(null);
+ data_validation.setSurppressDropDownArrow(false);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "POIFS,HSSF,HWPF,HPSF", true, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type=STOP ; In-cell dropdown=yes" );
+
+ data_validation = new HSSFDataValidation((short)(start_row+1),(short)0,(short)(start_row+1),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_LIST);
+ data_validation.setFirstFormula("4+5+6+7");
+ data_validation.setSecondFormula(null);
+ data_validation.setSurppressDropDownArrow(false);
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "POIFS,HSSF,HWPF,HPSF", false, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type=STOP ; In-cell dropdown=yes" );
+
+ data_validation = new HSSFDataValidation((short)(start_row+2),(short)0,(short)(start_row+2),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_LIST);
+ data_validation.setFirstFormula("7+21");
+ data_validation.setSecondFormula(null);
+ data_validation.setSurppressDropDownArrow(true);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "POIFS,HSSF,HWPF,HPSF", true, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type=STOP ; In-cell dropdown=no" );
+
+ data_validation = new HSSFDataValidation((short)(start_row+3),(short)0,(short)(start_row+3),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_LIST);
+ data_validation.setFirstFormula("8/2");
+ data_validation.setSecondFormula(null);
+ data_validation.setSurppressDropDownArrow(true);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "POIFS,HSSF,HWPF,HPSF", false, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type=STOP ; In-cell dropdown=no" );
+
+ this.createDVTypeRow( wb, 1, style_3, "Reference lists - list items are taken from others cells");
+ this.createDVDeescriptionRow( wb, 1, style_3, "Advantage - no restriction regarding the sum of item's length");
+ this.createHeaderRow( wb, 1, style_4 );
+
+ start_row += (short)(4+5);
+ String cellStrValue = "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 "+
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 "+
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 "+
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 ";
+
+ String strFormula = "$A$100:$A$120";
+ data_validation = new HSSFDataValidation((short)(start_row),(short)0,(short)(start_row),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_LIST);
+ data_validation.setFirstFormula(strFormula);
+ data_validation.setSecondFormula(null);
+ data_validation.setSurppressDropDownArrow(false);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, strFormula, true, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type=STOP ; In-cell dropdown=yes" );
+
+ data_validation = new HSSFDataValidation((short)(start_row+1),(short)0,(short)(start_row+1),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_LIST);
+ data_validation.setFirstFormula(strFormula);
+ data_validation.setSecondFormula(null);
+ data_validation.setSurppressDropDownArrow(false);
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, strFormula, false, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type=STOP ; In-cell dropdown=yes" );
+
+ data_validation = new HSSFDataValidation((short)(start_row+2),(short)0,(short)(start_row+2),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_LIST);
+ data_validation.setFirstFormula(strFormula);
+ data_validation.setSecondFormula(null);
+ data_validation.setSurppressDropDownArrow(true);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, strFormula, true, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type=STOP ; In-cell dropdown=no" );
+
+ data_validation = new HSSFDataValidation((short)(start_row+3),(short)0,(short)(start_row+3),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_LIST);
+ data_validation.setFirstFormula(strFormula);
+ data_validation.setSecondFormula(null);
+ data_validation.setSurppressDropDownArrow(true);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, strFormula, false, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type=STOP ; In-cell dropdown=no" );
+
+ for (int i=100; i<=120; i++)
+ {
+ HSSFRow currRow = fSheet.createRow(i);
+ currRow.createCell((short)0).setCellValue(cellStrValue);
+// currRow.hide( true );
+ }
+
+ System.out.println("done !");
+
+ //Date/Time Validation type
+ System.out.print(" Create sheet for 'Date' and 'Time' Data Validation types ... ");
+ fSheet = wb.createSheet("Date_Time");
+ SimpleDateFormat df = new SimpleDateFormat("m/d/yyyy");
+ HSSFDataFormat dataFormat = wb.createDataFormat();
+ short fmtDate = dataFormat.getFormat("m/d/yyyy");
+ short fmtTime = dataFormat.getFormat("h:mm");
+ HSSFCellStyle cellStyle_data = wb.createCellStyle();
+ cellStyle_data.setDataFormat(fmtDate);
+ HSSFCellStyle cellStyle_time = wb.createCellStyle();
+ cellStyle_time.setDataFormat(fmtTime);
+
+ this.createDVTypeRow( wb, 2, style_3, "Date ( cells are already formated as date - m/d/yyyy)");
+ this.createHeaderRow( wb, 2, style_4 );
+
+ start_row = (short)fSheet.getPhysicalNumberOfRows();
+ data_validation = new HSSFDataValidation((short)(start_row),(short)0,(short)(start_row),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_DATE);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_BETWEEN);
+
+ data_validation.setFirstFormula( String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("1/2/2004"))) );
+ data_validation.setSecondFormula( String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("1/6/2004"))) );
+
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Between 1/2/2004 and 1/6/2004 ", true, true, true );
+ this.setCellFormat( fSheet, cellStyle_data );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)(start_row+1));
+ data_validation.setLastRow((short)(start_row+1));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_BETWEEN);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_INFO);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not between 1/2/2004 and 1/6/2004 ", false, true, true );
+ this.setCellFormat( fSheet, cellStyle_data );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = INFO" );
+
+ data_validation.setFirstRow((short)(start_row+2));
+ data_validation.setLastRow((short)(start_row+2));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setFirstFormula(String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("3/2/2004"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_EQUAL);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_WARNING);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Equal to 3/2/2004", false, false, true );
+ this.setCellFormat( fSheet, cellStyle_data );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = WARNING" );
+
+ data_validation.setFirstRow((short)(start_row+3));
+ data_validation.setLastRow((short)(start_row+3));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula(String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("3/2/2004"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not equal to 3/2/2004", false, false, false );
+ this.setCellFormat( fSheet, cellStyle_data );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+4));
+ data_validation.setLastRow((short)(start_row+4));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula(String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("3/2/2004"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than 3/2/2004", true, false, false );
+ this.setCellFormat( fSheet, cellStyle_data );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+5));
+ data_validation.setLastRow((short)(start_row+5));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula(String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("3/2/2004"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than 3/2/2004", true, true, false );
+ this.setCellFormat( fSheet, cellStyle_data );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+6));
+ data_validation.setLastRow((short)(start_row+6));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_STOP);
+ data_validation.setShowErrorBox(true);
+ data_validation.setFirstFormula(String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("3/2/2004"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than or equal to 3/2/2004", true, false, true );
+ this.setCellFormat( fSheet, cellStyle_data );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)(start_row+7));
+ data_validation.setLastRow((short)(start_row+7));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula(String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("3/4/2004"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than or equal to 3/4/2004", false, true, false );
+ this.setCellFormat( fSheet, cellStyle_data );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ //"Time" validation type
+ this.createDVTypeRow( wb, 2, style_3, "Time ( cells are already formated as time - h:mm)");
+ this.createHeaderRow( wb, 2, style_4 );
+
+ df = new SimpleDateFormat("hh:mm");
+
+ start_row += (short)(8+4);
+ data_validation = new HSSFDataValidation((short)(start_row),(short)0,(short)(start_row),(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_TIME);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_BETWEEN);
+ data_validation.setFirstFormula(String.valueOf(HSSFDateUtil.getExcelDate(df.parse("12:00"))));
+ data_validation.setSecondFormula(String.valueOf(HSSFDateUtil.getExcelDate(df.parse("16:00"))));
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Between 12:00 and 16:00 ", true, true, true );
+ this.setCellFormat( fSheet, cellStyle_time );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)(start_row+1));
+ data_validation.setLastRow((short)(start_row+1));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_BETWEEN);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_INFO);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not between 12:00 and 16:00 ", false, true, true );
+ this.setCellFormat( fSheet, cellStyle_time );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = INFO" );
+
+ data_validation.setFirstRow((short)(start_row+2));
+ data_validation.setLastRow((short)(start_row+2));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setFirstFormula(String.valueOf((int)HSSFDateUtil.getExcelDate(df.parse("13:35"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_EQUAL);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_WARNING);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Equal to 13:35", false, false, true );
+ this.setCellFormat( fSheet, cellStyle_time );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = WARNING" );
+
+ data_validation.setFirstRow((short)(start_row+3));
+ data_validation.setLastRow((short)(start_row+3));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula(String.valueOf(HSSFDateUtil.getExcelDate(df.parse("13:35"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not equal to 13:35", false, false, false );
+ this.setCellFormat( fSheet, cellStyle_time );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+4));
+ data_validation.setLastRow((short)(start_row+4));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula(String.valueOf(HSSFDateUtil.getExcelDate(df.parse("12:00"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than 12:00", true, false, false );
+ this.setCellFormat( fSheet, cellStyle_time );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+5));
+ data_validation.setLastRow((short)(start_row+5));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula(String.valueOf(HSSFDateUtil.getExcelDate(df.parse("12:00"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than 12:00", true, true, false );
+ this.setCellFormat( fSheet, cellStyle_time );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)(start_row+6));
+ data_validation.setLastRow((short)(start_row+6));
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_STOP);
+ data_validation.setShowErrorBox(true);
+ data_validation.setFirstFormula(String.valueOf(HSSFDateUtil.getExcelDate(df.parse("14:00"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than or equal to 14:00", true, false, true );
+ this.setCellFormat( fSheet, cellStyle_time );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)(start_row+7));
+ data_validation.setLastRow((short)(start_row+7));
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula(String.valueOf(HSSFDateUtil.getExcelDate(df.parse("14:00"))));
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than or equal to 14:00", false, true, false );
+ this.setCellFormat( fSheet, cellStyle_time );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ System.out.println("done !");
+
+ //"Text length" validation type
+ System.out.print(" Create sheet for 'Text length' Data Validation type... ");
+ fSheet = wb.createSheet("Text length");
+ this.createHeaderRow( wb, 3, style_4 );
+
+ data_validation = new HSSFDataValidation((short)1,(short)0,(short)1,(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_TEXT_LENGTH);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_BETWEEN);
+ data_validation.setFirstFormula("2");
+ data_validation.setSecondFormula("6");
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Between 2 and 6 ", true, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)2);
+ data_validation.setLastRow((short)2);
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_BETWEEN);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_INFO);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not between 2 and 6 ", false, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = INFO" );
+
+ data_validation.setFirstRow((short)3);
+ data_validation.setLastRow((short)3);
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_EQUAL);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_WARNING);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Equal to 3", false, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = WARNING" );
+
+ data_validation.setFirstRow((short)4);
+ data_validation.setLastRow((short)4);
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_NOT_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Not equal to 3", false, false, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)5);
+ data_validation.setLastRow((short)5);
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than 3", true, false, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)6);
+ data_validation.setLastRow((short)6);
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("3");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_THAN);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than 3", true, true, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+
+ data_validation.setFirstRow((short)7);
+ data_validation.setLastRow((short)7);
+ data_validation.setEmptyCellAllowed(true);
+ data_validation.setShowPromptBox(false);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_STOP);
+ data_validation.setShowErrorBox(true);
+ data_validation.setFirstFormula("4");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_GREATER_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Greater than or equal to 4", true, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation.setFirstRow((short)8);
+ data_validation.setLastRow((short)8);
+ data_validation.setEmptyCellAllowed(false);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(false);
+ data_validation.setFirstFormula("4");
+ data_validation.setSecondFormula(null);
+ data_validation.setOperator(HSSFDataValidation.OPERATOR_LESS_OR_EQUAL);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "Less than or equal to 4", false, true, false );
+ this.writeOtherSettings( fSheet, style_1, "-" );
+ System.out.println("done !");
+
+ //Custom Validation type
+ System.out.print(" Create sheet for 'Custom' Data Validation type ... ");
+ fSheet = wb.createSheet("Custom");
+ this.createHeaderRow( wb, 4, style_4 );
+
+ data_validation = new HSSFDataValidation((short)1,(short)0,(short)1,(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_FORMULA);
+ data_validation.setFirstFormula("ISNUMBER($A2)");
+ data_validation.setSecondFormula(null);
+ data_validation.setShowPromptBox(true);
+ data_validation.setShowErrorBox(true);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.createPromptBox("Hi , dear user !", "So , you just selected me ! Thanks !");
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "ISNUMBER(A2)", true, true, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = STOP" );
+
+ data_validation = new HSSFDataValidation((short)2,(short)0,(short)2,(short)0);
+ data_validation.setDataValidationType(HSSFDataValidation.DATA_TYPE_FORMULA);
+ data_validation.setFirstFormula("IF(SUM(A2:A3)=5,TRUE,FALSE)");
+ data_validation.setSecondFormula(null);
+ data_validation.setShowPromptBox(false);
+ data_validation.setShowErrorBox(true);
+ data_validation.setErrorStyle(HSSFDataValidation.ERROR_STYLE_WARNING);
+ data_validation.createErrorBox("Invalid input !", "Something is wrong ; check condition !");
+ data_validation.setEmptyCellAllowed(false);
+ fSheet.addValidationData(data_validation);
+ this.writeDataValidationSettings( fSheet, style_1, style_2, "IF(SUM(A2:A3)=5,TRUE,FALSE)", false, false, true );
+ this.writeOtherSettings( fSheet, style_1, "Error box type = WARNING" );
+
+ System.out.println("done !");
+
+ //so , everything it's ok for now ; it remains for you to open the file
+ System.out.println("\n Everything it's ok since we've got so far -:) !\n"+
+ " In order to complete the test , it remains for you to open the file \n"+
+ " and see if there are four sheets , as described !");
+ System.out.println(" File was saved in \""+resultFile+"\"");
+
+ FileOutputStream fileOut = new FileOutputStream(resultFile);
+ wb.write(fileOut);
+ fileOut.close();
+ }
+
+ private void createDVTypeRow( HSSFWorkbook wb, int sheetNo , HSSFCellStyle cellStyle, String strTypeDescription)
+ {
+ HSSFSheet sheet = wb.getSheetAt(sheetNo);
+ HSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+ row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+ sheet.addMergedRegion(new Region((short)(sheet.getPhysicalNumberOfRows()-1),(short)0,(short)(sheet.getPhysicalNumberOfRows()-1),(short)5));
+ HSSFCell cell = row.createCell((short)0);
+ cell.setCellValue(strTypeDescription);
+ cell.setCellStyle(cellStyle);
+ row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+ }
+
+ private void createDVDeescriptionRow( HSSFWorkbook wb, int sheetNo , HSSFCellStyle cellStyle, String strTypeDescription )
+ {
+ HSSFSheet sheet = wb.getSheetAt(sheetNo);
+ HSSFRow row = sheet.getRow(sheet.getPhysicalNumberOfRows()-1);
+ sheet.addMergedRegion(new Region((short)(sheet.getPhysicalNumberOfRows()-1),(short)0,(short)(sheet.getPhysicalNumberOfRows()-1),(short)5));
+ HSSFCell cell = row.createCell((short)0);
+ cell.setCellValue(strTypeDescription);
+ cell.setCellStyle(cellStyle);
+ row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+ }
+
+ private void createHeaderRow( HSSFWorkbook wb, int sheetNo , HSSFCellStyle cellStyle )
+ {
+ HSSFSheet sheet = wb.getSheetAt(sheetNo);
+ HSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+ row.setHeight((short)400);
+ for ( int i=0; i<6; i++ )
+ {
+ row.createCell((short)i).setCellStyle( cellStyle );
+ if ( i==2 || i==3 || i==4 )
+ {
+ sheet.setColumnWidth( (short) i, (short) 3500);
+ }
+ else if ( i== 5)
+ {
+ sheet.setColumnWidth( (short) i, (short) 10000);
+ }
+ else
+ {
+ sheet.setColumnWidth( (short) i, (short) 8000);
+ }
+ }
+ HSSFCell cell = row.getCell((short)0);
+ cell.setCellValue("Data validation cells");
+ cell = row.getCell((short)1);
+ cell.setCellValue("Condition");
+ cell = row.getCell((short)2);
+ cell.setCellValue("Allow blank");
+ cell = row.getCell((short)3);
+ cell.setCellValue("Prompt box");
+ cell = row.getCell((short)4);
+ cell.setCellValue("Error box");
+ cell = row.getCell((short)5);
+ cell.setCellValue("Other settings");
+ }
+
+ private HSSFCellStyle createHeaderStyle(HSSFWorkbook wb)
+ {
+ HSSFFont font = wb.createFont();
+ font.setColor( HSSFColor.WHITE.index );
+ font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
+
+ HSSFCellStyle cellStyle = wb.createCellStyle();
+ cellStyle.setFillForegroundColor(HSSFColor.BLUE_GREY.index);
+ cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
+ cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
+ cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
+ cellStyle.setLeftBorderColor(HSSFColor.WHITE.index);
+ cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
+ cellStyle.setTopBorderColor(HSSFColor.WHITE.index);
+ cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
+ cellStyle.setRightBorderColor(HSSFColor.WHITE.index);
+ cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
+ cellStyle.setBottomBorderColor(HSSFColor.WHITE.index);
+ cellStyle.setFont(font);
+ return cellStyle;
+ }
+
+ private HSSFCellStyle createStyle( HSSFWorkbook wb, short h_align, short color, boolean bold )
+ {
+ HSSFFont font = wb.createFont();
+ if ( bold )
+ {
+ font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
+ }
+
+ HSSFCellStyle cellStyle = wb.createCellStyle();
+ cellStyle.setFont(font);
+ cellStyle.setFillForegroundColor(color);
+ cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
+ cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
+ cellStyle.setAlignment(h_align);
+ cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
+ cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
+ cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
+ cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
+ cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
+ cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
+ cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
+ cellStyle.setBottomBorderColor(HSSFColor.BLACK.index);
+
+ return cellStyle;
+ }
+
+ private HSSFCellStyle createStyle( HSSFWorkbook wb, short h_align )
+ {
+ return this.createStyle(wb, h_align, HSSFColor.WHITE.index, false);
+ }
+
+ private void writeDataValidationSettings( HSSFSheet sheet, HSSFCellStyle style_1, HSSFCellStyle style_2, String strCondition, boolean allowEmpty, boolean inputBox, boolean errorBox )
+ {
+ HSSFRow row = sheet.createRow( sheet.getPhysicalNumberOfRows() );
+ //condition's string
+ HSSFCell cell = row.createCell((short)1);
+ cell.setCellStyle(style_1);
+ cell.setCellValue(strCondition);
+ //allow empty cells
+ cell = row.createCell((short)2);
+ cell.setCellStyle(style_2);
+ cell.setCellValue( ((allowEmpty) ? "yes" : "no") );
+ //show input box
+ cell = row.createCell((short)3);
+ cell.setCellStyle(style_2);
+ cell.setCellValue( ((inputBox) ? "yes" : "no") );
+ //show error box
+ cell = row.createCell((short)4);
+ cell.setCellStyle(style_2);
+ cell.setCellValue( ((errorBox) ? "yes" : "no") );
+ }
+
+ private void setCellFormat( HSSFSheet sheet, HSSFCellStyle cell_style )
+ {
+ HSSFRow row = sheet.getRow( sheet.getPhysicalNumberOfRows() -1 );
+ HSSFCell cell = row.createCell((short)0);
+ cell.setCellStyle(cell_style);
+ }
+
+ private void writeOtherSettings( HSSFSheet sheet, HSSFCellStyle style, String strStettings )
+ {
+ HSSFRow row = sheet.getRow( sheet.getPhysicalNumberOfRows() -1 );
+ HSSFCell cell = row.createCell((short)5);
+ cell.setCellStyle(style);
+ cell.setCellValue(strStettings);
+ }
+
+ public static void main(String[] args)
+ {
+ junit.textui.TestRunner.run(TestDataValidation.class);
+ }
+}
* paticular datatypes, etc.
* @author Andrew C. Oliver (andy at superlinksoftware dot com)
* @author Dan Sherman (dsherman at isisph.com)
+ * @author Alex Jacoby (ajacoby at gmail.com)
*/
public class TestHSSFCell
}
/**
- * Checks that the recognition of files using 1904 date windowing
- * is working properly. Conversion of the date is also an issue,
- * but there's a separate unit test for that.
- */
- public void testDateWindowing() throws Exception {
- GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000
- Date date = cal.getTime();
- String path = System.getProperty("HSSF.testdata.path");
-
- // first check a file with 1900 Date Windowing
- String filename = path + "/1900DateWindowing.xls";
- FileInputStream stream = new FileInputStream(filename);
- POIFSFileSystem fs = new POIFSFileSystem(stream);
- HSSFWorkbook workbook = new HSSFWorkbook(fs);
- HSSFSheet sheet = workbook.getSheetAt(0);
-
- assertEquals("Date from file using 1900 Date Windowing",
- date.getTime(),
- sheet.getRow(0).getCell((short)0)
- .getDateCellValue().getTime());
- stream.close();
-
- // now check a file with 1904 Date Windowing
- filename = path + "/1904DateWindowing.xls";
- stream = new FileInputStream(filename);
- fs = new POIFSFileSystem(stream);
- workbook = new HSSFWorkbook(fs);
- sheet = workbook.getSheetAt(0);
-
- assertEquals("Date from file using 1904 Date Windowing",
- date.getTime(),
- sheet.getRow(0).getCell((short)0)
- .getDateCellValue().getTime());
- stream.close();
- }
-
+ * Checks that the recognition of files using 1904 date windowing
+ * is working properly. Conversion of the date is also an issue,
+ * but there's a separate unit test for that.
+ */
+ public void testDateWindowingRead() throws Exception {
+ GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000
+ Date date = cal.getTime();
+ String path = System.getProperty("HSSF.testdata.path");
+
+ // first check a file with 1900 Date Windowing
+ String filename = path + "/1900DateWindowing.xls";
+ FileInputStream stream = new FileInputStream(filename);
+ POIFSFileSystem fs = new POIFSFileSystem(stream);
+ HSSFWorkbook workbook = new HSSFWorkbook(fs);
+ HSSFSheet sheet = workbook.getSheetAt(0);
+
+ assertEquals("Date from file using 1900 Date Windowing",
+ date.getTime(),
+ sheet.getRow(0).getCell((short)0)
+ .getDateCellValue().getTime());
+ stream.close();
+
+ // now check a file with 1904 Date Windowing
+ filename = path + "/1904DateWindowing.xls";
+ stream = new FileInputStream(filename);
+ fs = new POIFSFileSystem(stream);
+ workbook = new HSSFWorkbook(fs);
+ sheet = workbook.getSheetAt(0);
+
+ assertEquals("Date from file using 1904 Date Windowing",
+ date.getTime(),
+ sheet.getRow(0).getCell((short)0)
+ .getDateCellValue().getTime());
+ stream.close();
+ }
+
+ /**
+ * Checks that dates are properly written to both types of files:
+ * those with 1900 and 1904 date windowing. Note that if the
+ * previous test ({@link #testDateWindowingRead}) fails, the
+ * results of this test are meaningless.
+ */
+ public void testDateWindowingWrite() throws Exception {
+ GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000
+ Date date = cal.getTime();
+ String path = System.getProperty("HSSF.testdata.path");
+
+ // first check a file with 1900 Date Windowing
+ String filename = path + "/1900DateWindowing.xls";
+ writeCell(filename, 0, (short) 1, date);
+ assertEquals("Date from file using 1900 Date Windowing",
+ date.getTime(),
+ readCell(filename, 0, (short) 1).getTime());
+
+ // now check a file with 1904 Date Windowing
+ filename = path + "/1904DateWindowing.xls";
+ writeCell(filename, 0, (short) 1, date);
+ assertEquals("Date from file using 1900 Date Windowing",
+ date.getTime(),
+ readCell(filename, 0, (short) 1).getTime());
+ }
+
+ /**
+ * Sets cell value and writes file.
+ */
+ private void writeCell(String filename,
+ int rowIdx, short colIdx, Date date) throws Exception {
+ FileInputStream stream = new FileInputStream(filename);
+ POIFSFileSystem fs = new POIFSFileSystem(stream);
+ HSSFWorkbook workbook = new HSSFWorkbook(fs);
+ HSSFSheet sheet = workbook.getSheetAt(0);
+ HSSFRow row = sheet.getRow(rowIdx);
+ HSSFCell cell = row.getCell(colIdx);
+
+ if (cell == null) {
+ cell = row.createCell(colIdx);
+ }
+ cell.setCellValue(date);
+
+ // Write the file
+ stream.close();
+ FileOutputStream oStream = new FileOutputStream(filename);
+ workbook.write(oStream);
+ oStream.close();
+ }
+
+ /**
+ * Reads cell value from file.
+ */
+ private Date readCell(String filename,
+ int rowIdx, short colIdx) throws Exception {
+ FileInputStream stream = new FileInputStream(filename);
+ POIFSFileSystem fs = new POIFSFileSystem(stream);
+ HSSFWorkbook workbook = new HSSFWorkbook(fs);
+ HSSFSheet sheet = workbook.getSheetAt(0);
+ HSSFRow row = sheet.getRow(rowIdx);
+ HSSFCell cell = row.getCell(colIdx);
+ return cell.getDateCellValue();
+ }
+
/**
* Tests that the active cell can be correctly read and set
*/
assertEquals(anchor[i].getRow2(), record.getRow2());
}
}
+
+ public void testAnchorHeightInPoints(){
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet = wb.createSheet();
+
+ HSSFClientAnchor[] anchor = {
+ new HSSFClientAnchor( 0 , 0, 0 , 0 ,(short)0, 1,(short)1, 3),
+ new HSSFClientAnchor( 0 , 254 , 0 , 126 ,(short)0, 1,(short)1, 3),
+ new HSSFClientAnchor( 0 , 128 , 0 , 128 ,(short)0, 1,(short)1, 3),
+ new HSSFClientAnchor( 0 , 0 , 0 , 128 ,(short)0, 1,(short)1, 3),
+ };
+ float[] ref = {24.0f, 18.0f, 24.0f, 30.0f};
+ for (int i = 0; i < anchor.length; i++) {
+ float height = anchor[i].getAnchorHeightInPoints(sheet);
+ assertEquals(ref[i], height, 0);
+ }
+
+ }
+
}
*
* @author Dan Sherman (dsherman at isisph.com)
* @author Hack Kampbjorn (hak at 2mba.dk)
+ * @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
+ * @author Alex Jacoby (ajacoby at gmail.com)
* @version %I%, %G%
*/
public static final int CALENDAR_FEBRUARY = 1;
public static final int CALENDAR_MARCH = 2;
public static final int CALENDAR_APRIL = 3;
-
+ public static final int CALENDAR_JULY = 6;
+ public static final int CALENDAR_OCTOBER = 9;
+
public TestHSSFDateUtil(String s)
{
super(s);
GregorianCalendar date = new GregorianCalendar(2002, 0, 1,
hour, 1, 1);
double excelDate =
- HSSFDateUtil.getExcelDate(date.getTime());
+ HSSFDateUtil.getExcelDate(date.getTime(), false);
assertEquals("Checking hour = " + hour, date.getTime().getTime(),
- HSSFDateUtil.getJavaDate(excelDate).getTime());
+ HSSFDateUtil.getJavaDate(excelDate, false).getTime());
}
// check 1900 and 1904 date windowing conversions
public void testExcelConversionOnDSTStart() {
TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen");
TimeZone.setDefault(cet);
- Calendar cal = new GregorianCalendar(2004, Calendar.MARCH, 28);
+ Calendar cal = new GregorianCalendar(2004, CALENDAR_MARCH, 28);
for (int hour = 0; hour < 24; hour++) {
// Skip 02:00 CET as that is the Daylight change time
cal.set(Calendar.HOUR_OF_DAY, hour);
Date javaDate = cal.getTime();
- double excelDate = HSSFDateUtil.getExcelDate(javaDate);
+ double excelDate = HSSFDateUtil.getExcelDate(javaDate, false);
double difference = excelDate - Math.floor(excelDate);
int differenceInHours = (int) (difference * 24 * 60 + 0.5) / 60;
assertEquals("Checking " + hour + " hour on Daylight Saving Time start date",
differenceInHours);
assertEquals("Checking " + hour + " hour on Daylight Saving Time start date",
javaDate.getTime(),
- HSSFDateUtil.getJavaDate(excelDate).getTime());
+ HSSFDateUtil.getJavaDate(excelDate, false).getTime());
}
}
public void testJavaConversionOnDSTStart() {
TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen");
TimeZone.setDefault(cet);
- Calendar cal = new GregorianCalendar(2004, Calendar.MARCH, 28);
- double excelDate = HSSFDateUtil.getExcelDate(cal.getTime());
+ Calendar cal = new GregorianCalendar(2004, CALENDAR_MARCH, 28);
+ double excelDate = HSSFDateUtil.getExcelDate(cal.getTime(), false);
double oneHour = 1.0 / 24;
double oneMinute = oneHour / 60;
for (int hour = 0; hour < 24; hour++, excelDate += oneHour) {
}
cal.set(Calendar.HOUR_OF_DAY, hour);
- Date javaDate = HSSFDateUtil.getJavaDate(excelDate);
+ Date javaDate = HSSFDateUtil.getJavaDate(excelDate, false);
assertEquals("Checking " + hour + " hours on Daylight Saving Time start date",
excelDate,
- HSSFDateUtil.getExcelDate(javaDate), oneMinute);
+ HSSFDateUtil.getExcelDate(javaDate, false), oneMinute);
}
}
public void testExcelConversionOnDSTEnd() {
TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen");
TimeZone.setDefault(cet);
- Calendar cal = new GregorianCalendar(2004, Calendar.OCTOBER, 31);
+ Calendar cal = new GregorianCalendar(2004, CALENDAR_OCTOBER, 31);
for (int hour = 0; hour < 24; hour++) {
cal.set(Calendar.HOUR_OF_DAY, hour);
Date javaDate = cal.getTime();
- double excelDate = HSSFDateUtil.getExcelDate(javaDate);
+ double excelDate = HSSFDateUtil.getExcelDate(javaDate, false);
double difference = excelDate - Math.floor(excelDate);
int differenceInHours = (int) (difference * 24 * 60 + 0.5) / 60;
assertEquals("Checking " + hour + " hour on Daylight Saving Time end date",
differenceInHours);
assertEquals("Checking " + hour + " hour on Daylight Saving Time start date",
javaDate.getTime(),
- HSSFDateUtil.getJavaDate(excelDate).getTime());
+ HSSFDateUtil.getJavaDate(excelDate, false).getTime());
}
}
public void testJavaConversionOnDSTEnd() {
TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen");
TimeZone.setDefault(cet);
- Calendar cal = new GregorianCalendar(2004, Calendar.OCTOBER, 31);
- double excelDate = HSSFDateUtil.getExcelDate(cal.getTime());
+ Calendar cal = new GregorianCalendar(2004, CALENDAR_OCTOBER, 31);
+ double excelDate = HSSFDateUtil.getExcelDate(cal.getTime(), false);
double oneHour = 1.0 / 24;
double oneMinute = oneHour / 60;
for (int hour = 0; hour < 24; hour++, excelDate += oneHour) {
cal.set(Calendar.HOUR_OF_DAY, hour);
- Date javaDate = HSSFDateUtil.getJavaDate(excelDate);
+ Date javaDate = HSSFDateUtil.getJavaDate(excelDate, false);
assertEquals("Checking " + hour + " hours on Daylight Saving Time start date",
excelDate,
- HSSFDateUtil.getExcelDate(javaDate), oneMinute);
+ HSSFDateUtil.getExcelDate(javaDate, false), oneMinute);
}
}
}
public void testDateBug_2Excel() {
- assertEquals(59.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_FEBRUARY, 28)), 0.00001);
- assertEquals(61.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_MARCH, 1)), 0.00001);
+ assertEquals(59.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_FEBRUARY, 28), false), 0.00001);
+ assertEquals(61.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_MARCH, 1), false), 0.00001);
- assertEquals(37315.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_FEBRUARY, 28)), 0.00001);
- assertEquals(37316.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_MARCH, 1)), 0.00001);
- assertEquals(37257.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_JANUARY, 1)), 0.00001);
- assertEquals(38074.00, HSSFDateUtil.getExcelDate(createDate(2004, CALENDAR_MARCH, 28)), 0.00001);
+ assertEquals(37315.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_FEBRUARY, 28), false), 0.00001);
+ assertEquals(37316.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_MARCH, 1), false), 0.00001);
+ assertEquals(37257.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_JANUARY, 1), false), 0.00001);
+ assertEquals(38074.00, HSSFDateUtil.getExcelDate(createDate(2004, CALENDAR_MARCH, 28), false), 0.00001);
}
public void testDateBug_2Java() {
- assertEquals(createDate(1900, Calendar.FEBRUARY, 28), HSSFDateUtil.getJavaDate(59.0));
- assertEquals(createDate(1900, Calendar.MARCH, 1), HSSFDateUtil.getJavaDate(61.0));
+ assertEquals(createDate(1900, CALENDAR_FEBRUARY, 28), HSSFDateUtil.getJavaDate(59.0, false));
+ assertEquals(createDate(1900, CALENDAR_MARCH, 1), HSSFDateUtil.getJavaDate(61.0, false));
- assertEquals(createDate(2002, Calendar.FEBRUARY, 28), HSSFDateUtil.getJavaDate(37315.00));
- assertEquals(createDate(2002, Calendar.MARCH, 1), HSSFDateUtil.getJavaDate(37316.00));
- assertEquals(createDate(2002, Calendar.JANUARY, 1), HSSFDateUtil.getJavaDate(37257.00));
- assertEquals(createDate(2004, Calendar.MARCH, 28), HSSFDateUtil.getJavaDate(38074.00));
+ assertEquals(createDate(2002, CALENDAR_FEBRUARY, 28), HSSFDateUtil.getJavaDate(37315.00, false));
+ assertEquals(createDate(2002, CALENDAR_MARCH, 1), HSSFDateUtil.getJavaDate(37316.00, false));
+ assertEquals(createDate(2002, CALENDAR_JANUARY, 1), HSSFDateUtil.getJavaDate(37257.00, false));
+ assertEquals(createDate(2004, CALENDAR_MARCH, 28), HSSFDateUtil.getJavaDate(38074.00, false));
}
-
+
+ public void testDate1904() {
+ assertEquals(createDate(1904, CALENDAR_JANUARY, 2), HSSFDateUtil.getJavaDate(1.0, true));
+ assertEquals(createDate(1904, CALENDAR_JANUARY, 1), HSSFDateUtil.getJavaDate(0.0, true));
+ assertEquals(0.0, HSSFDateUtil.getExcelDate(createDate(1904, CALENDAR_JANUARY, 1), true), 0.00001);
+ assertEquals(1.0, HSSFDateUtil.getExcelDate(createDate(1904, CALENDAR_JANUARY, 2), true), 0.00001);
+
+ assertEquals(createDate(1998, CALENDAR_JULY, 5), HSSFDateUtil.getJavaDate(35981, false));
+ assertEquals(createDate(1998, CALENDAR_JULY, 5), HSSFDateUtil.getJavaDate(34519, true));
+
+ assertEquals(35981.0, HSSFDateUtil.getExcelDate(createDate(1998, CALENDAR_JULY, 5), false), 0.00001);
+ assertEquals(34519.0, HSSFDateUtil.getExcelDate(createDate(1998, CALENDAR_JULY, 5), true), 0.00001);
+ }
+
private Date createDate(int year, int month, int day) {
Calendar c = new GregorianCalendar();
c.set(year, month, day, 0, 0, 0);
return c.getTime();
}
+ /**
+ * Check if HSSFDateUtil.getAbsoluteDay works as advertised.
+ */
+ public void testAbsoluteDay() {
+ // 1 Jan 1900 is 1 day after 31 Dec 1899
+ GregorianCalendar calendar = new GregorianCalendar(1900, 0, 1);
+ assertEquals("Checking absolute day (1 Jan 1900)", 1, HSSFDateUtil.absoluteDay(calendar, false));
+ // 1 Jan 1901 is 366 days after 31 Dec 1899
+ calendar = new GregorianCalendar(1901, 0, 1);
+ assertEquals("Checking absolute day (1 Jan 1901)", 366, HSSFDateUtil.absoluteDay(calendar, false));
+ }
+
public static void main(String [] args) {
System.out
.println("Testing org.apache.poi.hssf.usermodel.TestHSSFDateUtil");
junit.textui.TestRunner.run(TestHSSFDateUtil.class);
}
}
-
assertEquals(msg, (short) 100, actualRGB[2]);
}
+ /**
+ * Uses the palette from cell stylings
+ */
+ public void testPaletteFromCellColours() throws Exception {
+ String dir = System.getProperty("HSSF.testdata.path");
+ File sample = new File(dir + "/SimpleWithColours.xls");
+ assertTrue("SimpleWithColours.xls exists and is readable", sample.canRead());
+ FileInputStream fis = new FileInputStream(sample);
+ HSSFWorkbook book = new HSSFWorkbook(fis);
+ fis.close();
+
+ HSSFPalette p = book.getCustomPalette();
+
+ HSSFCell cellA = book.getSheetAt(0).getRow(0).getCell((short)0);
+ HSSFCell cellB = book.getSheetAt(0).getRow(1).getCell((short)0);
+ HSSFCell cellC = book.getSheetAt(0).getRow(2).getCell((short)0);
+ HSSFCell cellD = book.getSheetAt(0).getRow(3).getCell((short)0);
+ HSSFCell cellE = book.getSheetAt(0).getRow(4).getCell((short)0);
+
+ // Plain
+ assertEquals("I'm plain", cellA.getStringCellValue());
+ assertEquals(64, cellA.getCellStyle().getFillForegroundColor());
+ assertEquals(64, cellA.getCellStyle().getFillBackgroundColor());
+ assertEquals(HSSFFont.COLOR_NORMAL, cellA.getCellStyle().getFont(book).getColor());
+ assertEquals(0, cellA.getCellStyle().getFillPattern());
+ assertEquals("0:0:0", p.getColor((short)64).getHexString());
+ assertEquals(null, p.getColor((short)32767));
+
+ // Red
+ assertEquals("I'm red", cellB.getStringCellValue());
+ assertEquals(64, cellB.getCellStyle().getFillForegroundColor());
+ assertEquals(64, cellB.getCellStyle().getFillBackgroundColor());
+ assertEquals(10, cellB.getCellStyle().getFont(book).getColor());
+ assertEquals(0, cellB.getCellStyle().getFillPattern());
+ assertEquals("0:0:0", p.getColor((short)64).getHexString());
+ assertEquals("FFFF:0:0", p.getColor((short)10).getHexString());
+
+ // Red + green bg
+ assertEquals("I'm red with a green bg", cellC.getStringCellValue());
+ assertEquals(11, cellC.getCellStyle().getFillForegroundColor());
+ assertEquals(64, cellC.getCellStyle().getFillBackgroundColor());
+ assertEquals(10, cellC.getCellStyle().getFont(book).getColor());
+ assertEquals(1, cellC.getCellStyle().getFillPattern());
+ assertEquals("0:FFFF:0", p.getColor((short)11).getHexString());
+ assertEquals("FFFF:0:0", p.getColor((short)10).getHexString());
+
+ // Pink with yellow
+ assertEquals("I'm pink with a yellow pattern (none)", cellD.getStringCellValue());
+ assertEquals(13, cellD.getCellStyle().getFillForegroundColor());
+ assertEquals(64, cellD.getCellStyle().getFillBackgroundColor());
+ assertEquals(14, cellD.getCellStyle().getFont(book).getColor());
+ assertEquals(0, cellD.getCellStyle().getFillPattern());
+ assertEquals("FFFF:FFFF:0", p.getColor((short)13).getHexString());
+ assertEquals("FFFF:0:FFFF", p.getColor((short)14).getHexString());
+
+ // Pink with yellow - full
+ assertEquals("I'm pink with a yellow pattern (full)", cellE.getStringCellValue());
+ assertEquals(13, cellE.getCellStyle().getFillForegroundColor());
+ assertEquals(64, cellE.getCellStyle().getFillBackgroundColor());
+ assertEquals(14, cellE.getCellStyle().getFont(book).getColor());
+ assertEquals(0, cellE.getCellStyle().getFillPattern());
+ assertEquals("FFFF:FFFF:0", p.getColor((short)13).getHexString());
+ assertEquals("FFFF:0:FFFF", p.getColor((short)14).getHexString());
+ }
+
/**
* Verifies that the generated gnumeric-format string values match the
* hardcoded values in the HSSFColor default color palette
//System.out.println("first assertion for date");
assertEquals(new GregorianCalendar(2000, 0, 1, 10, 51, 2).getTime(),
HSSFDateUtil
- .getJavaDate(firstCell.getNumericCellValue()));
+ .getJavaDate(firstCell.getNumericCellValue(), false));
HSSFRow row = sheet.createRow(( short ) 15);
HSSFCell cell = row.createCell(( short ) 1);
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.poi.hssf.usermodel;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for how HSSFWorkbook behaves with XLS files
+ * with a WORKBOOK directory entry (instead of the more
+ * usual, Workbook)
+ */
+public class TestSheetHiding extends TestCase {
+ private String dirPath;
+ private String xlsHidden = "TwoSheetsOneHidden.xls";
+ private String xlsShown = "TwoSheetsNoneHidden.xls";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ dirPath = System.getProperty("HSSF.testdata.path");
+ }
+
+ /**
+ * Test that we get the right number of sheets,
+ * with the right text on them, no matter what
+ * the hidden flags are
+ */
+ public void testTextSheets() throws Exception {
+ FileInputStream isH = new FileInputStream(dirPath + "/" + xlsHidden);
+ POIFSFileSystem fsH = new POIFSFileSystem(isH);
+
+ FileInputStream isU = new FileInputStream(dirPath + "/" + xlsShown);
+ POIFSFileSystem fsU = new POIFSFileSystem(isU);
+
+ HSSFWorkbook wbH = new HSSFWorkbook(fsH);
+ HSSFWorkbook wbU = new HSSFWorkbook(fsU);
+
+ // Both should have two sheets
+ assertEquals(2, wbH.sheets.size());
+ assertEquals(2, wbU.sheets.size());
+
+ // All sheets should have one row
+ assertEquals(0, wbH.getSheetAt(0).getLastRowNum());
+ assertEquals(0, wbH.getSheetAt(1).getLastRowNum());
+ assertEquals(0, wbU.getSheetAt(0).getLastRowNum());
+ assertEquals(0, wbU.getSheetAt(1).getLastRowNum());
+
+ // All rows should have one column
+ assertEquals(1, wbH.getSheetAt(0).getRow(0).getLastCellNum());
+ assertEquals(1, wbH.getSheetAt(1).getRow(0).getLastCellNum());
+ assertEquals(1, wbU.getSheetAt(0).getRow(0).getLastCellNum());
+ assertEquals(1, wbU.getSheetAt(1).getRow(0).getLastCellNum());
+
+ // Text should be sheet based
+ assertEquals("Sheet1A1", wbH.getSheetAt(0).getRow(0).getCell((short)0).getStringCellValue());
+ assertEquals("Sheet2A1", wbH.getSheetAt(1).getRow(0).getCell((short)0).getStringCellValue());
+ assertEquals("Sheet1A1", wbU.getSheetAt(0).getRow(0).getCell((short)0).getStringCellValue());
+ assertEquals("Sheet2A1", wbU.getSheetAt(1).getRow(0).getCell((short)0).getStringCellValue());
+ }
+
+ /**
+ * Check that we can get and set the hidden flags
+ * as expected
+ */
+ public void testHideUnHideFlags() throws Exception {
+ // TODO
+ }
+
+ /**
+ * Turn the sheet with none hidden into the one with
+ * one hidden
+ */
+ public void testHide() throws Exception {
+ // TODO
+ }
+
+ /**
+ * Turn the sheet with one hidden into the one with
+ * none hidden
+ */
+ public void testUnHide() throws Exception {
+ // TODO
+ }
+}
import junit.framework.TestCase;
+import org.apache.poi.util.IOUtils;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.poifs.filesystem.POIFSWriterEvent;
import org.apache.poi.poifs.filesystem.POIFSWriterListener;
fs.writeFilesystem(out);
new POIFSFileSystem(new ByteArrayInputStream(out.toByteArray()));
}
+
+ public void testEmptyDocumentBug11744() throws Exception {
+ byte[] testData = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+ POIFSFileSystem fs = new POIFSFileSystem();
+ fs.createDocument(new ByteArrayInputStream(new byte[0]), "Empty");
+ fs.createDocument(new ByteArrayInputStream(testData), "NotEmpty");
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ fs.writeFilesystem(out);
+ out.toByteArray();
+
+ // This line caused the error.
+ fs = new POIFSFileSystem(new ByteArrayInputStream(out.toByteArray()));
+
+ DocumentEntry entry = (DocumentEntry) fs.getRoot().getEntry("Empty");
+ assertEquals("Expected zero size", 0, entry.getSize());
+ assertEquals("Expected zero read from stream", 0,
+ IOUtils.toByteArray(new DocumentInputStream(entry)).length);
+
+ entry = (DocumentEntry) fs.getRoot().getEntry("NotEmpty");
+ assertEquals("Expected size was wrong", testData.length, entry.getSize());
+ assertEquals("Expected different data read from stream", testData,
+ IOUtils.toByteArray(new DocumentInputStream(entry)));
+ }
}