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="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 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 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/bcpkix-jdk15on-1.60.jar"/>
|
||||||
<classpathentry kind="lib" path="compile-lib/bcprov-ext-jdk15on-1.59.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="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-codec-1.11.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="lib/commons-logging-1.2.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) {
|
task(japicmp, type: me.champeau.gradle.ArtifactJapicmpTask, dependsOn: jar) {
|
||||||
to = jar.archivePath
|
to = jar.archivePath
|
||||||
onlyModified = true
|
onlyModified = true
|
||||||
|
@ -187,6 +185,7 @@ project('main') {
|
||||||
compile 'javax.activation:activation:1.1.1'
|
compile 'javax.activation:activation:1.1.1'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
|
testCompile 'org.reflections:reflections:0.9.11'
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
@ -231,7 +230,7 @@ project('ooxml') {
|
||||||
compile 'org.apache.commons:commons-math3:3.6.1'
|
compile 'org.apache.commons:commons-math3:3.6.1'
|
||||||
compile 'org.apache.commons:commons-compress:1.18'
|
compile 'org.apache.commons:commons-compress:1.18'
|
||||||
compile 'org.apache.santuario:xmlsec:2.1.0'
|
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'
|
compile 'com.github.virtuald:curvesapi:1.05'
|
||||||
|
|
||||||
// for ooxml-lite, should we move this somewhere else?
|
// for ooxml-lite, should we move this somewhere else?
|
||||||
|
@ -245,6 +244,7 @@ project('ooxml') {
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
testCompile 'org.mockito:mockito-core:2.21.0'
|
testCompile 'org.mockito:mockito-core:2.21.0'
|
||||||
testCompile 'org.xmlunit:xmlunit-core:2.5.1'
|
testCompile 'org.xmlunit:xmlunit-core:2.5.1'
|
||||||
|
testCompile 'org.reflections:reflections:0.9.11'
|
||||||
testCompile project(path: ':main', configuration: 'tests')
|
testCompile project(path: ':main', configuration: 'tests')
|
||||||
testCompile 'org.openjdk.jmh:jmh-core:1.19'
|
testCompile 'org.openjdk.jmh:jmh-core:1.19'
|
||||||
testCompile 'org.openjdk.jmh:jmh-generator-annprocess: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="main.lib" location="lib"/>
|
||||||
<property name="ooxml.lib" location="ooxml-lib"/>
|
<property name="ooxml.lib" location="ooxml-lib"/>
|
||||||
|
<property name="ooxml.test.lib" location="ooxml-testlib"/>
|
||||||
<property name="compile.lib" location="compile-lib"/>
|
<property name="compile.lib" location="compile-lib"/>
|
||||||
|
|
||||||
<!-- compiler options options -->
|
<!-- compiler options options -->
|
||||||
|
@ -201,14 +202,14 @@ under the License.
|
||||||
<!-- xml signature libs -->
|
<!-- xml signature libs -->
|
||||||
<property name="dsig.xmlsec.jar" location="${compile.lib}/xmlsec-2.1.0.jar"/>
|
<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.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.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.59/bcprov-ext-jdk15on-1.59.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.59.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.59/bcpkix-jdk15on-1.59.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.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"/>
|
<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.jar" location="${ooxml.lib}/curvesapi-1.05.jar"/>
|
||||||
<property name="ooxml.curvesapi.url"
|
<property name="ooxml.curvesapi.url"
|
||||||
value="${repository.m2}/maven2/com/github/virtuald/curvesapi/1.05/curvesapi-1.05.jar"/>
|
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"
|
<property name="ooxml.commons-compress.url"
|
||||||
value="${repository.m2}/maven2/org/apache/commons/commons-compress/1.18/commons-compress-1.18.jar"/>
|
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 -->
|
<!-- coverage libs -->
|
||||||
<property name="jacoco.zip" location="${main.lib}/jacoco-0.8.2.zip"/>
|
<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"/>
|
<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 -->
|
<!-- license and api checks -->
|
||||||
<property name="rat.jar" location="${main.lib}/apache-rat-0.12.jar"/>
|
<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="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.jar" location="${main.lib}/forbiddenapis-2.6.jar"/>
|
||||||
<property name="forbidden.url" value="${repository.m2}/maven2/de/thetaphi/forbiddenapis/2.5/forbiddenapis-2.5.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"/>
|
<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"/>
|
<property name="halt.on.test.failure" value="true"/>
|
||||||
|
|
||||||
<!-- helper jars for pgp signing, building and nexus staging -->
|
<!-- 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.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.59/bcprov-ext-jdk15on-1.59.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.59.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.59/bcpg-jdk15on-1.59.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.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.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"/>
|
<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}"/>
|
<pathelement location="${additionaljar}"/>
|
||||||
</path>
|
</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 id="test.ooxml.classpath">
|
||||||
<path refid="ooxml.classpath"/>
|
<path refid="ooxml.classpath"/>
|
||||||
<path refid="ooxml.xmlsec.classpath"/>
|
<path refid="ooxml.xmlsec.classpath"/>
|
||||||
<path refid="test.jar.classpath"/>
|
<path refid="test.jar.classpath"/>
|
||||||
|
<path refid="test.ooxml.reflections.classpath"/>
|
||||||
<pathelement location="${ooxml.output.dir}"/>
|
<pathelement location="${ooxml.output.dir}"/>
|
||||||
<pathelement location="${ooxml.output.test.dir}"/>
|
<pathelement location="${ooxml.output.test.dir}"/>
|
||||||
<pathelement location="${main.output.test.dir}"/>
|
<pathelement location="${main.output.test.dir}"/>
|
||||||
|
@ -484,6 +503,7 @@ under the License.
|
||||||
<path refid="scratchpad.classpath"/>
|
<path refid="scratchpad.classpath"/>
|
||||||
<path refid="ooxml.classpath"/>
|
<path refid="ooxml.classpath"/>
|
||||||
<path refid="ooxml.xmlsec.classpath"/>
|
<path refid="ooxml.xmlsec.classpath"/>
|
||||||
|
<path refid="test.ooxml.reflections.classpath"/>
|
||||||
<path refid="excelant.classpath"/>
|
<path refid="excelant.classpath"/>
|
||||||
<path refid="examples.classpath"/>
|
<path refid="examples.classpath"/>
|
||||||
<pathelement location="${examples.output.dir}"/>
|
<pathelement location="${examples.output.dir}"/>
|
||||||
|
@ -582,6 +602,7 @@ under the License.
|
||||||
<mkdir dir="${main.lib}"/>
|
<mkdir dir="${main.lib}"/>
|
||||||
<mkdir dir="${compile.lib}"/>
|
<mkdir dir="${compile.lib}"/>
|
||||||
<mkdir dir="${ooxml.lib}"/>
|
<mkdir dir="${ooxml.lib}"/>
|
||||||
|
<mkdir dir="${ooxml.test.lib}"/>
|
||||||
<delete verbose="true">
|
<delete verbose="true">
|
||||||
<fileset dir="${main.lib}">
|
<fileset dir="${main.lib}">
|
||||||
<include name="ant-1.8*"/>
|
<include name="ant-1.8*"/>
|
||||||
|
@ -631,6 +652,7 @@ under the License.
|
||||||
<include name="forbiddenapis-2.0.jar"/>
|
<include name="forbiddenapis-2.0.jar"/>
|
||||||
<include name="forbiddenapis-2.1.jar"/>
|
<include name="forbiddenapis-2.1.jar"/>
|
||||||
<include name="forbiddenapis-2.3.jar"/>
|
<include name="forbiddenapis-2.3.jar"/>
|
||||||
|
<include name="forbiddenapis-2.5.jar"/>
|
||||||
<include name="apache-rat-0.11.jar"/>
|
<include name="apache-rat-0.11.jar"/>
|
||||||
<include name="mockito-core-2.13.0.jar"/>
|
<include name="mockito-core-2.13.0.jar"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
|
@ -655,10 +677,7 @@ under the License.
|
||||||
<include name="xmlsec-2.0.1.jar"/>
|
<include name="xmlsec-2.0.1.jar"/>
|
||||||
<include name="xmlsec-2.0.5.jar"/>
|
<include name="xmlsec-2.0.5.jar"/>
|
||||||
<include name="xmlsec-2.0.6.jar"/>
|
<include name="xmlsec-2.0.6.jar"/>
|
||||||
<include name="bc*jdk15on-1.51.jar"/>
|
<include name="bc*jdk15on-1.5*.jar"/>
|
||||||
<include name="bc*jdk15on-1.53.jar"/>
|
|
||||||
<include name="bc*jdk15on-1.54.jar"/>
|
|
||||||
<include name="bc*jdk15on-1.58.jar"/>
|
|
||||||
<include name="slf4j-api-1.7.7.jar"/>
|
<include name="slf4j-api-1.7.7.jar"/>
|
||||||
<include name="slf4j-api-1.7.12.jar"/>
|
<include name="slf4j-api-1.7.12.jar"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
|
@ -753,6 +772,9 @@ under the License.
|
||||||
<available file="${ooxml.curvesapi.jar}"/>
|
<available file="${ooxml.curvesapi.jar}"/>
|
||||||
<available file="${ooxml.xmlbeans.jar}"/>
|
<available file="${ooxml.xmlbeans.jar}"/>
|
||||||
<available file="${ooxml.commons-compress.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>
|
</and>
|
||||||
<isset property="disconnected"/>
|
<isset property="disconnected"/>
|
||||||
</or>
|
</or>
|
||||||
|
@ -760,9 +782,13 @@ under the License.
|
||||||
</target>
|
</target>
|
||||||
<target name="fetch-ooxml-jars" depends="check-ooxml-jars" unless="ooxml.jars.present">
|
<target name="fetch-ooxml-jars" depends="check-ooxml-jars" unless="ooxml.jars.present">
|
||||||
<mkdir dir="${ooxml.lib}"/>
|
<mkdir dir="${ooxml.lib}"/>
|
||||||
|
<mkdir dir="${ooxml.test.lib}"/>
|
||||||
<downloadfile src="${ooxml.curvesapi.url}" dest="${ooxml.curvesapi.jar}"/>
|
<downloadfile src="${ooxml.curvesapi.url}" dest="${ooxml.curvesapi.jar}"/>
|
||||||
<downloadfile src="${ooxml.xmlbeans.url}" dest="${ooxml.xmlbeans.jar}"/>
|
<downloadfile src="${ooxml.xmlbeans.url}" dest="${ooxml.xmlbeans.jar}"/>
|
||||||
<downloadfile src="${ooxml.commons-compress.url}" dest="${ooxml.commons-compress.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>
|
||||||
<target name="check-svn-jars">
|
<target name="check-svn-jars">
|
||||||
<condition property="svn.jars.present">
|
<condition property="svn.jars.present">
|
||||||
|
@ -2045,6 +2071,7 @@ under the License.
|
||||||
<include name="commons-codec-*.jar"/>
|
<include name="commons-codec-*.jar"/>
|
||||||
<include name="commons-logging-*.jar"/>
|
<include name="commons-logging-*.jar"/>
|
||||||
<include name="commons-collections4-*.jar"/>
|
<include name="commons-collections4-*.jar"/>
|
||||||
|
<include name="commons-compress*.jar"/>
|
||||||
<include name="commons-math3-*.jar"/>
|
<include name="commons-math3-*.jar"/>
|
||||||
<include name="jaxb-api-*.jar"/>
|
<include name="jaxb-api-*.jar"/>
|
||||||
<include name="jaxb-impl-*.jar"/>
|
<include name="jaxb-impl-*.jar"/>
|
||||||
|
@ -2753,13 +2780,20 @@ under the License.
|
||||||
project.setProperty(attributes.get("property"), mega);
|
project.setProperty(attributes.get("property"), mega);
|
||||||
</scriptdef>
|
</scriptdef>
|
||||||
|
|
||||||
<macrodef name="loadFilesize">
|
<macrodef name="download-line">
|
||||||
<attribute name="url"/>
|
<attribute name="prop"/>
|
||||||
<attribute name="property"/>
|
<attribute name="dist"/>
|
||||||
|
<attribute name="pack"/>
|
||||||
<sequential>
|
<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"/>
|
<delete file="build/loadFilesize.txt"/>
|
||||||
<record name="build/loadFilesize.txt" action="start" loglevel="verbose" append="false"/>
|
<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"/>
|
<record name="build/loadFilesize.txt" action="stop"/>
|
||||||
<local name="fileSize"/>
|
<local name="fileSize"/>
|
||||||
<loadfile property="fileSize" srcFile="build/loadFilesize.txt">
|
<loadfile property="fileSize" srcFile="build/loadFilesize.txt">
|
||||||
|
@ -2770,7 +2804,16 @@ under the License.
|
||||||
</tokenfilter>
|
</tokenfilter>
|
||||||
</filterchain>
|
</filterchain>
|
||||||
</loadfile>
|
</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>
|
</sequential>
|
||||||
</macrodef>
|
</macrodef>
|
||||||
|
|
||||||
|
@ -2795,23 +2838,17 @@ under the License.
|
||||||
<format property="rel_date" pattern="dd MMMM yyyy" locale="US"/>
|
<format property="rel_date" pattern="dd MMMM yyyy" locale="US"/>
|
||||||
<format property="file_date" pattern="yyyyMMdd" locale="US"/>
|
<format property="file_date" pattern="yyyyMMdd" locale="US"/>
|
||||||
</tstamp>
|
</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"/>
|
<local name="li1"/>
|
||||||
<loadChecksum property="bin-tar-sha512" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.tar.gz.sha512"/>
|
<local name="li2"/>
|
||||||
<loadChecksum property="bin-zip-sha256" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.zip.sha256"/>
|
<local name="li3"/>
|
||||||
<loadChecksum property="bin-zip-sha512" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.zip.sha512"/>
|
<local name="li4"/>
|
||||||
<loadChecksum property="src-tar-sha256" url="${baseurl}/src/poi-src-${version.id}-${file_date}.tar.gz.sha256"/>
|
<download-line prop="li1" dist="bin" pack="tar.gz"/>
|
||||||
<loadChecksum property="src-tar-sha512" url="${baseurl}/src/poi-src-${version.id}-${file_date}.tar.gz.sha512"/>
|
<download-line prop="li2" dist="bin" pack="zip"/>
|
||||||
<loadChecksum property="src-zip-sha256" url="${baseurl}/src/poi-src-${version.id}-${file_date}.zip.sha256"/>
|
<download-line prop="li3" dist="src" pack="tar.gz"/>
|
||||||
<loadChecksum property="src-zip-sha512" url="${baseurl}/src/poi-src-${version.id}-${file_date}.zip.sha512"/>
|
<download-line prop="li4" dist="src" pack="zip"/>
|
||||||
|
|
||||||
<loadFilesize property="bin-tar-size" url="${baseurl}/bin/poi-bin-${version.id}-${file_date}.tar.gz"/>
|
<echo file="download-snipplet.xml"><![CDATA[
|
||||||
<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[
|
|
||||||
<section id="POI-${version.id}"><title>${rel_date} - POI ${version.id} available</title>
|
<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}.
|
<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>
|
Featured are a handful of new areas of functionality and numerous bug fixes.</p>
|
||||||
|
@ -2828,46 +2865,14 @@ under the License.
|
||||||
</p>
|
</p>
|
||||||
<section id="POI-${version.id}-bin"><title>Binary Distribution</title>
|
<section id="POI-${version.id}-bin"><title>Binary Distribution</title>
|
||||||
<ul>
|
<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>
|
${li1}
|
||||||
(${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>)
|
${li2}
|
||||||
<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>
|
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
<section id="POI-${version.id}-src"><title>Source Distribution</title>
|
<section id="POI-${version.id}-src"><title>Source Distribution</title>
|
||||||
<ul>
|
<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>
|
${li3}
|
||||||
(${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>)
|
${li4}
|
||||||
<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>
|
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -25,19 +25,6 @@ def poijobs = [
|
||||||
// the JDK is missing on some slaves so builds are unstable
|
// the JDK is missing on some slaves so builds are unstable
|
||||||
skipcigame: true
|
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,
|
[ name: 'POI-DSL-1.10', jdk: '1.10', trigger: triggerSundays,
|
||||||
properties: ['-Djava9addmods=--add-modules=java.xml.bind',
|
properties: ['-Djava9addmods=--add-modules=java.xml.bind',
|
||||||
'-Djavadoc9addmods=--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 svnBase = 'https://svn.apache.org/repos/asf/poi/trunk'
|
||||||
|
def xmlbeansSvnBase = 'https://svn.apache.org/repos/asf/xmlbeans/trunk'
|
||||||
|
|
||||||
def defaultJdk = '1.8'
|
def defaultJdk = '1.8'
|
||||||
def defaultTrigger = 'H/15 * * * *' // check SCM every 60/15 = 4 minutes
|
def defaultTrigger = 'H/15 * * * *' // check SCM every 60/15 = 4 minutes
|
||||||
def defaultEmail = 'dev@poi.apache.org'
|
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 defaultSlaves = '(ubuntu||beam)&&!cloud-slave&&!H15&&!H17&&!H18&&!H24&&!ubuntu-4&&!H21'
|
||||||
|
|
||||||
def jdkMapping = [
|
def jdkMapping = [
|
||||||
|
'1.6': 'JDK 1.6 (latest)',
|
||||||
'1.8': 'JDK 1.8 (latest)',
|
'1.8': 'JDK 1.8 (latest)',
|
||||||
'1.9': 'JDK 1.9 (latest)',
|
|
||||||
'1.10': 'JDK 10 (latest)',
|
'1.10': 'JDK 10 (latest)',
|
||||||
'1.11': 'JDK 11 (latest)',
|
'1.11': 'JDK 11 (latest)',
|
||||||
'1.12': 'JDK 12 (latest)',
|
'1.12': 'JDK 12 (latest)',
|
||||||
|
@ -141,7 +135,7 @@ static def shellEx(def context, String cmd, def poijob) {
|
||||||
}
|
}
|
||||||
|
|
||||||
def defaultDesc = '''
|
def defaultDesc = '''
|
||||||
<img src="https://poi.apache.org/resources/images/project-logo.jpg" />
|
<img src="https://poi.apache.org/images/project-header.png" />
|
||||||
<p>
|
<p>
|
||||||
Apache POI - the Java API for Microsoft Documents
|
Apache POI - the Java API for Microsoft Documents
|
||||||
</p>
|
</p>
|
||||||
|
@ -233,7 +227,7 @@ poijobs.each { poijob ->
|
||||||
label(slaves)
|
label(slaves)
|
||||||
environmentVariables {
|
environmentVariables {
|
||||||
env('LANG', 'en_US.UTF-8')
|
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
|
// 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
|
// 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('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
|
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
|
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!
|
'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)',
|
'IBM 1.8 64-bit (on Ubuntu only)',
|
||||||
|
|
||||||
'JDK 1.9 (latest)',
|
|
||||||
|
|
||||||
'JDK 10 (latest)',
|
'JDK 10 (latest)',
|
||||||
'JDK 10 b46 (Windows Only)',
|
'JDK 10 b46 (Windows Only)',
|
||||||
'OpenJDK 10.0.2 (on Ubuntu only)',
|
'OpenJDK 10.0.2 (on Ubuntu only)',
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.virtuald</groupId>
|
<groupId>com.github.virtuald</groupId>
|
||||||
<artifactId>curvesapi</artifactId>
|
<artifactId>curvesapi</artifactId>
|
||||||
<version>1.04</version>
|
<version>1.05</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -76,7 +76,17 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-codec</groupId>
|
<groupId>commons-codec</groupId>
|
||||||
<artifactId>commons-codec</artifactId>
|
<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>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -91,11 +101,6 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<version>4.12</version>
|
<version>4.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-collections4</artifactId>
|
|
||||||
<version>4.2</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -137,12 +137,12 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bouncycastle</groupId>
|
<groupId>org.bouncycastle</groupId>
|
||||||
<artifactId>bcpkix-jdk15on</artifactId>
|
<artifactId>bcpkix-jdk15on</artifactId>
|
||||||
<version>1.59</version>
|
<version>1.60</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bouncycastle</groupId>
|
<groupId>org.bouncycastle</groupId>
|
||||||
<artifactId>bcprov-jdk15on</artifactId>
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
<version>1.59</version>
|
<version>1.60</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.santuario</groupId>
|
<groupId>org.apache.santuario</groupId>
|
||||||
|
@ -166,6 +166,12 @@
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.reflections</groupId>
|
||||||
|
<artifactId>reflections</artifactId>
|
||||||
|
<version>0.9.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjdk.jmh</groupId>
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
|
|
@ -348,11 +348,13 @@ public void paintBorder(Component c, Graphics g, int x, int y, int width,
|
||||||
|
|
||||||
// if there are borders on the west or east then
|
// if there are borders on the west or east then
|
||||||
// the second line shouldn't cross them
|
// the second line shouldn't cross them
|
||||||
if (westBorder)
|
if (westBorder) {
|
||||||
leftx = x+3;
|
leftx = x + 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (eastBorder)
|
if (eastBorder) {
|
||||||
rightx = width-3;
|
rightx = width - 3;
|
||||||
|
}
|
||||||
|
|
||||||
g.drawLine(x,y,width,y);
|
g.drawLine(x,y,width,y);
|
||||||
g.drawLine(leftx,y+2,rightx,y+2);
|
g.drawLine(leftx,y+2,rightx,y+2);
|
||||||
|
@ -370,11 +372,13 @@ public void paintBorder(Component c, Graphics g, int x, int y, int width,
|
||||||
int topy=y;
|
int topy=y;
|
||||||
int bottomy=height;
|
int bottomy=height;
|
||||||
|
|
||||||
if (northBorder)
|
if (northBorder) {
|
||||||
topy=y+3;
|
topy = y + 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (southBorder)
|
if (southBorder) {
|
||||||
bottomy=height-3;
|
bottomy = height - 3;
|
||||||
|
}
|
||||||
|
|
||||||
g.drawLine(width-1,y,width-1,height);
|
g.drawLine(width-1,y,width-1,height);
|
||||||
g.drawLine(width-3,topy,width-3,bottomy);
|
g.drawLine(width-3,topy,width-3,bottomy);
|
||||||
|
|
|
@ -533,12 +533,12 @@ public class ConditionalFormats {
|
||||||
Row r = sheet.createRow(1);
|
Row r = sheet.createRow(1);
|
||||||
r.createCell(0).setCellValue("Red-Yellow-Green");
|
r.createCell(0).setCellValue("Red-Yellow-Green");
|
||||||
for (int i=1; i<=7; i++) {
|
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 = sheet.createRow(2);
|
||||||
r.createCell(0).setCellValue("Red-White-Blue");
|
r.createCell(0).setCellValue("Red-White-Blue");
|
||||||
for (int i=1; i<=9; i++) {
|
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 = sheet.createRow(3);
|
||||||
r.createCell(0).setCellValue("Blue-Green");
|
r.createCell(0).setCellValue("Blue-Green");
|
||||||
|
@ -667,9 +667,13 @@ public class ConditionalFormats {
|
||||||
for (Cell c : r) {
|
for (Cell c : r) {
|
||||||
final List<EvaluationConditionalFormatRule> rules = cfEval.getConditionalFormattingForCell(c);
|
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
|
// 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);
|
final CellReference ref = ConditionalFormattingEvaluator.getRef(c);
|
||||||
if (rules.isEmpty()) continue;
|
if (rules.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("\n"
|
System.out.println("\n"
|
||||||
+ ref.formatAsString()
|
+ ref.formatAsString()
|
||||||
|
@ -709,9 +713,15 @@ public class ConditionalFormats {
|
||||||
b.append("\n\t\tfont format ")
|
b.append("\n\t\tfont format ")
|
||||||
.append("color index ")
|
.append("color index ")
|
||||||
.append(ff.getFontColorIndex());
|
.append(ff.getFontColorIndex());
|
||||||
if (ff.isBold()) b.append(" bold");
|
if (ff.isBold()) {
|
||||||
if (ff.isItalic()) b.append(" italic");
|
b.append(" bold");
|
||||||
if (ff.isStruckout()) b.append(" strikeout");
|
}
|
||||||
|
if (ff.isItalic()) {
|
||||||
|
b.append(" italic");
|
||||||
|
}
|
||||||
|
if (ff.isStruckout()) {
|
||||||
|
b.append(" strikeout");
|
||||||
|
}
|
||||||
b.append(" underline index ")
|
b.append(" underline index ")
|
||||||
.append(ff.getUnderlineType());
|
.append(ff.getUnderlineType());
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
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.CellFormat;
|
||||||
import org.apache.poi.ss.format.CellFormatResult;
|
import org.apache.poi.ss.format.CellFormatResult;
|
||||||
import org.apache.poi.ss.usermodel.BorderStyle;
|
import org.apache.poi.ss.usermodel.BorderStyle;
|
||||||
|
@ -189,10 +188,15 @@ public class ToHtml {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToHtml toHtml = create(args[0], new PrintWriter(new FileWriter(args[1])));
|
try (
|
||||||
|
FileWriter fw = new FileWriter(args[1]);
|
||||||
|
PrintWriter pw = new PrintWriter(fw)
|
||||||
|
) {
|
||||||
|
ToHtml toHtml = create(args[0], pw);
|
||||||
toHtml.setCompleteHTML(true);
|
toHtml.setCompleteHTML(true);
|
||||||
toHtml.printPage();
|
toHtml.printPage();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setCompleteHTML(boolean completeHTML) {
|
public void setCompleteHTML(boolean completeHTML) {
|
||||||
this.completeHTML = completeHTML;
|
this.completeHTML = completeHTML;
|
||||||
|
@ -375,7 +379,7 @@ public class ToHtml {
|
||||||
// compute width of the header column
|
// compute width of the header column
|
||||||
int lastRowNum = sheet.getLastRowNum();
|
int lastRowNum = sheet.getLastRowNum();
|
||||||
int headerCharCount = String.valueOf(lastRowNum).length();
|
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);
|
ret.put(IDX_HEADER_COL_WIDTH, headerColWidth);
|
||||||
tableWidth += headerColWidth;
|
tableWidth += headerColWidth;
|
||||||
|
|
||||||
|
|
|
@ -59,26 +59,30 @@ public class BarChartDemo {
|
||||||
BufferedReader modelReader = new BufferedReader(new FileReader(args[1]))) {
|
BufferedReader modelReader = new BufferedReader(new FileReader(args[1]))) {
|
||||||
|
|
||||||
String chartTitle = modelReader.readLine(); // first line is chart title
|
String chartTitle = modelReader.readLine(); // first line is chart title
|
||||||
|
String[] series = modelReader.readLine().split(",");
|
||||||
|
|
||||||
// Category Axis Data
|
// Category Axis Data
|
||||||
List<String> listCategories = new ArrayList<String>(3);
|
List<String> listLanguages = new ArrayList<>(10);
|
||||||
|
|
||||||
// Values
|
// Values
|
||||||
List<Double> listValues = new ArrayList<Double>(3);
|
List<Double> listCountries = new ArrayList<>(10);
|
||||||
|
List<Double> listSpeakers = new ArrayList<>(10);
|
||||||
|
|
||||||
// set model
|
// set model
|
||||||
String ln;
|
String ln;
|
||||||
while((ln = modelReader.readLine()) != null){
|
while((ln = modelReader.readLine()) != null) {
|
||||||
String[] vals = ln.split("\\s+");
|
String[] vals = ln.split(",");
|
||||||
listCategories.add(vals[0]);
|
listCountries.add(Double.valueOf(vals[0]));
|
||||||
listValues.add(Double.valueOf(vals[1]));
|
listSpeakers.add(Double.valueOf(vals[1]));
|
||||||
|
listLanguages.add(vals[2]);
|
||||||
}
|
}
|
||||||
String[] categories = listCategories.toArray(new String[listCategories.size()]);
|
String[] categories = listLanguages.toArray(new String[listLanguages.size()]);
|
||||||
Double[] values = listValues.toArray(new Double[listValues.size()]);
|
Double[] values1 = listCountries.toArray(new Double[listCountries.size()]);
|
||||||
|
Double[] values2 = listSpeakers.toArray(new Double[listSpeakers.size()]);
|
||||||
|
|
||||||
try (XMLSlideShow pptx = new XMLSlideShow(argIS)) {
|
try (XMLSlideShow pptx = new XMLSlideShow(argIS)) {
|
||||||
XSLFSlide slide = pptx.getSlides().get(0);
|
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));
|
XSLFChart chart = findChart(pptx.createSlide().importContent(slide));
|
||||||
setColumnData(chart, "Column variant");
|
setColumnData(chart, "Column variant");
|
||||||
|
@ -91,30 +95,41 @@ public class BarChartDemo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setBarData(XSLFChart chart, String chartTitle, String[] categories, Double[] values) {
|
private static void setBarData(XSLFChart chart, String chartTitle, String[] series, String[] categories, Double[] values1, Double[] values2) {
|
||||||
final List<XDDFChartData> series = chart.getChartSeries();
|
final List<XDDFChartData> data = chart.getChartSeries();
|
||||||
final XDDFBarChartData bar = (XDDFBarChartData) series.get(0);
|
final XDDFBarChartData bar = (XDDFBarChartData) data.get(0);
|
||||||
|
|
||||||
final int numOfPoints = categories.length;
|
final int numOfPoints = categories.length;
|
||||||
final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
|
final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
|
||||||
final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
|
final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
|
||||||
final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange);
|
final String valuesDataRange2 = chart.formatRange(new CellRangeAddress(1, numOfPoints, 2, 2));
|
||||||
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange);
|
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.plot(bar);
|
||||||
|
chart.setTitleText(chartTitle); // https://stackoverflow.com/questions/30532612
|
||||||
|
// chart.setTitleOverlay(overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setColumnData(XSLFChart chart, String chartTitle) {
|
private static void setColumnData(XSLFChart chart, String chartTitle) {
|
||||||
// Series Text
|
// Series Text
|
||||||
List<XDDFChartData> series = chart.getChartSeries();
|
List<XDDFChartData> series = chart.getChartSeries();
|
||||||
XDDFBarChartData bar = (XDDFBarChartData) series.get(0);
|
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
|
// in order to transform a bar chart into a column chart, you just need to change the bar direction
|
||||||
bar.setBarDirection(BarDirection.COL);
|
bar.setBarDirection(BarDirection.COL);
|
||||||
|
|
||||||
|
// looking for "Stacked Bar Chart"? uncomment the following line
|
||||||
|
// bar.setBarGrouping(BarGrouping.STACKED);
|
||||||
|
|
||||||
// additionally, you can adjust the axes
|
// additionally, you can adjust the axes
|
||||||
bar.getCategoryAxis().setOrientation(AxisOrientation.MAX_MIN);
|
bar.getCategoryAxis().setOrientation(AxisOrientation.MAX_MIN);
|
||||||
bar.getValueAxes().get(0).setPosition(AxisPosition.TOP);
|
bar.getValueAxes().get(0).setPosition(AxisPosition.TOP);
|
||||||
|
|
|
@ -77,10 +77,10 @@ public class PieChartDemo {
|
||||||
XDDFPieChartData pie = (XDDFPieChartData) series.get(0);
|
XDDFPieChartData pie = (XDDFPieChartData) series.get(0);
|
||||||
|
|
||||||
// Category Axis Data
|
// Category Axis Data
|
||||||
List<String> listCategories = new ArrayList<String>(3);
|
List<String> listCategories = new ArrayList<>(3);
|
||||||
|
|
||||||
// Values
|
// Values
|
||||||
List<Double> listValues = new ArrayList<Double>(3);
|
List<Double> listValues = new ArrayList<>(3);
|
||||||
|
|
||||||
// set model
|
// set model
|
||||||
String ln;
|
String ln;
|
||||||
|
@ -100,7 +100,7 @@ public class PieChartDemo {
|
||||||
|
|
||||||
XDDFPieChartData.Series firstSeries = (XDDFPieChartData.Series) pie.getSeries().get(0);
|
XDDFPieChartData.Series firstSeries = (XDDFPieChartData.Series) pie.getSeries().get(0);
|
||||||
firstSeries.replaceData(categoriesData, valuesData);
|
firstSeries.replaceData(categoriesData, valuesData);
|
||||||
firstSeries.setTitle(chartTitle, chart.setSheetTitle(chartTitle));
|
firstSeries.setTitle(chartTitle, chart.setSheetTitle(chartTitle, 0));
|
||||||
firstSeries.setExplosion(25);
|
firstSeries.setExplosion(25);
|
||||||
chart.plot(pie);
|
chart.plot(pie);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
My Bar or Column Chart
|
10 languages with most speakers as first language
|
||||||
First 1.0
|
countries,speakers,language
|
||||||
Second 3.0
|
58,315,العربية
|
||||||
Third 4.0
|
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.XDDFSolidFillProperties;
|
||||||
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
|
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
|
||||||
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
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.ChartTypes;
|
||||||
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
|
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.XDDFCategoryAxis;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
||||||
|
@ -61,7 +63,7 @@ public class BarChart {
|
||||||
row = sheet.createRow((short) rowIndex);
|
row = sheet.createRow((short) rowIndex);
|
||||||
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
||||||
cell = row.createCell((short) 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);
|
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
|
||||||
|
|
||||||
XSSFChart chart = drawing.createChart(anchor);
|
XSSFChart chart = drawing.createChart(anchor);
|
||||||
|
chart.setTitleText("x = 2x and x = 3x");
|
||||||
|
chart.setTitleOverlay(false);
|
||||||
XDDFChartLegend legend = chart.getOrAddLegend();
|
XDDFChartLegend legend = chart.getOrAddLegend();
|
||||||
legend.setPosition(LegendPosition.TOP_RIGHT);
|
legend.setPosition(LegendPosition.TOP_RIGHT);
|
||||||
|
|
||||||
// Use a category axis for the bottom axis.
|
// Use a category axis for the bottom axis.
|
||||||
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
||||||
|
bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
|
||||||
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
||||||
|
leftAxis.setTitle("f(x)");
|
||||||
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
||||||
|
|
||||||
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
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));
|
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
|
||||||
|
|
||||||
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
|
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
|
||||||
data.addSeries(xs, ys1);
|
XDDFChartData.Series series1 = data.addSeries(xs, ys1);
|
||||||
data.addSeries(xs, ys2);
|
series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
|
||||||
|
XDDFChartData.Series series2 = data.addSeries(xs, ys2);
|
||||||
|
series2.setTitle("3x", null);
|
||||||
chart.plot(data);
|
chart.plot(data);
|
||||||
|
|
||||||
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.CHARTREUSE));
|
// in order to transform a bar chart into a column chart, you just need to change the bar direction
|
||||||
XDDFChartData.Series firstSeries = data.getSeries().get(0);
|
XDDFBarChartData bar = (XDDFBarChartData) data;
|
||||||
XDDFShapeProperties properties = firstSeries.getShapeProperties();
|
bar.setBarDirection(BarDirection.COL);
|
||||||
if (properties == null) {
|
// looking for "Stacked Bar Chart"? uncomment the following line
|
||||||
properties = new XDDFShapeProperties();
|
// bar.setBarGrouping(BarGrouping.STACKED);
|
||||||
}
|
|
||||||
properties.setFillProperties(fill);
|
solidFillSeries(data, 0, PresetColor.CHARTREUSE);
|
||||||
firstSeries.setShapeProperties(properties);
|
solidFillSeries(data, 1, PresetColor.TURQUOISE);
|
||||||
|
|
||||||
// Write the output to a file
|
// Write the output to a file
|
||||||
try (FileOutputStream fileOut = new FileOutputStream("ooxml-bar-chart.xlsx")) {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,10 @@ public final class BigGridDemo {
|
||||||
|
|
||||||
//Step 2. Generate XML file.
|
//Step 2. Generate XML file.
|
||||||
File tmp = File.createTempFile("sheet", ".xml");
|
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);
|
generate(fw, styles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +268,9 @@ public final class BigGridDemo {
|
||||||
public void createCell(int columnIndex, String value, int styleIndex) throws IOException {
|
public void createCell(int columnIndex, String value, int styleIndex) throws IOException {
|
||||||
String ref = new CellReference(_rownum, columnIndex).formatAsString();
|
String ref = new CellReference(_rownum, columnIndex).formatAsString();
|
||||||
_out.write("<c r=\""+ref+"\" t=\"inlineStr\"");
|
_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(">");
|
||||||
_out.write("<is><t>"+value+"</t></is>");
|
_out.write("<is><t>"+value+"</t></is>");
|
||||||
_out.write("</c>");
|
_out.write("</c>");
|
||||||
|
@ -278,7 +283,9 @@ public final class BigGridDemo {
|
||||||
public void createCell(int columnIndex, double value, int styleIndex) throws IOException {
|
public void createCell(int columnIndex, double value, int styleIndex) throws IOException {
|
||||||
String ref = new CellReference(_rownum, columnIndex).formatAsString();
|
String ref = new CellReference(_rownum, columnIndex).formatAsString();
|
||||||
_out.write("<c r=\""+ref+"\" t=\"n\"");
|
_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(">");
|
||||||
_out.write("<v>"+value+"</v>");
|
_out.write("<v>"+value+"</v>");
|
||||||
_out.write("</c>");
|
_out.write("</c>");
|
||||||
|
|
|
@ -39,8 +39,12 @@ public class CreateTable {
|
||||||
try (Workbook wb = new XSSFWorkbook()) {
|
try (Workbook wb = new XSSFWorkbook()) {
|
||||||
XSSFSheet sheet = (XSSFSheet) wb.createSheet();
|
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
|
// Create
|
||||||
XSSFTable table = sheet.createTable();
|
XSSFTable table = sheet.createTable(reference);
|
||||||
table.setName("Test");
|
table.setName("Test");
|
||||||
table.setDisplayName("Test_Table");
|
table.setDisplayName("Test_Table");
|
||||||
|
|
||||||
|
@ -70,7 +74,7 @@ public class CreateTable {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
cell.setCellValue("Column" + (j + 1));
|
cell.setCellValue("Column" + (j + 1));
|
||||||
} else {
|
} 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 2");
|
||||||
table.createColumn("Column 3");
|
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
|
// Save
|
||||||
try (FileOutputStream fileOut = new FileOutputStream("ooxml-table.xlsx")) {
|
try (FileOutputStream fileOut = new FileOutputStream("ooxml-table.xlsx")) {
|
||||||
wb.write(fileOut);
|
wb.write(fileOut);
|
||||||
|
|
|
@ -32,7 +32,10 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
public class IterateCells {
|
public class IterateCells {
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
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++) {
|
for (int i = 0; i < wb.getNumberOfSheets(); i++) {
|
||||||
Sheet sheet = wb.getSheetAt(i);
|
Sheet sheet = wb.getSheetAt(i);
|
||||||
System.out.println(wb.getSheetName(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.Cell;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
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.AxisCrosses;
|
||||||
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
||||||
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
|
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
|
||||||
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
|
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.XDDFCategoryAxis;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
|
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
|
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.XDDFNumericalDataSource;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
|
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||||
|
@ -57,7 +64,7 @@ public class LineChart {
|
||||||
row = sheet.createRow((short) rowIndex);
|
row = sheet.createRow((short) rowIndex);
|
||||||
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
||||||
cell = row.createCell((short) colIndex);
|
cell = row.createCell((short) colIndex);
|
||||||
cell.setCellValue(colIndex * (rowIndex + 1));
|
cell.setCellValue(colIndex * (rowIndex + 1.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,22 +77,51 @@ public class LineChart {
|
||||||
|
|
||||||
// Use a category axis for the bottom axis.
|
// Use a category axis for the bottom axis.
|
||||||
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
||||||
|
bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
|
||||||
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
||||||
|
leftAxis.setTitle("f(x)");
|
||||||
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
||||||
|
|
||||||
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
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> 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));
|
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
|
||||||
|
|
||||||
XDDFChartData data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
|
XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
|
||||||
data.addSeries(xs, ys1);
|
XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xs, ys1);
|
||||||
data.addSeries(xs, ys2);
|
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);
|
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
|
// Write the output to a file
|
||||||
try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) {
|
try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) {
|
||||||
wb.write(fileOut);
|
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.Cell;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
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.AxisCrosses;
|
||||||
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
|
||||||
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
|
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.XDDFDataSource;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
|
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
|
||||||
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
|
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.xddf.usermodel.chart.XDDFValueAxis;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||||
|
@ -59,7 +65,7 @@ public class ScatterChart {
|
||||||
row = sheet.createRow((short) rowIndex);
|
row = sheet.createRow((short) rowIndex);
|
||||||
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
||||||
cell = row.createCell((short) colIndex);
|
cell = row.createCell((short) colIndex);
|
||||||
cell.setCellValue(colIndex * (rowIndex + 1));
|
cell.setCellValue(colIndex * (rowIndex + 1.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +77,9 @@ public class ScatterChart {
|
||||||
legend.setPosition(LegendPosition.TOP_RIGHT);
|
legend.setPosition(LegendPosition.TOP_RIGHT);
|
||||||
|
|
||||||
XDDFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.BOTTOM);
|
XDDFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.BOTTOM);
|
||||||
|
bottomAxis.setTitle("x"); // https://stackoverflow.com/questions/32010765
|
||||||
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
|
||||||
|
leftAxis.setTitle("f(x)");
|
||||||
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
||||||
|
|
||||||
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
||||||
|
@ -79,16 +87,34 @@ public class ScatterChart {
|
||||||
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 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);
|
XDDFScatterChartData data = (XDDFScatterChartData) chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis);
|
||||||
|
XDDFScatterChartData.Series series1 = (XDDFScatterChartData.Series) data.addSeries(xs, ys1);
|
||||||
data.addSeries(xs, ys1);
|
series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
|
||||||
data.addSeries(xs, ys2);
|
series1.setSmooth(false); // https://stackoverflow.com/questions/39636138
|
||||||
|
XDDFScatterChartData.Series series2 = (XDDFScatterChartData.Series) data.addSeries(xs, ys2);
|
||||||
|
series2.setTitle("3x", null);
|
||||||
chart.plot(data);
|
chart.plot(data);
|
||||||
|
|
||||||
|
solidLineSeries(data, 0, PresetColor.CHARTREUSE);
|
||||||
|
solidLineSeries(data, 1, PresetColor.TURQUOISE);
|
||||||
|
|
||||||
// Write the output to a file
|
// Write the output to a file
|
||||||
try (FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx")) {
|
try (FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx")) {
|
||||||
wb.write(fileOut);
|
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
|
* Build a bar chart from a template docx
|
||||||
*/
|
*/
|
||||||
public class BarChartExampleDOCX {
|
public class BarChartExample {
|
||||||
private static void usage(){
|
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-template.docx template with a bar chart");
|
||||||
System.out.println(" bar-chart-data.txt the model to set. First line is chart title, " +
|
System.out.println(" bar-chart-data.txt the model to set. First line is chart title, " +
|
||||||
"then go pairs {axis-label value}");
|
"then go pairs {axis-label value}");
|
||||||
|
@ -61,26 +61,30 @@ public class BarChartExampleDOCX {
|
||||||
BufferedReader modelReader = new BufferedReader(new FileReader(args[1]))) {
|
BufferedReader modelReader = new BufferedReader(new FileReader(args[1]))) {
|
||||||
|
|
||||||
String chartTitle = modelReader.readLine(); // first line is chart title
|
String chartTitle = modelReader.readLine(); // first line is chart title
|
||||||
|
String[] series = modelReader.readLine().split(",");
|
||||||
|
|
||||||
// Category Axis Data
|
// Category Axis Data
|
||||||
List<String> listCategories = new ArrayList<String>(3);
|
List<String> listLanguages = new ArrayList<>(10);
|
||||||
|
|
||||||
// Values
|
// Values
|
||||||
List<Double> listValues = new ArrayList<Double>(3);
|
List<Double> listCountries = new ArrayList<>(10);
|
||||||
|
List<Double> listSpeakers = new ArrayList<>(10);
|
||||||
|
|
||||||
// set model
|
// set model
|
||||||
String ln;
|
String ln;
|
||||||
while((ln = modelReader.readLine()) != null) {
|
while((ln = modelReader.readLine()) != null) {
|
||||||
String[] vals = ln.split("\\s+");
|
String[] vals = ln.split(",");
|
||||||
listCategories.add(vals[0]);
|
listCountries.add(Double.valueOf(vals[0]));
|
||||||
listValues.add(Double.valueOf(vals[1]));
|
listSpeakers.add(Double.valueOf(vals[1]));
|
||||||
|
listLanguages.add(vals[2]);
|
||||||
}
|
}
|
||||||
String[] categories = listCategories.toArray(new String[listCategories.size()]);
|
String[] categories = listLanguages.toArray(new String[listLanguages.size()]);
|
||||||
Double[] values = listValues.toArray(new Double[listValues.size()]);
|
Double[] values1 = listCountries.toArray(new Double[listCountries.size()]);
|
||||||
|
Double[] values2 = listSpeakers.toArray(new Double[listSpeakers.size()]);
|
||||||
|
|
||||||
try (XWPFDocument doc = new XWPFDocument(argIS)) {
|
try (XWPFDocument doc = new XWPFDocument(argIS)) {
|
||||||
XWPFChart chart = doc.getCharts().get(0);
|
XWPFChart chart = doc.getCharts().get(0);
|
||||||
setBarData(chart, chartTitle, categories, values);
|
setBarData(chart, chartTitle, series, categories, values1, values2);
|
||||||
chart = doc.getCharts().get(1);
|
chart = doc.getCharts().get(1);
|
||||||
setColumnData(chart, "Column variant");
|
setColumnData(chart, "Column variant");
|
||||||
|
|
||||||
|
@ -93,33 +97,41 @@ public class BarChartExampleDOCX {
|
||||||
System.out.println("Done");
|
System.out.println("Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setBarData(XWPFChart chart, String chartTitle, String[] categories, Double[] values) {
|
private static void setBarData(XWPFChart chart, String chartTitle, String[] series, String[] categories, Double[] values1, Double[] values2) {
|
||||||
final List<XDDFChartData> series = chart.getChartSeries();
|
final List<XDDFChartData> data = chart.getChartSeries();
|
||||||
final XDDFBarChartData bar = (XDDFBarChartData) series.get(0);
|
final XDDFBarChartData bar = (XDDFBarChartData) data.get(0);
|
||||||
|
|
||||||
final int numOfPoints = categories.length;
|
final int numOfPoints = categories.length;
|
||||||
final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
|
final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
|
||||||
final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
|
final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
|
||||||
final String valuesDataRange2 = chart.formatRange(new CellRangeAddress(1, numOfPoints, 2, 2));
|
final String valuesDataRange2 = chart.formatRange(new CellRangeAddress(1, numOfPoints, 2, 2));
|
||||||
final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
|
final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
|
||||||
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange, 1);
|
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values1, valuesDataRange, 1);
|
||||||
values[2] = 10.0;
|
values1[6] = 16.0; // if you ever want to change the underlying data
|
||||||
final XDDFNumericalDataSource<? extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values, valuesDataRange2, 2);
|
final XDDFNumericalDataSource<? extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values2, valuesDataRange2, 2);
|
||||||
bar.getSeries().get(0).replaceData(categoriesData, valuesData);
|
|
||||||
bar.addSeries(categoriesData, valuesData2);
|
XDDFChartData.Series series1 = bar.getSeries().get(0);
|
||||||
bar.getSeries().get(0).setTitle(chartTitle, chart.setSheetTitle(chartTitle));
|
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.plot(bar);
|
||||||
|
chart.setTitleText(chartTitle); // https://stackoverflow.com/questions/30532612
|
||||||
|
chart.setTitleOverlay(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setColumnData(XWPFChart chart, String chartTitle) {
|
private static void setColumnData(XWPFChart chart, String chartTitle) {
|
||||||
// Series Text
|
// Series Text
|
||||||
List<XDDFChartData> series = chart.getChartSeries();
|
List<XDDFChartData> series = chart.getChartSeries();
|
||||||
XDDFBarChartData bar = (XDDFBarChartData) series.get(0);
|
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
|
// in order to transform a bar chart into a column chart, you just need to change the bar direction
|
||||||
bar.setBarDirection(BarDirection.COL);
|
bar.setBarDirection(BarDirection.COL);
|
||||||
|
|
||||||
|
// looking for "Stacked Bar Chart"? uncomment the following line
|
||||||
|
// bar.setBarGrouping(BarGrouping.STACKED);
|
||||||
|
|
||||||
// additionally, you can adjust the axes
|
// additionally, you can adjust the axes
|
||||||
bar.getCategoryAxis().setOrientation(AxisOrientation.MAX_MIN);
|
bar.getCategoryAxis().setOrientation(AxisOrientation.MAX_MIN);
|
||||||
bar.getValueAxes().get(0).setPosition(AxisPosition.TOP);
|
bar.getValueAxes().get(0).setPosition(AxisPosition.TOP);
|
|
@ -111,16 +111,16 @@ public class SimpleDocument {
|
||||||
r5.setTextPosition(-10);
|
r5.setTextPosition(-10);
|
||||||
r5.setText("For in that sleep of death what dreams may come");
|
r5.setText("For in that sleep of death what dreams may come");
|
||||||
r5.addCarriageReturn();
|
r5.addCarriageReturn();
|
||||||
r5.setText("When we have shuffled off this mortal coil,"
|
r5.setText("When we have shuffled off this mortal coil, "
|
||||||
+ "Must give us pause: there's the respect"
|
+ "Must give us pause: there's the respect "
|
||||||
+ "That makes calamity of so long life;");
|
+ "That makes calamity of so long life;");
|
||||||
r5.addBreak();
|
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,");
|
+ "The oppressor's wrong, the proud man's contumely,");
|
||||||
|
|
||||||
r5.addBreak(BreakClear.ALL);
|
r5.addBreak(BreakClear.ALL);
|
||||||
r5.setText("The pangs of despised love, the law's delay,"
|
r5.setText("The pangs of despised love, the law's delay, "
|
||||||
+ "The insolence of office and the spurns" + ".......");
|
+ "The insolence of office and the spurns " + ".......");
|
||||||
|
|
||||||
try (FileOutputStream out = new FileOutputStream("simple.docx")) {
|
try (FileOutputStream out = new FileOutputStream("simple.docx")) {
|
||||||
doc.write(out);
|
doc.write(out);
|
||||||
|
|
|
@ -43,18 +43,29 @@ public class SimpleImages {
|
||||||
for (String imgFile : args) {
|
for (String imgFile : args) {
|
||||||
int format;
|
int format;
|
||||||
|
|
||||||
if (imgFile.endsWith(".emf")) format = XWPFDocument.PICTURE_TYPE_EMF;
|
if (imgFile.endsWith(".emf")) {
|
||||||
else if (imgFile.endsWith(".wmf")) format = XWPFDocument.PICTURE_TYPE_WMF;
|
format = XWPFDocument.PICTURE_TYPE_EMF;
|
||||||
else if (imgFile.endsWith(".pict")) format = XWPFDocument.PICTURE_TYPE_PICT;
|
} else if (imgFile.endsWith(".wmf")) {
|
||||||
else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) format = XWPFDocument.PICTURE_TYPE_JPEG;
|
format = XWPFDocument.PICTURE_TYPE_WMF;
|
||||||
else if (imgFile.endsWith(".png")) format = XWPFDocument.PICTURE_TYPE_PNG;
|
} else if (imgFile.endsWith(".pict")) {
|
||||||
else if (imgFile.endsWith(".dib")) format = XWPFDocument.PICTURE_TYPE_DIB;
|
format = XWPFDocument.PICTURE_TYPE_PICT;
|
||||||
else if (imgFile.endsWith(".gif")) format = XWPFDocument.PICTURE_TYPE_GIF;
|
} else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) {
|
||||||
else if (imgFile.endsWith(".tiff")) format = XWPFDocument.PICTURE_TYPE_TIFF;
|
format = XWPFDocument.PICTURE_TYPE_JPEG;
|
||||||
else if (imgFile.endsWith(".eps")) format = XWPFDocument.PICTURE_TYPE_EPS;
|
} else if (imgFile.endsWith(".png")) {
|
||||||
else if (imgFile.endsWith(".bmp")) format = XWPFDocument.PICTURE_TYPE_BMP;
|
format = XWPFDocument.PICTURE_TYPE_PNG;
|
||||||
else if (imgFile.endsWith(".wpg")) format = XWPFDocument.PICTURE_TYPE_WPG;
|
} else if (imgFile.endsWith(".dib")) {
|
||||||
else {
|
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 +
|
System.err.println("Unsupported picture: " + imgFile +
|
||||||
". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");
|
". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");
|
||||||
continue;
|
continue;
|
||||||
|
@ -62,7 +73,9 @@ public class SimpleImages {
|
||||||
|
|
||||||
r.setText(imgFile);
|
r.setText(imgFile);
|
||||||
r.addBreak();
|
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);
|
r.addBreak(BreakType.PAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
My Bar or Column Chart
|
10 languages with most speakers as first language
|
||||||
First 1.0
|
countries,speakers,language
|
||||||
Second 3.0
|
58,315,العربية
|
||||||
Third 4.0
|
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]);
|
String tagName = capitalizeAndTrim((String)attrs[0]);
|
||||||
boolean hasValue = false;
|
boolean hasValue = false;
|
||||||
boolean lastChildComplex = 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];
|
Object value = attrs[i+1];
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
// ignore null values
|
// ignore null values
|
||||||
|
@ -384,7 +384,7 @@ public abstract class EscherRecord implements Cloneable {
|
||||||
if (attrList != null && attrList.length > 0) {
|
if (attrList != null && attrList.length > 0) {
|
||||||
String childTab = " ";
|
String childTab = " ";
|
||||||
for (Object[] attrs : attrList) {
|
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];
|
Object value = attrs[i+1];
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
// ignore null values
|
// ignore null values
|
||||||
|
|
|
@ -21,15 +21,7 @@ import java.text.CollationKey;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.DecimalFormatSymbols;
|
import java.text.DecimalFormatSymbols;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
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 org.apache.poi.ss.formula.eval.BlankEval;
|
import org.apache.poi.ss.formula.eval.BlankEval;
|
||||||
import org.apache.poi.ss.formula.eval.BoolEval;
|
import org.apache.poi.ss.formula.eval.BoolEval;
|
||||||
|
@ -900,9 +892,9 @@ public class EvaluationConditionalFormatRule implements Comparable<EvaluationCon
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ValueAndFormat o = (ValueAndFormat) obj;
|
ValueAndFormat o = (ValueAndFormat) obj;
|
||||||
return ( value == o.value || value.equals(o.value))
|
return (Objects.equals(value, o.value)
|
||||||
&& ( format == o.format || format.equals(o.format))
|
&& Objects.equals(format, o.format)
|
||||||
&& (string == o.string || string.equals(o.string));
|
&& Objects.equals(string, o.string));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -382,9 +382,6 @@ public final class FormulaParser {
|
||||||
if (token instanceof OperandPtg) {
|
if (token instanceof OperandPtg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (token instanceof OperationPtg) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ final class RandBetween implements FreeRefFunction{
|
||||||
top = bottom;
|
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
|
* Creates a new StAX XMLInputFactory, with sensible defaults
|
||||||
*/
|
*/
|
||||||
public static XMLInputFactory newXMLInputFactory() {
|
public static XMLInputFactory newXMLInputFactory() {
|
||||||
XMLInputFactory factory = XMLInputFactory.newFactory();
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
trySetProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, true);
|
trySetProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, true);
|
||||||
trySetProperty(factory, XMLInputFactory.IS_VALIDATING, false);
|
trySetProperty(factory, XMLInputFactory.IS_VALIDATING, false);
|
||||||
trySetProperty(factory, XMLInputFactory.SUPPORT_DTD, false);
|
trySetProperty(factory, XMLInputFactory.SUPPORT_DTD, false);
|
||||||
|
@ -46,7 +46,7 @@ public final class StaxHelper {
|
||||||
* Creates a new StAX XMLOutputFactory, with sensible defaults
|
* Creates a new StAX XMLOutputFactory, with sensible defaults
|
||||||
*/
|
*/
|
||||||
public static XMLOutputFactory newXMLOutputFactory() {
|
public static XMLOutputFactory newXMLOutputFactory() {
|
||||||
XMLOutputFactory factory = XMLOutputFactory.newFactory();
|
XMLOutputFactory factory = XMLOutputFactory.newInstance();
|
||||||
trySetProperty(factory, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
|
trySetProperty(factory, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,8 @@ public final class StaxHelper {
|
||||||
* Creates a new StAX XMLEventFactory, with sensible defaults
|
* Creates a new StAX XMLEventFactory, with sensible defaults
|
||||||
*/
|
*/
|
||||||
public static XMLEventFactory newXMLEventFactory() {
|
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) {
|
private static void trySetProperty(XMLInputFactory factory, String feature, boolean flag) {
|
||||||
|
|
|
@ -223,7 +223,7 @@ public class POIXMLProperties {
|
||||||
throw new POIXMLException(e);
|
throw new POIXMLException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(extPart != null){
|
if(extPart != null && ext != null && ext.props != null){
|
||||||
try (OutputStream out = extPart.getOutputStream()) {
|
try (OutputStream out = extPart.getOutputStream()) {
|
||||||
if (extPart.getSize() > 0) {
|
if (extPart.getSize() > 0) {
|
||||||
extPart.clear();
|
extPart.clear();
|
||||||
|
@ -231,7 +231,7 @@ public class POIXMLProperties {
|
||||||
ext.props.save(out, DEFAULT_XML_OPTIONS);
|
ext.props.save(out, DEFAULT_XML_OPTIONS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(custPart != null){
|
if(custPart != null && cust != null && cust.props != null){
|
||||||
try (OutputStream out = custPart.getOutputStream()) {
|
try (OutputStream out = custPart.getOutputStream()) {
|
||||||
cust.props.save(out, DEFAULT_XML_OPTIONS);
|
cust.props.save(out, DEFAULT_XML_OPTIONS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import java.io.OutputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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()}
|
* If your package is open read only, then you should call {@link #revert()}
|
||||||
* when finished with the package.
|
* when finished with the package.
|
||||||
*
|
*
|
||||||
|
* This method is not thread-safe.
|
||||||
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* If an IO exception occur during the saving process.
|
* If an IO exception occur during the saving process.
|
||||||
*/
|
*/
|
||||||
|
@ -434,10 +435,6 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the content
|
|
||||||
ReentrantReadWriteLock l = new ReentrantReadWriteLock();
|
|
||||||
try {
|
|
||||||
l.writeLock().lock();
|
|
||||||
if (this.originalPackagePath != null
|
if (this.originalPackagePath != null
|
||||||
&& !this.originalPackagePath.trim().isEmpty()) {
|
&& !this.originalPackagePath.trim().isEmpty()) {
|
||||||
File targetFile = new File(this.originalPackagePath);
|
File targetFile = new File(this.originalPackagePath);
|
||||||
|
@ -453,9 +450,6 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
|
||||||
save(this.output);
|
save(this.output);
|
||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
l.writeLock().unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear
|
// Clear
|
||||||
this.contentTypeManager.clearAll();
|
this.contentTypeManager.clearAll();
|
||||||
|
|
|
@ -21,8 +21,6 @@ import java.io.OutputStream;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.xml.XMLConstants;
|
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.exceptions.OpenXML4JException;
|
||||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
|
@ -36,14 +34,14 @@ import org.w3c.dom.Element;
|
||||||
* Package properties marshaller.
|
* Package properties marshaller.
|
||||||
*/
|
*/
|
||||||
public class PackagePropertiesMarshaller implements PartMarshaller {
|
public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||||
private final static Namespace namespaceDC, namespaceCoreProperties, namespaceDcTerms, namespaceXSI;
|
private final static NamespaceImpl namespaceDC =
|
||||||
static {
|
new NamespaceImpl("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
|
||||||
final XMLEventFactory f = XMLEventFactory.newInstance();
|
private final static NamespaceImpl namespaceCoreProperties =
|
||||||
namespaceDC = f.createNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
|
new NamespaceImpl("cp", PackagePropertiesPart.NAMESPACE_CP_URI);;
|
||||||
namespaceCoreProperties = f.createNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
|
private final static NamespaceImpl namespaceDcTerms =
|
||||||
namespaceDcTerms = f.createNamespace("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
new NamespaceImpl("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
||||||
namespaceXSI = f.createNamespace("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_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";
|
||||||
|
|
||||||
|
@ -98,10 +96,14 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||||
xmlDoc = DocumentHelper.createDocument();
|
xmlDoc = DocumentHelper.createDocument();
|
||||||
Element rootElem = xmlDoc.createElementNS(namespaceCoreProperties.getNamespaceURI(),
|
Element rootElem = xmlDoc.createElementNS(namespaceCoreProperties.getNamespaceURI(),
|
||||||
getQName("coreProperties", namespaceCoreProperties));
|
getQName("coreProperties", namespaceCoreProperties));
|
||||||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceCoreProperties);
|
DocumentHelper.addNamespaceDeclaration(rootElem,
|
||||||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDC);
|
namespaceCoreProperties.getPrefix(), namespaceCoreProperties.getNamespaceURI());
|
||||||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDcTerms);
|
DocumentHelper.addNamespaceDeclaration(rootElem,
|
||||||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceXSI);
|
namespaceDC.getPrefix(), namespaceDC.getNamespaceURI());
|
||||||
|
DocumentHelper.addNamespaceDeclaration(rootElem,
|
||||||
|
namespaceDcTerms.getPrefix(), namespaceDcTerms.getNamespaceURI());
|
||||||
|
DocumentHelper.addNamespaceDeclaration(rootElem,
|
||||||
|
namespaceXSI.getPrefix(), namespaceXSI.getNamespaceURI());
|
||||||
xmlDoc.appendChild(rootElem);
|
xmlDoc.appendChild(rootElem);
|
||||||
|
|
||||||
addCategory();
|
addCategory();
|
||||||
|
@ -126,15 +128,15 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||||
/**
|
/**
|
||||||
* Sets the given element's text content, creating it if necessary.
|
* 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));
|
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;
|
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())
|
if (!property.isPresent())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -149,7 +151,7 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||||
return elem;
|
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);
|
Element element = setElementTextContent(localName, namespace, property, propertyValue);
|
||||||
if (element != null) {
|
if (element != null) {
|
||||||
element.setAttributeNS(namespaceXSI.getNamespaceURI(), getQName("type", namespaceXSI), xsiType);
|
element.setAttributeNS(namespaceXSI.getNamespaceURI(), getQName("type", namespaceXSI), xsiType);
|
||||||
|
@ -231,7 +233,6 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add 'last printed' property if needed.
|
* Add 'last printed' property if needed.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private void addLastPrinted() {
|
private void addLastPrinted() {
|
||||||
setElementTextContent(KEYWORD_LAST_PRINTED, namespaceCoreProperties, propsPart.getLastPrintedProperty(), propsPart.getLastPrintedPropertyString());
|
setElementTextContent(KEYWORD_LAST_PRINTED, namespaceCoreProperties, propsPart.getLastPrintedProperty(), propsPart.getLastPrintedPropertyString());
|
||||||
|
@ -269,4 +270,20 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||||
private void addVersion() {
|
private void addVersion() {
|
||||||
setElementTextContent(KEYWORD_VERSION, namespaceCoreProperties, propsPart.getVersionProperty());
|
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;
|
package org.apache.poi.openxml4j.util;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Removal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An immutable object that could be defined as null.
|
* An immutable object that could be defined as null.
|
||||||
*
|
*
|
||||||
* @author Julien Chable
|
* @author Julien Chable
|
||||||
* @version 0.9
|
* @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> {
|
public final class Nullable<E> {
|
||||||
|
|
||||||
private E value;
|
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
|
* <p>To use SignatureInfo and its sibling classes, you'll need to have the following libs
|
||||||
* in the classpath:</p>
|
* in the classpath:</p>
|
||||||
* <ul>
|
* <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>Apache Santuario "xmlsec" (tested against 2.1.0)</li>
|
||||||
* <li>and slf4j-api (tested against 1.7.25)</li>
|
* <li>and slf4j-api (tested against 1.7.25)</li>
|
||||||
* </ul>
|
* </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,
|
public XDDFBarChartData(CTBarChart chart, Map<Long, XDDFChartAxis> categories,
|
||||||
Map<Long, XDDFValueAxis> values) {
|
Map<Long, XDDFValueAxis> values) {
|
||||||
this.chart = chart;
|
this.chart = chart;
|
||||||
|
if (chart.getBarDir() == null) {
|
||||||
|
chart.addNewBarDir().setVal(BarDirection.BAR.underlying);
|
||||||
|
}
|
||||||
for (CTBarSer series : chart.getSerList()) {
|
for (CTBarSer series : chart.getSerList()) {
|
||||||
this.series.add(new Series(series, series.getCat(), series.getVal()));
|
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);
|
defineAxes(chart.getAxIdArray(), categories, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +109,7 @@ public class XDDFBarChartData extends XDDFChartData {
|
||||||
XDDFNumericalDataSource<? extends Number> values) {
|
XDDFNumericalDataSource<? extends Number> values) {
|
||||||
final int index = this.series.size();
|
final int index = this.series.size();
|
||||||
final CTBarSer ctSer = this.chart.addNewSer();
|
final CTBarSer ctSer = this.chart.addNewSer();
|
||||||
|
ctSer.addNewTx();
|
||||||
ctSer.addNewCat();
|
ctSer.addNewCat();
|
||||||
ctSer.addNewVal();
|
ctSer.addNewVal();
|
||||||
ctSer.addNewIdx().setVal(index);
|
ctSer.addNewIdx().setVal(index);
|
||||||
|
@ -119,7 +135,11 @@ public class XDDFBarChartData extends XDDFChartData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CTSerTx getSeriesText() {
|
protected CTSerTx getSeriesText() {
|
||||||
|
if (series.isSetTx()) {
|
||||||
return series.getTx();
|
return series.getTx();
|
||||||
|
} else {
|
||||||
|
return series.addNewTx();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -79,6 +79,19 @@ public class XDDFCategoryAxis extends XDDFChartAxis {
|
||||||
return new XDDFShapeProperties(properties);
|
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
|
@Override
|
||||||
public boolean isSetMinorUnit() {
|
public boolean isSetMinorUnit() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -23,4 +23,23 @@ import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
@Beta
|
@Beta
|
||||||
public interface XDDFCategoryDataSource extends XDDFDataSource<String> {
|
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.CTSerAx;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurface;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurface;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
|
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.CTValAx;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
|
||||||
|
@ -214,6 +213,72 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
|
||||||
chart.getAutoTitleDeleted().setVal(deleted);
|
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
|
* Get the chart title body if there is one, i.e. title is set and is not a
|
||||||
* formula.
|
* formula.
|
||||||
|
@ -225,15 +290,7 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
|
||||||
if (!chart.isSetTitle()) {
|
if (!chart.isSetTitle()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
CTTitle title = chart.getTitle();
|
return new XDDFTitle(this, chart.getTitle()).getBody();
|
||||||
if (!title.isSetTx()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
CTTx tx = title.getTx();
|
|
||||||
if (!tx.isSetRich()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new XDDFTextBody(this, tx.getRich());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -327,7 +384,7 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
|
||||||
private Map<Long, XDDFChartAxis> getCategoryAxes() {
|
private Map<Long, XDDFChartAxis> getCategoryAxes() {
|
||||||
CTPlotArea plotArea = getCTPlotArea();
|
CTPlotArea plotArea = getCTPlotArea();
|
||||||
int sizeOfArray = plotArea.sizeOfCatAxArray();
|
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++) {
|
for (int i = 0; i < sizeOfArray; i++) {
|
||||||
CTCatAx category = plotArea.getCatAxArray(i);
|
CTCatAx category = plotArea.getCatAxArray(i);
|
||||||
axes.put(category.getAxId().getVal(), new XDDFCategoryAxis(category));
|
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
|
* @param title
|
||||||
* title of sheet
|
* title of sheet
|
||||||
|
* @param column
|
||||||
|
* column index
|
||||||
* @return return cell reference
|
* @return return cell reference
|
||||||
* @since POI 4.0.0
|
* @since POI 4.0.0
|
||||||
*/
|
*/
|
||||||
public CellReference setSheetTitle(String title) {
|
public CellReference setSheetTitle(String title, int column) {
|
||||||
XSSFSheet sheet = getSheet();
|
XSSFSheet sheet = getSheet();
|
||||||
XSSFRow row = this.getRow(sheet, 0);
|
XSSFRow row = this.getRow(sheet, 0);
|
||||||
XSSFCell cell = this.getCell(row, 1);
|
XSSFCell cell = this.getCell(row, column);
|
||||||
cell.setCellValue(title);
|
cell.setCellValue(title);
|
||||||
this.updateSheetTable(sheet.getTables().get(0).getCTTable(), title, 1);
|
this.updateSheetTable(sheet.getTables().get(0).getCTTable(), title, column);
|
||||||
return new CellReference(sheet.getSheetName(), 0, 1, true, true);
|
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) {
|
private void updateSheetTable(CTTable ctTable, String title, int index) {
|
||||||
CTTableColumns tableColumnList = ctTable.getTableColumns();
|
CTTableColumns tableColumnList = ctTable.getTableColumns();
|
||||||
CTTableColumn column = null;
|
CTTableColumn column = null;
|
||||||
if (tableColumnList.getCount() >= index) {
|
for( int i = 0; tableColumnList.getCount() < index; i++) {
|
||||||
column = tableColumnList.getTableColumnArray(index);
|
|
||||||
} else {
|
|
||||||
column = tableColumnList.addNewTableColumn();
|
column = tableColumnList.addNewTableColumn();
|
||||||
column.setId(index);
|
column.setId(i);
|
||||||
}
|
}
|
||||||
|
column = tableColumnList.getTableColumnArray(index);
|
||||||
column.setName(title);
|
column.setName(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,11 @@ public abstract class XDDFChartAxis implements HasShapeProperties {
|
||||||
|
|
||||||
public abstract XDDFShapeProperties getOrAddMinorGridProperties();
|
public abstract XDDFShapeProperties getOrAddMinorGridProperties();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.0.1
|
||||||
|
*/
|
||||||
|
public abstract void setTitle(String text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if minor unit value is defined, false otherwise
|
* @return true if minor unit value is defined, false otherwise
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -130,6 +130,10 @@ public abstract class XDDFChartData {
|
||||||
} else {
|
} else {
|
||||||
cache = ref.addNewStrCache();
|
cache = ref.addNewStrCache();
|
||||||
}
|
}
|
||||||
|
if (cache.sizeOfPtArray() < 1) {
|
||||||
|
cache.addNewPtCount().setVal(1);
|
||||||
|
cache.addNewPt().setIdx(0);;
|
||||||
|
}
|
||||||
cache.getPtArray(0).setV(title);
|
cache.getPtArray(0).setV(title);
|
||||||
ref.setF(titleRef.formatAsString());
|
ref.setF(titleRef.formatAsString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,4 +34,6 @@ public interface XDDFDataSource<T> {
|
||||||
int getColIndex();
|
int getColIndex();
|
||||||
|
|
||||||
String getDataRangeReference();
|
String getDataRangeReference();
|
||||||
|
|
||||||
|
String getFormula();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,17 +41,18 @@ public class XDDFDataSourcesFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XDDFCategoryDataSource fromDataSource(final CTAxDataSource categoryDS) {
|
public static XDDFCategoryDataSource fromDataSource(final CTAxDataSource categoryDS) {
|
||||||
|
if (categoryDS.getStrRef() == null) {
|
||||||
return new XDDFCategoryDataSource() {
|
return new XDDFCategoryDataSource() {
|
||||||
private CTStrData category = (CTStrData) categoryDS.getStrRef().getStrCache().copy();
|
private CTNumData category = (CTNumData) categoryDS.getNumRef().getNumCache().copy();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNumeric() {
|
public boolean isNumeric() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReference() {
|
public String getFormula() {
|
||||||
return true;
|
return categoryDS.getNumRef().getF();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -63,24 +64,39 @@ public class XDDFDataSourcesFactory {
|
||||||
public String getPointAt(int index) {
|
public String getPointAt(int index) {
|
||||||
return category.getPtArray(index).getV();
|
return category.getPtArray(index).getV();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return new XDDFCategoryDataSource() {
|
||||||
|
private CTStrData category = (CTStrData) categoryDS.getStrRef().getStrCache().copy();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDataRangeReference() {
|
public String getFormula() {
|
||||||
return categoryDS.getStrRef().getF();
|
return categoryDS.getStrRef().getF();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColIndex() {
|
public int getPointCount() {
|
||||||
return 0;
|
return (int) category.getPtCount().getVal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPointAt(int index) {
|
||||||
|
return category.getPtArray(index).getV();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static XDDFNumericalDataSource<Double> fromDataSource(final CTNumDataSource valuesDS) {
|
public static XDDFNumericalDataSource<Double> fromDataSource(final CTNumDataSource valuesDS) {
|
||||||
return new XDDFNumericalDataSource<Double>() {
|
return new XDDFNumericalDataSource<Double>() {
|
||||||
private CTNumData values = (CTNumData) valuesDS.getNumRef().getNumCache().copy();
|
private CTNumData values = (CTNumData) valuesDS.getNumRef().getNumCache().copy();
|
||||||
private String formatCode = values.isSetFormatCode() ? values.getFormatCode() : null;
|
private String formatCode = values.isSetFormatCode() ? values.getFormatCode() : null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormula() {
|
||||||
|
return valuesDS.getNumRef().getF();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFormatCode() {
|
public String getFormatCode() {
|
||||||
return formatCode;
|
return formatCode;
|
||||||
|
@ -124,7 +140,7 @@ public class XDDFDataSourcesFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Number> XDDFNumericalDataSource<T> fromArray(T[] elements, String dataRange) {
|
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) {
|
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) {
|
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) {
|
public static XDDFCategoryDataSource fromArray(String[] elements, String dataRange, int col) {
|
||||||
|
@ -212,6 +228,11 @@ public class XDDFDataSourcesFactory {
|
||||||
super(elements, dataRange, col);
|
super(elements, dataRange, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormula() {
|
||||||
|
return getDataRangeReference();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFormatCode() {
|
public String getFormatCode() {
|
||||||
return formatCode;
|
return formatCode;
|
||||||
|
@ -232,6 +253,11 @@ public class XDDFDataSourcesFactory {
|
||||||
public StringArrayDataSource(String[] elements, String dataRange, int col) {
|
public StringArrayDataSource(String[] elements, String dataRange, int col) {
|
||||||
super(elements, dataRange, col);
|
super(elements, dataRange, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormula() {
|
||||||
|
return getDataRangeReference();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract static class AbstractCellRangeDataSource<T> implements XDDFDataSource<T> {
|
private abstract static class AbstractCellRangeDataSource<T> implements XDDFDataSource<T> {
|
||||||
|
@ -290,6 +316,11 @@ public class XDDFDataSourcesFactory {
|
||||||
super(sheet, cellRangeAddress);
|
super(sheet, cellRangeAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormula() {
|
||||||
|
return getDataRangeReference();
|
||||||
|
}
|
||||||
|
|
||||||
private String formatCode;
|
private String formatCode;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -324,6 +355,11 @@ public class XDDFDataSourcesFactory {
|
||||||
super(sheet, cellRangeAddress);
|
super(sheet, cellRangeAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormula() {
|
||||||
|
return getDataRangeReference();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPointAt(int index) {
|
public String getPointAt(int index) {
|
||||||
CellValue cellValue = getCellValueAt(index);
|
CellValue cellValue = getCellValueAt(index);
|
||||||
|
|
|
@ -82,6 +82,19 @@ public class XDDFDateAxis extends XDDFChartAxis {
|
||||||
return new XDDFShapeProperties(properties);
|
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
|
@Override
|
||||||
public boolean isSetMinorUnit() {
|
public boolean isSetMinorUnit() {
|
||||||
return ctDateAx.isSetMinorUnit();
|
return ctDateAx.isSetMinorUnit();
|
||||||
|
|
|
@ -38,6 +38,18 @@ public class XDDFLineChartData extends XDDFChartData {
|
||||||
for (CTLineSer series : chart.getSerList()) {
|
for (CTLineSer series : chart.getSerList()) {
|
||||||
this.series.add(new Series(series, series.getCat(), series.getVal()));
|
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);
|
defineAxes(chart.getAxIdArray(), categories, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +100,11 @@ public class XDDFLineChartData extends XDDFChartData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CTSerTx getSeriesText() {
|
protected CTSerTx getSeriesText() {
|
||||||
|
if (series.isSetTx()) {
|
||||||
return series.getTx();
|
return series.getTx();
|
||||||
|
} else {
|
||||||
|
return series.addNewTx();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
public void setMarkerSize(short size) {
|
||||||
|
if (size < 2 || 72 < size) {
|
||||||
|
throw new IllegalArgumentException("Minimum inclusive: 2; Maximum inclusive: 72");
|
||||||
|
}
|
||||||
CTMarker marker = getMarker();
|
CTMarker marker = getMarker();
|
||||||
if (marker.isSetSize()) {
|
if (marker.isSetSize()) {
|
||||||
marker.getSize().setVal(size);
|
marker.getSize().setVal(size);
|
||||||
|
|
|
@ -75,7 +75,11 @@ public class XDDFPieChartData extends XDDFChartData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CTSerTx getSeriesText() {
|
protected CTSerTx getSeriesText() {
|
||||||
|
if (series.isSetTx()) {
|
||||||
return series.getTx();
|
return series.getTx();
|
||||||
|
} else {
|
||||||
|
return series.addNewTx();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -38,6 +38,18 @@ public class XDDFRadarChartData extends XDDFChartData {
|
||||||
for (CTRadarSer series : chart.getSerList()) {
|
for (CTRadarSer series : chart.getSerList()) {
|
||||||
this.series.add(new Series(series, series.getCat(), series.getVal()));
|
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);
|
defineAxes(chart.getAxIdArray(), categories, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +104,11 @@ public class XDDFRadarChartData extends XDDFChartData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CTSerTx getSeriesText() {
|
protected CTSerTx getSeriesText() {
|
||||||
|
if (series.isSetTx()) {
|
||||||
return series.getTx();
|
return series.getTx();
|
||||||
|
} else {
|
||||||
|
return series.addNewTx();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
||||||
import org.apache.poi.util.Beta;
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
|
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
|
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.CTNumDataSource;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer;
|
||||||
|
@ -38,6 +39,18 @@ public class XDDFScatterChartData extends XDDFChartData {
|
||||||
for (CTScatterSer series : chart.getSerList()) {
|
for (CTScatterSer series : chart.getSerList()) {
|
||||||
this.series.add(new Series(series, series.getXVal(), series.getYVal()));
|
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);
|
defineAxes(chart.getAxIdArray(), categories, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +109,78 @@ public class XDDFScatterChartData extends XDDFChartData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CTSerTx getSeriesText() {
|
protected CTSerTx getSeriesText() {
|
||||||
|
if (series.isSetTx()) {
|
||||||
return series.getTx();
|
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
|
@Override
|
||||||
|
|
|
@ -79,6 +79,19 @@ public class XDDFSeriesAxis extends XDDFChartAxis {
|
||||||
return new XDDFShapeProperties(properties);
|
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
|
@Override
|
||||||
public boolean isSetMinorUnit() {
|
public boolean isSetMinorUnit() {
|
||||||
return false;
|
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);
|
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
|
@Override
|
||||||
public boolean isSetMinorUnit() {
|
public boolean isSetMinorUnit() {
|
||||||
return ctValAx.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() {
|
public XDDFRunProperties getDefaultRunProperties() {
|
||||||
if (props.isSetDefRPr()) {
|
if (props.isSetDefRPr()) {
|
||||||
return new XDDFRunProperties(props.getDefRPr());
|
return new XDDFRunProperties(props.getDefRPr());
|
||||||
|
|
|
@ -70,6 +70,19 @@ public class XDDFTextBody {
|
||||||
return p;
|
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() {
|
public XDDFTextParagraph addNewParagraph() {
|
||||||
return new XDDFTextParagraph(_body.addNewP(), this);
|
return new XDDFTextParagraph(_body.addNewP(), this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,24 @@ public class XDDFTextParagraph {
|
||||||
_runs.add(new XDDFTextRun((CTRegularTextRun) xo, this));
|
_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() {
|
public String getText() {
|
||||||
|
@ -662,6 +680,13 @@ public class XDDFTextParagraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.0.1
|
||||||
|
*/
|
||||||
|
public XDDFRunProperties addDefaultRunProperties() {
|
||||||
|
return getOrCreateProperties().addDefaultRunProperties();
|
||||||
|
}
|
||||||
|
|
||||||
public XDDFRunProperties getDefaultRunProperties() {
|
public XDDFRunProperties getDefaultRunProperties() {
|
||||||
if (_p.isSetPPr()) {
|
if (_p.isSetPPr()) {
|
||||||
return getProperties().getDefaultRunProperties();
|
return getProperties().getDefaultRunProperties();
|
||||||
|
|
|
@ -372,8 +372,8 @@ public class XMLSlideShow extends POIXMLDocument
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!themeIndexList.isEmpty()) {
|
if (!themeIndexList.isEmpty()) {
|
||||||
Boolean found = false;
|
boolean found = false;
|
||||||
for (Integer i = 1; i <= themeIndexList.size(); i++) {
|
for (int i = 1; i <= themeIndexList.size(); i++) {
|
||||||
if (!themeIndexList.contains(i)) {
|
if (!themeIndexList.contains(i)) {
|
||||||
found = true;
|
found = true;
|
||||||
themeIndex = i;
|
themeIndex = i;
|
||||||
|
|
|
@ -78,6 +78,19 @@ public class XSLFBackground extends XSLFSimpleShape
|
||||||
public void setFillColor(Color color) {
|
public void setFillColor(Color color) {
|
||||||
CTBackgroundProperties bgPr = getBgPr(true);
|
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 (color == null) {
|
||||||
if (bgPr.isSetSolidFill()) {
|
if (bgPr.isSetSolidFill()) {
|
||||||
bgPr.unsetSolidFill();
|
bgPr.unsetSolidFill();
|
||||||
|
|
|
@ -69,7 +69,7 @@ public final class XSLFChart extends XDDFChart {
|
||||||
return XSLFFactory.getInstance();
|
return XSLFFactory.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public XSLFTextShape getTitle() {
|
public XSLFTextShape getTitleShape() {
|
||||||
if (!chart.isSetTitle()) {
|
if (!chart.isSetTitle()) {
|
||||||
chart.addNewTitle();
|
chart.addNewTitle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ public class XSLFColor {
|
||||||
colorRef = _phClr.getVal().toString();
|
colorRef = _phClr.getVal().toString();
|
||||||
}
|
}
|
||||||
// find referenced CTColor in the theme and convert it to java.awt.Color via a recursive call
|
// 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) {
|
if(ctColor != null) {
|
||||||
color = toColor(ctColor, null);
|
color = toColor(ctColor, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -692,11 +692,25 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
|
||||||
/**
|
/**
|
||||||
* Helper method for sheet and group shapes
|
* 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) {
|
void removePictureRelation(XSLFPictureShape pictureShape) {
|
||||||
|
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());
|
removeRelation(pictureShape.getBlipId());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -98,7 +98,7 @@ public class StylesTable extends POIXMLDocumentPart implements Styles {
|
||||||
if (num < 0) {
|
if (num < 0) {
|
||||||
throw new IllegalArgumentException("Maximum Number of Data Formats must be greater than or equal to 0");
|
throw new IllegalArgumentException("Maximum Number of Data Formats must be greater than or equal to 0");
|
||||||
} else {
|
} 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.");
|
"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);
|
short nextKey = (short) (numberFormats.lastKey() + 1);
|
||||||
if (nextKey < 0) {
|
if (nextKey < 0) {
|
||||||
throw new IllegalStateException(
|
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.");
|
"This is probably due to arithmetic overflow.");
|
||||||
}
|
}
|
||||||
formatIndex = (short) Math.max(nextKey, FIRST_USER_DEFINED_NUMBER_FORMAT_ID);
|
formatIndex = (short) Math.max(nextKey, FIRST_USER_DEFINED_NUMBER_FORMAT_ID);
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
package org.apache.poi.xssf.usermodel;
|
package org.apache.poi.xssf.usermodel;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -33,8 +35,10 @@ import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
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.
|
||||||
|
@ -349,6 +353,7 @@ public enum XSSFBuiltinTableStyle {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: only checks by name, not definition.
|
* NOTE: only checks by name, not definition.
|
||||||
|
*
|
||||||
* @param style
|
* @param style
|
||||||
* @return true if the style represents a built-in style, false if it is null or a custom 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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only init once - thus the synchronized. Lazy, after creating instances,
|
* Only init once - thus the synchronized. Lazy, after creating instances,
|
||||||
* and only when a style is actually needed, to avoid overhead for uses
|
* and only when a style is actually needed, to avoid overhead for uses
|
||||||
|
@ -370,7 +376,7 @@ public enum XSSFBuiltinTableStyle {
|
||||||
* during evaluation if desired.
|
* during evaluation if desired.
|
||||||
*/
|
*/
|
||||||
public static synchronized void init() {
|
public static synchronized void init() {
|
||||||
if (! styleMap.isEmpty()) return;
|
if (!styleMap.isEmpty()) return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize map. Every built-in has this format:
|
* initialize map. Every built-in has this format:
|
||||||
|
@ -390,7 +396,7 @@ public enum XSSFBuiltinTableStyle {
|
||||||
final Document doc = DocumentHelper.readDocument(is);
|
final Document doc = DocumentHelper.readDocument(is);
|
||||||
|
|
||||||
final NodeList styleNodes = doc.getDocumentElement().getChildNodes();
|
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);
|
final Node node = styleNodes.item(i);
|
||||||
if (node.getNodeType() != Node.ELEMENT_NODE) continue; // only care about elements
|
if (node.getNodeType() != Node.ELEMENT_NODE) continue; // only care about elements
|
||||||
final Element tag = (Element) node;
|
final Element tag = (Element) node;
|
||||||
|
@ -414,27 +420,34 @@ public enum XSSFBuiltinTableStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
// built-ins doc uses 1-based dxf indexing, Excel uses 0 based.
|
||||||
// add a dummy node to adjust properly.
|
// add a dummy node to adjust properly.
|
||||||
dxfsNode.insertBefore(dxfsNode.getOwnerDocument().createElement("dxf"), dxfsNode.getFirstChild());
|
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();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n")
|
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n")
|
||||||
.append("<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" "
|
.append("<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ")
|
||||||
+ "xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" "
|
.append("xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" ")
|
||||||
+ "xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" "
|
.append("xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" ")
|
||||||
+ "xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\" "
|
.append("xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\" ")
|
||||||
+ "mc:Ignorable=\"x14ac x16r2\">\n");
|
.append("mc:Ignorable=\"x14ac x16r2\">\n");
|
||||||
sb.append(lsSerializer.writeToString(dxfsNode));
|
sb.append(writeToString(dxfsNode));
|
||||||
sb.append(lsSerializer.writeToString(tableStyleNode));
|
sb.append(writeToString(tableStyleNode));
|
||||||
sb.append("</styleSheet>");
|
sb.append("</styleSheet>");
|
||||||
return sb.toString();
|
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
|
* implementation for built-in styles
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -491,11 +491,14 @@ public final class XSSFCell implements Cell {
|
||||||
return cell.getCellFormula(fpb);
|
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);
|
return convertSharedFormula((int)f.getSi(), fpb == null ? XSSFEvaluationWorkbook.create(getSheet().getWorkbook()) : fpb);
|
||||||
}
|
} else {
|
||||||
return f.getStringValue();
|
return f.getStringValue();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a non shared formula from the shared formula counterpart
|
* Creates a non shared formula from the shared formula counterpart
|
||||||
|
|
|
@ -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.CTTitle;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTx;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTx;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
|
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.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.w3c.dom.Text;
|
import org.w3c.dom.Text;
|
||||||
|
@ -260,19 +256,6 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
|
||||||
return new XSSFManualLayout(this);
|
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
|
* 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
|
* 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());
|
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
|
* Get the chart title formula expression if there is one
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
package org.apache.poi.xssf.usermodel;
|
package org.apache.poi.xssf.usermodel;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
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.Internal;
|
||||||
import org.apache.poi.util.Units;
|
import org.apache.poi.util.Units;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
|
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());
|
// 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) {
|
private CTMarker calcCell(CTMarker cell, long w, long h) {
|
||||||
CTMarker c2 = CTMarker.Factory.newInstance();
|
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
|
// we potentially need to adjust the column/row information in the shape
|
||||||
// the same way as we do in setRow()/setColumn()
|
// 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());
|
CellReference ref = new CellReference(comment.getRef());
|
||||||
CTClientData clientData = vmlShape.getClientDataArray(0);
|
CTClientData clientData = vmlShape.getClientDataArray(0);
|
||||||
clientData.setRowArray(0, new BigInteger(String.valueOf(ref.getRow())));
|
clientData.setRowArray(0, new BigInteger(String.valueOf(ref.getRow())));
|
||||||
|
@ -70,7 +70,7 @@ public class XSSFComment implements Comment {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getAuthor() {
|
public String getAuthor() {
|
||||||
return _comments.getAuthor((int) _comment.getAuthorId());
|
return _comments.getAuthor(_comment.getAuthorId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,9 +80,7 @@ public class XSSFComment implements Comment {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setAuthor(String author) {
|
public void setAuthor(String author) {
|
||||||
_comment.setAuthorId(
|
_comment.setAuthorId(_comments.findAuthor(author));
|
||||||
_comments.findAuthor(author)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2262,8 +2262,8 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unsetCollapsed(boolean collapsed, CTCol ci) {
|
private void unsetCollapsed(Boolean collapsed, CTCol ci) {
|
||||||
if (collapsed) {
|
if (collapsed != null && collapsed.booleanValue()) {
|
||||||
ci.setCollapsed(collapsed);
|
ci.setCollapsed(collapsed);
|
||||||
} else {
|
} else {
|
||||||
ci.unsetCollapsed();
|
ci.unsetCollapsed();
|
||||||
|
@ -2410,7 +2410,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
||||||
boolean endHidden = false;
|
boolean endHidden = false;
|
||||||
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
|
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
|
||||||
CTCol[] colArray = cols.getColArray();
|
CTCol[] colArray = cols.getColArray();
|
||||||
if (endOfOutlineGroupIdx < colArray.length) {
|
if (endOfOutlineGroupIdx < (colArray.length - 1)) {
|
||||||
CTCol nextInfo = colArray[endOfOutlineGroupIdx + 1];
|
CTCol nextInfo = colArray[endOfOutlineGroupIdx + 1];
|
||||||
if (isAdjacentBefore(colArray[endOfOutlineGroupIdx], nextInfo)) {
|
if (isAdjacentBefore(colArray[endOfOutlineGroupIdx], nextInfo)) {
|
||||||
endLevel = nextInfo.getOutlineLevel();
|
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() + ".");
|
// "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.
|
// FIXME: assumes row objects belong to non-null sheets and sheets belong to non-null workbooks.
|
||||||
} else if (srcStartRow.getSheet().getWorkbook() != curRow.getSheet().getWorkbook()) {
|
} 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() + "). " +
|
"Expected all rows from same workbook (" + srcStartRow.getSheet().getWorkbook() + "). " +
|
||||||
"Got srcRows[" + index + "] from different workbook (" + curRow.getSheet().getWorkbook() + ").");
|
"Got srcRows[" + index + "] from different workbook (" + curRow.getSheet().getWorkbook() + ").");
|
||||||
} else if (srcStartRow.getSheet() != curRow.getSheet()) {
|
} 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
|
// check if name is unique and calculate unique column id
|
||||||
long nextColumnId = 1;
|
long nextColumnId = 0;
|
||||||
for (XSSFTableColumn tableColumn : getColumns()) {
|
for (XSSFTableColumn tableColumn : getColumns()) {
|
||||||
if (columnName != null && columnName.equalsIgnoreCase(tableColumn.getName())) {
|
if (columnName != null && columnName.equalsIgnoreCase(tableColumn.getName())) {
|
||||||
throw new IllegalArgumentException("Column '" + columnName
|
throw new IllegalArgumentException("Column '" + columnName
|
||||||
|
@ -291,6 +291,8 @@ public class XSSFTable extends POIXMLDocumentPart implements Table {
|
||||||
}
|
}
|
||||||
nextColumnId = Math.max(nextColumnId, tableColumn.getId());
|
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
|
// Add the new Column
|
||||||
CTTableColumn column = columns.insertNewTableColumn(columnIndex);
|
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
|
* this method does not create or remove any columns and does not change any
|
||||||
* cell values.
|
* 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"
|
* @see "Open Office XML Part 4: chapter 3.5.1.2, attribute ref"
|
||||||
* @since 3.17 beta 1
|
* @since 3.17 beta 1
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
@Removal(version="4.2.0")
|
|
||||||
public void setCellReferences(AreaReference refs) {
|
public void setCellReferences(AreaReference refs) {
|
||||||
setCellRef(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
|
* 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.
|
* the right side of the table but will not modify any cell values.
|
||||||
*
|
*
|
||||||
* @param refs
|
* @param tableArea
|
||||||
* the new area of the table
|
* the new area of the table
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* if the area is {@code null} or not
|
* if the area is {@code null} or not
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
|
|
||||||
package org.apache.poi.xssf.usermodel.helpers;
|
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.FormulaParser;
|
||||||
import org.apache.poi.ss.formula.FormulaRenderer;
|
import org.apache.poi.ss.formula.FormulaRenderer;
|
||||||
import org.apache.poi.ss.formula.FormulaType;
|
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.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
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.XSSFEvaluationWorkbook;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFName;
|
import org.apache.poi.xssf.usermodel.XSSFName;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
|
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
|
* 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)}
|
* Called from {@link XSSFWorkbook#setSheetName(int, String)}
|
||||||
* <p>
|
* <p>
|
||||||
* <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);
|
updatePtg(ptg, oldName, newName);
|
||||||
}
|
}
|
||||||
String updatedFormula = FormulaRenderer.toFormulaString(_fpwb, ptgs);
|
String updatedFormula = FormulaRenderer.toFormulaString(_fpwb, ptgs);
|
||||||
if (!formula.equals(updatedFormula)) f.setStringValue(updatedFormula);
|
if (!formula.equals(updatedFormula)) {
|
||||||
|
f.setStringValue(updatedFormula);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +143,9 @@ public final class XSSFFormulaUtils {
|
||||||
updatePtg(ptg, oldName, newName);
|
updatePtg(ptg, oldName, newName);
|
||||||
}
|
}
|
||||||
String updatedFormula = FormulaRenderer.toFormulaString(_fpwb, ptgs);
|
String updatedFormula = FormulaRenderer.toFormulaString(_fpwb, ptgs);
|
||||||
if (!formula.equals(updatedFormula)) name.setRefersToFormula(updatedFormula);
|
if (!formula.equals(updatedFormula)) {
|
||||||
|
name.setRefersToFormula(updatedFormula);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
@ -26,29 +38,11 @@ import java.security.AccessController;
|
||||||
import java.security.CodeSource;
|
import java.security.CodeSource;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
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.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.regex.Pattern;
|
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
|
* 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
|
//see what classes from the ooxml-schemas.jar are loaded
|
||||||
System.out.println("Copying classes to " + _destDest);
|
System.out.println("Copying classes to " + _destDest);
|
||||||
Map<String, Class<?>> classes = getLoadedClasses(_ooxmlJar.getName());
|
Set<Class<?>> classes = getLoadedClasses(_ooxmlJar.getName());
|
||||||
for (Class<?> cls : classes.values()) {
|
Set<String> packages = new HashSet<>();
|
||||||
String className = cls.getName();
|
for (Class<?> cls : classes) {
|
||||||
String classRef = className.replace('.', '/') + ".class";
|
copyFile(cls);
|
||||||
File destFile = new File(_destDest, classRef);
|
packages.add(cls.getPackage().getName());
|
||||||
IOUtils.copy(cls.getResourceAsStream('/' + classRef), destFile);
|
|
||||||
|
|
||||||
if(cls.isInterface()){
|
if (cls.isInterface()) {
|
||||||
/// Copy classes and interfaces declared as members of this class
|
/// Copy classes and interfaces declared as members of this class
|
||||||
for(Class<?> fc : cls.getDeclaredClasses()){
|
for (Class<?> fc : cls.getDeclaredClasses()) {
|
||||||
className = fc.getName();
|
copyFile(fc);
|
||||||
classRef = className.replace('.', '/') + ".class";
|
}
|
||||||
destFile = new File(_destDest, classRef);
|
}
|
||||||
IOUtils.copy(fc.getResourceAsStream('/' + classRef), destFile);
|
}
|
||||||
|
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) {
|
private static boolean checkForTestAnnotation(Class<?> testclass) {
|
||||||
for (Method m : testclass.getDeclaredMethods()) {
|
for (Method m : testclass.getDeclaredMethods()) {
|
||||||
if(m.isAnnotationPresent(Test.class)) {
|
if(m.isAnnotationPresent(Test.class)) {
|
||||||
|
@ -293,10 +311,10 @@ public final class OOXMLLite {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param ptrn the pattern to filter output
|
* @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")
|
@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
|
// 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
|
// 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
|
// 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();
|
ClassLoader appLoader = ClassLoader.getSystemClassLoader();
|
||||||
try {
|
try {
|
||||||
Vector<Class<?>> classes = (Vector<Class<?>>) _classes.get(appLoader);
|
Vector<Class<?>> classes = (Vector<Class<?>>) _classes.get(appLoader);
|
||||||
Map<String, Class<?>> map = new HashMap<>();
|
Set<Class<?>> set = new HashSet<>();
|
||||||
for (Class<?> cls : classes) {
|
for (Class<?> cls : classes) {
|
||||||
// e.g. proxy-classes, ...
|
// e.g. proxy-classes, ...
|
||||||
ProtectionDomain pd = cls.getProtectionDomain();
|
ProtectionDomain pd = cls.getProtectionDomain();
|
||||||
|
@ -329,10 +347,10 @@ public final class OOXMLLite {
|
||||||
|
|
||||||
String jar = loc.toString();
|
String jar = loc.toString();
|
||||||
if (jar.contains(ptrn)) {
|
if (jar.contains(ptrn)) {
|
||||||
map.put(cls.getName(), cls);
|
set.add(cls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return set;
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,12 @@ public class TestDocumentHelper {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDocumentBuilderFactory() throws Exception {
|
public void testDocumentBuilderFactory() throws Exception {
|
||||||
|
try {
|
||||||
assertTrue(DocumentHelper.documentBuilderFactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
|
assertTrue(DocumentHelper.documentBuilderFactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
|
||||||
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
|
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
|
||||||
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
|
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.junit.Test;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXNotRecognizedException;
|
||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
|
|
||||||
public class TestSAXHelper {
|
public class TestSAXHelper {
|
||||||
|
@ -31,6 +32,7 @@ public class TestSAXHelper {
|
||||||
public void testXMLReader() throws Exception {
|
public void testXMLReader() throws Exception {
|
||||||
XMLReader reader = SAXHelper.newXMLReader();
|
XMLReader reader = SAXHelper.newXMLReader();
|
||||||
assertNotSame(reader, SAXHelper.newXMLReader());
|
assertNotSame(reader, SAXHelper.newXMLReader());
|
||||||
|
try {
|
||||||
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
|
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
|
||||||
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
|
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
|
||||||
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
|
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
|
||||||
|
@ -38,7 +40,10 @@ public class TestSAXHelper {
|
||||||
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
|
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
|
||||||
assertEquals("1", reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
|
assertEquals("1", reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
|
||||||
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_SECURITY_MANAGER));
|
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"))));
|
reader.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes("UTF-8"))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -907,7 +907,7 @@ public final class TestPackage {
|
||||||
getZipStatsAndConsume((max_size, min_ratio) -> {
|
getZipStatsAndConsume((max_size, min_ratio) -> {
|
||||||
// check max entry size ouf of bounds
|
// check max entry size ouf of bounds
|
||||||
ZipSecureFile.setMinInflateRatio(min_ratio-0.002);
|
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) {
|
if (ze.getSize() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// add zip entry header ~ 30 bytes
|
// add zip entry header ~ 128 bytes
|
||||||
long size = ze.getSize()+30;
|
long size = ze.getSize()+128;
|
||||||
double ratio = ze.getCompressedSize() / (double)size;
|
double ratio = ze.getCompressedSize() / (double)size;
|
||||||
min_ratio = Math.min(min_ratio, ratio);
|
min_ratio = Math.min(min_ratio, ratio);
|
||||||
max_size = Math.max(max_size, size);
|
max_size = Math.max(max_size, size);
|
||||||
|
|
|
@ -93,6 +93,87 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
||||||
public class TestXSLFBugs {
|
public class TestXSLFBugs {
|
||||||
private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
|
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
|
@Test
|
||||||
public void bug61589() throws IOException {
|
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);
|
final XDDFNumericalDataSource<Integer> valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange);
|
||||||
series.replaceData(categoryData, valuesData);
|
series.replaceData(categoryData, valuesData);
|
||||||
final String title = "Apache POI";
|
final String title = "Apache POI";
|
||||||
series.setTitle(title, chart.setSheetTitle(title));
|
series.setTitle(title, chart.setSheetTitle(title, 0));
|
||||||
chart.plot(data);
|
chart.plot(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -395,15 +396,21 @@ public final class TestXSSFTable {
|
||||||
assertEquals(2, table.getRowCount());
|
assertEquals(2, table.getRowCount());
|
||||||
|
|
||||||
// add columns
|
// add columns
|
||||||
table.createColumn("Column B");
|
XSSFTableColumn c1 = table.getColumns().get(0);
|
||||||
table.createColumn("Column D");
|
XSSFTableColumn cB = table.createColumn("Column B");
|
||||||
table.createColumn("Column C", 2); // add between B and D
|
XSSFTableColumn cD = table.createColumn("Column D");
|
||||||
|
XSSFTableColumn cC = table.createColumn("Column C", 2); // add between B and D
|
||||||
table.updateReferences();
|
table.updateReferences();
|
||||||
table.updateHeaders();
|
table.updateHeaders();
|
||||||
|
|
||||||
assertEquals(4, table.getColumnCount());
|
assertEquals(4, table.getColumnCount());
|
||||||
assertEquals(2, table.getRowCount());
|
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 1", table.getColumns().get(0).getName()); // generated name
|
||||||
assertEquals("Column B", table.getColumns().get(1).getName());
|
assertEquals("Column B", table.getColumns().get(1).getName());
|
||||||
assertEquals("Column C", table.getColumns().get(2).getName());
|
assertEquals("Column C", table.getColumns().get(2).getName());
|
||||||
|
|
|
@ -39,8 +39,8 @@ import java.util.List;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.POIDataSamples;
|
||||||
import org.apache.poi.ooxml.POIXMLProperties;
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
|
import org.apache.poi.ooxml.POIXMLProperties;
|
||||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
import org.apache.poi.openxml4j.opc.ContentTypes;
|
import org.apache.poi.openxml4j.opc.ContentTypes;
|
||||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
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.IOUtils;
|
||||||
import org.apache.poi.util.LocaleUtil;
|
import org.apache.poi.util.LocaleUtil;
|
||||||
import org.apache.poi.util.TempFile;
|
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.XSSFITestDataProvider;
|
||||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||||
import org.apache.poi.xssf.model.StylesTable;
|
import org.apache.poi.xssf.model.StylesTable;
|
||||||
|
@ -553,7 +555,9 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
|
||||||
Sheet sheet = wb.getSheetAt(0);
|
Sheet sheet = wb.getSheetAt(0);
|
||||||
sheet.shiftRows(2, sheet.getLastRowNum(), 1, true, false);
|
sheet.shiftRows(2, sheet.getLastRowNum(), 1, true, false);
|
||||||
Row newRow = sheet.getRow(2);
|
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");
|
newRow.createCell(0).setCellValue(" Another Header");
|
||||||
wb.cloneSheet(0);
|
wb.cloneSheet(0);
|
||||||
|
|
||||||
|
@ -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 final int INDEX_NOT_FOUND = -1;
|
||||||
|
|
||||||
private static boolean isEmpty(CharSequence cs) {
|
private static boolean isEmpty(CharSequence cs) {
|
||||||
|
|
|
@ -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
|
@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()
|
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
|
@defaultMessage Unnecessary, inefficient, and confusing conversion of String.toString
|
||||||
java.lang.String#toString()
|
java.lang.String#toString()
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ public class TextSpecInfoRun {
|
||||||
smartTagFld, smartTagsBytes, "smart tags"
|
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];
|
BitField fld = (BitField)flds[i+0];
|
||||||
Object valO = flds[i+1];
|
Object valO = flds[i+1];
|
||||||
if (!fld.isSet(mask)) continue;
|
if (!fld.isSet(mask)) continue;
|
||||||
|
@ -210,7 +210,8 @@ public class TextSpecInfoRun {
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (!valid) {
|
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);
|
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
|
* Check where values are the same
|
||||||
*/
|
*/
|
||||||
|
@ -75,6 +69,17 @@ public class TestRandBetween extends TestCase {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
* Check special case where rounded up bottom value is greater than
|
||||||
* top value.
|
* top value.
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue