赞
踩
我也是凑巧用上了,就在这里分享一下,性能确实是没得说!
对easyexcel的介绍是:Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到KB级别,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便
1、导入的pom.xml
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>easyexcel</artifactId>
- <version>1.0.3</version>
- </dependency>
实际上版本(1.0.1
)在读取的时候是有BUG的,读取03版的.xls
格式的excel正常,但是读取07版的.xlsx
版的excel就会出异常,原因是在解析的时候sheet临时文件路径拼装有误,所以我们用1.0.3
2、使用easyexcel读取excel的时候需要设置excel的版本,但是有些时候我们无法预知excel的版本,所以在网上copy了大神模仿poi
写了一个用于获取com.alibaba.excel.ExcelReader
对象的工具类
- package easyExcel.com.easy.excel;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.PushbackInputStream;
-
- import org.apache.poi.EmptyFileException;
- import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
- import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
- import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
- import org.apache.poi.util.IOUtils;
-
- import com.alibaba.excel.ExcelReader;
- import com.alibaba.excel.read.context.AnalysisContext;
- import com.alibaba.excel.read.event.AnalysisEventListener;
- import com.alibaba.excel.support.ExcelTypeEnum;
-
- public class ExcelReaderFactory {
- /**
- * @param in
- * 文件输入流
- * @param customContent
- * 自定义模型可以在
- * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }
- * AnalysisContext中获取用于监听者回调使用
- * @param eventListener
- * 用户监听
- * @throws IOException
- * @throws EmptyFileException
- * @throws InvalidFormatException
- */
- public static ExcelReader getExcelReader(InputStream in, Object customContent,
- AnalysisEventListener<?> eventListener) throws EmptyFileException, IOException, InvalidFormatException {
- // 如果输入流不支持mark/reset,需要对其进行包裹
- if (!in.markSupported()) {
- in = new PushbackInputStream(in, 8);
- }
-
- // 确保至少有一些数据
- byte[] header8 = IOUtils.peekFirst8Bytes(in);
- ExcelTypeEnum excelTypeEnum = null;
- if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
- excelTypeEnum = ExcelTypeEnum.XLS;
- }
- if (DocumentFactoryHelper.hasOOXMLHeader(in)) {
- excelTypeEnum = ExcelTypeEnum.XLSX;
- }
- if (excelTypeEnum != null) {
- return new ExcelReader(in, excelTypeEnum, customContent, eventListener);
- }
- throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
-
- }
-
- /**
- * @param in
- * 文件输入流
- * @param customContent
- * 自定义模型可以在
- * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }
- * AnalysisContext中获取用于监听者回调使用
- * @param eventListener
- * 用户监听
- * @param trim
- * 是否对解析的String做trim()默认true,用于防止 excel中空格引起的装换报错。
- * @throws IOException
- * @throws EmptyFileException
- * @throws InvalidFormatException
- */
- public static ExcelReader getExcelReader(InputStream in, Object customContent,
- AnalysisEventListener<?> eventListener, boolean trim)
- throws EmptyFileException, IOException, InvalidFormatException {
- // 如果输入流不支持mark/reset,需要对其进行包裹
- if (!in.markSupported()) {
- in = new PushbackInputStream(in, 8);
- }
-
- // 确保至少有一些数据
- byte[] header8 = IOUtils.peekFirst8Bytes(in);
- ExcelTypeEnum excelTypeEnum = null;
- if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
- excelTypeEnum = ExcelTypeEnum.XLS;
- }
- if (DocumentFactoryHelper.hasOOXMLHeader(in)) {
- excelTypeEnum = ExcelTypeEnum.XLSX;
- }
- if (excelTypeEnum != null) {
- return new ExcelReader(in, excelTypeEnum, customContent, eventListener, trim);
- }
- throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
- }
- }
3、然后编写一个简单的测试类
- package easyExcel.com.easy.excel;
-
- import java.io.FileInputStream;
- import java.io.InputStream;
-
- import org.junit.Test;
-
- import com.alibaba.excel.ExcelReader;
- import com.alibaba.excel.annotation.ExcelProperty;
- import com.alibaba.excel.metadata.BaseRowModel;
- import com.alibaba.excel.metadata.Sheet;
- import com.alibaba.excel.read.context.AnalysisContext;
- import com.alibaba.excel.read.event.AnalysisEventListener;
-
- public class ExcelWriteTest {
-
- public static class ExcelPropertyIndexModel extends BaseRowModel {
- @ExcelProperty(value = "姓名", index = 0)
- private String name;
-
- @ExcelProperty(value = "年龄", index = 1)
- private String age;
-
- @ExcelProperty(value = "邮箱", index = 2)
- private String email;
-
- @ExcelProperty(value = "地址", index = 3)
- private String address;
-
- @ExcelProperty(value = "性别", index = 4)
- private String sax;
-
- @ExcelProperty(value = "高度", index = 5)
- private String heigh;
-
- @ExcelProperty(value = "备注", index = 6)
- private String last;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getAge() {
- return age;
- }
-
- public void setAge(String age) {
- this.age = age;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- public String getSax() {
- return sax;
- }
-
- public void setSax(String sax) {
- this.sax = sax;
- }
-
- public String getHeigh() {
- return heigh;
- }
-
- public void setHeigh(String heigh) {
- this.heigh = heigh;
- }
-
- public String getLast() {
- return last;
- }
-
- public void setLast(String last) {
- this.last = last;
- }
-
- @Override
- public String toString() {
- return "ExcelPropertyIndexModel [name=" + name + ", age=" + age + ", email=" + email + ", address="
- + address + ", sax=" + sax + ", heigh=" + heigh + ", last=" + last + "]";
- }
-
- }
-
- @Test
- public void read() throws Exception {
- //text.xlsx
- try (InputStream in = new FileInputStream("try.xlsx");) {
- AnalysisEventListener<ExcelPropertyIndexModel> listener = new AnalysisEventListener<ExcelPropertyIndexModel>() {
-
- @Override
- public void invoke(ExcelPropertyIndexModelobject, AnalysisContext context) {
- System.err.println("Row:" + context.getCurrentRowNum() + " Data:"
- + object.toString());
- }
-
- @Override
- public void doAfterAllAnalysed(AnalysisContext context) {
- System.err.println("doAfterAllAnalysed...");
- }
- };
- ExcelReader excelReader = ExcelReaderFactory.getExcelReader(in, null, listener);
- // 第二个参数为表头行数,按照实际设置
- excelReader.read(new Sheet(1, 1, ExcelPropertyIndexModel.class));
- }
- }
- }
解释一下测试类的代码:ExcelPropertyIndexModel是一个用来存放解析完表格的数据类,@ExcelProperty(value = "名称", index = 10)注解中的index标识着这个参数对应的列,index从0开始
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。