Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Excel Streaming Reader | 840 | 64 | 19 | a year ago | 20 | March 24, 2021 | 95 | apache-2.0 | Java | |
An easy-to-use implementation of a streaming Excel reader using Apache POI | ||||||||||
Xlstream | 148 | 5 | 4 | 7 months ago | 33 | October 18, 2022 | 1 | mit | TypeScript | |
Turns XLSX into a readable stream. | ||||||||||
Excel Stream | 129 | 17 | 10 | 5 years ago | 12 | July 21, 2015 | 10 | mit | JavaScript | |
Eec | 124 | a month ago | 26 | April 08, 2023 | 48 | apache-2.0 | Java | |||
A fast and lower memory excel write/read tool.一个非POI底层,支持流式处理的高效且超低内存的Excel读写工具 | ||||||||||
Androidpoiforreadexcelxlsx | 22 | 5 years ago | 1 | apache-2.0 | Java | |||||
android poi read excel xlsx | ||||||||||
Node Excel Stream | 14 | 1 | 1 | 10 months ago | 3 | September 20, 2020 | 15 | mit | JavaScript | |
A utility to read and write JSON data to excel in streams | ||||||||||
Exceljs Transform Stream | 9 | 3 years ago | mit | JavaScript | ||||||
Parse excel (XLSX) files as a through stream to JSON using exceljs | ||||||||||
Excel | 8 | 7 years ago | 1 | other | PHP | |||||
Reads very large Excel (.xlsx) workbook files. | ||||||||||
Xlsx Tables | 3 | 4 years ago | Go | |||||||
Easily stream large tables in xlsx sheets with Golang | ||||||||||
Bank Manager | 2 | 4 years ago | Java | |||||||
my first springboot demo |
EEC(Excel Export Core)是一个Excel读取和写入工具,目前支持xlsx格式的读取/写入以及xls格式的读取(xls支持BIFF8也就是excel 97~2003格式)。
EEC的设计初衷是为了解决Apache POI速度慢,高内存且API臃肿的诟病,EEC的底层并没有使用Apache POI包,所有的底层读写代码均自己实现,事实上EEC仅依懒dom4j
和slf4j
,前者用于小文件xml读取,后者统一日志接口。
EEC最大特点是高性能
和低内存
,如果在项目中做数据导入导出功能,选用EEC将为你带来极大的便利,同时它的可扩展
能力也不弱。
使用inlineStr
模式的情况下EEC的读写内存可以控制在10MB以下,SharedString
模式也可以控制在16MB以下。这里 有关于EEC的压力测试,最低可以在6MB的情况下完成100w行x29列数据的读写。
EEC采用单线程、高IO设计,所以多核心高内存并不能显著提高速度,高主频和一块好SSD提升更明显。
EEC在JVM参数-Xmx6m -Xms1m
下读写100w行x29列内存使用截图
写文件
读文件
目前已实现worksheet类型有
也可以继承已知Worksheet来实现自定义数据源,比如微服务,mybatis或者其它RPC
EEC并不是一个功能全面的Excel操作工具类,它功能有限并不能用它来完全替代Apache POI,它最擅长的操作是表格处理。比如将数据库表导出为Excel或者读取Excel表格内容到Stream或数据库。
阅读WIKI 了解更多用法
pom.xml添加
<dependency>
<groupId>org.ttzero</groupId>
<artifactId>eec</artifactId>
<version>${eec.version}</version>
</dependency>
所有测试生成的excel文件均放在target/excel目录下,可以使用mvn clean
清空。测试命令使用mvn clean test
清空先前文件避免找不到测试结果文件
对象数组导出时可以在对象上使用注解@ExcelColumn("列名")
来设置excel头部信息,未添加ExcelColumn注解标记的属性将不会被导出。
private int id; // not export
@ExcelColumn("渠道ID")
private int channelId;
@ExcelColumn
private String account;
@ExcelColumn("注册时间")
private Timestamp registered;
默认情况下导出的列顺序与字段在对象中的定义顺序一致,可以设置colIndex
或者在addSheet
时重置列头顺序。
// 创建一个名为"test object"的excel文件,指定作者,不指定时默认取系统登陆名
new Workbook("test object", "guanquan.wang")
// 添加一个worksheet,可以通过addSheet添加多个worksheet
.addSheet(new ListSheet<>("学生信息", students))
// 指定输出位置,如果做文件导出可以直接输出到`respone.getOutputStream()`
.writeTo(Paths.get("f:/excel"));
高亮和数据转换是通过@FunctionalInterface
实现,Java Bean也可以使用StyleDesign
注解,下面展示如何将低下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 ? Styles.clearFill(style) | sst.addFill(new Fill(PatternType.solid, Color.orange)) : style)
).writeTo(Paths.get("f:/excel"));
效果如下图
// 测试类
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"));
public static class RepeatableEntry {
@ExcelColumn("TOP")
@ExcelColumn("K")
@ExcelColumn
@ExcelColumn("订单号")
private String orderNo;
@ExcelColumn("TOP")
@ExcelColumn("K")
@ExcelColumn("A")
@ExcelColumn("收件人")
private String recipient;
@ExcelColumn("TOP")
@ExcelColumn("收件地址")
@ExcelColumn("A")
@ExcelColumn("省")
private String province;
@ExcelColumn("TOP")
@ExcelColumn("收件地址")
@ExcelColumn("A")
@ExcelColumn("市")
private String city;
@ExcelColumn("TOP")
@ExcelColumn("收件地址")
@ExcelColumn("B")
@ExcelColumn("区")
private String area;
@ExcelColumn("TOP")
@ExcelColumn("收件地址")
@ExcelColumn("B")
@ExcelColumn("详细地址")
private String detail;
}
现在使用普通的ListSheet就可以导出漂亮的报表,省掉建模板的烦恼。示例请跳转到 WIKI
记帐类
统计类
关于图片样式请参考1-导出Excel#导出图片
EEC使用ExcelReader#read
静态方法读文件,其内部采用流式操作,当使用某一行数据时才会真正读入内存,所以即使是GB级别的Excel文件也只占用少量内存。
默认的ExcelReader仅读取单元格的值而忽略公式,可以使用ExcelReader#parseFormula
方法使Reader解析单元格的公式。
下面展示一些常规的读取方法
try (ExcelReader reader = ExcelReader.read(defaultPath.resolve("用户注册.xlsx"))) {
// 读取所有worksheet并输出
reader.sheets().flatMap(Sheet::rows).forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
try (ExcelReader reader = ExcelReader.read(defaultPath.resolve("用户注册.xlsx"))) {
// 读取所有worksheet并转为Register对象
Register[] array = reader.sheets()
// 读取数据行
.flatMap(Sheet::dataRows)
// 将每行数据转换为Register象
.map(row -> row.to(Register.class))
// 转数组或者List
.toArray(Register[]::new);
} catch (IOException e) {
e.printStackTrace();
}
reader.sheet(0)
.dataRows()
.map(row -> row.to(Regist.class))
.filter(e -> "iOS".equals(e.platform()))
.collect(Collectors.toList());
以上代码相当于SQL select * from '用户注册' where platform = 'iOS'
如果要读取多行表头转对象或者Map时可以通过Sheet#header(fromRowNum, toRowNum)
来指定表头所在的行号,如上方“记帐类报表”则可以使用如下代码读取
reader.sheet(0)
.header(1, 2) // 指定表头所在的行第1行和第二行均为表头
.map(Row::toMap) // Row 转 Map
.forEach(System.out::println)
更多关于多表头使用方法可以参考 WIKI
pom.xml添加如下代码,添加好后即完成了xls的兼容,是的你不需要为xls写任何一行代码,原有的读取文件代码只需要传入xls即可读取,
<dependency>
<groupId>org.ttzero</groupId>
<artifactId>eec-e3-support</artifactId>
<version>${eec-e3-support.version}</version>
</dependency>
读取xls格式的方法与读取xlsx格式完全一样,读取文件时不需要判断是xls格式还是xlsx格式,EEC为其提供了完全一样的接口,内部会根据文件头去判断具体类型, 这种方式比判断文件后缀准确得多。
你可以在 search.maven.org 查询eec-e3-support版本,两个工具的兼容性 参考此表
CSVSheet
即可saveAsCSV
代码示例
// 直接保存为csv生成测试文件,对于数据量较多的场合也可以使用#more方法分批获取数据
new Workbook()
.addSheet(createTestData())
.saveAsCSV()
.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并保存为CSV格式
reader.sheet(0).saveAsCSV(Paths.get("./")); // 以sheet名csv文件名保存到当前目录
} catch (IOException e) {
e.printStackTrace();
}