mirror of https://github.com/apache/poi.git
merge trunk
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/hemf@1843032 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
commit
1f93a366f5
|
@ -28,8 +28,8 @@
|
|||
<classpathentry kind="lib" path="lib/jmh-generator-annprocess-1.19.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry exported="true" kind="lib" path="compile-lib/slf4j-api-1.7.25.jar"/>
|
||||
<classpathentry kind="lib" path="compile-lib/bcpkix-jdk15on-1.59.jar"/>
|
||||
<classpathentry kind="lib" path="compile-lib/bcprov-ext-jdk15on-1.59.jar"/>
|
||||
<classpathentry kind="lib" path="compile-lib/bcpkix-jdk15on-1.60.jar"/>
|
||||
<classpathentry kind="lib" path="compile-lib/bcprov-ext-jdk15on-1.60.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="compile-lib/xmlsec-2.1.0.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/commons-codec-1.11.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/commons-logging-1.2.jar"/>
|
||||
|
|
|
@ -159,8 +159,6 @@ subprojects {
|
|||
}
|
||||
}
|
||||
|
||||
// japicmp will fail with "Could not load" because we moved some classes out of the root-package
|
||||
// for Java 9 compatibility in 4.0.0
|
||||
task(japicmp, type: me.champeau.gradle.ArtifactJapicmpTask, dependsOn: jar) {
|
||||
to = jar.archivePath
|
||||
onlyModified = true
|
||||
|
@ -187,6 +185,7 @@ project('main') {
|
|||
compile 'javax.activation:activation:1.1.1'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.reflections:reflections:0.9.11'
|
||||
}
|
||||
|
||||
jar {
|
||||
|
@ -231,7 +230,7 @@ project('ooxml') {
|
|||
compile 'org.apache.commons:commons-math3:3.6.1'
|
||||
compile 'org.apache.commons:commons-compress:1.18'
|
||||
compile 'org.apache.santuario:xmlsec:2.1.0'
|
||||
compile 'org.bouncycastle:bcpkix-jdk15on:1.59'
|
||||
compile 'org.bouncycastle:bcpkix-jdk15on:1.60'
|
||||
compile 'com.github.virtuald:curvesapi:1.05'
|
||||
|
||||
// for ooxml-lite, should we move this somewhere else?
|
||||
|
@ -245,6 +244,7 @@ project('ooxml') {
|
|||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-core:2.21.0'
|
||||
testCompile 'org.xmlunit:xmlunit-core:2.5.1'
|
||||
testCompile 'org.reflections:reflections:0.9.11'
|
||||
testCompile project(path: ':main', configuration: 'tests')
|
||||
testCompile 'org.openjdk.jmh:jmh-core:1.19'
|
||||
testCompile 'org.openjdk.jmh:jmh-generator-annprocess:1.19'
|
||||
|
|
147
build.xml
147
build.xml
|
@ -52,6 +52,7 @@ under the License.
|
|||
|
||||
<property name="main.lib" location="lib"/>
|
||||
<property name="ooxml.lib" location="ooxml-lib"/>
|
||||
<property name="ooxml.test.lib" location="ooxml-testlib"/>
|
||||
<property name="compile.lib" location="compile-lib"/>
|
||||
|
||||
<!-- compiler options options -->
|
||||
|
@ -201,14 +202,14 @@ under the License.
|
|||
<!-- xml signature libs -->
|
||||
<property name="dsig.xmlsec.jar" location="${compile.lib}/xmlsec-2.1.0.jar"/>
|
||||
<property name="dsig.xmlsec.url" value="${repository.m2}/maven2/org/apache/santuario/xmlsec/2.1.0/xmlsec-2.1.0.jar"/>
|
||||
<property name="dsig.bouncycastle-prov.jar" location="${compile.lib}/bcprov-ext-jdk15on-1.59.jar"/>
|
||||
<property name="dsig.bouncycastle-prov.url" value="${repository.m2}/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.59/bcprov-ext-jdk15on-1.59.jar"/>
|
||||
<property name="dsig.bouncycastle-pkix.jar" location="${compile.lib}/bcpkix-jdk15on-1.59.jar"/>
|
||||
<property name="dsig.bouncycastle-pkix.url" value="${repository.m2}/maven2/org/bouncycastle/bcpkix-jdk15on/1.59/bcpkix-jdk15on-1.59.jar"/>
|
||||
<property name="dsig.bouncycastle-prov.jar" location="${compile.lib}/bcprov-ext-jdk15on-1.60.jar"/>
|
||||
<property name="dsig.bouncycastle-prov.url" value="${repository.m2}/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.60/bcprov-ext-jdk15on-1.60.jar"/>
|
||||
<property name="dsig.bouncycastle-pkix.jar" location="${compile.lib}/bcpkix-jdk15on-1.60.jar"/>
|
||||
<property name="dsig.bouncycastle-pkix.url" value="${repository.m2}/maven2/org/bouncycastle/bcpkix-jdk15on/1.60/bcpkix-jdk15on-1.60.jar"/>
|
||||
<property name="dsig.sl4j-api.jar" location="${compile.lib}/slf4j-api-1.7.25.jar"/>
|
||||
<property name="dsig.sl4j-api.url" value="${repository.m2}/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar"/>
|
||||
|
||||
<!-- jars in the lib-ooxml directory, see the fetch-ooxml-jars target-->
|
||||
<!-- jars in the ooxml-lib directory, see the fetch-ooxml-jars target-->
|
||||
<property name="ooxml.curvesapi.jar" location="${ooxml.lib}/curvesapi-1.05.jar"/>
|
||||
<property name="ooxml.curvesapi.url"
|
||||
value="${repository.m2}/maven2/com/github/virtuald/curvesapi/1.05/curvesapi-1.05.jar"/>
|
||||
|
@ -219,6 +220,17 @@ under the License.
|
|||
<property name="ooxml.commons-compress.url"
|
||||
value="${repository.m2}/maven2/org/apache/commons/commons-compress/1.18/commons-compress-1.18.jar"/>
|
||||
|
||||
<!-- jars in the ooxml-test-lib directory, see the fetch-ooxml-jars target-->
|
||||
<property name="ooxml.test.reflections.jar" location="${ooxml.test.lib}/reflections.jar"/>
|
||||
<property name="ooxml.test.reflections.url"
|
||||
value="${repository.m2}/maven2/org/reflections/reflections/0.9.11/reflections-0.9.11.jar"/>
|
||||
<property name="ooxml.test.guava.jar" location="${ooxml.test.lib}/guava.jar"/>
|
||||
<property name="ooxml.test.guava.url"
|
||||
value="${repository.m2}/maven2/com/google/guava/guava/20.0/guava-20.0.jar"/>
|
||||
<property name="ooxml.test.javassist.jar" location="${ooxml.test.lib}/javassist.jar"/>
|
||||
<property name="ooxml.test.javassist.url"
|
||||
value="${repository.m2}/maven2/org/javassist/javassist/3.21.0-GA/javassist-3.21.0-GA.jar"/>
|
||||
|
||||
<!-- coverage libs -->
|
||||
<property name="jacoco.zip" location="${main.lib}/jacoco-0.8.2.zip"/>
|
||||
<property name="jacoco.url" value="${repository.m2}/maven2/org/jacoco/jacoco/0.8.2/jacoco-0.8.2.zip"/>
|
||||
|
@ -232,8 +244,8 @@ under the License.
|
|||
<!-- license and api checks -->
|
||||
<property name="rat.jar" location="${main.lib}/apache-rat-0.12.jar"/>
|
||||
<property name="rat.url" value="${repository.m2}/maven2/org/apache/rat/apache-rat/0.12/apache-rat-0.12.jar"/>
|
||||
<property name="forbidden.jar" location="${main.lib}/forbiddenapis-2.5.jar"/>
|
||||
<property name="forbidden.url" value="${repository.m2}/maven2/de/thetaphi/forbiddenapis/2.5/forbiddenapis-2.5.jar"/>
|
||||
<property name="forbidden.jar" location="${main.lib}/forbiddenapis-2.6.jar"/>
|
||||
<property name="forbidden.url" value="${repository.m2}/maven2/de/thetaphi/forbiddenapis/2.6/forbiddenapis-2.6.jar"/>
|
||||
|
||||
<property name="maven.ooxml.xsds.version.id" value="1.4"/>
|
||||
|
||||
|
@ -282,10 +294,10 @@ under the License.
|
|||
<property name="halt.on.test.failure" value="true"/>
|
||||
|
||||
<!-- helper jars for pgp signing, building and nexus staging -->
|
||||
<property name="dist.bouncycastle-prov.jar" location="${compile.lib}/bcprov-ext-jdk15on-1.59.jar"/>
|
||||
<property name="dist.bouncycastle-prov.url" value="${repository.m2}/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.59/bcprov-ext-jdk15on-1.59.jar"/>
|
||||
<property name="dist.bouncycastle-bcpg.jar" location="${compile.lib}/bcpg-jdk15on-1.59.jar"/>
|
||||
<property name="dist.bouncycastle-bcpg.url" value="${repository.m2}/maven2/org/bouncycastle/bcpg-jdk15on/1.59/bcpg-jdk15on-1.59.jar"/>
|
||||
<property name="dist.bouncycastle-prov.jar" location="${compile.lib}/bcprov-ext-jdk15on-1.60.jar"/>
|
||||
<property name="dist.bouncycastle-prov.url" value="${repository.m2}/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.60/bcprov-ext-jdk15on-1.60.jar"/>
|
||||
<property name="dist.bouncycastle-bcpg.jar" location="${compile.lib}/bcpg-jdk15on-1.60.jar"/>
|
||||
<property name="dist.bouncycastle-bcpg.url" value="${repository.m2}/maven2/org/bouncycastle/bcpg-jdk15on/1.60/bcpg-jdk15on-1.60.jar"/>
|
||||
<property name="dist.commons-openpgp.jar" location="${compile.lib}/commons-openpgp-1.0-SNAPSHOT.jar"/>
|
||||
<property name="dist.commons-openpgp.url" value="https://repository.apache.org/snapshots/org/apache/commons/commons-openpgp/1.0-SNAPSHOT/commons-openpgp-1.0-20140717.171036-11.jar"/>
|
||||
<property name="dist.nexus-staging.jar" location="${compile.lib}/nexus-staging-ant-tasks-1.6.3-uber.jar"/>
|
||||
|
@ -416,10 +428,17 @@ under the License.
|
|||
<pathelement location="${additionaljar}"/>
|
||||
</path>
|
||||
|
||||
<path id="test.ooxml.reflections.classpath">
|
||||
<pathelement location="${ooxml.test.reflections.jar}"/>
|
||||
<pathelement location="${ooxml.test.guava.jar}"/>
|
||||
<pathelement location="${ooxml.test.javassist.jar}"/>
|
||||
</path>
|
||||
|
||||
<path id="test.ooxml.classpath">
|
||||
<path refid="ooxml.classpath"/>
|
||||
<path refid="ooxml.xmlsec.classpath"/>
|
||||
<path refid="test.jar.classpath"/>
|
||||
<path refid="test.ooxml.reflections.classpath"/>
|
||||
<pathelement location="${ooxml.output.dir}"/>
|
||||
<pathelement location="${ooxml.output.test.dir}"/>
|
||||
<pathelement location="${main.output.test.dir}"/>
|
||||
|
@ -484,6 +503,7 @@ under the License.
|
|||
<path refid="scratchpad.classpath"/>
|
||||
<path refid="ooxml.classpath"/>
|
||||
<path refid="ooxml.xmlsec.classpath"/>
|
||||
<path refid="test.ooxml.reflections.classpath"/>
|
||||
<path refid="excelant.classpath"/>
|
||||
<path refid="examples.classpath"/>
|
||||
<pathelement location="${examples.output.dir}"/>
|
||||
|
@ -582,6 +602,7 @@ under the License.
|
|||
<mkdir dir="${main.lib}"/>
|
||||
<mkdir dir="${compile.lib}"/>
|
||||
<mkdir dir="${ooxml.lib}"/>
|
||||
<mkdir dir="${ooxml.test.lib}"/>
|
||||
<delete verbose="true">
|
||||
<fileset dir="${main.lib}">
|
||||
<include name="ant-1.8*"/>
|
||||
|
@ -631,6 +652,7 @@ under the License.
|
|||
<include name="forbiddenapis-2.0.jar"/>
|
||||
<include name="forbiddenapis-2.1.jar"/>
|
||||
<include name="forbiddenapis-2.3.jar"/>
|
||||
<include name="forbiddenapis-2.5.jar"/>
|
||||
<include name="apache-rat-0.11.jar"/>
|
||||
<include name="mockito-core-2.13.0.jar"/>
|
||||
</fileset>
|
||||
|
@ -655,10 +677,7 @@ under the License.
|
|||
<include name="xmlsec-2.0.1.jar"/>
|
||||
<include name="xmlsec-2.0.5.jar"/>
|
||||
<include name="xmlsec-2.0.6.jar"/>
|
||||
<include name="bc*jdk15on-1.51.jar"/>
|
||||
<include name="bc*jdk15on-1.53.jar"/>
|
||||
<include name="bc*jdk15on-1.54.jar"/>
|
||||
<include name="bc*jdk15on-1.58.jar"/>
|
||||
<include name="bc*jdk15on-1.5*.jar"/>
|
||||
<include name="slf4j-api-1.7.7.jar"/>
|
||||
<include name="slf4j-api-1.7.12.jar"/>
|
||||
</fileset>
|
||||
|
@ -753,6 +772,9 @@ under the License.
|
|||
<available file="${ooxml.curvesapi.jar}"/>
|
||||
<available file="${ooxml.xmlbeans.jar}"/>
|
||||
<available file="${ooxml.commons-compress.jar}"/>
|
||||
<available file="${ooxml.test.reflections.jar}"/>
|
||||
<available file="${ooxml.test.guava.jar}"/>
|
||||
<available file="${ooxml.test.javassist.jar}"/>
|
||||
</and>
|
||||
<isset property="disconnected"/>
|
||||
</or>
|
||||
|
@ -760,9 +782,13 @@ under the License.
|
|||
</target>
|
||||
<target name="fetch-ooxml-jars" depends="check-ooxml-jars" unless="ooxml.jars.present">
|
||||
<mkdir dir="${ooxml.lib}"/>
|
||||
<mkdir dir="${ooxml.test.lib}"/>
|
||||
<downloadfile src="${ooxml.curvesapi.url}" dest="${ooxml.curvesapi.jar}"/>
|
||||
<downloadfile src="${ooxml.xmlbeans.url}" dest="${ooxml.xmlbeans.jar}"/>
|
||||
<downloadfile src="${ooxml.commons-compress.url}" dest="${ooxml.commons-compress.jar}"/>
|
||||
<downloadfile src="${ooxml.test.reflections.url}" dest="${ooxml.test.reflections.jar}"/>
|
||||
<downloadfile src="${ooxml.test.guava.url}" dest="${ooxml.test.guava.jar}"/>
|
||||
<downloadfile src="${ooxml.test.javassist.url}" dest="${ooxml.test.javassist.jar}"/>
|
||||
</target>
|
||||
<target name="check-svn-jars">
|
||||
<condition property="svn.jars.present">
|
||||
|
@ -2045,6 +2071,7 @@ under the License.
|
|||
<include name="commons-codec-*.jar"/>
|
||||
<include name="commons-logging-*.jar"/>
|
||||
<include name="commons-collections4-*.jar"/>
|
||||
<include name="commons-compress*.jar"/>
|
||||
<include name="commons-math3-*.jar"/>
|
||||
<include name="jaxb-api-*.jar"/>
|
||||
<include name="jaxb-impl-*.jar"/>
|
||||
|
@ -2753,13 +2780,20 @@ under the License.
|
|||
project.setProperty(attributes.get("property"), mega);
|
||||
</scriptdef>
|
||||
|
||||
<macrodef name="loadFilesize">
|
||||
<attribute name="url"/>
|
||||
<attribute name="property"/>
|
||||
<macrodef name="download-line">
|
||||
<attribute name="prop"/>
|
||||
<attribute name="dist"/>
|
||||
<attribute name="pack"/>
|
||||
<sequential>
|
||||
<local name="baseurl"/>
|
||||
<property name="baseurl" value="https://www.apache.org/dist/poi/release"/>
|
||||
|
||||
<local name="basedyn"/>
|
||||
<property name="basedyn" value="https://www.apache.org/dyn/closer.lua/poi/release"/>
|
||||
|
||||
<delete file="build/loadFilesize.txt"/>
|
||||
<record name="build/loadFilesize.txt" action="start" loglevel="verbose" append="false"/>
|
||||
<http url="@{url}" method="HEAD" expected="200" printrequestheaders="false" printresponseheaders="false"/>
|
||||
<http url="${baseurl}/@{dist}/poi-@{dist}-${version.id}-${file_date}.@{pack}" method="HEAD" expected="200" printrequestheaders="false" printresponseheaders="false"/>
|
||||
<record name="build/loadFilesize.txt" action="stop"/>
|
||||
<local name="fileSize"/>
|
||||
<loadfile property="fileSize" srcFile="build/loadFilesize.txt">
|
||||
|
@ -2770,7 +2804,16 @@ under the License.
|
|||
</tokenfilter>
|
||||
</filterchain>
|
||||
</loadfile>
|
||||
<bytes2mega property="@{property}" bytes="${fileSize}"/>
|
||||
|
||||
<local name="fileSizeMb"/>
|
||||
<bytes2mega property="fileSizeMb" bytes="${fileSize}"/>
|
||||
|
||||
<property name="@{prop}"><![CDATA[<li>
|
||||
<a href="${basedyn}/@{dist}/poi-@{dist}-${version.id}-${file_date}.@{pack}">poi-@{dist}-${version.id}-${file_date}.@{pack}</a>
|
||||
(${fileSizeMb} MB, <a href="${baseurl}/@{dist}/poi-@{dist}-${version.id}-${file_date}.@{pack}.asc">signature (.asc)</a>,
|
||||
checksum: <a href="${baseurl}/@{dist}/poi-@{dist}-${version.id}-${file_date}.@{pack}.sha256">SHA-256</a>,
|
||||
<a href="${baseurl}/@{dist}/poi-@{dist}-${version.id}-${file_date}.@{pack}.sha512">SHA-512</a>)
|
||||
</li>]]></property>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
|
@ -2795,23 +2838,17 @@ under the License.
|
|||
<format property="rel_date" pattern="dd MMMM yyyy" locale="US"/>
|
||||
<format property="file_date" pattern="yyyyMMdd" locale="US"/>
|
||||
</tstamp>
|
||||
<property name="baseurl" value="https://www.apache.org/dist/poi/release"/>
|
||||
|
||||
<loadChecksum property="bin-tar-sha256" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.tar.gz.sha256"/>
|
||||
<loadChecksum property="bin-tar-sha512" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.tar.gz.sha512"/>
|
||||
<loadChecksum property="bin-zip-sha256" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.zip.sha256"/>
|
||||
<loadChecksum property="bin-zip-sha512" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.zip.sha512"/>
|
||||
<loadChecksum property="src-tar-sha256" url="${baseurl}/src/poi-src-${version.id}-${file_date}.tar.gz.sha256"/>
|
||||
<loadChecksum property="src-tar-sha512" url="${baseurl}/src/poi-src-${version.id}-${file_date}.tar.gz.sha512"/>
|
||||
<loadChecksum property="src-zip-sha256" url="${baseurl}/src/poi-src-${version.id}-${file_date}.zip.sha256"/>
|
||||
<loadChecksum property="src-zip-sha512" url="${baseurl}/src/poi-src-${version.id}-${file_date}.zip.sha512"/>
|
||||
<local name="li1"/>
|
||||
<local name="li2"/>
|
||||
<local name="li3"/>
|
||||
<local name="li4"/>
|
||||
<download-line prop="li1" dist="bin" pack="tar.gz"/>
|
||||
<download-line prop="li2" dist="bin" pack="zip"/>
|
||||
<download-line prop="li3" dist="src" pack="tar.gz"/>
|
||||
<download-line prop="li4" dist="src" pack="zip"/>
|
||||
|
||||
<loadFilesize property="bin-tar-size" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.tar.gz"/>
|
||||
<loadFilesize property="bin-zip-size" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.zip"/>
|
||||
<loadFilesize property="src-tar-size" url="${baseurl}/src/poi-src-${version.id}-${file_date}.tar.gz"/>
|
||||
<loadFilesize property="src-zip-size" url="${baseurl}/src/poi-src-${version.id}-${file_date}.zip"/>
|
||||
|
||||
<echo file="download-snipplet.xml"><![CDATA[
|
||||
<echo file="download-snipplet.xml"><![CDATA[
|
||||
<section id="POI-${version.id}"><title>${rel_date} - POI ${version.id} available</title>
|
||||
<p>The Apache POI team is pleased to announce the release of ${version.id}.
|
||||
Featured are a handful of new areas of functionality and numerous bug fixes.</p>
|
||||
|
@ -2828,46 +2865,14 @@ under the License.
|
|||
</p>
|
||||
<section id="POI-${version.id}-bin"><title>Binary Distribution</title>
|
||||
<ul>
|
||||
<li><a href="https://www.apache.org/dyn/closer.lua/poi/release/bin/poi-bin-${version.id}-${file_date}.tar.gz">poi-bin-${version.id}-${file_date}.tar.gz</a>
|
||||
(${bin-tar-size} MB, <a href="https://www.apache.org/dist/poi/release/bin/poi-bin-${version.id}-${file_date}.tar.gz.asc">signature (.asc)</a>)
|
||||
<br/>
|
||||
SHA256 checksum: <a href="https://www.apache.org/dist/poi/release/bin/poi-bin-${version.id}-${file_date}.tar.gz.sha256">
|
||||
${bin-tar-sha256}</a>
|
||||
<br/>
|
||||
SHA512 checksum: <a href="https://www.apache.org/dist/poi/release/bin/poi-bin-${version.id}-${file_date}.tar.gz.sha512">
|
||||
${bin-tar-sha512}</a>
|
||||
</li>
|
||||
<li><a href="https://www.apache.org/dyn/closer.lua/poi/release/bin/poi-bin-${version.id}-${file_date}.zip">poi-bin-${version.id}-${file_date}.zip</a>
|
||||
(${bin-zip-size} MB, <a href="https://www.apache.org/dist/poi/release/bin/poi-bin-${version.id}-${file_date}.zip.asc">signature (.asc)</a>)
|
||||
<br/>
|
||||
SHA256 checksum: <a href="https://www.apache.org/dist/poi/release/bin/poi-bin-${version.id}-${file_date}.zip.sha256">
|
||||
${bin-zip-sha256}</a>
|
||||
<br/>
|
||||
SHA512 checksum: <a href="https://www.apache.org/dist/poi/release/bin/poi-bin-${version.id}-${file_date}.zip.sha512">
|
||||
${bin-zip-sha512}</a>
|
||||
</li>
|
||||
${li1}
|
||||
${li2}
|
||||
</ul>
|
||||
</section>
|
||||
<section id="POI-${version.id}-src"><title>Source Distribution</title>
|
||||
<ul>
|
||||
<li><a href="https://www.apache.org/dyn/closer.lua/poi/release/src/poi-src-${version.id}-${file_date}.tar.gz">poi-src-${version.id}-${file_date}.tar.gz</a>
|
||||
(${src-tar-size} MB, <a href="https://www.apache.org/dist/poi/release/src/poi-src-${version.id}-${file_date}.tar.gz.asc">signature (.asc)</a>)
|
||||
<br/>
|
||||
SHA256 checksum: <a href="https://www.apache.org/dist/poi/release/src/poi-src-${version.id}-${file_date}.tar.gz.sha256">
|
||||
${src-tar-sha256}</a>
|
||||
<br/>
|
||||
SHA512 checksum: <a href="https://www.apache.org/dist/poi/release/src/poi-src-${version.id}-${file_date}.tar.gz.sha512">
|
||||
${src-tar-sha512}</a>
|
||||
</li>
|
||||
<li><a href="https://www.apache.org/dyn/closer.lua/poi/release/src/poi-src-${version.id}-${file_date}.zip">poi-src-${version.id}-${file_date}.zip</a>
|
||||
(${src-zip-size} MB, <a href="https://www.apache.org/dist/poi/release/src/poi-src-${version.id}-${file_date}.zip.asc">signature (.asc)</a>)
|
||||
<br/>
|
||||
SHA256 checksum: <a href="https://www.apache.org/dist/poi/release/src/poi-src-${version.id}-${file_date}.zip.sha256">
|
||||
${src-zip-sha256}</a>
|
||||
<br/>
|
||||
SHA512 checksum: <a href="https://www.apache.org/dist/poi/release/src/poi-src-${version.id}-${file_date}.zip.sha512">
|
||||
${src-zip-sha512}</a>
|
||||
</li>
|
||||
${li3}
|
||||
${li4}
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -25,19 +25,6 @@ def poijobs = [
|
|||
// the JDK is missing on some slaves so builds are unstable
|
||||
skipcigame: true
|
||||
],
|
||||
[ name: 'POI-DSL-1.9', jdk: '1.9', trigger: triggerSundays,
|
||||
properties: ['-Djava9addmods=--add-modules=java.xml.bind',
|
||||
'-Djavadoc9addmods=--add-modules=java.xml.bind',
|
||||
'-Djava9addmodsvalue=-Dsun.reflect.debugModuleAccessChecks=true',
|
||||
'-Djava9addopens1=--add-opens=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED',
|
||||
'-Djava9addopens2=--add-opens=java.base/java.io=ALL-UNNAMED',
|
||||
'-Djava9addopens3=--add-opens=java.base/java.nio=ALL-UNNAMED',
|
||||
'-Djava9addopens4=--add-opens=java.base/java.lang=ALL-UNNAMED',
|
||||
'-Djava9addopens5=--add-opens=java.base/jdk.internal.ref=ALL-UNNAMED',
|
||||
'-Djava9addopens6=--add-opens=java.base/java.lang=java.xml.bind',
|
||||
'-Djava.locale.providers=JRE,CLDR'],
|
||||
skipcigame: true
|
||||
],
|
||||
[ name: 'POI-DSL-1.10', jdk: '1.10', trigger: triggerSundays,
|
||||
properties: ['-Djava9addmods=--add-modules=java.xml.bind',
|
||||
'-Djavadoc9addmods=--add-modules=java.xml.bind',
|
||||
|
@ -114,7 +101,14 @@ def poijobs = [
|
|||
],
|
||||
]
|
||||
|
||||
def xmlbeansjobs = [
|
||||
[ name: 'POI-XMLBeans-DSL-1.6', jdk: '1.6', trigger: 'H */12 * * *', skipcigame: true
|
||||
]
|
||||
]
|
||||
|
||||
def svnBase = 'https://svn.apache.org/repos/asf/poi/trunk'
|
||||
def xmlbeansSvnBase = 'https://svn.apache.org/repos/asf/xmlbeans/trunk'
|
||||
|
||||
def defaultJdk = '1.8'
|
||||
def defaultTrigger = 'H/15 * * * *' // check SCM every 60/15 = 4 minutes
|
||||
def defaultEmail = 'dev@poi.apache.org'
|
||||
|
@ -123,8 +117,8 @@ def defaultAnt = 'Ant 1.9.9'
|
|||
def defaultSlaves = '(ubuntu||beam)&&!cloud-slave&&!H15&&!H17&&!H18&&!H24&&!ubuntu-4&&!H21'
|
||||
|
||||
def jdkMapping = [
|
||||
'1.6': 'JDK 1.6 (latest)',
|
||||
'1.8': 'JDK 1.8 (latest)',
|
||||
'1.9': 'JDK 1.9 (latest)',
|
||||
'1.10': 'JDK 10 (latest)',
|
||||
'1.11': 'JDK 11 (latest)',
|
||||
'1.12': 'JDK 12 (latest)',
|
||||
|
@ -141,7 +135,7 @@ static def shellEx(def context, String cmd, def poijob) {
|
|||
}
|
||||
|
||||
def defaultDesc = '''
|
||||
<img src="https://poi.apache.org/resources/images/project-logo.jpg" />
|
||||
<img src="https://poi.apache.org/images/project-header.png" />
|
||||
<p>
|
||||
Apache POI - the Java API for Microsoft Documents
|
||||
</p>
|
||||
|
@ -233,7 +227,7 @@ poijobs.each { poijob ->
|
|||
label(slaves)
|
||||
environmentVariables {
|
||||
env('LANG', 'en_US.UTF-8')
|
||||
if(jdkKey == '1.9' || jdkKey == '1.10') {
|
||||
if(jdkKey == '1.10') {
|
||||
// when using JDK 9/10 for running Ant, we need to provide more modules for the forbidden-api-checks task
|
||||
// on JDK 11 and newer there is no such module any more, so do not add it here
|
||||
env('ANT_OPTS', '--add-modules=java.xml.bind --add-opens=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED')
|
||||
|
@ -442,6 +436,92 @@ poijobs.each { poijob ->
|
|||
}
|
||||
}
|
||||
|
||||
xmlbeansjobs.each { xjob ->
|
||||
def jdkKey = xjob.jdk ?: defaultJdk
|
||||
def trigger = xjob.trigger ?: defaultTrigger
|
||||
def email = xjob.email ?: defaultEmail
|
||||
def slaves = xjob.slaves ?: defaultSlaves + (xjob.slaveAdd ?: '')
|
||||
def antRT = defaultAnt + (xjob.windows ? ' (Windows)' : '')
|
||||
|
||||
job(xjob.name) {
|
||||
if (xjob.disabled) {
|
||||
disabled()
|
||||
}
|
||||
|
||||
description( defaultDesc + (xjob.apicheck ? apicheckDesc : sonarDesc) )
|
||||
logRotator {
|
||||
numToKeep(5)
|
||||
artifactNumToKeep(1)
|
||||
}
|
||||
label(slaves)
|
||||
environmentVariables {
|
||||
env('LANG', 'en_US.UTF-8')
|
||||
if(jdkKey == '1.10') {
|
||||
// when using JDK 9/10 for running Ant, we need to provide more modules for the forbidden-api-checks task
|
||||
// on JDK 11 and newer there is no such module any more, so do not add it here
|
||||
env('ANT_OPTS', '--add-modules=java.xml.bind --add-opens=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED')
|
||||
}
|
||||
env('FORREST_HOME', xjob.windows ? 'f:\\jenkins\\tools\\forrest\\latest' : '/home/jenkins/tools/forrest/latest')
|
||||
}
|
||||
wrappers {
|
||||
timeout {
|
||||
absolute(180)
|
||||
abortBuild()
|
||||
writeDescription('Build was aborted due to timeout')
|
||||
}
|
||||
}
|
||||
jdk(jdkMapping.get(jdkKey))
|
||||
scm {
|
||||
svn(xmlbeansSvnBase) { svnNode ->
|
||||
svnNode / browser(class: 'hudson.scm.browsers.ViewSVN') /
|
||||
url << 'http://svn.apache.org/viewcvs.cgi/?root=Apache-SVN'
|
||||
}
|
||||
}
|
||||
checkoutRetryCount(3)
|
||||
|
||||
triggers {
|
||||
scm(trigger)
|
||||
}
|
||||
|
||||
def shellcmds = (xjob.windows ? shellCmdsWin : shellCmdsUnix).replace('POIJOBSHELL', xjob.shell ?: '')
|
||||
|
||||
// Create steps and publishers depending on the type of Job that is selected
|
||||
steps {
|
||||
shellEx(delegate, shellcmds, xjob)
|
||||
if(xjob.addShell) {
|
||||
shellEx(delegate, xjob.addShell, xjob)
|
||||
}
|
||||
ant {
|
||||
targets(['clean'])
|
||||
antInstallation(antRT)
|
||||
}
|
||||
ant {
|
||||
targets(['checkintest'])
|
||||
antInstallation(antRT)
|
||||
}
|
||||
ant {
|
||||
targets(['dist'])
|
||||
antInstallation(antRT)
|
||||
}
|
||||
}
|
||||
publishers {
|
||||
archiveArtifacts('build/private/**')
|
||||
//archiveJunit('build/test/reports/*.xml') {
|
||||
// testDataPublishers {
|
||||
// publishTestStabilityData()
|
||||
// }
|
||||
//}
|
||||
|
||||
if (!xjob.skipcigame) {
|
||||
configure { project ->
|
||||
project / publishers << 'hudson.plugins.cigame.GamePublisher' {}
|
||||
}
|
||||
}
|
||||
mailer(email, false, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Add a special job which spans a two-dimensional matrix of all JDKs that we want to use and
|
||||
all slaves that we would like to use and test if the java and ant binaries are available
|
||||
|
@ -471,8 +551,6 @@ Unfortunately we often see builds break because of changes/new machines...'''
|
|||
'OpenJDK 8 (on Ubuntu only) ', // blank is required here until the name in the Jenkins instance is fixed!
|
||||
'IBM 1.8 64-bit (on Ubuntu only)',
|
||||
|
||||
'JDK 1.9 (latest)',
|
||||
|
||||
'JDK 10 (latest)',
|
||||
'JDK 10 b46 (Windows Only)',
|
||||
'OpenJDK 10.0.2 (on Ubuntu only)',
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
<dependency>
|
||||
<groupId>com.github.virtuald</groupId>
|
||||
<artifactId>curvesapi</artifactId>
|
||||
<version>1.04</version>
|
||||
<version>1.05</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -76,7 +76,17 @@
|
|||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.10</version>
|
||||
<version>1.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -91,11 +101,6 @@
|
|||
<scope>test</scope>
|
||||
<version>4.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -12,64 +12,64 @@
|
|||
<packaging>jar</packaging>
|
||||
|
||||
<name>Apache POI OOXML package</name>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- copy sources, resources and tests in place as otherwise Sonar does not pick them up correctly! -->
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>${maven.plugin.resources.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${basedir}/src/main/java</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>../../src/ooxml/java</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>../../src/resources/ooxml</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-tests</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${basedir}/src/test/java</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>../../src/ooxml/testcases</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- clean copied sources afterwards -->
|
||||
<plugin>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- copy sources, resources and tests in place as otherwise Sonar does not pick them up correctly! -->
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>${maven.plugin.resources.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${basedir}/src/main/java</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>../../src/ooxml/java</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>../../src/resources/ooxml</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-tests</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${basedir}/src/test/java</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>../../src/ooxml/testcases</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- clean copied sources afterwards -->
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>${maven.plugin.clean.version}</version>
|
||||
<configuration>
|
||||
|
@ -96,88 +96,94 @@
|
|||
<argLine>@{argLine} -Duser.language=en -Duser.country=US -Xmx1024m -Djava.io.tmpdir=target/tmp -XX:-OmitStackTraceInFastThrow</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>poi-ooxml-schema</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>poi-ooxml-schema-encryption</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>poi-ooxml-schema-security</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>poi-main</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>poi-main</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>poi-main</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlbeans</groupId>
|
||||
<artifactId>xmlbeans</artifactId>
|
||||
<version>${xmlbeans.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.59</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.59</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.santuario</groupId>
|
||||
<artifactId>xmlsec</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.18</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.virtuald</groupId>
|
||||
<artifactId>curvesapi</artifactId>
|
||||
<version>1.05</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlbeans</groupId>
|
||||
<artifactId>xmlbeans</artifactId>
|
||||
<version>${xmlbeans.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.60</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.60</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.santuario</groupId>
|
||||
<artifactId>xmlsec</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.18</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.virtuald</groupId>
|
||||
<artifactId>curvesapi</artifactId>
|
||||
<version>1.05</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>1.19</version>
|
||||
<scope>test</scope>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>1.19</version>
|
||||
<scope>test</scope>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -348,14 +348,16 @@ public void paintBorder(Component c, Graphics g, int x, int y, int width,
|
|||
|
||||
// if there are borders on the west or east then
|
||||
// the second line shouldn't cross them
|
||||
if (westBorder)
|
||||
leftx = x+3;
|
||||
if (westBorder) {
|
||||
leftx = x + 3;
|
||||
}
|
||||
|
||||
if (eastBorder)
|
||||
rightx = width-3;
|
||||
if (eastBorder) {
|
||||
rightx = width - 3;
|
||||
}
|
||||
|
||||
g.drawLine(x,y,width,y);
|
||||
g.drawLine(leftx,y+2,rightx,y+2);
|
||||
g.drawLine(x,y,width,y);
|
||||
g.drawLine(leftx,y+2,rightx,y+2);
|
||||
}
|
||||
|
||||
if (eastBorder &&
|
||||
|
@ -370,11 +372,13 @@ public void paintBorder(Component c, Graphics g, int x, int y, int width,
|
|||
int topy=y;
|
||||
int bottomy=height;
|
||||
|
||||
if (northBorder)
|
||||
topy=y+3;
|
||||
if (northBorder) {
|
||||
topy = y + 3;
|
||||
}
|
||||
|
||||
if (southBorder)
|
||||
bottomy=height-3;
|
||||
if (southBorder) {
|
||||
bottomy = height - 3;
|
||||
}
|
||||
|
||||
g.drawLine(width-1,y,width-1,height);
|
||||
g.drawLine(width-3,topy,width-3,bottomy);
|
||||
|
|
|
@ -53,7 +53,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|||
* Excel Conditional Formatting -- Examples
|
||||
*
|
||||
* <p>
|
||||
* Partly based on the code snippets from
|
||||
* Partly based on the code snippets from
|
||||
* http://www.contextures.com/xlcondformat03.html
|
||||
* </p>
|
||||
*/
|
||||
|
@ -89,7 +89,7 @@ public class ConditionalFormats {
|
|||
|
||||
// print overlapping rule results
|
||||
evaluateRules(wb, "Overlapping");
|
||||
|
||||
|
||||
// Write the output to a file
|
||||
String file = "cf-poi.xls";
|
||||
if(wb instanceof XSSFWorkbook) {
|
||||
|
@ -178,11 +178,11 @@ public class ConditionalFormats {
|
|||
|
||||
sheet.getRow(2).createCell(4).setCellValue("<== Condition 1: Formula Is =$B2>75 (Blue Fill)");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multiple conditional formatting rules can apply to
|
||||
* one cell, some combining, some beating others.
|
||||
* Done in order of the rules added to the
|
||||
* Done in order of the rules added to the
|
||||
* SheetConditionalFormatting object
|
||||
*/
|
||||
static void overlapping(Sheet sheet) {
|
||||
|
@ -210,39 +210,39 @@ public class ConditionalFormats {
|
|||
}
|
||||
sheet.autoSizeColumn(0);
|
||||
sheet.autoSizeColumn(1);
|
||||
|
||||
|
||||
sheet.getRow(1).createCell(3).setCellValue("Even rows are blue");
|
||||
sheet.getRow(2).createCell(3).setCellValue("Multiples of 3 have a grey background");
|
||||
sheet.getRow(4).createCell(3).setCellValue("Multiples of 5 are bold");
|
||||
sheet.getRow(9).createCell(3).setCellValue("Multiples of 10 are red (beats even)");
|
||||
|
||||
|
||||
SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
|
||||
|
||||
|
||||
// Condition 1: Row divides by 10, red (will beat #1)
|
||||
ConditionalFormattingRule rule1 =
|
||||
ConditionalFormattingRule rule1 =
|
||||
sheetCF.createConditionalFormattingRule("MOD(ROW(),10)=0");
|
||||
FontFormatting font1 = rule1.createFontFormatting();
|
||||
font1.setFontColorIndex(IndexedColors.RED.index);
|
||||
|
||||
|
||||
// Condition 2: Row is even, blue
|
||||
ConditionalFormattingRule rule2 =
|
||||
ConditionalFormattingRule rule2 =
|
||||
sheetCF.createConditionalFormattingRule("MOD(ROW(),2)=0");
|
||||
FontFormatting font2 = rule2.createFontFormatting();
|
||||
font2.setFontColorIndex(IndexedColors.BLUE.index);
|
||||
|
||||
|
||||
// Condition 3: Row divides by 5, bold
|
||||
ConditionalFormattingRule rule3 =
|
||||
ConditionalFormattingRule rule3 =
|
||||
sheetCF.createConditionalFormattingRule("MOD(ROW(),5)=0");
|
||||
FontFormatting font3 = rule3.createFontFormatting();
|
||||
font3.setFontStyle(false, true);
|
||||
|
||||
|
||||
// Condition 4: Row divides by 3, grey background
|
||||
ConditionalFormattingRule rule4 =
|
||||
ConditionalFormattingRule rule4 =
|
||||
sheetCF.createConditionalFormattingRule("MOD(ROW(),3)=0");
|
||||
PatternFormatting fill4 = rule4.createPatternFormatting();
|
||||
fill4.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.index);
|
||||
fill4.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
|
||||
|
||||
|
||||
// Apply
|
||||
CellRangeAddress[] regions = {
|
||||
CellRangeAddress.valueOf("A1:F41")
|
||||
|
@ -441,7 +441,7 @@ public class ConditionalFormats {
|
|||
}
|
||||
|
||||
/**
|
||||
* You can use Excel conditional formatting to shade bands of rows on the worksheet.
|
||||
* You can use Excel conditional formatting to shade bands of rows on the worksheet.
|
||||
* In this example, 3 rows are shaded light grey, and 3 are left with no shading.
|
||||
* In the MOD function, the total number of rows in the set of banded rows (6) is entered.
|
||||
*/
|
||||
|
@ -462,7 +462,7 @@ public class ConditionalFormats {
|
|||
sheet.createRow(0).createCell(1).setCellValue("Shade Bands of Rows");
|
||||
sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is =MOD(ROW(),6)<2 (Light Grey Fill)");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Icon Sets / Multi-States allow you to have icons shown which vary
|
||||
* based on the values, eg Red traffic light / Yellow traffic light /
|
||||
|
@ -487,7 +487,7 @@ public class ConditionalFormats {
|
|||
r.createCell(3).setCellValue(10);
|
||||
|
||||
SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
|
||||
|
||||
|
||||
CellRangeAddress[] regions = { CellRangeAddress.valueOf("B1:B4") };
|
||||
ConditionalFormattingRule rule1 =
|
||||
sheetCF.createConditionalFormattingRule(IconSet.GYR_3_TRAFFIC_LIGHTS);
|
||||
|
@ -497,7 +497,7 @@ public class ConditionalFormats {
|
|||
im1.getThresholds()[1].setValue(33d);
|
||||
im1.getThresholds()[2].setRangeType(RangeType.MAX);
|
||||
sheetCF.addConditionalFormatting(regions, rule1);
|
||||
|
||||
|
||||
regions = new CellRangeAddress[] { CellRangeAddress.valueOf("C1:C4") };
|
||||
ConditionalFormattingRule rule2 =
|
||||
sheetCF.createConditionalFormattingRule(IconSet.GYR_3_FLAGS);
|
||||
|
@ -509,7 +509,7 @@ public class ConditionalFormats {
|
|||
im2.getThresholds()[2].setRangeType(RangeType.PERCENT);
|
||||
im2.getThresholds()[2].setValue(67d);
|
||||
sheetCF.addConditionalFormatting(regions, rule2);
|
||||
|
||||
|
||||
regions = new CellRangeAddress[] { CellRangeAddress.valueOf("D1:D4") };
|
||||
ConditionalFormattingRule rule3 =
|
||||
sheetCF.createConditionalFormattingRule(IconSet.GYR_3_SYMBOLS_CIRCLE);
|
||||
|
@ -522,7 +522,7 @@ public class ConditionalFormats {
|
|||
im3.getThresholds()[2].setValue(7d);
|
||||
sheetCF.addConditionalFormatting(regions, rule3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Color Scales / Colour Scales / Colour Gradients allow you shade the
|
||||
* background colour of the cell based on the values, eg from Red to
|
||||
|
@ -533,12 +533,12 @@ public class ConditionalFormats {
|
|||
Row r = sheet.createRow(1);
|
||||
r.createCell(0).setCellValue("Red-Yellow-Green");
|
||||
for (int i=1; i<=7; i++) {
|
||||
r.createCell(i).setCellValue((i-1)*5);
|
||||
r.createCell(i).setCellValue((i-1)*5.0);
|
||||
}
|
||||
r = sheet.createRow(2);
|
||||
r.createCell(0).setCellValue("Red-White-Blue");
|
||||
for (int i=1; i<=9; i++) {
|
||||
r.createCell(i).setCellValue((i-1)*5);
|
||||
r.createCell(i).setCellValue((i-1)*5.0);
|
||||
}
|
||||
r = sheet.createRow(3);
|
||||
r.createCell(0).setCellValue("Blue-Green");
|
||||
|
@ -546,9 +546,9 @@ public class ConditionalFormats {
|
|||
r.createCell(i).setCellValue((i-1));
|
||||
}
|
||||
sheet.setColumnWidth(0, 5000);
|
||||
|
||||
|
||||
SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
|
||||
|
||||
|
||||
CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:H2") };
|
||||
ConditionalFormattingRule rule1 =
|
||||
sheetCF.createConditionalFormattingColorScaleRule();
|
||||
|
@ -561,7 +561,7 @@ public class ConditionalFormats {
|
|||
((ExtendedColor)cs1.getColors()[1]).setARGBHex("FFFFEB84");
|
||||
((ExtendedColor)cs1.getColors()[2]).setARGBHex("FF63BE7B");
|
||||
sheetCF.addConditionalFormatting(regions, rule1);
|
||||
|
||||
|
||||
regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B3:J3") };
|
||||
ConditionalFormattingRule rule2 =
|
||||
sheetCF.createConditionalFormattingColorScaleRule();
|
||||
|
@ -574,7 +574,7 @@ public class ConditionalFormats {
|
|||
((ExtendedColor)cs2.getColors()[1]).setARGBHex("FFFCFCFF");
|
||||
((ExtendedColor)cs2.getColors()[2]).setARGBHex("FF5A8AC6");
|
||||
sheetCF.addConditionalFormatting(regions, rule2);
|
||||
|
||||
|
||||
regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B4:Q4") };
|
||||
ConditionalFormattingRule rule3=
|
||||
sheetCF.createConditionalFormattingColorScaleRule();
|
||||
|
@ -586,7 +586,7 @@ public class ConditionalFormats {
|
|||
((ExtendedColor)cs3.getColors()[1]).setARGBHex("FF63BE7B");
|
||||
sheetCF.addConditionalFormatting(regions, rule3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DataBars / Data-Bars allow you to have bars shown vary
|
||||
* based on the values, from full to empty
|
||||
|
@ -623,7 +623,7 @@ public class ConditionalFormats {
|
|||
sheet.setColumnWidth(3, 5000);
|
||||
|
||||
SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
|
||||
|
||||
|
||||
ExtendedColor color = sheet.getWorkbook().getCreationHelper().createExtendedColor();
|
||||
color.setARGBHex("FF63BE7B");
|
||||
CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:B7") };
|
||||
|
@ -632,7 +632,7 @@ public class ConditionalFormats {
|
|||
db1.getMinThreshold().setRangeType(RangeType.MIN);
|
||||
db1.getMaxThreshold().setRangeType(RangeType.MAX);
|
||||
sheetCF.addConditionalFormatting(regions, rule1);
|
||||
|
||||
|
||||
color = sheet.getWorkbook().getCreationHelper().createExtendedColor();
|
||||
color.setARGBHex("FF5A8AC6");
|
||||
regions = new CellRangeAddress[] { CellRangeAddress.valueOf("C2:C7") };
|
||||
|
@ -641,7 +641,7 @@ public class ConditionalFormats {
|
|||
db2.getMinThreshold().setRangeType(RangeType.MIN);
|
||||
db2.getMaxThreshold().setRangeType(RangeType.MAX);
|
||||
sheetCF.addConditionalFormatting(regions, rule2);
|
||||
|
||||
|
||||
color = sheet.getWorkbook().getCreationHelper().createExtendedColor();
|
||||
color.setARGBHex("FFF8696B");
|
||||
regions = new CellRangeAddress[] { CellRangeAddress.valueOf("D2:D7") };
|
||||
|
@ -651,7 +651,7 @@ public class ConditionalFormats {
|
|||
db3.getMaxThreshold().setRangeType(RangeType.MAX);
|
||||
sheetCF.addConditionalFormatting(regions, rule3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print out a summary of the conditional formatting rules applied to cells on the given sheet.
|
||||
* Only cells with a matching rule are printed, and for those, all matching rules are sumarized.
|
||||
|
@ -661,15 +661,19 @@ public class ConditionalFormats {
|
|||
final ConditionalFormattingEvaluator cfEval = new ConditionalFormattingEvaluator(wb, wbEvalProv);
|
||||
// if cell values have changed, clear cached format results
|
||||
cfEval.clearAllCachedValues();
|
||||
|
||||
|
||||
final Sheet sheet = wb.getSheet(sheetName);
|
||||
for (Row r : sheet) {
|
||||
for (Cell c : r) {
|
||||
final List<EvaluationConditionalFormatRule> rules = cfEval.getConditionalFormattingForCell(c);
|
||||
// check rules list for null, although current implementation will return an empty list, not null, then do what you want with results
|
||||
if (rules == null || rules.isEmpty()) continue;
|
||||
if (rules == null || rules.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
final CellReference ref = ConditionalFormattingEvaluator.getRef(c);
|
||||
if (rules.isEmpty()) continue;
|
||||
if (rules.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
System.out.println("\n"
|
||||
+ ref.formatAsString()
|
||||
|
@ -682,7 +686,7 @@ public class ConditionalFormats {
|
|||
b.append("\tRule ")
|
||||
.append(rule.getFormattingIndex())
|
||||
.append(": ");
|
||||
|
||||
|
||||
// check for color scale
|
||||
if (cf.getColorScaleFormatting() != null) {
|
||||
b.append("\n\t\tcolor scale (caller must calculate bucket)");
|
||||
|
@ -709,13 +713,19 @@ public class ConditionalFormats {
|
|||
b.append("\n\t\tfont format ")
|
||||
.append("color index ")
|
||||
.append(ff.getFontColorIndex());
|
||||
if (ff.isBold()) b.append(" bold");
|
||||
if (ff.isItalic()) b.append(" italic");
|
||||
if (ff.isStruckout()) b.append(" strikeout");
|
||||
if (ff.isBold()) {
|
||||
b.append(" bold");
|
||||
}
|
||||
if (ff.isItalic()) {
|
||||
b.append(" italic");
|
||||
}
|
||||
if (ff.isStruckout()) {
|
||||
b.append(" strikeout");
|
||||
}
|
||||
b.append(" underline index ")
|
||||
.append(ff.getUnderlineType());
|
||||
}
|
||||
|
||||
|
||||
System.out.println(b);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import java.util.Set;
|
|||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.ss.format.CellFormat;
|
||||
import org.apache.poi.ss.format.CellFormatResult;
|
||||
import org.apache.poi.ss.usermodel.BorderStyle;
|
||||
|
@ -96,10 +95,10 @@ public class ToHtml {
|
|||
BorderStyle.SLANTED_DASH_DOT, "dashed 2pt",
|
||||
BorderStyle.THICK, "solid 3pt",
|
||||
BorderStyle.THIN, "dashed 1pt");
|
||||
|
||||
|
||||
private static final int IDX_TABLE_WIDTH = -2;
|
||||
private static final int IDX_HEADER_COL_WIDTH = -1;
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private static <K, V> Map<K, V> mapFor(Object... mapping) {
|
||||
|
@ -189,9 +188,14 @@ public class ToHtml {
|
|||
return;
|
||||
}
|
||||
|
||||
ToHtml toHtml = create(args[0], new PrintWriter(new FileWriter(args[1])));
|
||||
toHtml.setCompleteHTML(true);
|
||||
toHtml.printPage();
|
||||
try (
|
||||
FileWriter fw = new FileWriter(args[1]);
|
||||
PrintWriter pw = new PrintWriter(fw)
|
||||
) {
|
||||
ToHtml toHtml = create(args[0], pw);
|
||||
toHtml.setCompleteHTML(true);
|
||||
toHtml.printPage();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCompleteHTML(boolean completeHTML) {
|
||||
|
@ -350,32 +354,32 @@ public class ToHtml {
|
|||
public void printSheet(Sheet sheet) {
|
||||
ensureOut();
|
||||
Map<Integer, Integer> widths = computeWidths(sheet);
|
||||
int tableWidth = widths.get(IDX_TABLE_WIDTH);
|
||||
int tableWidth = widths.get(IDX_TABLE_WIDTH);
|
||||
out.format("<table class=%s style=\"width:%dpx;\">%n", DEFAULTS_CLASS, tableWidth);
|
||||
printCols(widths);
|
||||
printSheetContent(sheet);
|
||||
out.format("</table>%n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* computes the column widths, defined by the sheet.
|
||||
*
|
||||
* computes the column widths, defined by the sheet.
|
||||
*
|
||||
* @param sheet The sheet for which to compute widths
|
||||
* @return Map with key: column index; value: column width in pixels
|
||||
* <br>special keys:
|
||||
* <br>special keys:
|
||||
* <br>{@link #IDX_HEADER_COL_WIDTH} - width of the header column
|
||||
* <br>{@link #IDX_TABLE_WIDTH} - width of the entire table
|
||||
* <br>{@link #IDX_TABLE_WIDTH} - width of the entire table
|
||||
*/
|
||||
private Map<Integer, Integer> computeWidths(Sheet sheet) {
|
||||
Map<Integer, Integer> ret = new TreeMap<>();
|
||||
int tableWidth = 0;
|
||||
|
||||
ensureColumnBounds(sheet);
|
||||
|
||||
|
||||
// compute width of the header column
|
||||
int lastRowNum = sheet.getLastRowNum();
|
||||
int headerCharCount = String.valueOf(lastRowNum).length();
|
||||
int headerColWidth = widthToPixels((headerCharCount + 1) * 256);
|
||||
int headerColWidth = widthToPixels((headerCharCount + 1) * 256.0);
|
||||
ret.put(IDX_HEADER_COL_WIDTH, headerColWidth);
|
||||
tableWidth += headerColWidth;
|
||||
|
||||
|
@ -384,11 +388,11 @@ public class ToHtml {
|
|||
ret.put(i, colWidth);
|
||||
tableWidth += colWidth;
|
||||
}
|
||||
|
||||
|
||||
ret.put(IDX_TABLE_WIDTH, tableWidth);
|
||||
return ret ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Probably platform-specific, but appears to be a close approximation on some systems
|
||||
* @param widthUnits POI's native width unit (twips)
|
||||
|
|
|
@ -59,26 +59,30 @@ public class BarChartDemo {
|
|||
BufferedReader modelReader = new BufferedReader(new FileReader(args[1]))) {
|
||||
|
||||
String chartTitle = modelReader.readLine(); // first line is chart title
|
||||
String[] series = modelReader.readLine().split(",");
|
||||
|
||||
// Category Axis Data
|
||||
List<String> listCategories = new ArrayList<String>(3);
|
||||
List<String> listLanguages = new ArrayList<>(10);
|
||||
|
||||
// Values
|
||||
List<Double> listValues = new ArrayList<Double>(3);
|
||||
List<Double> listCountries = new ArrayList<>(10);
|
||||
List<Double> listSpeakers = new ArrayList<>(10);
|
||||
|
||||
// set model
|
||||
String ln;
|
||||
while((ln = modelReader.readLine()) != null){
|
||||
String[] vals = ln.split("\\s+");
|
||||
listCategories.add(vals[0]);
|
||||
listValues.add(Double.valueOf(vals[1]));
|
||||
while((ln = modelReader.readLine()) != null) {
|
||||
String[] vals = ln.split(",");
|
||||
listCountries.add(Double.valueOf(vals[0]));
|
||||
listSpeakers.add(Double.valueOf(vals[1]));
|
||||
listLanguages.add(vals[2]);
|
||||
}
|
||||
String[] categories = listCategories.toArray(new String[listCategories.size()]);
|
||||
Double[] values = listValues.toArray(new Double[listValues.size()]);
|
||||
String[] categories = listLanguages.toArray(new String[listLanguages.size()]);
|
||||
Double[] values1 = listCountries.toArray(new Double[listCountries.size()]);
|
||||
Double[] values2 = listSpeakers.toArray(new Double[listSpeakers.size()]);
|
||||
|
||||
try (XMLSlideShow pptx = new XMLSlideShow(argIS)) {
|
||||
XSLFSlide slide = pptx.getSlides().get(0);
|
||||
setBarData(findChart(slide), chartTitle, categories, values);
|
||||
setBarData(findChart(slide), chartTitle, series, categories, values1, values2);
|
||||
|
||||
XSLFChart chart = findChart(pptx.createSlide().importContent(slide));
|
||||
setColumnData(chart, "Column variant");
|
||||
|
@ -91,30 +95,41 @@ public class BarChartDemo {
|
|||
}
|
||||
}
|
||||
|
||||
private static void setBarData(XSLFChart chart, String chartTitle, String[] categories, Double[] values) {
|
||||
final List<XDDFChartData> series = chart.getChartSeries();
|
||||
final XDDFBarChartData bar = (XDDFBarChartData) series.get(0);
|
||||
private static void setBarData(XSLFChart chart, String chartTitle, String[] series, String[] categories, Double[] values1, Double[] values2) {
|
||||
final List<XDDFChartData> data = chart.getChartSeries();
|
||||
final XDDFBarChartData bar = (XDDFBarChartData) data.get(0);
|
||||
|
||||
final int numOfPoints = categories.length;
|
||||
final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
|
||||
final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
|
||||
final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange);
|
||||
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange);
|
||||
final String valuesDataRange2 = chart.formatRange(new CellRangeAddress(1, numOfPoints, 2, 2));
|
||||
final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
|
||||
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values1, valuesDataRange, 1);
|
||||
values1[6] = 16.0; // if you ever want to change the underlying data
|
||||
final XDDFNumericalDataSource<? extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values2, valuesDataRange2, 2);
|
||||
|
||||
XDDFChartData.Series series1 = bar.getSeries().get(0);
|
||||
series1.replaceData(categoriesData, valuesData);
|
||||
series1.setTitle(series[0], chart.setSheetTitle(series[0], 0));
|
||||
XDDFChartData.Series series2 = bar.addSeries(categoriesData, valuesData2);
|
||||
series2.setTitle(series[1], chart.setSheetTitle(series[1], 1));
|
||||
|
||||
bar.getSeries().get(0).replaceData(categoriesData, valuesData);
|
||||
bar.getSeries().get(0).setTitle(chartTitle, chart.setSheetTitle(chartTitle));
|
||||
chart.plot(bar);
|
||||
chart.setTitleText(chartTitle); // https://stackoverflow.com/questions/30532612
|
||||
// chart.setTitleOverlay(overlay);
|
||||
}
|
||||
|
||||
private static void setColumnData(XSLFChart chart, String chartTitle) {
|
||||
// Series Text
|
||||
List<XDDFChartData> series = chart.getChartSeries();
|
||||
XDDFBarChartData bar = (XDDFBarChartData) series.get(0);
|
||||
bar.getSeries().get(0).setTitle(chartTitle, chart.setSheetTitle(chartTitle));
|
||||
|
||||
// in order to transform a bar chart into a column chart, you just need to change the bar direction
|
||||
bar.setBarDirection(BarDirection.COL);
|
||||
|
||||
// looking for "Stacked Bar Chart"? uncomment the following line
|
||||
// bar.setBarGrouping(BarGrouping.STACKED);
|
||||
|
||||
// additionally, you can adjust the axes
|
||||
bar.getCategoryAxis().setOrientation(AxisOrientation.MAX_MIN);
|
||||
bar.getValueAxes().get(0).setPosition(AxisPosition.TOP);
|
||||
|
|
|
@ -77,10 +77,10 @@ public class PieChartDemo {
|
|||
XDDFPieChartData pie = (XDDFPieChartData) series.get(0);
|
||||
|
||||
// Category Axis Data
|
||||
List<String> listCategories = new ArrayList<String>(3);
|
||||
List<String> listCategories = new ArrayList<>(3);
|
||||
|
||||
// Values
|
||||
List<Double> listValues = new ArrayList<Double>(3);
|
||||
List<Double> listValues = new ArrayList<>(3);
|
||||
|
||||
// set model
|
||||
String ln;
|
||||
|
@ -100,7 +100,7 @@ public class PieChartDemo {
|
|||
|
||||
XDDFPieChartData.Series firstSeries = (XDDFPieChartData.Series) pie.getSeries().get(0);
|
||||
firstSeries.replaceData(categoriesData, valuesData);
|
||||
firstSeries.setTitle(chartTitle, chart.setSheetTitle(chartTitle));
|
||||
firstSeries.setTitle(chartTitle, chart.setSheetTitle(chartTitle, 0));
|
||||
firstSeries.setExplosion(25);
|
||||
chart.plot(pie);
|
||||
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
My Bar or Column Chart
|
||||
First 1.0
|
||||
Second 3.0
|
||||
Third 4.0
|
||||
10 languages with most speakers as first language
|
||||
countries,speakers,language
|
||||
58,315,العربية
|
||||
4,243,বাংলা
|
||||
38,1299,中文
|
||||
118,378,English
|
||||
4,260,हिन्दी
|
||||
2,128,日本語
|
||||
15,223,português
|
||||
6,119,ਪੰਜਾਬੀ
|
||||
18,154,Русский язык
|
||||
31,442,español
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.xssf.usermodel.examples;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.poi.common.usermodel.fonts.FontGroup;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.xddf.usermodel.PresetColor;
|
||||
import org.apache.poi.xddf.usermodel.XDDFColor;
|
||||
import org.apache.poi.xddf.usermodel.XDDFLineProperties;
|
||||
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
|
||||
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
|
||||
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
|
||||
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
||||
import org.apache.poi.xddf.usermodel.chart.BarDirection;
|
||||
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
|
||||
import org.apache.poi.xddf.usermodel.chart.LayoutMode;
|
||||
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryDataSource;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFLineChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFManualLayout;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
|
||||
import org.apache.poi.xddf.usermodel.text.UnderlineType;
|
||||
import org.apache.poi.xddf.usermodel.text.XDDFFont;
|
||||
import org.apache.poi.xddf.usermodel.text.XDDFRunProperties;
|
||||
import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFDrawing;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
// original contributions by Axel Richter on https://stackoverflow.com/questions/47065690
|
||||
// additional title formatting from https://stackoverflow.com/questions/50418856
|
||||
// and legend positioning from https://stackoverflow.com/questions/49615379
|
||||
// this would probably be an answer for https://stackoverflow.com/questions/36447925 too
|
||||
public class BarAndLineChart {
|
||||
private static final int NUM_OF_ROWS = 7;
|
||||
private static final Random RNG = new Random();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (XSSFWorkbook wb = new XSSFWorkbook()) {
|
||||
XSSFSheet sheet = wb.createSheet("Sheet1");
|
||||
|
||||
XSSFRow row = sheet.createRow(0);
|
||||
row.createCell(0);
|
||||
row.createCell(1).setCellValue("Bars");
|
||||
row.createCell(2).setCellValue("Lines");
|
||||
|
||||
XSSFCell cell;
|
||||
for (int r = 1; r < NUM_OF_ROWS; r++) {
|
||||
row = sheet.createRow(r);
|
||||
cell = row.createCell(0);
|
||||
cell.setCellValue("C" + r);
|
||||
cell = row.createCell(1);
|
||||
cell.setCellValue(RNG.nextDouble());
|
||||
cell = row.createCell(2);
|
||||
cell.setCellValue(RNG.nextDouble() * 10);
|
||||
}
|
||||
|
||||
XSSFDrawing drawing = sheet.createDrawingPatriarch();
|
||||
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 4, 0, 11, 15);
|
||||
|
||||
XSSFChart chart = drawing.createChart(anchor);
|
||||
chart.setTitleText("This is my title");
|
||||
chart.setTitleOverlay(true);
|
||||
XDDFRunProperties properties = new XDDFRunProperties();
|
||||
properties.setBold(true);
|
||||
properties.setItalic(true);
|
||||
properties.setUnderline(UnderlineType.DOT_DOT_DASH_HEAVY);
|
||||
properties.setFontSize(22.5);
|
||||
XDDFFont[] fonts = new XDDFFont[]{
|
||||
new XDDFFont(FontGroup.LATIN, "Calibri", null, null, null),
|
||||
new XDDFFont(FontGroup.COMPLEX_SCRIPT, "Liberation Sans", null, null, null)
|
||||
};
|
||||
properties.setFonts(fonts);
|
||||
properties.setLineProperties(solidLine(PresetColor.SIENNA));
|
||||
XDDFTextParagraph paragraph = chart.getTitle().getBody().getParagraph(0);
|
||||
paragraph.setDefaultRunProperties(properties);
|
||||
|
||||
// the data sources
|
||||
XDDFCategoryDataSource xs = XDDFDataSourcesFactory.fromStringCellRange(sheet,
|
||||
new CellRangeAddress(1, NUM_OF_ROWS - 1, 0, 0));
|
||||
XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet,
|
||||
new CellRangeAddress(1, NUM_OF_ROWS - 1, 1, 1));
|
||||
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet,
|
||||
new CellRangeAddress(1, NUM_OF_ROWS - 1, 2, 2));
|
||||
|
||||
// cat axis 1 (bars)
|
||||
XDDFCategoryAxis barCategories = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
||||
|
||||
// val axis 1 (left)
|
||||
XDDFValueAxis leftValues = chart.createValueAxis(AxisPosition.LEFT);
|
||||
leftValues.crossAxis(barCategories);
|
||||
barCategories.crossAxis(leftValues);
|
||||
|
||||
// cat axis 2 (lines)
|
||||
XDDFCategoryAxis lineCategories = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
||||
lineCategories.setVisible(false); // this cat axis is deleted
|
||||
|
||||
// val axis 2 (right)
|
||||
XDDFValueAxis rightValues = chart.createValueAxis(AxisPosition.RIGHT);
|
||||
// this value axis crosses its category axis at max value
|
||||
rightValues.setCrosses(AxisCrosses.MAX);
|
||||
rightValues.crossAxis(lineCategories);
|
||||
lineCategories.crossAxis(rightValues);
|
||||
|
||||
// the bar chart
|
||||
XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, lineCategories, rightValues);
|
||||
XDDFBarChartData.Series series1 = (XDDFBarChartData.Series) bar.addSeries(xs, ys1);
|
||||
series1.setTitle("Bars", new CellReference("Sheet1!$B$1"));
|
||||
bar.setVaryColors(true);
|
||||
bar.setBarDirection(BarDirection.COL);
|
||||
chart.plot(bar);
|
||||
|
||||
// the line chart
|
||||
XDDFLineChartData lines = (XDDFLineChartData) chart.createData(ChartTypes.LINE, lineCategories,
|
||||
rightValues);
|
||||
XDDFLineChartData.Series series2 = (XDDFLineChartData.Series) lines.addSeries(xs, ys2);
|
||||
series2.setTitle("Lines", new CellReference("Sheet1!$C$1"));
|
||||
lines.setVaryColors(true);
|
||||
chart.plot(lines);
|
||||
|
||||
// some colors
|
||||
solidFillSeries(bar, 0, PresetColor.CHARTREUSE);
|
||||
solidLineSeries(lines, 0, PresetColor.TURQUOISE);
|
||||
|
||||
// legend
|
||||
XDDFChartLegend legend = chart.getOrAddLegend();
|
||||
legend.setPosition(LegendPosition.LEFT);
|
||||
legend.setOverlay(false);
|
||||
XDDFManualLayout layout = legend.getOrAddManualLayout();
|
||||
layout.setXMode(LayoutMode.EDGE);
|
||||
layout.setYMode(LayoutMode.EDGE);
|
||||
layout.setX(0.00); //left edge of the chart
|
||||
layout.setY(0.25); //25% of chart's height from top edge of the chart
|
||||
|
||||
try (FileOutputStream fileOut = new FileOutputStream("BarAndLineChart.xlsx")) {
|
||||
wb.write(fileOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void solidFillSeries(XDDFChartData data, int index, PresetColor color) {
|
||||
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
|
||||
XDDFChartData.Series series = data.getSeries().get(index);
|
||||
XDDFShapeProperties properties = series.getShapeProperties();
|
||||
if (properties == null) {
|
||||
properties = new XDDFShapeProperties();
|
||||
}
|
||||
properties.setFillProperties(fill);
|
||||
series.setShapeProperties(properties);
|
||||
}
|
||||
|
||||
private static void solidLineSeries(XDDFChartData data, int index, PresetColor color) {
|
||||
XDDFLineProperties line = solidLine(color);
|
||||
XDDFChartData.Series series = data.getSeries().get(index);
|
||||
XDDFShapeProperties properties = series.getShapeProperties();
|
||||
if (properties == null) {
|
||||
properties = new XDDFShapeProperties();
|
||||
}
|
||||
properties.setLineProperties(line);
|
||||
series.setShapeProperties(properties);
|
||||
}
|
||||
|
||||
private static XDDFLineProperties solidLine(PresetColor color) {
|
||||
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
|
||||
XDDFLineProperties line = new XDDFLineProperties();
|
||||
line.setFillProperties(fill);
|
||||
return line;
|
||||
}
|
||||
}
|
|
@ -28,8 +28,10 @@ import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
|
|||
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
|
||||
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
|
||||
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
||||
import org.apache.poi.xddf.usermodel.chart.BarDirection;
|
||||
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
|
||||
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
||||
|
@ -61,7 +63,7 @@ public class BarChart {
|
|||
row = sheet.createRow((short) rowIndex);
|
||||
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
||||
cell = row.createCell((short) colIndex);
|
||||
cell.setCellValue(colIndex * (rowIndex + 1));
|
||||
cell.setCellValue(colIndex * (rowIndex + 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,12 +71,16 @@ public class BarChart {
|
|||
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
|
||||
|
||||
XSSFChart chart = drawing.createChart(anchor);
|
||||
chart.setTitleText("x = 2x and x = 3x");
|
||||
chart.setTitleOverlay(false);
|
||||
XDDFChartLegend legend = chart.getOrAddLegend();
|
||||
legend.setPosition(LegendPosition.TOP_RIGHT);
|
||||
|
||||
// Use a category axis for the bottom axis.
|
||||
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
||||
bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
|
||||
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
||||
leftAxis.setTitle("f(x)");
|
||||
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
||||
|
||||
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
||||
|
@ -82,18 +88,20 @@ public class BarChart {
|
|||
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
|
||||
|
||||
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
|
||||
data.addSeries(xs, ys1);
|
||||
data.addSeries(xs, ys2);
|
||||
XDDFChartData.Series series1 = data.addSeries(xs, ys1);
|
||||
series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
|
||||
XDDFChartData.Series series2 = data.addSeries(xs, ys2);
|
||||
series2.setTitle("3x", null);
|
||||
chart.plot(data);
|
||||
|
||||
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.CHARTREUSE));
|
||||
XDDFChartData.Series firstSeries = data.getSeries().get(0);
|
||||
XDDFShapeProperties properties = firstSeries.getShapeProperties();
|
||||
if (properties == null) {
|
||||
properties = new XDDFShapeProperties();
|
||||
}
|
||||
properties.setFillProperties(fill);
|
||||
firstSeries.setShapeProperties(properties);
|
||||
// in order to transform a bar chart into a column chart, you just need to change the bar direction
|
||||
XDDFBarChartData bar = (XDDFBarChartData) data;
|
||||
bar.setBarDirection(BarDirection.COL);
|
||||
// looking for "Stacked Bar Chart"? uncomment the following line
|
||||
// bar.setBarGrouping(BarGrouping.STACKED);
|
||||
|
||||
solidFillSeries(data, 0, PresetColor.CHARTREUSE);
|
||||
solidFillSeries(data, 1, PresetColor.TURQUOISE);
|
||||
|
||||
// Write the output to a file
|
||||
try (FileOutputStream fileOut = new FileOutputStream("ooxml-bar-chart.xlsx")) {
|
||||
|
@ -101,4 +109,15 @@ public class BarChart {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void solidFillSeries(XDDFChartData data, int index, PresetColor color) {
|
||||
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
|
||||
XDDFChartData.Series series = data.getSeries().get(index);
|
||||
XDDFShapeProperties properties = series.getShapeProperties();
|
||||
if (properties == null) {
|
||||
properties = new XDDFShapeProperties();
|
||||
}
|
||||
properties.setFillProperties(fill);
|
||||
series.setShapeProperties(properties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,18 +58,18 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|||
* <p>
|
||||
* If you really want to use this approach, which is also the one that SXSSF
|
||||
* does for you, it works as follows:
|
||||
*
|
||||
*
|
||||
* 1. create a template workbook, create sheets and global objects such as cell styles, number formats, etc.
|
||||
* 2. create an application that streams data in a text file
|
||||
* 3. Substitute the sheet in the template with the generated data
|
||||
*
|
||||
* <p>
|
||||
* Since 3.8 POI provides a low-memory footprint SXSSF API, which implements
|
||||
* Since 3.8 POI provides a low-memory footprint SXSSF API, which implements
|
||||
* ths "BigGridDemo" strategy. SXSSF is an API-compatible streaming extension
|
||||
* of XSSF to be used when very large spreadsheets have to be produced, and
|
||||
* heap space is limited. SXSSF achieves its low memory footprint by limiting
|
||||
* access to the rows that are within a sliding window, while XSSF gives access
|
||||
* to all rows in the document. Older rows that are no longer in the window
|
||||
* of XSSF to be used when very large spreadsheets have to be produced, and
|
||||
* heap space is limited. SXSSF achieves its low memory footprint by limiting
|
||||
* access to the rows that are within a sliding window, while XSSF gives access
|
||||
* to all rows in the document. Older rows that are no longer in the window
|
||||
* become inaccessible, as they are written to the disk.
|
||||
* </p>
|
||||
* See <a "http://poi.apache.org/spreadsheet/how-to.html#sxssf">
|
||||
|
@ -79,7 +79,7 @@ public final class BigGridDemo {
|
|||
private static final String XML_ENCODING = "UTF-8";
|
||||
|
||||
private BigGridDemo() {}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// Step 1. Create a template file. Setup sheets and workbook-level objects such as
|
||||
|
@ -99,7 +99,10 @@ public final class BigGridDemo {
|
|||
|
||||
//Step 2. Generate XML file.
|
||||
File tmp = File.createTempFile("sheet", ".xml");
|
||||
try (Writer fw = new OutputStreamWriter(new FileOutputStream(tmp), XML_ENCODING)) {
|
||||
try (
|
||||
FileOutputStream stream = new FileOutputStream(tmp);
|
||||
Writer fw = new OutputStreamWriter(stream, XML_ENCODING)
|
||||
) {
|
||||
generate(fw, styles);
|
||||
}
|
||||
|
||||
|
@ -265,7 +268,9 @@ public final class BigGridDemo {
|
|||
public void createCell(int columnIndex, String value, int styleIndex) throws IOException {
|
||||
String ref = new CellReference(_rownum, columnIndex).formatAsString();
|
||||
_out.write("<c r=\""+ref+"\" t=\"inlineStr\"");
|
||||
if(styleIndex != -1) _out.write(" s=\""+styleIndex+"\"");
|
||||
if(styleIndex != -1) {
|
||||
_out.write(" s=\""+styleIndex+"\"");
|
||||
}
|
||||
_out.write(">");
|
||||
_out.write("<is><t>"+value+"</t></is>");
|
||||
_out.write("</c>");
|
||||
|
@ -278,7 +283,9 @@ public final class BigGridDemo {
|
|||
public void createCell(int columnIndex, double value, int styleIndex) throws IOException {
|
||||
String ref = new CellReference(_rownum, columnIndex).formatAsString();
|
||||
_out.write("<c r=\""+ref+"\" t=\"n\"");
|
||||
if(styleIndex != -1) _out.write(" s=\""+styleIndex+"\"");
|
||||
if(styleIndex != -1) {
|
||||
_out.write(" s=\""+styleIndex+"\"");
|
||||
}
|
||||
_out.write(">");
|
||||
_out.write("<v>"+value+"</v>");
|
||||
_out.write("</c>");
|
||||
|
|
|
@ -33,14 +33,18 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|||
* Demonstrates how to create a simple table using Apache POI.
|
||||
*/
|
||||
public class CreateTable {
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
|
||||
try (Workbook wb = new XSSFWorkbook()) {
|
||||
XSSFSheet sheet = (XSSFSheet) wb.createSheet();
|
||||
|
||||
// Set which area the table should be placed in
|
||||
AreaReference reference = wb.getCreationHelper().createAreaReference(
|
||||
new CellReference(0, 0), new CellReference(2, 2));
|
||||
|
||||
// Create
|
||||
XSSFTable table = sheet.createTable();
|
||||
XSSFTable table = sheet.createTable(reference);
|
||||
table.setName("Test");
|
||||
table.setDisplayName("Test_Table");
|
||||
|
||||
|
@ -70,7 +74,7 @@ public class CreateTable {
|
|||
if (i == 0) {
|
||||
cell.setCellValue("Column" + (j + 1));
|
||||
} else {
|
||||
cell.setCellValue((i + 1) * (j + 1));
|
||||
cell.setCellValue((i + 1.0) * (j + 1.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,11 +83,6 @@ public class CreateTable {
|
|||
table.createColumn("Column 2");
|
||||
table.createColumn("Column 3");
|
||||
|
||||
// Set which area the table should be placed in
|
||||
AreaReference reference = wb.getCreationHelper().createAreaReference(
|
||||
new CellReference(0, 0), new CellReference(2, 2));
|
||||
table.setCellReferences(reference);
|
||||
|
||||
// Save
|
||||
try (FileOutputStream fileOut = new FileOutputStream("ooxml-table.xlsx")) {
|
||||
wb.write(fileOut);
|
||||
|
|
|
@ -32,7 +32,10 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|||
public class IterateCells {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
try (Workbook wb = new XSSFWorkbook(new FileInputStream(args[0]))) {
|
||||
try (
|
||||
FileInputStream is = new FileInputStream(args[0]);
|
||||
Workbook wb = new XSSFWorkbook(is)
|
||||
) {
|
||||
for (int i = 0; i < wb.getNumberOfSheets(); i++) {
|
||||
Sheet sheet = wb.getSheetAt(i);
|
||||
System.out.println(wb.getSheetName(i));
|
||||
|
|
|
@ -22,15 +22,22 @@ import java.io.IOException;
|
|||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xddf.usermodel.PresetColor;
|
||||
import org.apache.poi.xddf.usermodel.XDDFColor;
|
||||
import org.apache.poi.xddf.usermodel.XDDFLineProperties;
|
||||
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
|
||||
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
|
||||
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
|
||||
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
||||
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
|
||||
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
|
||||
import org.apache.poi.xddf.usermodel.chart.MarkerStyle;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFLineChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
|
||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||
|
@ -57,35 +64,64 @@ public class LineChart {
|
|||
row = sheet.createRow((short) rowIndex);
|
||||
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
||||
cell = row.createCell((short) colIndex);
|
||||
cell.setCellValue(colIndex * (rowIndex + 1));
|
||||
cell.setCellValue(colIndex * (rowIndex + 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
XSSFDrawing drawing = sheet.createDrawingPatriarch();
|
||||
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
|
||||
|
||||
|
||||
XSSFChart chart = drawing.createChart(anchor);
|
||||
XDDFChartLegend legend = chart.getOrAddLegend();
|
||||
legend.setPosition(LegendPosition.TOP_RIGHT);
|
||||
|
||||
|
||||
// Use a category axis for the bottom axis.
|
||||
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
||||
bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
|
||||
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
||||
leftAxis.setTitle("f(x)");
|
||||
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
||||
|
||||
|
||||
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
||||
XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
|
||||
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
|
||||
|
||||
XDDFChartData data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
|
||||
data.addSeries(xs, ys1);
|
||||
data.addSeries(xs, ys2);
|
||||
|
||||
XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
|
||||
XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xs, ys1);
|
||||
series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
|
||||
series1.setSmooth(false); // https://stackoverflow.com/questions/29014848
|
||||
series1.setMarkerStyle(MarkerStyle.STAR); // https://stackoverflow.com/questions/39636138
|
||||
XDDFLineChartData.Series series2 = (XDDFLineChartData.Series) data.addSeries(xs, ys2);
|
||||
series2.setTitle("3x", null);
|
||||
series2.setSmooth(true);
|
||||
series2.setMarkerSize((short) 6);
|
||||
series2.setMarkerStyle(MarkerStyle.TRIANGLE); // https://stackoverflow.com/questions/39636138
|
||||
chart.plot(data);
|
||||
|
||||
// if your series have missing values like https://stackoverflow.com/questions/29014848
|
||||
// chart.displayBlanksAs(DisplayBlanks.GAP);
|
||||
|
||||
// https://stackoverflow.com/questions/24676460
|
||||
solidLineSeries(data, 0, PresetColor.CHARTREUSE);
|
||||
solidLineSeries(data, 1, PresetColor.TURQUOISE);
|
||||
|
||||
// Write the output to a file
|
||||
try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) {
|
||||
wb.write(fileOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void solidLineSeries(XDDFChartData data, int index, PresetColor color) {
|
||||
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
|
||||
XDDFLineProperties line = new XDDFLineProperties();
|
||||
line.setFillProperties(fill);
|
||||
XDDFChartData.Series series = data.getSeries().get(index);
|
||||
XDDFShapeProperties properties = series.getShapeProperties();
|
||||
if (properties == null) {
|
||||
properties = new XDDFShapeProperties();
|
||||
}
|
||||
properties.setLineProperties(line);
|
||||
series.setShapeProperties(properties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ import java.io.IOException;
|
|||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xddf.usermodel.PresetColor;
|
||||
import org.apache.poi.xddf.usermodel.XDDFColor;
|
||||
import org.apache.poi.xddf.usermodel.XDDFLineProperties;
|
||||
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
|
||||
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
|
||||
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
|
||||
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
||||
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
|
||||
|
@ -34,6 +39,7 @@ import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
|||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFScatterChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
|
||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||
|
@ -59,36 +65,56 @@ public class ScatterChart {
|
|||
row = sheet.createRow((short) rowIndex);
|
||||
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
||||
cell = row.createCell((short) colIndex);
|
||||
cell.setCellValue(colIndex * (rowIndex + 1));
|
||||
cell.setCellValue(colIndex * (rowIndex + 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XSSFDrawing drawing = sheet.createDrawingPatriarch();
|
||||
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
|
||||
|
||||
|
||||
XSSFChart chart = drawing.createChart(anchor);
|
||||
XDDFChartLegend legend = chart.getOrAddLegend();
|
||||
legend.setPosition(LegendPosition.TOP_RIGHT);
|
||||
|
||||
|
||||
XDDFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.BOTTOM);
|
||||
bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
|
||||
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
||||
leftAxis.setTitle("f(x)");
|
||||
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
||||
|
||||
|
||||
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
||||
XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
|
||||
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
|
||||
|
||||
|
||||
XDDFChartData data = chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis);
|
||||
|
||||
data.addSeries(xs, ys1);
|
||||
data.addSeries(xs, ys2);
|
||||
|
||||
|
||||
XDDFScatterChartData data = (XDDFScatterChartData) chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis);
|
||||
XDDFScatterChartData.Series series1 = (XDDFScatterChartData.Series) data.addSeries(xs, ys1);
|
||||
series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
|
||||
series1.setSmooth(false); // https://stackoverflow.com/questions/39636138
|
||||
XDDFScatterChartData.Series series2 = (XDDFScatterChartData.Series) data.addSeries(xs, ys2);
|
||||
series2.setTitle("3x", null);
|
||||
chart.plot(data);
|
||||
|
||||
solidLineSeries(data, 0, PresetColor.CHARTREUSE);
|
||||
solidLineSeries(data, 1, PresetColor.TURQUOISE);
|
||||
|
||||
// Write the output to a file
|
||||
try (FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx")) {
|
||||
wb.write(fileOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void solidLineSeries(XDDFChartData data, int index, PresetColor color) {
|
||||
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
|
||||
XDDFLineProperties line = new XDDFLineProperties();
|
||||
line.setFillProperties(fill);
|
||||
XDDFChartData.Series series = data.getSeries().get(index);
|
||||
XDDFShapeProperties properties = series.getShapeProperties();
|
||||
if (properties == null) {
|
||||
properties = new XDDFShapeProperties();
|
||||
}
|
||||
properties.setLineProperties(line);
|
||||
series.setShapeProperties(properties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,9 +43,9 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
|||
/**
|
||||
* Build a bar chart from a template docx
|
||||
*/
|
||||
public class BarChartExampleDOCX {
|
||||
public class BarChartExample {
|
||||
private static void usage(){
|
||||
System.out.println("Usage: BarChartDemo <bar-chart-template.docx> <bar-chart-data.txt>");
|
||||
System.out.println("Usage: BarChartExample <bar-chart-template.docx> <bar-chart-data.txt>");
|
||||
System.out.println(" bar-chart-template.docx template with a bar chart");
|
||||
System.out.println(" bar-chart-data.txt the model to set. First line is chart title, " +
|
||||
"then go pairs {axis-label value}");
|
||||
|
@ -61,26 +61,30 @@ public class BarChartExampleDOCX {
|
|||
BufferedReader modelReader = new BufferedReader(new FileReader(args[1]))) {
|
||||
|
||||
String chartTitle = modelReader.readLine(); // first line is chart title
|
||||
String[] series = modelReader.readLine().split(",");
|
||||
|
||||
// Category Axis Data
|
||||
List<String> listCategories = new ArrayList<String>(3);
|
||||
List<String> listLanguages = new ArrayList<>(10);
|
||||
|
||||
// Values
|
||||
List<Double> listValues = new ArrayList<Double>(3);
|
||||
List<Double> listCountries = new ArrayList<>(10);
|
||||
List<Double> listSpeakers = new ArrayList<>(10);
|
||||
|
||||
// set model
|
||||
String ln;
|
||||
while((ln = modelReader.readLine()) != null) {
|
||||
String[] vals = ln.split("\\s+");
|
||||
listCategories.add(vals[0]);
|
||||
listValues.add(Double.valueOf(vals[1]));
|
||||
String[] vals = ln.split(",");
|
||||
listCountries.add(Double.valueOf(vals[0]));
|
||||
listSpeakers.add(Double.valueOf(vals[1]));
|
||||
listLanguages.add(vals[2]);
|
||||
}
|
||||
String[] categories = listCategories.toArray(new String[listCategories.size()]);
|
||||
Double[] values = listValues.toArray(new Double[listValues.size()]);
|
||||
String[] categories = listLanguages.toArray(new String[listLanguages.size()]);
|
||||
Double[] values1 = listCountries.toArray(new Double[listCountries.size()]);
|
||||
Double[] values2 = listSpeakers.toArray(new Double[listSpeakers.size()]);
|
||||
|
||||
try (XWPFDocument doc = new XWPFDocument(argIS)) {
|
||||
XWPFChart chart = doc.getCharts().get(0);
|
||||
setBarData(chart, chartTitle, categories, values);
|
||||
setBarData(chart, chartTitle, series, categories, values1, values2);
|
||||
chart = doc.getCharts().get(1);
|
||||
setColumnData(chart, "Column variant");
|
||||
|
||||
|
@ -93,33 +97,41 @@ public class BarChartExampleDOCX {
|
|||
System.out.println("Done");
|
||||
}
|
||||
|
||||
private static void setBarData(XWPFChart chart, String chartTitle, String[] categories, Double[] values) {
|
||||
final List<XDDFChartData> series = chart.getChartSeries();
|
||||
final XDDFBarChartData bar = (XDDFBarChartData) series.get(0);
|
||||
private static void setBarData(XWPFChart chart, String chartTitle, String[] series, String[] categories, Double[] values1, Double[] values2) {
|
||||
final List<XDDFChartData> data = chart.getChartSeries();
|
||||
final XDDFBarChartData bar = (XDDFBarChartData) data.get(0);
|
||||
|
||||
final int numOfPoints = categories.length;
|
||||
final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
|
||||
final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
|
||||
final String valuesDataRange2 = chart.formatRange(new CellRangeAddress(1, numOfPoints, 2, 2));
|
||||
final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
|
||||
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange, 1);
|
||||
values[2] = 10.0;
|
||||
final XDDFNumericalDataSource<? extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values, valuesDataRange2, 2);
|
||||
bar.getSeries().get(0).replaceData(categoriesData, valuesData);
|
||||
bar.addSeries(categoriesData, valuesData2);
|
||||
bar.getSeries().get(0).setTitle(chartTitle, chart.setSheetTitle(chartTitle));
|
||||
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values1, valuesDataRange, 1);
|
||||
values1[6] = 16.0; // if you ever want to change the underlying data
|
||||
final XDDFNumericalDataSource<? extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values2, valuesDataRange2, 2);
|
||||
|
||||
XDDFChartData.Series series1 = bar.getSeries().get(0);
|
||||
series1.replaceData(categoriesData, valuesData);
|
||||
series1.setTitle(series[0], chart.setSheetTitle(series[0], 0));
|
||||
XDDFChartData.Series series2 = bar.addSeries(categoriesData, valuesData2);
|
||||
series2.setTitle(series[1], chart.setSheetTitle(series[1], 1));
|
||||
|
||||
chart.plot(bar);
|
||||
chart.setTitleText(chartTitle); // https://stackoverflow.com/questions/30532612
|
||||
chart.setTitleOverlay(false);
|
||||
}
|
||||
|
||||
private static void setColumnData(XWPFChart chart, String chartTitle) {
|
||||
// Series Text
|
||||
List<XDDFChartData> series = chart.getChartSeries();
|
||||
XDDFBarChartData bar = (XDDFBarChartData) series.get(0);
|
||||
bar.getSeries().get(0).setTitle(chartTitle, chart.setSheetTitle(chartTitle));
|
||||
|
||||
// in order to transform a bar chart into a column chart, you just need to change the bar direction
|
||||
bar.setBarDirection(BarDirection.COL);
|
||||
|
||||
// looking for "Stacked Bar Chart"? uncomment the following line
|
||||
// bar.setBarGrouping(BarGrouping.STACKED);
|
||||
|
||||
// additionally, you can adjust the axes
|
||||
bar.getCategoryAxis().setOrientation(AxisOrientation.MAX_MIN);
|
||||
bar.getValueAxes().get(0).setPosition(AxisPosition.TOP);
|
|
@ -111,16 +111,16 @@ public class SimpleDocument {
|
|||
r5.setTextPosition(-10);
|
||||
r5.setText("For in that sleep of death what dreams may come");
|
||||
r5.addCarriageReturn();
|
||||
r5.setText("When we have shuffled off this mortal coil,"
|
||||
+ "Must give us pause: there's the respect"
|
||||
r5.setText("When we have shuffled off this mortal coil, "
|
||||
+ "Must give us pause: there's the respect "
|
||||
+ "That makes calamity of so long life;");
|
||||
r5.addBreak();
|
||||
r5.setText("For who would bear the whips and scorns of time,"
|
||||
r5.setText("For who would bear the whips and scorns of time, "
|
||||
+ "The oppressor's wrong, the proud man's contumely,");
|
||||
|
||||
r5.addBreak(BreakClear.ALL);
|
||||
r5.setText("The pangs of despised love, the law's delay,"
|
||||
+ "The insolence of office and the spurns" + ".......");
|
||||
r5.setText("The pangs of despised love, the law's delay, "
|
||||
+ "The insolence of office and the spurns " + ".......");
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream("simple.docx")) {
|
||||
doc.write(out);
|
||||
|
|
|
@ -43,18 +43,29 @@ public class SimpleImages {
|
|||
for (String imgFile : args) {
|
||||
int format;
|
||||
|
||||
if (imgFile.endsWith(".emf")) format = XWPFDocument.PICTURE_TYPE_EMF;
|
||||
else if (imgFile.endsWith(".wmf")) format = XWPFDocument.PICTURE_TYPE_WMF;
|
||||
else if (imgFile.endsWith(".pict")) format = XWPFDocument.PICTURE_TYPE_PICT;
|
||||
else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) format = XWPFDocument.PICTURE_TYPE_JPEG;
|
||||
else if (imgFile.endsWith(".png")) format = XWPFDocument.PICTURE_TYPE_PNG;
|
||||
else if (imgFile.endsWith(".dib")) format = XWPFDocument.PICTURE_TYPE_DIB;
|
||||
else if (imgFile.endsWith(".gif")) format = XWPFDocument.PICTURE_TYPE_GIF;
|
||||
else if (imgFile.endsWith(".tiff")) format = XWPFDocument.PICTURE_TYPE_TIFF;
|
||||
else if (imgFile.endsWith(".eps")) format = XWPFDocument.PICTURE_TYPE_EPS;
|
||||
else if (imgFile.endsWith(".bmp")) format = XWPFDocument.PICTURE_TYPE_BMP;
|
||||
else if (imgFile.endsWith(".wpg")) format = XWPFDocument.PICTURE_TYPE_WPG;
|
||||
else {
|
||||
if (imgFile.endsWith(".emf")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_EMF;
|
||||
} else if (imgFile.endsWith(".wmf")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_WMF;
|
||||
} else if (imgFile.endsWith(".pict")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_PICT;
|
||||
} else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_JPEG;
|
||||
} else if (imgFile.endsWith(".png")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_PNG;
|
||||
} else if (imgFile.endsWith(".dib")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_DIB;
|
||||
} else if (imgFile.endsWith(".gif")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_GIF;
|
||||
} else if (imgFile.endsWith(".tiff")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_TIFF;
|
||||
} else if (imgFile.endsWith(".eps")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_EPS;
|
||||
} else if (imgFile.endsWith(".bmp")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_BMP;
|
||||
} else if (imgFile.endsWith(".wpg")) {
|
||||
format = XWPFDocument.PICTURE_TYPE_WPG;
|
||||
} else {
|
||||
System.err.println("Unsupported picture: " + imgFile +
|
||||
". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");
|
||||
continue;
|
||||
|
@ -62,7 +73,9 @@ public class SimpleImages {
|
|||
|
||||
r.setText(imgFile);
|
||||
r.addBreak();
|
||||
r.addPicture(new FileInputStream(imgFile), format, imgFile, Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels
|
||||
try (FileInputStream is = new FileInputStream(imgFile)) {
|
||||
r.addPicture(is, format, imgFile, Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels
|
||||
}
|
||||
r.addBreak(BreakType.PAGE);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
My Bar or Column Chart
|
||||
First 1.0
|
||||
Second 3.0
|
||||
Third 4.0
|
||||
10 languages with most speakers as first language
|
||||
countries,speakers,language
|
||||
58,315,العربية
|
||||
4,243,বাংলা
|
||||
38,1299,中文
|
||||
118,378,English
|
||||
4,260,हिन्दी
|
||||
2,128,日本語
|
||||
15,223,português
|
||||
6,119,ਪੰਜਾਬੀ
|
||||
18,154,Русский язык
|
||||
31,442,español
|
||||
|
|
|
@ -336,7 +336,7 @@ public abstract class EscherRecord implements Cloneable {
|
|||
String tagName = capitalizeAndTrim((String)attrs[0]);
|
||||
boolean hasValue = false;
|
||||
boolean lastChildComplex = false;
|
||||
for (int i=0; i<attrs.length; i+=2) {
|
||||
for (int i=0; i<attrs.length-1; i+=2) {
|
||||
Object value = attrs[i+1];
|
||||
if (value == null) {
|
||||
// ignore null values
|
||||
|
@ -384,7 +384,7 @@ public abstract class EscherRecord implements Cloneable {
|
|||
if (attrList != null && attrList.length > 0) {
|
||||
String childTab = " ";
|
||||
for (Object[] attrs : attrList) {
|
||||
for (int i=0; i<attrs.length; i+=2) {
|
||||
for (int i=0; i<attrs.length-1; i+=2) {
|
||||
Object value = attrs[i+1];
|
||||
if (value == null) {
|
||||
// ignore null values
|
||||
|
|
|
@ -21,15 +21,7 @@ import java.text.CollationKey;
|
|||
import java.text.Collator;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.poi.ss.formula.eval.BlankEval;
|
||||
import org.apache.poi.ss.formula.eval.BoolEval;
|
||||
|
@ -900,9 +892,9 @@ public class EvaluationConditionalFormatRule implements Comparable<EvaluationCon
|
|||
return false;
|
||||
}
|
||||
ValueAndFormat o = (ValueAndFormat) obj;
|
||||
return ( value == o.value || value.equals(o.value))
|
||||
&& ( format == o.format || format.equals(o.format))
|
||||
&& (string == o.string || string.equals(o.string));
|
||||
return (Objects.equals(value, o.value)
|
||||
&& Objects.equals(format, o.format)
|
||||
&& Objects.equals(string, o.string));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -382,9 +382,6 @@ public final class FormulaParser {
|
|||
if (token instanceof OperandPtg) {
|
||||
return false;
|
||||
}
|
||||
if (token instanceof OperationPtg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ final class RandBetween implements FreeRefFunction{
|
|||
top = bottom;
|
||||
}
|
||||
|
||||
return new NumberEval((bottom + (int)(Math.random() * ((top - bottom) + 1))));
|
||||
return new NumberEval((bottom + (long)(Math.random() * ((top - bottom) + 1))));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ public final class StaxHelper {
|
|||
* Creates a new StAX XMLInputFactory, with sensible defaults
|
||||
*/
|
||||
public static XMLInputFactory newXMLInputFactory() {
|
||||
XMLInputFactory factory = XMLInputFactory.newFactory();
|
||||
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||
trySetProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, true);
|
||||
trySetProperty(factory, XMLInputFactory.IS_VALIDATING, false);
|
||||
trySetProperty(factory, XMLInputFactory.SUPPORT_DTD, false);
|
||||
|
@ -46,7 +46,7 @@ public final class StaxHelper {
|
|||
* Creates a new StAX XMLOutputFactory, with sensible defaults
|
||||
*/
|
||||
public static XMLOutputFactory newXMLOutputFactory() {
|
||||
XMLOutputFactory factory = XMLOutputFactory.newFactory();
|
||||
XMLOutputFactory factory = XMLOutputFactory.newInstance();
|
||||
trySetProperty(factory, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
|
||||
return factory;
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ public final class StaxHelper {
|
|||
* Creates a new StAX XMLEventFactory, with sensible defaults
|
||||
*/
|
||||
public static XMLEventFactory newXMLEventFactory() {
|
||||
return XMLEventFactory.newFactory();
|
||||
// this method seems safer on Android than getFactory()
|
||||
return XMLEventFactory.newInstance();
|
||||
}
|
||||
|
||||
private static void trySetProperty(XMLInputFactory factory, String feature, boolean flag) {
|
||||
|
|
|
@ -223,7 +223,7 @@ public class POIXMLProperties {
|
|||
throw new POIXMLException(e);
|
||||
}
|
||||
}
|
||||
if(extPart != null){
|
||||
if(extPart != null && ext != null && ext.props != null){
|
||||
try (OutputStream out = extPart.getOutputStream()) {
|
||||
if (extPart.getSize() > 0) {
|
||||
extPart.clear();
|
||||
|
@ -231,7 +231,7 @@ public class POIXMLProperties {
|
|||
ext.props.save(out, DEFAULT_XML_OPTIONS);
|
||||
}
|
||||
}
|
||||
if(custPart != null){
|
||||
if(custPart != null && cust != null && cust.props != null){
|
||||
try (OutputStream out = custPart.getOutputStream()) {
|
||||
cust.props.save(out, DEFAULT_XML_OPTIONS);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import java.io.OutputStream;
|
|||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -416,6 +415,8 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
|
|||
* If your package is open read only, then you should call {@link #revert()}
|
||||
* when finished with the package.
|
||||
*
|
||||
* This method is not thread-safe.
|
||||
*
|
||||
* @throws IOException
|
||||
* If an IO exception occur during the saving process.
|
||||
*/
|
||||
|
@ -434,27 +435,20 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
|
|||
return;
|
||||
}
|
||||
|
||||
// Save the content
|
||||
ReentrantReadWriteLock l = new ReentrantReadWriteLock();
|
||||
try {
|
||||
l.writeLock().lock();
|
||||
if (this.originalPackagePath != null
|
||||
&& !this.originalPackagePath.trim().isEmpty()) {
|
||||
File targetFile = new File(this.originalPackagePath);
|
||||
if (!targetFile.exists()
|
||||
|| !(this.originalPackagePath
|
||||
.equalsIgnoreCase(targetFile.getAbsolutePath()))) {
|
||||
// Case of a package created from scratch
|
||||
save(targetFile);
|
||||
} else {
|
||||
closeImpl();
|
||||
}
|
||||
} else if (this.output != null) {
|
||||
save(this.output);
|
||||
output.close();
|
||||
if (this.originalPackagePath != null
|
||||
&& !this.originalPackagePath.trim().isEmpty()) {
|
||||
File targetFile = new File(this.originalPackagePath);
|
||||
if (!targetFile.exists()
|
||||
|| !(this.originalPackagePath
|
||||
.equalsIgnoreCase(targetFile.getAbsolutePath()))) {
|
||||
// Case of a package created from scratch
|
||||
save(targetFile);
|
||||
} else {
|
||||
closeImpl();
|
||||
}
|
||||
} finally {
|
||||
l.writeLock().unlock();
|
||||
} else if (this.output != null) {
|
||||
save(this.output);
|
||||
output.close();
|
||||
}
|
||||
|
||||
// Clear
|
||||
|
|
|
@ -21,8 +21,6 @@ import java.io.OutputStream;
|
|||
import java.util.Optional;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.stream.XMLEventFactory;
|
||||
import javax.xml.stream.events.Namespace;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
@ -36,105 +34,109 @@ import org.w3c.dom.Element;
|
|||
* Package properties marshaller.
|
||||
*/
|
||||
public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||
private final static Namespace namespaceDC, namespaceCoreProperties, namespaceDcTerms, namespaceXSI;
|
||||
static {
|
||||
final XMLEventFactory f = XMLEventFactory.newInstance();
|
||||
namespaceDC = f.createNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
|
||||
namespaceCoreProperties = f.createNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
|
||||
namespaceDcTerms = f.createNamespace("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
||||
namespaceXSI = f.createNamespace("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
|
||||
}
|
||||
private final static NamespaceImpl namespaceDC =
|
||||
new NamespaceImpl("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
|
||||
private final static NamespaceImpl namespaceCoreProperties =
|
||||
new NamespaceImpl("cp", PackagePropertiesPart.NAMESPACE_CP_URI);;
|
||||
private final static NamespaceImpl namespaceDcTerms =
|
||||
new NamespaceImpl("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
||||
private final static NamespaceImpl namespaceXSI =
|
||||
new NamespaceImpl("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);;
|
||||
|
||||
protected static final String KEYWORD_CATEGORY = "category";
|
||||
protected static final String KEYWORD_CATEGORY = "category";
|
||||
|
||||
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
|
||||
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
|
||||
|
||||
protected static final String KEYWORD_CONTENT_TYPE = "contentType";
|
||||
protected static final String KEYWORD_CONTENT_TYPE = "contentType";
|
||||
|
||||
protected static final String KEYWORD_CREATED = "created";
|
||||
protected static final String KEYWORD_CREATED = "created";
|
||||
|
||||
protected static final String KEYWORD_CREATOR = "creator";
|
||||
protected static final String KEYWORD_CREATOR = "creator";
|
||||
|
||||
protected static final String KEYWORD_DESCRIPTION = "description";
|
||||
protected static final String KEYWORD_DESCRIPTION = "description";
|
||||
|
||||
protected static final String KEYWORD_IDENTIFIER = "identifier";
|
||||
protected static final String KEYWORD_IDENTIFIER = "identifier";
|
||||
|
||||
protected static final String KEYWORD_KEYWORDS = "keywords";
|
||||
protected static final String KEYWORD_KEYWORDS = "keywords";
|
||||
|
||||
protected static final String KEYWORD_LANGUAGE = "language";
|
||||
protected static final String KEYWORD_LANGUAGE = "language";
|
||||
|
||||
protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";
|
||||
protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";
|
||||
|
||||
protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";
|
||||
protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";
|
||||
|
||||
protected static final String KEYWORD_MODIFIED = "modified";
|
||||
protected static final String KEYWORD_MODIFIED = "modified";
|
||||
|
||||
protected static final String KEYWORD_REVISION = "revision";
|
||||
protected static final String KEYWORD_REVISION = "revision";
|
||||
|
||||
protected static final String KEYWORD_SUBJECT = "subject";
|
||||
protected static final String KEYWORD_SUBJECT = "subject";
|
||||
|
||||
protected static final String KEYWORD_TITLE = "title";
|
||||
protected static final String KEYWORD_TITLE = "title";
|
||||
|
||||
protected static final String KEYWORD_VERSION = "version";
|
||||
protected static final String KEYWORD_VERSION = "version";
|
||||
|
||||
PackagePropertiesPart propsPart;
|
||||
PackagePropertiesPart propsPart;
|
||||
|
||||
// The document
|
||||
Document xmlDoc;
|
||||
// The document
|
||||
Document xmlDoc;
|
||||
|
||||
/**
|
||||
* Marshall package core properties to an XML document. Always return
|
||||
* <code>true</code>.
|
||||
*/
|
||||
@Override
|
||||
public boolean marshall(PackagePart part, OutputStream out)
|
||||
throws OpenXML4JException {
|
||||
if (!(part instanceof PackagePropertiesPart))
|
||||
throw new IllegalArgumentException(
|
||||
"'part' must be a PackagePropertiesPart instance.");
|
||||
propsPart = (PackagePropertiesPart) part;
|
||||
/**
|
||||
* Marshall package core properties to an XML document. Always return
|
||||
* <code>true</code>.
|
||||
*/
|
||||
@Override
|
||||
public boolean marshall(PackagePart part, OutputStream out)
|
||||
throws OpenXML4JException {
|
||||
if (!(part instanceof PackagePropertiesPart))
|
||||
throw new IllegalArgumentException(
|
||||
"'part' must be a PackagePropertiesPart instance.");
|
||||
propsPart = (PackagePropertiesPart) part;
|
||||
|
||||
// Configure the document
|
||||
xmlDoc = DocumentHelper.createDocument();
|
||||
// Configure the document
|
||||
xmlDoc = DocumentHelper.createDocument();
|
||||
Element rootElem = xmlDoc.createElementNS(namespaceCoreProperties.getNamespaceURI(),
|
||||
getQName("coreProperties", namespaceCoreProperties));
|
||||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceCoreProperties);
|
||||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDC);
|
||||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDcTerms);
|
||||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceXSI);
|
||||
DocumentHelper.addNamespaceDeclaration(rootElem,
|
||||
namespaceCoreProperties.getPrefix(), namespaceCoreProperties.getNamespaceURI());
|
||||
DocumentHelper.addNamespaceDeclaration(rootElem,
|
||||
namespaceDC.getPrefix(), namespaceDC.getNamespaceURI());
|
||||
DocumentHelper.addNamespaceDeclaration(rootElem,
|
||||
namespaceDcTerms.getPrefix(), namespaceDcTerms.getNamespaceURI());
|
||||
DocumentHelper.addNamespaceDeclaration(rootElem,
|
||||
namespaceXSI.getPrefix(), namespaceXSI.getNamespaceURI());
|
||||
xmlDoc.appendChild(rootElem);
|
||||
|
||||
addCategory();
|
||||
addContentStatus();
|
||||
addContentType();
|
||||
addCreated();
|
||||
addCreator();
|
||||
addDescription();
|
||||
addIdentifier();
|
||||
addKeywords();
|
||||
addLanguage();
|
||||
addLastModifiedBy();
|
||||
addLastPrinted();
|
||||
addModified();
|
||||
addRevision();
|
||||
addSubject();
|
||||
addTitle();
|
||||
addVersion();
|
||||
return true;
|
||||
}
|
||||
addCategory();
|
||||
addContentStatus();
|
||||
addContentType();
|
||||
addCreated();
|
||||
addCreator();
|
||||
addDescription();
|
||||
addIdentifier();
|
||||
addKeywords();
|
||||
addLanguage();
|
||||
addLastModifiedBy();
|
||||
addLastPrinted();
|
||||
addModified();
|
||||
addRevision();
|
||||
addSubject();
|
||||
addTitle();
|
||||
addVersion();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given element's text content, creating it if necessary.
|
||||
*/
|
||||
private Element setElementTextContent(String localName, Namespace namespace, Optional<String> property) {
|
||||
private Element setElementTextContent(String localName, NamespaceImpl namespace, Optional<String> property) {
|
||||
return setElementTextContent(localName, namespace, property, property.orElse(null));
|
||||
}
|
||||
|
||||
private String getQName(String localName, Namespace namespace) {
|
||||
|
||||
private String getQName(String localName, NamespaceImpl namespace) {
|
||||
return namespace.getPrefix().isEmpty() ? localName : namespace.getPrefix() + ':' + localName;
|
||||
}
|
||||
|
||||
private Element setElementTextContent(String localName, Namespace namespace, Optional<?> property, String propertyValue) {
|
||||
private Element setElementTextContent(String localName, NamespaceImpl namespace, Optional<?> property, String propertyValue) {
|
||||
if (!property.isPresent())
|
||||
return null;
|
||||
|
||||
|
@ -149,7 +151,7 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
|||
return elem;
|
||||
}
|
||||
|
||||
private Element setElementTextContent(String localName, Namespace namespace, Optional<?> property, String propertyValue, String xsiType) {
|
||||
private Element setElementTextContent(String localName, NamespaceImpl namespace, Optional<?> property, String propertyValue, String xsiType) {
|
||||
Element element = setElementTextContent(localName, namespace, property, propertyValue);
|
||||
if (element != null) {
|
||||
element.setAttributeNS(namespaceXSI.getNamespaceURI(), getQName("type", namespaceXSI), xsiType);
|
||||
|
@ -159,114 +161,129 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
|||
|
||||
|
||||
/**
|
||||
* Add category property element if needed.
|
||||
*/
|
||||
private void addCategory() {
|
||||
* Add category property element if needed.
|
||||
*/
|
||||
private void addCategory() {
|
||||
setElementTextContent(KEYWORD_CATEGORY, namespaceCoreProperties, propsPart.getCategoryProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content status property element if needed.
|
||||
*/
|
||||
private void addContentStatus() {
|
||||
setElementTextContent(KEYWORD_CONTENT_STATUS, namespaceCoreProperties, propsPart.getContentStatusProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content type property element if needed.
|
||||
*/
|
||||
private void addContentType() {
|
||||
setElementTextContent(KEYWORD_CONTENT_TYPE, namespaceCoreProperties, propsPart.getContentTypeProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add created property element if needed.
|
||||
*/
|
||||
private void addCreated() {
|
||||
setElementTextContent(KEYWORD_CREATED, namespaceDcTerms, propsPart.getCreatedProperty(),
|
||||
propsPart.getCreatedPropertyString(), "dcterms:W3CDTF");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add creator property element if needed.
|
||||
*/
|
||||
private void addCreator() {
|
||||
setElementTextContent(KEYWORD_CREATOR, namespaceDC, propsPart.getCreatorProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add description property element if needed.
|
||||
*/
|
||||
private void addDescription() {
|
||||
setElementTextContent(KEYWORD_DESCRIPTION, namespaceDC, propsPart.getDescriptionProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add identifier property element if needed.
|
||||
*/
|
||||
private void addIdentifier() {
|
||||
setElementTextContent(KEYWORD_IDENTIFIER, namespaceDC, propsPart.getIdentifierProperty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add keywords property element if needed.
|
||||
*/
|
||||
private void addKeywords() {
|
||||
* Add content status property element if needed.
|
||||
*/
|
||||
private void addContentStatus() {
|
||||
setElementTextContent(KEYWORD_CONTENT_STATUS, namespaceCoreProperties, propsPart.getContentStatusProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content type property element if needed.
|
||||
*/
|
||||
private void addContentType() {
|
||||
setElementTextContent(KEYWORD_CONTENT_TYPE, namespaceCoreProperties, propsPart.getContentTypeProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add created property element if needed.
|
||||
*/
|
||||
private void addCreated() {
|
||||
setElementTextContent(KEYWORD_CREATED, namespaceDcTerms, propsPart.getCreatedProperty(),
|
||||
propsPart.getCreatedPropertyString(), "dcterms:W3CDTF");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add creator property element if needed.
|
||||
*/
|
||||
private void addCreator() {
|
||||
setElementTextContent(KEYWORD_CREATOR, namespaceDC, propsPart.getCreatorProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add description property element if needed.
|
||||
*/
|
||||
private void addDescription() {
|
||||
setElementTextContent(KEYWORD_DESCRIPTION, namespaceDC, propsPart.getDescriptionProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add identifier property element if needed.
|
||||
*/
|
||||
private void addIdentifier() {
|
||||
setElementTextContent(KEYWORD_IDENTIFIER, namespaceDC, propsPart.getIdentifierProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add keywords property element if needed.
|
||||
*/
|
||||
private void addKeywords() {
|
||||
setElementTextContent(KEYWORD_KEYWORDS, namespaceCoreProperties, propsPart.getKeywordsProperty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add language property element if needed.
|
||||
*/
|
||||
private void addLanguage() {
|
||||
/**
|
||||
* Add language property element if needed.
|
||||
*/
|
||||
private void addLanguage() {
|
||||
setElementTextContent(KEYWORD_LANGUAGE, namespaceDC, propsPart.getLanguageProperty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'last modified by' property if needed.
|
||||
*/
|
||||
private void addLastModifiedBy() {
|
||||
/**
|
||||
* Add 'last modified by' property if needed.
|
||||
*/
|
||||
private void addLastModifiedBy() {
|
||||
setElementTextContent(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties, propsPart.getLastModifiedByProperty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'last printed' property if needed.
|
||||
*
|
||||
*/
|
||||
private void addLastPrinted() {
|
||||
/**
|
||||
* Add 'last printed' property if needed.
|
||||
*/
|
||||
private void addLastPrinted() {
|
||||
setElementTextContent(KEYWORD_LAST_PRINTED, namespaceCoreProperties, propsPart.getLastPrintedProperty(), propsPart.getLastPrintedPropertyString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add modified property element if needed.
|
||||
*/
|
||||
private void addModified() {
|
||||
/**
|
||||
* Add modified property element if needed.
|
||||
*/
|
||||
private void addModified() {
|
||||
setElementTextContent(KEYWORD_MODIFIED, namespaceDcTerms, propsPart.getModifiedProperty(),
|
||||
propsPart.getModifiedPropertyString(), "dcterms:W3CDTF");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add revision property if needed.
|
||||
*/
|
||||
private void addRevision() {
|
||||
/**
|
||||
* Add revision property if needed.
|
||||
*/
|
||||
private void addRevision() {
|
||||
setElementTextContent(KEYWORD_REVISION, namespaceCoreProperties, propsPart.getRevisionProperty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subject property if needed.
|
||||
*/
|
||||
private void addSubject() {
|
||||
/**
|
||||
* Add subject property if needed.
|
||||
*/
|
||||
private void addSubject() {
|
||||
setElementTextContent(KEYWORD_SUBJECT, namespaceDC, propsPart.getSubjectProperty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add title property if needed.
|
||||
*/
|
||||
private void addTitle() {
|
||||
/**
|
||||
* Add title property if needed.
|
||||
*/
|
||||
private void addTitle() {
|
||||
setElementTextContent(KEYWORD_TITLE, namespaceDC, propsPart.getTitleProperty());
|
||||
}
|
||||
}
|
||||
|
||||
private void addVersion() {
|
||||
private void addVersion() {
|
||||
setElementTextContent(KEYWORD_VERSION, namespaceCoreProperties, propsPart.getVersionProperty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class NamespaceImpl {
|
||||
private final String prefix;
|
||||
private final String namespaceURI;
|
||||
|
||||
NamespaceImpl(String prefix, String namespaceURI) {
|
||||
this.prefix = prefix;
|
||||
this.namespaceURI = namespaceURI;
|
||||
}
|
||||
|
||||
public String getPrefix() { return prefix; }
|
||||
|
||||
public String getNamespaceURI() {
|
||||
return namespaceURI;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,12 +17,17 @@
|
|||
|
||||
package org.apache.poi.openxml4j.util;
|
||||
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* An immutable object that could be defined as null.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.9
|
||||
* @deprecated No longer used in POI code base, use {@link java.util.Optional} instead
|
||||
*/
|
||||
@Removal(version = "4.2")
|
||||
@Deprecated
|
||||
public final class Nullable<E> {
|
||||
|
||||
private E value;
|
||||
|
|
|
@ -150,7 +150,7 @@ import org.w3c.dom.events.EventTarget;
|
|||
* <p>To use SignatureInfo and its sibling classes, you'll need to have the following libs
|
||||
* in the classpath:</p>
|
||||
* <ul>
|
||||
* <li>BouncyCastle bcpkix and bcprov (tested against 1.59)</li>
|
||||
* <li>BouncyCastle bcpkix and bcprov (tested against 1.60)</li>
|
||||
* <li>Apache Santuario "xmlsec" (tested against 2.1.0)</li>
|
||||
* <li>and slf4j-api (tested against 1.7.25)</li>
|
||||
* </ul>
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* ====================================================================
|
||||
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.xddf.usermodel.chart;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.STDispBlanksAs;
|
||||
|
||||
public enum DisplayBlanks {
|
||||
GAP(STDispBlanksAs.GAP),
|
||||
SPAN(STDispBlanksAs.SPAN),
|
||||
ZERO(STDispBlanksAs.ZERO);
|
||||
|
||||
final STDispBlanksAs.Enum underlying;
|
||||
|
||||
DisplayBlanks(STDispBlanksAs.Enum mode) {
|
||||
this.underlying = mode;
|
||||
}
|
||||
|
||||
private final static HashMap<STDispBlanksAs.Enum, DisplayBlanks> reverse = new HashMap<>();
|
||||
static {
|
||||
for (DisplayBlanks value : values()) {
|
||||
reverse.put(value.underlying, value);
|
||||
}
|
||||
}
|
||||
|
||||
static DisplayBlanks valueOf(STDispBlanksAs.Enum mode) {
|
||||
return reverse.get(mode);
|
||||
}
|
||||
}
|
|
@ -34,9 +34,24 @@ public class XDDFBarChartData extends XDDFChartData {
|
|||
public XDDFBarChartData(CTBarChart chart, Map<Long, XDDFChartAxis> categories,
|
||||
Map<Long, XDDFValueAxis> values) {
|
||||
this.chart = chart;
|
||||
if (chart.getBarDir() == null) {
|
||||
chart.addNewBarDir().setVal(BarDirection.BAR.underlying);
|
||||
}
|
||||
for (CTBarSer series : chart.getSerList()) {
|
||||
this.series.add(new Series(series, series.getCat(), series.getVal()));
|
||||
}
|
||||
defineAxes(categories, values);
|
||||
}
|
||||
|
||||
private void defineAxes(Map<Long, XDDFChartAxis> categories, Map<Long, XDDFValueAxis> values) {
|
||||
if (chart.sizeOfAxIdArray() == 0) {
|
||||
for (Long id : categories.keySet()) {
|
||||
chart.addNewAxId().setVal(id);
|
||||
}
|
||||
for (Long id : values.keySet()) {
|
||||
chart.addNewAxId().setVal(id);
|
||||
}
|
||||
}
|
||||
defineAxes(chart.getAxIdArray(), categories, values);
|
||||
}
|
||||
|
||||
|
@ -94,6 +109,7 @@ public class XDDFBarChartData extends XDDFChartData {
|
|||
XDDFNumericalDataSource<? extends Number> values) {
|
||||
final int index = this.series.size();
|
||||
final CTBarSer ctSer = this.chart.addNewSer();
|
||||
ctSer.addNewTx();
|
||||
ctSer.addNewCat();
|
||||
ctSer.addNewVal();
|
||||
ctSer.addNewIdx().setVal(index);
|
||||
|
@ -119,7 +135,11 @@ public class XDDFBarChartData extends XDDFChartData {
|
|||
|
||||
@Override
|
||||
protected CTSerTx getSeriesText() {
|
||||
return series.getTx();
|
||||
if (series.isSetTx()) {
|
||||
return series.getTx();
|
||||
} else {
|
||||
return series.addNewTx();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -79,6 +79,19 @@ public class XDDFCategoryAxis extends XDDFChartAxis {
|
|||
return new XDDFShapeProperties(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
@Override
|
||||
public void setTitle(String text) {
|
||||
if (!ctCatAx.isSetTitle()) {
|
||||
ctCatAx.addNewTitle();
|
||||
}
|
||||
XDDFTitle title = new XDDFTitle(null, ctCatAx.getTitle());
|
||||
title.setOverlay(false);
|
||||
title.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetMinorUnit() {
|
||||
return false;
|
||||
|
|
|
@ -23,4 +23,23 @@ import org.apache.poi.util.Beta;
|
|||
|
||||
@Beta
|
||||
public interface XDDFCategoryDataSource extends XDDFDataSource<String> {
|
||||
@Override
|
||||
default int getColIndex() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isNumeric() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isReference() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
default String getDataRangeReference() {
|
||||
return getFormula();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,6 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
|
|||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerAx;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurface;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTx;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
|
||||
|
@ -214,6 +213,72 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
|
|||
chart.getAutoTitleDeleted().setVal(deleted);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*
|
||||
*/
|
||||
public void displayBlanksAs(DisplayBlanks as) {
|
||||
if (as == null){
|
||||
if (chart.isSetDispBlanksAs()) {
|
||||
chart.unsetDispBlanksAs();
|
||||
}
|
||||
} else {
|
||||
if (chart.isSetDispBlanksAs()) {
|
||||
chart.getDispBlanksAs().setVal(as.underlying);
|
||||
} else {
|
||||
chart.addNewDispBlanksAs().setVal(as.underlying);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public Boolean getTitleOverlay() {
|
||||
if (chart.isSetTitle()) {
|
||||
CTTitle title = chart.getTitle();
|
||||
if (title.isSetOverlay()) {
|
||||
return title.getOverlay().getVal();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public void setTitleOverlay(boolean overlay) {
|
||||
if (!chart.isSetTitle()) {
|
||||
chart.addNewTitle();
|
||||
}
|
||||
new XDDFTitle(this, chart.getTitle()).setOverlay(overlay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title text as a static string.
|
||||
*
|
||||
* @param text
|
||||
* to use as new title
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public void setTitleText(String text) {
|
||||
if (!chart.isSetTitle()) {
|
||||
chart.addNewTitle();
|
||||
}
|
||||
new XDDFTitle(this, chart.getTitle()).setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public XDDFTitle getTitle() {
|
||||
if (chart.isSetTitle()) {
|
||||
return new XDDFTitle(this, chart.getTitle());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chart title body if there is one, i.e. title is set and is not a
|
||||
* formula.
|
||||
|
@ -225,15 +290,7 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
|
|||
if (!chart.isSetTitle()) {
|
||||
return null;
|
||||
}
|
||||
CTTitle title = chart.getTitle();
|
||||
if (!title.isSetTx()) {
|
||||
return null;
|
||||
}
|
||||
CTTx tx = title.getTx();
|
||||
if (!tx.isSetRich()) {
|
||||
return null;
|
||||
}
|
||||
return new XDDFTextBody(this, tx.getRich());
|
||||
return new XDDFTitle(this, chart.getTitle()).getBody();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -327,7 +384,7 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
|
|||
private Map<Long, XDDFChartAxis> getCategoryAxes() {
|
||||
CTPlotArea plotArea = getCTPlotArea();
|
||||
int sizeOfArray = plotArea.sizeOfCatAxArray();
|
||||
Map<Long, XDDFChartAxis> axes = new HashMap<Long, XDDFChartAxis>(sizeOfArray);
|
||||
Map<Long, XDDFChartAxis> axes = new HashMap<>(sizeOfArray);
|
||||
for (int i = 0; i < sizeOfArray; i++) {
|
||||
CTCatAx category = plotArea.getCatAxArray(i);
|
||||
axes.put(category.getAxId().getVal(), new XDDFCategoryAxis(category));
|
||||
|
@ -641,20 +698,22 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
|
|||
}
|
||||
|
||||
/**
|
||||
* set sheet time in excel file
|
||||
* set sheet title in excel file
|
||||
*
|
||||
* @param title
|
||||
* title of sheet
|
||||
* @param column
|
||||
* column index
|
||||
* @return return cell reference
|
||||
* @since POI 4.0.0
|
||||
*/
|
||||
public CellReference setSheetTitle(String title) {
|
||||
public CellReference setSheetTitle(String title, int column) {
|
||||
XSSFSheet sheet = getSheet();
|
||||
XSSFRow row = this.getRow(sheet, 0);
|
||||
XSSFCell cell = this.getCell(row, 1);
|
||||
XSSFCell cell = this.getCell(row, column);
|
||||
cell.setCellValue(title);
|
||||
this.updateSheetTable(sheet.getTables().get(0).getCTTable(), title, 1);
|
||||
return new CellReference(sheet.getSheetName(), 0, 1, true, true);
|
||||
this.updateSheetTable(sheet.getTables().get(0).getCTTable(), title, column);
|
||||
return new CellReference(sheet.getSheetName(), 0, column, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -670,12 +729,11 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
|
|||
private void updateSheetTable(CTTable ctTable, String title, int index) {
|
||||
CTTableColumns tableColumnList = ctTable.getTableColumns();
|
||||
CTTableColumn column = null;
|
||||
if (tableColumnList.getCount() >= index) {
|
||||
column = tableColumnList.getTableColumnArray(index);
|
||||
} else {
|
||||
for( int i = 0; tableColumnList.getCount() < index; i++) {
|
||||
column = tableColumnList.addNewTableColumn();
|
||||
column.setId(index);
|
||||
column.setId(i);
|
||||
}
|
||||
column = tableColumnList.getTableColumnArray(index);
|
||||
column.setName(title);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,11 @@ public abstract class XDDFChartAxis implements HasShapeProperties {
|
|||
|
||||
public abstract XDDFShapeProperties getOrAddMinorGridProperties();
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public abstract void setTitle(String text);
|
||||
|
||||
/**
|
||||
* @return true if minor unit value is defined, false otherwise
|
||||
*/
|
||||
|
|
|
@ -130,6 +130,10 @@ public abstract class XDDFChartData {
|
|||
} else {
|
||||
cache = ref.addNewStrCache();
|
||||
}
|
||||
if (cache.sizeOfPtArray() < 1) {
|
||||
cache.addNewPtCount().setVal(1);
|
||||
cache.addNewPt().setIdx(0);;
|
||||
}
|
||||
cache.getPtArray(0).setV(title);
|
||||
ref.setF(titleRef.formatAsString());
|
||||
}
|
||||
|
|
|
@ -34,4 +34,6 @@ public interface XDDFDataSource<T> {
|
|||
int getColIndex();
|
||||
|
||||
String getDataRangeReference();
|
||||
|
||||
String getFormula();
|
||||
}
|
||||
|
|
|
@ -41,39 +41,50 @@ public class XDDFDataSourcesFactory {
|
|||
}
|
||||
|
||||
public static XDDFCategoryDataSource fromDataSource(final CTAxDataSource categoryDS) {
|
||||
return new XDDFCategoryDataSource() {
|
||||
private CTStrData category = (CTStrData) categoryDS.getStrRef().getStrCache().copy();
|
||||
if (categoryDS.getStrRef() == null) {
|
||||
return new XDDFCategoryDataSource() {
|
||||
private CTNumData category = (CTNumData) categoryDS.getNumRef().getNumCache().copy();
|
||||
|
||||
@Override
|
||||
public boolean isNumeric() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isNumeric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReference() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String getFormula() {
|
||||
return categoryDS.getNumRef().getF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPointCount() {
|
||||
return (int) category.getPtCount().getVal();
|
||||
}
|
||||
@Override
|
||||
public int getPointCount() {
|
||||
return (int) category.getPtCount().getVal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPointAt(int index) {
|
||||
return category.getPtArray(index).getV();
|
||||
}
|
||||
@Override
|
||||
public String getPointAt(int index) {
|
||||
return category.getPtArray(index).getV();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return new XDDFCategoryDataSource() {
|
||||
private CTStrData category = (CTStrData) categoryDS.getStrRef().getStrCache().copy();
|
||||
|
||||
@Override
|
||||
public String getDataRangeReference() {
|
||||
return categoryDS.getStrRef().getF();
|
||||
}
|
||||
@Override
|
||||
public String getFormula() {
|
||||
return categoryDS.getStrRef().getF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColIndex() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public int getPointCount() {
|
||||
return (int) category.getPtCount().getVal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPointAt(int index) {
|
||||
return category.getPtArray(index).getV();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static XDDFNumericalDataSource<Double> fromDataSource(final CTNumDataSource valuesDS) {
|
||||
|
@ -81,6 +92,11 @@ public class XDDFDataSourcesFactory {
|
|||
private CTNumData values = (CTNumData) valuesDS.getNumRef().getNumCache().copy();
|
||||
private String formatCode = values.isSetFormatCode() ? values.getFormatCode() : null;
|
||||
|
||||
@Override
|
||||
public String getFormula() {
|
||||
return valuesDS.getNumRef().getF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormatCode() {
|
||||
return formatCode;
|
||||
|
@ -124,7 +140,7 @@ public class XDDFDataSourcesFactory {
|
|||
}
|
||||
|
||||
public static <T extends Number> XDDFNumericalDataSource<T> fromArray(T[] elements, String dataRange) {
|
||||
return new NumericalArrayDataSource<T>(elements, dataRange);
|
||||
return new NumericalArrayDataSource<>(elements, dataRange);
|
||||
}
|
||||
|
||||
public static XDDFCategoryDataSource fromArray(String[] elements, String dataRange) {
|
||||
|
@ -132,7 +148,7 @@ public class XDDFDataSourcesFactory {
|
|||
}
|
||||
|
||||
public static <T extends Number> XDDFNumericalDataSource<T> fromArray(T[] elements, String dataRange, int col) {
|
||||
return new NumericalArrayDataSource<T>(elements, dataRange, col);
|
||||
return new NumericalArrayDataSource<>(elements, dataRange, col);
|
||||
}
|
||||
|
||||
public static XDDFCategoryDataSource fromArray(String[] elements, String dataRange, int col) {
|
||||
|
@ -212,6 +228,11 @@ public class XDDFDataSourcesFactory {
|
|||
super(elements, dataRange, col);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormula() {
|
||||
return getDataRangeReference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormatCode() {
|
||||
return formatCode;
|
||||
|
@ -232,6 +253,11 @@ public class XDDFDataSourcesFactory {
|
|||
public StringArrayDataSource(String[] elements, String dataRange, int col) {
|
||||
super(elements, dataRange, col);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormula() {
|
||||
return getDataRangeReference();
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class AbstractCellRangeDataSource<T> implements XDDFDataSource<T> {
|
||||
|
@ -290,6 +316,11 @@ public class XDDFDataSourcesFactory {
|
|||
super(sheet, cellRangeAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormula() {
|
||||
return getDataRangeReference();
|
||||
}
|
||||
|
||||
private String formatCode;
|
||||
|
||||
@Override
|
||||
|
@ -324,6 +355,11 @@ public class XDDFDataSourcesFactory {
|
|||
super(sheet, cellRangeAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormula() {
|
||||
return getDataRangeReference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPointAt(int index) {
|
||||
CellValue cellValue = getCellValueAt(index);
|
||||
|
|
|
@ -82,6 +82,19 @@ public class XDDFDateAxis extends XDDFChartAxis {
|
|||
return new XDDFShapeProperties(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
@Override
|
||||
public void setTitle(String text) {
|
||||
if (!ctDateAx.isSetTitle()) {
|
||||
ctDateAx.addNewTitle();
|
||||
}
|
||||
XDDFTitle title = new XDDFTitle(null, ctDateAx.getTitle());
|
||||
title.setOverlay(false);
|
||||
title.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetMinorUnit() {
|
||||
return ctDateAx.isSetMinorUnit();
|
||||
|
|
|
@ -38,6 +38,18 @@ public class XDDFLineChartData extends XDDFChartData {
|
|||
for (CTLineSer series : chart.getSerList()) {
|
||||
this.series.add(new Series(series, series.getCat(), series.getVal()));
|
||||
}
|
||||
defineAxes(categories, values);
|
||||
}
|
||||
|
||||
private void defineAxes(Map<Long, XDDFChartAxis> categories, Map<Long, XDDFValueAxis> values) {
|
||||
if (chart.sizeOfAxIdArray() == 0) {
|
||||
for (Long id : categories.keySet()) {
|
||||
chart.addNewAxId().setVal(id);
|
||||
}
|
||||
for (Long id : values.keySet()) {
|
||||
chart.addNewAxId().setVal(id);
|
||||
}
|
||||
}
|
||||
defineAxes(chart.getAxIdArray(), categories, values);
|
||||
}
|
||||
|
||||
|
@ -88,7 +100,11 @@ public class XDDFLineChartData extends XDDFChartData {
|
|||
|
||||
@Override
|
||||
protected CTSerTx getSeriesText() {
|
||||
return series.getTx();
|
||||
if (series.isSetTx()) {
|
||||
return series.getTx();
|
||||
} else {
|
||||
return series.addNewTx();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,7 +143,44 @@ public class XDDFLineChartData extends XDDFChartData {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public Boolean getSmooth() {
|
||||
if (series.isSetSmooth()) {
|
||||
return series.getSmooth().getVal();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param smooth
|
||||
* whether or not to smooth lines, if <code>null</code> then reverts to default.
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public void setSmooth(Boolean smooth) {
|
||||
if (smooth == null) {
|
||||
if (series.isSetSmooth()) {
|
||||
series.unsetSmooth();
|
||||
}
|
||||
} else {
|
||||
if (series.isSetSmooth()) {
|
||||
series.getSmooth().setVal(smooth);
|
||||
} else {
|
||||
series.addNewSmooth().setVal(smooth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size
|
||||
* <dl><dt>Minimum inclusive:</dt><dd>2</dd><dt>Maximum inclusive:</dt><dd>72</dd></dl>
|
||||
*/
|
||||
public void setMarkerSize(short size) {
|
||||
if (size < 2 || 72 < size) {
|
||||
throw new IllegalArgumentException("Minimum inclusive: 2; Maximum inclusive: 72");
|
||||
}
|
||||
CTMarker marker = getMarker();
|
||||
if (marker.isSetSize()) {
|
||||
marker.getSize().setVal(size);
|
||||
|
|
|
@ -75,7 +75,11 @@ public class XDDFPieChartData extends XDDFChartData {
|
|||
|
||||
@Override
|
||||
protected CTSerTx getSeriesText() {
|
||||
return series.getTx();
|
||||
if (series.isSetTx()) {
|
||||
return series.getTx();
|
||||
} else {
|
||||
return series.addNewTx();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,6 +38,18 @@ public class XDDFRadarChartData extends XDDFChartData {
|
|||
for (CTRadarSer series : chart.getSerList()) {
|
||||
this.series.add(new Series(series, series.getCat(), series.getVal()));
|
||||
}
|
||||
defineAxes(categories, values);
|
||||
}
|
||||
|
||||
private void defineAxes(Map<Long, XDDFChartAxis> categories, Map<Long, XDDFValueAxis> values) {
|
||||
if (chart.sizeOfAxIdArray() == 0) {
|
||||
for (Long id : categories.keySet()) {
|
||||
chart.addNewAxId().setVal(id);
|
||||
}
|
||||
for (Long id : values.keySet()) {
|
||||
chart.addNewAxId().setVal(id);
|
||||
}
|
||||
}
|
||||
defineAxes(chart.getAxIdArray(), categories, values);
|
||||
}
|
||||
|
||||
|
@ -92,7 +104,11 @@ public class XDDFRadarChartData extends XDDFChartData {
|
|||
|
||||
@Override
|
||||
protected CTSerTx getSeriesText() {
|
||||
return series.getTx();
|
||||
if (series.isSetTx()) {
|
||||
return series.getTx();
|
||||
} else {
|
||||
return series.addNewTx();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
|||
import org.apache.poi.util.Beta;
|
||||
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTMarker;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer;
|
||||
|
@ -38,6 +39,18 @@ public class XDDFScatterChartData extends XDDFChartData {
|
|||
for (CTScatterSer series : chart.getSerList()) {
|
||||
this.series.add(new Series(series, series.getXVal(), series.getYVal()));
|
||||
}
|
||||
defineAxes(categories, values);
|
||||
}
|
||||
|
||||
private void defineAxes(Map<Long, XDDFChartAxis> categories, Map<Long, XDDFValueAxis> values) {
|
||||
if (chart.sizeOfAxIdArray() == 0) {
|
||||
for (Long id : categories.keySet()) {
|
||||
chart.addNewAxId().setVal(id);
|
||||
}
|
||||
for (Long id : values.keySet()) {
|
||||
chart.addNewAxId().setVal(id);
|
||||
}
|
||||
}
|
||||
defineAxes(chart.getAxIdArray(), categories, values);
|
||||
}
|
||||
|
||||
|
@ -96,7 +109,78 @@ public class XDDFScatterChartData extends XDDFChartData {
|
|||
|
||||
@Override
|
||||
protected CTSerTx getSeriesText() {
|
||||
return series.getTx();
|
||||
if (series.isSetTx()) {
|
||||
return series.getTx();
|
||||
} else {
|
||||
return series.addNewTx();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public Boolean getSmooth() {
|
||||
if (series.isSetSmooth()) {
|
||||
return series.getSmooth().getVal();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param smooth
|
||||
* whether or not to smooth lines, if <code>null</code> then reverts to default.
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public void setSmooth(Boolean smooth) {
|
||||
if (smooth == null) {
|
||||
if (series.isSetSmooth()) {
|
||||
series.unsetSmooth();
|
||||
}
|
||||
} else {
|
||||
if (series.isSetSmooth()) {
|
||||
series.getSmooth().setVal(smooth);
|
||||
} else {
|
||||
series.addNewSmooth().setVal(smooth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size
|
||||
* <dl><dt>Minimum inclusive:</dt><dd>2</dd><dt>Maximum inclusive:</dt><dd>72</dd></dl>
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public void setMarkerSize(short size) {
|
||||
if (size < 2 || 72 < size) {
|
||||
throw new IllegalArgumentException("Minimum inclusive: 2; Maximum inclusive: 72");
|
||||
}
|
||||
CTMarker marker = getMarker();
|
||||
if (marker.isSetSize()) {
|
||||
marker.getSize().setVal(size);
|
||||
} else {
|
||||
marker.addNewSize().setVal(size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public void setMarkerStyle(MarkerStyle style) {
|
||||
CTMarker marker = getMarker();
|
||||
if (marker.isSetSymbol()) {
|
||||
marker.getSymbol().setVal(style.underlying);
|
||||
} else {
|
||||
marker.addNewSymbol().setVal(style.underlying);
|
||||
}
|
||||
}
|
||||
|
||||
private CTMarker getMarker() {
|
||||
if (series.isSetMarker()) {
|
||||
return series.getMarker();
|
||||
} else {
|
||||
return series.addNewMarker();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -79,6 +79,19 @@ public class XDDFSeriesAxis extends XDDFChartAxis {
|
|||
return new XDDFShapeProperties(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
@Override
|
||||
public void setTitle(String text) {
|
||||
if (!ctSerAx.isSetTitle()) {
|
||||
ctSerAx.addNewTitle();
|
||||
}
|
||||
XDDFTitle title = new XDDFTitle(null, ctSerAx.getTitle());
|
||||
title.setOverlay(false);
|
||||
title.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetMinorUnit() {
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.xddf.usermodel.chart;
|
||||
|
||||
import org.apache.poi.util.Beta;
|
||||
import org.apache.poi.xddf.usermodel.text.TextContainer;
|
||||
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTx;
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
@Beta
|
||||
public class XDDFTitle {
|
||||
private final CTTitle title;
|
||||
private final TextContainer parent;
|
||||
|
||||
public XDDFTitle(TextContainer parent, CTTitle title) {
|
||||
this.parent = parent;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public XDDFTextBody getBody() {
|
||||
if (!title.isSetTx()) {
|
||||
title.addNewTx();
|
||||
}
|
||||
CTTx tx = title.getTx();
|
||||
if (tx.isSetStrRef()) {
|
||||
tx.unsetStrRef();
|
||||
}
|
||||
if (!tx.isSetRich()) {
|
||||
tx.addNewRich();
|
||||
}
|
||||
return new XDDFTextBody(parent, tx.getRich());
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
if (!title.isSetLayout()) {
|
||||
title.addNewLayout();
|
||||
}
|
||||
getBody().setText(text);
|
||||
}
|
||||
|
||||
public void setOverlay(Boolean overlay) {
|
||||
if (overlay == null) {
|
||||
if (title.isSetOverlay()) {
|
||||
title.unsetOverlay();
|
||||
}
|
||||
} else {
|
||||
if (title.isSetOverlay()) {
|
||||
title.getOverlay().setVal(overlay);
|
||||
} else {
|
||||
title.addNewOverlay().setVal(overlay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -78,6 +78,19 @@ public class XDDFValueAxis extends XDDFChartAxis {
|
|||
return new XDDFShapeProperties(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
@Override
|
||||
public void setTitle(String text) {
|
||||
if (!ctValAx.isSetTitle()) {
|
||||
ctValAx.addNewTitle();
|
||||
}
|
||||
XDDFTitle title = new XDDFTitle(null, ctValAx.getTitle());
|
||||
title.setOverlay(false);
|
||||
title.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetMinorUnit() {
|
||||
return ctValAx.isSetMinorUnit();
|
||||
|
|
|
@ -67,6 +67,16 @@ public class XDDFParagraphProperties {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public XDDFRunProperties addDefaultRunProperties() {
|
||||
if (!props.isSetDefRPr()) {
|
||||
props.addNewDefRPr();
|
||||
}
|
||||
return getDefaultRunProperties();
|
||||
}
|
||||
|
||||
public XDDFRunProperties getDefaultRunProperties() {
|
||||
if (props.isSetDefRPr()) {
|
||||
return new XDDFRunProperties(props.getDefRPr());
|
||||
|
|
|
@ -70,6 +70,19 @@ public class XDDFTextBody {
|
|||
return p;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
if (_body.sizeOfPArray() > 0) {
|
||||
// remove all but first paragraph
|
||||
for (int i = _body.sizeOfPArray() - 1; i > 0; i--) {
|
||||
_body.removeP(i);
|
||||
}
|
||||
getParagraph(0).setText(text);
|
||||
} else {
|
||||
// as there were no paragraphs yet, initialize the text body
|
||||
initialize().setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public XDDFTextParagraph addNewParagraph() {
|
||||
return new XDDFTextParagraph(_body.addNewP(), this);
|
||||
}
|
||||
|
|
|
@ -69,6 +69,24 @@ public class XDDFTextParagraph {
|
|||
_runs.add(new XDDFTextRun((CTRegularTextRun) xo, this));
|
||||
}
|
||||
}
|
||||
|
||||
addDefaultRunProperties();
|
||||
addAfterLastRunProperties();
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
// remove all runs
|
||||
for (int i = _p.sizeOfBrArray() - 1; i >= 0; i--) {
|
||||
_p.removeBr(i);
|
||||
}
|
||||
for (int i = _p.sizeOfFldArray() - 1; i >= 0; i--) {
|
||||
_p.removeFld(i);
|
||||
}
|
||||
for (int i = _p.sizeOfRArray() - 1; i >= 0; i--) {
|
||||
_p.removeR(i);
|
||||
}
|
||||
_runs.clear();
|
||||
appendRegularRun(text);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
|
@ -662,6 +680,13 @@ public class XDDFTextParagraph {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.1
|
||||
*/
|
||||
public XDDFRunProperties addDefaultRunProperties() {
|
||||
return getOrCreateProperties().addDefaultRunProperties();
|
||||
}
|
||||
|
||||
public XDDFRunProperties getDefaultRunProperties() {
|
||||
if (_p.isSetPPr()) {
|
||||
return getProperties().getDefaultRunProperties();
|
||||
|
|
|
@ -372,8 +372,8 @@ public class XMLSlideShow extends POIXMLDocument
|
|||
}
|
||||
|
||||
if (!themeIndexList.isEmpty()) {
|
||||
Boolean found = false;
|
||||
for (Integer i = 1; i <= themeIndexList.size(); i++) {
|
||||
boolean found = false;
|
||||
for (int i = 1; i <= themeIndexList.size(); i++) {
|
||||
if (!themeIndexList.contains(i)) {
|
||||
found = true;
|
||||
themeIndex = i;
|
||||
|
|
|
@ -77,7 +77,20 @@ public class XSLFBackground extends XSLFSimpleShape
|
|||
|
||||
public void setFillColor(Color color) {
|
||||
CTBackgroundProperties bgPr = getBgPr(true);
|
||||
|
||||
|
||||
if (bgPr.isSetBlipFill()) {
|
||||
bgPr.unsetBlipFill();
|
||||
}
|
||||
if (bgPr.isSetGradFill()) {
|
||||
bgPr.unsetGradFill();
|
||||
}
|
||||
if (bgPr.isSetGrpFill()) {
|
||||
bgPr.unsetGrpFill();
|
||||
}
|
||||
if (bgPr.isSetPattFill()) {
|
||||
bgPr.unsetPattFill();
|
||||
}
|
||||
|
||||
if (color == null) {
|
||||
if (bgPr.isSetSolidFill()) {
|
||||
bgPr.unsetSolidFill();
|
||||
|
|
|
@ -69,7 +69,7 @@ public final class XSLFChart extends XDDFChart {
|
|||
return XSLFFactory.getInstance();
|
||||
}
|
||||
|
||||
public XSLFTextShape getTitle() {
|
||||
public XSLFTextShape getTitleShape() {
|
||||
if (!chart.isSetTitle()) {
|
||||
chart.addNewTitle();
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ public class XSLFColor {
|
|||
colorRef = _phClr.getVal().toString();
|
||||
}
|
||||
// find referenced CTColor in the theme and convert it to java.awt.Color via a recursive call
|
||||
CTColor ctColor = theme.getCTColor(colorRef);
|
||||
CTColor ctColor = theme == null ? null : theme.getCTColor(colorRef);
|
||||
if(ctColor != null) {
|
||||
color = toColor(ctColor, null);
|
||||
}
|
||||
|
|
|
@ -692,10 +692,24 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
|
|||
/**
|
||||
* Helper method for sheet and group shapes
|
||||
*
|
||||
* @param pictureShape the picture shapes whose relation is to be removed
|
||||
* @param pictureShape the picture shapes whose relation is to be removed,
|
||||
* only if there are no more relations on its sheet to that picture
|
||||
*/
|
||||
void removePictureRelation(XSLFPictureShape pictureShape) {
|
||||
removeRelation(pictureShape.getBlipId());
|
||||
int numberOfRelations = 0;
|
||||
String targetBlipId = pictureShape.getBlipId();
|
||||
for (XSLFShape shape : pictureShape.getSheet().getShapes()) {
|
||||
if (shape instanceof XSLFPictureShape) {
|
||||
XSLFPictureShape currentPictureShape = ((XSLFPictureShape) shape);
|
||||
String currentBlipId = currentPictureShape.getBlipId();
|
||||
if (currentBlipId != null && currentBlipId.equals(targetBlipId)) {
|
||||
numberOfRelations++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numberOfRelations <= 1) {
|
||||
removeRelation(pictureShape.getBlipId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ public class StylesTable extends POIXMLDocumentPart implements Styles {
|
|||
if (num < 0) {
|
||||
throw new IllegalArgumentException("Maximum Number of Data Formats must be greater than or equal to 0");
|
||||
} else {
|
||||
throw new IllegalStateException("Cannot set the maximum number of data formats less than the current quantity." +
|
||||
throw new IllegalStateException("Cannot set the maximum number of data formats less than the current quantity. " +
|
||||
"Data formats must be explicitly removed (via StylesTable.removeNumberFormat) before the limit can be decreased.");
|
||||
}
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ public class StylesTable extends POIXMLDocumentPart implements Styles {
|
|||
short nextKey = (short) (numberFormats.lastKey() + 1);
|
||||
if (nextKey < 0) {
|
||||
throw new IllegalStateException(
|
||||
"Cowardly avoiding creating a number format with a negative id." +
|
||||
"Cowardly avoiding creating a number format with a negative id. " +
|
||||
"This is probably due to arithmetic overflow.");
|
||||
}
|
||||
formatIndex = (short) Math.max(nextKey, FIRST_USER_DEFINED_NUMBER_FORMAT_ID);
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
|
@ -33,11 +35,13 @@ import org.w3c.dom.Document;
|
|||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.ls.DOMImplementationLS;
|
||||
import org.w3c.dom.ls.LSSerializer;
|
||||
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
/**
|
||||
* Table style names defined in the OOXML spec.
|
||||
* Table style names defined in the OOXML spec.
|
||||
* The actual styling is defined in presetTableStyles.xml
|
||||
*/
|
||||
public enum XSSFBuiltinTableStyle {
|
||||
|
@ -329,16 +333,16 @@ public enum XSSFBuiltinTableStyle {
|
|||
PivotStyleDark27,
|
||||
/***/
|
||||
PivotStyleDark28,
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* Interestingly, this is initialized after the enum instances, so using an {@link EnumMap} works.
|
||||
*/
|
||||
private static final Map<XSSFBuiltinTableStyle, TableStyle> styleMap = new EnumMap<>(XSSFBuiltinTableStyle.class);
|
||||
|
||||
|
||||
private XSSFBuiltinTableStyle() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return built-in {@link TableStyle} definition
|
||||
*/
|
||||
|
@ -346,9 +350,10 @@ public enum XSSFBuiltinTableStyle {
|
|||
init();
|
||||
return styleMap.get(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: only checks by name, not definition.
|
||||
*
|
||||
* @param style
|
||||
* @return true if the style represents a built-in style, false if it is null or a custom style
|
||||
*/
|
||||
|
@ -361,6 +366,7 @@ public enum XSSFBuiltinTableStyle {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only init once - thus the synchronized. Lazy, after creating instances,
|
||||
* and only when a style is actually needed, to avoid overhead for uses
|
||||
|
@ -370,8 +376,8 @@ public enum XSSFBuiltinTableStyle {
|
|||
* during evaluation if desired.
|
||||
*/
|
||||
public static synchronized void init() {
|
||||
if (! styleMap.isEmpty()) return;
|
||||
|
||||
if (!styleMap.isEmpty()) return;
|
||||
|
||||
/*
|
||||
* initialize map. Every built-in has this format:
|
||||
* <styleName>
|
||||
|
@ -388,18 +394,18 @@ public enum XSSFBuiltinTableStyle {
|
|||
final InputStream is = XSSFBuiltinTableStyle.class.getResourceAsStream("presetTableStyles.xml");
|
||||
try {
|
||||
final Document doc = DocumentHelper.readDocument(is);
|
||||
|
||||
|
||||
final NodeList styleNodes = doc.getDocumentElement().getChildNodes();
|
||||
for (int i=0; i < styleNodes.getLength(); i++) {
|
||||
for (int i = 0; i < styleNodes.getLength(); i++) {
|
||||
final Node node = styleNodes.item(i);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) continue; // only care about elements
|
||||
final Element tag = (Element) node;
|
||||
String styleName = tag.getTagName();
|
||||
XSSFBuiltinTableStyle builtIn = XSSFBuiltinTableStyle.valueOf(styleName);
|
||||
|
||||
|
||||
Node dxfsNode = tag.getElementsByTagName("dxfs").item(0);
|
||||
Node tableStyleNode = tag.getElementsByTagName("tableStyles").item(0);
|
||||
|
||||
|
||||
// hack because I can't figure out how to get XMLBeans to parse a sub-element in a standalone manner
|
||||
// - build a fake styles.xml file with just this built-in
|
||||
StylesTable styles = new StylesTable();
|
||||
|
@ -413,28 +419,35 @@ public enum XSSFBuiltinTableStyle {
|
|||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String styleXML(Node dxfsNode, Node tableStyleNode) {
|
||||
|
||||
private static String styleXML(Node dxfsNode, Node tableStyleNode) throws IOException, TransformerException {
|
||||
// built-ins doc uses 1-based dxf indexing, Excel uses 0 based.
|
||||
// add a dummy node to adjust properly.
|
||||
dxfsNode.insertBefore(dxfsNode.getOwnerDocument().createElement("dxf"), dxfsNode.getFirstChild());
|
||||
|
||||
DOMImplementationLS lsImpl = (DOMImplementationLS)dxfsNode.getOwnerDocument().getImplementation().getFeature("LS", "3.0");
|
||||
LSSerializer lsSerializer = lsImpl.createLSSerializer();
|
||||
lsSerializer.getDomConfig().setParameter("xml-declaration", false);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n")
|
||||
.append("<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" "
|
||||
+ "xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" "
|
||||
+ "xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" "
|
||||
+ "xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\" "
|
||||
+ "mc:Ignorable=\"x14ac x16r2\">\n");
|
||||
sb.append(lsSerializer.writeToString(dxfsNode));
|
||||
sb.append(lsSerializer.writeToString(tableStyleNode));
|
||||
sb.append("</styleSheet>");
|
||||
return sb.toString();
|
||||
.append("<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ")
|
||||
.append("xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" ")
|
||||
.append("xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" ")
|
||||
.append("xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\" ")
|
||||
.append("mc:Ignorable=\"x14ac x16r2\">\n");
|
||||
sb.append(writeToString(dxfsNode));
|
||||
sb.append(writeToString(tableStyleNode));
|
||||
sb.append("</styleSheet>");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String writeToString(Node node) throws IOException, TransformerException {
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
try (StringWriter sw = new StringWriter()){
|
||||
Transformer transformer = tf.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
transformer.transform(new DOMSource(node), new StreamResult(sw));
|
||||
return sw.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation for built-in styles
|
||||
*/
|
||||
|
@ -451,7 +464,7 @@ public enum XSSFBuiltinTableStyle {
|
|||
this.builtIn = builtIn;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return style.getName();
|
||||
}
|
||||
|
@ -463,10 +476,10 @@ public enum XSSFBuiltinTableStyle {
|
|||
public boolean isBuiltin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public DifferentialStyleProvider getStyle(TableStyleType type) {
|
||||
return style.getStyle(type);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -491,10 +491,13 @@ public final class XSSFCell implements Cell {
|
|||
return cell.getCellFormula(fpb);
|
||||
}
|
||||
}
|
||||
if (f.getT() == STCellFormulaType.SHARED) {
|
||||
if (f == null) {
|
||||
return null;
|
||||
} else if (f.getT() == STCellFormulaType.SHARED) {
|
||||
return convertSharedFormula((int)f.getSi(), fpb == null ? XSSFEvaluationWorkbook.create(getSheet().getWorkbook()) : fpb);
|
||||
} else {
|
||||
return f.getStringValue();
|
||||
}
|
||||
return f.getStringValue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,10 +55,6 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef;
|
|||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTx;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.Text;
|
||||
|
@ -260,19 +256,6 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
|
|||
return new XSSFManualLayout(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title static text, or null if none is set. Note that a title
|
||||
* formula may be set instead.
|
||||
*
|
||||
* @return static title text, if set
|
||||
* @deprecated POI 3.16, use {@link #getTitleText()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Removal(version = "4.0")
|
||||
public XSSFRichTextString getTitle() {
|
||||
return getTitleText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title static text, or null if none is set. Note that a title
|
||||
* formula may be set instead. Empty text result is for backward
|
||||
|
@ -307,59 +290,6 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
|
|||
return new XSSFRichTextString(text.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title text as a static string.
|
||||
*
|
||||
* @param newTitle
|
||||
* to use
|
||||
*/
|
||||
public void setTitleText(String newTitle) {
|
||||
CTTitle ctTitle;
|
||||
if (chart.isSetTitle()) {
|
||||
ctTitle = chart.getTitle();
|
||||
} else {
|
||||
ctTitle = chart.addNewTitle();
|
||||
}
|
||||
|
||||
CTTx tx;
|
||||
if (ctTitle.isSetTx()) {
|
||||
tx = ctTitle.getTx();
|
||||
} else {
|
||||
tx = ctTitle.addNewTx();
|
||||
}
|
||||
|
||||
if (tx.isSetStrRef()) {
|
||||
tx.unsetStrRef();
|
||||
}
|
||||
|
||||
CTTextBody rich;
|
||||
if (tx.isSetRich()) {
|
||||
rich = tx.getRich();
|
||||
} else {
|
||||
rich = tx.addNewRich();
|
||||
rich.addNewBodyPr(); // body properties must exist (but can be
|
||||
// empty)
|
||||
}
|
||||
|
||||
CTTextParagraph para;
|
||||
if (rich.sizeOfPArray() > 0) {
|
||||
para = rich.getPArray(0);
|
||||
} else {
|
||||
para = rich.addNewP();
|
||||
}
|
||||
|
||||
if (para.sizeOfRArray() > 0) {
|
||||
CTRegularTextRun run = para.getRArray(0);
|
||||
run.setT(newTitle);
|
||||
} else if (para.sizeOfFldArray() > 0) {
|
||||
CTTextField fld = para.getFldArray(0);
|
||||
fld.setT(newTitle);
|
||||
} else {
|
||||
CTRegularTextRun run = para.addNewR();
|
||||
run.setT(newTitle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chart title formula expression if there is one
|
||||
*
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
|
||||
|
@ -154,12 +153,6 @@ public class XSSFClientAnchor extends XSSFAnchor implements ClientAnchor {
|
|||
// this.cell2 = calcCell(sheet, cell1, size.getCx(), size.getCy());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sheet
|
||||
* @param cell starting point and offsets (may be zeros)
|
||||
* @param size dimensions to calculate relative to starting point
|
||||
*/
|
||||
private CTMarker calcCell(CTMarker cell, long w, long h) {
|
||||
CTMarker c2 = CTMarker.Factory.newInstance();
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public class XSSFComment implements Comment {
|
|||
|
||||
// we potentially need to adjust the column/row information in the shape
|
||||
// the same way as we do in setRow()/setColumn()
|
||||
if(vmlShape != null && vmlShape.sizeOfClientDataArray() > 0) {
|
||||
if(comment != null && vmlShape != null && vmlShape.sizeOfClientDataArray() > 0) {
|
||||
CellReference ref = new CellReference(comment.getRef());
|
||||
CTClientData clientData = vmlShape.getClientDataArray(0);
|
||||
clientData.setRowArray(0, new BigInteger(String.valueOf(ref.getRow())));
|
||||
|
@ -70,7 +70,7 @@ public class XSSFComment implements Comment {
|
|||
*/
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return _comments.getAuthor((int) _comment.getAuthorId());
|
||||
return _comments.getAuthor(_comment.getAuthorId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,9 +80,7 @@ public class XSSFComment implements Comment {
|
|||
*/
|
||||
@Override
|
||||
public void setAuthor(String author) {
|
||||
_comment.setAuthorId(
|
||||
_comments.findAuthor(author)
|
||||
);
|
||||
_comment.setAuthorId(_comments.findAuthor(author));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2262,8 +2262,8 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
}
|
||||
}
|
||||
|
||||
private void unsetCollapsed(boolean collapsed, CTCol ci) {
|
||||
if (collapsed) {
|
||||
private void unsetCollapsed(Boolean collapsed, CTCol ci) {
|
||||
if (collapsed != null && collapsed.booleanValue()) {
|
||||
ci.setCollapsed(collapsed);
|
||||
} else {
|
||||
ci.unsetCollapsed();
|
||||
|
@ -2410,7 +2410,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
boolean endHidden = false;
|
||||
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
|
||||
CTCol[] colArray = cols.getColArray();
|
||||
if (endOfOutlineGroupIdx < colArray.length) {
|
||||
if (endOfOutlineGroupIdx < (colArray.length - 1)) {
|
||||
CTCol nextInfo = colArray[endOfOutlineGroupIdx + 1];
|
||||
if (isAdjacentBefore(colArray[endOfOutlineGroupIdx], nextInfo)) {
|
||||
endLevel = nextInfo.getOutlineLevel();
|
||||
|
@ -2900,7 +2900,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
// "Got srcRows[" + (index-1) + "]=Row " + prevRow.getRowNum() + ", srcRows[" + index + "]=Row " + curRow.getRowNum() + ".");
|
||||
// FIXME: assumes row objects belong to non-null sheets and sheets belong to non-null workbooks.
|
||||
} else if (srcStartRow.getSheet().getWorkbook() != curRow.getSheet().getWorkbook()) {
|
||||
throw new IllegalArgumentException("All rows in srcRows must belong to the same sheet in the same workbook." +
|
||||
throw new IllegalArgumentException("All rows in srcRows must belong to the same sheet in the same workbook. " +
|
||||
"Expected all rows from same workbook (" + srcStartRow.getSheet().getWorkbook() + "). " +
|
||||
"Got srcRows[" + index + "] from different workbook (" + curRow.getSheet().getWorkbook() + ").");
|
||||
} else if (srcStartRow.getSheet() != curRow.getSheet()) {
|
||||
|
|
|
@ -283,7 +283,7 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
}
|
||||
|
||||
// check if name is unique and calculate unique column id
|
||||
long nextColumnId = 1;
|
||||
long nextColumnId = 0;
|
||||
for (XSSFTableColumn tableColumn : getColumns()) {
|
||||
if (columnName != null && columnName.equalsIgnoreCase(tableColumn.getName())) {
|
||||
throw new IllegalArgumentException("Column '" + columnName
|
||||
|
@ -291,6 +291,8 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
}
|
||||
nextColumnId = Math.max(nextColumnId, tableColumn.getId());
|
||||
}
|
||||
// Bug #62740, the logic was just re-using the existing max ID, not incrementing beyond it.
|
||||
nextColumnId++;
|
||||
|
||||
// Add the new Column
|
||||
CTTableColumn column = columns.insertNewTableColumn(columnIndex);
|
||||
|
@ -474,14 +476,9 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
* this method does not create or remove any columns and does not change any
|
||||
* cell values.
|
||||
*
|
||||
* @deprecated Use {@link #setTableArea} instead, which will ensure that the
|
||||
* the amount of columns always matches table area always width.
|
||||
*
|
||||
* @see "Open Office XML Part 4: chapter 3.5.1.2, attribute ref"
|
||||
* @since 3.17 beta 1
|
||||
*/
|
||||
@Deprecated
|
||||
@Removal(version="4.2.0")
|
||||
public void setCellReferences(AreaReference refs) {
|
||||
setCellRef(refs);
|
||||
}
|
||||
|
@ -525,7 +522,7 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
|||
* Updating the area with this method will create new column as necessary to
|
||||
* the right side of the table but will not modify any cell values.
|
||||
*
|
||||
* @param refs
|
||||
* @param tableArea
|
||||
* the new area of the table
|
||||
* @throws IllegalArgumentException
|
||||
* if the area is {@code null} or not
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
package org.apache.poi.xssf.usermodel.helpers;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.ooxml.POIXMLDocumentPart;
|
||||
import org.apache.poi.ss.formula.FormulaParser;
|
||||
import org.apache.poi.ss.formula.FormulaRenderer;
|
||||
import org.apache.poi.ss.formula.FormulaType;
|
||||
|
@ -30,10 +34,14 @@ import org.apache.poi.ss.usermodel.CellType;
|
|||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||
import org.apache.poi.xssf.usermodel.XSSFDrawing;
|
||||
import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFName;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* Utility to update formulas and named ranges when a sheet name was changed
|
||||
|
@ -50,7 +58,7 @@ public final class XSSFFormulaUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Update sheet name in all formulas and named ranges.
|
||||
* Update sheet name in all charts, formulas and named ranges.
|
||||
* Called from {@link XSSFWorkbook#setSheetName(int, String)}
|
||||
* <p>
|
||||
* <p>
|
||||
|
@ -81,6 +89,20 @@ public final class XSSFFormulaUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update charts
|
||||
List<POIXMLDocumentPart> rels = _wb.getSheetAt(sheetIndex).getRelations();
|
||||
for (POIXMLDocumentPart r : rels) {
|
||||
if (r instanceof XSSFDrawing) {
|
||||
XSSFDrawing dg = (XSSFDrawing) r;
|
||||
Iterator<XSSFChart> it = dg.getCharts().iterator();
|
||||
while (it.hasNext()) {
|
||||
XSSFChart chart = it.next();
|
||||
Node dom = chart.getCTChartSpace().getDomNode();
|
||||
updateDomSheetReference(dom, oldName, newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +121,9 @@ public final class XSSFFormulaUtils {
|
|||
updatePtg(ptg, oldName, newName);
|
||||
}
|
||||
String updatedFormula = FormulaRenderer.toFormulaString(_fpwb, ptgs);
|
||||
if (!formula.equals(updatedFormula)) f.setStringValue(updatedFormula);
|
||||
if (!formula.equals(updatedFormula)) {
|
||||
f.setStringValue(updatedFormula);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,10 +143,12 @@ public final class XSSFFormulaUtils {
|
|||
updatePtg(ptg, oldName, newName);
|
||||
}
|
||||
String updatedFormula = FormulaRenderer.toFormulaString(_fpwb, ptgs);
|
||||
if (!formula.equals(updatedFormula)) name.setRefersToFormula(updatedFormula);
|
||||
if (!formula.equals(updatedFormula)) {
|
||||
name.setRefersToFormula(updatedFormula);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updatePtg(Ptg ptg, String oldName, String newName) {
|
||||
if (ptg instanceof Pxg) {
|
||||
Pxg pxg = (Pxg)ptg;
|
||||
|
@ -141,4 +167,32 @@ public final class XSSFFormulaUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the DOM tree recursively searching for text containing reference to the old sheet name and replacing it.
|
||||
*
|
||||
* @param dom the XML node in which to perform the replacement.
|
||||
*
|
||||
* Code extracted from: <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=54470">Bug 54470</a>
|
||||
*/
|
||||
private void updateDomSheetReference(Node dom, final String oldName, final String newName) {
|
||||
String value = dom.getNodeValue();
|
||||
if (value != null) {
|
||||
// make sure the value contains the old sheet and not a similar sheet
|
||||
// (ex: Valid: 'Sheet1'! or Sheet1! ; NotValid: 'Sheet1Test'! or Sheet1Test!)
|
||||
if (value.contains(oldName+"!") || value.contains(oldName+"'!")) {
|
||||
XSSFName temporary = _wb.createName();
|
||||
temporary.setRefersToFormula(value);
|
||||
updateName(temporary, oldName, newName);
|
||||
dom.setNodeValue(temporary.getRefersToFormula());
|
||||
_wb.removeName(temporary);
|
||||
}
|
||||
}
|
||||
NodeList nl = dom.getChildNodes();
|
||||
for (int i = 0; i < nl.getLength(); i++) {
|
||||
updateDomSheetReference(nl.item(i), oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,18 @@
|
|||
|
||||
package org.apache.poi.ooxml.util;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
import org.apache.poi.util.SuppressForbidden;
|
||||
import org.apache.xmlbeans.StringEnumAbstractBase;
|
||||
import org.junit.Test;
|
||||
import org.junit.internal.TextListener;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runner.JUnitCore;
|
||||
import org.junit.runner.Result;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
@ -26,29 +38,11 @@ import java.security.AccessController;
|
|||
import java.security.CodeSource;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
import java.util.*;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
import org.apache.poi.util.SuppressForbidden;
|
||||
import org.junit.Test;
|
||||
import org.junit.internal.TextListener;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runner.JUnitCore;
|
||||
import org.junit.runner.Result;
|
||||
|
||||
/**
|
||||
* Build a 'lite' version of the ooxml-schemas.jar
|
||||
*
|
||||
|
@ -193,20 +187,37 @@ public final class OOXMLLite {
|
|||
|
||||
//see what classes from the ooxml-schemas.jar are loaded
|
||||
System.out.println("Copying classes to " + _destDest);
|
||||
Map<String, Class<?>> classes = getLoadedClasses(_ooxmlJar.getName());
|
||||
for (Class<?> cls : classes.values()) {
|
||||
String className = cls.getName();
|
||||
String classRef = className.replace('.', '/') + ".class";
|
||||
File destFile = new File(_destDest, classRef);
|
||||
IOUtils.copy(cls.getResourceAsStream('/' + classRef), destFile);
|
||||
Set<Class<?>> classes = getLoadedClasses(_ooxmlJar.getName());
|
||||
Set<String> packages = new HashSet<>();
|
||||
for (Class<?> cls : classes) {
|
||||
copyFile(cls);
|
||||
packages.add(cls.getPackage().getName());
|
||||
|
||||
if(cls.isInterface()){
|
||||
if (cls.isInterface()) {
|
||||
/// Copy classes and interfaces declared as members of this class
|
||||
for(Class<?> fc : cls.getDeclaredClasses()){
|
||||
className = fc.getName();
|
||||
classRef = className.replace('.', '/') + ".class";
|
||||
destFile = new File(_destDest, classRef);
|
||||
IOUtils.copy(fc.getResourceAsStream('/' + classRef), destFile);
|
||||
for (Class<?> fc : cls.getDeclaredClasses()) {
|
||||
copyFile(fc);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String pkg : packages) {
|
||||
Reflections reflections = new Reflections(pkg);
|
||||
Set<Class<? extends List>> listClasses = reflections.getSubTypesOf(List.class);
|
||||
listClasses.removeAll(classes);
|
||||
for (Class listClass : listClasses) {
|
||||
for (Class<?> compare : classes) {
|
||||
if (listClass.getName().startsWith(compare.getName())) {
|
||||
copyFile(listClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<Class<? extends StringEnumAbstractBase>> enumClasses = reflections.getSubTypesOf(StringEnumAbstractBase.class);
|
||||
listClasses.removeAll(classes);
|
||||
for (Class enumClass : enumClasses) {
|
||||
for (Class<?> compare : classes) {
|
||||
if (enumClass.getName().startsWith(compare.getName())) {
|
||||
copyFile(enumClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,6 +235,13 @@ public final class OOXMLLite {
|
|||
}
|
||||
}
|
||||
|
||||
private void copyFile(Class<?> cls) throws IOException {
|
||||
String className = cls.getName();
|
||||
String classRef = className.replace('.', '/') + ".class";
|
||||
File destFile = new File(_destDest, classRef);
|
||||
IOUtils.copy(cls.getResourceAsStream('/' + classRef), destFile);
|
||||
}
|
||||
|
||||
private static boolean checkForTestAnnotation(Class<?> testclass) {
|
||||
for (Method m : testclass.getDeclaredMethods()) {
|
||||
if(m.isAnnotationPresent(Test.class)) {
|
||||
|
@ -293,10 +311,10 @@ public final class OOXMLLite {
|
|||
/**
|
||||
*
|
||||
* @param ptrn the pattern to filter output
|
||||
* @return the classes loaded by the system class loader keyed by class name
|
||||
* @return the classes loaded by the system class loader
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Map<String, Class<?>> getLoadedClasses(String ptrn) {
|
||||
private static Set<Class<?>> getLoadedClasses(String ptrn) {
|
||||
// make the field accessible, we defer this from static initialization to here to
|
||||
// allow JDKs which do not have this field (e.g. IBM JDK) to at least load the class
|
||||
// without failing, see https://issues.apache.org/bugzilla/show_bug.cgi?id=56550
|
||||
|
@ -317,7 +335,7 @@ public final class OOXMLLite {
|
|||
ClassLoader appLoader = ClassLoader.getSystemClassLoader();
|
||||
try {
|
||||
Vector<Class<?>> classes = (Vector<Class<?>>) _classes.get(appLoader);
|
||||
Map<String, Class<?>> map = new HashMap<>();
|
||||
Set<Class<?>> set = new HashSet<>();
|
||||
for (Class<?> cls : classes) {
|
||||
// e.g. proxy-classes, ...
|
||||
ProtectionDomain pd = cls.getProtectionDomain();
|
||||
|
@ -326,13 +344,13 @@ public final class OOXMLLite {
|
|||
if (cs == null) continue;
|
||||
URL loc = cs.getLocation();
|
||||
if (loc == null) continue;
|
||||
|
||||
|
||||
String jar = loc.toString();
|
||||
if (jar.contains(ptrn)) {
|
||||
map.put(cls.getName(), cls);
|
||||
set.add(cls);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
return set;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
@ -37,8 +37,12 @@ public class TestDocumentHelper {
|
|||
|
||||
@Test
|
||||
public void testDocumentBuilderFactory() throws Exception {
|
||||
assertTrue(DocumentHelper.documentBuilderFactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
|
||||
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
|
||||
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
|
||||
try {
|
||||
assertTrue(DocumentHelper.documentBuilderFactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
|
||||
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
|
||||
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
|
||||
} catch(AbstractMethodError e) {
|
||||
// ignore exceptions from old parsers that don't support this API (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.xml.XMLConstants;
|
|||
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
public class TestSAXHelper {
|
||||
|
@ -31,14 +32,18 @@ public class TestSAXHelper {
|
|||
public void testXMLReader() throws Exception {
|
||||
XMLReader reader = SAXHelper.newXMLReader();
|
||||
assertNotSame(reader, SAXHelper.newXMLReader());
|
||||
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
|
||||
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
|
||||
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
|
||||
assertEquals(SAXHelper.IGNORING_ENTITY_RESOLVER, reader.getEntityResolver());
|
||||
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
|
||||
assertEquals("1", reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
|
||||
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_SECURITY_MANAGER));
|
||||
|
||||
try {
|
||||
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
|
||||
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
|
||||
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
|
||||
assertEquals(SAXHelper.IGNORING_ENTITY_RESOLVER, reader.getEntityResolver());
|
||||
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
|
||||
assertEquals("1", reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
|
||||
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_SECURITY_MANAGER));
|
||||
} catch(SAXNotRecognizedException e) {
|
||||
// ignore exceptions from old parsers that don't support these features
|
||||
// (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
|
||||
}
|
||||
reader.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes("UTF-8"))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -907,7 +907,7 @@ public final class TestPackage {
|
|||
getZipStatsAndConsume((max_size, min_ratio) -> {
|
||||
// check max entry size ouf of bounds
|
||||
ZipSecureFile.setMinInflateRatio(min_ratio-0.002);
|
||||
ZipSecureFile.setMaxEntrySize(max_size-100);
|
||||
ZipSecureFile.setMaxEntrySize(max_size-200);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -925,8 +925,8 @@ public final class TestPackage {
|
|||
if (ze.getSize() == 0) {
|
||||
continue;
|
||||
}
|
||||
// add zip entry header ~ 30 bytes
|
||||
long size = ze.getSize()+30;
|
||||
// add zip entry header ~ 128 bytes
|
||||
long size = ze.getSize()+128;
|
||||
double ratio = ze.getCompressedSize() / (double)size;
|
||||
min_ratio = Math.min(min_ratio, ratio);
|
||||
max_size = Math.max(max_size, size);
|
||||
|
|
|
@ -93,6 +93,87 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
|||
public class TestXSLFBugs {
|
||||
private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
|
||||
|
||||
@Test
|
||||
public void bug62736() throws Exception {
|
||||
XMLSlideShow ss1 = XSLFTestDataSamples.openSampleDocument("bug62736.pptx");
|
||||
|
||||
assertEquals(1, ss1.getSlides().size());
|
||||
|
||||
XSLFSlide slide0 = ss1.getSlides().get(0);
|
||||
|
||||
assertEquals(slide0.getShapes().size(), 4);
|
||||
|
||||
assertRelation(slide0, "/ppt/slides/slide1.xml", null);
|
||||
assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
|
||||
assertRelation(slide0, "/ppt/media/image1.png", "rId2");
|
||||
assertEquals(slide0.getRelations().size(), 2);
|
||||
|
||||
List<XSLFPictureShape> pictures = new ArrayList<>();
|
||||
for (XSLFShape shape : slide0.getShapes()) {
|
||||
if (shape instanceof XSLFPictureShape) {
|
||||
pictures.add((XSLFPictureShape) shape);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(pictures.size(), 2);
|
||||
assertEquals(pictures.get(0).getPictureData().getFileName(), "image1.png");
|
||||
assertEquals(pictures.get(1).getPictureData().getFileName(), "image1.png");
|
||||
// blipId is rId2 of both pictures
|
||||
|
||||
// remove just the first picture
|
||||
slide0.removeShape(pictures.get(0));
|
||||
|
||||
assertEquals(slide0.getShapes().size(), 3);
|
||||
|
||||
assertRelation(slide0, "/ppt/slides/slide1.xml", null);
|
||||
assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
|
||||
// the bug is that the following relation is gone
|
||||
assertRelation(slide0, "/ppt/media/image1.png", "rId2");
|
||||
assertEquals(slide0.getRelations().size(), 2);
|
||||
|
||||
// Save and re-load
|
||||
XMLSlideShow ss2 = XSLFTestDataSamples.writeOutAndReadBack(ss1);
|
||||
ss1.close();
|
||||
assertEquals(1, ss2.getSlides().size());
|
||||
|
||||
slide0 = ss2.getSlides().get(0);
|
||||
|
||||
assertRelation(slide0, "/ppt/slides/slide1.xml", null);
|
||||
assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
|
||||
assertRelation(slide0, "/ppt/media/image1.png", "rId2");
|
||||
assertEquals(slide0.getRelations().size(), 2);
|
||||
|
||||
pictures.clear();
|
||||
for (XSLFShape shape : slide0.getShapes()) {
|
||||
if (shape instanceof XSLFPictureShape) {
|
||||
pictures.add((XSLFPictureShape) shape);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(pictures.size(), 1);
|
||||
assertEquals(pictures.get(0).getPictureData().getFileName(), "image1.png");
|
||||
|
||||
slide0.removeShape(pictures.get(0));
|
||||
|
||||
assertEquals(slide0.getShapes().size(), 2);
|
||||
|
||||
assertRelation(slide0, "/ppt/slides/slide1.xml", null);
|
||||
assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
|
||||
assertNull(slide0.getRelationById("rId2"));
|
||||
assertEquals(slide0.getRelations().size(), 1);
|
||||
|
||||
// Save and re-load
|
||||
XMLSlideShow ss3 = XSLFTestDataSamples.writeOutAndReadBack(ss2);
|
||||
ss2.close();
|
||||
assertEquals(1, ss3.getSlides().size());
|
||||
|
||||
slide0 = ss3.getSlides().get(0);
|
||||
|
||||
assertRelation(slide0, "/ppt/slides/slide1.xml", null);
|
||||
assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
|
||||
assertEquals(slide0.getShapes().size(), 2);
|
||||
ss3.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bug61589() throws IOException {
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/* ====================================================================
|
||||
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.xslf.usermodel;
|
||||
|
||||
import org.apache.poi.xslf.XSLFTestDataSamples;
|
||||
import org.junit.Test;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.impl.CTBackgroundImpl;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TestXSLFBackground {
|
||||
@Test
|
||||
public void testNoFillBackground() throws IOException {
|
||||
XMLSlideShow pptx = new XMLSlideShow();
|
||||
XSLFSlide slide = pptx.createSlide();
|
||||
|
||||
slide.getBackground().setFillColor(null);
|
||||
|
||||
CTBackgroundImpl bg = (CTBackgroundImpl) slide.getBackground().getXmlObject();
|
||||
CTBackgroundProperties bgPr = bg.getBgPr();
|
||||
|
||||
assertFalse(bgPr.isSetBlipFill());
|
||||
assertFalse(bgPr.isSetGradFill());
|
||||
assertFalse(bgPr.isSetGrpFill());
|
||||
assertFalse(bgPr.isSetPattFill());
|
||||
assertFalse(bgPr.isSetSolidFill());
|
||||
assertTrue(bgPr.isSetNoFill());
|
||||
|
||||
pptx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSolidFillBackground() throws IOException {
|
||||
XMLSlideShow pptx = new XMLSlideShow();
|
||||
XSLFSlide slide = pptx.createSlide();
|
||||
|
||||
Color color = Color.RED;
|
||||
|
||||
slide.getBackground().setFillColor(color);
|
||||
|
||||
CTBackgroundImpl bg = (CTBackgroundImpl) slide.getBackground().getXmlObject();
|
||||
CTBackgroundProperties bgPr = bg.getBgPr();
|
||||
|
||||
assertFalse(bgPr.isSetBlipFill());
|
||||
assertFalse(bgPr.isSetGradFill());
|
||||
assertFalse(bgPr.isSetGrpFill());
|
||||
assertFalse(bgPr.isSetPattFill());
|
||||
assertTrue(bgPr.isSetSolidFill());
|
||||
assertFalse(bgPr.isSetNoFill());
|
||||
|
||||
assertEquals(slide.getBackground().getFillColor(), color);
|
||||
|
||||
pptx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlipFillBackground() throws IOException {
|
||||
XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("pptx2svg.pptx");
|
||||
XSLFSlide slide = pptx.getSlides().get(0);
|
||||
|
||||
Color color = Color.WHITE;
|
||||
|
||||
CTBackgroundImpl bg = (CTBackgroundImpl) slide.getBackground().getXmlObject();
|
||||
CTBackgroundProperties bgPr = bg.getBgPr();
|
||||
|
||||
assertTrue(bgPr.isSetBlipFill());
|
||||
assertFalse(bgPr.isSetGradFill());
|
||||
assertFalse(bgPr.isSetGrpFill());
|
||||
assertFalse(bgPr.isSetPattFill());
|
||||
assertFalse(bgPr.isSetSolidFill());
|
||||
assertFalse(bgPr.isSetNoFill());
|
||||
|
||||
slide.getBackground().setFillColor(color);
|
||||
|
||||
assertFalse(bgPr.isSetBlipFill());
|
||||
assertFalse(bgPr.isSetGradFill());
|
||||
assertFalse(bgPr.isSetGrpFill());
|
||||
assertFalse(bgPr.isSetPattFill());
|
||||
assertTrue(bgPr.isSetSolidFill());
|
||||
assertFalse(bgPr.isSetNoFill());
|
||||
|
||||
assertEquals(slide.getBackground().getFillColor(), color);
|
||||
|
||||
slide.getBackground().setFillColor(null);
|
||||
|
||||
assertFalse(bgPr.isSetBlipFill());
|
||||
assertFalse(bgPr.isSetGradFill());
|
||||
assertFalse(bgPr.isSetGrpFill());
|
||||
assertFalse(bgPr.isSetPattFill());
|
||||
assertFalse(bgPr.isSetSolidFill());
|
||||
assertTrue(bgPr.isSetNoFill());
|
||||
|
||||
assertNull(slide.getBackground().getFillColor());
|
||||
|
||||
pptx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGradFillBackground() throws IOException {
|
||||
XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("themes.pptx");
|
||||
XSLFSlide slide = pptx.getSlides().get(9);
|
||||
|
||||
Color color = Color.GREEN;
|
||||
|
||||
CTBackgroundImpl bg = (CTBackgroundImpl) slide.getBackground().getXmlObject();
|
||||
CTBackgroundProperties bgPr = bg.getBgPr();
|
||||
|
||||
assertFalse(bgPr.isSetBlipFill());
|
||||
assertTrue(bgPr.isSetGradFill());
|
||||
assertFalse(bgPr.isSetGrpFill());
|
||||
assertFalse(bgPr.isSetPattFill());
|
||||
assertFalse(bgPr.isSetSolidFill());
|
||||
assertFalse(bgPr.isSetNoFill());
|
||||
|
||||
slide.getBackground().setFillColor(color);
|
||||
|
||||
assertFalse(bgPr.isSetBlipFill());
|
||||
assertFalse(bgPr.isSetGradFill());
|
||||
assertFalse(bgPr.isSetGrpFill());
|
||||
assertFalse(bgPr.isSetPattFill());
|
||||
assertTrue(bgPr.isSetSolidFill());
|
||||
assertFalse(bgPr.isSetNoFill());
|
||||
|
||||
assertEquals(slide.getBackground().getFillColor(), color);
|
||||
|
||||
slide.getBackground().setFillColor(null);
|
||||
|
||||
assertFalse(bgPr.isSetBlipFill());
|
||||
assertFalse(bgPr.isSetGradFill());
|
||||
assertFalse(bgPr.isSetGrpFill());
|
||||
assertFalse(bgPr.isSetPattFill());
|
||||
assertFalse(bgPr.isSetSolidFill());
|
||||
assertTrue(bgPr.isSetNoFill());
|
||||
|
||||
assertNull(slide.getBackground().getFillColor());
|
||||
|
||||
pptx.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -158,7 +158,7 @@ public class TestXSLFChart {
|
|||
final XDDFNumericalDataSource<Integer> valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange);
|
||||
series.replaceData(categoryData, valuesData);
|
||||
final String title = "Apache POI";
|
||||
series.setTitle(title, chart.setSheetTitle(title));
|
||||
series.setTitle(title, chart.setSheetTitle(title, 0));
|
||||
chart.plot(data);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -395,15 +396,21 @@ public final class TestXSSFTable {
|
|||
assertEquals(2, table.getRowCount());
|
||||
|
||||
// add columns
|
||||
table.createColumn("Column B");
|
||||
table.createColumn("Column D");
|
||||
table.createColumn("Column C", 2); // add between B and D
|
||||
XSSFTableColumn c1 = table.getColumns().get(0);
|
||||
XSSFTableColumn cB = table.createColumn("Column B");
|
||||
XSSFTableColumn cD = table.createColumn("Column D");
|
||||
XSSFTableColumn cC = table.createColumn("Column C", 2); // add between B and D
|
||||
table.updateReferences();
|
||||
table.updateHeaders();
|
||||
|
||||
assertEquals(4, table.getColumnCount());
|
||||
assertEquals(2, table.getRowCount());
|
||||
|
||||
// column IDs start at 1, and increase in the order columns are added (see bug #62740)
|
||||
assertEquals("Column c ID", 1, c1.getId());
|
||||
assertTrue("Column B ID", c1.getId() < cB.getId());
|
||||
assertTrue("Column D ID", cB.getId() < cD.getId());
|
||||
assertTrue("Column C ID", cD.getId() < cC.getId());
|
||||
assertEquals("Column 1", table.getColumns().get(0).getName()); // generated name
|
||||
assertEquals("Column B", table.getColumns().get(1).getName());
|
||||
assertEquals("Column C", table.getColumns().get(2).getName());
|
||||
|
|
|
@ -39,8 +39,8 @@ import java.util.List;
|
|||
import java.util.zip.CRC32;
|
||||
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.ooxml.POIXMLProperties;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.ooxml.POIXMLProperties;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.ContentTypes;
|
||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
|
@ -67,6 +67,8 @@ import org.apache.poi.ss.util.CellReference;
|
|||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.LocaleUtil;
|
||||
import org.apache.poi.util.TempFile;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
||||
import org.apache.poi.xssf.XSSFITestDataProvider;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.xssf.model.StylesTable;
|
||||
|
@ -553,7 +555,9 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
|
|||
Sheet sheet = wb.getSheetAt(0);
|
||||
sheet.shiftRows(2, sheet.getLastRowNum(), 1, true, false);
|
||||
Row newRow = sheet.getRow(2);
|
||||
if (newRow == null) newRow = sheet.createRow(2);
|
||||
if (newRow == null) {
|
||||
newRow = sheet.createRow(2);
|
||||
}
|
||||
newRow.createCell(0).setCellValue(" Another Header");
|
||||
wb.cloneSheet(0);
|
||||
|
||||
|
@ -667,8 +671,8 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
|
|||
XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2);
|
||||
assertNotNull(wb3);
|
||||
sheet = wb3.getSheetAt(0);
|
||||
row = sheet.getRow(2);
|
||||
|
||||
row = sheet.getRow(2);
|
||||
|
||||
assertEquals("test1", row.getCell(3).getStringCellValue());
|
||||
assertEquals("test2", row.getCell(4).getStringCellValue());
|
||||
wb3.close();
|
||||
|
@ -700,6 +704,24 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bug60509() throws Exception {
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("60509.xlsx");
|
||||
assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3");
|
||||
int sheetIndex = wb.getSheetIndex("Sheet1");
|
||||
wb.setSheetName(sheetIndex, "Sheet1-Renamed");
|
||||
Workbook read = XSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
assertNotNull(read);
|
||||
assertSheetOrder(read, "Sheet1-Renamed", "Sheet2", "Sheet3");
|
||||
XSSFSheet sheet = (XSSFSheet) read.getSheet("Sheet1-Renamed");
|
||||
XDDFChartData.Series series = sheet.getDrawingPatriarch().getCharts().get(0).getChartSeries().get(0).getSeries().get(0);
|
||||
assertTrue("should be a bar chart data series", series instanceof XDDFBarChartData.Series);
|
||||
String formula = ((XDDFBarChartData.Series) series).getCategoryData().getFormula();
|
||||
assertTrue("should contain new sheet name", formula.startsWith("'Sheet1-Renamed'!"));
|
||||
read.close();
|
||||
wb.close();
|
||||
}
|
||||
|
||||
private static final int INDEX_NOT_FOUND = -1;
|
||||
|
||||
private static boolean isEmpty(CharSequence cs) {
|
||||
|
@ -1009,22 +1031,22 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
|
|||
final String filename = "SampleSS.xlsx";
|
||||
final File file = POIDataSamples.getSpreadSheetInstance().getFile(filename);
|
||||
Workbook wb;
|
||||
|
||||
|
||||
// Some tests commented out because close() modifies the file
|
||||
// See bug 58779
|
||||
|
||||
|
||||
// String
|
||||
//wb = new XSSFWorkbook(file.getPath());
|
||||
//assertCloseDoesNotModifyFile(filename, wb);
|
||||
|
||||
|
||||
// File
|
||||
//wb = new XSSFWorkbook(file);
|
||||
//assertCloseDoesNotModifyFile(filename, wb);
|
||||
|
||||
|
||||
// InputStream
|
||||
wb = new XSSFWorkbook(new FileInputStream(file));
|
||||
assertCloseDoesNotModifyFile(filename, wb);
|
||||
|
||||
|
||||
// OPCPackage
|
||||
//wb = new XSSFWorkbook(OPCPackage.open(file));
|
||||
//assertCloseDoesNotModifyFile(filename, wb);
|
||||
|
@ -1070,7 +1092,7 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
|
|||
XSSFTable table2 = wb.getSheet("Foglio2").createTable();
|
||||
table2.setName("Table2");
|
||||
assertSame("Did not find Table2", table2, wb.getTable("Table2"));
|
||||
|
||||
|
||||
// If table name is modified after getTable is called, the table can only be found by its new name
|
||||
// This test makes sure that if any caching is done that getTable never uses a stale cache
|
||||
table1.setName("Table1");
|
||||
|
|
|
@ -123,6 +123,11 @@ java.util.concurrent.Future#cancel(boolean)
|
|||
@defaultMessage Don't use ...InputStream.available() as it gives wrong result for certain streams - use IOUtils.toByteArray to read the stream fully and then count the available bytes
|
||||
java.io.InputStream#available()
|
||||
|
||||
@defaultMessage Use newInstance, as newFactory does not seem to work on Android - https://github.com/centic9/poi-on-android/issues/44#issuecomment-426517981
|
||||
javax.xml.stream.XMLEventFactory#newFactory()
|
||||
javax.xml.stream.XMLInputFactory#newFactory()
|
||||
javax.xml.stream.XMLOutputFactory#newFactory()
|
||||
|
||||
@defaultMessage Unnecessary, inefficient, and confusing conversion of String.toString
|
||||
java.lang.String#toString()
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ public class TextSpecInfoRun {
|
|||
smartTagFld, smartTagsBytes, "smart tags"
|
||||
};
|
||||
|
||||
for (int i=0; i<flds.length; i+=3) {
|
||||
for (int i=0; i<flds.length-1; i+=3) {
|
||||
BitField fld = (BitField)flds[i+0];
|
||||
Object valO = flds[i+1];
|
||||
if (!fld.isSet(mask)) continue;
|
||||
|
@ -210,7 +210,8 @@ public class TextSpecInfoRun {
|
|||
valid = false;
|
||||
}
|
||||
if (!valid) {
|
||||
throw new IOException(flds[i+2]+" is activated, but its value is invalid");
|
||||
Object fval = (i + 2) < flds.length ? flds[i + 2] : null;
|
||||
throw new IOException(fval + " is activated, but its value is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,12 +53,6 @@ public class TestRandBetween extends TestCase {
|
|||
formulaCell = row.createCell(2, CellType.FORMULA);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
// TODO Auto-generated method stub
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check where values are the same
|
||||
*/
|
||||
|
@ -74,6 +68,17 @@ public class TestRandBetween extends TestCase {
|
|||
assertEquals(-1, formulaCell.getNumericCellValue(), 0);
|
||||
|
||||
}
|
||||
|
||||
public void testRandBetweenLargeLongs() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
evaluator.clearAllCachedResultValues();
|
||||
formulaCell.setCellFormula("RANDBETWEEN(0,9999999999)");
|
||||
evaluator.evaluateFormulaCell(formulaCell);
|
||||
double value = formulaCell.getNumericCellValue();
|
||||
assertTrue("rand is greater than or equal to lowerbound", value >= 0.0);
|
||||
assertTrue("rand is less than or equal to upperbound", value <= 9999999999.0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check special case where rounded up bottom value is greater than
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue