16 Star 226 Fork 49

wangguanquan / eec

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

EEC介绍

Release License

EEC(Excel Export Core)是一款轻量且高效的Excel读写工具,它具有包体小、接入代码量少和运行时消耗资源少等优点

EEC的设计初衷是为了解决Apache POI内存高、速度慢且API臃肿的诟病。EEC的底层并不依赖POI包,所有的底层代码均自己实现,事实上EEC仅依赖dom4jslf4j,前者用于小文件xml读取,后者统一日志接口。

EEC在JVM参数-Xmx10m -Xms10m下读写100w行x29列内存使用截图,下载 eec-benchmark 项目进行性能测试

write_read 100w

使用场景

EEC是线程不安全的它不支持多线程读写,同时其为流式设计且只能顺序向后,这意味着不能通过指定行列坐标来随机读写,通常可以使用EEC来做一些日常的导入/导出功能,推荐在大数据量性能/内存要求较高的场景或者没有随机读写的场景下使用。

目前已实现worksheet类型有七种,也可以继承已有Worksheet来实现自定义数据源

主要功能

  1. 支持大数据量导出行数无上限,超过单个Sheet上限会自动分页
  2. 超低内存,无论是xlsx还是xls格式,大部分情况下可以在10MB以内完成十万级甚至百万级行数据读写
  3. 支持动态样式,如导出库存时将低于预警阈值的行背景标黄显示
  4. 支持一键设置斑马线,利于阅读
  5. 自适应列宽对中文更精准
  6. 采用Stream流读文件,按需加载不会将整个文件读入到内存
  7. 支持Iterator和Stream+Lambda读文件,你可以像操作集合类一样操作Excel
  8. 支持csv与excel格式相互转换

WIKI

阅读WIKI 了解更多用法

Gitee

国内用户可访问Gitee, 在Gitee提issue开发者也同样会及时回复

使用方法

pom.xml添加

<dependency>
    <groupId>org.ttzero</groupId>
    <artifactId>eec</artifactId>
    <version>${eec.version}</version>
</dependency>

示例

1. 简单导出

对象数组导出时可以在对象上使用注解@ExcelColumn("列名")来设置excel头部信息

@ExcelColumn("渠道ID")
private int channelId;

@ExcelColumn
private String account;

默认情况下导出的列顺序与字段在对象中的定义顺序一致,可以通过指定colIndex或指定Column数组来重置顺序。

// 创建一个名为"test object"的excel文件
new Workbook("test object")

    // 添加"工作表"并指定导出数据,可以通过addSheet添加多个worksheet
    .addSheet(new ListSheet<>("学生信息", students))

    // 指定输出位置,如果做文件导出可以直接输出到`respone.getOutputStream()`
    .writeTo(Paths.get("f:/excel"));

2. 动态样式

动态样式和数据转换都是使用@FunctionalInterface实现,通常用于突出或高亮显示一些重要的单元格或行,下面展示如何将低下60分的成绩输出为"不合格"并将整行标为橙色

new Workbook("2021小五班期未考试成绩")
    .addSheet(new ListSheet<>("期末成绩", students
         , new Column("学号", "id", int.class)
         , new Column("姓名", "name", String.class)
         , new Column("成绩", "score", int.class, n -> (int) n < 60 ? "不合格" : n)
    ).setStyleProcessor((o, style, sst) -> 
            o.getScore() < 60 ? sst.modifyFill(style, new Fill(PatternType.solid, Color.orange)) : style)
    ).writeTo(Paths.get("f:/excel"));

效果如下图

期未成绩

3. 支持模板导出

EEC支持xls和xlsx模板格式,模板工作表TemplateSheet与其它工作表一样是一种数据源,只是样式由源工作表决定且不受ExcelColumn注解限制,导出的数据范围由模板中的占位符决定,关于模板导出请参考3-模板导出

new Workbook()
    // 复制[企业名片.xls]文件的[封面]工作表
    .addSheet(new TemplateSheet(Paths.get("./template/企业名片.xls", "封面"))
    .addSheet(new TemplateSheet(Paths.get("./template/商品导入模板.xlsx"))
        .setData(Entity.mock()) // 设置对象 对应占位符${*}
        // 分片拉取数据 对应占位符${list.*}
        .setData("list", (i,lastOne) -> scrollQuery(i > 0 ? ((Product)lastOne).getId() : 0))
    ).writeTo(Paths.get("f:/excel"));

4. 自适应列宽更精准

// 测试类
public static class WidthTestItem {
    @ExcelColumn(value = "整型", format = "#,##0_);[Red]-#,##0_);0_)")
    private Integer nv;
    @ExcelColumn("字符串(en)")
    private String sen;
    @ExcelColumn("字符串(中文)")
    private String scn;
    @ExcelColumn(value = "日期时间", format = "yyyy-mm-dd hh:mm:ss")
    private Timestamp iv;
}

new Workbook("Auto Width Test")
    .setAutoSize(true) // <- 自适应列宽
    .addSheet(new ListSheet<>(randomTestData()))
    .writeTo(Paths.get("f:/excel"));

自动列宽

5. 支持多级表头

EEC使用多个ExcelColumn注解来实现多级表头,名称一样的行或列将自动合并

 public static class RepeatableEntry {
    @ExcelColumn("运单号")
    private String orderNo;
    @ExcelColumn("收件地址")
    @ExcelColumn("省")
    private String rProvince;
    @ExcelColumn("收件地址")
    @ExcelColumn("市")
    private String rCity;
    @ExcelColumn("收件地址")
    @ExcelColumn("详细地址")
    private String rDetail;
    @ExcelColumn("收件人")
    private String recipient;
    @ExcelColumn("寄件地址")
    @ExcelColumn("省")
    private String sProvince;
    @ExcelColumn("寄件地址")
    @ExcelColumn("市")
    private String sCity;
    @ExcelColumn("寄件地址")
    @ExcelColumn("详细地址")
    private String sDetail;
    @ExcelColumn("寄件人")
    private String sender;
}

多行表头

6. 报表轻松制作

现在使用普通的ListSheet就可以导出漂亮的报表。示例请跳转到 WIKI

记帐类

报表1

统计类

报表2

7. 支持28种预设图片样式

导出图片时添加内置样式使其更美观,关于图片样式请参考1-导出Excel#导出图片

effect

读取示例

EEC使用ExcelReader#read静态方法读文件,其支持标准Stream所以可以直接使用mapfiltercollect等JDK内置函数,读取Excel就像操作集合类一样简单,极大降低学习成本。

1. 使用Stream

try (ExcelReader reader = ExcelReader.read(Paths.get("./User.xlsx"))) {
    // 读取所有worksheet并输出
    reader.sheets().flatMap(Sheet::rows).forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}

2. 读入到数组或List中

try (ExcelReader reader = ExcelReader.read(Paths.get("./User.xlsx"))) {
    List<User> users = reader.sheet(0) // 读取第1个Sheet页
        .header(6)                     // 指定第6行为表头
        .rows()                        // 读取数据行
        .map(row -> row.to(User.class))// 将每行数据转换为User对象
        .collect(Collectors.toList()); // 收集数据进行后续处理
} catch (IOException e) {
    e.printStackTrace();
}

3. 过滤和聚合

EEC支持Stream的大部分功能,以下代码展示过滤平台为"iOS"的注册用户

reader.sheet(0).header(6)
    .rows()
    // 过滤平台为"iOS"的用户
    .filter(row -> "iOS".equals(row.getString("platform")))
    .map(row -> row.to(User.class))
    .collect(Collectors.toList());

4. 多级表头读取

多级表头可以使用header方法来指定表头所在的多个行号

reader.sheet(0)
    .header(1, 2)    // <- 指定第1、2行均为表头
    .map(Row::toMap) // <- Row 转 Map
    .forEach(System.out::println)

多级表头将以A1:A2:A3这种格式进行纵向拼接,像上面第4个示例中的运单数据读取结果将以运单号收件地址:省收件地址:市呈现,这样就可以解决出现两个导致错乱的问题

更多关于多表头使用方法可以参考 WIKI

xls格式支持

pom.xml添加如下依赖,添加好后即完成了xls的兼容,是的!你不需要为xls格式添加任何一行代码。

<dependency>
    <groupId>org.ttzero</groupId>
    <artifactId>eec-e3-support</artifactId>
    <version>${eec-e3-support.version}</version>
</dependency>

读取xls的方法与xlsx完全一样,外部不需要判断是哪种格式,EEC为其提供了完全一样的接口,内部会根据文件头去判断具体类型,这种方式比简单判断文件后缀准确得多。

两个工具的兼容性 参考此表

CSV与Excel格式互转

  • CSV => Excel:向Workbook中添加一个CSVSheet工作表
  • Excel => CSV:读Excel时调用saveAsCSV另存为csv格式

代码示例

// 直接保存为csv生成测试文件,对于数据量较多的场合也可以使用#more方法分批获取数据
new Workbook()
    .addSheet(createTestData())
    .saveAsCSV() // 指定输出格式为csv
    .writeTo(Paths.get("d:\\abc.csv"));

// CSV转Excel
new Workbook()
    .addSheet(new CSVSheet(Paths.get("d:\\abc.csv"))) // 添加CSVSheet并指定csv路径
    .writeTo(Paths.get("d:\\abc.xlsx"));
    
// Excel转CSV
try (ExcelReader reader = ExcelReader.read(Paths.get("d:\\abc.xlsx"))) {
    // 读取Excel使用saveAsCSV保存为CSV格式
    reader.sheet(0).saveAsCSV(Paths.get("./"));
} catch (IOException e) {
    e.printStackTrace();
}

CHANGELOG

Version 0.5.14 (2024-04-22)

  • 新增数据验证Validation
  • 新增超链接注解Hyperlink
  • 新增模板工作表TemplateSheet
  • 新增TypeCastException用于Row转对象时如果出现类型转换异常时携带行列等信息
  • ListSheet新增data-supplier减化分片开发难度
  • 新增zoomScale扩展属性支持设置工作表缩放比例
  • 修复读取双色填充样式时抛异常

Version 0.5.13 (2024-02-20)

  • logback安全更新
  • 新增全属性工作表FullSheet以读取更多属性,它集合了MergeSheet和CalcSheet的功能
  • 新增扩展属性AutoFilter用于添加列筛选功能
  • 修复继承自ListSheet的工作表初始无法获取对象类型导致单元格空白的问题
  • 修复部分场景下边框颜色无法设置的问题
  • 修复部分Excel的indexed颜色与标准有所不同导致获取颜色不正确的问题
  • 修复部分场景读取Excel发生IndexOutOfBound异常
  • 修复HeaderStyle注解设置样式时,字段样式被全局样式替换的问题

Version 0.5.12 (2023-11-26)

  • 移除watch改用slf4j输出日志
  • 新增进度窗口onProgress
  • 优化自适应列宽算法使其支持更多字体和大小
  • 数据转换器功能增强,ExcelColumn增加converter属性以支持导出/导入时双向数据转换(#362)
  • 支持读取xlsx格式wps的内嵌图片(#363)
  • 部分类的注释改为中文,后续会将全部注释改为中文

Version 0.5.11 (2023-10-08)

  • 优化ExcelReader性能,性能提升100%~300%
  • 增加setHeaderColumnReadOption方法提高ExcelReader丰富性
  • 修复读取16进制转义字符时出现乱码问题
  • 修复非法UTF8字符导致写文件异常
  • 无数据且能获取表头信息时正常写表头(#361)
  • 屏蔽JDK17以上版本使用ExcelReader抛异常的问题

更多...

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "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.

简介

一款轻量且高效的Excel读写工具,它具有包体小、接入代码量少和运行时消耗资源少等优点。它支持10M内存读写百万级数据,同时支持Stream+Lambda方式读文件使你可以像操作集合类一样操作Excel 展开 收起
Java 等 2 种语言
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/wangguanquan/eec.git
git@gitee.com:wangguanquan/eec.git
wangguanquan
eec
eec
master

搜索帮助