Compare commits

..

1 Commits

2096 changed files with 18967 additions and 86085 deletions

View File

@ -1,7 +1,7 @@
# https://github.com/apache/infrastructure-asfyaml/blob/main/README.md # https://cwiki.apache.org/confluence/display/INFRA/Git+-+.asf.yaml+features
github: github:
description: "Mirror of Apache POI gitbox. The Java API for Microsoft Documents." description: "Mirror of Apache POI subversion. The Java API for Microsoft Documents."
homepage: https://poi.apache.org/ homepage: https://poi.apache.org/
labels: labels:
- poi - poi
@ -14,35 +14,10 @@ github:
- powerpoint - powerpoint
- visio - visio
dependabot_alerts: true
dependabot_updates: false
features: features:
# Enable wiki for documentation # Enable wiki for documentation
wiki: false wiki: false
# Enable issue management # Enable issue management
issues: true issues: false
# Enable projects for project management boards # Enable projects for project management boards
projects: false projects: false
# Enable github discussions
discussions: true
enabled_merge_buttons:
squash: true
merge: false
rebase: true
protected_branches:
trunk: {}
5.5.x: {}
asf-site: {}
notifications:
commits: commits@poi.apache.org
issues: dev@poi.apache.org
pullrequests: dev@poi.apache.org
discussions: dev@poi.apache.org
jobs: dev@poi.apache.org
publish:
whoami: asf-site

View File

@ -9,7 +9,3 @@ updates:
directory: "/" # Location of package manifests directory: "/" # Location of package manifests
schedule: schedule:
interval: "daily" interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

View File

@ -5,11 +5,9 @@ name: Java CI with Gradle
on: on:
push: push:
branches: [ trunk, 5.5.x ] branches: [ trunk ]
pull_request: pull_request:
branches: [ trunk, 5.5.x ] branches: [ trunk ]
permissions: {}
jobs: jobs:
build: build:
@ -17,17 +15,30 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v2
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v5 uses: actions/setup-java@v2
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '11' java-version: '11'
cache: 'gradle' check-latest: true
- name: Cache Gradle wrapper and dependencies
uses: actions/cache@v2.1.3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Verify Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew check -PjdkVersion=11 --no-daemon --refresh-dependencies run: ./gradlew check -PjdkVersion=11

3
.gitignore vendored
View File

@ -37,6 +37,3 @@ TEST-org.apache.poi*.xml
/*/build/ /*/build/
dist dist
lib/ lib/
# Compiled module-info class-files
/poi*/src/*/java9/*.class

79
KEYS
View File

@ -2545,12 +2545,11 @@ bpjAhwE2YmGQ7oB+3V798HtAmceRNf8AY0GWrZswJlg7xUn+WJNwQ9uIHI1fxYHx
2Nr+AmDDs6ZOEI5zhwxioePw/Cg= 2Nr+AmDDs6ZOEI5zhwxioePw/Cg=
=9lKb =9lKb
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub rsa2048 2018-05-02 [SC] [expires: 2026-05-11] pub rsa2048 2018-05-02 [SC] [expires: 2022-05-17]
6BA4DA8B1C88A49428A29C3D0C69C1EF41181E13 6BA4DA8B1C88A49428A29C3D0C69C1EF41181E13
uid [ unknown] PJ Fanning (http://www.apache.org/) <fanningpj@apache.org> uid [ultimate] PJ Fanning (http://www.apache.org/) <fanningpj@apache.org>
uid [ unknown] PJ Fanning (GitHub noreply address) <pjfanning@users.noreply.github.com> uid [ultimate] PJ Fanning <fanningpj@yahoo.com>
uid [ unknown] PJ Fanning <fanningpj@yahoo.com> sub rsa2048 2018-05-02 [E] [expires: 2022-05-17]
sub rsa2048 2018-05-02 [E] [expires: 2026-05-11]
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
@ -2559,45 +2558,37 @@ ARFmtFPnwYwLTdz3ECqWWsC3RkI62079DweNasXV8nBz9sUt6mQqSMx3W/s6389/
k9iywPLvhHH7rpp05js8zwJoA8Fr1YwPtBjyhrxl58LQ5ihd/1f2ud2tnwQw1dI2 k9iywPLvhHH7rpp05js8zwJoA8Fr1YwPtBjyhrxl58LQ5ihd/1f2ud2tnwQw1dI2
8fuTS3QaKP4Zdx2diD5rYhkAecWaFRwxn1L7Tye5dfD1uPElPCHGKqfaeQXtl01u 8fuTS3QaKP4Zdx2diD5rYhkAecWaFRwxn1L7Tye5dfD1uPElPCHGKqfaeQXtl01u
TOwYB1p9tKPHvfni1qgD3QLWUJ2oyBGSA9IgEF5rm8LtR6vADKQwORjg99a7HE2h TOwYB1p9tKPHvfni1qgD3QLWUJ2oyBGSA9IgEF5rm8LtR6vADKQwORjg99a7HE2h
lDBZi/tmu23fgWSioiy084fB5GqmApK/681DABEBAAG0SFBKIEZhbm5pbmcgKEdp lDBZi/tmu23fgWSioiy084fB5GqmApK/681DABEBAAG0OlBKIEZhbm5pbmcgKGh0
dEh1YiBub3JlcGx5IGFkZHJlc3MpIDxwamZhbm5pbmdAdXNlcnMubm9yZXBseS5n dHA6Ly93d3cuYXBhY2hlLm9yZy8pIDxmYW5uaW5ncGpAYXBhY2hlLm9yZz6JAVQE
aXRodWIuY29tPokBVwQTAQgAQQIbAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIX EwEIAD4CGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQRrpNqLHIiklCiinD0M
gBYhBGuk2osciKSUKKKcPQxpwe9BGB4TBQJmJYbdBQkPGNgHAAoJEAxpwe9BGB4T acHvQRgeEwUCXsE82gUJB5owBAAKCRAMacHvQRgeE6ZAB/40Lysb8A5J1PtwJhdJ
5Z4H/3sDqi2QozHbsUy2dm+xS105bpmiNn3aDYzEyjOBggypDWpG5fmlD6ya3Yfd m236LINbMmPhqTkTa45ozjOAXBKKGiUyoCmUjcc22hbcB6f3RmE59MP9YBfIbuP9
H172auahZ1SK6t7Q7u97QdtrvMKTVBBq+DahkHnvw4nsPwBI00aTy616of1+CirZ F9pujP5QdFzGf8sdZ5qwvLEePng0CDwy18+aQtCV2GWYKuO5gL2AubRo2pRCZirL
lDPo912aLrWlouizuy6qeJE0EfB0PGXtuZP3E0yZHqgmIOBrQw5fJQtrka5WWK3C zftnZm3pctRESXhbDae1PjMjWCsvMaTrqZLzkYMsypsrzLiXPpVgXgMW37IHFsIP
AqO2Z1hZLh9ftheJtKSYX1gZnPEAWs3ZBG2tCk4+qAjB8y5kRvrJFpC36FkisYlg cLPWvKgipaUeXHFT/3lcZl9MlUO/X/URrGjHL1EJVgLPhmGZcq7+VU5RqBWdhduQ
YTtAOSMHED/3YFsDsXFvLmrSkNBImjdAnRW59TD5XUgEMDZ9Dylz3/b4/gtNi2SX HUwYPOpKFhDjbj1du8effvdurJTZamJH/gS1N6r+V073J6dIQOHw9Mu81RNHBlwi
9WSYWC60/3Jgxh4u3cTUnUtW2yC0IFBKIEZhbm5pbmcgPGZhbm5pbmdwakB5YWhv 1QUntCBQSiBGYW5uaW5nIDxmYW5uaW5ncGpAeWFob28uY29tPokBVAQTAQgAPgIb
by5jb20+iQFUBBMBCAA+AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAFiEEa6Ta AwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBGuk2osciKSUKKKcPQxpwe9BGB4T
ixyIpJQoopw9DGnB70EYHhMFAmYlhuUFCQ8Y2AcACgkQDGnB70EYHhOecwgApleV BQJewTzaBQkHmjAEAAoJEAxpwe9BGB4TW1gH+gOewMCrUGRSh9r3oS8wnL/cHXxF
9IOazPAk8pF0WfkslRWNrGHzaGoqO+WVhMS4doxR8bjqkrHwuI4c8Z2vCCMnKqb1 9+S0dXmLP4T4zGJtz7Q6h0RPIorY7jwAFzzU0zohFIB7/9ECo9dKFmuGlYlNLNax
LF7djz9GXFGklvoyV7rQYrDx15bYWjtassvM4KExcnoPGxx9Kb7f0j0WSZwtwMUl d4if7QFxdC/yCuZOrvUUhWus/f+7hM06E7qQ+64DhJy2BBk1Kfp2mLFGtP+yVhUM
XWvsrS0+BkbRz+PIpGtDJhlI++aRoZdWCz5j5st5HzmacC0GVuYGvRPj8uMW2LN5 9F2seTRuJWzzC4gyRpNg8P7W1Sic/Pc0xXpEkO4JPRa9dl4DeV66Gk5HVrb+4SYV
5HvGzlzqWIQ7l68KQPz7g5KIFKUrCPyzZS0m8Nj+gRWhF3+u3/1SY2hoCzobSMJj YXFmIMqTvK9ksZs+XwcBjHsv7eA9bv3MzHKYOnM5d+BQEJUPcD52F1Y6rb41Yvrk
PNhEovdpi8h5qbUOpHn2OM7l8/nioRaJwAmcMTnmlh1lqeyxIFYnFIBT24o3aEtN QQew6R3lJZio1TbZW6S86h3a1I6L+byQ1V8TjVZvaMqt5mMHRWmh/WwcOai5AQ0E
N2d1xg/moXvzNTq7yrQ6UEogRmFubmluZyAoaHR0cDovL3d3dy5hcGFjaGUub3Jn Wulz1gEIAORuS4e+Ek+d+0gBMlnigNJ2HoQalKFaERf5K/iQZY4E6Z2ahJ4UFIj7
LykgPGZhbm5pbmdwakBhcGFjaGUub3JnPokBVAQTAQgAPgIbAwULCQgHAgYVCgkI ri3isWgOleP+REJJPfeSrWQ5XgdklDlHHyv4O5iMkEFWQHttiaTuvdomDncQrNRP
CwIEFgIDAQIeAQIXgBYhBGuk2osciKSUKKKcPQxpwe9BGB4TBQJmJYblBQkPGNgH TaIOe9iQgfQzDw6mqsb7ZWd5ICA8Krd97BwNHjq/CZ9+WrU6GDc6ImissLVVGGdk
AAoJEAxpwe9BGB4TgwMIAJj3aQYKSxt9iyIP5nFhIWAFSPZcZ0gRB6jYMuANVoJE EGO7qZTqNUCeH4Znm/00mNMI4OH8xkwA2vzV5o3J5116zIuv29XQDtcSM+9NQ/Hd
yelbhIziN2dXLOjHWpia2x9p7krxY6ZLtogkL4MjfVpCaaXwsaYOq6LeuPN27/Pt sjKIA0OpDyWE7Ek/SO+/CvkylwaOcmkuf33ADNjpF4BsBxn7L9XI1WJDtRaMkpbq
9rRcDz7j5lA9u9MShc6O8lwNbVReCWR08H0oiEdS09xwZY3aiZniptRBeK+mcsNc MsymIxi35VUOGD+ms+72CcUStfYj4NEAEQEAAYkBPAQYAQgAJgIbDBYhBGuk2osc
Zw7kNmPHC79WaI6Rb/qnPLHJDD0l8vrVSShgmEeVJJoC/YjuVzKoiy2BmjSOpOLF iKSUKKKcPQxpwe9BGB4TBQJewT2iBQkHmjDMAAoJEAxpwe9BGB4TNXoIAJunpJ8r
d88NlquWbvLO6j2tzboUs+93Kc4MwG57hwRIqS7wfsENkecSRj23KQN0UOpxgwz7 DC5v3GMRCVu21DEIwAcAzBQhB7lK7VfDqkeB/ivCkoTpqs+ZFK2LT5uJQgRmPhF7
b0+ii9F9jsddEqqpXspcM8zaacf+FpIwO6rk7v1U8LG5AQ0EWulz1gEIAORuS4e+ xgMDn2WXrsD76eOzPr0qMr9qCa66Ou4EBywvZdPDVFJI4J5e2BgZYf5cq9YvO3qv
Ek+d+0gBMlnigNJ2HoQalKFaERf5K/iQZY4E6Z2ahJ4UFIj7ri3isWgOleP+REJJ feL0IKFyljSCk+DPGW+A57KgGTGBMWuicSn3b6OEYewtzVWhbyFKYChZyV7fRv/i
PfeSrWQ5XgdklDlHHyv4O5iMkEFWQHttiaTuvdomDncQrNRPTaIOe9iQgfQzDw6m UKo4gBqFrn4nUqDocG2Pl0qTngNL+LllThFHq9Wq5+ngMUk+Qtw8Um8xOnyNO3er
qsb7ZWd5ICA8Krd97BwNHjq/CZ9+WrU6GDc6ImissLVVGGdkEGO7qZTqNUCeH4Zn a1pShs2sKKgQwtXpEIZ+l7B193A/35RPTH1kDQSu2GBSFebQfl9yimW22T/ncEeP
m/00mNMI4OH8xkwA2vzV5o3J5116zIuv29XQDtcSM+9NQ/HdsjKIA0OpDyWE7Ek/ dXK7AeuHr+AogJ8=
SO+/CvkylwaOcmkuf33ADNjpF4BsBxn7L9XI1WJDtRaMkpbqMsymIxi35VUOGD+m =aV2J
s+72CcUStfYj4NEAEQEAAYkBPAQYAQgAJgIbDBYhBGuk2osciKSUKKKcPQxpwe9B
GB4TBQJmJYcPBQkPGNg5AAoJEAxpwe9BGB4TTswH/3RmARIBV2LV72Sqk3rBcKLG
mY808npRuL6tQDVnrFPl9J8Q1/zItINYUc+2p8rHPW/N/5vyun4oVF9mT+Swqmuy
FkciQ8vCTdPlocGsGmb8eIKSvkzyRb3B8RkiXq2btDQBCVqVWbB6fh3FSI8L5442
r/IAQOKyd5wDGP2vDt1wGQ+0aV60gO2lWXOMi6U7dvt/+9vFaMciNdeZt7llNFIF
OzQuaMAqRP8viuuA29GAsy59x92LWEhm6RRSyU6rMGqfhbHQEs6FZ0x6zuBq8Ru7
T9wf/cc6uGGG6BqnjxFbWL/g9XJeU8gDxQ+ElJbYDXHT255g8kb92mHbJziPbxM=
=WUaV
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub 2048R/1556F3A4 2016-10-04 pub 2048R/1556F3A4 2016-10-04
uid Greg Woolsey <gwoolsey@apache.org> uid Greg Woolsey <gwoolsey@apache.org>

View File

@ -1,4 +1,6 @@
# Apache POI™
Apache POI
======================
A Java library for reading and writing Microsoft Office binary and OOXML file formats. A Java library for reading and writing Microsoft Office binary and OOXML file formats.
@ -33,45 +35,36 @@ And lower-level, supporting components:
| Components named H??F are for reading or writing OLE2 binary formats. | Components named H??F are for reading or writing OLE2 binary formats.
| Components named X??F are for reading or writing OpenOffice XML (OOXML) formats. | Components named X??F are for reading or writing OpenOffice XML (OOXML) formats.
# Getting started Getting started
------------------
Website: https://poi.apache.org/ Website: https://poi.apache.org/
[Mailing lists](https://poi.apache.org/mailinglists.html): `Mailing lists`_:
* [Developers](https://lists.apache.org/list.html?dev@poi.apache.org) * `Developers`_
* [Users](https://lists.apache.org/list.html?user@poi.apache.org) Including Announcements * `Users`_
* [General](https://lists.apache.org/list.html?general@poi.apache.org) * `General`_ (release announcements)
## Bug trackers Bug tracker:
* [Bugzilla](https://bz.apache.org/bugzilla/buglist.cgi?product=POI) * `Bugzilla`_
* [GitHub](https://github.com/apache/poi/issues) * `GitHub pull requests`_
## Source code Source code:
* https://github.com/apache/poi * Official `Apache Subversion repo`_ at apache.org
* `ViewVC repo browser`_ at apache.org
* `GitHub git mirror`_ at github.com
Requires Java 11 or later. `trunk` branch is used for 6.0.0 development. POI 4 and 5 releases require Java 8 or later. Requires Java 1.8 or later.
Contributing
------------------
## Jars * Download and install svn or git, Java JDK 1.8+, and Apache Ant 1.8+ or Gradle
A good resource for finding the published jars and forming build tool dependency definitions is https://mvnrepository.com/artifact/org.apache.poi. * Check out the code from svn or git
* poi - main jar, including shared interfaces
* poi-scratchpad - extra classes to support legacy MS file formats (`H**F`)
* poi-ooxml - support for newer OOXML file formats (`X**F`)
* poi-ooxml-lite - generated classes based on MS XSDs used by poi-ooxml (only includes the most commonly used classes)
* poi-ooxml-full - generated classes based on MS XSDs (can be used instead of poi-ooxml-lite if you need support for less commonly used features)
* poi-excelant - tools for working with Excel files in Apache Ant scripts
* poi-examples
# Contributing
* Download and install git, Java JDK 11+, and Apache Ant 1.8+ or Gradle
* Check out the code from git
* Import the project into Eclipse or your favorite IDE * Import the project into Eclipse or your favorite IDE
@ -89,12 +82,25 @@ A good resource for finding the published jars and forming build tool dependency
* Scratchpad (Binary formats): poi-scratchpad/src/main/java/org/apache/poi/ * Scratchpad (Binary formats): poi-scratchpad/src/main/java/org/apache/poi/
* Examples: poi-examples/src/main/java/org/apache/poi/ * Examples: poi-examples/src/main/java/org/apache/poi/
* More info: [How To Build page](https://poi.apache.org/devel/) * More info: `How To Build page`_ at apache.org
# Building jar files Building jar files
------------------
To build the jar files for poi, poi-ooxml, poi-ooxml-lite, poi-ooxml-full and poi-examples:: To build the jar files for poi, poi-ooxml, poi-ooxml-lite, poi-ooxml-full and poi-examples::
./gradlew jar ./gradlew jar
gradlew jar gradlew jar
.. _Mailing lists: https://poi.apache.org/mailinglists.html
.. _Developers: https://lists.apache.org/list.html?dev@poi.apache.org
.. _Users: https://lists.apache.org/list.html?user@poi.apache.org
.. _General: https://lists.apache.org/list.html?general@poi.apache.org
.. _Bugzilla: https://bz.apache.org/bugzilla/buglist.cgi?product=POI
.. _GitHub pull requests: https://github.com/apache/poi/pulls
.. _Apache Subversion repo: https://svn.apache.org/repos/asf/poi/trunk
.. _ViewVC repo browser: https://svn.apache.org/viewvc/poi/trunk
.. _GitHub git mirror: https://github.com/apache/poi
.. _How To Build page: http://poi.apache.org/devel/

View File

@ -1,9 +1,4 @@
# Security # Security
If you suspect you have found a security vulnerability in Apache POI code, please read https://www.apache.org/security/ If you suspect you have found a security vulnerability in Apache POI code, please read https://www.apache.org/security/
for how to report the issue. Please do not report the details publicly until the report is reviewed. for how to report the issue. Please do not report the details publicly until the report is reviewed.
## Secure Processing
We strongly discourage users of Apache POI from using the lib to parse documents from untrusted sources. For more details,
please read https://poi.apache.org/security.html.

View File

@ -24,33 +24,53 @@ import javax.xml.xpath.XPathFactory
buildscript { buildscript {
repositories { repositories {
maven { url = 'https://plugins.gradle.org/m2/' } maven { url 'https://plugins.gradle.org/m2/' }
mavenCentral() mavenCentral()
} }
dependencies {
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'
classpath 'de.thetaphi:forbiddenapis:3.2'
}
} }
plugins { plugins {
id 'base' id 'base'
id 'com.dorongold.task-tree' version '4.0.1' id "com.dorongold.task-tree" version "2.1.0"
id 'org.nosphere.apache.rat' version '0.8.1' id('org.nosphere.apache.rat') version '0.7.0'
id 'distribution' id 'distribution'
id "com.github.spotbugs" version "4.8.0"
// 6.2.0+ requires JDK 11 id 'com.github.jk1.dependency-license-report' version '2.0'
// this is the version of the Gradle plugin, it usually includes a
// different version of spotbugs itself
// Latest spotbugs: https://github.com/spotbugs/spotbugs
// Latest gradle plugin: https://plugins.gradle.org/plugin/com.github.spotbugs
id 'com.github.spotbugs' version '6.4.8'
id 'de.thetaphi.forbiddenapis' version '3.10'
id 'org.sonarqube' version '7.2.2.6593'
id 'org.cyclonedx.bom' version '2.4.1'
id 'com.adarshr.test-logger' version '4.0.0'
} }
repositories { repositories {
mavenCentral() mavenCentral()
// maven { url 'https://repository.apache.org/content/repositories/staging' } }
import com.github.jk1.license.render.*
import com.github.jk1.license.importer.*
licenseReport {
// Select projects to examine for dependencies.
// Defaults to current project and all its subprojects
projects = [project] + project.subprojects
// Adjust the configurations to fetch dependencies, e.g. for Android projects. Default is 'runtimeClasspath'
configurations = ['runtimeClasspath']
// Use 'ALL' to dynamically resolve all configurations:
// configurations = ALL
// Don't include artifacts of project's own group into the report
excludeOwnGroup = true
// Don't exclude bom dependencies.
// If set to true, then all boms will be excluded from the report
excludeBoms = false
// Set custom report renderer, implementing ReportRenderer.
// Yes, you can write your own to support any format necessary.
renderers = [new XmlReportRenderer('third-party-libs.xml', 'Back-End Libraries')]
} }
// Only add the plugin for Sonar if enabled // Only add the plugin for Sonar if enabled
@ -59,8 +79,7 @@ if (project.hasProperty('enableSonar')) {
apply plugin: 'org.sonarqube' apply plugin: 'org.sonarqube'
} }
boolean isCIBuild = false boolean isCIBuild = false;
String dateSuffix = new Date().format('yyyyMMdd')
// For help converting an Ant build to a Gradle build, see // For help converting an Ant build to a Gradle build, see
// https://docs.gradle.org/current/userguide/ant.html // https://docs.gradle.org/current/userguide/ant.html
@ -74,8 +93,8 @@ configurations {
} }
dependencies { dependencies {
antLibs("org.junit.jupiter:junit-jupiter:5.13.4") antLibs("org.junit.jupiter:junit-jupiter:5.8.2")
antLibs("org.apache.ant:ant-junitlauncher:1.10.15") antLibs("org.apache.ant:ant-junitlauncher:1.10.12")
} }
ant.taskdef(name: "junit", ant.taskdef(name: "junit",
@ -84,10 +103,19 @@ ant.taskdef(name: "junit",
wrapper { wrapper {
gradleVersion = '8.14.3' gradleVersion = '7.4'
} }
group = 'org.apache.poi' task adjustWrapperPropertiesFile {
doLast {
ant.replaceregexp(match:'^#.*', replace:'', flags:'g', byline:true) {
fileset(dir: project.projectDir, includes: 'gradle/wrapper/gradle-wrapper.properties')
}
new File(project.projectDir, 'gradle/wrapper/gradle-wrapper.properties').with { it.text = it.readLines().findAll { it }.sort().join('\n') }
ant.fixcrlf(file: 'gradle/wrapper/gradle-wrapper.properties', eol: 'lf')
}
}
wrapper.finalizedBy adjustWrapperPropertiesFile
/** /**
Define properties for all projects, including this one Define properties for all projects, including this one
@ -95,8 +123,6 @@ group = 'org.apache.poi'
allprojects { allprojects {
// apply plugin: 'eclipse' // apply plugin: 'eclipse'
apply plugin: 'idea' apply plugin: 'idea'
version = '6.0.0-SNAPSHOT'
} }
/** /**
@ -110,94 +136,82 @@ subprojects {
apply plugin: 'signing' apply plugin: 'signing'
apply plugin: 'de.thetaphi.forbiddenapis' apply plugin: 'de.thetaphi.forbiddenapis'
apply plugin: 'com.github.spotbugs' apply plugin: 'com.github.spotbugs'
apply plugin: 'org.cyclonedx.bom'
apply plugin: 'com.adarshr.test-logger'
version = '5.2.2'
ext { ext {
bouncyCastleVersion = '1.83' bouncyCastleVersion = '1.70'
commonsCodecVersion = '1.21.0' commonsCodecVersion = '1.15'
commonsCompressVersion = '1.28.0' commonsCompressVersion = '1.21'
commonsIoVersion = '2.21.0' commonsIoVersion = '2.11.0'
commonsMathVersion = '3.6.1' commonsMathVersion = '3.6.1'
junitVersion = '5.13.4' junitVersion = '5.8.2'
log4jVersion = '2.25.3' log4jVersion = '2.17.2'
mockitoVersion = '5.21.0' mockitoVersion = '4.4.0'
hamcrestVersion = '3.0' hamcrestVersion = '2.2'
xmlbeansVersion = '5.3.0' xmlbeansVersion = '5.0.3'
batikVersion = '1.19' batikVersion = '1.14'
graphics2dVersion = '3.0.5' graphics2dVersion = '0.35'
pdfboxVersion = '3.0.6' pdfboxVersion = '2.0.25'
saxonVersion = '12.9' saxonVersion = '11.2'
xmlSecVersion = '3.0.6'
apiGuardianVersion = '1.1.2' apiGuardianVersion = '1.1.2'
jdkVersion = (project.properties['jdkVersion'] ?: '11') as int jdkVersion = (project.properties['jdkVersion'] ?: '8') as int
// see https://github.com/gradle/gradle/blob/master/subprojects/jvm-services/src/main/java/org/gradle/internal/jvm/inspection/JvmVendor.java // see https://github.com/gradle/gradle/blob/master/subprojects/jvm-services/src/main/java/org/gradle/internal/jvm/inspection/JvmVendor.java
jdkVendor = (project.properties['jdkVendor'] ?: '') as String jdkVendor = (project.properties['jdkVendor'] ?: '') as String
JAVA9_SRC = 'src/main/java9' JAVA9_SRC = 'src/main/java9'
JAVA9_OUT = layout.buildDirectory.dir('classes/java9/main/').get().asFile.absolutePath JAVA9_OUT = "${buildDir}/classes/java9/main/"
TEST9_SRC = 'src/test/java9' TEST9_SRC = 'src/test/java9'
TEST9_OUT = layout.buildDirectory.dir('classes/java9/test/').get().asFile.absolutePath TEST9_OUT = "${buildDir}/classes/java9/test/"
VERSIONS9 = '/META-INF/versions/9' VERSIONS9 = 'META-INF/versions/9'
NO_SCRATCHPAD = (findProperty("scratchpad.ignore") == "true") NO_SCRATCHPAD = (findProperty("scratchpad.ignore") == "true")
SAXON_TEST = (findProperty("saxon.test") == "true") SAXON_TEST = (findProperty("saxon.test") == "true")
} }
configurations { configurations {
configureEach { all {
resolutionStrategy { resolutionStrategy {
force "commons-io:commons-io:${commonsIoVersion}" force "commons-io:commons-io:${commonsIoVersion}"
force 'org.slf4j:slf4j-api:2.0.17' force 'org.slf4j:slf4j-api:1.7.36'
force 'com.fasterxml.woodstox:woodstox-core:7.1.1' force 'com.fasterxml.woodstox:woodstox-core:6.2.8'
} }
} }
} }
tasks.withType(JavaCompile).configureEach { tasks.withType(JavaCompile) {
options.encoding = 'UTF-8' options.encoding = 'UTF-8'
options.compilerArgs += '-Xlint:unchecked' options.compilerArgs << '-Xlint:unchecked'
options.deprecation = true options.deprecation = true
options.incremental = true options.incremental = true
}
tasks.withType(Test).configureEach { onlyIf {
systemProperty "file.encoding", "UTF-8" (name != "compileJava9" && name != "compileTest9") // || jdkVersion > 8
} }
tasks.withType(Javadoc).configureEach {
options.encoding = 'UTF-8'
}
tasks.withType(AbstractArchiveTask).configureEach {
preserveFileTimestamps = false
reproducibleFileOrder = true
} }
repositories { repositories {
mavenCentral() mavenCentral()
// maven { url 'https://repository.apache.org/content/repositories/staging' } maven {
url 'https://repository.apache.org/content/repositories/releases'
}
} }
dependencies { dependencies {
api platform("org.apache.logging.log4j:log4j-bom:${log4jVersion}") testImplementation "org.junit.jupiter:junit-jupiter:${junitVersion}"
api 'org.apache.logging.log4j:log4j-api'
testImplementation platform("org.junit:junit-bom:${junitVersion}")
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation "org.mockito:mockito-core:${mockitoVersion}" testImplementation "org.mockito:mockito-core:${mockitoVersion}"
testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}" testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}"
testImplementation 'org.apache.logging.log4j:log4j-core' testImplementation "org.apache.logging.log4j:log4j-core:${log4jVersion}"
}
if (SAXON_TEST) { task wrapper(type: Wrapper){
testRuntimeOnly("net.sf.saxon:Saxon-HE:${saxonVersion}") { gradleVersion = '7.4'
exclude group: 'xml-apis', module: 'xml-apis'
}
}
} }
java { java {
toolchain { toolchain {
languageVersion = JavaLanguageVersion.of(jdkVersion) languageVersion.set(JavaLanguageVersion.of(jdkVersion))
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor) if (jdkVendor != '') vendor.set(JvmVendorSpec.matching(jdkVendor))
} }
withJavadocJar() withJavadocJar()
withSourcesJar() withSourcesJar()
@ -207,7 +221,7 @@ subprojects {
failOnError = true failOnError = true
maxMemory = "1024M" maxMemory = "1024M"
javadocTool = javaToolchains.javadocToolFor { javadocTool = javaToolchains.javadocToolFor {
languageVersion = JavaLanguageVersion.of(jdkVersion) languageVersion = JavaLanguageVersion.of(Math.max(11,jdkVersion))
} }
doFirst { doFirst {
@ -215,90 +229,22 @@ subprojects {
addBooleanOption('html5', true) addBooleanOption('html5', true)
addBooleanOption('Xdoclint:all,-missing', true) addBooleanOption('Xdoclint:all,-missing', true)
links 'https://poi.apache.org/apidocs/dev/' links 'https://poi.apache.org/apidocs/dev/'
if (jdkVersion >= 23) links 'https://docs.oracle.com/en/java/javase/23/docs/api/' else links 'https://docs.oracle.com/en/java/javase/11/docs/api/' links 'https://docs.oracle.com/javase/8/docs/api/'
links 'https://xmlbeans.apache.org/docs/5.0.0/' links 'https://xmlbeans.apache.org/docs/5.0.0/'
links 'https://www.javadocs.dev/org.apache.commons/commons-compress/1.28.0/'
use = true use = true
splitIndex = true splitIndex = true
source = "11" source = "1.8"
} }
} }
} }
// helper-target to get a directory with all third-party libraries tasks.withType(Jar) {
// this is used for mass-regression-testing duplicatesStrategy = 'fail'
tasks.register('getDeps', Copy) { destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
from sourceSets.main.runtimeClasspath
into 'build/runtime/'
}
tasks.withType(Jar).configureEach {
duplicatesStrategy = DuplicatesStrategy.FAIL
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}")
doLast { doLast {
// make sure we do not have distribution jar-files with different versions ant.checksum(file: it.archivePath, algorithm: 'SHA-256', fileext: '.sha256', format: 'MD5SUM')
// in the build-dir as those lead to strange errors about "duplicate modules" ant.checksum(file: it.archivePath, algorithm: 'SHA-512', fileext: '.sha512', format: 'MD5SUM')
// when building java9 JPMS class files ("java9")
ant.delete(failOnError: true, verbose: true) {
fileset(dir: "../build/dist/maven/${base.archivesName.get()}", erroronmissingdir: false) {
include(name: '*.jar')
exclude(name: "*${version}.jar")
exclude(name: "*${version}-sources.jar")
include(name: '*.jar.asc')
exclude(name: "*${version}.jar.asc")
exclude(name: "*${version}-sources.jar.asc")
include(name: '*.jar.sha256')
exclude(name: "*${version}.jar.sha256")
exclude(name: "*${version}-sources.jar.sha256")
include(name: '*.jar.sha512')
exclude(name: "*${version}.jar.sha512")
exclude(name: "*${version}-sources.jar.sha512")
include(name: '*.pom')
exclude(name: "*${version}.pom")
include(name: '*.pom.asc')
exclude(name: "*${version}.pom.asc")
}
}
// use failOnError=false for -javadoc and -tests as not all modules create this directory
ant.delete(failOnError: false, verbose: true) {
fileset(dir: "../build/dist/maven/${base.archivesName.get()}-javadoc", erroronmissingdir: false) {
include(name: '*-javadoc.jar')
exclude(name: "*${version}-javadoc.jar")
include(name: '*-javadoc.jar.asc')
exclude(name: "*${version}-javadoc.jar.asc")
include(name: '*-javadoc.jar.sha256')
exclude(name: "*${version}-javadoc.jar.sha256")
include(name: '*-javadoc.jar.sha512')
exclude(name: "*${version}-javadoc.jar.sha512")
}
}
ant.delete(failOnError: false, verbose: true) {
fileset(dir: "../build/dist/maven/${base.archivesName.get()}-tests", erroronmissingdir: false) {
include(name: '*-tests.jar')
exclude(name: "*${version}-tests.jar")
include(name: '*-tests.jar.asc')
exclude(name: "*${version}-tests.jar.asc")
include(name: '*-tests.jar.sha256')
exclude(name: "*${version}-tests.jar.sha256")
include(name: '*-tests.jar.sha512')
exclude(name: "*${version}-tests.jar.sha512")
}
}
ant.checksum(file: it.archiveFile.get().asFile, algorithm: 'SHA-256', fileext: '.sha256', format: 'MD5SUM')
ant.checksum(file: it.archiveFile.get().asFile, algorithm: 'SHA-512', fileext: '.sha512', format: 'MD5SUM')
} }
} }
@ -326,19 +272,15 @@ subprojects {
javadocJar { javadocJar {
// if javadocs and binaries are in the same directory, JPMS complaints about duplicated modules // if javadocs and binaries are in the same directory, JPMS complaints about duplicated modules
// in the module-path // in the module-path
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}-javadoc") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}-javadoc")
} }
sourcesJar { sourcesJar {
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
exclude 'META-INF/services/**' exclude 'META-INF/services/**'
} }
test { test {
// use US locale for tests
systemProperty "user.language", "en"
systemProperty "user.country", "US"
// make XML test-results available for Jenkins CI // make XML test-results available for Jenkins CI
useJUnitPlatform() useJUnitPlatform()
reports { reports {
@ -346,8 +288,8 @@ subprojects {
} }
javaLauncher = javaToolchains.launcherFor { javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(jdkVersion) languageVersion.set(JavaLanguageVersion.of(jdkVersion))
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor) if (jdkVendor != '') vendor.set(JvmVendorSpec.matching(jdkVendor))
} }
// Exclude some tests that are not actually tests or do not run cleanly on purpose // Exclude some tests that are not actually tests or do not run cleanly on purpose
@ -362,11 +304,11 @@ subprojects {
// set heap size for the test JVM(s) // set heap size for the test JVM(s)
minHeapSize = "128m" minHeapSize = "128m"
maxHeapSize = "2g" maxHeapSize = "1G"
// Specifying the local via system properties did not work, so we set them this way // Specifying the local via system properties did not work, so we set them this way
jvmArgs += [ jvmArgs << [
'-Djava.awt.headless=true', '-Djava.awt.headless=true',
'-Djavax.xml.stream.XMLInputFactory=com.sun.xml.internal.stream.XMLInputFactoryImpl', '-Djavax.xml.stream.XMLInputFactory=com.sun.xml.internal.stream.XMLInputFactoryImpl',
"-Dversion.id=${project.version}", "-Dversion.id=${project.version}",
@ -375,18 +317,18 @@ subprojects {
] ]
// detect if running on Jenkins/CI // detect if running on Jenkins/CI
isCIBuild |= Boolean.valueOf(System.getenv("CI_BUILD")) isCIBuild |= Boolean.valueOf(System.getenv("CI_BUILD"));
if (isCIBuild) { if (isCIBuild) {
System.out.println("Run with reduced parallelism for CI build") System.out.println("Run with reduced parallelism for CI build");
jvmArgs += [ jvmArgs += [
// Strictly serial // Strictly serial
'-Djunit.jupiter.execution.parallel.enabled=false', // '-Djunit.jupiter.execution.parallel.enabled=false',
// OR parallel on 2 threads // OR parallel on 2 threads
//'-Djunit.jupiter.execution.parallel.config.strategy=fixed', '-Djunit.jupiter.execution.parallel.config.strategy=fixed',
//'-Djunit.jupiter.execution.parallel.config.fixed.parallelism=2' '-Djunit.jupiter.execution.parallel.config.fixed.parallelism=2'
] ]
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
} else { } else {
@ -421,25 +363,27 @@ subprojects {
systemProperties['java.locale.providers'] = 'JRE,CLDR' systemProperties['java.locale.providers'] = 'JRE,CLDR'
doFirst { doFirst {
// some options were removed in JDK 18 if (jdkVersion > 8) {
if (jdkVersion < 18) { // some options were removed in JDK 18
if (jdkVersion < 18) {
jvmArgs += [
'--illegal-access=warn',
]
}
jvmArgs += [ jvmArgs += [
'--illegal-access=warn', // see https://github.com/java9-modularity/gradle-modules-plugin/issues/97
// opposed to the recommendation there, it doesn't work to add ... to the dependencies
// testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.7.1'
// gradles gradle-worker.jar is still not a JPMS module and thus runs as unnamed module
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=org.apache.poi.poi',
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=ALL-UNNAMED',
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.logging=ALL-UNNAMED',
'-Dsun.reflect.debugModuleAccessChecks=true',
'-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true',
] ]
} }
jvmArgs += [
// see https://github.com/java9-modularity/gradle-modules-plugin/issues/97
// opposed to the recommendation there, it doesn't work to add ... to the dependencies
// testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.13.2'
// gradles gradle-worker.jar is still not a JPMS module and thus runs as unnamed module
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=org.apache.poi.poi',
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=ALL-UNNAMED',
'--add-exports','org.junit.platform.commons/org.junit.platform.commons.logging=ALL-UNNAMED',
'-Dsun.reflect.debugModuleAccessChecks=true',
'-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true',
]
} }
jacoco { jacoco {
@ -452,7 +396,7 @@ subprojects {
} }
jacoco { jacoco {
toolVersion = '0.8.13' toolVersion = '0.8.7'
} }
jacocoTestReport { jacocoTestReport {
@ -469,9 +413,9 @@ subprojects {
// https://docs.sonarqube.org/display/SONARQUBE52/Analyzing+with+SonarQube+Scanner+for+Gradle // https://docs.sonarqube.org/display/SONARQUBE52/Analyzing+with+SonarQube+Scanner+for+Gradle
// for documentation of properties. // for documentation of properties.
// //
// Some additional properties are currently set in the Jenkins-DSL, see jenkins/create_jobs.groovy // Some additional properties are currently set in the Jenkins-DSL, see jenksin/create_jobs.groovy
// //
sonar { sonarqube {
properties { properties {
// as we currently use build/<module>/ as project-basedir, we need to tell Sonar to use // as we currently use build/<module>/ as project-basedir, we need to tell Sonar to use
// the root-folder as "basedir" for the projects // the root-folder as "basedir" for the projects
@ -495,23 +439,26 @@ subprojects {
signaturesFiles = files('../src/resources/devtools/forbidden-signatures.txt') signaturesFiles = files('../src/resources/devtools/forbidden-signatures.txt')
ignoreFailures = false ignoreFailures = false
suppressAnnotations = [ 'org.apache.poi.util.SuppressForbidden' ] suppressAnnotations = [ 'org.apache.poi.util.SuppressForbidden' ]
} // forbiddenapis bundled signatures max supported version is 14
// targetCompatibility = (JavaVersion.VERSION_14.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_14)
forbiddenApisTest {
// forbiddenapis:3.8 bundled signatures max supported version is 23
targetCompatibility = (JavaVersion.VERSION_23.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_23)
} }
forbiddenApisMain { forbiddenApisMain {
signaturesFiles += files('../src/resources/devtools/forbidden-signatures-prod.txt') signaturesFiles += files('../src/resources/devtools/forbidden-signatures-prod.txt')
targetCompatibility = (JavaVersion.VERSION_23.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_23)
} }
task jenkins
jenkins.dependsOn build
jenkins.dependsOn check
jenkins.dependsOn javadoc
jenkins.dependsOn jacocoTestReport
jenkins.dependsOn rat
publishing { publishing {
publications { publications {
POI(MavenPublication) { POI(MavenPublication) {
groupId = 'org.apache.poi' groupId 'org.apache.poi'
artifactId = base.archivesName.get() artifactId project.archivesBaseName
from components.java from components.java
@ -526,13 +473,13 @@ subprojects {
name = 'POI Users List' name = 'POI Users List'
subscribe = 'user-subscribe@poi.apache.org' subscribe = 'user-subscribe@poi.apache.org'
unsubscribe = 'user-unsubscribe@poi.apache.org' unsubscribe = 'user-unsubscribe@poi.apache.org'
archive = 'https://lists.apache.org/list.html?user@poi.apache.org' archive = 'http://mail-archives.apache.org/mod_mbox/poi-user/'
} }
mailingList { mailingList {
name = 'POI Developer List' name = 'POI Developer List'
subscribe = 'dev-subscribe@poi.apache.org' subscribe = 'dev-subscribe@poi.apache.org'
unsubscribe = 'dev-unsubscribe@poi.apache.org' unsubscribe = 'dev-unsubscribe@poi.apache.org'
archive = 'https://lists.apache.org/list.html?dev@poi.apache.org' archive = 'http://mail-archives.apache.org/mod_mbox/poi-dev/'
} }
} }
@ -549,20 +496,6 @@ subprojects {
url = 'http://www.apache.org/' url = 'http://www.apache.org/'
} }
issueManagement {
system = 'bugzilla'
url = 'https://bz.apache.org/bugzilla'
}
developers {
developer {
name = 'POI Team'
id = 'poi'
email = 'user@poi.apache.org'
organization = 'Apache POI'
}
}
withXml { withXml {
def r = asElement() def r = asElement()
def doc = r.getOwnerDocument() def doc = r.getOwnerDocument()
@ -592,9 +525,9 @@ subprojects {
} }
} }
generatePomFileForPOIPublication.destination = "../build/dist/maven/${base.archivesName.get()}/${base.archivesName.get()}-${project.version}.pom" generatePomFileForPOIPublication.destination = "../build/dist/maven/${project.archivesBaseName}/${project.archivesBaseName}-${project.version}.pom"
tasks.withType(GenerateModuleMetadata).configureEach { tasks.withType(GenerateModuleMetadata) {
enabled = false enabled = false
} }
@ -611,7 +544,6 @@ subprojects {
spotbugs { spotbugs {
ignoreFailures = true ignoreFailures = true
showStackTraces = false showStackTraces = false
maxHeapSize = '2g'
} }
build { build {
@ -622,14 +554,14 @@ subprojects {
} }
// initial try to provide a combined JavaDoc, grouping is still missing here, though! // initial try to provide a combined JavaDoc, grouping is still missing here, though!
tasks.register('allJavaDoc', Javadoc) { task allJavaDoc(type: Javadoc) {
var prj = [project(':poi'), project(':poi-excelant'), project(':poi-ooxml'), project(':poi-scratchpad')] var prj = [ project(':poi'), project(':poi-excelant'), project(':poi-ooxml'), project(':poi-scratchpad') ]
source prj.collect { it.sourceSets.main.allJava } source prj.collect { it.sourceSets.main.allJava }
// for possible settings see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.javadoc.Javadoc.html // for possible settings see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.javadoc.Javadoc.html
classpath = files(subprojects.collect { it.sourceSets.main.compileClasspath }) classpath = files(subprojects.collect { it.sourceSets.main.compileClasspath })
destinationDir = layout.buildDirectory.dir('docs/javadoc').get().asFile destinationDir = file("${buildDir}/docs/javadoc")
maxMemory = "2048M" maxMemory="2048M"
// for possible options see https://docs.gradle.org/current/javadoc/org/gradle/external/javadoc/StandardJavadocDocletOptions.html // for possible options see https://docs.gradle.org/current/javadoc/org/gradle/external/javadoc/StandardJavadocDocletOptions.html
options.use = true options.use = true
@ -644,7 +576,7 @@ tasks.register('allJavaDoc', Javadoc) {
options.group('SS - Common Spreadsheet Format', 'org.apache.poi.ss*') options.group('SS - Common Spreadsheet Format', 'org.apache.poi.ss*')
options.group('HSSF - Horrible Spreadsheet Format', 'org.apache.poi.hssf*') options.group('HSSF - Horrible Spreadsheet Format', 'org.apache.poi.hssf*')
options.group('XSSF - Open Office XML Spreadsheet Format', 'org.apache.poi.xssf*') options.group('XSSF - Open Office XML Spreadsheet Format', 'org.apache.poi.xssf*')
options.group('SL - Common Slideshow Format', 'org.apache.poi.sl*') options.group('SL - Common Slideshow Format', 'org.apache.poi.sl*')
options.group('HSLF - Horrible Slideshow Format', 'org.apache.poi.hslf*', 'org.apache.poi.hwmf*', 'org.apache.poi.hemf*') options.group('HSLF - Horrible Slideshow Format', 'org.apache.poi.hslf*', 'org.apache.poi.hwmf*', 'org.apache.poi.hemf*')
options.group('XSLF - Open Office XML Slideshow Format', 'org.apache.poi.xslf*') options.group('XSLF - Open Office XML Slideshow Format', 'org.apache.poi.xslf*')
options.group('HWPF - Horrible Word Processor Format', 'org.apache.poi.hwpf*') options.group('HWPF - Horrible Word Processor Format', 'org.apache.poi.hwpf*')
@ -660,6 +592,9 @@ tasks.register('allJavaDoc', Javadoc) {
// options.group('Examples', 'org.apache.poi.examples*') // options.group('Examples', 'org.apache.poi.examples*')
} }
task jenkins(dependsOn: ['replaceVersion', subprojects.build, 'binDistZip','binDistTar','srcDistZip','srcDistTar']) {}
clean { clean {
delete "${rootDir}/build/dist" delete "${rootDir}/build/dist"
} }
@ -700,14 +635,12 @@ rat {
"poi/src/main/resources/org/apache/poi/sl/draw/geom/presetShapeDefinitions.xml", "poi/src/main/resources/org/apache/poi/sl/draw/geom/presetShapeDefinitions.xml",
"poi-ooxml/src/main/resources/org/apache/poi/xslf/usermodel/notesMaster.xml", "poi-ooxml/src/main/resources/org/apache/poi/xslf/usermodel/notesMaster.xml",
"poi-ooxml/src/main/resources/org/apache/poi/xssf/usermodel/presetTableStyles.xml", "poi-ooxml/src/main/resources/org/apache/poi/xssf/usermodel/presetTableStyles.xml",
"poi-ooxml-full/src/main/xmlschema/org/apache/poi/schemas/*.xsd", "poi-ooxml-full/src/main/xmlschema/org/apache/poi/schemas/XAdES*.xsd",
"poi-ooxml-full/src/main/xmlschema/org/apache/poi/schemas/xmldsig-core-schema.xsd",
"poi-ooxml-full/src/main/xmlschema/org/apache/poi/xdgf/visio.xsd", "poi-ooxml-full/src/main/xmlschema/org/apache/poi/xdgf/visio.xsd",
"osgi/README.md", "osgi/README.md",
"src/resources/ooxml-lite-report.*",
// ignore svn conflict artifacts // ignore svn conflict artifacts
"**/module-info.*", "**/module-info.*"
"poi-examples/src/main/groovy/settings.gradle",
"poi-examples/src/main/groovy/.gradle/**"
] ]
/* /*
@ -721,24 +654,6 @@ rat {
verbose.set(true) verbose.set(true)
} }
task jenkins(dependsOn: [
'replaceVersion',
subprojects.build,
subprojects.check,
subprojects.javadoc,
subprojects.jacocoTestReport,
subprojects.getDeps,
'srcDistZip',
'srcDistTar',
rat
]) {}
task jenkinsLite(dependsOn: [
'replaceVersion',
subprojects.build,
subprojects.test
]) {}
/*task downloadJarsToLibs() { /*task downloadJarsToLibs() {
def f = new File("$projectDir/../lib/ooxml/xmlbeans-5.0.0.jar") def f = new File("$projectDir/../lib/ooxml/xmlbeans-5.0.0.jar")
if (!f.exists()) { if (!f.exists()) {
@ -750,14 +665,14 @@ task jenkinsLite(dependsOn: [
//compileJava.dependsOn 'downloadJarsToLibs' //compileJava.dependsOn 'downloadJarsToLibs'
tasks.register('replaceVersion') { task replaceVersion() {
outputs.upToDateWhen { false } outputs.upToDateWhen { false }
var version = subprojects[0].version var version = subprojects[0].version
var tokens = [ var tokens = [
['osgi', 'pom.xml', '(packaging>\\n\\s*<version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}"], [ 'osgi', 'pom.xml', '(packaging>\\n\\s*<version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}" ],
['osgi', 'pom.xml', '(<poi.version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}"] [ 'osgi', 'pom.xml', '(<poi.version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}" ]
// [ '.', 'build.gradle', ' version = \'[0-9.]+(?:-SNAPSHOT)?\'', " version = '${version}'" ] // [ '.', 'build.gradle', ' version = \'[0-9.]+(?:-SNAPSHOT)?\'', " version = '${version}'" ]
] ]
doLast { doLast {
@ -781,13 +696,54 @@ task zipJavadocs(type: Zip, dependsOn: allJavaDoc) {
archiveExtension = 'jar' archiveExtension = 'jar'
} }
tasks.withType(Tar).configureEach { tasks.withType(Tar) {
compression = Compression.GZIP compression = Compression.GZIP
archiveExtension = 'tgz' archiveExtension = 'tgz'
} }
distributions { distributions {
var version = subprojects[0].version
var date = new Date().format('yyyyMMdd')
var poiDep = project(':poi').configurations.getAt('compileClasspath')
var ooxmlImp = project(':poi-ooxml').configurations.getAt('compileClasspath')
bin {
distributionBaseName = "poi-bin-${version}-${date}"
contents {
from('build/dist/maven') {
include "**/*${version}.jar"
exclude "**/*lite-agent*.jar"
exclude "**/*integration*.jar"
}
from('build/dist') { include 'poi-javadoc*.jar'}
from('legal') { exclude 'HEADER' }
from(poiDep) { include "**/*.jar" }
from(ooxmlImp) { include "**/*.jar" }
includeEmptyDirs = false
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
eachFile {
String root = "poi-bin-${version}/"
if (name.startsWith('poi')) {
path = root + name
} else if (poiDep.contains(file)) {
path = root + 'lib/' + name
} else if (name =~ /^(batik|bc|fontbox|graphics|pdfbox|xml-apis|xmlgraphics|xmlsec)/) {
path = root + 'auxiliary/' + name
} else if (ooxmlImp.contains(file)) {
path = root + 'ooxml-lib/' + name
} else {
path = root + name
}
}
}
}
src { src {
distributionBaseName = "poi-src-${version}-${date}"
contents { contents {
from('.') { from('.') {
exclude '*/build/**' exclude '*/build/**'
@ -828,19 +784,16 @@ distributions {
exclude '*.docx' exclude '*.docx'
exclude '*.pptx' exclude '*.pptx'
exclude '*.xlsx' exclude '*.xlsx'
// exclude intermediate files
exclude '**/*-saved.xls'
} }
from('legal') { exclude 'HEADER' } from('legal') { exclude 'HEADER' }
includeEmptyDirs = false
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
} }
} }
} }
tasks.register('soLinkCheck') { binDistZip.dependsOn 'zipJavadocs', ':poi-ooxml-lite:jar'
binDistTar.dependsOn 'zipJavadocs', ':poi-ooxml-lite:jar'
task soLinkCheck() {
doLast { doLast {
def path = ant.path { def path = ant.path {
fileset(dir: '.', includes: '**/*.java') { fileset(dir: '.', includes: '**/*.java') {
@ -861,30 +814,28 @@ tasks.register('soLinkCheck') {
} }
var srcDep = [ var srcDep = [
':poi:compileJava9', ':poi:cacheJava9',
':poi:compileTest9', ':poi:cacheTest9',
':poi-ooxml-full:compileJava9', ':poi-ooxml-full:cacheJava9',
':poi-ooxml-lite-agent:compileJava9', ':poi-ooxml-lite-agent:cacheJava9',
':poi-ooxml:compileJava9', ':poi-ooxml:cacheJava9',
':poi-ooxml:compileTest9', ':poi-ooxml:cacheTest9',
':poi-scratchpad:compileJava9', ':poi-scratchpad:cacheJava9',
':poi-scratchpad:compileTest9', ':poi-scratchpad:cacheTest9',
':poi-excelant:compileJava9', ':poi-excelant:cacheJava9',
':poi-excelant:compileTest9', ':poi-excelant:cacheTest9',
':poi-examples:compileJava9', ':poi-examples:cacheJava9',
':poi-integration:compileTest9', ':poi-integration:cacheTest9',
':poi-ooxml-lite:compileJava9', ':poi-ooxml-lite:cacheJava9',
':poi-ooxml-lite:generateModuleInfo' ':poi-ooxml-lite:generateModuleInfo'
] ]
srcDistTar.setArchiveFileName("apache-poi-src-${subprojects[0].version}-${dateSuffix}.tgz")
srcDistZip.setArchiveFileName("apache-poi-src-${subprojects[0].version}-${dateSuffix}.zip")
srcDistTar.dependsOn srcDep srcDistTar.dependsOn srcDep
srcDistZip.dependsOn srcDep srcDistZip.dependsOn srcDep
soLinkCheck.dependsOn srcDep soLinkCheck.dependsOn srcDep
rat.dependsOn soLinkCheck rat.dependsOn soLinkCheck
tasks.register('fixDistDir') { task fixDistDir {
doLast { doLast {
ant.mkdir(dir: 'build/dist') ant.mkdir(dir: 'build/dist')
ant.move(todir: 'build/dist') { ant.move(todir: 'build/dist') {
@ -893,5 +844,7 @@ tasks.register('fixDistDir') {
} }
} }
binDistZip.finalizedBy fixDistDir
binDistTar.finalizedBy fixDistDir
srcDistZip.finalizedBy fixDistDir srcDistZip.finalizedBy fixDistDir
srcDistTar.finalizedBy fixDistDir srcDistTar.finalizedBy fixDistDir

739
build.xml

File diff suppressed because it is too large Load Diff

View File

@ -35,69 +35,6 @@
<programming-language>Java</programming-language> <programming-language>Java</programming-language>
<category rdf:resource="https://projects.apache.org/category/content" /> <category rdf:resource="https://projects.apache.org/category/content" />
<category rdf:resource="https://projects.apache.org/category/library" /> <category rdf:resource="https://projects.apache.org/category/library" />
<release>
<Version>
<name>Apache POI 5.5.1</name>
<created>2025-11-30</created>
<revision>5.5.1</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.5.0</name>
<created>2025-11-15</created>
<revision>5.5.0</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.4.1</name>
<created>2025-04-06</created>
<revision>5.4.1</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.4.0</name>
<created>2025-01-08</created>
<revision>5.4.0</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.3.0</name>
<created>2024-07-02</created>
<revision>5.3.0</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.2.5</name>
<created>2023-11-25</created>
<revision>5.2.5</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.2.4</name>
<created>2023-09-28</created>
<revision>5.2.4</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.2.3</name>
<created>2022-09-16</created>
<revision>5.2.3</revision>
</Version>
</release>
<release>
<Version>
<name>Apache POI 5.2.2</name>
<created>2022-03-20</created>
<revision>5.2.2</revision>
</Version>
</release>
<release> <release>
<Version> <Version>
<name>Apache POI 5.2.1</name> <name>Apache POI 5.2.1</name>
@ -267,10 +204,10 @@
</Version> </Version>
</release> </release>
<repository> <repository>
<GitRepository> <SVNRepository>
<location rdf:resource="https://github.com/apache/poi.git"/> <location rdf:resource="https://svn.apache.org/repos/asf/poi/"/>
<browse rdf:resource="https://github.com/apache/poi/"/> <browse rdf:resource="https://svn.apache.org/viewvc/poi/"/>
</GitRepository> </SVNRepository>
</repository> </repository>
<maintainer> <maintainer>
<foaf:Person> <foaf:Person>

View File

@ -51,13 +51,6 @@ org.apache.openjpa.lib.util.J2DoPrivHelper$7.run
serp.bytecode.BCClass.read serp.bytecode.BCClass.read
serp.util.Strings.toClass serp.util.Strings.toClass
# Logging
java.util.logging.Logger.findSystemResourceBundle
java.util.logging.LogManager.readPrimordialConfiguration
org.slf4j.LoggerFactory.getLogger
org.apache.log4j.FileAppender.setFile
org.apache.logging.log4j.core.config.ConfigurationSource.getConfigurationSource
# Java # Java
sun.util.resources.LocaleData.getBundle sun.util.resources.LocaleData.getBundle
sun.util.LocaleServiceProviderPool.<init> sun.util.LocaleServiceProviderPool.<init>
@ -70,14 +63,15 @@ sun.font.SunFontManager.loadFonts
sun.font.FontManagerFactory.getInstance sun.font.FontManagerFactory.getInstance
sun.font.TrueTypeFont.open sun.font.TrueTypeFont.open
sun.reflect.misc.MethodUtil.<clinit> sun.reflect.misc.MethodUtil.<clinit>
java.util.logging.Logger.findSystemResourceBundle
java.text.BreakIterator.getBundle java.text.BreakIterator.getBundle
sun.java2d.SunGraphicsEnvironment.<init> sun.java2d.SunGraphicsEnvironment.<init>
org.kohsuke.file_leak_detector.AgentMain.runHttpServer org.kohsuke.file_leak_detector.AgentMain.runHttpServer
org.apache.log4j.FileAppender.setFile
org.apache.logging.log4j.core.config.ConfigurationSource.getConfigurationSource
sun.launcher.LauncherHelper.validateMainClass sun.launcher.LauncherHelper.validateMainClass
sun.util.locale.provider.RuleBasedBreakIterator$1.run sun.util.locale.provider.RuleBasedBreakIterator$1.run
java.util.ServiceLoader$LazyIterator.hasNextService java.util.ServiceLoader$LazyIterator.hasNextService
java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass
java.lang.ClassLoader.loadClass
# other third party libs # other third party libs
net.bytebuddy.dynamic.ClassFileLocator$ForClassLoader.locate net.bytebuddy.dynamic.ClassFileLocator$ForClassLoader.locate

View File

@ -1,11 +1,11 @@
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
# Less than 2G definitely slows things down. Increased to 3G due to OOM issues on ci-builds.apache.org. # Less than 2G definitely slows things down. -XX:+HeapDumpOnOutOfMemoryError
# -XX:+HeapDumpOnOutOfMemoryError org.gradle.jvmargs=-Xmx2G -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx3G -Dfile.encoding=UTF-8
# Activating will be much faster, but break the build of 'poi-ooxml-lite' # Activating will be much faster, but break the build of 'poi-ooxml-lite'
org.gradle.caching=true # @todo: look into poi-ooxml-lite task generateModuleInfo and enforce running whatever is needed before
org.gradle.caching=false
# Modularise your project and enable parallel build # Modularise your project and enable parallel build
org.gradle.parallel=true org.gradle.parallel=true

Binary file not shown.

View File

@ -1,7 +1,19 @@
# Copyright 2004 The Apache Software Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

47
gradlew vendored
View File

@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@ -57,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -82,11 +80,13 @@ do
esac esac
done done
# This is normally unused APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;; NONSTOP* ) nonstop=true ;;
esac esac
CLASSPATH="\\\"\\\"" CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
@ -133,29 +133,22 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
if ! command -v java >/dev/null 2>&1 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -200,28 +193,18 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java command;
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# Collect all arguments for the java command: # * put everything else in single quotes, so that it's not re-expanded.
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \ -classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # With -n1 it outputs one arg per line, with the quotes and backslashes removed.

183
gradlew.bat vendored
View File

@ -1,94 +1,89 @@
@rem @rem
@rem Copyright 2015 the original author or authors. @rem Copyright 2015 the original author or authors.
@rem @rem
@rem Licensed under the Apache License, Version 2.0 (the "License"); @rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License. @rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at @rem You may obtain a copy of the License at
@rem @rem
@rem https://www.apache.org/licenses/LICENSE-2.0 @rem https://www.apache.org/licenses/LICENSE-2.0
@rem @rem
@rem Unless required by applicable law or agreed to in writing, software @rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS, @rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem @if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@if "%DEBUG%"=="" @echo off @rem
@rem ########################################################################## @rem Gradle startup script for Windows
@rem @rem
@rem Gradle startup script for Windows @rem ##########################################################################
@rem
@rem ########################################################################## @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set DIRNAME=%~dp0 set APP_BASE_NAME=%~n0
if "%DIRNAME%"=="" set DIRNAME=. set APP_HOME=%DIRNAME%
@rem This is normally unused
set APP_BASE_NAME=%~n0 @rem Resolve any "." and ".." in APP_HOME to make it shorter.
set APP_HOME=%DIRNAME% for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Resolve any "." and ".." in APP_HOME to make it shorter. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Find java.exe
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" if defined JAVA_HOME goto findJavaFromJavaHome
@rem Find java.exe set JAVA_EXE=java.exe
if defined JAVA_HOME goto findJavaFromJavaHome %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 echo.
if %ERRORLEVEL% equ 0 goto execute echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 echo location of your Java installation.
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 goto fail
echo location of your Java installation. 1>&2
:findJavaFromJavaHome
goto fail set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% if exist "%JAVA_EXE%" goto execute
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
echo.
if exist "%JAVA_EXE%" goto execute echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 echo location of your Java installation.
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 goto fail
echo location of your Java installation. 1>&2
:execute
goto fail @rem Setup the command line
:execute set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Setup the command line
set CLASSPATH= @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
@rem Execute Gradle :end
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:end
@rem End local scope for the variables with windows NT shell :fail
if %ERRORLEVEL% equ 0 goto mainEnd rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
:fail if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of exit /b 1
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL% :mainEnd
if %EXIT_CODE% equ 0 set EXIT_CODE=1 if "%OS%"=="Windows_NT" endlocal
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE% :omega
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -1,20 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
// This script is used as input to the Jenkins Job DSL plugin to create all the build-jobs that // This script is used as input to the Jenkins Job DSL plugin to create all the build-jobs that
// Apache POI uses on the public Jenkins instance at https://ci-builds.apache.org/job/POI/ // Apache POI uses on the public Jenkins instance at https://ci-builds.apache.org/job/POI/
// //
@ -31,108 +14,124 @@ def xercesUrl = 'https://repo1.maven.org/maven2/xerces/xercesImpl/2.6.1/xercesIm
def xercesLib = './xercesImpl-2.6.1.jar' def xercesLib = './xercesImpl-2.6.1.jar'
def poijobs = [ def poijobs = [
[ name: 'POI-DSL-1.8', [ name: 'POI-DSL-1.8', trigger: 'H */12 * * *', gradle: true
jdk: '1.8',
trigger: 'H */12 * * *',
jenkinsLite: true,
disabled: true // JDK 8 is no longer supported by POI 6
], ],
[ name: 'POI-DSL-1.8-branch-5.5.x', [ name: 'POI-DSL-OpenJDK', jdk: 'OpenJDK 1.8', trigger: 'H */12 * * *',
jdk: '1.8', // only a limited set of nodes still have OpenJDK 8 (on Ubuntu) installed
branch: '5.5.x', slaves: 'ubuntu',
trigger: 'H */12 * * *', skipcigame: true, gradle: true
jenkinsLite: true,
], ],
[ name: 'POI-DSL-1.11', jdk: '1.11', trigger: triggerSundays, skipcigame: true // [ name: 'POI-DSL-1.10', jdk: '1.10', trigger: triggerSundays, skipcigame: true,
// // let's save some CPU cycles here, 10 had EOL in September 2018
// disabled: true
// ],
[ name: 'POI-DSL-1.11', jdk: '1.11', trigger: triggerSundays, skipcigame: true, gradle: true
], ],
[ name: 'POI-DSL-1.17', jdk: '1.17', trigger: 'H */12 * * *', skipcigame: true // [ name: 'POI-DSL-1.12', jdk: '1.12', trigger: triggerSundays, skipcigame: true,
// // let's save some CPU cycles here, 12 is not a LTS and JDK 13 is GA as of 17 September 2019
// disabled: true
// ],
// [ name: 'POI-DSL-1.13', jdk: '1.13', trigger: triggerSundays, skipcigame: true,
// // let's save some CPU cycles here, 13 is not a LTS and JDK 14 is GA as of 17 March 2020
// disabled: true
// ],
// [ name: 'POI-DSL-1.14', jdk: '1.14', trigger: triggerSundays, skipcigame: true,
// // let's save some CPU cycles here, 14 is not a LTS and JDK 15 is GA as of 15 September 2020
// disabled: true
// ],
[ name: 'POI-DSL-1.15', jdk: '1.15', trigger: triggerSundays, skipcigame: true, gradle: true,
// let's save some CPU cycles here, 15 is not a LTS and JDK 16 is GA
disabled: true
], ],
[ name: 'POI-DSL-1.21', jdk: '1.21', trigger: 'H */12 * * *', skipcigame: true [ name: 'POI-DSL-1.16', jdk: '1.16', trigger: 'H */12 * * *', skipcigame: true, gradle: true,
// let's save some CPU cycles here, 16 is not a LTS and JDK 17 is GA
disabled: true
], ],
[ name: 'POI-DSL-1.24', jdk: '1.24', trigger: triggerSundays, skipcigame: true, [ name: 'POI-DSL-1.17', jdk: '1.17', trigger: 'H */12 * * *', skipcigame: true, gradle: true
], ],
[ name: 'POI-DSL-1.25', jdk: '1.25', trigger: triggerSundays, skipcigame: true, skipSpotbugs: true, [ name: 'POI-DSL-1.18', jdk: '1.18', trigger: triggerSundays, skipcigame: true, gradle: true
// use Ant for building until Gradle supports JDK 25
// see https://docs.gradle.org/current/userguide/compatibility.html
// and https://github.com/gradle/gradle/issues/31625
useAnt: true
], ],
// Use Ant-build for now as selecting IBM JDK via toolchain does not work (yet) [ name: 'POI-DSL-IBM-JDK', jdk: 'IBMJDK', trigger: triggerSundays, skipcigame: true, gradle: true
[ name: 'POI-DSL-IBM-JDK', jdk: 'IBMJDK', trigger: triggerSundays, skipcigame: true, useAnt: true
], ],
// Use Ant-build for now as passing the "additionaljar" does not work in Gradle build (yet) [ name: 'POI-DSL-old-Xerces', trigger: triggerSundays, skipcigame: true,
[ name: 'POI-DSL-old-Xerces', trigger: triggerSundays, skipcigame: true, useAnt: true,
shell: "test -s ${xercesLib} || wget -O ${xercesLib} ${xercesUrl}\n", shell: "test -s ${xercesLib} || wget -O ${xercesLib} ${xercesUrl}\n",
// the property triggers using Xerces as XML Parser and previously showed some exception that can occur // the property triggers using Xerces as XML Parser and previously showed some exception that can occur
properties: ["-Dadditionaljar=${xercesLib}"] properties: ["-Dadditionaljar=${xercesLib}"]
], ],
// [ name: 'POI-DSL-Maven', trigger: 'H */4 * * *', maven: true,
// // not needed any more now that we use Gradle for SonarQube
// disabled: true
// ],
[ name: 'POI-DSL-regenerate-javadoc', trigger: triggerSundays, javadoc: true [ name: 'POI-DSL-regenerate-javadoc', trigger: triggerSundays, javadoc: true
], ],
// it was impossible to make this run stable in Gradle, thus disabling this for now // it was impossible to make this run stable in Gradle, thus disabling this for now
[ name: 'POI-DSL-API-Check', trigger: '@daily', apicheck: true, disabled: true, useAnt: true [ name: 'POI-DSL-API-Check', trigger: '@daily', apicheck: true, disabled: true
], ],
[ name: 'POI-DSL-no-scratchpad', trigger: triggerSundays, noScratchpad: true // [ name: 'POI-DSL-Gradle', trigger: triggerSundays, email: 'centic@apache.org', gradle: true
// ],
[ name: 'POI-DSL-no-scratchpad', trigger: triggerSundays, noScratchpad: true, gradle: true
], ],
[ name: 'POI-DSL-saxon-test', trigger: triggerSundays, saxonTest: true [ name: 'POI-DSL-saxon-test', trigger: triggerSundays, saxonTest: true, gradle: true
], ],
// [ name: 'POI-DSL-SonarQube', jdk: '1.11', trigger: 'H 7 * * *', maven: true, sonar: true, skipcigame: true, // [ name: 'POI-DSL-SonarQube', jdk: '1.11', trigger: 'H 7 * * *', maven: true, sonar: true, skipcigame: true,
// email: 'kiwiwings@apache.org', // email: 'kiwiwings@apache.org',
// // replaced by Gradle-based build now // // replaced by Gradle-based build now
// disabled: true // disabled: true
// ], // ],
[ name: 'POI-DSL-SonarQube-Gradle', jdk: '1.17', trigger: 'H 7 * * *', sonar: true, skipcigame: true [ name: 'POI-DSL-SonarQube-Gradle', jdk: '1.11', trigger: 'H 7 * * *', gradle: true, sonar: true, skipcigame: true
], ],
[ name: 'POI-DSL-Windows-1.8', [ name: 'POI-DSL-Windows-1.8', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', gradle: true
trigger: 'H */12 * * *',
windows: true,
slaves: 'Windows',
jenkinsLite: true,
disabled: true // JDK 8 is no longer supported by POI 6
], ],
[ name: 'POI-DSL-Windows-1.11', jdk: '1.11', trigger: triggerSundays, windows: true, slaves: 'Windows', // [ name: 'POI-DSL-Windows-1.12', jdk: '1.12', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true, gradle: true,
jenkinsLite: true // // let's save some CPU cycles here, 12 is not a LTS and JDK 13 is GA now
// disabled: true
// ],
// [ name: 'POI-DSL-Windows-1.14', jdk: '1.14', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true, gradle: true,
// // let's only verify the latest two JDKs
// disabled: true
// ],
[ name: 'POI-DSL-Windows-1.15', jdk: '1.15', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true, gradle: true,
// let's save some CPU cycles here, 14 is not a LTS and JDK 15 is GA as of 15 September 2020
disabled: true
], ],
[ name: 'POI-DSL-Windows-1.17', jdk: '1.17', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', skipcigame: true [ name: 'POI-DSL-Windows-1.16', jdk: '1.16', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', skipcigame: true, gradle: true,
// let's save some CPU cycles here, 16 is not a LTS and JDK 17 is GA
disabled: true
], ],
[ name: 'POI-DSL-Windows-1.21', jdk: '1.21', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', skipcigame: true [ name: 'POI-DSL-Windows-1.17', jdk: '1.17', trigger: 'H */12 * * *', windows: true, slaves: 'Windows', skipcigame: true, gradle: true
], ],
[ name: 'POI-DSL-Windows-1.24', jdk: '1.24', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true, [ name: 'POI-DSL-Windows-1.18', jdk: '1.18', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true, gradle: true
], ],
[ name: 'POI-DSL-Windows-1.25', jdk: '1.25', trigger: triggerSundays, windows: true, slaves: 'Windows', skipcigame: true, [ name: 'POI-DSL-Github-PullRequests', trigger: '', githubpr: true, skipcigame: true,
skipSpotbugs: true, // ensure the file which is needed from the separate documentation module does exist
// use Ant for building until Gradle supports JDK 24 // as we are checking out from git, we do not have the reference checked out here
// see https://docs.gradle.org/current/userguide/compatibility.html addShell: 'mkdir -p src/documentation\ntouch src/documentation/RELEASE-NOTES.txt'
// and https://github.com/gradle/gradle/issues/31625
useAnt: true
],
[ name: 'POI-DSL-Github-PullRequests', trigger: '', skipcigame: true, disabled: true
], ],
] ]
def xmlbeansjobs = [ def xmlbeansjobs = [
[ name: 'POI-XMLBeans-DSL-1.8', jdk: '1.8', trigger: 'H */12 * * *', skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.8', jdk: '1.8', trigger: 'H */12 * * *', skipcigame: true, gradle: true,
], ],
[ name: 'POI-XMLBeans-DSL-1.11', jdk: '1.11', trigger: triggerSundays, skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.11', jdk: '1.11', trigger: triggerSundays, skipcigame: true, gradle: true,
], ],
[ name: 'POI-XMLBeans-DSL-1.17', jdk: '1.17', trigger: 'H */12 * * *', skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.16', jdk: '1.16', trigger: triggerSundays, skipcigame: true, gradle: true,
], // let's save some CPU cycles here, 16 is not a LTS and JDK 17 is GA
[ name: 'POI-XMLBeans-DSL-1.21', jdk: '1.21', trigger: 'H */12 * * *', skipcigame: true,
],
[ name: 'POI-XMLBeans-DSL-1.24', jdk: '1.24', trigger: triggerSundays, skipcigame: true,
disabled: true disabled: true
], ],
[ name: 'POI-XMLBeans-DSL-1.25', jdk: '1.25', trigger: triggerSundays, skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.17', jdk: '1.17', trigger: triggerSundays, skipcigame: true, gradle: true,
], ],
[ name: 'POI-XMLBeans-DSL-Sonar', jdk: '1.17', trigger: triggerSundays, skipcigame: true, [ name: 'POI-XMLBeans-DSL-1.18', jdk: '1.18', trigger: triggerSundays, skipcigame: true, gradle: true,
],
[ name: 'POI-XMLBeans-DSL-Sonar', jdk: '1.11', trigger: triggerSundays, skipcigame: true,
sonar: true sonar: true
] ]
] ]
def gitBase = 'https://github.com/apache/poi.git' def svnBase = 'https://svn.apache.org/repos/asf/poi/trunk'
def xmlbeansGitBase = 'https://github.com/apache/xmlbeans.git' def xmlbeansSvnBase = 'https://svn.apache.org/repos/asf/xmlbeans/trunk'
def defaultJdk = '1.11' def defaultJdk = '1.8'
def defaultBranch = 'trunk'
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'
def defaultAnt = 'ant_1.10_latest' def defaultAnt = 'ant_1.10_latest'
@ -142,14 +141,18 @@ def defaultMaven = 'maven_3_latest'
def defaultSlaves = '(ubuntu)&&!beam&&!cloud-slave&&!H29' def defaultSlaves = '(ubuntu)&&!beam&&!cloud-slave&&!H29'
def jdkMapping = [ def jdkMapping = [
'1.8': [ jenkinsJdk: 'jdk_1.8_latest', jdkVersion: 8, jdkVendor: '' ], '1.8': [ jenkinsJdk: 'jdk_1.8_latest', jdkVersion: 8, jdkVendor: 'oracle' ],
'1.11': [ jenkinsJdk: 'jdk_11_latest', jdkVersion: 11, jdkVendor: '' ], '1.10': [ jenkinsJdk: 'jdk_10_latest', jdkVersion: 10, jdkVendor: 'oracle' ],
'1.11': [ jenkinsJdk: 'jdk_11_latest', jdkVersion: 11, jdkVendor: 'oracle' ],
'1.12': [ jenkinsJdk: 'jdk_12_latest', jdkVersion: 12, jdkVendor: '' ],
'1.13': [ jenkinsJdk: 'jdk_13_latest', jdkVersion: 13, jdkVendor: '' ],
'1.14': [ jenkinsJdk: 'jdk_14_latest', jdkVersion: 14, jdkVendor: '' ],
'1.15': [ jenkinsJdk: 'jdk_15_latest', jdkVersion: 15, jdkVendor: '' ],
'1.16': [ jenkinsJdk: 'jdk_16_latest', jdkVersion: 16, jdkVendor: '' ],
'1.17': [ jenkinsJdk: 'jdk_17_latest', jdkVersion: 17, jdkVendor: '' ], '1.17': [ jenkinsJdk: 'jdk_17_latest', jdkVersion: 17, jdkVendor: '' ],
'1.21': [ jenkinsJdk: 'jdk_21_latest', jdkVersion: 21, jdkVendor: '' ], '1.18': [ jenkinsJdk: 'jdk_18_latest', jdkVersion: 18, jdkVendor: '' ],
'1.24': [ jenkinsJdk: 'jdk_24_latest', jdkVersion: 24, jdkVendor: '' ], 'OpenJDK 1.8': [ jenkinsJdk: 'adoptopenjdk_hotspot_8u282', jdkVersion: 8, jdkVendor: 'adoptopenjdk' ],
'1.25': [ jenkinsJdk: 'jdk_25_latest', jdkVersion: 25, jdkVendor: '' ], 'IBMJDK': [ jenkinsJdk: 'ibmjdk_1.8.0_261', jdkVersion: 8, jdkVendor: 'ibm' ]
// one of the few IBM JDKs that is still supported on ci-builds.apache.org
'IBMJDK': [ jenkinsJdk: 'ibm_semeru_21.0.2_13', jdkVersion: 21, jdkVendor: 'ibm' ]
] ]
static def shellEx(def context, String cmd, def poijob) { static def shellEx(def context, String cmd, def poijob) {
@ -167,7 +170,7 @@ Apache POI - the Java API for Microsoft Documents
</p> </p>
<p> <p>
<b>This is an automatically generated Job Config, do not edit it here! <b>This is an automatically generated Job Config, do not edit it here!
Instead change the Jenkins Job DSL at <a href="https://github.com/apache/poi/blob/trunk/jenkins/">https://github.com/apache/poi/blob/trunk/jenkins/</a>, Instead change the Jenkins Job DSL at <a href="https://svn.apache.org/repos/asf/poi/trunk/jenkins">https://svn.apache.org/repos/asf/poi/trunk/jenkins</a>,
see <a href="https://github.com/jenkinsci/job-dsl-plugin/wiki">https://github.com/jenkinsci/job-dsl-plugin/wiki</a> see <a href="https://github.com/jenkinsci/job-dsl-plugin/wiki">https://github.com/jenkinsci/job-dsl-plugin/wiki</a>
for more details about the DSL.</b> for more details about the DSL.</b>
</p>''' </p>'''
@ -186,9 +189,9 @@ def apicheckDesc = '''
def sonarDesc = ''' def sonarDesc = '''
<p> <p>
<b><a href="lastSuccessfulBuild/spotbugs/" target="_blank">Spotbugs report of latest build</a></b> - <b><a href="lastSuccessfulBuild/findbugsResult/" target="_blank">Findbugs report of latest build</a></b> -
<b><a href="https://sonarcloud.io/dashboard?id=poi-parent" target="_blank">Sonar reports</a></b> - <b><a href="https://sonarcloud.io/dashboard?id=poi-parent" target="_blank">Sonar reports</a></b> -
<b><a href="lastSuccessfulBuild/jacoco/" target="_blank">Coverage of latest build</a></b> <b><a href="lastSuccessfulBuild/artifact/build/coverage/index.html" target="_blank">Coverage of latest build</a></b>
</p> </p>
''' '''
@ -197,9 +200,9 @@ def shellCmdsUnix =
rm -rf examples excelant integrationtest main ooxml ooxml-schema scratchpad build.javacheck.xml rm -rf examples excelant integrationtest main ooxml ooxml-schema scratchpad build.javacheck.xml
# show which files are currently modified in the working copy # show which files are currently modified in the working copy
git status || true svn status || true
# make sure no changed module-class-files or ooxml-lite-report-files are lingering on # make sure no changed module-class-files are lingering on
git reset --hard || true svn revert poi*/src/*/java9/module-info.* || true
# print out information about which exact version of java we are using # print out information about which exact version of java we are using
echo Java-Home: $JAVA_HOME echo Java-Home: $JAVA_HOME
@ -232,9 +235,9 @@ exit 0'''
def shellCmdsWin = def shellCmdsWin =
'''@echo off '''@echo off
:: show which files are currently modified in the working copy :: show which files are currently modified in the working copy
git status svn status
:: make sure no changed module-class-files are lingering on :: make sure no changed module-class-files are lingering on
git reset --hard svn revert poi*\\src\\*\\java9\\module-info.*
:: print out information about which exact version of java we are using :: print out information about which exact version of java we are using
echo Java-Home: %JAVA_HOME% echo Java-Home: %JAVA_HOME%
@ -252,7 +255,6 @@ poijobs.each { poijob ->
def email = poijob.email ?: defaultEmail def email = poijob.email ?: defaultEmail
def slaves = poijob.slaves ?: defaultSlaves + (poijob.slaveAdd ?: '') def slaves = poijob.slaves ?: defaultSlaves + (poijob.slaveAdd ?: '')
def antRT = poijob.windows ? defaultAntWindows : defaultAnt def antRT = poijob.windows ? defaultAntWindows : defaultAnt
def checkoutBranch = poijob.branch ?: defaultBranch
job('POI/' + poijob.name) { job('POI/' + poijob.name) {
if (poijob.disabled) { if (poijob.disabled) {
@ -268,6 +270,11 @@ poijobs.each { poijob ->
environmentVariables { environmentVariables {
env('LANG', 'en_US.UTF-8') env('LANG', 'en_US.UTF-8')
env('CI_BUILD', 'TRUE') env('CI_BUILD', 'TRUE')
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', poijob.windows ? 'f:\\jenkins\\tools\\forrest\\latest' : '/home/jenkins/tools/forrest/latest') env('FORREST_HOME', poijob.windows ? 'f:\\jenkins\\tools\\forrest\\latest' : '/home/jenkins/tools/forrest/latest')
} }
@ -297,17 +304,50 @@ poijobs.each { poijob ->
} }
jdk(jdkMapping.get(jdkKey).jenkinsJdk) jdk(jdkMapping.get(jdkKey).jenkinsJdk)
scm { scm {
git { if (poijob.githubpr) {
remote { git {
url(gitBase) remote {
github('apache/poi')
refspec('+refs/pull/*:refs/remotes/origin/pr/*')
}
branch('${sha1}')
}
} else {
svn(svnBase) { svnNode ->
svnNode / browser(class: 'hudson.scm.browsers.ViewSVN') /
url << 'https://svn.apache.org/viewcvs.cgi/?root=Apache-SVN'
} }
branch("*/${checkoutBranch}")
} }
} }
checkoutRetryCount(3) checkoutRetryCount(3)
triggers { if (poijob.githubpr) {
scm(trigger) throttleConcurrentBuilds {
maxPerNode(1)
maxTotal(1)
}
parameters {
/* plugin not available:
gitParam('sha1') {
description('Pull request')
type('BRANCH')
}*/
stringParam('sha1', 'origin/pr/9/head', 'Provide a branch-spec, e.g. origin/pr/9/head')
}
triggers {
pullRequestBuildTrigger()
/*githubPullRequest {
admins(['centic9', 'poi-benchmark', 'tballison', 'gagravarr', 'onealj', 'pjfanning', 'Alain-Bearez'])
userWhitelist(['centic9', 'poi-benchmark', 'tballison', 'gagravarr', 'onealj', 'pjfanning', 'Alain-Bearez'])
orgWhitelist(['apache'])
cron('H/5 * * * *')
triggerPhrase('OK to test')
}*/
}
} else {
triggers {
scm(trigger)
}
} }
def shellcmds = (poijob.windows ? shellCmdsWin : shellCmdsUnix).replace('POIJOBSHELL', poijob.shell ?: '') def shellcmds = (poijob.windows ? shellCmdsWin : shellCmdsUnix).replace('POIJOBSHELL', poijob.shell ?: '')
@ -339,7 +379,7 @@ poijobs.each { poijob ->
gradle { gradle {
switches('-PenableSonar') switches('-PenableSonar')
switches('-Dsonar.token=${POI_SONAR_TOKEN}') switches('-Dsonar.login=${POI_SONAR_TOKEN}')
switches('-Dsonar.organization=apache') switches('-Dsonar.organization=apache')
switches('-Dsonar.projectKey=poi-parent') switches('-Dsonar.projectKey=poi-parent')
switches('-Dsonar.host.url=https://sonarcloud.io') switches('-Dsonar.host.url=https://sonarcloud.io')
@ -350,13 +390,90 @@ poijobs.each { poijob ->
tasks('clean') tasks('clean')
tasks('check') tasks('check')
tasks('jacocoTestReport') tasks('jacocoTestReport')
tasks('sonar') tasks('sonarqube')
useWrapper(true) useWrapper(true)
} }
} }
publishers { publishers {
// in archive, junit and jacoco publishers, matches beneath build/*/build/... are for Gradle-build results
archiveArtifacts('build/dist/*.tar.gz,*/build/reports/**,poi-integration/build/test-results/**,*/build/libs/*.jar')
archiveJunit('*/build/test-results/**/TEST-*.xml') {
testDataPublishers {
publishTestStabilityData()
}
}
jacocoCodeCoverage {
classPattern('*/build/classes')
execPattern('*/build/*.exec,*/build/jacoco/*.exec')
sourcePattern('*/src/main/java')
exclusionPattern('com/microsoft/**,org/openxmlformats/**,org/etsi/**,org/w3/**,schemaorg*/**,schemasMicrosoft*/**,org/apache/poi/hdf/model/hdftypes/definitions/*.class,org/apache/poi/hwpf/model/types/*.class,org/apache/poi/hssf/usermodel/DummyGraphics2d.class,org/apache/poi/sl/draw/binding/*.class')
}
if (!poijob.skipcigame) {
configure { project ->
project / publishers << 'hudson.plugins.cigame.GamePublisher' {}
}
}
mailer(email, false, false)
}
} else {
steps {
shellEx(delegate, shellcmds, poijob)
if(poijob.addShell) {
shellEx(delegate, poijob.addShell, poijob)
}
// For Jobs that should still have the default set of publishers we can configure different steps here
if(poijob.gradle) {
if (!poijob.windows) {
// Gradle will not run any tests if the code is up-to-date, therefore manually mark the files as updated
shellEx(delegate, 'touch --no-create build/*/build/test-results/TEST-*.xml build/*/build/test-results/test/TEST-*.xml', poijob)
}
gradle {
tasks('clean jenkins')
useWrapper(true)
if (poijob.noScratchpad) {
switches('-Pscratchpad.ignore=true')
}
if (poijob.saxonTest) {
switches('-Psaxon.test=true')
}
switches("-PjdkVersion=${jdkMapping.get(jdkKey).jdkVersion}")
if (jdkMapping.get(jdkKey).jdkVendor != '') {
switches("-PjdkVendor=${jdkMapping.get(jdkKey).jdkVendor}")
}
}
} else {
ant {
targets(['clean', 'jenkins'] + (poijob.properties ?: []))
prop('coverage.enabled', true)
// Properties did not work, so I had to use targets instead
//properties(poijob.properties ?: '')
antInstallation(antRT)
}
ant {
targets(['run'] + (poijob.properties ?: []))
buildFile('poi-integration/build.xml')
// Properties did not work, so I had to use targets instead
//properties(poijob.properties ?: '')
antInstallation(antRT)
}
}
}
publishers {
recordIssues {
tools {
spotBugs {
pattern('*/build/reports/spotbugs/*.xml')
reportEncoding('UTF-8')
}
}
}
// in archive, junit and jacoco publishers, matches beneath build/*/build/... are for Gradle-build results // in archive, junit and jacoco publishers, matches beneath build/*/build/... are for Gradle-build results
archiveArtifacts('build/dist/*.tar.gz,*/build/reports/**,poi-integration/build/test-results/**,*/build/libs/*.jar') archiveArtifacts('build/dist/*.zip,build/dist/*.tgz,build/dist/maven/*/*.jar,build/coverage/**,build/hs_err*.log')
warnings(['Java Compiler (javac)', 'JavaDoc Tool'], null) {
resolveRelativePaths()
}
archiveJunit('*/build/test-results/**/TEST-*.xml') { archiveJunit('*/build/test-results/**/TEST-*.xml') {
testDataPublishers { testDataPublishers {
publishTestStabilityData() publishTestStabilityData()
@ -369,95 +486,6 @@ poijobs.each { poijob ->
exclusionPattern('com/microsoft/**,org/openxmlformats/**,org/etsi/**,org/w3/**,schemaorg*/**,schemasMicrosoft*/**,org/apache/poi/hdf/model/hdftypes/definitions/*.class,org/apache/poi/hwpf/model/types/*.class,org/apache/poi/hssf/usermodel/DummyGraphics2d.class,org/apache/poi/sl/draw/binding/*.class') exclusionPattern('com/microsoft/**,org/openxmlformats/**,org/etsi/**,org/w3/**,schemaorg*/**,schemasMicrosoft*/**,org/apache/poi/hdf/model/hdftypes/definitions/*.class,org/apache/poi/hwpf/model/types/*.class,org/apache/poi/hssf/usermodel/DummyGraphics2d.class,org/apache/poi/sl/draw/binding/*.class')
} }
if (!poijob.skipcigame) {
configure { project ->
project / publishers << 'hudson.plugins.cigame.GamePublisher' {}
}
}
mailer(email, false, false)
}
} else {
steps {
shellEx(delegate, shellcmds, poijob)
if(poijob.addShell) {
shellEx(delegate, poijob.addShell, poijob)
}
// For Jobs that should still have the default set of publishers we can configure different steps here
if(!poijob.useAnt) {
if (!poijob.windows) {
// Gradle will not run any tests if the code is up-to-date, therefore manually mark the files as updated
shellEx(delegate, 'touch --no-create build/*/build/test-results/TEST-*.xml build/*/build/test-results/test/TEST-*.xml', poijob)
}
gradle {
if (poijob.jenkinsLite) {
tasks('clean jenkinsLite')
} else {
tasks('clean jenkins')
}
useWrapper(true)
if (poijob.noScratchpad) {
switches('-Pscratchpad.ignore=true')
}
if (poijob.saxonTest) {
switches('-Psaxon.test=true')
}
switches("-PjdkVersion=${jdkMapping.get(jdkKey).jdkVersion}")
if (jdkMapping.get(jdkKey).jdkVendor != '') {
switches("-PjdkVendor=${jdkMapping.get(jdkKey).jdkVendor}")
}
switches("--refresh-dependencies")
}
} else {
ant {
targets(['clean', 'jenkins'] + (poijob.properties ?: []))
prop('coverage.enabled', !poijob.skipSpotbugs)
// Properties did not work, so I had to use targets instead
//properties(poijob.properties ?: '')
antInstallation(antRT)
}
if(!poijob.skipSourceBuild) {
ant {
targets(['run'] + (poijob.properties ?: []))
buildFile('poi-integration/build.xml')
// Properties did not work, so I had to use targets instead
//properties(poijob.properties ?: '')
antInstallation(antRT)
}
}
}
}
publishers {
if (!poijob.skipSpotbugs) {
recordIssues {
tools {
spotBugs {
pattern('*/build/reports/spotbugs/*.xml')
reportEncoding('UTF-8')
}
}
}
}
// in archive, junit and jacoco publishers, matches beneath build/*/build/... are for Gradle-build results
archiveArtifacts('build/dist/*.zip,build/dist/*.tgz,build/dist/maven/*/*.jar,build/dist/maven/*/*.pom,build/dist/maven/*/*.asc,build/dist/maven/*/*.sha256,build/dist/maven/*/*.sha512,build/coverage/**,*/build/reports/*.bom.*,build/hs_err*.log')
/* this plugin is currently missing on the Apache Jenkins instance
warnings(['Java Compiler (javac)', 'JavaDoc Tool'], null) {
resolveRelativePaths()
} */
archiveJunit('*/build/test-results/**/TEST-*.xml') {
testDataPublishers {
publishTestStabilityData()
}
}
if (!poijob.skipSpotbugs) {
jacocoCodeCoverage {
classPattern('*/build/classes')
execPattern('*/build/*.exec,*/build/jacoco/*.exec')
sourcePattern('*/src/main/java')
exclusionPattern('com/microsoft/**,org/openxmlformats/**,org/etsi/**,org/w3/**,schemaorg*/**,schemasMicrosoft*/**,org/apache/poi/hdf/model/hdftypes/definitions/*.class,org/apache/poi/hwpf/model/types/*.class,org/apache/poi/hssf/usermodel/DummyGraphics2d.class,org/apache/poi/sl/draw/binding/*.class')
}
}
if (!poijob.skipcigame) { if (!poijob.skipcigame) {
configure { project -> configure { project ->
project / publishers << 'hudson.plugins.cigame.GamePublisher' {} project / publishers << 'hudson.plugins.cigame.GamePublisher' {}
@ -467,6 +495,15 @@ poijobs.each { poijob ->
} }
} }
if (poijob.githubpr) {
configure {
it / 'properties' << 'com.cloudbees.jenkins.plugins.git.vmerge.JobPropertyImpl'(plugin: 'git-validated-merge') {
credentialsId('ASF_Cloudbees_Jenkins_ci-builds')
postBuildPushFailureHandler(class: 'com.cloudbees.jenkins.plugins.git.vmerge.pbph.PushFailureIsFailure')
}
}
}
} }
} }
@ -490,8 +527,11 @@ xmlbeansjobs.each { xjob ->
label(slaves) label(slaves)
environmentVariables { environmentVariables {
env('LANG', 'en_US.UTF-8') env('LANG', 'en_US.UTF-8')
if (jdkKey == '1.11' || jdkKey == '1.17' || jdkKey == '1.21' if(jdkKey == '1.10') {
|| jdkKey == '1.23' || jdkKey == '1.24' || jdkKey == '1.25') { // 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')
} else if (jdkKey == '1.11' || jdkKey == '1.12' || jdkKey == '1.13' || jdkKey == '1.14' || jdkKey == '1.15' || jdkKey == '1.16' || jdkKey == '1.17') {
env('ANT_OPTS', '--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-opens=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED')
} }
// will be needed for forbidden-apis-check: env('ANT_HOME', xjob.windows ? 'f:\\jenkins\\tools\\ant\\latest' : '/usr/share/ant') // will be needed for forbidden-apis-check: env('ANT_HOME', xjob.windows ? 'f:\\jenkins\\tools\\ant\\latest' : '/usr/share/ant')
@ -514,11 +554,9 @@ xmlbeansjobs.each { xjob ->
} }
jdk(jdkMapping.get(jdkKey).jenkinsJdk) jdk(jdkMapping.get(jdkKey).jenkinsJdk)
scm { scm {
git { svn(xmlbeansSvnBase) { svnNode ->
remote { svnNode / browser(class: 'hudson.scm.browsers.ViewSVN') /
url(xmlbeansGitBase) url << 'https://svn.apache.org/viewcvs.cgi/?root=Apache-SVN'
}
branch('*/trunk')
} }
} }
checkoutRetryCount(3) checkoutRetryCount(3)
@ -539,7 +577,7 @@ xmlbeansjobs.each { xjob ->
gradle { gradle {
if (xjob.sonar) { if (xjob.sonar) {
switches('-PenableSonar') switches('-PenableSonar')
switches('-Dsonar.token=${POI_SONAR_TOKEN}') switches('-Dsonar.login=${POI_SONAR_TOKEN}')
switches('-Dsonar.organization=apache') switches('-Dsonar.organization=apache')
switches('-Dsonar.projectKey=apache_xmlbeans') switches('-Dsonar.projectKey=apache_xmlbeans')
switches('-Dsonar.host.url=https://sonarcloud.io') switches('-Dsonar.host.url=https://sonarcloud.io')
@ -552,18 +590,17 @@ xmlbeansjobs.each { xjob ->
tasks('jenkins') tasks('jenkins')
tasks('jacocoTestReport') tasks('jacocoTestReport')
if (xjob.sonar) { if (xjob.sonar) {
tasks('sonar') tasks('sonarqube')
} }
useWrapper(true) useWrapper(true)
} }
} }
publishers { publishers {
archiveArtifacts('build/libs/xmlbeans*.jar,build/distributions/*,build/reports/*.bom.*,build/hs_err*.log') archiveArtifacts('build/libs/xmlbeans*.jar,build/distributions/*,build/hs_err*.log')
/* this plugin is currently missing on the Apache Jenkins instance
warnings(['Java Compiler (javac)', 'JavaDoc Tool'], null) { warnings(['Java Compiler (javac)', 'JavaDoc Tool'], null) {
resolveRelativePaths() resolveRelativePaths()
} */ }
archiveJunit('build/test-results/test/TEST-*.xml') { archiveJunit('build/test-results/test/TEST-*.xml') {
testDataPublishers { testDataPublishers {
publishTestStabilityData() publishTestStabilityData()
@ -611,56 +648,59 @@ Unfortunately we often see builds break because of changes/new machines...''')
} }
axes { axes {
jdk( jdk(
'jdk_8_latest', 'jdk_1.8_latest',
'jdk_10_latest',
'jdk_11_latest', 'jdk_11_latest',
/* don't look for JDKs that are out of support
'jdk_12_latest',
'jdk_13_latest',
'jdk_14_latest',
'jdk_15_latest',
'jdk_16_latest',*/
'jdk_17_latest', 'jdk_17_latest',
'jdk_21_latest', 'jdk_18_latest',
'jdk_23_latest', 'adoptopenjdk_hotspot_8u282',
'jdk_24_latest', 'ibmjdk_1.8.0_261'
'jdk_25_latest',
'jdk_26_latest',
'ibm_semeru_21.0.2_13'
) )
// Note H50 is reserved according to its node-description // Note H50 is reserved according to it's node-descripion
label('Nodes','builds22','builds23','builds24','builds25','builds26','builds27','builds28','builds29','builds30','builds31','builds32','builds33','builds34','builds35','builds36','builds37','builds38','builds39','builds40','builds50','builds56','builds57','builds58','builds59','builds60', label('Nodes','H22','H23','H24','H25','H26','H27','H28','H29','H30','H31','H32','H33','H34','H35','H36','H37','H38','H39','H40','H41','H42','H43','H44','H48','lucene1','lucene2','master')
'jenkins-win-azr-1','jenkins-win-azr-2','jenkins-win-azr-3','jenkins-win-azr-4','jenkins-win-azr-5','jenkins-win-azr-6','jenkins-win-azr-7','jenkins-win-azr-8','jenkins-win-azr-10','jenkins-win-azr-11','jenkins-win-azr-12')
} }
steps { steps {
conditionalSteps { conditionalSteps {
condition { condition {
fileExists('/usr', BaseDir.WORKSPACE) fileExists('/usr', BaseDir.WORKSPACE)
} }
runner('DontRun') runner('DontRun')
steps { steps {
shell( shell(
'''which git || true '''which svn || true
which javac which javac
javac -version javac -version
echo '<?xml version="1.0"?><project name="POI Build" default="test"><target name="test"><echo>Using Ant: ${ant.version} from ${ant.home}</echo></target></project>' > build.xml echo '<?xml version="1.0"?><project name="POI Build" default="test"><target name="test"><echo>Using Ant: ${ant.version} from ${ant.home}</echo></target></project>' > build.xml
''') ''')
ant { ant {
antInstallation(defaultAnt) antInstallation(defaultAnt)
} }
shell( shell(
'''which mvn || true '''which mvn || true
mvn -version || true mvn -version || true
echo '<project><modelVersion>4.0.0</modelVersion><groupId>org.apache.poi</groupId><artifactId>build-tst</artifactId><version>1.0.0</version></project>' > pom.xml echo '<project><modelVersion>4.0.0</modelVersion><groupId>org.apache.poi</groupId><artifactId>build-tst</artifactId><version>1.0.0</version></project>' > pom.xml
''') ''')
maven { maven {
goals('package') goals('package')
mavenInstallation(defaultMaven) mavenInstallation(defaultMaven)
} }
} }
} }
conditionalSteps { conditionalSteps {
condition { condition {
fileExists('c:\\windows', BaseDir.WORKSPACE) fileExists('c:\\windows', BaseDir.WORKSPACE)
} }
runner('DontRun') runner('DontRun')
steps { steps {
batchFile( batchFile(
'''@echo off '''@echo off
echo . echo .
where javac.exe where javac.exe
echo . echo .
@ -668,10 +708,71 @@ javac -version
echo . echo .
echo ^<?xml version=^"1.0^"?^>^<project name=^"POI Build^" default=^"test^"^>^<target name=^"test^"^>^<echo^>Using Ant: ${ant.version} from ${ant.home}, ant detected Java ${ant.java.version} (may be different than actual Java sometimes...), using Java: ${java.version}/${java.runtime.version}/${java.vm.version}/${java.vm.name} from ${java.vm.vendor} on ${os.name}: ${os.version}^</echo^>^</target^>^</project^> > build.xml echo ^<?xml version=^"1.0^"?^>^<project name=^"POI Build^" default=^"test^"^>^<target name=^"test^"^>^<echo^>Using Ant: ${ant.version} from ${ant.home}, ant detected Java ${ant.java.version} (may be different than actual Java sometimes...), using Java: ${java.version}/${java.runtime.version}/${java.vm.version}/${java.vm.name} from ${java.vm.vendor} on ${os.name}: ${os.version}^</echo^>^</target^>^</project^> > build.xml
''') ''')
ant { ant {
antInstallation(defaultAntWindows) antInstallation(defaultAntWindows)
} }
} }
} }
} }
} }
/* I tried to put the view into a sub-folder/sub-view, but failed, there are multiple related
plugins so this is all a bit confusing :(, see also https://issues.apache.org/jira/browse/INFRA-14002
dashboardView("P/POI-new") {
columns {
status()
weather()
configureProject()
buildButton()
cronTrigger()
lastBuildConsole()
name()
lastSuccess()
lastFailure()
lastDuration()
//lastSuccessDescription()
jacoco()
}
description("<table>\n" +
" <tr>\n" +
" <td><img src=\"https://poi.apache.org/images/project-header.png\" /></td>\n" +
" <td> \n" +
" <p>Apache POI - the Java API for Microsoft Documents</p>\n" +
" <p><b>Most of the POI Jobs are automatically generated by Jenkins Job DSL\n" +
" at <a href=\"https://svn.apache.org/repos/asf/poi/trunk/jenkins\">https://svn.apache.org/repos/asf/poi/trunk/jenkins</a>,<br/>\n" +
" see <a href=\"https://github.com/jenkinsci/job-dsl-plugin/wiki\">https://github.com/jenkinsci/job-dsl-plugin/wiki</a>\n" +
" for more details about the DSL.</b>\n" +
" </p>\n" +
" <p>\n" +
" <b><a href=\"job/POI-DSL-1.8/lastSuccessfulBuild/findbugsResult/\" target=\"_blank\">Findbugs report of latest build</a></b> -\n" +
" <b><a href=\"https://sonarcloud.io/dashboard?id=poi-parent\" target=\"_blank\">Sonar reports</a></b> -\n" +
" <b><a href=\"job/POI-DSL-1.8/lastSuccessfulBuild/artifact/build/coverage/index.html\" target=\"_blank\">Coverage of latest build</a></b>\n" +
" </p>\n" +
" </td>\n" +
" </tr>\n" +
"</table>")
filterBuildQueue(false)
filterExecutors(false)
// Job selection
jobs {*/
//regex(/.*POI.*/)
/*}
// Layout
topPortlets {
jenkinsJobsList {
displayName('POI jobs')
}
}
leftPortlets {
testStatisticsChart()
}
rightPortlets {
testTrendChart()
}
bottomPortlets {
testStatisticsGrid()
buildStatistics()
}
}*/

View File

@ -222,16 +222,74 @@ Office Open XML schemas (poi-ooxml-full-*.jar)
Furthermore, both Microsoft and Adobe have granted patent licenses Furthermore, both Microsoft and Adobe have granted patent licenses
to this work [3,4,5]. to this work [3,4,5].
[1] https://www.ecma-international.org/publications/standards/Ecma-376.htm [1] http://www.ecma-international.org/publications/standards/Ecma-376.htm
[2] https://www.ecma-international.org/memento/Ecmabylaws.htm [2] http://www.ecma-international.org/memento/Ecmabylaws.htm
[3] https://www.microsoft.com/openspecifications/en/us/programs/osp/default.aspx [3] http://www.microsoft.com/openspecifications/en/us/programs/osp/default.aspx
[4] https://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/ [4] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/
Patent%20statements%20ok/ECMA-376%20Edition%202%20Microsoft%20Patent%20Declaration.pdf Patent%20statements%20ok/ECMA-376%20Edition%202%20Microsoft%20Patent%20Declaration.pdf
[5] https://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/ [5] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/
Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf
org.apache.poi.util.ReplacingInputStream is based on code from Bouncy Castle library (bcprov-*.jar, bcpg-*.jar, bcpkix-*.jar)
Copyright (c) 2000 - 2021 The Legion of the Bouncy Castle Inc.
(https://www.bouncycastle.org)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
CurvesAPI / Curve API
BSD License
Copyright (c) 2000-2015 www.hamcrest.org
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. Redistributions in
binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution. Neither the name of Hamcrest nor
the names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Log4j 2 library (log4j-api-*.jar)
Apache License Version 2.0
inbot-utils (https://github.com/Inbot/inbot-utils) inbot-utils (https://github.com/Inbot/inbot-utils)
The MIT License (MIT) The MIT License (MIT)
@ -254,15 +312,4 @@ inbot-utils (https://github.com/Inbot/inbot-utils)
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
ExceptionUtils is derived from `scala.util.control.NonFatal` in scala-library
which was released under the Apache 2.0 license.
Copyright (c) 2002-2023 EPFL
Copyright (c) 2011-2023 Lightbend, Inc.
The POI Source Release bundles the Gradle Wrapper. (https://docs.gradle.org/current/userguide/gradle_wrapper.html)
This is released under the Apache License, v2.0.
Copyright © 2015-2021 the original authors.
The wrapper.gradle file was developed by the Apache Kafka project and is released under the Apache License, v2.0.

View File

@ -1,5 +1,5 @@
Apache POI Apache POI
Copyright 2003-2026 The Apache Software Foundation Copyright 2003-2021 The Apache Software Foundation
This product includes software developed at This product includes software developed at
The Apache Software Foundation (https://www.apache.org/). The Apache Software Foundation (https://www.apache.org/).
@ -9,8 +9,6 @@ Copyright (c) 2000-2003, BEA Systems, <http://www.bea.com/> (dead link),
which was acquired by Oracle Corporation in 2008. which was acquired by Oracle Corporation in 2008.
<http://www.oracle.com/us/corporate/Acquisitions/bea/index.html> <http://www.oracle.com/us/corporate/Acquisitions/bea/index.html>
<https://en.wikipedia.org/wiki/BEA_Systems> <https://en.wikipedia.org/wiki/BEA_Systems>
Note: The ASF Secretary has on hand a Software Grant Agreement (SGA) from
BEA Systems, Inc. dated 9 Sep 2003 for XMLBeans signed by their EVP/CFO.
This product contains W3C XML Schema documents. Copyright 2001-2003 (c) This product contains W3C XML Schema documents. Copyright 2001-2003 (c)
World Wide Web Consortium (Massachusetts Institute of Technology, European World Wide Web Consortium (Massachusetts Institute of Technology, European
@ -24,13 +22,3 @@ This product contains parts of the eID Applet project
Copyright (c) 2009-2018 Copyright (c) 2009-2018
FedICT (federal ICT department of Belgium), e-Contract.be BVBA (https://www.e-contract.be), FedICT (federal ICT department of Belgium), e-Contract.be BVBA (https://www.e-contract.be),
Bart Hanssens from FedICT Bart Hanssens from FedICT
ExceptionUtils is derived from `scala.util.control.NonFatal` in scala-library
which was released under the Apache 2.0 license.
Copyright (c) 2002-2023 EPFL
Copyright (c) 2011-2023 Lightbend, Inc.
Scala includes software developed at
LAMP/EPFL (https://lamp.epfl.ch/) and
Lightbend, Inc. (https://www.lightbend.com/).

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib.stored/svnant-1.3.1.jar Normal file

Binary file not shown.

View File

@ -21,15 +21,15 @@ The bundle embeds all the jars from lib/main:
Required to render WMF/EMF images. The OSGi bundle is provided by ServiceMix and available in Maven Central: https://mvnrepository.com/artifact/org.apache.servicemix.bundles/org.apache.servicemix.bundles.batik/1.14_1 Required to render WMF/EMF images. The OSGi bundle is provided by ServiceMix and available in Maven Central: https://mvnrepository.com/artifact/org.apache.servicemix.bundles/org.apache.servicemix.bundles.batik/1.14_1
2. Saxon 2. Saxon
Required if using as the XSLT and XQuery Processor engine in XML Beans. Required if using as the XSLT and XQuery Processor engine in XML Beans.
Available in Maven Central: https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE/12.3 Available in Maven Central: https://mvnrepository.com/artifact/net.sf.saxon/saxon/8.9.0.4-osgi
3. Apache XML Security for Java, Bouncy Castle and XML Commons Resolver 3. Apache XML Security for Java, Bouncy Castle and XML Commons Resolver
These are required to sign or validate signed Office documents. The OSGi bundles are available in Maven Central: These are required to sign or validate signed Office documents. The OSGi bundles are available in Maven Central:
- Apache XML Security for Java: https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/3.0.6 - Apache XML Security for Java: https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/2.3.0
- XML Commons Resolver: https://mvnrepository.com/artifact/xml-resolver/xml-resolver/1.2-osgi - XML Commons Resolver: https://mvnrepository.com/artifact/xml-resolver/xml-resolver/1.2-osgi
- Bouncy Castle: https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk18on/1.82, https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk18on/1.82 - Bouncy Castle: https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk15on/1.70, https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on/1.70
4. PDFBox and PDFBox Graphics2D 4. PDFBox and PDFBox Graphics2D
Required to render to PDF documents. Required to render to PDF documents.
The required jars can be downloaded from: The required jars can be downloaded from:

View File

@ -24,13 +24,13 @@
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-bundle</artifactId> <artifactId>poi-bundle</artifactId>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<version>6.0.0-SNAPSHOT</version> <version>5.2.2</version>
<name>Apache POI OSGi bundle</name> <name>Apache POI OSGi bundle</name>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<poi.version>6.0.0-SNAPSHOT</poi.version> <poi.version>5.2.2</poi.version>
<pax.exam.version>4.14.0</pax.exam.version> <pax.exam.version>4.12.0</pax.exam.version>
</properties> </properties>
<build> <build>
@ -39,8 +39,8 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version> <version>3.8.0</version>
<configuration> <configuration>
<source>11</source> <source>1.8</source>
<target>11</target> <target>1.8</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
@ -176,7 +176,7 @@
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<scope>test</scope> <scope>test</scope>
<version>4.13.2</version> <version>4.13.1</version>
</dependency> </dependency>
<!-- Pax Exam --> <!-- Pax Exam -->
@ -231,7 +231,7 @@
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>2.25.3</version> <version>2.17.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -57,7 +57,7 @@ public class OSGiExtractorsIT extends BaseOSGiTestCase {
box.setText("Hello, World!"); box.setText("Hello, World!");
box.setAnchor(new Rectangle(36, 15, 648, 65)); box.setAnchor(new Rectangle(36, 15, 648, 65));
UnsynchronizedByteArrayOutputStream out = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
ppt.write(out); ppt.write(out);
return out.toByteArray(); return out.toByteArray();
} }
@ -66,7 +66,7 @@ public class OSGiExtractorsIT extends BaseOSGiTestCase {
Sheet s = wb.createSheet("OSGi"); Sheet s = wb.createSheet("OSGi");
s.createRow(0).createCell(0).setCellValue("Hello, World!"); s.createRow(0).createCell(0).setCellValue("Hello, World!");
UnsynchronizedByteArrayOutputStream out = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
wb.write(out); wb.write(out);
return out.toByteArray(); return out.toByteArray();

View File

@ -75,7 +75,7 @@ public class OSGiSlideShowIT extends BaseOSGiTestCase {
} }
box2.setAnchor(new Rectangle(36, 80, 648, 400)); box2.setAnchor(new Rectangle(36, 80, 648, 400));
try (UnsynchronizedByteArrayOutputStream baos = UnsynchronizedByteArrayOutputStream.builder().get()) { try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream()) {
ppt.write(baos); ppt.write(baos);
try (InputStream bais = baos.toInputStream()) { try (InputStream bais = baos.toInputStream()) {
ppt = SlideShowFactory.create(bais); ppt = SlideShowFactory.create(bais);

View File

@ -48,7 +48,7 @@ public class OSGiSpreadsheetIT extends BaseOSGiTestCase {
s.createRow(0).createCell(0).setCellValue("With OSGi"); s.createRow(0).createCell(0).setCellValue("With OSGi");
s.createRow(1).createCell(0).setCellFormula("SUM(A1:B3)"); s.createRow(1).createCell(0).setCellFormula("SUM(A1:B3)");
try (UnsynchronizedByteArrayOutputStream baos = UnsynchronizedByteArrayOutputStream.builder().get()) { try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream()) {
wb.write(baos); wb.write(baos);
try (InputStream bais = baos.toInputStream()) { try (InputStream bais = baos.toInputStream()) {
wb = WorkbookFactory.create(bais); wb = WorkbookFactory.create(bais);

View File

@ -19,7 +19,9 @@ import java.util.regex.Pattern
sourceSets { sourceSets {
main { main {
output.dir(JAVA9_OUT, builtBy: 'compileJava9') if (jdkVersion > 8) {
output.dir(JAVA9_OUT, builtBy: 'cacheJava9')
}
} }
} }
@ -35,39 +37,63 @@ dependencies {
implementation project(path: ':poi-scratchpad', configuration: 'archives') implementation project(path: ':poi-scratchpad', configuration: 'archives')
} }
implementation "org.apache.logging.log4j:log4j-api:${log4jVersion}"
testImplementation(project(path: ':poi-ooxml', configuration: 'tests')) { testImplementation(project(path: ':poi-ooxml', configuration: 'tests')) {
if (NO_SCRATCHPAD) { if (NO_SCRATCHPAD) {
exclude group: 'org.apache.poi', module: 'poi-scratchpad' exclude group: 'org.apache.poi', module: 'poi-scratchpad'
} }
} }
testImplementation project(path: ':poi', configuration: 'tests') testImplementation project(path: ':poi', configuration: 'tests')
if (SAXON_TEST) {
testRuntimeOnly "net.sf.saxon:Saxon-HE:${saxonVersion}"
}
} }
final String MODULE_NAME = 'org.apache.poi.examples' final String MODULE_NAME = 'org.apache.poi.examples'
final Pattern MODULE_REGEX = ~'\\.jar$' final Pattern MODULE_REGEX = ~'\\.jar$'
final List MODULE_COMPILE_PATH = sourceSets.main.compileClasspath.findAll{ it.path =~ MODULE_REGEX }.collect{ it.parent }.unique() final List MODULE_COMPILE_PATH = sourceSets.main.compileClasspath.findAll{ it.path =~ MODULE_REGEX }.collect{ it.parent }.unique()
tasks.register('compileJava9', JavaCompile) { task compileJava9(type: JavaCompile) {
dependsOn 'compileJava', ':poi-ooxml:jar', ':poi-scratchpad:jar' dependsOn 'compileJava', ':poi-ooxml:jar', ':poi-scratchpad:jar'
javaCompiler = javaToolchains.compilerFor { javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion)) languageVersion = JavaLanguageVersion.of(jdkVersion)
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
} }
sourceCompatibility = 11
targetCompatibility = 11
destinationDirectory = file(JAVA9_OUT + VERSIONS9) destinationDirectory = file(JAVA9_OUT + VERSIONS9)
source = file(JAVA9_SRC) source = file(JAVA9_SRC)
classpath = files() classpath = files()
options.compilerArgs = [ options.compilerArgs = [
'--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}", '--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}",
'--module-path', files(MODULE_COMPILE_PATH).asPath '--module-path', files(MODULE_COMPILE_PATH).asPath
] ]
onlyIf {
jdkVersion > 8
}
}
task cacheJava9(type: Copy) {
dependsOn 'compileJava9'
from(file(JAVA9_OUT + VERSIONS9))
into(JAVA9_SRC)
} }
jar { jar {
dependsOn compileJava9 dependsOn cacheJava9
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
if (jdkVersion == 8) {
into('META-INF/versions/9') {
from JAVA9_SRC include '*.class'
}
}
manifest { manifest {
attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true') attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true')
@ -87,22 +113,3 @@ sourcesJar {
from("$projectDir/../legal/NOTICE") from("$projectDir/../legal/NOTICE")
} }
} }
cyclonedxBom {
// includeConfigs is the list of configuration names to include when generating the BOM (leave empty to include every configuration)
includeConfigs = ["runtimeClasspath"]
// skipConfigs is a list of configuration names to exclude when generating the BOM
//skipConfigs = ["compileClasspath", "testCompileClasspath"]
// Specified the type of project being built. Defaults to 'library'
projectType = "library"
// Specified the version of the CycloneDX specification to use. Defaults to 1.4.
schemaVersion = "1.4"
// Boms destination directory (defaults to build/reports)
destination = file("build/reports")
// The file name for the generated BOMs (before the file format suffix). Defaults to 'bom'
outputName = "poi-examples-${project.version}.bom"
// The file format generated, can be xml, json or all for generating both
outputFormat = "all"
// Exclude BOM Serial Number
includeBomSerialNumber = true
}

View File

@ -36,7 +36,7 @@ WorkbookFactory.create(f,null,true).withCloseable { workbook ->
def sheet = workbook.getSheetAt(sheetNum) def sheet = workbook.getSheetAt(sheetNum)
sheet.each { row -> sheet.each { row ->
def nonEmptyCells = row.grep { c -> c.getCellType() != CellType.BLANK } def nonEmptyCells = row.grep { c -> c.getCellType() != Cell.CELL_TYPE_BLANK }
println " Row ${row.getRowNum()} has ${nonEmptyCells.size()} non-empty cells:" println " Row ${row.getRowNum()} has ${nonEmptyCells.size()} non-empty cells:"
nonEmptyCells.each { c -> nonEmptyCells.each { c ->
def cRef = [c] as CellReference def cRef = [c] as CellReference
@ -52,7 +52,7 @@ WorkbookFactory.create(f,null,true).withCloseable { workbook ->
ns1.createRow(1).createCell(0).setCellValue("TODO - Populate with data") ns1.createRow(1).createCell(0).setCellValue("TODO - Populate with data")
Sheet ns2 = workbook.createSheet("Generated 2") Sheet ns2 = workbook.createSheet("Generated 2")
exportHeader(ns2, headerStyle, "This is a demo sheet", exportHeader(ns2, headerStyle, "This is a demo sheet",
["ID","Title","Date","Author","Num"] as String[]) ["ID","Title","Date","Author","Num"] as String[])
ns2.createRow(2).createCell(0).setCellValue(1) ns2.createRow(2).createCell(0).setCellValue(1)
ns2.createRow(3).createCell(0).setCellValue(4) ns2.createRow(3).createCell(0).setCellValue(4)

View File

@ -21,11 +21,10 @@ apply plugin: 'groovy'
repositories { repositories {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation 'org.codehaus.groovy:groovy-all:2.4.21' compile 'org.codehaus.groovy:groovy-all:2.4.13'
implementation 'org.apache.poi:poi:5.3.0' compile 'org.apache.poi:poi:5.0.0'
implementation 'org.apache.poi:poi-ooxml:5.3.0' compile 'org.apache.poi:poi-ooxml:5.0.0'
} }
// Our files are in the current directory // Our files are in the current directory
@ -34,11 +33,11 @@ sourceSets {
} }
// Run out read demo by default // Run out read demo by default
tasks.withType(JavaExec).configureEach { tasks.withType(JavaExec) {
classpath = sourceSets.main.runtimeClasspath classpath = sourceSets.main.runtimeClasspath
} }
tasks.register('runScript', JavaExec) { task runScript(type: JavaExec) {
mainClass = "SpreadSheetDemo" main = "SpreadSheetDemo"
args = ["../../../../test-data/spreadsheet/Simple.xls"] args = ["../../../test-data/spreadsheet/Simple.xls"]
} }
defaultTasks 'runScript' defaultTasks 'runScript'

View File

@ -1 +0,0 @@
// empty file required to have a standalone build

View File

@ -21,7 +21,7 @@ package org.apache.poi.examples.crypt;
import java.io.File; import java.io.File;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Optional; import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -72,7 +72,7 @@ public final class OOXMLPasswordsTry {
}; };
// Try each password in turn, reporting progress // Try each password in turn, reporting progress
try (Stream<String> lines = Files.lines(Path.of(words))) { try (Stream<String> lines = Files.lines(Paths.get(words))) {
Optional<String> found = lines.filter(counter).filter(w -> isValid(d, w)).findFirst(); Optional<String> found = lines.filter(counter).filter(w -> isValid(d, w)).findFirst();
System.out.println(found.map(s -> "Password found: " + s).orElse("Error - No password matched")); System.out.println(found.map(s -> "Password found: " + s).orElse("Error - No password matched"));
} }

View File

@ -174,8 +174,8 @@ public final class CopyCompare {
for (int i=0; i<path.length(); i++) { for (int i=0; i<path.length(); i++) {
String subDir = path.getComponent(i); String subDir = path.getComponent(i);
if (de.hasEntryCaseInsensitive(subDir)) { if (de.hasEntry(subDir)) {
de = (DirectoryEntry)de.getEntryCaseInsensitive(subDir); de = (DirectoryEntry)de.getEntry(subDir);
} else { } else {
de = de.createDirectory(subDir); de = de.createDirectory(subDir);
if (i == path.length()-1) { if (i == path.length()-1) {

View File

@ -158,7 +158,7 @@ public final class WriteAuthorAndTitle {
for (int i=0; i<path.length(); i++) { for (int i=0; i<path.length(); i++) {
String subDir = path.getComponent(i); String subDir = path.getComponent(i);
de = (de.hasEntryCaseInsensitive(subDir)) ? (DirectoryEntry)de.getEntryCaseInsensitive(subDir) : de.createDirectory(subDir); de = (de.hasEntry(subDir)) ? (DirectoryEntry)de.getEntry(subDir) : de.createDirectory(subDir);
} }
de.createDocument(event.getName(), is); de.createDocument(event.getName(), is);

View File

@ -22,7 +22,6 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import org.apache.poi.hsmf.MAPIMessage; import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks; import org.apache.poi.hsmf.datatypes.AttachmentChunks;
@ -63,7 +62,7 @@ public class Msg2txt {
public void processMessage() throws IOException { public void processMessage() throws IOException {
String txtFileName = fileNameStem + ".txt"; String txtFileName = fileNameStem + ".txt";
String attDirName = fileNameStem + "-att"; String attDirName = fileNameStem + "-att";
try (PrintWriter txtOut = new PrintWriter(txtFileName, StandardCharsets.UTF_8.name())) { try (PrintWriter txtOut = new PrintWriter(txtFileName, "UTF-8")) {
try { try {
String displayFrom = msg.getDisplayFrom(); String displayFrom = msg.getDisplayFrom();
txtOut.println("From: " + displayFrom); txtOut.println("From: " + displayFrom);
@ -142,7 +141,7 @@ public class Msg2txt {
* @param args the list of MSG files to process * @param args the list of MSG files to process
*/ */
public static void main(String[] args) { public static void main(String[] args) {
if(args.length == 0) { if(args.length <= 0) {
System.err.println("No files names provided"); System.err.println("No files names provided");
} else { } else {
for (String arg : args) { for (String arg : args) {

View File

@ -253,10 +253,6 @@ public class XLS2CSVmra implements HSSFListener {
// Format // Format
thisStr = formatListener.formatNumberDateCell(numrec); thisStr = formatListener.formatNumberDateCell(numrec);
if (thisStr.contains(",")) {
thisStr = '"' + thisStr + '"';
}
break; break;
case RKRecord.sid: case RKRecord.sid:
RKRecord rkrec = (RKRecord) record; RKRecord rkrec = (RKRecord) record;

View File

@ -16,21 +16,15 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.ss.usermodel; package org.apache.poi.examples.hssf.usermodel;
import org.apache.poi.util.Removal;
/** /**
* The CellPropertyCategory enum represents the different categories of cell properties. * Placeholder Class - this is now handled in the Common SS example
* Each category is used to classify and organize the cell properties based on their characteristics. * @deprecated in 5.1.0 - use {@link org.apache.poi.examples.ss.AddDimensionedImage}
*
* @since 5.4.0
*/ */
public enum CellPropertyCategory { @Removal(version="6.0.0")
@Deprecated
SHORT, public class AddDimensionedImage extends org.apache.poi.examples.ss.AddDimensionedImage {
COLOR, }
INT,
BOOL,
BORDER_TYPE,
OTHER
}

View File

@ -75,7 +75,7 @@ public class EventExample implements HSSFListener {
System.out.println("Cell found with value " + numrec.getValue() System.out.println("Cell found with value " + numrec.getValue()
+ " at row " + numrec.getRow() + " and column " + numrec.getColumn()); + " at row " + numrec.getRow() + " and column " + numrec.getColumn());
break; break;
// SSTRecords store an array of unique strings used in Excel. // SSTRecords store a array of unique strings used in Excel.
case SSTRecord.sid: case SSTRecord.sid:
sstrec = (SSTRecord) record; sstrec = (SSTRecord) record;
for (int k = 0; k < sstrec.getNumUniqueStrings(); k++) for (int k = 0; k < sstrec.getNumUniqueStrings(); k++)

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFCellStyle;
@ -31,7 +32,6 @@ import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.logging.PoiLogManager;
/** /**
* This class contains code that demonstrates how to insert plain, numbered * This class contains code that demonstrates how to insert plain, numbered
@ -50,7 +50,7 @@ import org.apache.poi.logging.PoiLogManager;
*/ */
@SuppressWarnings({"java:S106","java:S4823"}) @SuppressWarnings({"java:S106","java:S4823"})
public class InCellLists { public class InCellLists {
private static final Logger LOG = PoiLogManager.getLogger(InCellLists.class); private static final Logger LOG = LogManager.getLogger(InCellLists.class);
// This character looks like a solid, black, loser case letter 'o' // This character looks like a solid, black, loser case letter 'o'
@ -190,7 +190,7 @@ public class InCellLists {
String formatString = InCellLists.BULLET_CHARACTER + " @"; String formatString = InCellLists.BULLET_CHARACTER + " @";
int formatIndex = format.getFormat(formatString); int formatIndex = format.getFormat(formatString);
// Construct an HSSFCellStyle and set its data format to use the // Construct an HSSFCellStyle and set it's data formt to use the
// object created above. // object created above.
HSSFCellStyle bulletStyle = workbook.createCellStyle(); HSSFCellStyle bulletStyle = workbook.createCellStyle();
bulletStyle.setDataFormat((short)formatIndex); bulletStyle.setDataFormat((short)formatIndex);
@ -248,8 +248,8 @@ public class InCellLists {
int increment) { int increment) {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
int itemNumber = startingValue; int itemNumber = startingValue;
// Note that again, an HSSFCellStyle object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Note that the basic method is identical to the listInCell() method // Note that the basic method is identical to the listInCell() method
@ -282,7 +282,7 @@ public class InCellLists {
HSSFCell cell) { HSSFCell cell) {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
// Note that again, an HSSFCellStye object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Note that the basic method is identical to the listInCell() method // Note that the basic method is identical to the listInCell() method
@ -318,7 +318,7 @@ public class InCellLists {
HSSFCell cell) { HSSFCell cell) {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
// Note that again, an HSSFCellStye object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Step through the ArrayList of MultilLevelListItem instances. // Step through the ArrayList of MultilLevelListItem instances.
@ -381,7 +381,7 @@ public class InCellLists {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
int highLevelItemNumber = highLevelStartingValue; int highLevelItemNumber = highLevelStartingValue;
// Note that again, an HSSFCellStye object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Step through the ArrayList of MultilLevelListItem instances. // Step through the ArrayList of MultilLevelListItem instances.
@ -436,7 +436,7 @@ public class InCellLists {
HSSFCell cell) { HSSFCell cell) {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
// Note that again, an HSSFCellStye object is required and that // Note that again, an HSSFCellStye object is required and that
// its wrap text property should be set to 'true' // it's wrap text property should be set to 'true'
HSSFCellStyle wrapStyle = workbook.createCellStyle(); HSSFCellStyle wrapStyle = workbook.createCellStyle();
wrapStyle.setWrapText(true); wrapStyle.setWrapText(true);
// Step through the ArrayList of MultilLevelListItem instances. // Step through the ArrayList of MultilLevelListItem instances.

View File

@ -192,7 +192,7 @@ public final class OfficeDrawing {
private static int loadPicture( String path, HSSFWorkbook wb ) throws IOException { private static int loadPicture( String path, HSSFWorkbook wb ) throws IOException {
int pictureIndex; int pictureIndex;
try (FileInputStream fis = new FileInputStream(path); try (FileInputStream fis = new FileInputStream(path);
UnsynchronizedByteArrayOutputStream bos = UnsynchronizedByteArrayOutputStream.builder().get()) { UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) {
IOUtils.copy(fis, bos); IOUtils.copy(fis, bos);
pictureIndex = wb.addPicture(bos.toByteArray(), Workbook.PICTURE_TYPE_PNG); pictureIndex = wb.addPicture(bos.toByteArray(), Workbook.PICTURE_TYPE_PNG);
} }

View File

@ -22,12 +22,12 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.logging.PoiLogManager;
/** /**
* Creates outlines. * Creates outlines.
@ -35,7 +35,7 @@ import org.apache.poi.logging.PoiLogManager;
public class Outlines implements Closeable { public class Outlines implements Closeable {
public static void main(String[] args) public static void main(String[] args)
throws IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { throws IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Logger LOGGER = PoiLogManager.getLogger(Outlines.class); Logger LOGGER = LogManager.getLogger(Outlines.class);
for (int i=1; i<=13; i++) { for (int i=1; i<=13; i++) {
try (Outlines o = new Outlines()) { try (Outlines o = new Outlines()) {
String log = (String) Outlines.class.getDeclaredMethod("test" + i).invoke(o); String log = (String) Outlines.class.getDeclaredMethod("test" + i).invoke(o);

View File

@ -51,7 +51,7 @@ public class RepeatingRowsAndColumns {
sheet1.setRepeatingColumns(CellRangeAddress.valueOf("A:C")); sheet1.setRepeatingColumns(CellRangeAddress.valueOf("A:C"));
// Set the rows to repeat from row 0 to 2 on the second sheet. // Set the rows to repeat from row 0 to 2 on the second sheet.
sheet2.setRepeatingRows(CellRangeAddress.valueOf("1:3")); sheet2.setRepeatingRows(CellRangeAddress.valueOf("1:3"));
// Set the repeating rows and columns on the third sheet. // Set the the repeating rows and columns on the third sheet.
CellRangeAddress cra = CellRangeAddress.valueOf("D1:E2"); CellRangeAddress cra = CellRangeAddress.valueOf("D1:E2");
sheet3.setRepeatingColumns(cra); sheet3.setRepeatingColumns(cra);
sheet3.setRepeatingRows(cra); sheet3.setRepeatingRows(cra);

View File

@ -24,7 +24,6 @@ import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.PaneType;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
public class SplitAndFreezePanes { public class SplitAndFreezePanes {
@ -42,7 +41,7 @@ public class SplitAndFreezePanes {
// Freeze the columns and rows (forget about scrolling position of the lower right quadrant). // Freeze the columns and rows (forget about scrolling position of the lower right quadrant).
sheet3.createFreezePane(2, 2); sheet3.createFreezePane(2, 2);
// Create a split with the lower left side being the active quadrant // Create a split with the lower left side being the active quadrant
sheet4.createSplitPane(2000, 2000, 0, 0, PaneType.LOWER_LEFT); sheet4.createSplitPane(2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT);
try (FileOutputStream fileOut = new FileOutputStream("workbook.xls")) { try (FileOutputStream fileOut = new FileOutputStream("workbook.xls")) {
wb.write(fileOut); wb.write(fileOut);

View File

@ -59,7 +59,7 @@ public final class Word2Forrest
{ {
Paragraph p = r.getParagraph (x); Paragraph p = r.getParagraph (x);
String text = p.text (); String text = p.text ();
if (text.trim().isEmpty()) if (text.trim ().length () == 0)
{ {
continue; continue;
} }

View File

@ -116,7 +116,7 @@ import java.util.Locale;
* <p> * <p>
* The following example demonstrates a slightly different way to insert an * The following example demonstrates a slightly different way to insert an
* image into cell A1 and to ensure that it occupies the whole of the cell. This * image into cell A1 and to ensure that it occupies the whole of the cell. This
* is accomplished by specifying the images bottom right hand corner should be * is accomplished by specifying the the images bottom right hand corner should be
* aligned with the bottom right hand corner of the cell. It is also a case * aligned with the bottom right hand corner of the cell. It is also a case
* where the image will not increase in size if the user increases the size of * where the image will not increase in size if the user increases the size of
* the enclosing cell - irrespective of the anchors type - but it will reduce in * the enclosing cell - irrespective of the anchors type - but it will reduce in
@ -135,7 +135,7 @@ import java.util.Locale;
* <p> * <p>
* Note that the final four method calls all pass the same value and seem to * Note that the final four method calls all pass the same value and seem to
* indicate that the images top left hand corner is aligned with the top left * indicate that the images top left hand corner is aligned with the top left
* hand corner of cell A1 and that its bottom right hand corner is also * hand corner of cell A1 and that it's bottom right hand corner is also
* aligned with the top left hand corner of cell A1. Yet, running this code * aligned with the top left hand corner of cell A1. Yet, running this code
* would see the image fully occupying cell A1. That is the result of the * would see the image fully occupying cell A1. That is the result of the
* values passed to parameters three and four; these I have referred to as * values passed to parameters three and four; these I have referred to as
@ -182,7 +182,7 @@ import java.util.Locale;
* *
* @version 1.00 5th August 2009. * @version 1.00 5th August 2009.
* 2.00 26th February 2010. * 2.00 26th February 2010.
* Ported to make use of the SS usermodel classes. * Ported to make use of the the SS usermodel classes.
* Ability to reuse the Drawing Patriarch so that multiple images * Ability to reuse the Drawing Patriarch so that multiple images
* can be inserted without unintentionally erasing earlier images. * can be inserted without unintentionally erasing earlier images.
* Check on image type added; i.e. jpg, jpeg or png. * Check on image type added; i.e. jpg, jpeg or png.
@ -406,7 +406,7 @@ public class AddDimensionedImage {
* the image, adjusts the columns width if necessary and creates then * the image, adjusts the columns width if necessary and creates then
* returns a ClientAnchorDetail object that facilitates construction of * returns a ClientAnchorDetail object that facilitates construction of
* an ClientAnchor that will fix the image on the sheet and establish * an ClientAnchor that will fix the image on the sheet and establish
* its size. * it's size.
* *
* @param sheet A reference to the sheet that will 'contain' the image. * @param sheet A reference to the sheet that will 'contain' the image.
* @param colNumber A primitive int that contains the index number of a * @param colNumber A primitive int that contains the index number of a
@ -483,7 +483,7 @@ public class AddDimensionedImage {
// Mow many co-ordinate positions are there per millimetre? // Mow many co-ordinate positions are there per millimetre?
colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
colWidthMM; colWidthMM;
// Given the width of the image, what should be its co-ordinate? // Given the width of the image, what should be it's co-ordinate?
pictureWidthCoordinates = (int) (reqImageWidthMM * colCoordinatesPerMM); pictureWidthCoordinates = (int) (reqImageWidthMM * colCoordinatesPerMM);
} else { } else {
pictureWidthCoordinates = (int) reqImageWidthMM * pictureWidthCoordinates = (int) reqImageWidthMM *
@ -500,7 +500,7 @@ public class AddDimensionedImage {
* the image, adjusts the rows height if necessary and creates then * the image, adjusts the rows height if necessary and creates then
* returns a ClientAnchorDetail object that facilitates construction of * returns a ClientAnchorDetail object that facilitates construction of
* a ClientAnchor that will fix the image on the sheet and establish * a ClientAnchor that will fix the image on the sheet and establish
* its size. * it's size.
* *
* @param sheet A reference to the sheet that will 'contain' the image. * @param sheet A reference to the sheet that will 'contain' the image.
* @param rowNumber A primitive int that contains the index number of a * @param rowNumber A primitive int that contains the index number of a
@ -528,7 +528,7 @@ public class AddDimensionedImage {
int pictureHeightCoordinates; int pictureHeightCoordinates;
ClientAnchorDetail rowClientAnchorDetail = null; ClientAnchorDetail rowClientAnchorDetail = null;
// Get the row and its height // Get the row and it's height
row = sheet.getRow(rowNumber); row = sheet.getRow(rowNumber);
if (row == null) { if (row == null) {
// Create row if it does not exist. // Create row if it does not exist.
@ -624,7 +624,7 @@ public class AddDimensionedImage {
colWidthMM = ConvertImageUnits.widthUnits2Millimetres( colWidthMM = ConvertImageUnits.widthUnits2Millimetres(
(short) (sheet.getColumnWidth(toColumn))); (short) (sheet.getColumnWidth(toColumn)));
// Note use of the cell border width constant. Testing with an image // Note use of the cell border width constant. Testing with an image
// declared to fit exactly into one column demonstrated that its // declared to fit exactly into one column demonstrated that it's
// width was greater than the width of the column the POI returned. // width was greater than the width of the column the POI returned.
// Further, this difference was a constant value that I am assuming // Further, this difference was a constant value that I am assuming
// related to the cell's borders. Either way, that difference needs // related to the cell's borders. Either way, that difference needs
@ -632,7 +632,7 @@ public class AddDimensionedImage {
totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES); totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES);
toColumn++; toColumn++;
} }
// De-rement by one the last column value. // De-crement by one the last column value.
toColumn--; toColumn--;
// Highly unlikely that this will be true but, if the width of a series // Highly unlikely that this will be true but, if the width of a series
// of columns is exactly equal to the required width of the image, then // of columns is exactly equal to the required width of the image, then
@ -949,10 +949,10 @@ public class AddDimensionedImage {
* pixel units to excel width units(units of 1/256th of a character width) * pixel units to excel width units(units of 1/256th of a character width)
*/ */
public static short pixel2WidthUnits(int pxs) { public static short pixel2WidthUnits(int pxs) {
int widthUnits = (EXCEL_COLUMN_WIDTH_FACTOR * short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR *
(pxs / UNIT_OFFSET_LENGTH)); (pxs / UNIT_OFFSET_LENGTH));
widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)]; widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)];
return (short) widthUnits; return widthUnits;
} }
/** /**

View File

@ -19,10 +19,8 @@
package org.apache.poi.examples.ss; package org.apache.poi.examples.ss;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List; import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@ -95,7 +93,7 @@ public final class ConditionalFormats {
if (wb instanceof XSSFWorkbook) { if (wb instanceof XSSFWorkbook) {
file += "x"; file += "x";
} }
try (OutputStream out = Files.newOutputStream(Path.of(file))) { try (FileOutputStream out = new FileOutputStream(file)) {
wb.write(out); wb.write(out);
} }
System.out.println("Generated: " + file); System.out.println("Generated: " + file);
@ -203,7 +201,7 @@ public final class ConditionalFormats {
if (rn%10 == 0) { if (rn%10 == 0) {
str = str + "x10 "; str = str + "x10 ";
} }
if (str.isEmpty()) { if (str.length() == 0) {
str = "nothing special..."; str = "nothing special...";
} }
r.createCell(1).setCellValue("It is " + str); r.createCell(1).setCellValue("It is " + str);
@ -287,7 +285,7 @@ public final class ConditionalFormats {
/** /**
* Use Excel conditional formatting to hide the duplicate values, * Use Excel conditional formatting to hide the duplicate values,
* and make the list easier to read. In this example, when the table is sorted by Region, * and make the list easier to read. In this example, when the table is sorted by Region,
* the second (and subsequent) occurrences of each region name will have white font colour. * the second (and subsequent) occurences of each region name will have white font colour.
*/ */
static void hideDupplicates(Sheet sheet) { static void hideDupplicates(Sheet sheet) {
sheet.createRow(0).createCell(0).setCellValue("City"); sheet.createRow(0).createCell(0).setCellValue("City");
@ -311,7 +309,7 @@ public final class ConditionalFormats {
sheetCF.addConditionalFormatting(regions, rule1); sheetCF.addConditionalFormatting(regions, rule1);
sheet.getRow(1).createCell(1).setCellValue("<== the second (and subsequent) " + sheet.getRow(1).createCell(1).setCellValue("<== the second (and subsequent) " +
"occurrences of each region name will have white font colour. " + "occurences of each region name will have white font colour. " +
"Condition: Formula Is =A2=A1 (White Font)"); "Condition: Formula Is =A2=A1 (White Font)");
} }

View File

@ -77,7 +77,7 @@ public class LinkedDropDownLists {
LinkedDropDownLists.buildDataSheet(sheet); LinkedDropDownLists.buildDataSheet(sheet);
// Build the first data validation to occupy cell A1. Note // Build the first data validation to occupy cell A1. Note
// that it retrieves its data from the named area or region called // that it retrieves it's data from the named area or region called
// CHOICES. Further information about this can be found in the // CHOICES. Further information about this can be found in the
// static buildDataSheet() method below. // static buildDataSheet() method below.
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0); CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);

View File

@ -68,96 +68,79 @@ public final class LoadEmbedded {
for (HSSFObjectData obj : workbook.getAllEmbeddedObjects()) { for (HSSFObjectData obj : workbook.getAllEmbeddedObjects()) {
//the OLE2 Class Name of the object //the OLE2 Class Name of the object
String oleName = obj.getOLE2ClassName(); String oleName = obj.getOLE2ClassName();
switch (oleName) { if (oleName.equals("Worksheet")) {
case "Worksheet": { DirectoryNode dn = (DirectoryNode) obj.getDirectory();
HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(dn, false);
embeddedWorkbook.close();
} else if (oleName.equals("Document")) {
DirectoryNode dn = (DirectoryNode) obj.getDirectory();
HWPFDocument embeddedWordDocument = new HWPFDocument(dn);
embeddedWordDocument.close();
} else if (oleName.equals("Presentation")) {
DirectoryNode dn = (DirectoryNode) obj.getDirectory();
SlideShow<?,?> embeddedSlieShow = new HSLFSlideShow(dn);
embeddedSlieShow.close();
} else {
if(obj.hasDirectoryEntry()){
// The DirectoryEntry is a DocumentNode. Examine its entries to find out what it is
DirectoryNode dn = (DirectoryNode) obj.getDirectory(); DirectoryNode dn = (DirectoryNode) obj.getDirectory();
HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(dn, false); for (Entry entry : dn) {
embeddedWorkbook.close(); //System.out.println(oleName + "." + entry.getName());
break;
}
case "Document": {
DirectoryNode dn = (DirectoryNode) obj.getDirectory();
HWPFDocument embeddedWordDocument = new HWPFDocument(dn);
embeddedWordDocument.close();
break;
}
case "Presentation": {
DirectoryNode dn = (DirectoryNode) obj.getDirectory();
SlideShow<?, ?> embeddedSlieShow = new HSLFSlideShow(dn);
embeddedSlieShow.close();
break;
}
default:
if (obj.hasDirectoryEntry()) {
// The DirectoryEntry is a DocumentNode. Examine its entries to find out what it is
DirectoryNode dn = (DirectoryNode) obj.getDirectory();
for (Entry entry : dn) {
//System.out.println(oleName + "." + entry.getName());
}
} else {
// There is no DirectoryEntry
// Recover the object's data from the HSSFObjectData instance.
byte[] objectData = obj.getObjectData();
} }
break; } else {
// There is no DirectoryEntry
// Recover the object's data from the HSSFObjectData instance.
byte[] objectData = obj.getObjectData();
}
} }
} }
} }
public static void loadEmbedded(XSSFWorkbook workbook) throws IOException, InvalidFormatException, public static void loadEmbedded(XSSFWorkbook workbook) throws IOException, InvalidFormatException, OpenXML4JException, XmlException {
OpenXML4JException, XmlException {
for (PackagePart pPart : workbook.getAllEmbeddedParts()) { for (PackagePart pPart : workbook.getAllEmbeddedParts()) {
String contentType = pPart.getContentType(); String contentType = pPart.getContentType();
switch (contentType) { if (contentType.equals("application/vnd.ms-excel")) {
case "application/vnd.ms-excel": // Excel Workbook - either binary or OpenXML
// Excel Workbook - either binary or OpenXML try (InputStream stream = pPart.getInputStream()) {
try (InputStream stream = pPart.getInputStream()) { HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(stream);
HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(stream); embeddedWorkbook.close();
embeddedWorkbook.close(); }
} } else if (contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
break; // Excel Workbook - OpenXML file format
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": try (InputStream stream = pPart.getInputStream()) {
// Excel Workbook - OpenXML file format XSSFWorkbook embeddedWorkbook = new XSSFWorkbook(stream);
try (InputStream stream = pPart.getInputStream()) { embeddedWorkbook.close();
XSSFWorkbook embeddedWorkbook = new XSSFWorkbook(stream); }
embeddedWorkbook.close(); } else if (contentType.equals("application/msword")) {
} // Word Document - binary (OLE2CDF) file format
break; try (InputStream stream = pPart.getInputStream()) {
case "application/msword": HWPFDocument document = new HWPFDocument(stream);
// Word Document - binary (OLE2CDF) file format document.close();
try (InputStream stream = pPart.getInputStream()) { }
HWPFDocument document = new HWPFDocument(stream); } else if (contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) {
document.close(); // Word Document - OpenXML file format
} try (InputStream stream = pPart.getInputStream()) {
break; XWPFDocument document = new XWPFDocument(stream);
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": document.close();
// Word Document - OpenXML file format }
try (InputStream stream = pPart.getInputStream()) { } else if (contentType.equals("application/vnd.ms-powerpoint")) {
XWPFDocument document = new XWPFDocument(stream); // PowerPoint Document - binary file format
document.close(); try (InputStream stream = pPart.getInputStream()) {
} HSLFSlideShow slideShow = new HSLFSlideShow(stream);
break; slideShow.close();
case "application/vnd.ms-powerpoint": }
// PowerPoint Document - binary file format } else if (contentType.equals("application/vnd.openxmlformats-officedocument.presentationml.presentation")) {
try (InputStream stream = pPart.getInputStream()) { // PowerPoint Document - OpenXML file format
HSLFSlideShow slideShow = new HSLFSlideShow(stream); try (InputStream stream = pPart.getInputStream()) {
slideShow.close(); XMLSlideShow slideShow = new XMLSlideShow(stream);
} slideShow.close();
break; }
case "application/vnd.openxmlformats-officedocument.presentationml.presentation": } else {
// PowerPoint Document - OpenXML file format // Any other type of embedded object.
try (InputStream stream = pPart.getInputStream()) { System.out.println("Unknown Embedded Document: " + contentType);
XMLSlideShow slideShow = new XMLSlideShow(stream); try (InputStream inputStream = pPart.getInputStream()) {
slideShow.close();
}
break;
default:
// Any other type of embedded object.
System.out.println("Unknown Embedded Document: " + contentType);
try (InputStream inputStream = pPart.getInputStream()) {
} }
break;
} }
} }
} }

View File

@ -70,25 +70,21 @@ public final class SSPerformanceTest {
if(warmup) { if(warmup) {
System.out.println("Performing a warmup run first"); System.out.println("Performing a warmup run first");
runWithArgs(type, rows, cols, saveFile, System.currentTimeMillis()); runWithArgs(type, rows, cols, saveFile);
} }
System.out.println("Performing test-run");
long timeStarted = System.currentTimeMillis(); long timeStarted = System.currentTimeMillis();
runWithArgs(type, rows, cols, saveFile, timeStarted); runWithArgs(type, rows, cols, saveFile);
long timeFinished = System.currentTimeMillis(); long timeFinished = System.currentTimeMillis();
System.out.printf(Locale.ROOT, "Elapsed %.2f seconds for arguments %s%n", ((double)timeFinished - timeStarted) / 1000, Arrays.toString(args)); System.out.printf(Locale.ROOT, "Elapsed %.2f seconds for arguments %s%n", ((double)timeFinished - timeStarted) / 1000, Arrays.toString(args));
} }
private static void runWithArgs(String type, int rows, int cols, boolean saveFile, long timeStarted) throws IOException { private static void runWithArgs(String type, int rows, int cols, boolean saveFile) throws IOException {
try (Workbook workBook = createWorkbook(type)) { try (Workbook workBook = createWorkbook(type)) {
boolean isHType = workBook instanceof HSSFWorkbook; boolean isHType = workBook instanceof HSSFWorkbook;
addContent(workBook, isHType, rows, cols); addContent(workBook, isHType, rows, cols);
long timeFinished = System.currentTimeMillis();
System.out.printf(Locale.ROOT, "Elapsed %.2f seconds before save%n", ((double)timeFinished - timeStarted) / 1000);
if (saveFile) { if (saveFile) {
String fileName = type + "_" + rows + "_" + cols + "." + getFileSuffix(type); String fileName = type + "_" + rows + "_" + cols + "." + getFileSuffix(type);
saveFile(workBook, fileName); saveFile(workBook, fileName);

View File

@ -28,8 +28,8 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList; import java.util.ArrayList;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.logging.PoiLogManager;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.DataFormatter;
@ -134,7 +134,7 @@ import org.apache.poi.ss.usermodel.WorkbookFactory;
*/ */
@SuppressWarnings({"java:S106","java:S4823","java:S1192"}) @SuppressWarnings({"java:S106","java:S4823","java:S1192"})
public class ToCSV { public class ToCSV {
private static final Logger LOG = PoiLogManager.getLogger(ToCSV.class); private static final Logger LOG = LogManager.getLogger(ToCSV.class);
private Workbook workbook; private Workbook workbook;
private ArrayList<ArrayList<String>> csvData; private ArrayList<ArrayList<String>> csvData;
@ -327,7 +327,7 @@ public class ToCSV {
} }
// Step through each of the files in the source folder and for each // Step through each of the files in the source folder and for each
// open the workbook, convert its contents to CSV format and then // open the workbook, convert it's contents to CSV format and then
// save the resulting file away into the folder specified by the // save the resulting file away into the folder specified by the
// contents of the destination variable. Note that the name of the // contents of the destination variable. Note that the name of the
// csv file will be created by taking the name of the Excel file, // csv file will be created by taking the name of the Excel file,
@ -342,7 +342,7 @@ public class ToCSV {
// Open the workbook // Open the workbook
this.openWorkbook(excelFile); this.openWorkbook(excelFile);
// Convert its contents into a CSV file // Convert it's contents into a CSV file
this.convertToCSV(); this.convertToCSV();
// Build the name of the csv folder from that of the Excel workbook. // Build the name of the csv folder from that of the Excel workbook.
@ -451,7 +451,7 @@ public class ToCSV {
// from this 'row' ArrayList one at a time and to write the Strings // from this 'row' ArrayList one at a time and to write the Strings
// away to a StringBuilder thus assembling a single line for inclusion // away to a StringBuilder thus assembling a single line for inclusion
// in the CSV file. If a row was empty or if it was short, then // in the CSV file. If a row was empty or if it was short, then
// the ArrayList that contains its data will also be shorter than // the ArrayList that contains it's data will also be shorter than
// some of the others. Therefore, it is necessary to check within // some of the others. Therefore, it is necessary to check within
// the for loop to ensure that the ArrayList contains data to be // the for loop to ensure that the ArrayList contains data to be
// processed. If it does, then an element will be recovered and // processed. If it does, then an element will be recovered and
@ -689,7 +689,7 @@ public class ToCSV {
// It is not wise to have such a wide catch clause - Exception is very // It is not wise to have such a wide catch clause - Exception is very
// close to being at the top of the inheritance hierarchy - though it // close to being at the top of the inheritance hierarchy - though it
// will suffice for this example as it is really not possible to recover // will suffice for this example as it is really not possible to recover
// easily from an exceptional set of circumstances at this point in the // easilly from an exceptional set of circumstances at this point in the
// program. It should however, ideally be replaced with one or more // program. It should however, ideally be replaced with one or more
// catch clauses optimised to handle more specific problems. // catch clauses optimised to handle more specific problems.
catch(Exception ex) { catch(Exception ex) {

View File

@ -25,7 +25,9 @@ import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.functions.FreeRefFunction; import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.apache.poi.ss.formula.udf.UDFFinder; import org.apache.poi.ss.formula.udf.UDFFinder;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
@ -51,7 +53,12 @@ public class SettingExternalFunction {
// dummy function that returns NA // dummy function that returns NA
// don't care about the implementation, we are not interested in evaluation // don't care about the implementation, we are not interested in evaluation
// and this method will never be called // and this method will never be called
FreeRefFunction NA = (args, ec) -> ErrorEval.NA; FreeRefFunction NA = new FreeRefFunction() {
@Override
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
return ErrorEval.NA;
}
};
_functionsByName = new HashMap<>(); _functionsByName = new HashMap<>();
_functionsByName.put("BDP", NA); _functionsByName.put("BDP", NA);
_functionsByName.put("BDH", NA); _functionsByName.put("BDH", NA);

View File

@ -190,7 +190,7 @@ public final class ToHtml {
return; return;
} }
try (PrintWriter pw = new PrintWriter(args[1], StandardCharsets.UTF_8.name())) { try (PrintWriter pw = new PrintWriter(args[1], "UTF-8")) {
ToHtml toHtml = create(args[0], pw); ToHtml toHtml = create(args[0], pw);
toHtml.setCompleteHTML(true); toHtml.setCompleteHTML(true);
toHtml.printPage(); toHtml.printPage();
@ -320,7 +320,7 @@ public final class ToHtml {
private String styleName(CellStyle style) { private String styleName(CellStyle style) {
if (style == null) { if (style == null) {
style = wb.getCellStyleAt(0); style = wb.getCellStyleAt((short) 0);
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
try (Formatter fmt = new Formatter(sb, Locale.ROOT)) { try (Formatter fmt = new Formatter(sb, Locale.ROOT)) {

View File

@ -19,11 +19,9 @@
package org.apache.poi.examples.util; package org.apache.poi.examples.util;
import org.apache.poi.util.DefaultTempFileCreationStrategy;
import org.apache.poi.util.TempFile;
import java.io.File; import java.io.File;
import java.nio.file.Path;
import org.apache.poi.util.TempFile;
public final class TempFileUtils { public final class TempFileUtils {
private TempFileUtils() { private TempFileUtils() {
@ -31,7 +29,8 @@ public final class TempFileUtils {
@SuppressWarnings("java:S106") @SuppressWarnings("java:S106")
public static void checkTempFiles() { public static void checkTempFiles() {
File tempDir = Path.of(System.getProperty(TempFile.JAVA_IO_TMPDIR), DefaultTempFileCreationStrategy.POIFILES).toFile(); String tmpDir = System.getProperty(TempFile.JAVA_IO_TMPDIR) + "/poifiles";
File tempDir = new File(tmpDir);
if(tempDir.exists()) { if(tempDir.exists()) {
String[] tempFiles = tempDir.list(); String[] tempFiles = tempDir.list();
if(tempFiles != null && tempFiles.length > 0) { if(tempFiles != null && tempFiles.length > 0) {

View File

@ -1,251 +1,253 @@
/* /*
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* ==================================================================== * ====================================================================
*/ */
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.sl.usermodel.PictureData.PictureType; import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink; import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
import org.openxmlformats.schemas.presentationml.x2006.main.CTExtension; import org.openxmlformats.schemas.presentationml.x2006.main.CTExtension;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonMediaNodeData; import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonMediaNodeData;
import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonTimeNodeData; import org.openxmlformats.schemas.presentationml.x2006.main.CTTLCommonTimeNodeData;
import org.openxmlformats.schemas.presentationml.x2006.main.CTTimeNodeList; import org.openxmlformats.schemas.presentationml.x2006.main.CTTimeNodeList;
import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeIndefinite; import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeIndefinite;
import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeFillType; import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeFillType;
import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeRestartType; import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeRestartType;
import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeType; import org.openxmlformats.schemas.presentationml.x2006.main.STTLTimeNodeType;
import com.xuggle.mediatool.IMediaReader; import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaListenerAdapter; import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory; import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent; import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.Global; import com.xuggle.xuggler.Global;
import com.xuggle.xuggler.IContainer; import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.io.InputOutputStreamHandler; import com.xuggle.xuggler.io.InputOutputStreamHandler;
/** /**
* Adding multiple videos to a slide * Adding multiple videos to a slide
* *
* need the Xuggler 5.4 jars: * need the Xuggler 5.4 jars:
* &lt;repositories&gt; * &lt;repositories&gt;
* &lt;repository&gt; * &lt;repository&gt;
* &lt;id&gt;xuggle repo&lt;/id&gt; * &lt;id&gt;xuggle repo&lt;/id&gt;
* &lt;url&gt;http://xuggle.googlecode.com/svn/trunk/repo/share/java/&lt;/url&gt; * &lt;url&gt;http://xuggle.googlecode.com/svn/trunk/repo/share/java/&lt;/url&gt;
* &lt;/repository&gt; * &lt;/repository&gt;
* &lt;/repositories&gt; * &lt;/repositories&gt;
* ... * ...
* &lt;dependency&gt; * &lt;dependency&gt;
* &lt;groupId&gt;xuggle&lt;/groupId&gt; * &lt;groupId&gt;xuggle&lt;/groupId&gt;
* &lt;artifactId&gt;xuggle-xuggler&lt;/artifactId&gt; * &lt;artifactId&gt;xuggle-xuggler&lt;/artifactId&gt;
* &lt;version&gt;5.4&lt;/version&gt; * &lt;version&gt;5.4&lt;/version&gt;
* &lt;/dependency&gt; * &lt;/dependency&gt;
* *
* @see <a href="http://stackoverflow.com/questions/15197300/apache-poi-xslf-adding-movie-to-the-slide">Apache POI XSLF Adding movie to the slide</a> * @see <a href="http://stackoverflow.com/questions/15197300/apache-poi-xslf-adding-movie-to-the-slide">Apache POI XSLF Adding movie to the slide</a>
* @see <a href="http://apache-poi.1045710.n5.nabble.com/Question-about-embedded-video-in-PPTX-files-tt5718461.html">Question about embedded video in PPTX files</a> * @see <a href="http://apache-poi.1045710.n5.nabble.com/Question-about-embedded-video-in-PPTX-files-tt5718461.html">Question about embedded video in PPTX files</a>
*/ */
public class AddVideoToPptx { public class AddVideoToPptx {
static DecimalFormat df_time = new DecimalFormat("0.####"); static DecimalFormat df_time = new DecimalFormat("0.####");
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
URL video = new URL("http://archive.org/download/test-mpeg/test-mpeg.mpg"); URL video = new URL("http://archive.org/download/test-mpeg/test-mpeg.mpg");
// URL video = new URL("file:test-mpeg.mpg"); // URL video = new URL("file:test-mpeg.mpg");
XMLSlideShow pptx = new XMLSlideShow(); XMLSlideShow pptx = new XMLSlideShow();
// add video file // add video file
String videoFileName = video.getPath().substring(video.getPath().lastIndexOf('/')+1); String videoFileName = video.getPath().substring(video.getPath().lastIndexOf('/')+1);
PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/"+videoFileName); PackagePartName partName = PackagingURIHelper.createPartName("/ppt/media/"+videoFileName);
PackagePart part = pptx.getPackage().createPart(partName, "video/mpeg"); PackagePart part = pptx.getPackage().createPart(partName, "video/mpeg");
OutputStream partOs = part.getOutputStream(); OutputStream partOs = part.getOutputStream();
InputStream fis = video.openStream(); InputStream fis = video.openStream();
byte buf[] = new byte[1024]; byte buf[] = new byte[1024];
for (int readBytes; (readBytes = fis.read(buf)) != -1; partOs.write(buf, 0, readBytes)); for (int readBytes; (readBytes = fis.read(buf)) != -1; partOs.write(buf, 0, readBytes));
fis.close(); fis.close();
partOs.close(); partOs.close();
XSLFSlide slide1 = pptx.createSlide(); XSLFSlide slide1 = pptx.createSlide();
XSLFPictureShape pv1 = addPreview(pptx, slide1, part, 5, 50, 50); XSLFPictureShape pv1 = addPreview(pptx, slide1, part, 5, 50, 50);
addVideo(pptx, slide1, part, pv1, 5); addVideo(pptx, slide1, part, pv1, 5);
addTimingInfo(slide1, pv1); addTimingInfo(slide1, pv1);
XSLFPictureShape pv2 = addPreview(pptx, slide1, part, 9, 50, 250); XSLFPictureShape pv2 = addPreview(pptx, slide1, part, 9, 50, 250);
addVideo(pptx, slide1, part, pv2, 9); addVideo(pptx, slide1, part, pv2, 9);
addTimingInfo(slide1, pv2); addTimingInfo(slide1, pv2);
FileOutputStream fos = new FileOutputStream("pptx-with-video.pptx"); FileOutputStream fos = new FileOutputStream("pptx-with-video.pptx");
pptx.write(fos); pptx.write(fos);
fos.close(); fos.close();
pptx.close(); pptx.close();
} }
static XSLFPictureShape addPreview(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, double seconds, int x, int y) throws IOException { static XSLFPictureShape addPreview(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, double seconds, int x, int y) throws IOException {
// get preview after 5 sec. // get preview after 5 sec.
IContainer ic = IContainer.make(); IContainer ic = IContainer.make();
InputOutputStreamHandler iosh = new InputOutputStreamHandler(videoPart.getInputStream()); InputOutputStreamHandler iosh = new InputOutputStreamHandler(videoPart.getInputStream());
if (ic.open(iosh, IContainer.Type.READ, null) < 0) return null; if (ic.open(iosh, IContainer.Type.READ, null) < 0) return null;
IMediaReader mediaReader = ToolFactory.makeReader(ic); IMediaReader mediaReader = ToolFactory.makeReader(ic);
// stipulate that we want BufferedImages created in BGR 24bit color space // stipulate that we want BufferedImages created in BGR 24bit color space
mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR); mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
ImageSnapListener isl = new ImageSnapListener(seconds); ImageSnapListener isl = new ImageSnapListener(seconds);
mediaReader.addListener(isl); mediaReader.addListener(isl);
// read out the contents of the media file and // read out the contents of the media file and
// dispatch events to the attached listener // dispatch events to the attached listener
while (!isl.hasFired && mediaReader.readPacket() == null) ; while (!isl.hasFired && mediaReader.readPacket() == null) ;
mediaReader.close(); mediaReader.close();
ic.close(); ic.close();
// add snapshot // add snapshot
BufferedImage image1 = isl.image; BufferedImage image1 = isl.image;
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image1, "jpeg", bos); ImageIO.write(image1, "jpeg", bos);
XSLFPictureData snap = pptx.addPicture(bos.toByteArray(), PictureType.JPEG); XSLFPictureData snap = pptx.addPicture(bos.toByteArray(), PictureType.JPEG);
XSLFPictureShape pic1 = slide1.createPicture(snap); XSLFPictureShape pic1 = slide1.createPicture(snap);
pic1.setAnchor(new Rectangle(x, y, image1.getWidth(), image1.getHeight())); pic1.setAnchor(new Rectangle(x, y, image1.getWidth(), image1.getHeight()));
return pic1; return pic1;
} }
static void addVideo(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, XSLFPictureShape pic1, double seconds) throws IOException { static void addVideo(XMLSlideShow pptx, XSLFSlide slide1, PackagePart videoPart, XSLFPictureShape pic1, double seconds) throws IOException {
// add video shape // add video shape
PackagePartName partName = videoPart.getPartName(); PackagePartName partName = videoPart.getPartName();
PackageRelationship prsEmbed1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.microsoft.com/office/2007/relationships/media"); PackageRelationship prsEmbed1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.microsoft.com/office/2007/relationships/media");
PackageRelationship prsExec1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"); PackageRelationship prsExec1 = slide1.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video");
CTPicture xpic1 = (CTPicture)pic1.getXmlObject(); CTPicture xpic1 = (CTPicture)pic1.getXmlObject();
CTHyperlink link1 = xpic1.getNvPicPr().getCNvPr().addNewHlinkClick(); CTHyperlink link1 = xpic1.getNvPicPr().getCNvPr().addNewHlinkClick();
link1.setId(""); link1.setId("");
link1.setAction("ppaction://media"); link1.setAction("ppaction://media");
// add video relation // add video relation
CTApplicationNonVisualDrawingProps nvPr = xpic1.getNvPicPr().getNvPr(); CTApplicationNonVisualDrawingProps nvPr = xpic1.getNvPicPr().getNvPr();
nvPr.addNewVideoFile().setLink(prsExec1.getId()); nvPr.addNewVideoFile().setLink(prsExec1.getId());
CTExtension ext = nvPr.addNewExtLst().addNewExt(); CTExtension ext = nvPr.addNewExtLst().addNewExt();
// see http://msdn.microsoft.com/en-us/library/dd950140(v=office.12).aspx // see http://msdn.microsoft.com/en-us/library/dd950140(v=office.12).aspx
ext.setUri("{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}"); ext.setUri("{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}");
String p14Ns = "http://schemas.microsoft.com/office/powerpoint/2010/main"; String p14Ns = "http://schemas.microsoft.com/office/powerpoint/2010/main";
XmlCursor cur = ext.newCursor();
try (XmlCursor cur = ext.newCursor()) { try {
cur.toEndToken(); cur.toEndToken();
cur.beginElement(new QName(p14Ns, "media", "p14")); cur.beginElement(new QName(p14Ns, "media", "p14"));
cur.insertNamespace("p14", p14Ns); cur.insertNamespace("p14", p14Ns);
cur.insertAttributeWithValue(new QName(STRelationshipId.type.getName().getNamespaceURI(), "embed"), prsEmbed1.getId()); cur.insertAttributeWithValue(new QName(STRelationshipId.type.getName().getNamespaceURI(), "embed"), prsEmbed1.getId());
cur.beginElement(new QName(p14Ns, "trim", "p14")); cur.beginElement(new QName(p14Ns, "trim", "p14"));
cur.insertAttributeWithValue("st", df_time.format(seconds*1000.0)); cur.insertAttributeWithValue("st", df_time.format(seconds*1000.0));
} } finally {
} cur.dispose();
}
static void addTimingInfo(XSLFSlide slide1, XSLFPictureShape pic1) { }
// add slide timing information, so video can be controlled
CTSlide xslide = slide1.getXmlObject(); static void addTimingInfo(XSLFSlide slide1, XSLFPictureShape pic1) {
CTTimeNodeList ctnl; // add slide timing information, so video can be controlled
if (!xslide.isSetTiming()) { CTSlide xslide = slide1.getXmlObject();
CTTLCommonTimeNodeData ctn = xslide.addNewTiming().addNewTnLst().addNewPar().addNewCTn(); CTTimeNodeList ctnl;
ctn.setDur(STTLTimeIndefinite.INDEFINITE); if (!xslide.isSetTiming()) {
ctn.setRestart(STTLTimeNodeRestartType.NEVER); CTTLCommonTimeNodeData ctn = xslide.addNewTiming().addNewTnLst().addNewPar().addNewCTn();
ctn.setNodeType(STTLTimeNodeType.TM_ROOT); ctn.setDur(STTLTimeIndefinite.INDEFINITE);
ctnl = ctn.addNewChildTnLst(); ctn.setRestart(STTLTimeNodeRestartType.NEVER);
} else { ctn.setNodeType(STTLTimeNodeType.TM_ROOT);
ctnl = xslide.getTiming().getTnLst().getParArray(0).getCTn().getChildTnLst(); ctnl = ctn.addNewChildTnLst();
} } else {
ctnl = xslide.getTiming().getTnLst().getParArray(0).getCTn().getChildTnLst();
CTTLCommonMediaNodeData cmedia = ctnl.addNewVideo().addNewCMediaNode(); }
cmedia.setVol(80000);
CTTLCommonTimeNodeData ctn = cmedia.addNewCTn(); CTTLCommonMediaNodeData cmedia = ctnl.addNewVideo().addNewCMediaNode();
ctn.setFill(STTLTimeNodeFillType.HOLD); cmedia.setVol(80000);
ctn.setDisplay(false); CTTLCommonTimeNodeData ctn = cmedia.addNewCTn();
ctn.addNewStCondLst().addNewCond().setDelay(STTLTimeIndefinite.INDEFINITE); ctn.setFill(STTLTimeNodeFillType.HOLD);
cmedia.addNewTgtEl().addNewSpTgt().setSpid(""+pic1.getShapeId()); ctn.setDisplay(false);
} ctn.addNewStCondLst().addNewCond().setDelay(STTLTimeIndefinite.INDEFINITE);
cmedia.addNewTgtEl().addNewSpTgt().setSpid(""+pic1.getShapeId());
}
static class ImageSnapListener extends MediaListenerAdapter {
final double SECONDS_BETWEEN_FRAMES;
final long MICRO_SECONDS_BETWEEN_FRAMES; static class ImageSnapListener extends MediaListenerAdapter {
boolean hasFired = false; final double SECONDS_BETWEEN_FRAMES;
BufferedImage image = null; final long MICRO_SECONDS_BETWEEN_FRAMES;
boolean hasFired = false;
// The video stream index, used to ensure we display frames from one and BufferedImage image = null;
// only one video stream from the media container.
int mVideoStreamIndex = -1; // The video stream index, used to ensure we display frames from one and
// only one video stream from the media container.
// Time of last frame write int mVideoStreamIndex = -1;
long mLastPtsWrite = Global.NO_PTS;
// Time of last frame write
public ImageSnapListener(double seconds) { long mLastPtsWrite = Global.NO_PTS;
SECONDS_BETWEEN_FRAMES = seconds;
MICRO_SECONDS_BETWEEN_FRAMES = public ImageSnapListener(double seconds) {
(long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES); SECONDS_BETWEEN_FRAMES = seconds;
} MICRO_SECONDS_BETWEEN_FRAMES =
(long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
@Override
if (event.getStreamIndex() != mVideoStreamIndex) { public void onVideoPicture(IVideoPictureEvent event) {
// if the selected video stream id is not yet set, go ahead an
// select this lucky video stream if (event.getStreamIndex() != mVideoStreamIndex) {
if (mVideoStreamIndex != -1) return; // if the selected video stream id is not yet set, go ahead an
mVideoStreamIndex = event.getStreamIndex(); // select this lucky video stream
} if (mVideoStreamIndex != -1) return;
mVideoStreamIndex = event.getStreamIndex();
long evtTS = event.getTimeStamp(); }
// if uninitialized, back date mLastPtsWrite to get the very first frame long evtTS = event.getTimeStamp();
if (mLastPtsWrite == Global.NO_PTS)
mLastPtsWrite = Math.max(0, evtTS - MICRO_SECONDS_BETWEEN_FRAMES); // if uninitialized, back date mLastPtsWrite to get the very first frame
if (mLastPtsWrite == Global.NO_PTS)
// if its time to write the next frame mLastPtsWrite = Math.max(0, evtTS - MICRO_SECONDS_BETWEEN_FRAMES);
if (evtTS - mLastPtsWrite >= MICRO_SECONDS_BETWEEN_FRAMES) {
if (!hasFired) { // if it's time to write the next frame
image = event.getImage(); if (evtTS - mLastPtsWrite >= MICRO_SECONDS_BETWEEN_FRAMES) {
hasFired = true; if (!hasFired) {
} image = event.getImage();
// update last write time hasFired = true;
mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES; }
} // update last write time
} mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;
} }
}
} }
}

View File

@ -25,7 +25,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -64,7 +64,7 @@ public final class BarChartDemo {
} }
try (FileInputStream argIS = new FileInputStream(args[0]); try (FileInputStream argIS = new FileInputStream(args[0]);
BufferedReader modelReader = Files.newBufferedReader(Path.of(args[1]), StandardCharsets.UTF_8)) { BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[1]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();

View File

@ -26,7 +26,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -72,7 +72,7 @@ public final class ChartFromScratch {
return; return;
} }
try (BufferedReader modelReader = Files.newBufferedReader(Path.of(args[0]), StandardCharsets.UTF_8)) { try (BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[0]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();
@ -180,10 +180,6 @@ public final class ChartFromScratch {
chart.setTitleText(chartTitle); chart.setTitleText(chartTitle);
chart.setTitleOverlay(false); chart.setTitleOverlay(false);
chart.setAutoTitleDeleted(false); chart.setAutoTitleDeleted(false);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
} }
private static final int COLUMN_LANGUAGES = 0; private static final int COLUMN_LANGUAGES = 0;

View File

@ -21,13 +21,19 @@ package org.apache.poi.examples.xslf;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.AxisCrossBetween;
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
import org.apache.poi.xddf.usermodel.chart.AxisTickMark;
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.XDDFChartAxis;
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.XDDFDoughnutChartData; import org.apache.poi.xddf.usermodel.chart.XDDFDoughnutChartData;
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.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFChart; import org.apache.poi.xslf.usermodel.XSLFChart;
import org.apache.poi.xslf.usermodel.XSLFGraphicFrame; import org.apache.poi.xslf.usermodel.XSLFGraphicFrame;
@ -41,7 +47,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -64,7 +70,7 @@ public final class DoughnutChartFromScratch {
return; return;
} }
try (BufferedReader modelReader = Files.newBufferedReader(Path.of(args[0]), StandardCharsets.UTF_8)) { try (BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[0]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();

View File

@ -84,11 +84,14 @@ public final class LinkVideoToPptx {
ext.setUri("{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}"); ext.setUri("{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}");
String p14Ns = "http://schemas.microsoft.com/office/powerpoint/2010/main"; String p14Ns = "http://schemas.microsoft.com/office/powerpoint/2010/main";
try (XmlCursor cur = ext.newCursor()) { XmlCursor cur = ext.newCursor();
try {
cur.toEndToken(); cur.toEndToken();
cur.beginElement(new QName(p14Ns, "media", "p14")); cur.beginElement(new QName(p14Ns, "media", "p14"));
cur.insertNamespace("p14", p14Ns); cur.insertNamespace("p14", p14Ns);
cur.insertAttributeWithValue(new QName(CORE_PROPERTIES_ECMA376_NS, "link"), prsEmbed1.getId()); cur.insertAttributeWithValue(new QName(CORE_PROPERTIES_ECMA376_NS, "link"), prsEmbed1.getId());
} finally {
cur.dispose();
} }
CTSlide xslide = slide1.getXmlObject(); CTSlide xslide = slide1.getXmlObject();

View File

@ -25,7 +25,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -61,7 +61,7 @@ public final class PieChartDemo {
} }
try (FileInputStream argIS = new FileInputStream(args[0]); try (FileInputStream argIS = new FileInputStream(args[0]);
BufferedReader modelReader = Files.newBufferedReader(Path.of(args[1]), StandardCharsets.UTF_8)) { BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[1]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
try (XMLSlideShow pptx = new XMLSlideShow(argIS)) { try (XMLSlideShow pptx = new XMLSlideShow(argIS)) {

View File

@ -1,137 +0,0 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.examples.xslf;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.xslf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
/**
* Converts SmartArt to openxml shapes and saves the result to the specified output path.
*/
public class SmartArtConversionDemo {
private final XMLSlideShow inputPptx;
private final XMLSlideShow outputPptx;
SmartArtConversionDemo(XMLSlideShow inputPptx, XMLSlideShow outputPptx) {
this.inputPptx = inputPptx;
this.outputPptx = outputPptx;
}
public static void main(String[] args) throws IOException {
if (args.length != 2) {
System.out.println("Expected arguments: <inputPath> <outputPath>");
System.exit(1);
}
File inputFile = new File(args[0]);
if (!inputFile.exists()) {
System.out.printf(LocaleUtil.getUserLocale(), "Unable to find input file at path: %s", args[0]);
System.exit(1);
}
try (
FileInputStream inputPptxStream = new FileInputStream(inputFile);
FileOutputStream outputPptxStream = new FileOutputStream(args[1])
) {
XMLSlideShow inputPptx = new XMLSlideShow(inputPptxStream);
XMLSlideShow outputPptx = new XMLSlideShow();
SmartArtConversionDemo demo = new SmartArtConversionDemo(inputPptx, outputPptx);
demo.convertSmartArt();
outputPptx.write(outputPptxStream);
}
}
private static void copyAndUpdateImageRelations(XSLFDiagram diagram, XSLFSlide outputSlide) throws IOException {
XSLFGroupShape inputGroupShape = diagram.getGroupShape();
for (XSLFShape shape : inputGroupShape.getShapes()) {
org.openxmlformats.schemas.presentationml.x2006.main.CTShape ctShape
= (org.openxmlformats.schemas.presentationml.x2006.main.CTShape) shape.getXmlObject();
if (ctShape.getSpPr().getBlipFill() == null) {
continue;
}
CTBlipFillProperties blipFillProps = ctShape.getSpPr().getBlipFill();
CTBlip blip = blipFillProps.getBlip();
// Relationships for SmartArt diagrams are stored in `drawing#.xml.rels`, not `slide#.xml.rels`.
POIXMLDocumentPart inputPicturePart = diagram.getDiagramDrawing().getRelationById(blip.getEmbed());
if (inputPicturePart == null || inputPicturePart.getPackagePart() == null) {
continue;
}
XSLFPictureData inputPictureData = new XSLFPictureData(inputPicturePart.getPackagePart());
// Copy the input image to the output slides and update the shape to reference the copied image
XMLSlideShow outputPptx = outputSlide.getSlideShow();
XSLFPictureData outputPictureData = outputPptx.addPicture(
inputPicturePart.getPackagePart().getInputStream(), inputPictureData.getType());
POIXMLDocumentPart.RelationPart outputRelation = outputSlide.addRelation(null, XSLFRelation.IMAGES, outputPictureData);
ctShape.getSpPr().getBlipFill().getBlip().setEmbed(outputRelation.getRelationship().getId());
}
}
private static XSLFTheme extractTheme(XMLSlideShow slideShow) {
if (!slideShow.getSlideMasters().isEmpty()) {
return slideShow.getSlideMasters().get(0).getTheme();
}
return null;
}
private void convertSmartArt() throws IOException {
// Copy page size and theme
outputPptx.setPageSize(inputPptx.getPageSize());
XSLFTheme theme = extractTheme(inputPptx);
if (theme != null) {
outputPptx.getSlideMasters().get(0).getTheme().getXmlObject().set(theme.getXmlObject());
}
for (XSLFSlide inputSlide : inputPptx.getSlides()) {
XSLFSlide outputSlide = outputPptx.createSlide();
List<XSLFShape> inputShapes = inputSlide.getShapes();
for (XSLFShape shape : inputShapes) {
if (shape instanceof XSLFDiagram) {
copyDiagramToOutput((XSLFDiagram) shape, outputSlide);
} else {
XSLFAutoShape autoShape = outputSlide.createAutoShape();
// Hacky hack. Reassign xml to copy the content over.
autoShape.getXmlObject().set(shape.getXmlObject());
}
}
}
}
private void copyDiagramToOutput(XSLFDiagram inputDiagram, XSLFSlide outputSlide) throws IOException {
// This method modifies the underlying xml of the input shapes. We modify the xml structure first, then
// assign that to our output shape.
copyAndUpdateImageRelations(inputDiagram, outputSlide);
XSLFGroupShape inputGroupShape = inputDiagram.getGroupShape();
XSLFGroupShape outputGroupShape = outputSlide.createGroup();
outputGroupShape.getXmlObject().set(inputGroupShape.getXmlObject());
}
}

View File

@ -1,12 +1,12 @@
10 languages with most speakers as first language 10 languages with most speakers as first language
countries,speakers,language countries,speakers,language
58,315,العربية 58,315,العربية
4,243,বাংলা 4,243,বাংলা
38,1299,中文 38,1299,中文
118,378,English 118,378,English
4,260,हिन्दी 4,260,हिन्दी
2,128,日本語 2,128,日本語
15,223,português 15,223,português
6,119,ਪੰਜਾਬੀ 6,119,ਪੰਜਾਬੀ
18,154,Русский язык 18,154,Русский язык
31,442,español 31,442,español

View File

@ -1,4 +1,4 @@
My Chart My Chart
First 1.0 First 1.0
Second 3.0 Second 3.0
Third 4.0 Third 4.0

View File

@ -25,7 +25,6 @@ import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.util.StringUtil;
import org.apache.poi.util.XMLHelper; import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStrings; import org.apache.poi.xssf.model.SharedStrings;
@ -133,10 +132,10 @@ public class FromHowTo {
throws SAXException { throws SAXException {
// Process the last contents as required. // Process the last contents as required.
// Do now, as characters() may be called more than once // Do now, as characters() may be called more than once
if(nextIsString && StringUtil.isNotBlank(lastContents)) { if(nextIsString && !lastContents.trim().isEmpty()) {
Integer idx = Integer.valueOf(lastContents); Integer idx = Integer.valueOf(lastContents);
lastContents = lruCache.get(idx); lastContents = lruCache.get(idx);
if (lastContents == null && !lruCache.containsKey(idx) && sst != null) { if (lastContents == null && !lruCache.containsKey(idx)) {
lastContents = sst.getItemAt(idx).getString(); lastContents = sst.getItemAt(idx).getString();
lruCache.put(idx, lastContents); lruCache.put(idx, lastContents);
} }

View File

@ -20,12 +20,12 @@
package org.apache.poi.examples.xssf.eventusermodel; package org.apache.poi.examples.xssf.eventusermodel;
import java.io.InputStream; import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.examples.xssf.usermodel.LoadPasswordProtectedXlsx; import org.apache.poi.examples.xssf.usermodel.LoadPasswordProtectedXlsx;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource; import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource;
import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFReader.SheetIterator;
/** /**
* An example that loads a password protected workbook and counts the sheets. * An example that loads a password protected workbook and counts the sheets.
@ -48,12 +48,11 @@ public final class LoadPasswordProtectedXlsxStreaming {
try (AesZipFileZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(inputStream); try (AesZipFileZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(inputStream);
OPCPackage pkg = OPCPackage.open(source)) { OPCPackage pkg = OPCPackage.open(source)) {
XSSFReader reader = new XSSFReader(pkg); XSSFReader reader = new XSSFReader(pkg);
Iterator<InputStream> iter = reader.getSheetsData(); SheetIterator iter = (SheetIterator)reader.getSheetsData();
int count = 0; int count = 0;
while(iter.hasNext()) { while(iter.hasNext()) {
try (InputStream stream = iter.next()) { iter.next();
count++; count++;
}
} }
System.out.println("sheet count: " + count); System.out.println("sheet count: " + count);
} }

View File

@ -212,7 +212,7 @@ public class XLSX2CSV {
styles, null, strings, sheetHandler, formatter, false); styles, null, strings, sheetHandler, formatter, false);
sheetParser.setContentHandler(handler); sheetParser.setContentHandler(handler);
sheetParser.parse(sheetSource); sheetParser.parse(sheetSource);
} catch (ParserConfigurationException e) { } catch(ParserConfigurationException e) {
throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage()); throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage());
} }
} }
@ -234,12 +234,7 @@ public class XLSX2CSV {
String sheetName = iter.getSheetName(); String sheetName = iter.getSheetName();
this.output.println(); this.output.println();
this.output.println(sheetName + " [index=" + index + "]:"); this.output.println(sheetName + " [index=" + index + "]:");
processSheet(styles, strings, new SheetToCSV(), stream);
try {
processSheet(styles, strings, new SheetToCSV(), stream);
} catch (NumberFormatException e) {
throw new IOException("Failed to parse sheet " + sheetName, e);
}
} }
++index; ++index;
} }

View File

@ -53,13 +53,12 @@ public class DeferredGeneration {
try (FileOutputStream fileOut = new FileOutputStream("DeferredGeneration.xlsx")) { try (FileOutputStream fileOut = new FileOutputStream("DeferredGeneration.xlsx")) {
wb.write(fileOut); wb.write(fileOut);
// writeAvoidingTempFiles was added as an experimental change in POI 5.1.0 //writeAvoidingTempFiles was added as an experimental change in POI 5.1.0
// wb.writeAvoidingTempFiles(fileOut); //wb.writeAvoidingTempFiles(fileOut);
} finally {
//the dispose call is necessary to ensure temp files are removed
wb.dispose();
} }
// finally {
// the dispose call is no longer necessary to ensure temp files are removed
// wb.dispose();
// }
System.out.println("wrote DeferredGeneration.xlsx"); System.out.println("wrote DeferredGeneration.xlsx");
} }
} }

View File

@ -46,11 +46,10 @@ public class Outlining {
try (FileOutputStream fileOut = new FileOutputStream("outlining_collapsed.xlsx")) { try (FileOutputStream fileOut = new FileOutputStream("outlining_collapsed.xlsx")) {
wb2.write(fileOut); wb2.write(fileOut);
} finally {
//the dispose call is necessary to ensure temp files are removed
wb2.dispose();
} }
// finally {
// the dispose call is no longer necessary to ensure temp files are removed
// wb2.dispose();
// }
} }
} }
} }

View File

@ -58,7 +58,8 @@ public final class SavePasswordProtectedXlsx {
TempFileUtils.checkTempFiles(); TempFileUtils.checkTempFiles();
String filename = args[0]; String filename = args[0];
String password = args[1]; String password = args[1];
try (SXSSFWorkbookWithCustomZipEntrySource wb = new SXSSFWorkbookWithCustomZipEntrySource()) { SXSSFWorkbookWithCustomZipEntrySource wb = new SXSSFWorkbookWithCustomZipEntrySource();
try {
for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) {
SXSSFSheet sheet = wb.createSheet("Sheet" + i); SXSSFSheet sheet = wb.createSheet("Sheet" + i);
for(int r = 0; r < 1000; r++) { for(int r = 0; r < 1000; r++) {
@ -77,6 +78,10 @@ public final class SavePasswordProtectedXlsx {
} finally { } finally {
tempData.dispose(); tempData.dispose();
} }
} finally {
wb.close();
//the dispose call is necessary to ensure temp files are removed
wb.dispose();
} }
TempFileUtils.checkTempFiles(); TempFileUtils.checkTempFiles();
} }

View File

@ -104,10 +104,6 @@ public final class BarChart {
solidFillSeries(data, 0, PresetColor.CHARTREUSE); solidFillSeries(data, 0, PresetColor.CHARTREUSE);
solidFillSeries(data, 1, PresetColor.TURQUOISE); solidFillSeries(data, 1, PresetColor.TURQUOISE);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
// 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")) {
wb.write(fileOut); wb.write(fileOut);

View File

@ -25,7 +25,6 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Calendar; import java.util.Calendar;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
@ -35,8 +34,8 @@ import java.util.Random;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.poi.logging.PoiLogManager;
import org.apache.poi.openxml4j.opc.internal.ZipHelper; import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.FillPatternType;
@ -77,7 +76,8 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
* See <a href="https://poi.apache.org/spreadsheet/how-to.html#sxssf">SXSSF (Streaming Usermodel API)</a>. * See <a href="https://poi.apache.org/spreadsheet/how-to.html#sxssf">SXSSF (Streaming Usermodel API)</a>.
*/ */
public final class BigGridDemo { public final class BigGridDemo {
private static final Logger LOG = PoiLogManager.getLogger(BigGridDemo.class); private static final Logger LOG = LogManager.getLogger(BigGridDemo.class);
private static final String XML_ENCODING = "UTF-8";
private static final Random rnd = new Random(); private static final Random rnd = new Random();
@ -105,7 +105,7 @@ public final class BigGridDemo {
tmp = TempFile.createTempFile("sheet", ".xml"); tmp = TempFile.createTempFile("sheet", ".xml");
try ( try (
FileOutputStream stream = new FileOutputStream(tmp); FileOutputStream stream = new FileOutputStream(tmp);
Writer fw = new OutputStreamWriter(stream, StandardCharsets.UTF_8) Writer fw = new OutputStreamWriter(stream, XML_ENCODING)
) { ) {
generate(fw, styles); generate(fw, styles);
} }
@ -247,7 +247,7 @@ public final class BigGridDemo {
} }
void beginSheet() throws IOException { void beginSheet() throws IOException {
_out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + _out.write("<?xml version=\"1.0\" encoding=\""+XML_ENCODING+"\"?>" +
"<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">" ); "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">" );
_out.write("<sheetData>\n"); _out.write("<sheetData>\n");
} }

View File

@ -38,7 +38,7 @@ public final class CustomXMLMapping {
for (XSSFMap map : wb.getCustomXMLMappings()) { for (XSSFMap map : wb.getCustomXMLMappings()) {
XSSFExportToXml exporter = new XSSFExportToXml(map); XSSFExportToXml exporter = new XSSFExportToXml(map);
UnsynchronizedByteArrayOutputStream os = UnsynchronizedByteArrayOutputStream.builder().get(); UnsynchronizedByteArrayOutputStream os = new UnsynchronizedByteArrayOutputStream();
exporter.exportToXML(os, true); exporter.exportToXML(os, true);
String xml = os.toString(StandardCharsets.UTF_8); String xml = os.toString(StandardCharsets.UTF_8);
System.out.println(xml); System.out.println(xml);

View File

@ -37,35 +37,27 @@ public class EmbeddedObjects {
String contentType = pPart.getContentType(); String contentType = pPart.getContentType();
try (InputStream is = pPart.getInputStream()) { try (InputStream is = pPart.getInputStream()) {
Closeable document; Closeable document;
switch (contentType) { if (contentType.equals("application/vnd.ms-excel")) {
case "application/vnd.ms-excel": // Excel Workbook - either binary or OpenXML
// Excel Workbook - either binary or OpenXML document = new HSSFWorkbook(is);
document = new HSSFWorkbook(is); } else if (contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
break; // Excel Workbook - OpenXML file format
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": document = new XSSFWorkbook(is);
// Excel Workbook - OpenXML file format } else if (contentType.equals("application/msword")) {
document = new XSSFWorkbook(is); // Word Document - binary (OLE2CDF) file format
break; document = new HWPFDocument(is);
case "application/msword": } else if (contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) {
// Word Document - binary (OLE2CDF) file format // Word Document - OpenXML file format
document = new HWPFDocument(is); document = new XWPFDocument(is);
break; } else if (contentType.equals("application/vnd.ms-powerpoint")) {
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": // PowerPoint Document - binary file format
// Word Document - OpenXML file format document = new HSLFSlideShow(is);
document = new XWPFDocument(is); } else if (contentType.equals("application/vnd.openxmlformats-officedocument.presentationml.presentation")) {
break; // PowerPoint Document - OpenXML file format
case "application/vnd.ms-powerpoint": document = new XMLSlideShow(is);
// PowerPoint Document - binary file format } else {
document = new HSLFSlideShow(is); // Any other type of embedded object.
break; document = is;
case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
// PowerPoint Document - OpenXML file format
document = new XMLSlideShow(is);
break;
default:
// Any other type of embedded object.
document = is;
break;
} }
document.close(); document.close();
} }

View File

@ -105,10 +105,6 @@ public final class LineChart {
solidLineSeries(data, 0, PresetColor.CHARTREUSE); solidLineSeries(data, 0, PresetColor.CHARTREUSE);
solidLineSeries(data, 1, PresetColor.TURQUOISE); solidLineSeries(data, 1, PresetColor.TURQUOISE);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
// 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);

View File

@ -99,10 +99,6 @@ public final class ScatterChart {
solidLineSeries(data, 0, PresetColor.CHARTREUSE); solidLineSeries(data, 0, PresetColor.CHARTREUSE);
solidLineSeries(data, 1, PresetColor.TURQUOISE); solidLineSeries(data, 1, PresetColor.TURQUOISE);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
// 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);

View File

@ -20,7 +20,6 @@ package org.apache.poi.examples.xssf.usermodel;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.poi.ss.usermodel.PaneType;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@ -43,7 +42,7 @@ public class SplitAndFreezePanes {
// Freeze the columns and rows (forget about scrolling position of the lower right quadrant). // Freeze the columns and rows (forget about scrolling position of the lower right quadrant).
sheet3.createFreezePane(2, 2); sheet3.createFreezePane(2, 2);
// Create a split with the lower left side being the active quadrant // Create a split with the lower left side being the active quadrant
sheet4.createSplitPane(2000, 2000, 0, 0, PaneType.LOWER_LEFT); sheet4.createSplitPane(2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT);
try (FileOutputStream fileOut = new FileOutputStream("splitFreezePane.xlsx")) { try (FileOutputStream fileOut = new FileOutputStream("splitFreezePane.xlsx")) {
wb.write(fileOut); wb.write(fileOut);

View File

@ -65,7 +65,7 @@ public class WorkingWithPageSetup {
// Set the columns to repeat from column 0 to 2 on the first sheet // Set the columns to repeat from column 0 to 2 on the first sheet
sheet1.setRepeatingColumns(CellRangeAddress.valueOf("A:C")); sheet1.setRepeatingColumns(CellRangeAddress.valueOf("A:C"));
// Set the repeating rows and columns on the second sheet. // Set the the repeating rows and columns on the second sheet.
CellRangeAddress cra = CellRangeAddress.valueOf("E2:F3"); CellRangeAddress cra = CellRangeAddress.valueOf("E2:F3");
sheet2.setRepeatingColumns(cra); sheet2.setRepeatingColumns(cra);
sheet2.setRepeatingRows(cra); sheet2.setRepeatingRows(cra);

View File

@ -26,7 +26,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -63,7 +63,7 @@ public final class BarChartExample {
} }
try (FileInputStream argIS = new FileInputStream(args[0]); try (FileInputStream argIS = new FileInputStream(args[0]);
BufferedReader modelReader = Files.newBufferedReader(Path.of(args[1]), StandardCharsets.UTF_8)) { BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[1]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();

View File

@ -24,7 +24,7 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -67,7 +67,7 @@ public final class ChartFromScratch {
return; return;
} }
try (BufferedReader modelReader = Files.newBufferedReader(Path.of(args[0]), StandardCharsets.UTF_8)) { try (BufferedReader modelReader = Files.newBufferedReader(Paths.get(args[0]), StandardCharsets.UTF_8)) {
String chartTitle = modelReader.readLine(); // first line is chart title String chartTitle = modelReader.readLine(); // first line is chart title
String seriesText = modelReader.readLine(); String seriesText = modelReader.readLine();
@ -146,10 +146,6 @@ public final class ChartFromScratch {
chart.setTitleText(chartTitle); chart.setTitleText(chartTitle);
chart.setTitleOverlay(false); chart.setTitleOverlay(false);
chart.setAutoTitleDeleted(false); chart.setAutoTitleDeleted(false);
// temporary workaround for https://bz.apache.org/bugzilla/show_bug.cgi?id=67510
if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
} }
private static final int COLUMN_LANGUAGES = 0; private static final int COLUMN_LANGUAGES = 0;

View File

@ -22,10 +22,10 @@ import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.poi.common.usermodel.PictureType;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.BreakType; import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFRun;
@ -45,30 +45,30 @@ public final class SimpleImages {
XWPFRun r = p.createRun(); XWPFRun r = p.createRun();
for (String imgFile : args) { for (String imgFile : args) {
PictureType format; int format;
if (imgFile.endsWith(".emf")) { if (imgFile.endsWith(".emf")) {
format = PictureType.EMF; format = Document.PICTURE_TYPE_EMF;
} else if (imgFile.endsWith(".wmf")) { } else if (imgFile.endsWith(".wmf")) {
format = PictureType.WMF; format = Document.PICTURE_TYPE_WMF;
} else if (imgFile.endsWith(".pict")) { } else if (imgFile.endsWith(".pict")) {
format = PictureType.PICT; format = Document.PICTURE_TYPE_PICT;
} else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) { } else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) {
format = PictureType.JPEG; format = Document.PICTURE_TYPE_JPEG;
} else if (imgFile.endsWith(".png")) { } else if (imgFile.endsWith(".png")) {
format = PictureType.PNG; format = Document.PICTURE_TYPE_PNG;
} else if (imgFile.endsWith(".dib")) { } else if (imgFile.endsWith(".dib")) {
format = PictureType.DIB; format = Document.PICTURE_TYPE_DIB;
} else if (imgFile.endsWith(".gif")) { } else if (imgFile.endsWith(".gif")) {
format = PictureType.GIF; format = Document.PICTURE_TYPE_GIF;
} else if (imgFile.endsWith(".tiff")) { } else if (imgFile.endsWith(".tiff")) {
format = PictureType.TIFF; format = Document.PICTURE_TYPE_TIFF;
} else if (imgFile.endsWith(".eps")) { } else if (imgFile.endsWith(".eps")) {
format = PictureType.EPS; format = Document.PICTURE_TYPE_EPS;
} else if (imgFile.endsWith(".bmp")) { } else if (imgFile.endsWith(".bmp")) {
format = PictureType.BMP; format = Document.PICTURE_TYPE_BMP;
} else if (imgFile.endsWith(".wpg")) { } else if (imgFile.endsWith(".wpg")) {
format = PictureType.WPG; format = Document.PICTURE_TYPE_WPG;
} else { } 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");

View File

@ -44,7 +44,7 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
* SpreadsheetML workbook embedded into the document.<p> * SpreadsheetML workbook embedded into the document.<p>
* *
* This code was successfully tested with the following file from the POI test collection: * This code was successfully tested with the following file from the POI test collection:
* test-data/document/EmbeddedDocument.docx * http://svn.apache.org/repos/asf/poi/trunk/test-data/document/EmbeddedDocument.docx
*/ */
@SuppressWarnings({"java:S106","java:S4823","java:S1192"}) @SuppressWarnings({"java:S106","java:S4823","java:S1192"})
public class UpdateEmbeddedDoc { public class UpdateEmbeddedDoc {

View File

@ -1,12 +1,12 @@
10 languages with most speakers as first language 10 languages with most speakers as first language
countries,speakers,language countries,speakers,language
58,315,العربية 58,315,العربية
4,243,বাংলা 4,243,বাংলা
38,1299,中文 38,1299,中文
118,378,English 118,378,English
4,260,हिन्दी 4,260,हिन्दी
2,128,日本語 2,128,日本語
15,223,português 15,223,português
6,119,ਪੰਜਾਬੀ 6,119,ਪੰਜਾਬੀ
18,154,Русский язык 18,154,Русский язык
31,442,español 31,442,español

Binary file not shown.

View File

@ -1,115 +0,0 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.examples.hssf.eventusermodel;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.junit.jupiter.api.Test;
class TestXLS2CSVmra {
@Test
void test() throws Exception {
XLS2CSVmra.main(new String[] { HSSFTestDataSamples.getSampleFile("SampleSS.xls").getAbsolutePath() });
}
@Test
void testWithMinCols() throws Exception {
XLS2CSVmra.main(new String[] { HSSFTestDataSamples.getSampleFile("SampleSS.xls").getAbsolutePath(), "100" });
}
@Test
void testProcess() throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
PrintStream out = new PrintStream(outStream, false, StandardCharsets.UTF_8.name());
XLS2CSVmra cvs = new XLS2CSVmra(
new POIFSFileSystem(new FileInputStream(HSSFTestDataSamples.getSampleFile("SampleSS.xls").getAbsolutePath())),
out, -1);
cvs.process();
outStream.flush();
assertEquals(sanitize("\n"
+ "First Sheet [1]:\n"
+ "\"Test spreadsheet\"\n"
+ "\"2nd row\",\"2nd row 2nd column\"\n"
+ "\n"
+ "\"This one is red\"\n"
+ "\n"
+ "Sheet Number 2 [2]:\n"
+ "\"Start of 2nd sheet\"\n"
+ "\"Sheet 2 row 2\"\n"
+ "\n"
+ "\"I'm in bold blue, on a yellow background\"\n"
+ "\n"
+ "\"cb=1\",\"cb=10\",\"cb=2\",\"cb=sum\"\n"
+ "1,10,2,13\n"
+ "\n"
+ "Sheet3 [3]:\n"), sanitize(new String(outStream.toByteArray(), StandardCharsets.UTF_8)));
}
@Test
void testProcessNumberRecord() throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
PrintStream out = new PrintStream(outStream, false, StandardCharsets.UTF_8.name());
XLS2CSVmra cvs = new XLS2CSVmra(
new POIFSFileSystem(new FileInputStream(HSSFTestDataSamples.getSampleFile("empty.xls").getAbsolutePath())),
out, -1);
// need to call process() first to initialize members
cvs.process();
outStream.flush();
assertEquals(sanitize("\n"
+ "Лист1 [1]:\n"
+ "\n"
+ "Лист2 [2]:\n"
+ "\n"
+ "Лист3 [3]:\n"), sanitize(new String(outStream.toByteArray(), StandardCharsets.UTF_8)));
NumberRecord record = new NumberRecord();
record.setValue(1.243);
cvs.processRecord(record);
outStream.flush();
assertEquals(sanitize("\n"
+ "Лист1 [1]:\n"
+ "\n"
+ "Лист2 [2]:\n"
+ "\n"
+ "Лист3 [3]:\n"
+ "1.243"), sanitize(new String(outStream.toByteArray(), StandardCharsets.UTF_8)));
}
private String sanitize(String str) {
return str.replace("\r\n", "\n");
}
}

View File

@ -18,38 +18,31 @@
package org.apache.poi.integration; package org.apache.poi.integration;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
import org.apache.poi.examples.xssf.eventusermodel.XLSX2CSV; import org.apache.poi.examples.xssf.eventusermodel.XLSX2CSV;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFTestDataSamples;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import net.bytebuddy.utility.RandomString;
public class TestXLSX2CSV { public class TestXLSX2CSV {
private PrintStream err; private PrintStream err;
private final UnsynchronizedByteArrayOutputStream errorBytes = UnsynchronizedByteArrayOutputStream.builder().get(); private final UnsynchronizedByteArrayOutputStream errorBytes = new UnsynchronizedByteArrayOutputStream();
@BeforeEach @BeforeEach
public void setUp() throws UnsupportedEncodingException { public void setUp() throws UnsupportedEncodingException {
// remember and replace default error streams // remember and replace default error streams
err = System.err; err = System.err;
PrintStream error = new PrintStream(errorBytes, true, StandardCharsets.UTF_8.name()); PrintStream error = new PrintStream(errorBytes, true, "UTF-8");
System.setErr(error); System.setErr(error);
} }
@ -78,14 +71,14 @@ public class TestXLSX2CSV {
// returns with some System.err // returns with some System.err
XLSX2CSV.main(new String[] { "not-existing-file.xlsx" }); XLSX2CSV.main(new String[] { "not-existing-file.xlsx" });
String output = errorBytes.toString(StandardCharsets.UTF_8); String output = errorBytes.toString("UTF-8");
assertTrue(output.contains("Not found or not a file: not-existing-file.xlsx"), "Had: " + output); assertTrue(output.contains("Not found or not a file: not-existing-file.xlsx"), "Had: " + output);
} }
@Test @Test
public void testSampleFile() throws Exception { public void testSampleFile() throws Exception {
final UnsynchronizedByteArrayOutputStream outputBytes = UnsynchronizedByteArrayOutputStream.builder().get(); final UnsynchronizedByteArrayOutputStream outputBytes = new UnsynchronizedByteArrayOutputStream();
PrintStream out = new PrintStream(outputBytes, true, StandardCharsets.UTF_8.name()); PrintStream out = new PrintStream(outputBytes, true, "UTF-8");
// The package open is instantaneous, as it should be. // The package open is instantaneous, as it should be.
try (OPCPackage p = OPCPackage.open(XSSFTestDataSamples.getSampleFile("sample.xlsx").getAbsolutePath(), PackageAccess.READ)) { try (OPCPackage p = OPCPackage.open(XSSFTestDataSamples.getSampleFile("sample.xlsx").getAbsolutePath(), PackageAccess.READ)) {
@ -101,29 +94,10 @@ public class TestXLSX2CSV {
assertTrue(output.contains(",\"hello, xssf\",,\"hello, xssf\""), "Had: " + output); assertTrue(output.contains(",\"hello, xssf\",,\"hello, xssf\""), "Had: " + output);
} }
@Test
public void testInvalidSampleFile() throws Exception {
final UnsynchronizedByteArrayOutputStream outputBytes = UnsynchronizedByteArrayOutputStream.builder().get();
PrintStream out = new PrintStream(outputBytes, true, StandardCharsets.UTF_8.name());
// The package open is instantaneous, as it should be.
try (OPCPackage p = OPCPackage.open(XSSFTestDataSamples.getSampleFile("clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-5025401116950528.xlsx").getAbsolutePath(), PackageAccess.READ)) {
XLSX2CSV xlsx2csv = new XLSX2CSV(p, out, -1);
assertThrows(POIXMLException.class,
xlsx2csv::process);
}
String errorOutput = errorBytes.toString(StandardCharsets.UTF_8);
assertEquals("", errorOutput);
String output = outputBytes.toString(StandardCharsets.UTF_8);
assertEquals("", output, "Had: " + output);
}
@Test @Test
public void testMinColumns() throws Exception { public void testMinColumns() throws Exception {
final UnsynchronizedByteArrayOutputStream outputBytes = UnsynchronizedByteArrayOutputStream.builder().get(); final UnsynchronizedByteArrayOutputStream outputBytes = new UnsynchronizedByteArrayOutputStream();
PrintStream out = new PrintStream(outputBytes, true, StandardCharsets.UTF_8.name()); PrintStream out = new PrintStream(outputBytes, true, "UTF-8");
// The package open is instantaneous, as it should be. // The package open is instantaneous, as it should be.
try (OPCPackage p = OPCPackage.open(XSSFTestDataSamples.getSampleFile("sample.xlsx").getAbsolutePath(), PackageAccess.READ)) { try (OPCPackage p = OPCPackage.open(XSSFTestDataSamples.getSampleFile("sample.xlsx").getAbsolutePath(), PackageAccess.READ)) {
@ -135,87 +109,7 @@ public class TestXLSX2CSV {
assertEquals("", errorOutput); assertEquals("", errorOutput);
String output = outputBytes.toString(StandardCharsets.UTF_8); String output = outputBytes.toString(StandardCharsets.UTF_8);
assertTrue(output.contains("\"Lorem\",111,,,"), "Had: " + output); assertTrue(output.contains("\"Lorem\",111,,,"), "Had: " + output);
assertTrue(output.contains(",\"hello, xssf\",,\"hello, xssf\","), "Had: " + output); assertTrue(output.contains(",\"hello, xssf\",,\"hello, xssf\","), "Had: " + output);
}
@Disabled("Used for local micro-benchmarking")
@Test
public void microBenchmark() {
checkReplace("str");
checkReplace("str.123");
checkReplace("str.123,");
checkReplace("str,,,.123,,,,");
for (int i = 0; i < 1000;i++) {
checkReplace(RandomString.make(20));
}
for (int i = 0;i < 10;i++) {
long start = System.currentTimeMillis();
String str = RandomString.make(100) + "\"\"" + RandomString.make(100) + "\"\"" + RandomString.make(100);
String expected = str.replace("\"", "\"\"");
for (int j = 0;j < 300000;j++) {
//assertEquals(expected, replaceString(str, "\"", "\"\""));
assertEquals(expected, replaceDirect(str, "\"", "\"\""));
}
System.out.println(" , " + (System.currentTimeMillis() - start));
}
// Java 8: replaceString: 1001, 921, 1264, 1019, 1258, 990, 1089, 1430, 1153, 907
// Java 8: replaceDirect: 375, 282, 240, 246, 264, 271, 258, 250, 263, 259
// Java 11: replaceString: 510, 218, 202, 205, 202, 198, 202, 198, 208, 201
// Java 11: replaceDirect: 384, 228, 204, 201, 201, 200, 206, 196, 200, 200
//
// => On Java 8, a custom implementation would make sense, however on Java 9
// String.replace() was optimized so that it does not make any difference
// anymore!
}
private void checkReplace(String orig) {
assertEquals(replaceString(orig, ",", "."), replaceDirect(orig, ",", "."),
"Did have a difference with " + orig);
}
public static String replaceString(String originalStr, String oldStr, String newStr) {
return originalStr.replace(oldStr, newStr);
}
public static String replaceDirect(String originalStr, String oldStr, String newStr) {
int p = originalStr.indexOf(oldStr);
if (p == -1) {
return originalStr;
} else {
StringBuilder result = new StringBuilder();
result.append(originalStr, 0, p);
result.append(newStr);
int q = p + oldStr.length();
while ((p = originalStr.indexOf(oldStr, q)) != -1) {
result.append(originalStr, q, p);
result.append(newStr);
q = p + oldStr.length();
}
result.append(originalStr, q, originalStr.length());
return result.toString();
}
}
@Test
public void testDeepFile() {
// returns with some System.err
try {
assertThrows(IOException.class,
() -> XLSX2CSV.main(new String[] { XSSFTestDataSamples.getSampleFile("deep-data.xlsx").getAbsolutePath() }));
} catch (Throwable e) {
// restore output-streams again to get proper error output
System.setErr(err);
throw e;
}
String output = errorBytes.toString(StandardCharsets.UTF_8);
assertFalse(output.contains("Not found"), "Had: " + output);
System.out.println(output);
} }
} }

View File

@ -23,15 +23,19 @@ configurations {
sourceSets { sourceSets {
main { main {
output.dir(JAVA9_OUT, builtBy: 'compileJava9') if (jdkVersion > 8) {
output.dir(JAVA9_OUT, builtBy: 'cacheJava9')
}
} }
test { test {
output.dir(TEST9_OUT, builtBy: 'compileTest9') if (jdkVersion > 8) {
output.dir(TEST9_OUT, builtBy: 'cacheTest9')
}
} }
} }
dependencies { dependencies {
api 'org.apache.ant:ant:1.10.15' api 'org.apache.ant:ant:1.10.12'
api project(':poi-ooxml') api project(':poi-ooxml')
compileOnly project(path: ':poi-ooxml', configuration: 'archives') compileOnly project(path: ':poi-ooxml', configuration: 'archives')
@ -41,10 +45,14 @@ dependencies {
testImplementation(project(path: ':poi-ooxml', configuration: 'tests')) { testImplementation(project(path: ':poi-ooxml', configuration: 'tests')) {
exclude group: 'org.apache.poi', module: 'poi-scratchpad' exclude group: 'org.apache.poi', module: 'poi-scratchpad'
} }
testImplementation 'com.google.guava:guava:33.5.0-jre' testImplementation 'com.google.guava:guava:31.1-jre'
testImplementation "org.apache.logging.log4j:log4j-slf4j2-impl:${log4jVersion}" testImplementation "org.apache.logging.log4j:log4j-slf4j18-impl:${log4jVersion}"
testImplementation 'org.slf4j:slf4j-simple:2.0.17' testImplementation 'org.slf4j:slf4j-simple:1.7.36'
testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}" testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}"
if (SAXON_TEST) {
testRuntimeOnly "net.sf.saxon:Saxon-HE:${saxonVersion}"
}
} }
final String MODULE_NAME = 'org.apache.poi.excelant' final String MODULE_NAME = 'org.apache.poi.excelant'
@ -54,48 +62,75 @@ final List MAIN_MODULE_PATH = sourceSets.main.runtimeClasspath.findAll{ it.path
final List TEST_MODULE_PATH = configurations.testRuntimeClasspath.findAll{ it.path =~ MODULE_REGEX && !(it.path =~ MODULE_NOT_REGEX) }.collect{ it.parent }.unique() final List TEST_MODULE_PATH = configurations.testRuntimeClasspath.findAll{ it.path =~ MODULE_REGEX && !(it.path =~ MODULE_NOT_REGEX) }.collect{ it.parent }.unique()
final String OOXML_LITE_AGENT = "../build/dist/maven/poi-ooxml-lite-agent/poi-ooxml-lite-agent-${project.version}.jar" final String OOXML_LITE_AGENT = "../build/dist/maven/poi-ooxml-lite-agent/poi-ooxml-lite-agent-${project.version}.jar"
final String OOXML_LITE_REPORT = '../src/resources/ooxml-lite-report' final String OOXML_LITE_REPORT = '../build/ooxml-lite-report'
final String OOXML_LITE_JAR = "../build/dist/maven/poi-ooxml-lite/poi-ooxml-lite-${project.version}.jar"
final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)" final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)"
tasks.register('compileJava9', JavaCompile) { task compileJava9(type: JavaCompile) {
dependsOn 'compileJava', ':poi-ooxml:jar', ':poi-scratchpad:jar' dependsOn 'compileJava', ':poi-ooxml:jar', ':poi-scratchpad:jar'
javaCompiler = javaToolchains.compilerFor { javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion)) languageVersion = JavaLanguageVersion.of(jdkVersion)
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
} }
sourceCompatibility = 11
targetCompatibility = 11
destinationDirectory = file(JAVA9_OUT + VERSIONS9) destinationDirectory = file(JAVA9_OUT + VERSIONS9)
source = file(JAVA9_SRC) source = file(JAVA9_SRC)
classpath = files() classpath = files()
options.compilerArgs = [ options.compilerArgs = [
'--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}", '--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}",
'--module-path', files(MAIN_MODULE_PATH).asPath '--module-path', files(MAIN_MODULE_PATH).asPath
] ]
onlyIf {
jdkVersion > 8
}
} }
tasks.register('compileTest9', JavaCompile) { task cacheJava9(type: Copy) {
dependsOn 'compileJava9'
from(file(JAVA9_OUT + VERSIONS9))
into(JAVA9_SRC)
}
task compileTest9(type: JavaCompile) {
dependsOn 'compileTestJava', ':poi-ooxml:jar', ':poi-scratchpad:jar' dependsOn 'compileTestJava', ':poi-ooxml:jar', ':poi-scratchpad:jar'
javaCompiler = javaToolchains.compilerFor { javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion)) languageVersion = JavaLanguageVersion.of(jdkVersion)
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
} }
sourceCompatibility = 11
targetCompatibility = 11
destinationDirectory = file(TEST9_OUT + VERSIONS9) destinationDirectory = file(TEST9_OUT + VERSIONS9)
source = file(TEST9_SRC) source = file(TEST9_SRC)
options.compilerArgs = [ options.compilerArgs = [
'--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}", '--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}",
'--module-path', files(TEST_MODULE_PATH).asPath '--module-path', files(TEST_MODULE_PATH).asPath
] ]
classpath = files() classpath = files()
onlyIf {
jdkVersion > 8
}
} }
jar { task cacheTest9(type: Copy) {
dependsOn compileJava9 dependsOn 'compileTest9'
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") from(file(TEST9_OUT + VERSIONS9))
into(TEST9_SRC)
}
jar {
dependsOn cacheJava9
destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
if (jdkVersion == 8) {
into('META-INF/versions/9') {
from JAVA9_SRC include '*.class'
}
}
manifest { manifest {
attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true') attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true')
@ -118,12 +153,18 @@ sourcesJar {
// Create a separate jar for test-code to depend on it in other projects // Create a separate jar for test-code to depend on it in other projects
// See http://stackoverflow.com/questions/5144325/gradle-test-dependency // See http://stackoverflow.com/questions/5144325/gradle-test-dependency
task testJar(type: Jar, dependsOn: [ testClasses, compileTest9 ] ) { task testJar(type: Jar, dependsOn: [ testClasses, cacheTest9 ] ) {
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}-tests") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}-tests")
setArchiveClassifier 'tests' classifier 'tests'
// ignore second module-info.class from main // ignore second module-info.class from main
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = 'exclude'
if (jdkVersion == 8) {
into('META-INF/versions/9') {
from TEST9_SRC include '*.class'
}
}
from sourceSets.test.output + sourceSets.main.output from sourceSets.test.output + sourceSets.main.output
@ -142,9 +183,13 @@ test {
doFirst { doFirst {
jvmArgs += [ jvmArgs += [
"-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}", "-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}",
'--add-modules', MODULE_NAME,
'--module-path', '../build/dist/maven/poi-excelant-tests' + File.pathSeparator + files(TEST_MODULE_PATH).asPath,
] ]
if (jdkVersion > 8) {
jvmArgs += [
'--add-modules', MODULE_NAME,
'--module-path', '../build/dist/maven/poi-excelant-tests' + File.pathSeparator + files(TEST_MODULE_PATH).asPath,
]
}
} }
} }
@ -158,22 +203,3 @@ publishing {
} }
} }
} }
cyclonedxBom {
// includeConfigs is the list of configuration names to include when generating the BOM (leave empty to include every configuration)
includeConfigs = ["runtimeClasspath"]
// skipConfigs is a list of configuration names to exclude when generating the BOM
//skipConfigs = ["compileClasspath", "testCompileClasspath"]
// Specified the type of project being built. Defaults to 'library'
projectType = "library"
// Specified the version of the CycloneDX specification to use. Defaults to 1.4.
schemaVersion = "1.4"
// Boms destination directory (defaults to build/reports)
destination = file("build/reports")
// The file name for the generated BOMs (before the file format suffix). Defaults to 'bom'
outputName = "poi-excelant-${project.version}.bom"
// The file format generated, can be xml, json or all for generating both
outputFormat = "all"
// Exclude BOM Serial Number
includeBomSerialNumber = true
}

View File

@ -37,7 +37,7 @@ import org.apache.tools.ant.Task;
* <p> * <p>
* In order to use this tag you must write a class that implements the * In order to use this tag you must write a class that implements the
* {@code IExcelAntWorkbookHandler} interface. After writing the * {@code IExcelAntWorkbookHandler} interface. After writing the
* class you should package it and its dependencies into a jar file to * class you should package it and it's dependencies into a jar file to
* add as library in your Ant build file. * add as library in your Ant build file.
*/ */
public class ExcelAntHandlerTask extends Task { public class ExcelAntHandlerTask extends Task {

View File

@ -27,7 +27,7 @@ import java.util.Map;
*/ */
public final class ExcelAntWorkbookUtilFactory { public final class ExcelAntWorkbookUtilFactory {
private static final Map<String, ExcelAntWorkbookUtil> workbookUtilMap = new HashMap<>(); private static Map<String, ExcelAntWorkbookUtil> workbookUtilMap;
private ExcelAntWorkbookUtilFactory() { private ExcelAntWorkbookUtilFactory() {
} }
@ -41,14 +41,16 @@ public final class ExcelAntWorkbookUtilFactory {
* a freshly instantiated one if none did exist before. * a freshly instantiated one if none did exist before.
*/ */
public static ExcelAntWorkbookUtil getInstance(String fileName) { public static ExcelAntWorkbookUtil getInstance(String fileName) {
synchronized (workbookUtilMap) { if(workbookUtilMap == null) {
if(workbookUtilMap.containsKey(fileName)) { workbookUtilMap = new HashMap<>();
return workbookUtilMap.get(fileName);
}
ExcelAntWorkbookUtil wbu = new ExcelAntWorkbookUtil(fileName);
workbookUtilMap.put(fileName, wbu);
return wbu;
} }
if(workbookUtilMap.containsKey(fileName)) {
return workbookUtilMap.get(fileName);
}
ExcelAntWorkbookUtil wbu = new ExcelAntWorkbookUtil(fileName);
workbookUtilMap.put(fileName, wbu);
return wbu;
} }
} }

Binary file not shown.

View File

@ -18,7 +18,6 @@
module org.apache.poi.excelant { module org.apache.poi.excelant {
requires ant; requires ant;
requires transitive org.apache.poi.poi;
requires org.apache.poi.ooxml; requires org.apache.poi.ooxml;
exports org.apache.poi.ss.excelant; exports org.apache.poi.ss.excelant;

View File

@ -28,7 +28,7 @@ import org.junit.platform.launcher.TestIdentifier;
/** /**
* Custom listener class for Ants junitlauncher, because it chomps the important running details * Custom listener class for Ants junitlauncher, because it chomps the important running details
* *
* @see <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=64836">Bug 64836 - junitlauncher poor summary</a> * @see <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=64836">Bug 64836 - junitlaucher poor summary</a>
**/ **/
public class Junit5Progress implements TestExecutionListener { public class Junit5Progress implements TestExecutionListener {
private final AtomicInteger numSkippedInTestSet = new AtomicInteger(); private final AtomicInteger numSkippedInTestSet = new AtomicInteger();
@ -76,17 +76,17 @@ public class Junit5Progress implements TestExecutionListener {
String summary = String.format("Tests run: %d, Failures: %d, Aborted: %d, Skipped: %d, Time elapsed: %f sec", totalTestsInClass, String summary = String.format("Tests run: %d, Failures: %d, Aborted: %d, Skipped: %d, Time elapsed: %f sec", totalTestsInClass,
this.numFailedInTestSet.get(), this.numAbortedInTestSet.get(), this.numSkippedInTestSet.get(), numSeconds); this.numFailedInTestSet.get(), this.numAbortedInTestSet.get(), this.numSkippedInTestSet.get(), numSeconds);
println(summary); println(summary);
} else { } else if (testIdentifier.isTest()) {
switch (testExecutionResult.getStatus()) { switch (testExecutionResult.getStatus()) {
case SUCCESSFUL: case SUCCESSFUL:
this.numSucceededInTestSet.incrementAndGet(); this.numSucceededInTestSet.incrementAndGet();
break; break;
case ABORTED: case ABORTED:
println(" Aborted: " + testIdentifier.getDisplayName() + ": " + testExecutionResult.getThrowable().orElse(null)); println(" Aborted: " + testIdentifier.getDisplayName());
this.numAbortedInTestSet.incrementAndGet(); this.numAbortedInTestSet.incrementAndGet();
break; break;
case FAILED: case FAILED:
println(" Failed: " + testIdentifier.getDisplayName() + ": " + testExecutionResult.getThrowable().orElse(null)); println(" Failed: " + testIdentifier.getDisplayName());
this.numFailedInTestSet.incrementAndGet(); this.numFailedInTestSet.incrementAndGet();
break; break;
} }

Binary file not shown.

View File

@ -1,3 +1,5 @@
import java.util.regex.Pattern
/* ==================================================================== /* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
@ -15,10 +17,8 @@
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
import java.util.regex.Pattern
final String TEST9_SRC = 'src/test/java9' final String TEST9_SRC = 'src/test/java9'
final String TEST9_OUT = layout.buildDirectory.dir('classes/java9/test/').get().asFile.absolutePath final String TEST9_OUT = "${buildDir}/classes/java9/test/"
final String VERSIONS9 = 'META-INF/versions/9' final String VERSIONS9 = 'META-INF/versions/9'
final boolean IBMVM = System.getProperty("java.vendor").contains("IBM") final boolean IBMVM = System.getProperty("java.vendor").contains("IBM")
@ -29,7 +29,9 @@ configurations {
sourceSets { sourceSets {
test { test {
output.dir(TEST9_OUT, builtBy: 'compileTest9') if (jdkVersion > 8) {
output.dir(TEST9_OUT, builtBy: 'cacheTest9')
}
if (IBMVM) { if (IBMVM) {
java { java {
exclude '**/HeapDump**' exclude '**/HeapDump**'
@ -39,9 +41,9 @@ sourceSets {
} }
dependencies { dependencies {
testImplementation 'org.apache.ant:ant:1.10.15' testImplementation 'org.apache.ant:ant:1.10.12'
testImplementation 'org.apache.commons:commons-collections4:4.5.0' testImplementation 'org.apache.commons:commons-collections4:4.4'
testImplementation 'com.google.guava:guava:33.5.0-jre' testImplementation 'com.google.guava:guava:31.1-jre'
misc(project(':poi-ooxml')) { misc(project(':poi-ooxml')) {
capabilities { capabilities {
@ -75,9 +77,13 @@ dependencies {
} }
} }
testImplementation project(path: ':poi-ooxml-lite-agent', configuration: 'archives') testImplementation project(path: ':poi-ooxml-lite-agent', configuration: 'archives')
testImplementation "org.apache.logging.log4j:log4j-slf4j2-impl:${log4jVersion}" testImplementation "org.apache.logging.log4j:log4j-slf4j18-impl:${log4jVersion}"
testImplementation 'org.slf4j:slf4j-simple:2.0.17' testImplementation 'org.slf4j:slf4j-simple:1.7.36'
testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}" testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}"
if (SAXON_TEST) {
testRuntimeOnly "net.sf.saxon:Saxon-HE:${saxonVersion}"
}
} }
final String MODULE_NAME = 'org.apache.poi.stress' final String MODULE_NAME = 'org.apache.poi.stress'
@ -87,29 +93,47 @@ final List MODULE_COMPILE_PATH = (sourceSets.test.compileClasspath + configurati
final List MODULE_RUNTIME_PATH = (sourceSets.test.runtimeClasspath + configurations.misc.files).findAll{ it.path =~ MODULE_REGEX && !(it.path =~ MODULE_NOT_REGEX) }.collect{ it.parent }.unique() final List MODULE_RUNTIME_PATH = (sourceSets.test.runtimeClasspath + configurations.misc.files).findAll{ it.path =~ MODULE_REGEX && !(it.path =~ MODULE_NOT_REGEX) }.collect{ it.parent }.unique()
final String OOXML_LITE_AGENT = "../build/dist/maven/poi-ooxml-lite-agent/poi-ooxml-lite-agent-${project.version}.jar" final String OOXML_LITE_AGENT = "../build/dist/maven/poi-ooxml-lite-agent/poi-ooxml-lite-agent-${project.version}.jar"
final String OOXML_LITE_REPORT = '../src/resources/ooxml-lite-report' final String OOXML_LITE_REPORT = '../build/ooxml-lite-report'
final String OOXML_LITE_JAR = "../build/dist/maven/poi-ooxml-lite/poi-ooxml-lite-${project.version}.jar"
final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)" final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)"
tasks.register('compileTest9', JavaCompile) { java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(jdkVersion))
if (jdkVendor != '') vendor.set(JvmVendorSpec.matching(jdkVendor))
}
}
task compileTest9(type: JavaCompile) {
dependsOn 'compileTestJava', ':poi-ooxml:testJar', ':poi-scratchpad:testJar', ':poi-examples:jar' dependsOn 'compileTestJava', ':poi-ooxml:testJar', ':poi-scratchpad:testJar', ':poi-examples:jar'
javaCompiler = javaToolchains.compilerFor { javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion)) languageVersion = JavaLanguageVersion.of(jdkVersion)
if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
} }
sourceCompatibility = 11
targetCompatibility = 11
destinationDirectory = file(TEST9_OUT + VERSIONS9) destinationDirectory = file(TEST9_OUT + VERSIONS9)
source = file(TEST9_SRC) source = file(TEST9_SRC)
options.compilerArgs = [ options.compilerArgs = [
'--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}", '--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}",
'--module-path', files(MODULE_COMPILE_PATH).asPath '--module-path', files(MODULE_COMPILE_PATH).asPath
] ]
classpath = files() classpath = files()
onlyIf {
jdkVersion > 8
}
} }
task cacheTest9(type: Copy) {
dependsOn 'compileTest9'
from(file(TEST9_OUT + VERSIONS9))
into(TEST9_SRC)
}
jar { jar {
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
manifest { manifest {
attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true') attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true')
@ -118,12 +142,18 @@ jar {
// Create a separate jar for test-code to depend on it in other projects // Create a separate jar for test-code to depend on it in other projects
// See http://stackoverflow.com/questions/5144325/gradle-test-dependency // See http://stackoverflow.com/questions/5144325/gradle-test-dependency
task testJar(type: Jar, dependsOn: [ testClasses, compileTest9 ] ) { task testJar(type: Jar, dependsOn: [ testClasses, cacheTest9 ] ) {
destinationDirectory = file("../build/dist/maven/${base.archivesName.get()}-tests") destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}-tests")
setArchiveClassifier 'tests' classifier 'tests'
// ignore second module-info.class from main // ignore second module-info.class from main
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = 'exclude'
if (jdkVersion == 8) {
into('META-INF/versions/9') {
from TEST9_SRC include '*.class'
}
}
from sourceSets.test.output + sourceSets.main.output from sourceSets.test.output + sourceSets.main.output
@ -147,22 +177,24 @@ test {
doFirst { doFirst {
jvmArgs += [ jvmArgs += [
"-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}", "-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}",
'--add-modules', MODULE_NAME,
'--module-path', '../build/dist/maven/poi-integration-tests' + File.pathSeparator + files(MODULE_RUNTIME_PATH).asPath,
] ]
if (jdkVersion > 8) {
jvmArgs += [
'--add-modules', MODULE_NAME,
'--module-path', '../build/dist/maven/poi-integration-tests' + File.pathSeparator + files(MODULE_RUNTIME_PATH).asPath,
]
}
if (NO_SCRATCHPAD) { if (NO_SCRATCHPAD) {
systemProperty 'scratchpad.ignore', 'true' systemProperty 'scratchpad.ignore', 'true'
} }
} }
} }
javadoc { javadoc.onlyIf { false }
enabled = false
}
sourcesJar { javadocJar.onlyIf { false }
enabled = false
} sourcesJar.onlyIf { false }
generateMetadataFileForPOIPublication.enabled = false generateMetadataFileForPOIPublication.enabled = false
publishPOIPublicationToMavenLocal.enabled = false publishPOIPublicationToMavenLocal.enabled = false

View File

@ -27,14 +27,11 @@ Before running this, you should execute the "jar" target in the main build.gradl
<property name="dist" value="../build/dist"/> <property name="dist" value="../build/dist"/>
<property name="build" value="../build/distsourcebuild"/> <property name="build" value="../build/distsourcebuild"/>
<!-- Gradle is executed in ../build/poi-<version>, so three ".." are needed to use gradle from the root-dir --> <condition property="gradle.executable" value="../gradlew.bat" else="../gradlew">
<condition property="gradle.executable" value="../../../gradlew.bat" else="../../../gradlew">
<os family="windows" /> <os family="windows" />
</condition> </condition>
<target name="init" depends=""> <target name="init" depends="">
<echo message="Using Ant: ${ant.version} from ${ant.home}, Ant detected Java ${ant.java.version} (may be different than actual Java sometimes...)" />
<echo message="Using Java: ${java.version}/${java.runtime.version}/${java.vm.version}/${java.vm.name} from ${java.vm.vendor} on ${os.name}: ${os.version}" />
</target> </target>
<target name="run" depends="init,runSourceBuild,runCompileTest"/> <target name="run" depends="init,runSourceBuild,runCompileTest"/>
@ -51,14 +48,14 @@ Before running this, you should execute the "jar" target in the main build.gradl
<date xmlns="antlib:org.apache.tools.ant.types.resources.comparators"/> <date xmlns="antlib:org.apache.tools.ant.types.resources.comparators"/>
<resources> <resources>
<fileset dir="${dist}"> <fileset dir="${dist}">
<include name="apache-poi-src-*.zip"/> <include name="poi-src-*.zip"/>
</fileset> </fileset>
</resources> </resources>
</sort> </sort>
</last> </last>
</pathconvert> </pathconvert>
<echo message="Found source package with pattern 'apache-poi-src-*.zip' in ${dist} at '${srcpackage}'. Run Gradle-task 'srcDistZip' in the main directory if it is missing"/> <echo message="Found source package at ${srcpackage}"/>
<unzip src="${srcpackage}" dest="${build}" failOnEmptyArchive="true"/> <unzip src="${srcpackage}" dest="${build}" failOnEmptyArchive="true"/>
<!-- look for name of sub-dir, do this dynamically as it changes with every (beta|rc)-release --> <!-- look for name of sub-dir, do this dynamically as it changes with every (beta|rc)-release -->
@ -77,7 +74,7 @@ Before running this, you should execute the "jar" target in the main build.gradl
<!-- finally call Ant on the extracted source to check if we can build the packages --> <!-- finally call Ant on the extracted source to check if we can build the packages -->
<echo message="Building in temporary dir ${dirversion}/"/> <echo message="Building in temporary dir ${dirversion}/"/>
<!--ant dir="${dirversion}" target="assemble" inheritAll="false" inheritRefs="false" useNativeBasedir="true"/--> <!--ant dir="${dirversion}" target="assemble" inheritAll="false" inheritRefs="false" useNativeBasedir="true"/-->
<exec executable="${gradle.executable}" dir="${dirversion}" failonerror="true"> <exec executable="${gradle.executable}" dir="." failonerror="true">
<arg value="assemble" /> <arg value="assemble" />
</exec> </exec>
</target> </target>
@ -94,9 +91,9 @@ Before running this, you should execute the "jar" target in the main build.gradl
<sort> <sort>
<resources> <resources>
<fileset dir="${dist}"> <fileset dir="${dist}">
<include name="**/poi-6.*.jar"/> <include name="**/poi-5.*.jar"/>
<include name="**/poi-ooxml-6.*.jar"/> <include name="**/poi-ooxml-5.*.jar"/>
<include name="**/poi-ooxml-lite-6.*.jar"/> <include name="**/poi-ooxml-lite-5.*.jar"/>
<exclude name="**/*-javadoc*"/> <exclude name="**/*-javadoc*"/>
<exclude name="**/*-sources*"/> <exclude name="**/*-sources*"/>
</fileset> </fileset>
@ -126,7 +123,7 @@ Before running this, you should execute the "jar" target in the main build.gradl
<echo message="Compiling examples without linking to scratchpad.jar to ensure that only some specific ones require this jar"/> <echo message="Compiling examples without linking to scratchpad.jar to ensure that only some specific ones require this jar"/>
<javac srcdir="../poi-examples/src/main/java" destdir="${build}" <javac srcdir="../poi-examples/src/main/java" destdir="${build}"
target="11" source="11" debug="true" target="1.8" source="1.8" debug="true"
encoding="ASCII" fork="yes" includeantruntime="false" encoding="ASCII" fork="yes" includeantruntime="false"
excludes="org/apache/poi/examples/hslf/**,org/apache/poi/examples/hsmf/**,org/apache/poi/examples/hwmf/**,**/EmbeddedObjects.java,**/EmeddedObjects.java,**/LoadEmbedded.java,**/Word2Forrest.java" excludes="org/apache/poi/examples/hslf/**,org/apache/poi/examples/hsmf/**,org/apache/poi/examples/hwmf/**,**/EmbeddedObjects.java,**/EmeddedObjects.java,**/LoadEmbedded.java,**/Word2Forrest.java"
classpath="${jarpackage}" classpathref="libs"> classpath="${jarpackage}" classpathref="libs">
@ -137,10 +134,10 @@ Before running this, you should execute the "jar" target in the main build.gradl
<sort> <sort>
<resources> <resources>
<fileset dir="${dist}"> <fileset dir="${dist}">
<include name="**/poi-6.*.jar"/> <include name="**/poi-5.*.jar"/>
<include name="**/poi-ooxml-6.*.jar"/> <include name="**/poi-ooxml-5.*.jar"/>
<include name="**/poi-ooxml-lite-6.*.jar"/> <include name="**/poi-ooxml-lite-5.*.jar"/>
<include name="**/poi-scratchpad-6.*.jar"/> <include name="**/poi-scratchpad-5.*.jar"/>
<exclude name="**/*-javadoc*"/> <exclude name="**/*-javadoc*"/>
<exclude name="**/*-sources*"/> <exclude name="**/*-sources*"/>
</fileset> </fileset>
@ -150,7 +147,7 @@ Before running this, you should execute the "jar" target in the main build.gradl
<echo message="Compiling all examples with the additional scratchpad.jar"/> <echo message="Compiling all examples with the additional scratchpad.jar"/>
<javac srcdir="../poi-examples/src/main/java" destdir="${build}" <javac srcdir="../poi-examples/src/main/java" destdir="${build}"
target="11" source="11" debug="true" target="1.8" source="1.8" debug="true"
encoding="ASCII" fork="yes" includeantruntime="false" encoding="ASCII" fork="yes" includeantruntime="false"
classpath="${jarpackagescratchpad}" classpathref="libs"> classpath="${jarpackagescratchpad}" classpathref="libs">
</javac> </javac>

View File

@ -37,6 +37,7 @@ import org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor;
import org.apache.poi.hssf.extractor.EventBasedExcelExtractor; import org.apache.poi.hssf.extractor.EventBasedExcelExtractor;
import org.apache.poi.ooxml.POIXMLException; import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ss.extractor.ExcelExtractor; import org.apache.poi.ss.extractor.ExcelExtractor;
import org.apache.poi.util.IOUtils;
/** /**
* Base class with things that can be run for any supported file handler * Base class with things that can be run for any supported file handler
@ -87,78 +88,54 @@ public abstract class AbstractFileHandler implements FileHandler {
long length = file.length(); long length = file.length();
long modified = file.lastModified(); long modified = file.lastModified();
POITextExtractor extractor = null;
String fileAndParentName = file.getParentFile().getName() + "/" + file.getName(); String fileAndParentName = file.getParentFile().getName() + "/" + file.getName();
try { try {
handleExtractingAsStream(file);
// fix windows absolute paths for exception message tracking // fix windows absolute paths for exception message tracking
String relPath = file.getPath().replaceAll(".*test-data", "test-data").replace('\\', '/'); String relPath = file.getPath().replaceAll(".*test-data", "test-data").replace('\\', '/');
try (POITextExtractor extractor = ExtractorFactory.createExtractor(file)) { extractor = ExtractorFactory.createExtractor(file);
assertNotNull(extractor, "Should get a POITextExtractor but had none for file " + relPath); assertNotNull(extractor, "Should get a POITextExtractor but had none for file " + relPath);
assertNotNull(extractor.getText(), "Should get some text but had none for file " + relPath); assertNotNull(extractor.getText(), "Should get some text but had none for file " + relPath);
// also try metadata // also try metadata
POITextExtractor metadataExtractor = extractor.getMetadataTextExtractor(); @SuppressWarnings("resource")
assertNotNull(metadataExtractor.getText()); POITextExtractor metadataExtractor = extractor.getMetadataTextExtractor();
assertNotNull(metadataExtractor.getText());
assertFalse(EXPECTED_EXTRACTOR_FAILURES.contains(fileAndParentName), assertFalse(EXPECTED_EXTRACTOR_FAILURES.contains(fileAndParentName),
"Expected Extraction to fail for file " + relPath + " and handler " + this + ", but did not fail!"); "Expected Extraction to fail for file " + relPath + " and handler " + this + ", but did not fail!");
assertEquals(length, file.length(), "File should not be modified by extractor"); assertEquals(length, file.length(), "File should not be modified by extractor");
assertEquals(modified, file.lastModified(), "File should not be modified by extractor"); assertEquals(modified, file.lastModified(), "File should not be modified by extractor");
if (extractor instanceof POIOLE2TextExtractor) { handleExtractingAsStream(file);
POIOLE2TextExtractor ole2Extractor = (POIOLE2TextExtractor) extractor;
ole2Extractor.getRoot();
if (!(ole2Extractor instanceof EventBasedExcelExtractor)) {
ole2Extractor.getSummaryInformation();
ole2Extractor.getDocSummaryInformation();
}
try (HPSFPropertiesExtractor hpsfExtractor = new HPSFPropertiesExtractor(ole2Extractor)) { if (extractor instanceof POIOLE2TextExtractor) {
assertNotNull(hpsfExtractor.getDocumentSummaryInformationText()); try (HPSFPropertiesExtractor hpsfExtractor = new HPSFPropertiesExtractor((POIOLE2TextExtractor) extractor)) {
assertNotNull(hpsfExtractor.getSummaryInformationText()); assertNotNull(hpsfExtractor.getDocumentSummaryInformationText());
String text = hpsfExtractor.getText(); assertNotNull(hpsfExtractor.getSummaryInformationText());
//System.out.println(text); String text = hpsfExtractor.getText();
assertNotNull(text); //System.out.println(text);
}
if (ole2Extractor.getRoot() != null && !Boolean.getBoolean("scratchpad.ignore")) {
POITextExtractor[] embedded = ExtractorFactory.getEmbeddedDocsTextExtractors(ole2Extractor);
try {
for (POITextExtractor poiTextExtractor : embedded) {
poiTextExtractor.getText();
poiTextExtractor.getDocument();
poiTextExtractor.getFilesystem();
POITextExtractor metaData = poiTextExtractor.getMetadataTextExtractor();
metaData.getFilesystem();
metaData.getText();
}
} finally {
for (POITextExtractor embeddedExtractor : embedded) {
embeddedExtractor.close();
}
}
}
}
// test again with including formulas and cell-comments as this caused some bugs
if (extractor instanceof ExcelExtractor &&
// comment-extraction and formula extraction are not well supported in event based extraction
!(extractor instanceof EventBasedExcelExtractor)) {
((ExcelExtractor) extractor).setFormulasNotResults(true);
String text = extractor.getText();
assertNotNull(text);
// */
((ExcelExtractor) extractor).setIncludeCellComments(true);
text = extractor.getText();
assertNotNull(text); assertNotNull(text);
} }
} }
// test again with including formulas and cell-comments as this caused some bugs
if (extractor instanceof ExcelExtractor &&
// comment-extraction and formula extraction are not well supported in event based extraction
!(extractor instanceof EventBasedExcelExtractor)) {
((ExcelExtractor) extractor).setFormulasNotResults(true);
String text = extractor.getText();
assertNotNull(text);
// */
((ExcelExtractor) extractor).setIncludeCellComments(true);
text = extractor.getText();
assertNotNull(text);
}
} catch (IOException | POIXMLException e) { } catch (IOException | POIXMLException e) {
Exception prevE = e; Exception prevE = e;
Throwable cause; Throwable cause;
@ -182,6 +159,8 @@ public abstract class AbstractFileHandler implements FileHandler {
if (!e.getMessage().contains("POI Scratchpad jar missing") || !Boolean.getBoolean("scratchpad.ignore")) { if (!e.getMessage().contains("POI Scratchpad jar missing") || !Boolean.getBoolean("scratchpad.ignore")) {
throw e; throw e;
} }
} finally {
IOUtils.closeQuietly(extractor);
} }
} }
@ -191,11 +170,6 @@ public abstract class AbstractFileHandler implements FileHandler {
assertNotNull(streamExtractor); assertNotNull(streamExtractor);
assertNotNull(streamExtractor.getText()); assertNotNull(streamExtractor.getText());
POITextExtractor metadataTextExtractor = streamExtractor.getMetadataTextExtractor();
assertNotNull(metadataTextExtractor);
assertNotNull(metadataTextExtractor.getText());
} }
} }
} }

View File

@ -90,7 +90,7 @@ public class ExcInfo {
public boolean isValid(String testName, String handler) { public boolean isValid(String testName, String handler) {
return return
!IGNORED_TESTS.equals(tests) && !IGNORED_TESTS.equals(tests) &&
(tests == null || (tests.contains(testName) && !tests.contains("!"+testName))) && (tests == null || tests.contains(testName)) &&
(this.handler == null || (this.handler.contains(handler) && !this.handler.contains("!"+handler))); (this.handler == null || this.handler.contains(handler));
} }
} }

View File

@ -29,8 +29,6 @@ public enum FileHandlerKnown {
HSLF, HSLF,
HSMF, HSMF,
HSSF, HSSF,
HEMF,
HWMF,
HWPF, HWPF,
OPC, OPC,
POIFS, POIFS,

View File

@ -1,85 +0,0 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.stress;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.poi.hemf.record.emf.HemfRecord;
import org.apache.poi.hemf.record.emf.HemfRecordType;
import org.apache.poi.hemf.record.emf.HemfText;
import org.apache.poi.hemf.usermodel.HemfPicture;
import org.junit.jupiter.api.Test;
public class HEMFFileHandler implements FileHandler {
@Override
public void handleExtracting(File file) throws Exception {
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
HemfPicture picture = new HemfPicture(stream);
// mimic a bit what e.g. Tika does to extract some information from .emf files
for (HemfRecord record : picture.getRecords()) {
if (record.getEmfRecordType().equals(HemfRecordType.extTextOutW)) {
assertInstanceOf(HemfText.EmfExtTextOutW.class, record);
HemfText.EmfExtTextOutW textOut = (HemfText.EmfExtTextOutW) record;
textOut.getText(StandardCharsets.UTF_16LE);
} else if (record.getEmfRecordType().equals(HemfRecordType.extTextOutA)) {
assertInstanceOf(HemfText.EmfExtTextOutA.class, record);
HemfText.EmfExtTextOutA textOut = (HemfText.EmfExtTextOutA) record;
textOut.getText(StandardCharsets.UTF_8);
}
}
}
}
@Override
public void handleAdditional(File file) throws Exception {
// no additional checks for now
}
@Override
public void handleFile(InputStream stream, String path) throws Exception {
HemfPicture picture = new HemfPicture(stream);
for (HemfRecord record : picture.getRecords()) {
record.getEmfRecordType();
record.getGenericRecordType();
}
BufferedImage dest = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
picture.draw(dest.createGraphics(), new Rectangle2D.Double(0, 0, 256, 256));
}
@Test
void test() throws Exception {
String file = "test-data/slideshow/wrench.emf";
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
handleFile(stream, file);
}
handleExtracting(new File(file));
}
}

View File

@ -45,16 +45,22 @@ public class HPBFFileHandler extends POIFSFileHandler {
void test() throws Exception { void test() throws Exception {
File file = new File("test-data/publisher/SampleBrochure.pub"); File file = new File("test-data/publisher/SampleBrochure.pub");
try (InputStream stream = new FileInputStream(file)) { InputStream stream = new FileInputStream(file);
try {
handleFile(stream, file.getPath()); handleFile(stream, file.getPath());
} finally {
stream.close();
} }
handleExtracting(file); handleExtracting(file);
try (InputStream stream = new FileInputStream(file)) { stream = new FileInputStream(file);
try {
try (PublisherTextExtractor extractor = new PublisherTextExtractor(stream)) { try (PublisherTextExtractor extractor = new PublisherTextExtractor(stream)) {
assertNotNull(extractor.getText()); assertNotNull(extractor.getText());
} }
} finally {
stream.close();
} }
} }

View File

@ -43,6 +43,8 @@ import org.apache.poi.util.TempFile;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class HPSFFileHandler extends POIFSFileHandler { public class HPSFFileHandler extends POIFSFileHandler {
private static final String NL = System.getProperty("line.separator");
private static final ThreadLocal<File> copyOutput = ThreadLocal.withInitial(HPSFFileHandler::getTempFile); private static final ThreadLocal<File> copyOutput = ThreadLocal.withInitial(HPSFFileHandler::getTempFile);
static final Set<String> EXCLUDES_HANDLE_ADD = StressTestUtils.unmodifiableHashSet( static final Set<String> EXCLUDES_HANDLE_ADD = StressTestUtils.unmodifiableHashSet(
@ -101,7 +103,7 @@ public class HPSFFileHandler extends POIFSFileHandler {
private static boolean hasPropertyStream(POIFSFileSystem poifs, String streamName) throws IOException { private static boolean hasPropertyStream(POIFSFileSystem poifs, String streamName) throws IOException {
DirectoryNode root = poifs.getRoot(); DirectoryNode root = poifs.getRoot();
if (!root.hasEntryCaseInsensitive(streamName)) { if (!root.hasEntry(streamName)) {
return false; return false;
} }
try (DocumentInputStream dis = root.createDocumentInputStream(streamName)) { try (DocumentInputStream dis = root.createDocumentInputStream(streamName)) {
@ -138,10 +140,12 @@ public class HPSFFileHandler extends POIFSFileHandler {
try (InputStream stream = new FileInputStream(path)) { try (InputStream stream = new FileInputStream(path)) {
handleFile(stream, path); handleFile(stream, path);
} }
}
File file = new File(path); // a test-case to test this locally without executing the full TestAllFiles
@Test
void testExtractor() {
File file = new File("test-data/hpsf/TestBug44375.xls");
assertDoesNotThrow(() -> handleExtracting(file)); assertDoesNotThrow(() -> handleExtracting(file));
handleAdditional(file);
} }
} }

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