Compare commits

..

14 Commits

92 changed files with 762 additions and 1234 deletions

View File

@ -1,9 +1,15 @@
root = true
[*.{groovy,java,kt,xml}]
[*.{groovy, java, kt, xml}]
#缩进风格:空格
indent_style = space
#缩进大小
indent_size = 4
#换行符lf
end_of_line = lf
#字符集utf-8
charset = utf-8
#是否删除行尾的空格
trim_trailing_whitespace = true
insert_final_newline = true
#是否在文件的最后插入一个空行
insert_final_newline = true

View File

0
.github/ISSUE_TEMPLATE/bug.md vendored Normal file
View File

0
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

0
.github/ISSUE_TEMPLATE/suggest.md vendored Normal file
View File

View File

View File

@ -1,42 +1,57 @@
#
# Copyright 2009-2021 the original author or authors.
#
# 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.
#
name: Java CI
on:
pull_request:
branches: [ main ]
push:
branches: [ main ]
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
strategy:
matrix:
java: [ 8, 11, 17, 21]
distribution: [ 'adopt' ]
fail-fast: false
max-parallel: 4
name: Test JDK ${{ matrix.java }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@main
- name: Set up JDK
uses: actions/setup-java@v4
uses: actions/setup-java@main
with:
java-version: ${{ matrix.java }}
distribution: ${{ matrix.distribution }}
- name: Cache local Maven repository
uses: actions/cache@v4
uses: actions/cache@main
with:
path: ~/.m2/repository
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-m2
- name: Chmod
run: chmod +x mvnw
- name: Test with Maven
if: ${{ matrix.java == '8' }}
run: ./mvnw test -B -Dmaven.test.skip=false
- name: Test with Maven
if: ${{ matrix.java != '8' }}
run: ./mvnw test -B -Dmaven.test.skip=false -DargLine="--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/sun.reflect.annotation=ALL-UNNAMED"
- name: Maven Build
run: ./mvnw install -B -V
- name: Java Doc

View File

@ -1,17 +1,35 @@
#
# Copyright 2009-2021 the original author or authors.
#
# 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.
#
name: Publish package to the Maven Central Repository
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
uses: actions/checkout@main
- name: Install Java and Maven
uses: actions/setup-java@v4
uses: actions/setup-java@main
with:
java-version: 8
distribution: 'adopt'
@ -19,19 +37,19 @@ jobs:
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
- name: Cache local Maven repository
uses: actions/cache@v4
uses: actions/cache@main
with:
path: ~/.m2/repository
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-m2
- name: Install GPG secret key
run: cat <(echo -e "${{ secrets.GPG_PRIVATE_KEY }}") | gpg --batch --import
- id: install-secret-key
name: Install GPG secret key
run: |
cat <(echo -e "${{ secrets.GPG_PRIVATE_KEY }}") | gpg --batch --import
- name: Publish package
run: >
./mvnw --batch-mode clean deploy
-Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }}
-Dmaven.test.skip=true -Dmaven.javadoc.skip=false -Dgpg.skip=false
run: |
mvn --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} clean deploy -Dmaven.test.skip=true -Dmaven.javadoc.skip=false -Dgpg.skip=false
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}

27
.github/workflows/sync2gitee.yml vendored Normal file
View File

@ -0,0 +1,27 @@
# 通过 Github action 在仓库的每一次 commit 后自动同步到 Gitee 上
# 临时修改为手动触发,等待同步完成后再修改为自动触发
name: Mirror the Github organization repos to Gitee
on: workflow_dispatch
jobs:
repo-sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
with:
persist-credentials: false
- name: Mirror the Github organization repos to Gitee.
uses: Yikun/hub-mirror-action@master
with:
# 必选,需要同步的 Github 这里记住选择的是仓库 或者账号 而不是具体的项目
src: github/CodePhiliaX
# 必选,需要同步到的 Gitee 这里记住选择的是仓库 或者账号 而不是具体的项目
dst: gitee/fastexcel
# 必选Gitee公钥对应的私钥https://gitee.com/profile/sshkeys
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
# 必选Gitee对应的用于创建仓库的tokenhttps://gitee.com/profile/personal_access_tokens
dst_token: ${{ secrets.GITEE_TOKEN }}
# 如果是组织,指定组织即可,默认为用户 user
account_type: org
# 需要同步的仓库里面的项目
static_list: "fastexcel"

2
.gitignore vendored
View File

@ -15,5 +15,3 @@ antx.properties
output/
.flattened-pom.xml
dependency-reduced-pom.xml
/.mvn/wrapper/maven-wrapper.jar

BIN
.mvn/wrapper/maven-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -5,14 +5,14 @@
# 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.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar

View File

@ -1,14 +0,0 @@
# CHANGELOG
## 1.1.0
此次升级主要修复 [EasyExcel](https://github.com/alibaba/easyexcel) 历史 BUG同时剔除了部分依赖库符合 MIT 协议的相关规范。
具体更新内容如下:
- 【改进】移除 `itext` 依赖库,将 `转换PDF` 功能迁移至新项目;
- 【修复】fill填充空数据可能导致行数据错乱的问题
- 【修复】自定义数据格式可能导致数据读取失败的问题;
- 【优化】例行升级依赖的Jar包版本;
- 【优化】增加报错内容详细信息;
- 【优化】更新代码格式和部分错别字;
- 【优化】更新部分文档和使用说明。

View File

@ -1,144 +0,0 @@
# 为 FastExcel 做贡献
FastExcel 欢迎社区的每一位用户和开发者成为贡献者。无论是报告问题、改进文档、提交代码,还是提供技术支持,您的参与都将帮助 FastExcel 变得更好。
---
## 报告问题
我们鼓励用户在使用 FastExcel 的过程中随时提供反馈。您可以通过 [NEW ISSUE](https://github.com/fast-excel/fastexcel/issues/new/choose) 提交问题。
### 高质量问题报告
为了提高沟通效率,请在提交问题前:
1. **搜索现有问题**:检查您的问题是否已被报告。如果存在,请直接在现有问题下评论补充详细信息,而不是创建新问题。
2. **使用问题模板**:问题模板位于 [ISSUE TEMPLATE](./.github/ISSUE_TEMPLATE),请按照模板要求填写,以确保问题描述准确且完整。
以下情况适合提交新问题:
- Bug 报告
- 新功能需求
- 性能问题
- 功能提案或设计
- 文档改进
- 测试覆盖率优化
- 需要技术支持
- 其他与项目相关的问题
> **注意**:请勿在问题中包含敏感信息,如密码、密钥、服务器地址或私人数据。
---
## 贡献代码与文档
所有对 FastExcel 的改进均可通过 Pull Request (PR) 实现。无论是修复 Bug、优化代码、增强功能还是改进文档都非常欢迎
### 您可以贡献的方向
- 修复错别字
- 修复 Bug
- 删除冗余代码
- 添加测试用例
- 增强功能
- 添加注释以提升代码可读性
- 优化代码结构
- 改进或完善文档
**原则****任何有助于项目改进的 PR 都值得鼓励!**
在提交 PR 前,请熟悉以下指南:
1. [工作区准备](#工作区准备)
2. [分支定义](#分支定义)
3. [提交规则](#提交规则)
4. [PR 说明](#pr说明)
---
### 工作区准备
确保您已注册 GitHub 账号,并按照以下步骤完成本地开发环境配置:
1. **Fork 仓库**:在 FastExcel 的 [GitHub 页面](https://github.com/fast-excel/fastexcel) 点击 `Fork` 按钮,将项目复制到您的 GitHub 账户下,例如:`https://github.com/<your-username>/fastexcel`
2. **克隆代码库**:运行以下命令将 Fork 的项目克隆到本地:
```bash
git clone git@github.com:<your-username>/fastexcel.git
```
3. **设置上游仓库**:将官方仓库设置为 `upstream`,方便同步更新:
```bash
git remote add upstream git@github.com:fast-excel/fastexcel.git
git remote set-url --push upstream no-pushing
```
运行 `git remote -v` 可检查配置是否正确。
---
### 分支定义
在 FastExcel 中,所有贡献应基于 `main` 开发分支。此外,还有以下分支类型:
- **release 分支**:用于版本发布(如 `0.6.0`, `0.6.1`)。
- **feature 分支**:用于开发较大的功能。
- **hotfix 分支**:用于修复重要 Bug。
提交 PR 时,请确保变更基于 `main` 分支。
---
### 提交规则
#### 提交信息
请确保提交消息清晰且具有描述性,遵循以下格式:
- **docs**: 更新文档,例如 `docs: 更新 PR 提交指南`
- **feature**: 新功能,例如 `feature: 支持 并发写入`
- **bugfix**: 修复 Bug例如 `bugfix: 修复空指针异常`
- **refactor**: 重构代码,例如 `refactor: 优化数据处理逻辑`
- **test**: 增加或改进测试,例如 `test: 添加单元测试`
不建议使用模糊的提交信息,如:
- ~~修复问题~~
- ~~更新代码~~
如果需要帮助,请参考 [如何编写 Git 提交消息](http://chris.beams.io/posts/git-commit/)。
#### 提交内容
一次提交应包含完整且可审查的更改,确保:
- 避免提交过于庞大的改动。
- 每次提交内容独立且可通过 CI 测试。
另外,请确保提交时配置正确的 Git 用户信息:
```bash
git config --get user.name
git config --get user.email
```
---
### PR 说明
为了帮助审阅者快速了解 PR 的内容和目的,请使用 [PR 模板](.github/PULL_REQUEST_TEMPLATE/pull_request_template.md)。详细的描述将极大提高代码审阅效率。
---
## 测试用例贡献
任何测试用例的贡献都值得鼓励,尤其是单元测试。建议在对应模块的 `test` 目录中创建 `XXXTest.java` 文件,推荐使用 JUnit5 框架。
---
## 其他参与方式
除了直接贡献代码,以下方式同样是对 FastExcel 的宝贵支持:
- 回答其他用户的问题。
- 帮助审阅他人的 PR。
- 提出改进建议。
- 撰写技术博客,宣传 FastExcel。
- 在社区中分享项目相关知识。
---
## 代码风格
请遵循 [阿里巴巴 Java 编码规范](https://alibaba.github.io/Alibaba-Java-Coding-Guidelines/) 进行代码编写。
您可以选择安装以下插件(非必需)以帮助检查代码风格:
- **IntelliJ IDEA 插件**[安装指南](https://github.com/alibaba/p3c/blob/master/idea-plugin/README.md)
- **Eclipse 插件**[安装指南](https://github.com/alibaba/p3c/blob/master/eclipse-plugin/README.md)
---
**最后,感谢您对 FastExcel 的支持!每一份帮助,都是我们前进的动力。**

214
LICENSE
View File

@ -1,201 +1,21 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
MIT License
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Copyright (c) 2024 CodePhiliaX
1. Definitions.
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:
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
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.

View File

@ -5,7 +5,7 @@
FastExcel 是由原 EasyExcel 作者创建的新项目。2023 年我已从阿里离职,近期阿里宣布停止更新 EasyExcel我决定继续维护和升级这个项目。在重新开始时我选择为它起名为 FastExcel以突出这个框架在处理 Excel 文件时的高性能表现,而不仅仅是简单易用。
FastExcel 将始终坚持免费开源,并采用商业友好的 Apache 协议使其适用于任何商业化场景。这为开发者和企业提供了极大的自由度和灵活性。FastExcel 的一些显著特点包括:
FastExcel 将始终坚持免费开源,并采用最开放的 MIT 协议使其适用于任何商业化场景。这为开发者和企业提供了极大的自由度和灵活性。FastExcel 的一些显著特点包括:
- 1、完全兼容原 EasyExcel 的所有功能和特性,这使得用户可以无缝过渡。
@ -37,22 +37,20 @@ FastExcel 将始终坚持免费开源,并采用商业友好的 Apache 协议
> 当前 FastExcel 底层使用 poi 作为基础包,如果您的项目中已经有 poi 相关组件,需要您手动排除 poi 的相关 jar 包。
## 更新
您可以在 [版本升级详情](CHANGELOG.md) 中查询到具体的版本更新细节。 您也可以在[Maven 中心仓库](https://mvnrepository.com/artifact/cn.idev.excel/fastexcel)中查询到所有的版本。
### Maven
如果您使用 Maven 进行项目构建,请在 `pom.xml` 文件中引入以下配置:
```xml
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>1.1.0</version>
<version>1.0.0</version>
</dependency>
```
### Gradle
如果您使用 Gradle 进行项目构建,请在 `build.gradle` 文件中引入以下配置:
```gradle
dependencies {
implementation 'cn.idev.excel:fastexcel:1.1.0'
implementation 'cn.idev.excel:fastexcel:1.0.0'
}
```
## EasyExcel 与 FastExcel 的区别
@ -77,7 +75,7 @@ dependencies {
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>1.1.0</version>
<version>1.0.0</version>
</dependency>
```
@ -85,11 +83,11 @@ dependencies {
将 EasyExcel 的包名替换为 FastExcel 的包名,如下:
```java
// 将 easyexcel 的包名替换为 FastExcel 的包名
import com.alibaba.excel.*;
import com.alibaba.excel.**;
```
替换为
```java
import cn.idev.excel.*;
import cn.idev.excel.**;
```
### 3. 不修改代码直接依赖 FastExcel
如果由于种种原因您不想修改代码,可以直接依赖 FastExcel ,然后在 `pom.xml` 文件中直接依赖 FastExcel。

View File

@ -4,7 +4,7 @@
FastExcel is the latest work created by the original author of EasyExcel. After I left Alibaba in 2023, and with Alibaba announcing the cessation of EasyExcel updates, I decided to continue maintaining and upgrading this project. When restarting, I chose the name FastExcel to emphasize the high performance of this framework when handling Excel files, not just its simplicity and ease of use.
FastExcel will always be free and open source , use the business-friendly Apache license., making it suitable for any commercial scenarios. This provides developers and enterprises with great freedom and flexibility. Some notable features of FastExcel include:
FastExcel will always remain free and open-source, adopting the most open MIT license, making it suitable for any commercial scenarios. This provides developers and enterprises with great freedom and flexibility. Some notable features of FastExcel include:
- 1. Full compatibility with all functionalities and features of the original EasyExcel, allowing users to transition seamlessly.
- 2. Migrating from EasyExcel to FastExcel only requires a simple change of package name and Maven dependency to complete the upgrade.
@ -37,7 +37,7 @@ If you are using Maven for project building, add the following configuration in
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>1.1.0</version>
<version>1.0.0</version>
</dependency>
```
### Gradle
@ -45,11 +45,9 @@ If you are using Gradle for project building, add the following configuration in
```gradle
dependencies {
implementation 'cn.idev.excel:fastexcel:1.1.0'
implementation 'cn.idev.excel:fastexcel:1.0.0'
}
```
## Update
For detailed update logs, refer to [Details of version updates](CHANGELOG.md). You can also find all available versions in the [Maven Central Repository](https://mvnrepository.com/artifact/cn.idev.excel/fastexcel).
## Differences Between EasyExcel and FastExcel
- FastExcel supports all the features of EasyExcel but with better performance and stability.
@ -57,7 +55,7 @@ For detailed update logs, refer to [Details of version updates](CHANGELOG.md). Y
- FastExcel will continue to update, fix bugs, optimize performance, and add new features.
## How to Upgrade from EasyExcel to FastExcel
### 1. Update Dependencies
### 1. Modify Dependencies
Replace the EasyExcel dependency with the FastExcel dependency, as follows:
```xml
@ -73,23 +71,23 @@ Replace with:
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>1.1.0</version>
<version>1.0.0</version>
</dependency>
```
### 2. Update Code
### 2. Modify Code
Replace the EasyExcel package name with the FastExcel package name, as follows:
```java
// Replace EasyExcel package name with FastExcel package name
import com.alibaba.excel.*;
import com.alibaba.excel.**;
```
Replace with:
```java
import cn.idev.excel.*;
import cn.idev.excel.** ;
```
### 3. Import FastExcel Without Modifying Code
### 3. Depend on FastExcel Without Modifying Code
If you do not want to modify the code for various reasons, you can directly depend on FastExcel by directly adding the dependency in the pom.xml file. EasyExcel and FastExcel can coexist, but long-term switching to FastExcel is recommended.
### 4. Future Use of FastExcel Classes Recommended

View File

@ -4,7 +4,7 @@
FastExcelは、元EasyExcelの作者によって作成された最新の作品です。2023年に私がアリババを退職した後、アリババがEasyExcelの更新を停止することを発表したことに伴い、このプロジェクトを引き続きメンテナンスおよびアップグレードすることを決定しました。再び始める際に、私はこのフレームワークの名前をFastExcelとし、Excelファイルの処理における高性能を強調しました。その使いやすさだけではありません。
FastExcelは常にフリーでオープンソースであり、ビジネスに適したApacheオープンソースプロトコルを使用しています。。これにより、開発者や企業に大きな自由度と柔軟性が提供されます。FastExcelのいくつかの顕著な特徴は以下の通りです
FastExcelは常に無料でオープンソースであり、最もオープンなMITライセンスを採用しており、任意の商業シナリオで使用できます。これにより、開発者や企業に大きな自由度と柔軟性が提供されます。FastExcelのいくつかの顕著な特徴は以下の通りです
- 1. 元のEasyExcelのすべての機能と特性との完全な互換性があるため、ユーザーはシームレスに移行できます。
- 2. EasyExcelからFastExcelへの移行は、パッケージ名とMaven依存関係を単純に変更するだけでアップグレードが完了します。
@ -37,7 +37,7 @@ Mavenでプロジェクトを構築する場合、`pom.xml`ファイルに次の
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>1.1.0</version>
<version>1.0.0</version>
</dependency>
```
### Gradle
@ -45,11 +45,9 @@ Mavenでプロジェクトを構築する場合、`pom.xml`ファイルに次の
Gradleでプロジェクトを構築する場合、build.gradleファイルに次の構成を含めてください
```gradle
dependencies {
implementation 'cn.idev.excel:fastexcel:1.1.0'
implementation 'cn.idev.excel:fastexcel:1.0.0'
}
```
## 更新する
具体的なバージョンアップ内容は[バージョンアップ詳細](CHANGELOG.md)で確認できます。 [Maven Central Repository](https://mvnrepository.com/artifact/cn.idev.excel/fastexcel) 内のすべてのバージョンをクエリすることもできます。
## EasyExcelとFastExcelの違い
- FastExcelはEasyExcelのすべての機能をサポートしていますが、FastExcelのパフォーマンスはより良く、より安定しています。
- FastExcelとEasyExcelのAPIは完全に一致しているため、シームレスに切り替えることができます。
@ -70,18 +68,18 @@ EasyExcelの依存関係をFastExcelの依存関係に置き換えます。以
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>1.1.0</version>
<version>1.0.0</version>
</dependency>
```
### 2. コードの修正
EasyExcelのパッケージ名をFastExcelのパッケージ名に置き換えます。以下のように
```java
// EasyExcelのパッケージ名をFastExcelのパッケージ名に置き換えます
import com.alibaba.excel.*;
import com.alibaba.excel.**;
```
を以下に置き換えます
```java
import cn.idev.excel.*;
import cn.idev.excel.** ;
```
### 3. コードを修正せずにFastExcelを直接依存する
何らかの理由でコードを修正したくない場合は、FastExcelに直接依存し、pom.xmlファイル内でFastExcelに直接依存できます。EasyExcelとFastExcelは共存できますが、長期的にはFastExcelを使用することを推奨します。

1
easyexcel_en.md Normal file
View File

@ -0,0 +1 @@
1

View File

@ -6,62 +6,56 @@
<parent>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel-parent</artifactId>
<version>1.1.0</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<url>https://github.com/CodePhiliaX/fastexcel</url>
<packaging>jar</packaging>
<artifactId>fastexcel-core</artifactId>
<name>fastexcel-core</name>
<version>${revision}</version>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.11</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<!-- provided -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<version>1.18.32</version>
</dependency>
<dependency>
<groupId>cn.idev.excel</groupId>

View File

@ -174,7 +174,7 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
}
// close csv.
// https://github.com/fast-excel/fastexcel/issues/2309
// https://github.com/CodePhiliaX/fastexcel/issues/2309
try {
if ((readWorkbookHolder instanceof CsvReadWorkbookHolder)
&& ((CsvReadWorkbookHolder) readWorkbookHolder).getCsvParser() != null

View File

@ -34,7 +34,7 @@ public class DummyRecordHandler extends AbstractXlsRecordHandler implements Igno
xlsReadSheetHolder.setTempRowType(RowTypeEnum.EMPTY);
} else if (record instanceof MissingCellDummyRecord) {
MissingCellDummyRecord mcdr = (MissingCellDummyRecord)record;
// https://github.com/fast-excel/fastexcel/issues/2236
// https://github.com/CodePhiliaX/fastexcel/issues/2236
// Some abnormal XLS, in the case of data already exist, or there will be a "MissingCellDummyRecord"
// records, so if the existing data, empty data is ignored
xlsReadSheetHolder.getCellMap().putIfAbsent(mcdr.getColumn(),

View File

@ -1,9 +1,9 @@
package cn.idev.excel.read.builder;
import cn.idev.excel.metadata.AbstractParameterBuilder;
import cn.idev.excel.read.listener.ReadListener;
import cn.idev.excel.read.metadata.ReadBasicParameter;
import cn.idev.excel.util.ListUtils;
import cn.idev.excel.metadata.AbstractParameterBuilder;
/**
* Build ExcelBuilder

View File

@ -8,17 +8,17 @@ import java.util.List;
import javax.xml.parsers.SAXParserFactory;
import cn.idev.excel.ExcelReader;
import cn.idev.excel.cache.ReadCache;
import cn.idev.excel.cache.selector.ReadCacheSelector;
import cn.idev.excel.cache.selector.SimpleReadCacheSelector;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.enums.CellExtraTypeEnum;
import cn.idev.excel.enums.ReadDefaultReturnEnum;
import cn.idev.excel.event.AnalysisEventListener;
import cn.idev.excel.event.SyncReadListener;
import cn.idev.excel.read.listener.ModelBuildEventListener;
import cn.idev.excel.read.metadata.ReadWorkbook;
import cn.idev.excel.ExcelReader;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.support.ExcelTypeEnum;
/**
@ -211,6 +211,7 @@ public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder<Exce
return this;
}
public ExcelReaderBuilder numRows(Integer numRows) {
readWorkbook.setNumRows(numRows);
return this;

View File

@ -2,11 +2,11 @@ package cn.idev.excel.read.builder;
import java.util.List;
import cn.idev.excel.ExcelReader;
import cn.idev.excel.event.SyncReadListener;
import cn.idev.excel.read.metadata.ReadSheet;
import cn.idev.excel.ExcelReader;
import cn.idev.excel.exception.ExcelAnalysisException;
import cn.idev.excel.exception.ExcelGenerateException;
import cn.idev.excel.read.metadata.ReadSheet;
/**
* Build sheet

View File

@ -4,16 +4,16 @@ import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.enums.CellDataTypeEnum;
import cn.idev.excel.enums.HeadKindEnum;
import cn.idev.excel.enums.ReadDefaultReturnEnum;
import cn.idev.excel.read.metadata.holder.ReadSheetHolder;
import cn.idev.excel.read.metadata.property.ExcelReadHeadProperty;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.exception.ExcelDataConvertException;
import cn.idev.excel.metadata.Head;
import cn.idev.excel.metadata.data.DataFormatData;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.read.metadata.holder.ReadSheetHolder;
import cn.idev.excel.read.metadata.property.ExcelReadHeadProperty;
import cn.idev.excel.support.cglib.beans.BeanMap;
import cn.idev.excel.util.BeanMapUtils;
import cn.idev.excel.util.ClassUtils;
@ -21,6 +21,7 @@ import cn.idev.excel.util.ConverterUtils;
import cn.idev.excel.util.DateUtils;
import cn.idev.excel.util.MapUtils;
/**
* Convert to the object the user needs
*
@ -56,7 +57,7 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<
if (readDefaultReturn == ReadDefaultReturnEnum.STRING) {
// string
map.put(key,
(String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(),
(String) ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(),
context, context.readRowHolder().getRowIndex(), key));
} else {
// return ReadCellData
@ -69,7 +70,7 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<
}
}
}
// fix https://github.com/fast-excel/fastexcel/issues/2014
// fix https://github.com/CodePhiliaX/fastexcel/issues/2014
int headSize = calculateHeadSize(readSheetHolder);
while (index < headSize) {
map.put(index, null);

View File

@ -3,8 +3,9 @@ package cn.idev.excel.read.listener;
import java.util.List;
import java.util.function.Consumer;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.util.ListUtils;
import cn.idev.excel.context.AnalysisContext;
import org.apache.commons.collections4.CollectionUtils;
/**

View File

@ -2,11 +2,13 @@ package cn.idev.excel.read.listener;
import java.util.Map;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.event.Listener;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.metadata.CellExtra;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.read.metadata.holder.ReadRowHolder;
import cn.idev.excel.read.metadata.holder.ReadSheetHolder;
import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder;
/**
* Interface to listen for read results
@ -67,10 +69,10 @@ public interface ReadListener<T> extends Listener {
*/
default boolean hasNext(AnalysisContext context) {
if (context == null
|| context.readRowHolder() == null
|| context.readSheetHolder() == null
|| context.readSheetHolder().getReadSheet() == null
|| context.readWorkbookHolder().getReadWorkbook() == null
|| context.readRowHolder() == null
|| context.readSheetHolder() == null
|| context.readSheetHolder().getReadSheet() == null
|| context.readWorkbookHolder().getReadWorkbook() == null
) {
return true;
}

View File

@ -5,6 +5,7 @@ import java.util.List;
import cn.idev.excel.metadata.BasicParameter;
import cn.idev.excel.read.listener.ReadListener;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

View File

@ -31,7 +31,7 @@ public class ReadSheet extends ReadBasicParameter {
this.sheetName = sheetName;
}
public ReadSheet(Integer sheetNo, String sheetName, Integer numRows) {
public ReadSheet(Integer sheetNo, String sheetName,Integer numRows) {
this.sheetNo = sheetNo;
this.sheetName = sheetName;
this.numRows = numRows;
@ -53,6 +53,7 @@ public class ReadSheet extends ReadBasicParameter {
this.sheetName = sheetName;
}
public Integer getNumRows() {
return numRows;
}

View File

@ -3,17 +3,18 @@ package cn.idev.excel.read.metadata.holder;
import java.util.HashMap;
import java.util.List;
import cn.idev.excel.enums.HolderEnum;
import cn.idev.excel.read.metadata.property.ExcelReadHeadProperty;
import cn.idev.excel.util.ListUtils;
import cn.idev.excel.converters.Converter;
import cn.idev.excel.converters.ConverterKeyBuild;
import cn.idev.excel.converters.DefaultConverterLoader;
import cn.idev.excel.enums.HolderEnum;
import cn.idev.excel.metadata.AbstractHolder;
import cn.idev.excel.read.listener.ModelBuildEventListener;
import cn.idev.excel.read.listener.ReadListener;
import cn.idev.excel.read.metadata.ReadBasicParameter;
import cn.idev.excel.read.metadata.ReadWorkbook;
import cn.idev.excel.read.metadata.property.ExcelReadHeadProperty;
import cn.idev.excel.util.ListUtils;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

View File

@ -2,11 +2,12 @@ package cn.idev.excel.read.metadata.holder;
import java.util.List;
import cn.idev.excel.read.metadata.property.ExcelReadHeadProperty;
import cn.idev.excel.metadata.ConfigurationHolder;
import cn.idev.excel.read.listener.ReadListener;
import cn.idev.excel.read.metadata.property.ExcelReadHeadProperty;
/**
*
* Get the corresponding Holder
*
* @author Jiaju Zhuang

View File

@ -4,10 +4,11 @@ import java.util.LinkedHashMap;
import java.util.Map;
import cn.idev.excel.enums.HolderEnum;
import cn.idev.excel.read.metadata.ReadSheet;
import cn.idev.excel.metadata.Cell;
import cn.idev.excel.metadata.CellExtra;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.read.metadata.ReadSheet;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
@ -62,7 +63,7 @@ public class ReadSheetHolder extends AbstractReadHolder {
private ReadCellData<?> tempCellData;
/**
* Read the size of the largest head in sheet head data.
* see https://github.com/fast-excel/fastexcel/issues/2014
* see https://github.com/CodePhiliaX/fastexcel/issues/2014
*/
private Integer maxNotEmptyDataHeadSize;

View File

@ -3,6 +3,7 @@ package cn.idev.excel.read.metadata.holder.csv;
import cn.idev.excel.read.metadata.ReadWorkbook;
import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder;
import cn.idev.excel.support.ExcelTypeEnum;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

View File

@ -7,6 +7,7 @@ import cn.idev.excel.enums.RowTypeEnum;
import cn.idev.excel.read.metadata.ReadSheet;
import cn.idev.excel.read.metadata.holder.ReadSheetHolder;
import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

View File

@ -5,7 +5,6 @@ import java.util.List;
import cn.idev.excel.read.metadata.ReadWorkbook;
import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder;
import cn.idev.excel.support.ExcelTypeEnum;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
@ -15,6 +14,8 @@ import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import cn.idev.excel.support.ExcelTypeEnum;
/**
* Workbook holder
*

View File

@ -6,6 +6,7 @@ import java.util.LinkedList;
import cn.idev.excel.read.metadata.ReadSheet;
import cn.idev.excel.read.metadata.holder.ReadSheetHolder;
import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

View File

@ -4,12 +4,13 @@ import java.util.Map;
import javax.xml.parsers.SAXParserFactory;
import cn.idev.excel.constant.BuiltinFormats;
import cn.idev.excel.metadata.data.DataFormatData;
import cn.idev.excel.read.metadata.ReadWorkbook;
import cn.idev.excel.read.metadata.holder.ReadWorkbookHolder;
import cn.idev.excel.support.ExcelTypeEnum;
import cn.idev.excel.util.MapUtils;
import cn.idev.excel.constant.BuiltinFormats;
import cn.idev.excel.metadata.data.DataFormatData;
import cn.idev.excel.support.ExcelTypeEnum;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

View File

@ -3,6 +3,7 @@ package cn.idev.excel.read.processor;
import cn.idev.excel.context.AnalysisContext;
/**
*
* Event processor
*
* @author jipengfei
@ -25,7 +26,8 @@ public interface AnalysisEventProcessor {
/**
* Notify after all analysed
*
* @param analysisContext Analysis context
* @param analysisContext
* Analysis context
*/
void endSheet(AnalysisContext analysisContext);
}

View File

@ -4,21 +4,22 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.enums.CellDataTypeEnum;
import cn.idev.excel.enums.HeadKindEnum;
import cn.idev.excel.enums.RowTypeEnum;
import cn.idev.excel.exception.ExcelAnalysisException;
import cn.idev.excel.exception.ExcelAnalysisStopException;
import cn.idev.excel.metadata.Head;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.read.listener.ReadListener;
import cn.idev.excel.read.metadata.holder.ReadRowHolder;
import cn.idev.excel.read.metadata.holder.ReadSheetHolder;
import cn.idev.excel.read.metadata.property.ExcelReadHeadProperty;
import cn.idev.excel.util.BooleanUtils;
import cn.idev.excel.util.ConverterUtils;
import cn.idev.excel.util.StringUtils;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.exception.ExcelAnalysisException;
import cn.idev.excel.exception.ExcelAnalysisStopException;
import cn.idev.excel.metadata.Head;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.read.listener.ReadListener;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -36,28 +37,16 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor {
dealExtra(analysisContext);
}
/**
* Ends the processing of a row.
* This method is called after reading a row of data to perform corresponding processing.
* If the current row is empty and the workbook holder is set to ignore empty rows, then directly return without processing.
* If the row is not empty or empty rows are not ignored, then call the dealData method to process the data.
*
* @param analysisContext Analysis context, containing information about the current analysis, including the type and content of the row.
*/
@Override
public void endRow(AnalysisContext analysisContext) {
// Check if the current row is empty
if (RowTypeEnum.EMPTY.equals(analysisContext.readRowHolder().getRowType())) {
// Log debug information if the current row is empty
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Empty row!");
}
// If the workbook holder is set to ignore empty rows, then directly return
if (analysisContext.readWorkbookHolder().getIgnoreEmptyRow()) {
return;
}
}
// Call the data processing method
dealData(analysisContext);
}

View File

@ -17,7 +17,7 @@ public class BeanMapUtils {
* <code>BeanMap.Generator</code> instead of this static method.
*
* Custom naming policy to prevent null pointer exceptions.
* see: https://github.com/fast-excel/fastexcel/issues/2064
* see: https://github.com/CodePhiliaX/fastexcel/issues/2064
*
* @param bean the JavaBean underlying the map
* @return a new <code>BeanMap</code> instance

View File

@ -102,7 +102,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
if (dataIndex >= oneRowData.size()) {
return;
}
// fix https://github.com/fast-excel/fastexcel/issues/1702
// fix https://github.com/CodePhiliaX/fastexcel/issues/1702
// If there is data, it is written to the next cell
maxCellIndex++;
@ -196,7 +196,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
writeContext, row, rowIndex, null, maxCellIndex, relativeRowIndex, Boolean.FALSE, excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
// fix https://github.com/fast-excel/fastexcel/issues/1870
// fix https://github.com/CodePhiliaX/fastexcel/issues/1870
// If there is data, it is written to the next cell
Cell cell = WorkBookUtil.createCell(row, maxCellIndex);
cellWriteHandlerContext.setCell(cell);

View File

@ -428,7 +428,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if (!analysisCell.getFirstRow() || !WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection())) {
return;
}
// fix https://github.com/fast-excel/fastexcel/issues/1869
// fix https://github.com/CodePhiliaX/fastexcel/issues/1869
if (isOriginalCell && PoiUtils.customHeight(row)) {
collectionRowHeightCache.put(currentUniqueDataFlag, row.getHeight());
return;
@ -538,7 +538,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
analysisCell.getVariableList().add(variable);
if (lastPrepareDataIndex == prefixIndex) {
analysisCell.getPrepareDataList().add(StringUtils.EMPTY);
// fix https://github.com/fast-excel/fastexcel/issues/2035
// fix https://github.com/CodePhiliaX/fastexcel/issues/2035
if (lastPrepareDataIndex != 0) {
analysisCell.setOnlyOneVariable(Boolean.FALSE);
}
@ -550,7 +550,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
lastPrepareDataIndex = suffixIndex + 1;
}
// fix https://github.com/fast-excel/fastexcel/issues/1552
// fix https://github.com/CodePhiliaX/fastexcel/issues/1552
// When read template, XLSX data may be in `is` labels, and set the time set in `v` label, lead to can't set
// up successfully, so all data format to empty first.
if (analysisCell != null && CollectionUtils.isNotEmpty(analysisCell.getVariableList())) {

View File

@ -19,7 +19,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
/**
* Handle the problem of unable to write dimension.
*
* https://github.com/fast-excel/fastexcel/issues/1282
* https://github.com/CodePhiliaX/fastexcel/issues/1282
*
* @author Jiaju Zhuang
*/

View File

@ -1,3 +0,0 @@
# easyexcel-support
External dependencies: Currently, there is only one dependency, cglib. Since cglib does not support higher versions of the JDK, a separate copy has been made.

View File

@ -7,12 +7,15 @@
<parent>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel-parent</artifactId>
<version>1.1.0</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<url>https://github.com/CodePhiliaX/fastexcel</url>
<packaging>jar</packaging>
<artifactId>fastexcel-support</artifactId>
<name>fastexcel-support</name>
<version>${revision}</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -26,6 +29,7 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.37</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
@ -99,5 +103,6 @@
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -7,56 +7,63 @@
<parent>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel-parent</artifactId>
<version>1.1.0</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<url>https://github.com/CodePhiliaX/fastexcel</url>
<packaging>jar</packaging>
<artifactId>fastexcel-test</artifactId>
<name>fastexcel-test</name>
<version>${revision}</version>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
<dependencies>
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel-core</artifactId>
<version>${project.version}</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.51</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.7.18</version>
</dependency>
<!-- logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.5.6</version>
</dependency>
</dependencies>

View File

@ -32,7 +32,7 @@ public class CompatibilityTest {
@Test
public void t01() {
// https://github.com/fast-excel/fastexcel/issues/2236
// https://github.com/CodePhiliaX/fastexcel/issues/2236
List<Map<Integer, Object>> list = EasyExcel.read(TestFileUtil.getPath() + "compatibility/t01.xls").sheet()
.doReadSync();
Assertions.assertEquals(2, list.size());
@ -75,7 +75,7 @@ public class CompatibilityTest {
@Test
public void t05() {
// https://github.com/fast-excel/fastexcel/issues/1956
// https://github.com/CodePhiliaX/fastexcel/issues/1956
// Excel read date needs to be rounded
List<Map<Integer, String>> list = EasyExcel
.read(TestFileUtil.getPath() + "compatibility/t05.xlsx")
@ -103,7 +103,7 @@ public class CompatibilityTest {
@Test
public void t07() {
// https://github.com/fast-excel/fastexcel/issues/2805
// https://github.com/CodePhiliaX/fastexcel/issues/2805
// Excel read date needs to be rounded
List<Map<Integer, Object>> list = EasyExcel
.read(TestFileUtil.getPath() + "compatibility/t07.xlsx")
@ -123,7 +123,7 @@ public class CompatibilityTest {
@Test
public void t08() {
// https://github.com/fast-excel/fastexcel/issues/2693
// https://github.com/CodePhiliaX/fastexcel/issues/2693
// Temporary files may be deleted if there is no operation for a long time, so they need to be recreated.
File file = TestFileUtil.createNewFile("compatibility/t08.xlsx");
EasyExcel.write(file, SimpleData.class)

View File

@ -136,7 +136,7 @@ public class FillDataTest {
private void byNameFill(File file, File template) {
FillData fillData = new FillData();
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
EasyExcel.write(file, FillData.class).withTemplate(template).sheet("Sheet2").doFill(fillData);
}
@ -153,17 +153,17 @@ public class FillDataTest {
excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
excelWriter.fill(map, writeSheet);
}
List<Object> list = EasyExcel.read(file).ignoreEmptyRow(false).sheet().headRowNumber(0).doReadSync();
Map<String, String> map0 = (Map<String, String>)list.get(0);
Assertions.assertEquals("Zhang San", map0.get(21));
Assertions.assertEquals("张三", map0.get(21));
Map<String, String> map27 = (Map<String, String>)list.get(27);
Assertions.assertEquals("Zhang San", map27.get(0));
Assertions.assertEquals("张三", map27.get(0));
Map<String, String> map29 = (Map<String, String>)list.get(29);
Assertions.assertEquals("Zhang San", map29.get(3));
Assertions.assertEquals("张三", map29.get(3));
}
private void horizontalFill(File file, File template) {
@ -173,7 +173,7 @@ public class FillDataTest {
excelWriter.fill(data(), fillConfig, writeSheet);
excelWriter.fill(data(), fillConfig, writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
excelWriter.fill(map, writeSheet);
excelWriter.finish();
}
@ -181,7 +181,7 @@ public class FillDataTest {
List<Object> list = EasyExcel.read(file).sheet().headRowNumber(0).doReadSync();
Assertions.assertEquals(list.size(), 5L);
Map<String, String> map0 = (Map<String, String>)list.get(0);
Assertions.assertEquals("Zhang San", map0.get(2));
Assertions.assertEquals("张三", map0.get(2));
}
private void complexFill(File file, File template) {
@ -191,19 +191,19 @@ public class FillDataTest {
excelWriter.fill(data(), fillConfig, writeSheet);
excelWriter.fill(data(), fillConfig, writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
map.put("total", 1000);
excelWriter.fill(map, writeSheet);
}
List<Object> list = EasyExcel.read(file).sheet().headRowNumber(3).doReadSync();
Assertions.assertEquals(list.size(), 21L);
Map<String, String> map19 = (Map<String, String>)list.get(19);
Assertions.assertEquals("Zhang San", map19.get(0));
Assertions.assertEquals("张三", map19.get(0));
}
private void fill(File file, File template) {
FillData fillData = new FillData();
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
EasyExcel.write(file, FillData.class).withTemplate(template).sheet().doFill(fillData);
}
@ -213,7 +213,7 @@ public class FillDataTest {
for (int i = 0; i < 10; i++) {
FillData fillData = new FillData();
list.add(fillData);
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
if (i == 5) {
fillData.setName(null);

View File

@ -21,19 +21,19 @@ import lombok.Setter;
@EqualsAndHashCode
@ContentRowHeight(100)
public class FillAnnotationData {
@ExcelProperty("Date")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
@ExcelProperty("日期")
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
private Date date;
@ExcelProperty(value = "Number")
@ExcelProperty(value = "数字")
@NumberFormat("#.##%")
private Double number;
@ContentLoopMerge(columnExtend = 2)
@ExcelProperty("String 1")
@ExcelProperty("字符串1")
private String string1;
@ExcelProperty("String 2")
@ExcelProperty("字符串2")
private String string2;
@ExcelProperty(value = "Image", converter = StringImageConverter.class)
@ExcelProperty(value = "图片", converter = StringImageConverter.class)
private String image;
}

View File

@ -70,7 +70,7 @@ public class FillAnnotationDataTest {
Date date = cell10.getDateCellValue();
Assertions.assertEquals(DateUtils.parseDate("2020-01-01 01:01:01").getTime(), date.getTime());
String dataFormatString = cell10.getCellStyle().getDataFormatString();
Assertions.assertEquals("yyyy-MM-dd HH:mm:ss", dataFormatString);
Assertions.assertEquals("yyyy年MM月dd日HH时mm分ss秒", dataFormatString);
Cell cell11 = row1.getCell(1);
Assertions.assertEquals(99.99, cell11.getNumericCellValue(), 2);
boolean hasMerge = false;

View File

@ -61,7 +61,7 @@ public class FillStyleAnnotatedTest {
private void t01Fill07check(XSSFRow row) {
XSSFCell cell0 = row.getCell(0);
Assertions.assertEquals("Zhang San", cell0.getStringCellValue());
Assertions.assertEquals("张三", cell0.getStringCellValue());
Assertions.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFFFF00", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF808000", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
@ -83,21 +83,21 @@ public class FillStyleAnnotatedTest {
Assertions.assertTrue(cell2.getCellStyle().getFont().getBold());
XSSFCell cell3 = row.getCell(3);
Assertions.assertEquals("Zhang San is 5.2 years old this year", cell3.getStringCellValue());
Assertions.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assertions.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF0000", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FFEEECE1", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assertions.assertTrue(cell3.getCellStyle().getFont().getBold());
XSSFCell cell4 = row.getCell(4);
Assertions.assertEquals("{.name} ignoredZhang San", cell4.getStringCellValue());
Assertions.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assertions.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assertions.assertEquals("FFC00000", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF000000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assertions.assertFalse(cell4.getCellStyle().getFont().getBold());
XSSFCell cell5 = row.getCell(5);
Assertions.assertEquals("Empty", cell5.getStringCellValue());
Assertions.assertEquals("", cell5.getStringCellValue());
Assertions.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assertions.assertEquals("FFF79646", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF8064A2", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
@ -115,7 +115,7 @@ public class FillStyleAnnotatedTest {
private void t02Fill03check(HSSFWorkbook workbook, HSSFRow row) {
HSSFCell cell0 = row.getCell(0);
Assertions.assertEquals("Zhang San", cell0.getStringCellValue());
Assertions.assertEquals("张三", cell0.getStringCellValue());
Assertions.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF:FFFF:0", cell0.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("8080:8080:0", cell0.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -140,7 +140,7 @@ public class FillStyleAnnotatedTest {
Assertions.assertTrue(cell2.getCellStyle().getFont(workbook).getBold());
HSSFCell cell3 = row.getCell(3);
Assertions.assertEquals("Zhang San is 5.2 years old this year", cell3.getStringCellValue());
Assertions.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assertions.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF:0:0", cell3.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("FFFF:FFFF:9999", cell3.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -148,7 +148,7 @@ public class FillStyleAnnotatedTest {
Assertions.assertTrue(cell3.getCellStyle().getFont(workbook).getBold());
HSSFCell cell4 = row.getCell(4);
Assertions.assertEquals("{.name} ignoredZhang San", cell4.getStringCellValue());
Assertions.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assertions.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assertions.assertEquals("9999:3333:0", cell4.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("3333:3333:3333", cell4.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -156,7 +156,7 @@ public class FillStyleAnnotatedTest {
Assertions.assertFalse(cell4.getCellStyle().getFont(workbook).getBold());
HSSFCell cell5 = row.getCell(5);
Assertions.assertEquals("Empty", cell5.getStringCellValue());
Assertions.assertEquals("", cell5.getStringCellValue());
Assertions.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assertions.assertEquals("9999:3333:0", cell5.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("CCCC:9999:FFFF", cell5.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -170,7 +170,7 @@ public class FillStyleAnnotatedTest {
private void t11FillStyleHandler07check(XSSFRow row) {
XSSFCell cell0 = row.getCell(0);
Assertions.assertEquals("Zhang San", cell0.getStringCellValue());
Assertions.assertEquals("张三", cell0.getStringCellValue());
Assertions.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFFFF00", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF808000", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
@ -192,21 +192,21 @@ public class FillStyleAnnotatedTest {
Assertions.assertTrue(cell2.getCellStyle().getFont().getBold());
XSSFCell cell3 = row.getCell(3);
Assertions.assertEquals("Zhang San is 5 years old this year", cell3.getStringCellValue());
Assertions.assertEquals("张三今年5岁了", cell3.getStringCellValue());
Assertions.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assertions.assertEquals("FF0000FF", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF000080", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assertions.assertTrue(cell3.getCellStyle().getFont().getBold());
XSSFCell cell4 = row.getCell(4);
Assertions.assertEquals("{.name} ignoredZhang San", cell4.getStringCellValue());
Assertions.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assertions.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFFFF00", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF808000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assertions.assertTrue(cell4.getCellStyle().getFont().getBold());
XSSFCell cell5 = row.getCell(5);
Assertions.assertEquals("Empty", cell5.getStringCellValue());
Assertions.assertEquals("", cell5.getStringCellValue());
Assertions.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assertions.assertEquals("FF008080", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF003366", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
@ -215,7 +215,7 @@ public class FillStyleAnnotatedTest {
private void t12FillStyleHandler03check(HSSFWorkbook workbook, HSSFRow row) {
HSSFCell cell0 = row.getCell(0);
Assertions.assertEquals("Zhang San", cell0.getStringCellValue());
Assertions.assertEquals("张三", cell0.getStringCellValue());
Assertions.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF:FFFF:0", cell0.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("8080:8080:0", cell0.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -240,7 +240,7 @@ public class FillStyleAnnotatedTest {
Assertions.assertTrue(cell2.getCellStyle().getFont(workbook).getBold());
HSSFCell cell3 = row.getCell(3);
Assertions.assertEquals("Zhang San is 5 years old this year", cell3.getStringCellValue());
Assertions.assertEquals("张三今年5岁了", cell3.getStringCellValue());
Assertions.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assertions.assertEquals("0:0:FFFF", cell3.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("0:0:8080", cell3.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -248,7 +248,7 @@ public class FillStyleAnnotatedTest {
Assertions.assertTrue(cell3.getCellStyle().getFont(workbook).getBold());
HSSFCell cell4 = row.getCell(4);
Assertions.assertEquals("{.name} ignoredZhang San", cell4.getStringCellValue());
Assertions.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assertions.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF:FFFF:0", cell4.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("8080:8080:0", cell4.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -256,7 +256,7 @@ public class FillStyleAnnotatedTest {
Assertions.assertTrue(cell4.getCellStyle().getFont(workbook).getBold());
HSSFCell cell5 = row.getCell(5);
Assertions.assertEquals("Empty", cell5.getStringCellValue());
Assertions.assertEquals("", cell5.getStringCellValue());
Assertions.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assertions.assertEquals("0:8080:8080", cell5.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("0:3333:6666", cell5.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -316,7 +316,7 @@ public class FillStyleAnnotatedTest {
for (int i = 0; i < 10; i++) {
FillStyleAnnotatedData fillData = new FillStyleAnnotatedData();
list.add(fillData);
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
fillData.setDate(DateUtils.parseDate("2020-01-01 01:01:01"));
if (i == 5) {

View File

@ -64,7 +64,7 @@ public class FillStyleDataTest {
private void t01Fill07check(XSSFRow row) {
XSSFCell cell0 = row.getCell(0);
Assertions.assertEquals("Zhang San", cell0.getStringCellValue());
Assertions.assertEquals("张三", cell0.getStringCellValue());
Assertions.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assertions.assertEquals("FF00B050", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF7030A0", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
@ -86,21 +86,21 @@ public class FillStyleDataTest {
Assertions.assertTrue(cell2.getCellStyle().getFont().getBold());
XSSFCell cell3 = row.getCell(3);
Assertions.assertEquals("Zhang San is 5.2 years old this year", cell3.getStringCellValue());
Assertions.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assertions.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF0000", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FFEEECE1", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assertions.assertTrue(cell3.getCellStyle().getFont().getBold());
XSSFCell cell4 = row.getCell(4);
Assertions.assertEquals("{.name} ignoredZhang San", cell4.getStringCellValue());
Assertions.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assertions.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assertions.assertEquals("FFC00000", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF000000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assertions.assertFalse(cell4.getCellStyle().getFont().getBold());
XSSFCell cell5 = row.getCell(5);
Assertions.assertEquals("Empty", cell5.getStringCellValue());
Assertions.assertEquals("", cell5.getStringCellValue());
Assertions.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assertions.assertEquals("FFF79646", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF8064A2", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
@ -118,7 +118,7 @@ public class FillStyleDataTest {
private void t02Fill03check(HSSFWorkbook workbook, HSSFRow row) {
HSSFCell cell0 = row.getCell(0);
Assertions.assertEquals("Zhang San", cell0.getStringCellValue());
Assertions.assertEquals("张三", cell0.getStringCellValue());
Assertions.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assertions.assertEquals("0:8080:0", cell0.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("8080:0:8080", cell0.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -143,7 +143,7 @@ public class FillStyleDataTest {
Assertions.assertTrue(cell2.getCellStyle().getFont(workbook).getBold());
HSSFCell cell3 = row.getCell(3);
Assertions.assertEquals("Zhang San is 5.2 years old this year", cell3.getStringCellValue());
Assertions.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assertions.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF:0:0", cell3.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("FFFF:FFFF:9999", cell3.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -151,7 +151,7 @@ public class FillStyleDataTest {
Assertions.assertTrue(cell3.getCellStyle().getFont(workbook).getBold());
HSSFCell cell4 = row.getCell(4);
Assertions.assertEquals("{.name} ignoredZhang San", cell4.getStringCellValue());
Assertions.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assertions.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assertions.assertEquals("9999:3333:0", cell4.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("3333:3333:3333", cell4.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -159,7 +159,7 @@ public class FillStyleDataTest {
Assertions.assertFalse(cell4.getCellStyle().getFont(workbook).getBold());
HSSFCell cell5 = row.getCell(5);
Assertions.assertEquals("Empty", cell5.getStringCellValue());
Assertions.assertEquals("", cell5.getStringCellValue());
Assertions.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assertions.assertEquals("9999:3333:0", cell5.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("CCCC:9999:FFFF", cell5.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -182,7 +182,7 @@ public class FillStyleDataTest {
private void t11FillStyleHandler07check(XSSFRow row) {
XSSFCell cell0 = row.getCell(0);
Assertions.assertEquals("Zhang San", cell0.getStringCellValue());
Assertions.assertEquals("张三", cell0.getStringCellValue());
Assertions.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFFFF00", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF808000", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
@ -204,21 +204,21 @@ public class FillStyleDataTest {
Assertions.assertTrue(cell2.getCellStyle().getFont().getBold());
XSSFCell cell3 = row.getCell(3);
Assertions.assertEquals("Zhang San is 5.2 years old this year", cell3.getStringCellValue());
Assertions.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assertions.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF0000", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FFEEECE1", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assertions.assertTrue(cell3.getCellStyle().getFont().getBold());
XSSFCell cell4 = row.getCell(4);
Assertions.assertEquals("{.name} ignoredZhang San", cell4.getStringCellValue());
Assertions.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assertions.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assertions.assertEquals("FFC00000", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF000000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assertions.assertFalse(cell4.getCellStyle().getFont().getBold());
XSSFCell cell5 = row.getCell(5);
Assertions.assertEquals("Empty", cell5.getStringCellValue());
Assertions.assertEquals("", cell5.getStringCellValue());
Assertions.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assertions.assertEquals("FFF79646", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assertions.assertEquals("FF8064A2", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
@ -236,7 +236,7 @@ public class FillStyleDataTest {
private void t12FillStyleHandler03check(HSSFWorkbook workbook, HSSFRow row) {
HSSFCell cell0 = row.getCell(0);
Assertions.assertEquals("Zhang San", cell0.getStringCellValue());
Assertions.assertEquals("张三", cell0.getStringCellValue());
Assertions.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF:FFFF:0", cell0.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("8080:8080:0", cell0.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -261,7 +261,7 @@ public class FillStyleDataTest {
Assertions.assertTrue(cell2.getCellStyle().getFont(workbook).getBold());
HSSFCell cell3 = row.getCell(3);
Assertions.assertEquals("Zhang San is 5.2 years old this year", cell3.getStringCellValue());
Assertions.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assertions.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assertions.assertEquals("FFFF:0:0", cell3.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("FFFF:FFFF:9999", cell3.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -269,7 +269,7 @@ public class FillStyleDataTest {
Assertions.assertTrue(cell3.getCellStyle().getFont(workbook).getBold());
HSSFCell cell4 = row.getCell(4);
Assertions.assertEquals("{.name} ignoredZhang San", cell4.getStringCellValue());
Assertions.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assertions.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assertions.assertEquals("9999:3333:0", cell4.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("3333:3333:3333", cell4.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -277,7 +277,7 @@ public class FillStyleDataTest {
Assertions.assertFalse(cell4.getCellStyle().getFont(workbook).getBold());
HSSFCell cell5 = row.getCell(5);
Assertions.assertEquals("Empty", cell5.getStringCellValue());
Assertions.assertEquals("", cell5.getStringCellValue());
Assertions.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assertions.assertEquals("9999:3333:0", cell5.getCellStyle().getFillForegroundColorColor().getHexString());
Assertions.assertEquals("CCCC:9999:FFFF", cell5.getCellStyle().getFont(workbook).getHSSFColor(workbook)
@ -337,7 +337,7 @@ public class FillStyleDataTest {
for (int i = 0; i < 10; i++) {
FillStyleData fillData = new FillStyleData();
list.add(fillData);
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
fillData.setDate(DateUtils.parseDate("2020-01-01 01:01:01"));
if (i == 5) {

View File

@ -19,7 +19,7 @@ import cn.idev.excel.write.metadata.fill.FillWrapper;
import org.junit.jupiter.api.Test;
/**
* Example of writing and filling data into Excel
* 写的填充写法
*
* @author Jiaju Zhuang
* @since 2.1.1
@ -27,52 +27,52 @@ import org.junit.jupiter.api.Test;
public class FillTest {
/**
* Simplest example of filling data
* 最简单的填充
*
* @since 2.1.1
*/
@Test
public void simpleFill() {
// Template note: Use {} to indicate variables. If there are existing "{", "}" characters, use "\{", "\}" instead.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "simple.xlsx";
// Option 1: Fill based on an object
// 方案1 根据对象填充
String fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx";
// This will fill the first sheet, and the file stream will be automatically closed.
// 这里 会填充到第一个sheet 然后文件流会自动关闭
FillData fillData = new FillData();
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(fillData);
// Option 2: Fill based on a Map
// 方案2 根据Map填充
fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx";
// This will fill the first sheet, and the file stream will be automatically closed.
// 这里 会填充到第一个sheet 然后文件流会自动关闭
Map<String, Object> map = MapUtils.newHashMap();
map.put("name", "Zhang San");
map.put("name", "张三");
map.put("number", 5.2);
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(map);
}
/**
* Example of filling a list
* 填充列表
*
* @since 2.1.1
*/
@Test
public void listFill() {
// Template note: Use {} to indicate variables. If there are existing "{", "}" characters, use "\{", "\}" instead.
// When filling a list, note that {.} in the template indicates a list.
// If the object filling the list is a Map, it must contain all keys of the list, even if the data is null. Use map.put(key, null).
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// 填充list 的时候还要注意 模板中{.} 多了个点 表示list
// 如果填充list的对象是map,必须包涵所有list的key,哪怕数据为null必须使用map.put(key,null)
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "list.xlsx";
// Option 1: Load all data into memory at once and fill
// 方案1 一下子全部放到内存里面 并填充
String fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx";
// This will fill the first sheet, and the file stream will be automatically closed.
// 这里 会填充到第一个sheet 然后文件流会自动关闭
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(data());
// Option 2: Fill in multiple passes, using file caching (saves memory)
// 方案2 分多次 填充 会使用文件缓存省内存
fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx";
try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
@ -82,95 +82,95 @@ public class FillTest {
}
/**
* Example of complex filling
* 复杂的填充
*
* @since 2.1.1
*/
@Test
public void complexFill() {
// Template note: Use {} to indicate variables. If there are existing "{", "}" characters, use "\{", "\}" instead.
// {} represents a normal variable, {.} represents a list variable.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "complex.xlsx";
String fileName = TestFileUtil.getPath() + "complexFill" + System.currentTimeMillis() + ".xlsx";
// Option 1
// 方案1
try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// Note: The forceNewRow parameter is used here. When writing a list, it will always create a new row, and the data below will be shifted down. Default is false, which will use the next row if available, otherwise create a new one.
// forceNewRow: If set to true, it will load all data into memory, so use it with caution.
// In short, if your template has a list and the list is not the last row, and there is data below that needs to be filled, you must set forceNewRow=true. However, this will consume a lot of memory.
// For large datasets where the list is not the last row, refer to the next example.
// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行然后下面的数据往后移动默认 是false会直接使用下一行如果没有则创建
// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了所以慎用
// 简单的说 如果你的模板有list,且list不是最后一行下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
// 如果数据量大 list不是最后一行 参照下一个
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
excelWriter.fill(data(), fillConfig, writeSheet);
excelWriter.fill(data(), fillConfig, writeSheet);
Map<String, Object> map = MapUtils.newHashMap();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
map.put("total", 1000);
excelWriter.fill(map, writeSheet);
}
}
/**
* Example of complex filling with large datasets
* 数据量大的复杂填充
* <p>
* The solution here is to ensure that the list in the template is the last row, and then append a table. For Excel 2003, there is no solution other than increasing memory.
* 这里的解决方案是 确保模板list为最后一行然后再拼接table.还有03版没救只能刚正面加内存
*
* @since 2.1.1
*/
@Test
public void complexFillWithTable() {
// Template note: Use {} to indicate variables. If there are existing "{", "}" characters, use "\{", "\}" instead.
// {} represents a normal variable, {.} represents a list variable.
// Here, the template deletes the data after the list, i.e., the summary row.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
// 这里模板 删除了list以后的数据也就是统计的这一行
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "complexFillWithTable.xlsx";
String fileName = TestFileUtil.getPath() + "complexFillWithTable" + System.currentTimeMillis() + ".xlsx";
// Option 1
// 方案1
try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// Directly write data
// 直接写入数据
excelWriter.fill(data(), writeSheet);
excelWriter.fill(data(), writeSheet);
// Write data before the list
// 写入list之前的数据
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
excelWriter.fill(map, writeSheet);
// There is a summary after the list, which needs to be written manually.
// Here, we use a list for simplicity. You can also use an object.
// list 后面还有个统计 想办法手动写入
// 这里偷懒直接用list 也可以用对象
List<List<String>> totalListList = ListUtils.newArrayList();
List<String> totalList = ListUtils.newArrayList();
totalListList.add(totalList);
totalList.add(null);
totalList.add(null);
totalList.add(null);
// Fourth column
totalList.add("Total:1000");
// Note: Use write here, not fill.
// 第四列
totalList.add("统计:1000");
// 这里是write 别和fill 搞错了
excelWriter.write(totalListList, writeSheet);
// Overall, the writing is complex, but there is no better solution. Asynchronous writing to Excel does not support row deletion or movement, nor does it support writing comments, so this approach is used.
// The idea is to create a new sheet and copy data bit by bit. However, when adding rows to the list, the data in the columns below cannot be shifted. A better solution will be explored in the future.
// 总体上写法比较复杂 但是也没有想到好的版本 异步的去写入excel 不支持行的删除和移动也不支持备注这种的写入所以也排除了可以
// 新建一个 然后一点点复制过来的方案最后导致list需要新增行的时候后面的列的数据没法后移后续会继续想想解决方案
}
}
/**
* Example of horizontal filling
* 横向的填充
*
* @since 2.1.1
*/
@Test
public void horizontalFill() {
// Template note: Use {} to indicate variables. If there are existing "{", "}" characters, use "\{", "\}" instead.
// {} represents a normal variable, {.} represents a list variable.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "horizontal.xlsx";
String fileName = TestFileUtil.getPath() + "horizontalFill" + System.currentTimeMillis() + ".xlsx";
// Option 1
// 方案1
try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
@ -178,30 +178,30 @@ public class FillTest {
excelWriter.fill(data(), fillConfig, writeSheet);
Map<String, Object> map = new HashMap<>();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
excelWriter.fill(map, writeSheet);
}
}
/**
* Example of composite filling with multiple lists
* 多列表组合填充填充
*
* @since 2.2.0-beta1
*/
@Test
public void compositeFill() {
// Template note: Use {} to indicate variables. If there are existing "{", "}" characters, use "\{", "\}" instead.
// {} represents a normal variable, {.} represents a list variable, {prefix.} prefix can distinguish different lists.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量 {前缀.} 前缀可以区分不同的list
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "composite.xlsx";
String fileName = TestFileUtil.getPath() + "compositeFill" + System.currentTimeMillis() + ".xlsx";
// Option 1
// 方案1
try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
// If there are multiple lists, the template must have {prefix.}. Here, the prefix is data1, and multiple lists must be wrapped with FillWrapper.
// 如果有多个list 模板上必须有{前缀.} 这里的前缀就是 data1然后多个list必须用 FillWrapper包裹
excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data2", data()), writeSheet);
@ -210,6 +210,7 @@ public class FillTest {
excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
//map.put("date", "2019年10月9日13:28:28");
map.put("date", new Date());
excelWriter.fill(map, writeSheet);
@ -221,7 +222,7 @@ public class FillTest {
for (int i = 0; i < 10; i++) {
FillData fillData = new FillData();
list.add(fillData);
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
fillData.setDate(new Date());
}

View File

@ -11,7 +11,7 @@ import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Hyperlink;
/**
* 自定义拦截器对第一行第一列的头超链接到:https://github.com/fast-excel/fastexcel
* 自定义拦截器对第一行第一列的头超链接到:https://github.com/CodePhiliaX/fastexcel
*
* @author Jiaju Zhuang
*/
@ -26,7 +26,7 @@ public class CustomCellWriteHandler implements CellWriteHandler {
if (BooleanUtils.isTrue(context.getHead()) && cell.getColumnIndex() == 0) {
CreationHelper createHelper = context.getWriteSheetHolder().getSheet().getWorkbook().getCreationHelper();
Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL);
hyperlink.setAddress("https://github.com/fast-excel/fastexcel");
hyperlink.setAddress("https://github.com/CodePhiliaX/fastexcel");
cell.setHyperlink(hyperlink);
}
}

View File

@ -255,7 +255,7 @@ public class WriteTest {
imageDemoData.setString(imagePath);
imageDemoData.setInputStream(inputStream);
imageDemoData.setUrl(new URL(
"https://raw.githubusercontent.com/fast-excel/fastexcel/master/src/test/resources/converter/img.jpg"));
"https://raw.githubusercontent.com/CodePhiliaX/fastexcel/master/src/test/resources/converter/img.jpg"));
// 这里演示
// 需要额外放入文字
@ -328,7 +328,7 @@ public class WriteTest {
writeCellDemoData.setHyperlink(hyperlink);
HyperlinkData hyperlinkData = new HyperlinkData();
hyperlink.setHyperlinkData(hyperlinkData);
hyperlinkData.setAddress("https://github.com/fast-excel/fastexcel");
hyperlinkData.setAddress("https://github.com/CodePhiliaX/fastexcel");
hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);
// 设置备注
@ -640,7 +640,7 @@ public class WriteTest {
/**
* 下拉超链接等自定义拦截器上面几点都不符合但是要对单元格进行操作的参照这个
* <p>
* demo这里实现2点1. 对第一行第一列的头超链接到:https://github.com/fast-excel/fastexcel 2. 对第一列第一行和第二行的数据新增下拉框显示 测试1 测试2
* demo这里实现2点1. 对第一行第一列的头超链接到:https://github.com/CodePhiliaX/fastexcel 2. 对第一列第一行和第二行的数据新增下拉框显示 测试1 测试2
* <p>
* 1. 创建excel对应的实体对象 参照{@link DemoData}
* <p>

View File

@ -19,7 +19,7 @@ import cn.idev.excel.write.metadata.fill.FillWrapper;
import org.junit.jupiter.api.Test;
/**
* Example of filling data into Excel templates.
* 写的填充写法
*
* @author Jiaju Zhuang
* @since 2.1.1
@ -27,146 +27,141 @@ import org.junit.jupiter.api.Test;
public class FillTempTest {
/**
* Simplest example of filling data.
* 最简单的填充
*
* @since 2.1.1
*/
@Test
public void simpleFill() {
// Template note: Use {} to represent variables. If the template contains "{", "}" as special characters, use "\{", "\}" instead.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
String templateFileName = "/Users/zhuangjiaju/Downloads/simple.xlsx";
// Option 1: Fill using an object
// 方案1 根据对象填充
String fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx";
// This will fill the first sheet, and the file stream will be closed automatically.
// 这里 会填充到第一个sheet 然后文件流会自动关闭
FillData fillData = new FillData();
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(fillData);
/*
// Option 2: Fill using a Map
fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx";
// This will fill the first sheet, and the file stream will be closed automatically.
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "Zhang San");
map.put("number", 5.2);
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(map);
*/
//// 方案2 根据Map填充
//fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx";
//// 这里 会填充到第一个sheet 然后文件流会自动关闭
//Map<String, Object> map = new HashMap<String, Object>();
//map.put("name", "张三");
//map.put("number", 5.2);
//EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(map);
}
/**
* Example of filling a list of data.
* 填充列表
*
* @since 2.1.1
*/
@Test
public void listFill() {
// Template note: Use {} to represent variables. If the template contains "{", "}" as special characters, use "\{", "\}" instead.
// When filling a list, note that {.} in the template indicates a list.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// 填充list 的时候还要注意 模板中{.} 多了个点 表示list
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "list.xlsx";
// Option 1: Load all data into memory at once and fill
// 方案1 一下子全部放到内存里面 并填充
String fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx";
// This will fill the first sheet, and the file stream will be closed automatically.
// 这里 会填充到第一个sheet 然后文件流会自动关闭
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(data());
// Option 2: Fill in multiple passes using file caching (saves memory)
// 方案2 分多次 填充 会使用文件缓存省内存
fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx";
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
excelWriter.fill(data(), writeSheet);
excelWriter.fill(data(), writeSheet);
// Do not forget to close the stream
// 千万别忘记关闭流
excelWriter.finish();
}
/**
* Example of complex data filling.
* 复杂的填充
*
* @since 2.1.1
*/
@Test
public void complexFill() {
// Template note: Use {} to represent variables. If the template contains "{", "}" as special characters, use "\{", "\}" instead.
// {} represents a regular variable, {.} represents a list variable.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "complex.xlsx";
String fileName = TestFileUtil.getPath() + "complexFill" + System.currentTimeMillis() + ".xlsx";
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// Note: The `forceNewRow` parameter ensures that a new row is created when writing a list, even if there are no empty rows below it.
// By default, it is false, meaning it will use the next row if available, or create one if not.
// Setting `forceNewRow=true` has the drawback of loading all data into memory, so use it cautiously.
// If your template has a list and data below it, you must set `forceNewRow=true`, but this will consume more memory.
// For large datasets where the list is not the last row, refer to the next example.
// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行然后下面的数据往后移动默认 是false会直接使用下一行如果没有则创建
// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了所以慎用
// 简单的说 如果你的模板有list,且list不是最后一行下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
// 如果数据量大 list不是最后一行 参照下一个
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
excelWriter.fill(data(), fillConfig, writeSheet);
excelWriter.fill(data(), fillConfig, writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
map.put("total", 1000);
excelWriter.fill(map, writeSheet);
excelWriter.finish();
}
/**
* Example of complex data filling with large datasets.
* 数据量大的复杂填充
* <p>
* The solution here is to ensure the list in the template is the last row, then append a table.
* Note: Excel 2003 format is not supported and requires more memory.
* 这里的解决方案是 确保模板list为最后一行然后再拼接table.还有03版没救只能刚正面加内存
*
* @since 2.1.1
*/
@Test
public void complexFillWithTable() {
// Template note: Use {} to represent variables. If the template contains "{", "}" as special characters, use "\{", "\}" instead.
// {} represents a regular variable, {.} represents a list variable.
// Here, the template removes data after the list, such as summary rows.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
// 这里模板 删除了list以后的数据也就是统计的这一行
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "complexFillWithTable.xlsx";
String fileName = TestFileUtil.getPath() + "complexFillWithTable" + System.currentTimeMillis() + ".xlsx";
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// Directly write data
// 直接写入数据
excelWriter.fill(data(), writeSheet);
excelWriter.fill(data(), writeSheet);
// Write data before the list
// 写入list之前的数据
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
excelWriter.fill(map, writeSheet);
// Manually write summary data after the list
// Here, we use a list for simplicity, but an object could also be used.
// list 后面还有个统计 想办法手动写入
// 这里偷懒直接用list 也可以用对象
List<List<String>> totalListList = new ArrayList<List<String>>();
List<String> totalList = new ArrayList<String>();
totalListList.add(totalList);
totalList.add(null);
totalList.add(null);
totalList.add(null);
// Fourth column
totalList.add("Total: 1000");
// Use `write` instead of `fill` here
// 第四列
totalList.add("统计:1000");
// 这里是write 别和fill 搞错了
excelWriter.write(totalListList, writeSheet);
excelWriter.finish();
// Overall, this approach is complex, but no better solution is available.
// Asynchronous writing to Excel does not support row deletion or movement, nor does it support comments.
// Therefore, this workaround is necessary.
// 总体上写法比较复杂 但是也没有想到好的版本 异步的去写入excel 不支持行的删除和移动也不支持备注这种的写入所以也排除了可以
// 新建一个 然后一点点复制过来的方案最后导致list需要新增行的时候后面的列的数据没法后移后续会继续想想解决方案
}
/**
* Example of horizontal data filling.
* 横向的填充
*
* @since 2.1.1
*/
@Test
public void horizontalFill() {
// Template note: Use {} to represent variables. If the template contains "{", "}" as special characters, use "\{", "\}" instead.
// {} represents a regular variable, {.} represents a list variable.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "horizontal.xlsx";
@ -178,22 +173,22 @@ public class FillTempTest {
excelWriter.fill(data(), fillConfig, writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019-10-09 13:28:28");
map.put("date", "2019年10月9日13:28:28");
excelWriter.fill(map, writeSheet);
// Do not forget to close the stream
// 别忘记关闭流
excelWriter.finish();
}
/**
* Example of composite data filling with multiple lists.
* 多列表组合填充填充
*
* @since 2.2.0-beta1
*/
@Test
public void compositeFill() {
// Template note: Use {} to represent variables. If the template contains "{", "}" as special characters, use "\{", "\}" instead.
// {} represents a regular variable, {.} represents a list variable, and {prefix.} distinguishes different lists.
// 模板注意 {} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 "\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量 {前缀.} 前缀可以区分不同的list
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "composite.xlsx";
@ -201,8 +196,7 @@ public class FillTempTest {
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
// If there are multiple lists, the template must use {prefix.}, where "data1" is the prefix.
// Multiple lists must be wrapped in FillWrapper.
// 如果有多个list 模板上必须有{前缀.} 这里的前缀就是 data1然后多个list必须用 FillWrapper包裹
excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data2", data()), writeSheet);
@ -211,26 +205,21 @@ public class FillTempTest {
excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
//map.put("date", "2019-10-09 13:28:28");
//map.put("date", "2019年10月9日13:28:28");
map.put("date", new Date());
excelWriter.fill(map, writeSheet);
// Do not forget to close the stream
// 别忘记关闭流
excelWriter.finish();
}
/**
* Generates sample data for filling.
*
* @return A list of FillData objects.
*/
private List<FillData> data() {
List<FillData> list = new ArrayList<FillData>();
for (int i = 0; i < 10; i++) {
FillData fillData = new FillData();
list.add(fillData);
fillData.setName("Zhang San");
fillData.setName("张三");
fillData.setNumber(5.2);
}
return list;

View File

@ -17,7 +17,7 @@ import org.junit.jupiter.api.Test;
@Slf4j
public class Issue2443Test {
//CS304 (manually written) Issue link: https://github.com/fast-excel/fastexcel/issues/2443
//CS304 (manually written) Issue link: https://github.com/CodePhiliaX/fastexcel/issues/2443
@Test
public void IssueTest1() {
String fileName = TestFileUtil.getPath() + "temp/issue2443" + File.separator + "date1.xlsx";
@ -28,7 +28,7 @@ public class Issue2443Test {
})).sheet().doRead();
}
//CS304 (manually written) Issue link: https://github.com/fast-excel/fastexcel/issues/2443
//CS304 (manually written) Issue link: https://github.com/CodePhiliaX/fastexcel/issues/2443
@Test
public void IssueTest2() {
String fileName = TestFileUtil.getPath() + "temp/issue2443" + File.separator + "date2.xlsx";

View File

@ -1,2 +1,2 @@
Name,Number,Complex,Ignored,Empty
{name},{number},{name} is {number} years old this year,\{name\} ignored {name},Empty{.empty}
姓名,数字,复杂,忽略,
{name},{number},{name}今年{number}岁了,\{name\}忽略,{name},{.empty}
1 Name 姓名 Number 数字 Complex 复杂 Ignored 忽略 Empty
2 {name} {name} {number} {number} {name} is {number} years old this year {name}今年{number}岁了 \{name\} ignored, {name} \{name\}忽略,{name} Empty{.empty} 空{.empty}

View File

@ -7,18 +7,22 @@
<parent>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel-parent</artifactId>
<version>1.1.0</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<url>https://github.com/CodePhiliaX/fastexcel</url>
<packaging>jar</packaging>
<artifactId>fastexcel</artifactId>
<name>fastexcel</name>
<version>${revision}</version>
<dependencies>
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel-core</artifactId>
<version>${project.version}</version>
<version>${revision}</version>
</dependency>
</dependencies>

228
mvnw vendored
View File

@ -19,7 +19,7 @@
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.2.0
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
@ -27,6 +27,7 @@
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@ -53,7 +54,7 @@ fi
cygwin=false;
darwin=false;
mingw=false
case "$(uname)" in
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
@ -61,9 +62,9 @@ case "$(uname)" in
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
export JAVA_HOME="`/usr/libexec/java_home`"
else
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
@ -71,38 +72,68 @@ esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=$(java-config --jre-home)
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="$(which javac)"
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=$(which readlink)
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="$(dirname "\"$javaExecutable\"")"
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="$(dirname "\"$javaExecutable\"")"
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
@ -118,7 +149,7 @@ if [ -z "$JAVACMD" ] ; then
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
@ -132,9 +163,12 @@ if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
@ -150,99 +184,96 @@ find_maven_basedir() {
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=$(cd "$wdir/.." || exit 1; pwd)
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
# Remove \r in case we run on Windows within Git Bash
# and check out the repository with auto CRLF management
# enabled. Otherwise, we may read lines that are delimited with
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
# splitting rules.
tr -s '\r\n' ' ' < "$1"
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
log() {
if [ "$MVNW_VERBOSE" = true ]; then
printf '%s\n' "$1"
fi
}
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
log "$MAVEN_PROJECTBASEDIR"
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
if [ -r "$wrapperJarPath" ]; then
log "Found $wrapperJarPath"
else
log "Couldn't find $wrapperJarPath, downloading it ..."
if [ -n "$MVNW_REPOURL" ]; then
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
else
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
while IFS="=" read -r key value; do
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
safeValue=$(echo "$value" | tr -d '\r')
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
log "Downloading from: $wrapperUrl"
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
log "Found wget ... using wget"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
log "Found curl ... using curl"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
else
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
log "Falling back to using Java to download"
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaSource=$(cygpath --path --windows "$javaSource")
javaClass=$(cygpath --path --windows "$javaClass")
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaSource" ]; then
if [ ! -e "$javaClass" ]; then
log " - Compiling MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/javac" "$javaSource")
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$javaClass" ]; then
log " - Running MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
@ -251,58 +282,35 @@ fi
# End of extension
##########################################################################################
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
wrapperSha256Sum=""
while IFS="=" read -r key value; do
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
if [ -n "$wrapperSha256Sum" ]; then
wrapperSha256Result=false
if command -v sha256sum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
elif command -v shasum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
exit 1
fi
if [ $wrapperSha256Result = false ]; then
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
exit 1
fi
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
# shellcheck disable=SC2086 # safe args
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

393
mvnw.cmd vendored
View File

@ -1,205 +1,188 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.2.0
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
SET WRAPPER_SHA_256_SUM=""
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
)
IF NOT %WRAPPER_SHA_256_SUM%=="" (
powershell -Command "&{"^
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
" exit 1;"^
"}"^
"}"
if ERRORLEVEL 1 goto error
)
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

167
pom.xml
View File

@ -1,20 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel-parent</artifactId>
<version>1.1.0</version>
<packaging>pom</packaging>
<version>${revision}</version>
<name>fastexcel-parent</name>
<description>Fastexcel is an Excel handle tools written in Java</description>
<url>https://github.com/fast-excel/fastexcel</url>
<description>fastexcel is a excel handle tools written in Java</description>
<url>https://github.com/CodePhiliaX/fastexcel</url>
<inceptionYear>2024</inceptionYear>
<modules>
@ -24,37 +18,25 @@
<module>fastexcel</module>
</modules>
<properties>
<revision>1.0.0</revision>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.8</jdk.version>
<gpg.skip>true</gpg.skip>
<maven.javadoc.skip>true</maven.javadoc.skip>
<maven.test.skip>true</maven.test.skip>
<commons-csv.version>1.11.0</commons-csv.version>
<poi.version>5.3.0</poi.version>
<poi-ooxml.version>5.3.0</poi-ooxml.version>
<ehcache.version>3.9.11</ehcache.version>
<commons-io.version>2.16.1</commons-io.version>
<slf4j-api.version>1.7.36</slf4j-api.version>
<lombok.version>1.18.32</lombok.version>
<spring-core.version>5.3.37</spring-core.version>
<fastjson2.version>2.0.51</fastjson2.version>
<spring-boot-starter-web.version>2.7.18</spring-boot-starter-web.version>
<spring-boot-starter-test.version>2.7.18</spring-boot-starter-test.version>
<slf4j-simple.version>1.7.36</slf4j-simple.version>
<jcl-over-slf4j.version>1.7.36</jcl-over-slf4j.version>
<log4j-over-slf4j.version>1.7.36</log4j-over-slf4j.version>
<logback-classic.version>1.5.6</logback-classic.version>
</properties>
<scm>
<url>https://github.com/fast-excel/fastexcel</url>
<connection>scm:git:https://git@github.com/fast-excel/fastexcel.git</connection>
<url>https://github.com/CodePhiliaX/fastexcel</url>
<connection>scm:git:https://git@github.com/CodePhiliaX/fastexcel.git</connection>
</scm>
<organization>
<name>fast-excel</name>
<url>https://github.com/fast-excel</url>
<name>Chat2DB</name>
<url>https://github.com/CodePhiliaX</url>
</organization>
<developers>
@ -72,12 +54,14 @@
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
<distribution>repo</distribution>
<comments>A permissive license that allows for wide reuse</comments>
</license>
</licenses>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
@ -91,99 +75,6 @@
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>${commons-csv.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi-ooxml.version}</version>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${ehcache.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<!-- provided -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-core.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j-simple.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${jcl-over-slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${log4j-over-slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-starter-web.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot-starter-test.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -231,6 +122,11 @@
<artifactId>flatten-maven-plugin</artifactId>
<version>1.2.7</version>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.sonatype.plugins</groupId>-->
<!-- <artifactId>nexus-staging-maven-plugin</artifactId>-->
<!-- <version>1.6.13</version>-->
<!-- </plugin>-->
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
@ -241,6 +137,7 @@
<plugins>
<!-- code style -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
@ -341,16 +238,16 @@
</plugin>
<!-- Publish package to the Maven Central Repository -->
<!-- <plugin>-->
<!-- <groupId>org.sonatype.plugins</groupId>-->
<!-- <artifactId>nexus-staging-maven-plugin</artifactId>-->
<!-- <extensions>true</extensions>-->
<!-- <configuration>-->
<!-- <serverId>ossrh</serverId>-->
<!-- <nexusUrl>https://oss.sonatype.org/</nexusUrl>-->
<!-- <autoReleaseAfterClose>true</autoReleaseAfterClose>-->
<!-- </configuration>-->
<!-- </plugin>-->
<!-- <plugin>-->
<!-- <groupId>org.sonatype.plugins</groupId>-->
<!-- <artifactId>nexus-staging-maven-plugin</artifactId>-->
<!-- <extensions>true</extensions>-->
<!-- <configuration>-->
<!-- <serverId>ossrh</serverId>-->
<!-- <nexusUrl>https://oss.sonatype.org/</nexusUrl>-->
<!-- <autoReleaseAfterClose>true</autoReleaseAfterClose>-->
<!-- </configuration>-->
<!-- </plugin>-->
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>

0
quickstart.md Normal file
View File

View File

@ -0,0 +1,3 @@
/**
* Documents have been migrated to <a href="https://github.com/CodePhiliaX/fastexcel/blob/master/easyexcel-test/src/test/java/com/CodePhiliaX/fastexcel/test/demo/fill/FillTest.java">https://github.com/CodePhiliaX/fastexcel/blob/master/easyexcel-test/src/test/java/com/CodePhiliaX/fastexcel/test/demo/fill/FillTest.java</a>
*/

View File

@ -0,0 +1,3 @@
/**
* Documents have been migrated to <a href="https://github.com/CodePhiliaX/fastexcel/blob/master/easyexcel-test/src/test/java/com/CodePhiliaX/fastexcel/test/demo/read/ReadTest.java">https://github.com/CodePhiliaX/fastexcel/blob/master/easyexcel-test/src/test/java/com/CodePhiliaX/fastexcel/test/demo/read/ReadTest.java</a>
*/

View File

@ -0,0 +1,3 @@
/**
* Documents have been migrated to <a href="https://github.com/CodePhiliaX/fastexcel/blob/master/easyexcel-test/src/test/java/com/CodePhiliaX/fastexcel/test/demo/web/WebTest.java">https://github.com/CodePhiliaX/fastexcel/blob/master/easyexcel-test/src/test/java/com/CodePhiliaX/fastexcel/test/demo/web/WebTest.java</a>
*/

View File

@ -0,0 +1,3 @@
/**
* Documents have been migrated to <a href="https://github.com/CodePhiliaX/fastexcel/blob/master/easyexcel-test/src/test/java/com/CodePhiliaX/fastexcel/test/demo/write/WriteTest.java">https://github.com/CodePhiliaX/fastexcel/blob/master/easyexcel-test/src/test/java/com/CodePhiliaX/fastexcel/test/demo/write/WriteTest.java</a>
*/

View File

@ -1,105 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--Refer http://checkstyle.sourceforge.net/reports/google-java-style.html#s2.2-file-encoding -->
<module name="Checker">
<property name="localeLanguage" value="en"/>
<!--To configure the check to report on the first instance in each file-->
<module name="FileTabCharacter"/>
<module name="RegexpSingleline">
<property name="format" value="System\.out\.println"/>
<property name="message" value="Prohibit invoking System.out.println in source code !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="//FIXME"/>
<property name="message" value="Recommended fix FIXME task !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="//TODO"/>
<property name="message" value="Recommended fix TODO task !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="@taobao"/>
<property name="message" value="Recommended remove @taobao keyword!"/>
</module>
<module name="RegexpSingleline">
<property name="format"
value=".*[\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF]+.*"/>
<property name="message" value="Not allow chinese character !"/>
</module>
<module name="FileLength">
<property name="max" value="3000"/>
</module>
<module name="TreeWalker">
<module name="RedundantImport"/>
<!--<module name="IllegalImport" />-->
<!--Checks that classes that override equals() also override hashCode()-->
<module name="EqualsHashCode"/>
<!--Checks for over-complicated boolean expressions. Currently finds code like if (topic == true), topic || true, !false, etc.-->
<module name="SimplifyBooleanExpression"/>
<module name="OneStatementPerLine"/>
<module name="UnnecessaryParentheses"/>
<!--Checks for over-complicated boolean return statements. For example the following code-->
<module name="SimplifyBooleanReturn"/>
<!--Check that the default is after all the cases in producerGroup switch statement-->
<module name="DefaultComesLast"/>
<!--Detects empty statements (standalone ";" semicolon)-->
<module name="EmptyStatement"/>
<!--Checks that long constants are defined with an upper ell-->
<module name="UpperEll"/>
<module name="ConstantName">
<property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)|(^log$)"/>
</module>
<!--Checks that local, non-final variable names conform to producerGroup format specified by the format property-->
<module name="LocalVariableName"/>
<!--Validates identifiers for local, final variables, including catch parameters-->
<module name="LocalFinalVariableName"/>
<!--Validates identifiers for non-static fields-->
<module name="MemberName"/>
<!--Validates identifiers for class type parameters-->
<module name="ClassTypeParameterName">
<property name="format" value="^[A-Z0-9]*$"/>
</module>
<!--Validates identifiers for method type parameters-->
<module name="MethodTypeParameterName">
<property name="format" value="^[A-Z0-9]*$"/>
</module>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName">
<property name="format" value="^[a-zA-Z0-9_]*$"/>
</module>
<module name="TypeName"/>
<!--Checks that there are no import statements that use the * notation-->
<module name="AvoidStarImport"/>
<!-- unused imports -->
<module name="UnusedImports"/>
<!--whitespace-->
<module name="GenericWhitespace"/>
<!--<module name="NoWhitespaceBefore"/>-->
<!--<module name="NoWhitespaceAfter"/>-->
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyMethods" value="true"/>
</module>
<module name="Indentation"/>
<module name="MethodParamPad"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
</module>
</module>

9
update.md Normal file
View File

@ -0,0 +1,9 @@
# 1.1.0
此次升级主要修复历史 BUG同时剔除了部分依赖库保证 `MIT` 协议下的使用。
具体更新内容如下:
- 【改进】移除 `itext` 依赖库,将 `转换PDF` 功能迁移至新项目;
- 【修复】fill填充空数据可能导致行数据错乱的问题
- 【修复】自定义数据格式可能导致数据读取失败的问题;
- 【优化】增加报错内容详细信息;
- 【优化】更新代码格式和部分错别字。