Merge pull request #169 from CodePhiliaX/feature-1.x
montly release to 1.1.0
This commit is contained in:
commit
2c8d0abfd0
@ -0,0 +1,12 @@
|
||||
<!-- 请确保你已经阅读并理解了贡献指南 -->
|
||||
|
||||
### Ⅰ. 描述这个 PR 做了什么
|
||||
|
||||
### Ⅱ. 这个 pull request 是否修复了一个问题?
|
||||
<!-- 如果是,请在下一行添加“fix #xxx”,例如 fix #97。-->
|
||||
|
||||
### Ⅲ. 为什么不需要添加测试用例(单元测试/集成测试)?
|
||||
|
||||
### Ⅳ. 描述如何验证它
|
||||
|
||||
### Ⅴ. 评审的特别说明
|
144
CONTRIBUTING.md
144
CONTRIBUTING.md
@ -0,0 +1,144 @@
|
||||
# 为 FastExcel 做贡献
|
||||
|
||||
FastExcel 欢迎社区的每一位用户和开发者成为贡献者。无论是报告问题、改进文档、提交代码,还是提供技术支持,您的参与都将帮助 FastExcel 变得更好。
|
||||
|
||||
---
|
||||
|
||||
## 报告问题
|
||||
|
||||
我们鼓励用户在使用 FastExcel 的过程中随时提供反馈。您可以通过 [NEW ISSUE](https://github.com/CodePhiliaX/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/CodePhiliaX/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:CodePhiliaX/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 的支持!每一份帮助,都是我们前进的动力。**
|
@ -37,20 +37,22 @@ FastExcel 将始终坚持免费开源,并采用最开放的 MIT 协议,使
|
||||
|
||||
> 当前 FastExcel 底层使用 poi 作为基础包,如果您的项目中已经有 poi 相关组件,需要您手动排除 poi 的相关 jar 包。
|
||||
|
||||
## 更新
|
||||
您可以在 [版本升级详情](update.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.0.0</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
```
|
||||
### Gradle
|
||||
如果您使用 Gradle 进行项目构建,请在 `build.gradle` 文件中引入以下配置:
|
||||
```gradle
|
||||
dependencies {
|
||||
implementation 'cn.idev.excel:fastexcel:1.0.0'
|
||||
implementation 'cn.idev.excel:fastexcel:1.1.0'
|
||||
}
|
||||
```
|
||||
## EasyExcel 与 FastExcel 的区别
|
||||
@ -75,7 +77,7 @@ dependencies {
|
||||
<dependency>
|
||||
<groupId>cn.idev.excel</groupId>
|
||||
<artifactId>fastexcel</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
@ -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.0.0</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
```
|
||||
### Gradle
|
||||
@ -45,9 +45,11 @@ If you are using Gradle for project building, add the following configuration in
|
||||
|
||||
```gradle
|
||||
dependencies {
|
||||
implementation 'cn.idev.excel:fastexcel:1.0.0'
|
||||
implementation 'cn.idev.excel:fastexcel:1.1.0'
|
||||
}
|
||||
```
|
||||
## Update
|
||||
For detailed update logs, refer to [Details of version updates](update.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.
|
||||
@ -71,7 +73,7 @@ Replace with:
|
||||
<dependency>
|
||||
<groupId>cn.idev.excel</groupId>
|
||||
<artifactId>fastexcel</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
```
|
||||
### 2. Modify Code
|
||||
|
@ -37,7 +37,7 @@ Mavenでプロジェクトを構築する場合、`pom.xml`ファイルに次の
|
||||
<dependency>
|
||||
<groupId>cn.idev.excel</groupId>
|
||||
<artifactId>fastexcel</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
```
|
||||
### Gradle
|
||||
@ -45,9 +45,11 @@ Mavenでプロジェクトを構築する場合、`pom.xml`ファイルに次の
|
||||
Gradleでプロジェクトを構築する場合、build.gradleファイルに次の構成を含めてください:
|
||||
```gradle
|
||||
dependencies {
|
||||
implementation 'cn.idev.excel:fastexcel:1.0.0'
|
||||
implementation 'cn.idev.excel:fastexcel:1.1.0'
|
||||
}
|
||||
```
|
||||
## 更新する
|
||||
具体的なバージョンアップ内容は[バージョンアップ詳細](update.md)で確認できます。 [Maven Central Repository](https://mvnrepository.com/artifact/cn.idev.excel/fastexcel) 内のすべてのバージョンをクエリすることもできます。
|
||||
## EasyExcelとFastExcelの違い
|
||||
- FastExcelはEasyExcelのすべての機能をサポートしていますが、FastExcelのパフォーマンスはより良く、より安定しています。
|
||||
- FastExcelとEasyExcelのAPIは完全に一致しているため、シームレスに切り替えることができます。
|
||||
@ -68,7 +70,7 @@ EasyExcelの依存関係をFastExcelの依存関係に置き換えます。以
|
||||
<dependency>
|
||||
<groupId>cn.idev.excel</groupId>
|
||||
<artifactId>fastexcel</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
```
|
||||
### 2. コードの修正
|
||||
|
@ -1 +0,0 @@
|
||||
1
|
@ -16,9 +16,6 @@
|
||||
<name>fastexcel-core</name>
|
||||
<version>${revision}</version>
|
||||
|
||||
<properties>
|
||||
<itext.version>7.1.15</itext.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@ -31,11 +28,27 @@
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>5.2.5</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>5.2.5</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -65,47 +78,5 @@
|
||||
<artifactId>fastexcel-support</artifactId>
|
||||
<version>0.0.1</version>
|
||||
</dependency>
|
||||
<!-- itext7 -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itext7-core</artifactId>
|
||||
<version>${itext.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>kernel</artifactId>
|
||||
<version>${itext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>io</artifactId>
|
||||
<version>${itext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>layout</artifactId>
|
||||
<version>${itext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>forms</artifactId>
|
||||
<version>${itext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>pdfa</artifactId>
|
||||
<version>${itext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>pdftest</artifactId>
|
||||
<version>${itext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>font-asian</artifactId>
|
||||
<version>${itext.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -1,10 +1,5 @@
|
||||
package cn.idev.excel;
|
||||
|
||||
import cn.idev.excel.fileconvertor.ExcelConverter;
|
||||
import cn.idev.excel.fileconvertor.FileConverterContext;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* This is actually {@link FastExcelFactory}, and short names look better.
|
||||
*
|
||||
@ -12,18 +7,4 @@ import java.io.File;
|
||||
*/
|
||||
public class FastExcel extends FastExcelFactory {
|
||||
|
||||
/**
|
||||
* Convert excel to pdf
|
||||
*
|
||||
* @param excelFile excel file
|
||||
* @param pdfFile pdf file
|
||||
* @param fontPath font path for pdf can be null
|
||||
* @param sheets sheet index to convert, if null convert all sheets
|
||||
*/
|
||||
public static void convertToPdf(File excelFile, File pdfFile, String fontPath, int[] sheets) {
|
||||
FileConverterContext context = new FileConverterContext(excelFile, pdfFile, fontPath, sheets);
|
||||
ExcelConverter excelConverter = context.getExcelConverter();
|
||||
excelConverter.convertToPdf();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ import org.xml.sax.helpers.DefaultHandler;
|
||||
*/
|
||||
public class SharedStringsTableHandler extends DefaultHandler {
|
||||
|
||||
private static final Pattern UTF_PATTTERN = Pattern.compile("_x([0-9A-Fa-f]{4})_");
|
||||
private static final Pattern UTF_PATTERN = Pattern.compile("_x([0-9A-Fa-f]{4})_");
|
||||
|
||||
/**
|
||||
* The final piece of data
|
||||
@ -154,7 +154,7 @@ public class SharedStringsTableHandler extends DefaultHandler {
|
||||
}
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Matcher m = UTF_PATTTERN.matcher(value);
|
||||
Matcher m = UTF_PATTERN.matcher(value);
|
||||
int idx = 0;
|
||||
while (m.find()) {
|
||||
int pos = m.start();
|
||||
|
@ -4,7 +4,6 @@ import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.idev.excel.util.MapUtils;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.io.ByteOrderMark;
|
||||
|
||||
@ -35,9 +34,7 @@ public enum ByteOrderMarkEnum {
|
||||
/**
|
||||
* UTF_32LE
|
||||
*/
|
||||
UTF_32LE(ByteOrderMark.UTF_32LE),
|
||||
|
||||
;
|
||||
UTF_32LE(ByteOrderMark.UTF_32LE);
|
||||
|
||||
final ByteOrderMark byteOrderMark;
|
||||
final String stringPrefix;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.idev.excel.enums;
|
||||
|
||||
/**
|
||||
* cache locaciton
|
||||
* cache location
|
||||
*
|
||||
* @author Jiaju Zhuang
|
||||
**/
|
||||
@ -19,5 +19,5 @@ public enum CacheLocationEnum {
|
||||
/**
|
||||
* No caching.It may lose some of performance.
|
||||
*/
|
||||
NONE;
|
||||
NONE
|
||||
}
|
||||
|
@ -43,8 +43,7 @@ public enum CellDataTypeEnum {
|
||||
/**
|
||||
* rich text string.Support only when writing.
|
||||
*/
|
||||
RICH_TEXT_STRING,
|
||||
;
|
||||
RICH_TEXT_STRING;
|
||||
|
||||
private static final Map<String, CellDataTypeEnum> TYPE_ROUTING_MAP = new HashMap<String, CellDataTypeEnum>(16);
|
||||
|
||||
|
@ -17,5 +17,5 @@ public enum CellExtraTypeEnum {
|
||||
/**
|
||||
* Merge
|
||||
*/
|
||||
MERGE,;
|
||||
MERGE
|
||||
}
|
||||
|
@ -17,5 +17,5 @@ public enum HeadKindEnum {
|
||||
/**
|
||||
* String
|
||||
*/
|
||||
STRING;
|
||||
STRING
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ public enum ReadDefaultReturnEnum {
|
||||
/**
|
||||
* Return to {@link ReadCellData}, can decide which field you need.
|
||||
*/
|
||||
READ_CELL_DATA,
|
||||
;
|
||||
READ_CELL_DATA
|
||||
|
||||
}
|
||||
|
@ -17,5 +17,5 @@ public enum WriteLastRowTypeEnum {
|
||||
/**
|
||||
* Any data has been written;
|
||||
*/
|
||||
HAS_DATA,;
|
||||
HAS_DATA
|
||||
}
|
||||
|
@ -13,5 +13,5 @@ public enum WriteTemplateAnalysisCellTypeEnum {
|
||||
/**
|
||||
* A collection of fields.
|
||||
*/
|
||||
COLLECTION,;
|
||||
COLLECTION
|
||||
}
|
||||
|
@ -13,5 +13,5 @@ public enum WriteTypeEnum {
|
||||
/**
|
||||
* Fill.
|
||||
*/
|
||||
FILL,;
|
||||
FILL
|
||||
}
|
||||
|
@ -1,172 +0,0 @@
|
||||
package cn.idev.excel.fileconvertor;
|
||||
|
||||
import com.itextpdf.layout.element.Table;
|
||||
import com.itextpdf.layout.property.TextAlignment;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseExcelConverter implements ExcelConverter {
|
||||
|
||||
private final FileConverterContext context;
|
||||
|
||||
public BaseExcelConverter(FileConverterContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToPdf() {
|
||||
try {
|
||||
for (int sheetIndex : context.getSheets()) {
|
||||
processSheet(sheetIndex);
|
||||
}
|
||||
context.getDocument().close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processSheet(int sheetIndex) throws IOException {
|
||||
Sheet sheet = context.getWorkbook().getSheetAt(sheetIndex);
|
||||
if (sheet == null || sheet.getRow(0) == null) {
|
||||
return;
|
||||
}
|
||||
float[] columnWidths = getColumnWidths(sheet);
|
||||
Table table = new Table(columnWidths);
|
||||
|
||||
addRowsToTable(table, sheet, columnWidths, context.getFontPath());
|
||||
// addPicsToTable(table, sheet);
|
||||
|
||||
context.getDocument().add(table);
|
||||
}
|
||||
|
||||
protected abstract void addPicsToTable(Table table, Sheet sheet);
|
||||
|
||||
private void addRowsToTable(Table table, Sheet sheet, float[] columnWidths, String fontPath) throws IOException {
|
||||
int lastRowNum = sheet.getLastRowNum() + 1;
|
||||
int lastCellNum = sheet.getRow(0).getLastCellNum();
|
||||
for (int i = 0; i < lastRowNum; i++) {
|
||||
Row row = sheet.getRow(i);
|
||||
addRowToTable(table, row, lastCellNum, columnWidths, fontPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void addRowToTable(Table table, Row row, int lastCellNum, float[] columnWidths, String fontPath) throws IOException {
|
||||
if (row == null) {
|
||||
addEmptyCells(table, lastCellNum); // 0 for empty row
|
||||
return;
|
||||
}
|
||||
|
||||
for (int j = 0; j < lastCellNum; j++) {
|
||||
Cell cell = row.getCell(j);
|
||||
if (cell != null && !isCellProcessed(cell)) {
|
||||
// addCellToTable(table, cell, columnWidths, fontPath);
|
||||
CellRangeAddress cellRange = getCellRangeAddress(cell);
|
||||
int rowspan = (cellRange != null) ? (cellRange.getLastRow() - cellRange.getFirstRow() + 1) : 1;
|
||||
int colspan = (cellRange != null) ? (cellRange.getLastColumn() - cellRange.getFirstColumn() + 1) : 1;
|
||||
if ((cellRange != null)) {
|
||||
j = cellRange.getLastColumn();
|
||||
}
|
||||
float maxWidth = (cellRange != null) ? calculateMaxWidth(columnWidths, cellRange) : columnWidths[j];
|
||||
|
||||
com.itextpdf.layout.element.Cell pdfCell = convertCell(cell, rowspan, colspan, maxWidth, fontPath);
|
||||
table.addCell(pdfCell);
|
||||
} else if (cell == null) {
|
||||
addEmptyCell(table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float calculateMaxWidth(float[] columnWidths, CellRangeAddress cellRange) {
|
||||
float maxWidth = 0;
|
||||
for (int k = cellRange.getFirstColumn(); k < cellRange.getLastColumn(); k++) {
|
||||
maxWidth += columnWidths[k];
|
||||
}
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
private void addEmptyCell(Table table) {
|
||||
com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell();
|
||||
pdfCell.setBorder(com.itextpdf.layout.borders.Border.NO_BORDER);
|
||||
table.addCell(pdfCell);
|
||||
}
|
||||
|
||||
private void addEmptyCells(Table table, int numberOfCells) {
|
||||
for (int j = 0; j < numberOfCells; j++) {
|
||||
addEmptyCell(table);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract com.itextpdf.layout.element.Cell convertCell(Cell cell, int rowspan, int colspan, float maxWidth, String fontPath) throws IOException;
|
||||
|
||||
public static com.itextpdf.layout.property.VerticalAlignment getVerticalAlignment(VerticalAlignment verticalAlignment) {
|
||||
switch (verticalAlignment) {
|
||||
case TOP:
|
||||
return com.itextpdf.layout.property.VerticalAlignment.TOP;
|
||||
case BOTTOM:
|
||||
return com.itextpdf.layout.property.VerticalAlignment.BOTTOM;
|
||||
case JUSTIFY:
|
||||
case CENTER:
|
||||
return com.itextpdf.layout.property.VerticalAlignment.MIDDLE;
|
||||
}
|
||||
return com.itextpdf.layout.property.VerticalAlignment.MIDDLE;
|
||||
}
|
||||
|
||||
public static TextAlignment getTextAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment alignment, CellType cellType) {
|
||||
switch (alignment) {
|
||||
case LEFT:
|
||||
return TextAlignment.LEFT;
|
||||
case RIGHT:
|
||||
return TextAlignment.RIGHT;
|
||||
case CENTER:
|
||||
return TextAlignment.CENTER;
|
||||
case JUSTIFY:
|
||||
return TextAlignment.JUSTIFIED;
|
||||
case GENERAL:
|
||||
if (cellType == CellType.NUMERIC) {
|
||||
return TextAlignment.RIGHT;
|
||||
} else if (cellType == CellType.BOOLEAN) {
|
||||
return TextAlignment.CENTER;
|
||||
}
|
||||
}
|
||||
return TextAlignment.LEFT;
|
||||
}
|
||||
|
||||
private float[] getColumnWidths(Sheet sheet) {
|
||||
short lastCellNum = sheet.getRow(0).getLastCellNum();
|
||||
float[] widths = new float[lastCellNum];
|
||||
for (int i = 0; i < lastCellNum; i++) {
|
||||
widths[i] = sheet.getColumnWidthInPixels(i);
|
||||
}
|
||||
return widths;
|
||||
}
|
||||
|
||||
private boolean isCellProcessed(Cell cell) {
|
||||
List<CellRangeAddress> mergedRegions = cell.getSheet().getMergedRegions();
|
||||
int rowIndex = cell.getRowIndex();
|
||||
int columnIndex = cell.getColumnIndex();
|
||||
|
||||
for (CellRangeAddress cellAddresses : mergedRegions) {
|
||||
if (cellAddresses.getFirstRow() <= rowIndex && cellAddresses.getLastRow() >= rowIndex
|
||||
&& cellAddresses.getFirstColumn() <= columnIndex && cellAddresses.getLastColumn() >= columnIndex) {
|
||||
return !(cellAddresses.getFirstRow() == rowIndex && cellAddresses.getFirstColumn() == columnIndex);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private CellRangeAddress getCellRangeAddress(Cell cell) {
|
||||
List<CellRangeAddress> mergedRegions = cell.getSheet().getMergedRegions();
|
||||
int rowIndex = cell.getRowIndex();
|
||||
int columnIndex = cell.getColumnIndex();
|
||||
|
||||
for (CellRangeAddress cellAddresses : mergedRegions) {
|
||||
if (cellAddresses.getFirstRow() == rowIndex && cellAddresses.getFirstColumn() == columnIndex) {
|
||||
return cellAddresses;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package cn.idev.excel.fileconvertor;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.ss.usermodel.DateUtil;
|
||||
import org.apache.poi.util.LocaleUtil;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
public class Excel2PdfUtils {
|
||||
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; // 日期格式
|
||||
private static final String TRUE_STRING = "TRUE";
|
||||
private static final String FALSE_STRING = "FALSE";
|
||||
private static final String EMPTY_STRING = "";
|
||||
|
||||
// 使用单例模式确保 SimpleDateFormat 只被创建一次
|
||||
private static final ThreadLocal<SimpleDateFormat> DATE_FORMATTER = ThreadLocal.withInitial(() ->
|
||||
new SimpleDateFormat(DATE_FORMAT, LocaleUtil.getUserLocale())
|
||||
);
|
||||
|
||||
public static String getValue(Cell cell) {
|
||||
if (cell == null) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
CellType cellType = cell.getCellType();
|
||||
switch (cellType) {
|
||||
case BOOLEAN:
|
||||
return cell.getBooleanCellValue() ? TRUE_STRING : FALSE_STRING;
|
||||
case NUMERIC:
|
||||
return getNumericCellValue(cell);
|
||||
case STRING:
|
||||
return cell.getStringCellValue();
|
||||
default:
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getNumericCellValue(Cell cell) {
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
return DATE_FORMATTER.get().format(cell.getDateCellValue());
|
||||
}
|
||||
return String.valueOf(cell.getNumericCellValue());
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package cn.idev.excel.fileconvertor;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Excel convert to other file
|
||||
* @author jipengfei
|
||||
*/
|
||||
public interface ExcelConverter {
|
||||
|
||||
/**
|
||||
* excel to pdf
|
||||
*
|
||||
*/
|
||||
void convertToPdf();
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
package cn.idev.excel.fileconvertor;
|
||||
|
||||
import cn.idev.excel.read.metadata.ReadWorkbook;
|
||||
import cn.idev.excel.support.ExcelTypeEnum;
|
||||
import com.itextpdf.kernel.geom.PageSize;
|
||||
import com.itextpdf.kernel.pdf.PdfDocument;
|
||||
import com.itextpdf.kernel.pdf.PdfWriter;
|
||||
import com.itextpdf.layout.Document;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileConverterContext {
|
||||
|
||||
private File inputFile;
|
||||
private File outputFile;
|
||||
private String fontPath;
|
||||
private Workbook workbook;
|
||||
private Document document;
|
||||
private int[] sheets;
|
||||
private ExcelTypeEnum excelTypeEnum;
|
||||
|
||||
public FileConverterContext(File inputFile, File outputFile, String fontPath, int[] sheets) {
|
||||
try {
|
||||
this.inputFile = inputFile;
|
||||
this.outputFile = outputFile;
|
||||
this.fontPath = fontPath;
|
||||
ReadWorkbook readWorkbook = new ReadWorkbook();
|
||||
readWorkbook.setFile(inputFile);
|
||||
excelTypeEnum = ExcelTypeEnum.valueOf(readWorkbook);
|
||||
if (excelTypeEnum == ExcelTypeEnum.XLSX) {
|
||||
this.workbook = new XSSFWorkbook(inputFile);
|
||||
} else if (excelTypeEnum == ExcelTypeEnum.XLS) {
|
||||
this.workbook = new HSSFWorkbook(new FileInputStream(inputFile));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not supported excel type");
|
||||
}
|
||||
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outputFile));
|
||||
this.document = new Document(pdfDocument, PageSize.A4.rotate());
|
||||
if (sheets == null) {
|
||||
this.sheets = new int[workbook.getNumberOfSheets()];
|
||||
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
|
||||
this.sheets[i] = i;
|
||||
}
|
||||
} else {
|
||||
this.sheets = sheets;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public ExcelConverter getExcelConverter() {
|
||||
if (excelTypeEnum == ExcelTypeEnum.XLSX) {
|
||||
return new cn.idev.excel.fileconvertor.v07.XlsxConverter(this);
|
||||
} else if (excelTypeEnum == ExcelTypeEnum.XLS) {
|
||||
return new cn.idev.excel.fileconvertor.v03.XlsConverter(this);
|
||||
}
|
||||
throw new IllegalArgumentException("Not supported excel type");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
package cn.idev.excel.fileconvertor.v03;
|
||||
|
||||
import cn.idev.excel.fileconvertor.BaseExcelConverter;
|
||||
import cn.idev.excel.fileconvertor.Excel2PdfUtils;
|
||||
import cn.idev.excel.fileconvertor.FileConverterContext;
|
||||
import cn.idev.excel.util.StringUtils;
|
||||
import com.itextpdf.io.font.PdfEncodings;
|
||||
import com.itextpdf.kernel.colors.Color;
|
||||
import com.itextpdf.kernel.colors.ColorConstants;
|
||||
import com.itextpdf.kernel.colors.DeviceRgb;
|
||||
import com.itextpdf.kernel.font.PdfFontFactory;
|
||||
import com.itextpdf.layout.borders.*;
|
||||
import com.itextpdf.layout.element.*;
|
||||
import com.itextpdf.layout.element.Cell;
|
||||
import com.itextpdf.layout.element.Table;
|
||||
import org.apache.poi.hssf.usermodel.*;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class XlsConverter extends BaseExcelConverter {
|
||||
public XlsConverter(FileConverterContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPicsToTable(Table table, Sheet sheet) {
|
||||
HSSFPatriarch drawingPatriarch = ((HSSFSheet) sheet).getDrawingPatriarch();
|
||||
if (drawingPatriarch != null) {
|
||||
List<HSSFPicture> pictures = new ArrayList<>();
|
||||
for (HSSFShape shape : drawingPatriarch.getChildren()) {
|
||||
if (shape instanceof HSSFPicture) {
|
||||
pictures.add((HSSFPicture) shape);
|
||||
}
|
||||
}
|
||||
table.setNextRenderer(new XlsImageTableRenderer(table, pictures, (HSSFSheet) sheet));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cell convertCell(org.apache.poi.ss.usermodel.Cell cell, int rowspan, int colspan, float maxWidth, String fontPath) throws IOException {
|
||||
String value = Excel2PdfUtils.getValue(cell);
|
||||
Cell pdfCell = createPdfCell(rowspan, colspan, cell, value, maxWidth, fontPath);
|
||||
|
||||
return pdfCell;
|
||||
}
|
||||
|
||||
private Cell createPdfCell(int rowspan, int colspan, org.apache.poi.ss.usermodel.Cell cell, String value, float maxWidth, String fontPath) throws IOException {
|
||||
float cellHeight = cell.getRow().getHeightInPoints() * 1.2f;
|
||||
Cell pdfCell = new Cell(rowspan, colspan)
|
||||
.setHeight(cellHeight)
|
||||
.setPadding(0);
|
||||
Text text = new Text(value);
|
||||
setPdfCellFont((HSSFCell) cell, text, fontPath);
|
||||
|
||||
Paragraph paragraph = new Paragraph(text).setPadding(0f).setMargin(0f);
|
||||
HSSFCellStyle cellStyle = ((HSSFCell) cell).getCellStyle();
|
||||
if (cellStyle.getWrapText()) {
|
||||
paragraph.setMaxWidth(maxWidth);
|
||||
}
|
||||
|
||||
pdfCell.add(paragraph);
|
||||
|
||||
setCellStyles(cell, pdfCell);
|
||||
return pdfCell;
|
||||
}
|
||||
|
||||
private void setCellStyles(org.apache.poi.ss.usermodel.Cell cell, Cell pdfCell) throws IOException {
|
||||
HSSFCellStyle cellStyle = ((HSSFCell) cell).getCellStyle();
|
||||
// Layout
|
||||
pdfCell.setVerticalAlignment(getVerticalAlignment(cellStyle.getVerticalAlignment()));
|
||||
pdfCell.setTextAlignment(getTextAlignment(cellStyle.getAlignment(), cell.getCellType()));
|
||||
|
||||
// Set borders
|
||||
transformBorders((HSSFCell) cell, pdfCell);
|
||||
|
||||
// Set background color
|
||||
setBackgroundColor(cellStyle, pdfCell, cell);
|
||||
}
|
||||
|
||||
private void setBackgroundColor(HSSFCellStyle cellStyle, Cell pdfCell, org.apache.poi.ss.usermodel.Cell cell) {
|
||||
short colorIndex = cellStyle.getFillForegroundColor();
|
||||
HSSFWorkbook workbook = (HSSFWorkbook) cell.getSheet().getWorkbook();
|
||||
HSSFColor color = workbook.getCustomPalette().getColor(colorIndex);
|
||||
if (color != null && color.getIndex() != 64) {
|
||||
short[] triplet = color.getTriplet();
|
||||
int r = Math.min(triplet[0] + 32, 255);
|
||||
int g = Math.min(triplet[1] + 90, 255);
|
||||
int b = Math.min(triplet[2] + 60, 255);
|
||||
pdfCell.setBackgroundColor(new DeviceRgb(r, g, b));
|
||||
}
|
||||
}
|
||||
|
||||
public static void transformBorders(HSSFCell cell, Cell pdfCell) {
|
||||
HSSFCellStyle cellStyle = cell.getCellStyle();
|
||||
pdfCell.setBorderBottom(getBorder(cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor(), cell));
|
||||
pdfCell.setBorderLeft(getBorder(cellStyle.getBorderLeft(), cellStyle.getLeftBorderColor(), cell));
|
||||
pdfCell.setBorderRight(getBorder(cellStyle.getBorderRight(), cellStyle.getRightBorderColor(), cell));
|
||||
pdfCell.setBorderTop(getBorder(cellStyle.getBorderTop(), cellStyle.getTopBorderColor(), cell));
|
||||
}
|
||||
|
||||
private void setPdfCellFont(HSSFCell cell, Text text, String fontPath) throws IOException {
|
||||
HSSFCellStyle cellStyle = cell.getCellStyle();
|
||||
HSSFFont font = cellStyle.getFont(cell.getSheet().getWorkbook());
|
||||
text.setFont(StringUtils.isEmpty(fontPath) ? PdfFontFactory.createFont() : PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H));
|
||||
text.setFontSize(font.getFontHeightInPoints());
|
||||
|
||||
// Set font color
|
||||
HSSFColor hssfColor = font.getHSSFColor(cell.getSheet().getWorkbook());
|
||||
if (hssfColor != null && hssfColor.getIndex() != 64) {
|
||||
short[] triplet = hssfColor.getTriplet();
|
||||
text.setFontColor(new DeviceRgb(triplet[0], triplet[1], triplet[2]));
|
||||
}
|
||||
|
||||
// Set font styles
|
||||
if (font.getBold()) text.setBold();
|
||||
if (font.getItalic()) text.setItalic();
|
||||
if (font.getUnderline() == 1) text.setUnderline(0.5f, -1f);
|
||||
}
|
||||
|
||||
public static Border getBorder(BorderStyle borderStyle, short colorIndex, HSSFCell cell) {
|
||||
HSSFPalette customPalette = cell.getSheet().getWorkbook().getCustomPalette();
|
||||
HSSFColor color = customPalette.getColor(colorIndex);
|
||||
Color defaultColor = (color != null && color.getIndex() != 64)
|
||||
? new DeviceRgb(color.getTriplet()[0], color.getTriplet()[1], color.getTriplet()[2])
|
||||
: ColorConstants.BLACK;
|
||||
|
||||
switch (borderStyle) {
|
||||
case THIN:
|
||||
return new SolidBorder(defaultColor, 0.3f);
|
||||
case MEDIUM:
|
||||
return new SolidBorder(defaultColor, 0.5f);
|
||||
case DASHED:
|
||||
return new DashedBorder(defaultColor, 0.3f);
|
||||
case DOTTED:
|
||||
return new DottedBorder(defaultColor, 0.3f);
|
||||
case THICK:
|
||||
return new SolidBorder(defaultColor, 1f);
|
||||
case DOUBLE:
|
||||
return new DoubleBorder(defaultColor, 0.3f);
|
||||
case MEDIUM_DASHED:
|
||||
return new DashedBorder(defaultColor, 0.5f);
|
||||
default:
|
||||
return Border.NO_BORDER;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
package cn.idev.excel.fileconvertor.v03;
|
||||
|
||||
import com.itextpdf.io.image.ImageData;
|
||||
import com.itextpdf.io.image.ImageDataFactory;
|
||||
import com.itextpdf.kernel.geom.Rectangle;
|
||||
import com.itextpdf.layout.element.Table;
|
||||
import com.itextpdf.layout.renderer.CellRenderer;
|
||||
import com.itextpdf.layout.renderer.DrawContext;
|
||||
import com.itextpdf.layout.renderer.IRenderer;
|
||||
import com.itextpdf.layout.renderer.TableRenderer;
|
||||
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
|
||||
import org.apache.poi.hssf.usermodel.HSSFPicture;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Renders images from an Excel sheet onto a PDF table.
|
||||
*/
|
||||
public class XlsImageTableRenderer extends TableRenderer {
|
||||
private List<HSSFPicture> hSSFPictures;
|
||||
private HSSFSheet sheet;
|
||||
|
||||
public XlsImageTableRenderer(Table modelElement, List<HSSFPicture> hSSFPictures, HSSFSheet sheet) {
|
||||
super(modelElement);
|
||||
this.hSSFPictures = hSSFPictures;
|
||||
this.sheet = sheet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawChildren(DrawContext drawContext) {
|
||||
super.drawChildren(drawContext);
|
||||
drawExcelImages(drawContext);
|
||||
}
|
||||
|
||||
private void drawExcelImages(DrawContext drawContext) {
|
||||
for (HSSFPicture picture : hSSFPictures) {
|
||||
HSSFClientAnchor clientAnchor = picture.getClientAnchor();
|
||||
Rectangle imageRect = calculateImageRectangle(clientAnchor);
|
||||
ImageData imageData = ImageDataFactory.create(picture.getPictureData().getData());
|
||||
drawContext.getCanvas().addImage(imageData,
|
||||
imageRect.getWidth(),
|
||||
0,
|
||||
0,
|
||||
imageRect.getHeight(),
|
||||
imageRect.getLeft(),
|
||||
imageRect.getTop());
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle calculateImageRectangle(HSSFClientAnchor clientAnchor) {
|
||||
CellRenderer cellRenderer1 = rows.get(clientAnchor.getRow1())[clientAnchor.getCol1()];
|
||||
Rectangle rect1 = cellRenderer1.getOccupiedAreaBBox();
|
||||
|
||||
CellRenderer cellRenderer2 = rows.get(clientAnchor.getRow2())[clientAnchor.getCol2()];
|
||||
Rectangle rect2 = cellRenderer2.getOccupiedAreaBBox();
|
||||
|
||||
float widthRate = calculateWidthRate(rect2);
|
||||
float heightRate = calculateHeightRate(rect2);
|
||||
|
||||
float width = calculateImageWidth(clientAnchor, widthRate);
|
||||
float height = calculateImageHeight(clientAnchor, heightRate);
|
||||
|
||||
float x = rect1.getLeft() + clientAnchor.getDx1() * widthRate;
|
||||
float y = rect1.getTop() - height - clientAnchor.getDy1() * heightRate;
|
||||
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
private float calculateWidthRate(Rectangle rect2) {
|
||||
return (super.getOccupiedAreaBBox().getWidth() + rect2.getWidth()) / getExcelWidth(sheet);
|
||||
}
|
||||
|
||||
private float calculateHeightRate(Rectangle rect2) {
|
||||
return (super.getOccupiedAreaBBox().getHeight() - rect2.getHeight()) / getExcelHeight(sheet);
|
||||
}
|
||||
|
||||
private float calculateImageWidth(HSSFClientAnchor clientAnchor, float widthRate) {
|
||||
float width = 0f;
|
||||
for (int j = clientAnchor.getCol1(); j < clientAnchor.getCol2(); j++) {
|
||||
width += sheet.getColumnWidth(j);
|
||||
}
|
||||
return Math.abs(width - clientAnchor.getDx1() + clientAnchor.getDx2()) * widthRate;
|
||||
}
|
||||
|
||||
private float calculateImageHeight(HSSFClientAnchor clientAnchor, float heightRate) {
|
||||
float height = 0f;
|
||||
for (int j = clientAnchor.getRow1(); j < clientAnchor.getRow2(); j++) {
|
||||
height += sheet.getRow(j).getHeight();
|
||||
}
|
||||
return Math.abs(height - clientAnchor.getDy1() + clientAnchor.getDy2()) * heightRate;
|
||||
}
|
||||
|
||||
private float getExcelHeight(HSSFSheet sheet) {
|
||||
int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
|
||||
float result = 0;
|
||||
for (int i = 0; i < physicalNumberOfRows; i++) {
|
||||
result += sheet.getRow(i).getHeight();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float getExcelWidth(HSSFSheet sheet) {
|
||||
short lastCellNum = sheet.getRow(0).getLastCellNum();
|
||||
float result = 0;
|
||||
for (int i = 0; i < lastCellNum; i++) {
|
||||
result += sheet.getColumnWidth(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRenderer getNextRenderer() {
|
||||
return new XlsImageTableRenderer((Table) modelElement, hSSFPictures, sheet);
|
||||
}
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
package cn.idev.excel.fileconvertor.v07;
|
||||
|
||||
import cn.idev.excel.fileconvertor.BaseExcelConverter;
|
||||
import cn.idev.excel.fileconvertor.Excel2PdfUtils;
|
||||
import cn.idev.excel.fileconvertor.FileConverterContext;
|
||||
import cn.idev.excel.util.StringUtils;
|
||||
import com.itextpdf.io.font.PdfEncodings;
|
||||
import com.itextpdf.kernel.colors.DeviceRgb;
|
||||
import com.itextpdf.kernel.font.PdfFontFactory;
|
||||
import com.itextpdf.layout.borders.*;
|
||||
import com.itextpdf.layout.element.Paragraph;
|
||||
import com.itextpdf.layout.element.Table;
|
||||
import com.itextpdf.layout.element.Text;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class XlsxConverter extends BaseExcelConverter {
|
||||
private static final String DEFAULT_FONT_PATH = System.getProperty("user.dir") + "/doc/font/SimHei.TTF";
|
||||
|
||||
public XlsxConverter(FileConverterContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPicsToTable(Table table, Sheet sheet) {
|
||||
XSSFDrawing drawing = (XSSFDrawing) sheet.createDrawingPatriarch();
|
||||
if (drawing != null) {
|
||||
List<XSSFPicture> pictures = new ArrayList<>();
|
||||
for (XSSFShape shape : drawing.getShapes()) {
|
||||
if (shape instanceof XSSFPicture) {
|
||||
pictures.add((XSSFPicture) shape);
|
||||
}
|
||||
}
|
||||
table.setNextRenderer(new XlsxImageTableRenderer(table, pictures, (XSSFSheet) sheet));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.itextpdf.layout.element.Cell convertCell(Cell cell, int rowspan, int colspan, float maxWidth, String fontPath) throws IOException {
|
||||
String value = Excel2PdfUtils.getValue(cell);
|
||||
com.itextpdf.layout.element.Cell pdfCell = createPdfCell(rowspan, colspan, cell, value, maxWidth, fontPath);
|
||||
return pdfCell;
|
||||
}
|
||||
|
||||
public static void transformBorder(XSSFCell cell, com.itextpdf.layout.element.Cell pdfCell) {
|
||||
XSSFCellStyle cellStyle = cell.getCellStyle();
|
||||
BorderStyle borderBottom = cellStyle.getBorderBottom();
|
||||
pdfCell.setBorderBottom(getBorder(borderBottom, cellStyle.getBottomBorderXSSFColor()));
|
||||
|
||||
BorderStyle borderLeft = cellStyle.getBorderLeft();
|
||||
pdfCell.setBorderLeft(getBorder(borderLeft, cellStyle.getLeftBorderXSSFColor()));
|
||||
|
||||
BorderStyle borderRight = cellStyle.getBorderRight();
|
||||
pdfCell.setBorderRight(getBorder(borderRight, cellStyle.getRightBorderXSSFColor()));
|
||||
|
||||
BorderStyle borderTop = cellStyle.getBorderTop();
|
||||
pdfCell.setBorderTop(getBorder(borderTop, cellStyle.getTopBorderXSSFColor()));
|
||||
}
|
||||
|
||||
private com.itextpdf.layout.element.Cell createPdfCell(int rowspan, int colspan, Cell cell, String value, float maxWidth, String fontPath) throws IOException {
|
||||
com.itextpdf.layout.element.Cell pdfCell = new com.itextpdf.layout.element.Cell(rowspan, colspan)
|
||||
.setHeight(cell.getRow().getHeightInPoints() * 1.2f)
|
||||
.setPadding(0);
|
||||
Text text = new Text(value);
|
||||
setPdfCellFont((XSSFCell) cell, text, fontPath);
|
||||
Paragraph paragraph = new Paragraph(text).setPadding(0f).setMargin(0f);
|
||||
XSSFCellStyle cellStyle = ((XSSFCell) cell).getCellStyle();
|
||||
if (cellStyle.getWrapText()) {
|
||||
paragraph.setMaxWidth(maxWidth);
|
||||
}
|
||||
pdfCell.add(paragraph);
|
||||
setCellStyles((XSSFCell)cell, pdfCell);
|
||||
return pdfCell;
|
||||
}
|
||||
|
||||
private void setCellStyles( XSSFCell cell,com.itextpdf.layout.element.Cell pdfCell) throws IOException {
|
||||
XSSFCellStyle cellStyle = cell.getCellStyle();
|
||||
pdfCell.setVerticalAlignment(getVerticalAlignment(cellStyle.getVerticalAlignment()))
|
||||
.setTextAlignment(getTextAlignment(cellStyle.getAlignment(), cell.getCellType()));
|
||||
|
||||
// Set borders and background color
|
||||
setBorders(pdfCell, cellStyle);
|
||||
setBackgroundColor(pdfCell, cellStyle);
|
||||
}
|
||||
|
||||
private void setBorders(com.itextpdf.layout.element.Cell pdfCell, XSSFCellStyle cellStyle) {
|
||||
pdfCell.setBorderBottom(getBorder(cellStyle.getBorderBottom(), cellStyle.getBottomBorderXSSFColor()));
|
||||
pdfCell.setBorderLeft(getBorder(cellStyle.getBorderLeft(), cellStyle.getLeftBorderXSSFColor()));
|
||||
pdfCell.setBorderRight(getBorder(cellStyle.getBorderRight(), cellStyle.getRightBorderXSSFColor()));
|
||||
pdfCell.setBorderTop(getBorder(cellStyle.getBorderTop(), cellStyle.getTopBorderXSSFColor()));
|
||||
}
|
||||
|
||||
private void setBackgroundColor(com.itextpdf.layout.element.Cell pdfCell, XSSFCellStyle cellStyle) {
|
||||
XSSFColor fillColor = cellStyle.getFillForegroundXSSFColor();
|
||||
if (fillColor != null) {
|
||||
byte[] rgb = fillColor.getRGB();
|
||||
if (rgb != null) {
|
||||
pdfCell.setBackgroundColor(new DeviceRgb(Byte.toUnsignedInt(rgb[0]), Byte.toUnsignedInt(rgb[1]), Byte.toUnsignedInt(rgb[2])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setPdfCellFont(XSSFCell cell, Text text,String fontPath) throws IOException {
|
||||
XSSFCellStyle cellStyle = cell.getCellStyle();
|
||||
short fontHeight = cellStyle.getFont().getFontHeightInPoints();
|
||||
cellStyle.getFont().getFontName();
|
||||
text.setFont(StringUtils.isEmpty(fontPath) ? PdfFontFactory.createFont() : PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H));
|
||||
text.setFontSize(fontHeight);
|
||||
setFontColor(cellStyle.getFont(), text);
|
||||
setFontStyles(cell.getCellStyle().getFont(), text);
|
||||
}
|
||||
|
||||
private void setFontColor(XSSFFont font, Text text) {
|
||||
XSSFColor xssfColor = font.getXSSFColor();
|
||||
if (xssfColor != null && xssfColor.getIndex() != 64) {
|
||||
byte[] rgb = xssfColor.getRGB();
|
||||
if (rgb != null) {
|
||||
text.setFontColor(new DeviceRgb(Byte.toUnsignedInt(rgb[0]), Byte.toUnsignedInt(rgb[1]), Byte.toUnsignedInt(rgb[2])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setFontStyles(XSSFFont font, Text text) {
|
||||
if (font.getBold()) text.setBold();
|
||||
if (font.getItalic()) text.setItalic();
|
||||
if (font.getUnderline() == 1) text.setUnderline(0.5f, -1f);
|
||||
}
|
||||
|
||||
public static com.itextpdf.layout.borders.Border getBorder(BorderStyle borderStyle, XSSFColor xSSFColor) {
|
||||
DeviceRgb defaultColor = new DeviceRgb(0, 0, 0); // Default to black
|
||||
if (xSSFColor != null) {
|
||||
byte[] rgb = xSSFColor.getRGB();
|
||||
if (rgb != null) {
|
||||
defaultColor = new DeviceRgb(Byte.toUnsignedInt(rgb[0]), Byte.toUnsignedInt(rgb[1]), Byte.toUnsignedInt(rgb[2]));
|
||||
}
|
||||
}
|
||||
|
||||
switch (borderStyle) {
|
||||
case THIN:
|
||||
return new SolidBorder(defaultColor, 0.3f);
|
||||
case MEDIUM:
|
||||
return new SolidBorder(defaultColor, 0.5f);
|
||||
case DASHED:
|
||||
return new DashedBorder(defaultColor, 0.3f);
|
||||
case DOTTED:
|
||||
return new DottedBorder(defaultColor, 0.3f);
|
||||
case THICK:
|
||||
return new SolidBorder(defaultColor, 1f);
|
||||
case DOUBLE:
|
||||
return new DoubleBorder(defaultColor, 0.3f);
|
||||
case MEDIUM_DASHED:
|
||||
return new DashedBorder(defaultColor, 0.5f);
|
||||
default:
|
||||
return Border.NO_BORDER;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
package cn.idev.excel.fileconvertor.v07;
|
||||
|
||||
import com.itextpdf.io.image.ImageData;
|
||||
import com.itextpdf.io.image.ImageDataFactory;
|
||||
import com.itextpdf.kernel.geom.Rectangle;
|
||||
import com.itextpdf.layout.element.Table;
|
||||
import com.itextpdf.layout.renderer.CellRenderer;
|
||||
import com.itextpdf.layout.renderer.DrawContext;
|
||||
import com.itextpdf.layout.renderer.IRenderer;
|
||||
import com.itextpdf.layout.renderer.TableRenderer;
|
||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFPicture;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Renders images from an Excel sheet onto a PDF table.
|
||||
*/
|
||||
public class XlsxImageTableRenderer extends TableRenderer {
|
||||
private List<XSSFPicture> xssfPictures;
|
||||
private XSSFSheet sheet;
|
||||
|
||||
public XlsxImageTableRenderer(Table modelElement, List<XSSFPicture> xssfPictures, XSSFSheet sheet) {
|
||||
super(modelElement);
|
||||
this.xssfPictures = xssfPictures;
|
||||
this.sheet = sheet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawChildren(DrawContext drawContext) {
|
||||
super.drawChildren(drawContext);
|
||||
renderExcelImages(drawContext);
|
||||
}
|
||||
|
||||
private void renderExcelImages(DrawContext drawContext) {
|
||||
for (XSSFPicture picture : xssfPictures) {
|
||||
XSSFClientAnchor clientAnchor = picture.getClientAnchor();
|
||||
Rectangle imageRect = calculateImageRectangle(clientAnchor);
|
||||
ImageData imageData = ImageDataFactory.create(picture.getPictureData().getData());
|
||||
drawContext.getCanvas().addImage(imageData,
|
||||
imageRect.getWidth(),
|
||||
0,
|
||||
0,
|
||||
imageRect.getHeight(),
|
||||
imageRect.getLeft(),
|
||||
imageRect.getTop());
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle calculateImageRectangle(XSSFClientAnchor clientAnchor) {
|
||||
CellRenderer cellRenderer1 = rows.get(clientAnchor.getRow1())[clientAnchor.getCol1()];
|
||||
CellRenderer cellRenderer2 = rows.get(clientAnchor.getRow2())[clientAnchor.getCol2()];
|
||||
Rectangle rect1 = cellRenderer1.getOccupiedAreaBBox();
|
||||
Rectangle rect2 = cellRenderer2.getOccupiedAreaBBox();
|
||||
|
||||
float widthRate = (super.getOccupiedAreaBBox().getWidth() + rect2.getWidth()) / getExcelWidth(sheet);
|
||||
float heightRate = (super.getOccupiedAreaBBox().getHeight() - rect2.getHeight()) / getExcelHeight(sheet);
|
||||
|
||||
float width = calculateImageWidth(clientAnchor, widthRate);
|
||||
float height = calculateImageHeight(clientAnchor, heightRate);
|
||||
|
||||
float x = rect1.getLeft() + clientAnchor.getDx1() * widthRate;
|
||||
float y = rect1.getTop() - height - clientAnchor.getDy1() * heightRate;
|
||||
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
private float calculateImageWidth(XSSFClientAnchor clientAnchor, float widthRate) {
|
||||
float width = 0f;
|
||||
for (int j = clientAnchor.getCol1(); j < clientAnchor.getCol2(); j++) {
|
||||
width += sheet.getColumnWidth(j);
|
||||
}
|
||||
return Math.abs(width - clientAnchor.getDx1() + clientAnchor.getDx2()) * widthRate;
|
||||
}
|
||||
|
||||
private float calculateImageHeight(XSSFClientAnchor clientAnchor, float heightRate) {
|
||||
float height = 0f;
|
||||
for (int j = clientAnchor.getRow1(); j < clientAnchor.getRow2(); j++) {
|
||||
height += sheet.getRow(j).getHeight();
|
||||
}
|
||||
return Math.abs(height - clientAnchor.getDy1() + clientAnchor.getDy2()) * heightRate;
|
||||
}
|
||||
|
||||
private float getExcelHeight(XSSFSheet sheet) {
|
||||
float totalHeight = 0;
|
||||
for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
|
||||
totalHeight += sheet.getRow(i).getHeight();
|
||||
}
|
||||
return totalHeight;
|
||||
}
|
||||
|
||||
private float getExcelWidth(XSSFSheet sheet) {
|
||||
return (short)sheet.getRow(0).getLastCellNum() * sheet.getColumnWidth(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRenderer getNextRenderer() {
|
||||
return new XlsxImageTableRenderer((Table) modelElement, xssfPictures, sheet);
|
||||
}
|
||||
}
|
@ -118,6 +118,8 @@ public class DataFormatter {
|
||||
*/
|
||||
private static final String invalidDateTimeString;
|
||||
|
||||
private static final BigDecimal TEN = new BigDecimal(10);
|
||||
|
||||
static {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i = 0; i < 255; i++) {buf.append('#');}
|
||||
@ -524,11 +526,17 @@ public class DataFormatter {
|
||||
setExcelStyleRoundingMode(df);
|
||||
Matcher endsWithCommasMatcher = endsWithCommas.matcher(pattern);
|
||||
if (endsWithCommasMatcher.find()) {
|
||||
int index_point = pattern.indexOf(".");
|
||||
int index_comma = pattern.indexOf(",");
|
||||
int cnt = index_comma - index_point - 1;
|
||||
String commas = (endsWithCommasMatcher.group(1));
|
||||
BigDecimal temp = BigDecimal.ONE;
|
||||
for (int i = 0; i < commas.length(); ++i) {
|
||||
temp = temp.multiply(ONE_THOUSAND);
|
||||
}
|
||||
for (int i = 0; i < cnt ; i++) {
|
||||
temp = temp.multiply(TEN);
|
||||
}
|
||||
divider = temp;
|
||||
} else {
|
||||
divider = null;
|
||||
|
@ -60,7 +60,7 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<
|
||||
(String) ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(),
|
||||
context, context.readRowHolder().getRowIndex(), key));
|
||||
} else {
|
||||
// retrun ReadCellData
|
||||
// return ReadCellData
|
||||
ReadCellData<?> convertedReadCellData = convertReadCellData(cellData,
|
||||
context.readWorkbookHolder().getReadDefaultReturn(), readSheetHolder, context, key);
|
||||
if (readDefaultReturn == ReadDefaultReturnEnum.READ_CELL_DATA) {
|
||||
|
@ -10,13 +10,12 @@ import javax.xml.parsers.SAXParserFactory;
|
||||
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.context.AnalysisContext;
|
||||
import cn.idev.excel.read.listener.ModelBuildEventListener;
|
||||
import cn.idev.excel.support.ExcelTypeEnum;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@ -97,7 +96,7 @@ public class ReadWorkbook extends ReadBasicParameter {
|
||||
* Whether to use the default listener, which is used by default.
|
||||
* <p>
|
||||
* The {@link ModelBuildEventListener} is loaded by default to convert the object.
|
||||
* defualt is true.
|
||||
* default is true.
|
||||
*/
|
||||
private Boolean useDefaultListener;
|
||||
|
||||
|
@ -9,8 +9,8 @@ import cn.idev.excel.exception.ExcelAnalysisException;
|
||||
import cn.idev.excel.exception.ExcelCommonException;
|
||||
import cn.idev.excel.read.metadata.ReadWorkbook;
|
||||
import cn.idev.excel.util.StringUtils;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.poi.EmptyFileException;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
|
||||
/**
|
||||
@ -87,6 +87,8 @@ public enum ExcelTypeEnum {
|
||||
return recognitionExcelType(inputStream);
|
||||
} catch (ExcelCommonException e) {
|
||||
throw e;
|
||||
} catch (EmptyFileException e) {
|
||||
throw new ExcelCommonException("The supplied file was empty (zero bytes long)");
|
||||
} catch (Exception e) {
|
||||
throw new ExcelCommonException(
|
||||
"Convert excel format exception.You can try specifying the 'excelType' yourself", e);
|
||||
|
@ -174,14 +174,14 @@ public class ConverterUtils {
|
||||
}
|
||||
if (converter == null) {
|
||||
throw new ExcelDataConvertException(rowIndex, columnIndex, cellData, contentProperty,
|
||||
"Converter not found, convert " + cellData.getType() + " to " + clazz.getName());
|
||||
"Error at row " + rowIndex + ", column " + columnIndex + ": Converter not found, convert " + cellData.getType() + " to " + clazz.getName());
|
||||
}
|
||||
|
||||
try {
|
||||
return converter.convertToJavaData(new ReadConverterContext<>(cellData, contentProperty, context));
|
||||
} catch (Exception e) {
|
||||
throw new ExcelDataConvertException(rowIndex, columnIndex, cellData, contentProperty,
|
||||
"Convert data " + cellData + " to " + clazz + " error ", e);
|
||||
"Error at row " + rowIndex + ", column " + columnIndex + ": Convert data " + cellData + " to " + clazz + " error ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ public class StyleUtil {
|
||||
}
|
||||
if (StringUtils.isNotBlank(dataFormatData.getFormat())) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.info("create new data fromat:{}", dataFormatData);
|
||||
log.info("create new data format:{}", dataFormatData);
|
||||
}
|
||||
DataFormat dataFormatCreate = workbook.createDataFormat();
|
||||
return dataFormatCreate.getFormat(dataFormatData.getFormat());
|
||||
|
@ -23,6 +23,7 @@ import cn.idev.excel.util.ClassUtils;
|
||||
import cn.idev.excel.util.FieldUtils;
|
||||
import cn.idev.excel.util.ListUtils;
|
||||
import cn.idev.excel.util.MapUtils;
|
||||
import cn.idev.excel.util.PoiUtils;
|
||||
import cn.idev.excel.util.StringUtils;
|
||||
import cn.idev.excel.util.WriteHandlerUtils;
|
||||
import cn.idev.excel.write.handler.context.CellWriteHandlerContext;
|
||||
@ -31,15 +32,11 @@ import cn.idev.excel.write.metadata.fill.AnalysisCell;
|
||||
import cn.idev.excel.write.metadata.fill.FillConfig;
|
||||
import cn.idev.excel.write.metadata.fill.FillWrapper;
|
||||
import cn.idev.excel.write.metadata.holder.WriteSheetHolder;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import cn.idev.excel.util.PoiUtils;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
@ -212,10 +209,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
|
||||
|
||||
if (analysisCell.getOnlyOneVariable()) {
|
||||
String variable = analysisCell.getVariableList().get(0);
|
||||
if (!dataKeySet.contains(variable)) {
|
||||
continue;
|
||||
Object value = null;
|
||||
if (dataKeySet.contains(variable)) {
|
||||
value = dataMap.get(variable);
|
||||
}
|
||||
Object value = dataMap.get(variable);
|
||||
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
|
||||
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable,
|
||||
writeContext.currentWriteHolder());
|
||||
@ -247,10 +244,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
|
||||
|
||||
for (String variable : analysisCell.getVariableList()) {
|
||||
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++));
|
||||
if (!dataKeySet.contains(variable)) {
|
||||
continue;
|
||||
Object value = null;
|
||||
if (dataKeySet.contains(variable)) {
|
||||
value = dataMap.get(variable);
|
||||
}
|
||||
Object value = dataMap.get(variable);
|
||||
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
|
||||
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable,
|
||||
writeContext.currentWriteHolder());
|
||||
|
@ -1,11 +1,19 @@
|
||||
package cn.idev.excel.test.core.excludeorinclude;
|
||||
|
||||
import cn.idev.excel.test.util.TestFileUtil;
|
||||
import cn.idev.excel.EasyExcel;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.idev.excel.EasyExcel;
|
||||
import cn.idev.excel.test.util.TestFileUtil;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
|
||||
/**
|
||||
* @author Jiaju Zhuang
|
||||
@ -150,7 +158,7 @@ public class ExcludeOrIncludeDataTest {
|
||||
excludeColumnIndexes.add(0);
|
||||
excludeColumnIndexes.add(3);
|
||||
EasyExcel.write(file, ExcludeOrIncludeData.class).excludeColumnIndexes(excludeColumnIndexes).sheet()
|
||||
.doWrite(data());
|
||||
.doWrite(data());
|
||||
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
|
||||
Assertions.assertEquals(1, dataMap.size());
|
||||
Map<Integer, String> record = dataMap.get(0);
|
||||
@ -166,7 +174,7 @@ public class ExcludeOrIncludeDataTest {
|
||||
excludeColumnFieldNames.add("column3");
|
||||
excludeColumnFieldNames.add("column4");
|
||||
EasyExcel.write(file, ExcludeOrIncludeData.class).excludeColumnFieldNames(excludeColumnFieldNames).sheet()
|
||||
.doWrite(data());
|
||||
.doWrite(data());
|
||||
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
|
||||
Assertions.assertEquals(1, dataMap.size());
|
||||
Map<Integer, String> record = dataMap.get(0);
|
||||
@ -180,7 +188,7 @@ public class ExcludeOrIncludeDataTest {
|
||||
includeColumnIndexes.add(1);
|
||||
includeColumnIndexes.add(2);
|
||||
EasyExcel.write(file, ExcludeOrIncludeData.class).includeColumnIndexes(includeColumnIndexes).sheet()
|
||||
.doWrite(data());
|
||||
.doWrite(data());
|
||||
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
|
||||
Assertions.assertEquals(1, dataMap.size());
|
||||
Map<Integer, String> record = dataMap.get(0);
|
||||
@ -195,9 +203,9 @@ public class ExcludeOrIncludeDataTest {
|
||||
includeColumnFieldNames.add("column2");
|
||||
includeColumnFieldNames.add("column3");
|
||||
EasyExcel.write(file, ExcludeOrIncludeData.class)
|
||||
.sheet()
|
||||
.includeColumnFieldNames(includeColumnFieldNames)
|
||||
.doWrite(data());
|
||||
.sheet()
|
||||
.includeColumnFieldNames(includeColumnFieldNames)
|
||||
.doWrite(data());
|
||||
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
|
||||
Assertions.assertEquals(1, dataMap.size());
|
||||
Map<Integer, String> record = dataMap.get(0);
|
||||
@ -213,10 +221,10 @@ public class ExcludeOrIncludeDataTest {
|
||||
includeColumnIndexes.add(2);
|
||||
includeColumnIndexes.add(0);
|
||||
EasyExcel.write(file, ExcludeOrIncludeData.class)
|
||||
.includeColumnIndexes(includeColumnIndexes)
|
||||
.orderByIncludeColumn(true).
|
||||
sheet()
|
||||
.doWrite(data());
|
||||
.includeColumnIndexes(includeColumnIndexes)
|
||||
.orderByIncludeColumn(true).
|
||||
sheet()
|
||||
.doWrite(data());
|
||||
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
|
||||
Assertions.assertEquals(1, dataMap.size());
|
||||
Map<Integer, String> record = dataMap.get(0);
|
||||
@ -233,10 +241,10 @@ public class ExcludeOrIncludeDataTest {
|
||||
includeColumnFieldNames.add("column2");
|
||||
includeColumnFieldNames.add("column3");
|
||||
EasyExcel.write(file, ExcludeOrIncludeData.class)
|
||||
.includeColumnFieldNames(includeColumnFieldNames)
|
||||
.orderByIncludeColumn(true).
|
||||
sheet()
|
||||
.doWrite(data());
|
||||
.includeColumnFieldNames(includeColumnFieldNames)
|
||||
.orderByIncludeColumn(true).
|
||||
sheet()
|
||||
.doWrite(data());
|
||||
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
|
||||
Assertions.assertEquals(1, dataMap.size());
|
||||
Map<Integer, String> record = dataMap.get(0);
|
||||
|
@ -363,7 +363,7 @@ public class WriteTest {
|
||||
writeCellStyleData.setFillForegroundColor(IndexedColors.GREEN.getIndex());
|
||||
|
||||
// 设置单个单元格多种样式
|
||||
// 这里需要设置 inMomery=true 不然会导致无法展示单个单元格多种样式,所以慎用
|
||||
// 这里需要设置 inMemory=true 不然会导致无法展示单个单元格多种样式,所以慎用
|
||||
WriteCellData<String> richTest = new WriteCellData<>();
|
||||
richTest.setType(CellDataTypeEnum.RICH_TEXT_STRING);
|
||||
writeCellDemoData.setRichText(richTest);
|
||||
|
@ -7,7 +7,7 @@ import com.alibaba.fastjson2.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class CsvDataListeer extends AnalysisEventListener<CsvData> {
|
||||
public class CsvDataListener extends AnalysisEventListener<CsvData> {
|
||||
@Override
|
||||
public void invoke(CsvData data, AnalysisContext context) {
|
||||
log.info("data:{}", JSON.toJSONString(data));
|
@ -72,7 +72,7 @@ public class CsvReadTest {
|
||||
// 如果这里想使用03 则 传入excelType参数即可
|
||||
EasyExcel.write(fileName, CsvData.class).sheet().doWrite(data());
|
||||
|
||||
EasyExcel.read(fileName, CsvData.class, new CsvDataListeer()).sheet().doRead();
|
||||
EasyExcel.read(fileName, CsvData.class, new CsvDataListener()).sheet().doRead();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -102,7 +102,7 @@ import org.slf4j.LoggerFactory;
|
||||
* and space ("_ ") in the format adds a space to the end and Excel formats this cell as <code>"12.34 "</code>, but
|
||||
* <code>DataFormatter</code> trims the formatted value and returns <code>"12.34"</code>.
|
||||
* </p>
|
||||
* You can enable spaces by passing the <code>emulateCSV=true</code> flag in the <code>DateFormatter</code> cosntructor.
|
||||
* You can enable spaces by passing the <code>emulateCSV=true</code> flag in the <code>DateFormatter</code> constructor.
|
||||
* If set to true, then the output tries to conform to what you get when you take an xls or xlsx in Excel and Save As
|
||||
* CSV file:
|
||||
* <ul>
|
||||
|
@ -0,0 +1,13 @@
|
||||
package cn.idev.excel.test.temp.issue2319;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class Issue2319 {
|
||||
private String num1;
|
||||
private String num2;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package cn.idev.excel.test.temp.issue2319;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
|
||||
import cn.idev.excel.EasyExcel;
|
||||
import cn.idev.excel.FastExcel;
|
||||
import cn.idev.excel.read.listener.PageReadListener;
|
||||
import cn.idev.excel.test.util.TestFileUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Slf4j
|
||||
public class Issue2319Test {
|
||||
@Test
|
||||
public void IssueTest1() {
|
||||
String fileName = TestFileUtil.getPath() + "temp/issue2319" + File.separator + "test1.xlsx";
|
||||
FastExcel.read(fileName, Issue2319.class, new PageReadListener<Issue2319>(dataList -> {
|
||||
for (Issue2319 issueData : dataList) {
|
||||
System.out.println(("读取到一条数据{}" + JSON.toJSONString(issueData)));
|
||||
}
|
||||
})).sheet().doRead();
|
||||
}
|
||||
|
||||
//CS304 (manually written) Issue link: https://github.com/alibaba/easyexcel/issues/2319
|
||||
@Test
|
||||
public void IssueTest2() {
|
||||
String fileName = TestFileUtil.getPath() + "temp/issue2319" + File.separator + "test2.xlsx";
|
||||
FastExcel.read(fileName, Issue2319.class, new PageReadListener<Issue2319>(dataList -> {
|
||||
for (Issue2319 issueData : dataList) {
|
||||
System.out.println(("读取到一条数据{}" + JSON.toJSONString(issueData)));
|
||||
}
|
||||
})).sheet().doRead();
|
||||
}
|
||||
}
|
BIN
fastexcel-test/src/test/resources/temp/issue2319/test1.xlsx
Normal file
BIN
fastexcel-test/src/test/resources/temp/issue2319/test1.xlsx
Normal file
Binary file not shown.
BIN
fastexcel-test/src/test/resources/temp/issue2319/test2.xlsx
Normal file
BIN
fastexcel-test/src/test/resources/temp/issue2319/test2.xlsx
Normal file
Binary file not shown.
15
pom.xml
15
pom.xml
@ -20,7 +20,7 @@
|
||||
|
||||
|
||||
<properties>
|
||||
<revision>1.0.0</revision>
|
||||
<revision>1.1.0</revision>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<jdk.version>1.8</jdk.version>
|
||||
<gpg.skip>true</gpg.skip>
|
||||
@ -79,19 +79,6 @@
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.slf4j</groupId>-->
|
||||
<!-- <artifactId>slf4j-api</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.projectlombok</groupId>-->
|
||||
<!-- <artifactId>lombok</artifactId>-->
|
||||
<!-- <scope>provided</scope>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
|
@ -1,91 +1,91 @@
|
||||
<code_scheme name="easyexcel" version="173">
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="java" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="javax" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="com.alibaba" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="FORMATTER_TAGS_ENABLED" value="true" />
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="ANNOTATION_PARAMETER_WRAP" value="1" />
|
||||
<option name="CLASS_NAMES_IN_JAVADOC" value="3" />
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<code_scheme name="fastexcel" version="173">
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true"/>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="java" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="javax" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="com.alibaba" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
</value>
|
||||
<value>
|
||||
<package name="java" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="javax" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="cn.idev.excel" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="true"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
|
||||
<option name="JD_P_AT_EMPTY_LINES" value="false" />
|
||||
<option name="JD_PRESERVE_LINE_FEEDS" value="true" />
|
||||
</JavaCodeStyleSettings>
|
||||
<editorconfig>
|
||||
<option name="ENABLED" value="false" />
|
||||
</editorconfig>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="PREFER_PARAMETERS_WRAP" value="true" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="RESOURCE_LIST_WRAP" value="1" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="THROWS_LIST_WRAP" value="1" />
|
||||
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
|
||||
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
|
||||
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||
<option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="WRAP_COMMENTS" value="true" />
|
||||
<option name="ASSERT_STATEMENT_WRAP" value="1" />
|
||||
<option name="ASSERT_STATEMENT_COLON_ON_NEXT_LINE" value="true" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<option name="WRAP_LONG_LINES" value="true" />
|
||||
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
|
||||
<option name="VARIABLE_ANNOTATION_WRAP" value="2" />
|
||||
<option name="ENUM_CONSTANTS_WRAP" value="2" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<option name="FORMATTER_TAGS_ENABLED" value="true"/>
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="ANNOTATION_PARAMETER_WRAP" value="1"/>
|
||||
<option name="CLASS_NAMES_IN_JAVADOC" value="3"/>
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true"/>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="java" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="javax" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="cn.idev.excel" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="true"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
|
||||
<option name="JD_P_AT_EMPTY_LINES" value="false"/>
|
||||
<option name="JD_PRESERVE_LINE_FEEDS" value="true"/>
|
||||
</JavaCodeStyleSettings>
|
||||
<editorconfig>
|
||||
<option name="ENABLED" value="false"/>
|
||||
</editorconfig>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false"/>
|
||||
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false"/>
|
||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false"/>
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
|
||||
<option name="SPACE_AFTER_TYPE_CAST" value="false"/>
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="PREFER_PARAMETERS_WRAP" value="true"/>
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="RESOURCE_LIST_WRAP" value="1"/>
|
||||
<option name="EXTENDS_LIST_WRAP" value="1"/>
|
||||
<option name="THROWS_LIST_WRAP" value="1"/>
|
||||
<option name="EXTENDS_KEYWORD_WRAP" value="1"/>
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1"/>
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
|
||||
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true"/>
|
||||
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true"/>
|
||||
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true"/>
|
||||
<option name="FOR_STATEMENT_WRAP" value="1"/>
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
|
||||
<option name="ASSIGNMENT_WRAP" value="1"/>
|
||||
<option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true"/>
|
||||
<option name="WRAP_COMMENTS" value="true"/>
|
||||
<option name="ASSERT_STATEMENT_WRAP" value="1"/>
|
||||
<option name="ASSERT_STATEMENT_COLON_ON_NEXT_LINE" value="true"/>
|
||||
<option name="IF_BRACE_FORCE" value="3"/>
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="WHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="FOR_BRACE_FORCE" value="3"/>
|
||||
<option name="WRAP_LONG_LINES" value="true"/>
|
||||
<option name="PARAMETER_ANNOTATION_WRAP" value="1"/>
|
||||
<option name="VARIABLE_ANNOTATION_WRAP" value="2"/>
|
||||
<option name="ENUM_CONSTANTS_WRAP" value="2"/>
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
11
update.md
11
update.md
@ -0,0 +1,11 @@
|
||||
# 1.1.0
|
||||
此次升级主要修复 [EasyExcel](https://github.com/alibaba/easyexcel) 历史 BUG,同时剔除了部分依赖库,符合 `MIT` 协议的相关规范。
|
||||
|
||||
具体更新内容如下:
|
||||
- 【改进】移除 `itext` 依赖库,将 `转换PDF` 功能迁移至新项目;
|
||||
- 【修复】fill填充空数据,可能导致行数据错乱的问题;
|
||||
- 【修复】自定义数据格式可能导致数据读取失败的问题;
|
||||
- 【优化】例行升级依赖的Jar包版本;
|
||||
- 【优化】增加报错内容详细信息;
|
||||
- 【优化】更新代码格式和部分错别字;
|
||||
- 【优化】更新部分文档和使用说明。
|
Loading…
x
Reference in New Issue
Block a user