赞
踩
目录
1、工作中使用 excel 表格处理数据是很常见的操作,经常会使用 excel 文件来导入数据或者导出数据。
2、Java 解析、生成 Excel 比较有名的框架有 Apache poi、jxl,但他们都存在一个严重的问题就是非常的耗内存,poi 有一套 SAX 模式的 API 可以一定程度的解决一些内存溢出的问题,但仍有一些缺陷,比如版本兼容、代码臃肿等。
3、easyexcel 是 Alibaba 的 开源的一款快速、简单、可避免 OOM 的 java 处理 Excel 工具。easyexcel 重写了 poi 对 07 版 Excel 的解析,对原本一个 3M 的 excel 用 POI sax 需要 100M 左右的内存降低到几 M,并且再大的 excel 也不会出现内存溢出。
4、github 开源地址:https://github.com/alibaba/easyexcel,源码中提供了丰富的示例,推荐参考。
Excel2003(xls) 最多 65536行,256 列,超过就会报错。
Excel2007(xlsx) 最多1048576 行,16384列(采取的是xml存储)超过就会报错,不过已经完全够用了。
Easyexcel 依赖
1、本文环境:Spring boot 2.1.4 + Java JDK 1.8 + easyexcel 2.2.6,新建一个 Spring boot web 应用,然后 pom.xml 文件导入 easyexcel 依赖如下。
- <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>easyexcel</artifactId>
- <version>2.2.6</version>
- </dependency>
2、easyexcel 内部依赖项如下(easyexcel 是对 poi 的改写,同时使用了 ehcache 做缓存,提升效率):
Group / Artifact |
---|
cglib » cglib |
org.apache.poi » poi |
org.apache.poi » poi-ooxml |
org.apache.poi » poi-ooxml-schemas |
org.ehcache » ehcache |
org.slf4j » slf4j-api |
1、EasyExcel 类是个空类,也是整个框架的核心类,方法全部继承于 EasyExcelFactory,目的是编码起来名称更加简短直观,与整个框架的名称一致,常用方法如下:
====读取 excel 文件方法==== ExcelReaderBuilder read(String pathName) ExcelReaderBuilder read(String pathName, Class head, ReadListener readListener) ExcelReaderBuilder read(String pathName, ReadListener readListener) ExcelReaderBuilder read(File file) ExcelReaderBuilder read(File file, Class head, ReadListener readListener) ExcelReaderBuilder read(File file, ReadListener readListener) ExcelReaderBuilder read(InputStream inputStream) ExcelReaderBuilder read(InputStream inputStream, Class head, ReadListener readListener) ExcelReaderBuilder read(InputStream inputStream, ReadListener readListener) 1、可以读取本地 excel 文件,也可以网络文件(比如文件上传),网络文件使用 InputStream 参数即可。 2、pathName、file、inputStream 参数都是需要读取的 excel 文件。 3、head:是一个实体对象,将实体对象的属性与 excel 文件的列进行对应,一个实体对象就是 excel 中的一行数据。 4、readListener 是读取监听器,每读取一行标题、或者一行正文数据,都会进入相应的回调方法,然后可以对数据进行处理。 |
====写入 excel 文件方法==== 1、可以写入到本地文件,也可以是网络文件(如文件下载),网络文件使用 OutputStream 参数即可。 |
2、ExcelWriterBuilder 是 excel 写构建器,用于设置写入操作:
ExcelWriterSheetBuilder sheet(String sheetName):指定 sheet 的名称,默认为 Sheet1、Sheet2...,Sheet 是excel 中的工作簿 autoCloseStream(Boolean autoCloseStream):设置是否自动关闭流,默认为 true,设置成 false 后,需要自己手动关流。 2、设置模板文件,比如写入的时候,希望将数据写入到一个模板文件中去,支持本地文件和网络文件。 |
3、ExcelReaderBuilder 是 excel 读构建器,用于设置读取操作:
ExcelReaderSheetBuilder sheet(String sheetName):读取指定名称的 sheet。 |
4、常用注解:
@ExcelIgnore | 标识在字段上,表示忽略这个字段不与 excel 中的列匹配,即忽略此字段读取与写入 |
@ColumnWidth | 指定写入的 excel 的列宽,包括标题与正文内容,标识在类上对所有列生效,标识在字段上对单个字段生效 |
@ExcelProperty | 标识实体中的属性与 excel 文件中的列相对应,常用属性如下: index:表示下标匹配,从0开始,0 应表格中的第1列的值,1 对应 excel 中第二列的值,依此类推 value:表示名称匹配,直接指明对应表中的哪一列,值是一个字符串数组,按顺序为一级标题、二级标题,一级标题相同时,会自动合并居中。 官方不建议 index 和 name 同时使用,同一个对象中,要么只用 index,要么只用 name。 |
@HeadRowHeight | 指定写入的 excel 的标题的行高,不包括正文内容,只能标记在类上、接口上、枚举上 |
@HeadStyle | 自定义excel表格标题单元格样式,比如前/背景色等,fillPatternType 是填充模式,fillForegroundColor 表示前景色,值从 {@link IndexedColors} 枚举中取,默认标题会为灰色,字体为黑色,大小为 14 |
@HeadFontStyle | 自定义表格标题的字体样式、比如大小、颜色、字体、下划线等等。默认为 14,居中显示。fontHeightInPoints 表示字体大小,color 表示样式,值从 {@link IndexedColors} 枚举中取 |
@ContentStyle | 设置表格中正文内容单元格的样式,比如前/背景色等,默认无。同理 @HeadStyle |
@ContentFontStyle | 设置表格中正文内容的样式,比如字体、颜色、大小等,默认大小为 11。同理 @HeadFontStyle |
5、AnalysisEventListener - excel 读取事件监听器:
1、AnalysisEventListener 抽象类实现了 ReadListener 接口, 2、自定义的读取监听器需要实现此抽象类,然后实现 invoke 方法, 3、读取监听器的目的在于能捕获读取到的每一条数据,这样可以轻松的对每一条数据进行处理,比如存库、清洗、验证、记录日志等 4、读取监听器实例不能交由 spring 容器管理,EasyExcel.read 时只能通过 new 读取监听器对象,如果读取监听器中需要用到哪个 bean,则可以通过构造器参数传入。 5、invoke :每成功解析一条数据,都会进入此方法 6、invokeHeadMap:每成功解析完成一行表头,都会进入此方法 7、doAfterAllAnalysed:所有数据解析完成后进入此方法 8、onException:解析异常时进入本方法,如果抛出异常,则停止读取,否则继续读取下一行 |
实际生产中使用上面的上传、下载多一些,本节是对读 excel 文件的更深入的介绍与汇总。
1、本节演示的源码地址:src/main/java/com/wmx/excel/test/ExcelReadTest.java · 汪少棠/h2Smil - Gitee.com
2、本节演示的 excel 文件:https://gitee.com/wangmx1993/h2-smil/tree/master/src/main/resources/excelTemplates
3、本文的 demo 是在 easyExcel 官方 demo 的基础上修改而来,本节源码中加入了更详细的注释,更多内容建议参考官网。
实际生产中使用上面的上传、下载多一些,本节是对写 excel 文件的更深入的介绍与汇总。
1、本节演示的源码地址:src/main/java/com/wmx/excel/test/ExcelWriteTest.java · 汪少棠/h2Smil - Gitee.com
2、本节演示的 excel 文件:https://gitee.com/wangmx1993/h2-smil/tree/master/src/main/resources/excelTemplates
3、本文的 demo 是在 easyExcel 官方 demo 的基础上修改而来,本节源码中加入了更详细的注释,更多内容建议参考官网。
实际生产中使用上传、下载多一些,对于读/写操作更多的介绍可以参考下面的 "读 Excel "、"写 Excel "章节。
1、本节演示的源码地址:https://gitee.com/wangmx1993/h2-smil/tree/master/src/main/java/com/wmx/excel/web
2、本节演示的 excel 文件:https://gitee.com/wangmx1993/h2-smil/tree/master/src/main/resources/excelTemplates
3、本文的 demo 是在 easyExcel 官方 demo 的基础上修改而来,本节源码中加入了更详细的注释,更多内容建议参考官网。
1、某些系统或者浏览器在下载文件的时候,可能出现文件名称乱码的现象,如下所示。
2、解决方案的核心代码如下,就是修改返回的头信息。
- public static void returnErrorExlForColumn(Map<String, String> progressData, List<Map<String, Object>> errorData,
- List<UiRunColumn> uvColumnList, UiRunView uvView, HttpServletRequest request, HttpServletResponse response) throws IOException {
- OutputStream os = null;
- // 工作薄
- Workbook wb = null;
- try {
- wb = FWExcelCreateUtil.expExcelDataByPt(errorData, uvView, uvColumnList);
- if (wb != null) {
- //动态决定导出文件的后缀名
- String suffix = ".xlsx";
- if(wb instanceof HSSFWorkbook) {
- suffix = ".xls";
- }
- //判断客户端是否为 IE浏览器
- boolean isMSIE = isMSBrowser(request);
- //文件名称
- String fileName = uvView.getName() + "(错误信息)";
- response.setContentType("application/vnd.ms-excel");
- if (isMSIE) {
- //解决IE浏览器文件名称乱码
- fileName = new String(fileName.getBytes("gb2312"), "iso8859-1");
- response.setHeader("Content-Disposition", "inline; filename=" + fileName + suffix);
- } else {
- //万能文件名称乱码问题解决
- fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
- response.setHeader("Content-disposition", "attachment;filename=" + fileName + suffix);
- }
- os = response.getOutputStream();
- wb.write(os);
- }
- } catch (Exception ex) {
- log.error(ExceptionUtils.getStackTrace(ex));
- } finally {
- os.flush();
- os.close();
- if (errorData.size() > 999){
- //清除缓存数据
- ((SXSSFWorkbook)wb).dispose();
- }
- }
- }
-
- /**
- * 判断客户端是否为 IE浏览器
- * @param request :客户端请求
- * @return
- */
- public static boolean isMSBrowser(HttpServletRequest request) {
- String userAgent = request.getHeader("User-Agent");
- String[] IEBrowserSignals = {"MSIE", "Trident", "Edge"};
- for (String signal : IEBrowserSignals) {
- if (StringUtils.contains(userAgent, signal)) {
- return true;
- }
- }
- return false;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。