Eec

A fast and lower memory excel write/read tool.一个非POI底层,支持流式处理的高效且超低内存的Excel读写工具
Alternatives To Eec
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Excel Streaming Reader8406419a year ago20March 24, 202195apache-2.0Java
An easy-to-use implementation of a streaming Excel reader using Apache POI
Xlstream148547 months ago33October 18, 20221mitTypeScript
Turns XLSX into a readable stream.
Excel Stream12917105 years ago12July 21, 201510mitJavaScript
Eec124
a month ago26April 08, 202348apache-2.0Java
A fast and lower memory excel write/read tool.一个非POI底层,支持流式处理的高效且超低内存的Excel读写工具
Androidpoiforreadexcelxlsx22
5 years ago1apache-2.0Java
android poi read excel xlsx
Node Excel Stream141110 months ago3September 20, 202015mitJavaScript
A utility to read and write JSON data to excel in streams
Exceljs Transform Stream9
3 years agomitJavaScript
Parse excel (XLSX) files as a through stream to JSON using exceljs
Excel8
7 years ago1otherPHP
Reads very large Excel (.xlsx) workbook files.
Xlsx Tables3
4 years agoGo
Easily stream large tables in xlsx sheets with Golang
Bank Manager2
4 years agoJava
my first springboot demo
Alternatives To Eec
Select To Compare


Alternative Project Comparisons
Readme

EEC介绍

Release License

EEC(Excel Export Core)是一个Excel读取和写入工具,目前支持xlsx格式的读取/写入以及xls格式的读取(xls支持BIFF8也就是excel 97~2003格式)。 EEC的设计初衷是为了解决Apache POI速度慢,高内存且API臃肿的诟病,EEC的底层并没有使用Apache POI包,所有的底层读写代码均自己实现,事实上EEC仅依懒dom4jslf4j,前者用于小文件xml读取,后者统一日志接口。

EEC最大特点是高性能低内存,如果在项目中做数据导入导出功能,选用EEC将为你带来极大的便利,同时它的可扩展能力也不弱。

使用inlineStr模式的情况下EEC的读写内存可以控制在10MB以下,SharedString模式也可以控制在16MB以下。这里 有关于EEC的压力测试,最低可以在6MB的情况下完成100w行x29列数据的读写。

EEC采用单线程、高IO设计,所以多核心高内存并不能显著提高速度,高主频和一块好SSD提升更明显。

EEC在JVM参数-Xmx6m -Xms1m下读写100w行x29列内存使用截图

写文件

eec write 100w

读文件

eec read 100w

现状

目前已实现worksheet类型有

也可以继承已知Worksheet来实现自定义数据源,比如微服务,mybatis或者其它RPC

EEC并不是一个功能全面的Excel操作工具类,它功能有限并不能用它来完全替代Apache POI,它最擅长的操作是表格处理。比如将数据库表导出为Excel或者读取Excel表格内容到Stream或数据库。

WIKI

阅读WIKI 了解更多用法

主要功能

  1. 支持大数据量导出,行数无上限。如果数据量超过单个sheet上限会自动分页。
  2. 超低内存,无论是xlsx还是xls格式,大部分情况下可以在10MB以内完成十万级甚至百万级行数据读写。
  3. 可以为某列设置阀值高亮显示,如导出学生成绩时低于60分的单元格背景标黄显示。
  4. 支持一键设置斑马线,利于阅读
  5. 自适应列宽对中文更精准
  6. 采用流式方式读取文件,操作某行数据才会实际加载,而不会将整个文件读入到内存。
  7. 支持iterator或者stream+lambda,你可以像操作集合类一样操作excel

使用方法

pom.xml添加

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

示例

导出示例,更多使用方法请参考test/各测试类

所有测试生成的excel文件均放在target/excel目录下,可以使用mvn clean清空。测试命令使用mvn clean test 清空先前文件避免找不到测试结果文件

1. 简单导出

对象数组导出时可以在对象上使用注解@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"));

2. 高亮和数据转换

高亮和数据转换是通过@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"));

效果如下图

期未成绩

3. 自适应列宽更精准

// 测试类
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"));

自动列宽

4. 支持多行表头

 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;
}

多行表头

5. 报表轻松制作

现在使用普通的ListSheet就可以导出漂亮的报表,省掉建模板的烦恼。示例请跳转到 WIKI

记帐类

报表1

统计类

报表2

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

关于图片样式请参考1-导出Excel#导出图片

effect

读取示例

EEC使用ExcelReader#read静态方法读文件,其内部采用流式操作,当使用某一行数据时才会真正读入内存,所以即使是GB级别的Excel文件也只占用少量内存。

默认的ExcelReader仅读取单元格的值而忽略公式,可以使用ExcelReader#parseFormula方法使Reader解析单元格的公式。

下面展示一些常规的读取方法

1. 使用stream操作

try (ExcelReader reader = ExcelReader.read(defaultPath.resolve("用户注册.xlsx"))) {
    // 读取所有worksheet并输出
    reader.sheets().flatMap(Sheet::rows).forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}

2. 将excel读入到数组或List中

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();
}

3. 既然是Stream那就可以使用流的全部功能,比如加一些过滤和聚合等。

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'

4. 多表头读取

如果要读取多行表头转对象或者Map时可以通过Sheet#header(fromRowNum, toRowNum)来指定表头所在的行号,如上方“记帐类报表”则可以使用如下代码读取

reader.sheet(0)
    .header(1, 2) // 指定表头所在的行第1行和第二行均为表头
    .map(Row::toMap) // Row 转 Map
    .forEach(System.out::println)

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

xls格式支持

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版本,两个工具的兼容性 参考此表

CSV与Excel格式互转

  • CSV => Excel 向Workbook中添加一个CSVSheet即可
  • Excel => CSV 读Excel后通过Worksheet调用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();
}

CHANGELOG

Version 0.5.10 (2023-08-10)

  • 修复单元格长度过长导致内容错位的异常(#354)
  • 支持导出图片

Version 0.5.9 (2023-05-10)

  • 修复dom4j默认构造器容易造成XXE安全漏洞

Version 0.5.8 (2023-04-08)

  • 删除部分已标记为过时的方法和类,兼容处理请查看wiki升级指引
    1. 删除Sheet.Column类
    2. 删除Row#getRowNumber方法
    3. 删除IntConversionProcessor类
  • 重命名xxOddFill为xxZebraLine
  • 修复自动分页后打开文件弹出警告
  • 取消默认斑马线,增加XMLZebraLineCellValueAndStyle自定义斑马线
  • 表头背景从666699调整为E9EAEC,斑马线颜色从EFF5EB调整为E9EAEC
  • 单个Column可以指定auto-size属性(#337)
  • 提供入口自定义处理未知的数据类型
  • 导出数据支持指定起始行号(#345)
  • 修复xls解析RK Value丢失精度问题
  • 修复部分已知BUG(#334, #342, #346)

Version 0.5.7 (2023-02-17)

  • 修复读取font-size时因为浮点数造成异常
  • 修复auto-size重置列宽时抛Buffer异常
  • 新增 #setRowHeight, #setHeaderRowHeight 方法设置行高

更多...

Popular Excel Projects
Popular Stream Projects
Popular Applications Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Java
Stream
Csv
Excel
Xlsx
Xls