文章目录
1、EasyExcle优点
EasyExcle是阿里巴巴开源的excle处理框架,以使用简单、节省内存
著称。EasyExcel能大大减少占用内存的主要原因是再解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。使用观察者模式将读取的数据通过AnalysisEventListener
进行处理。
<!-- 使用easyexcle -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
2、EasyExcle使用
首次将测试文件展示一下:
测试的excle一共有两个sheet分别是“个人信息”“公司信息”
首先根据excle的内容定义实体:个人信息(UserData )、公司信息(CompanyData )。
UserData.java
public class UserData {
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "性别")
private String sex;
@ExcelProperty(value = "年龄")
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "DataDemo{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age='" + age + '\'' +
'}';
}
}
CompanyData.java
public class CompanyData {
@ExcelProperty(value = "公司名称")
private String compName;
@ExcelProperty(value = "地址")
private String address;
@ExcelProperty(value = "类型")
private String type;
@ExcelProperty(value = "创办日期")
private String createDate;
public String getCompName() {
return compName;
}
public void setCompName(String compName) {
this.compName = compName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
@Override
public String toString() {
return "CompanyData{" +
"compName='" + compName + '\'' +
", address='" + address + '\'' +
", type='" + type + '\'' +
", createDate='" + createDate + '\'' +
'}';
}
}
2.1、读取excle文件(方式一)
直接读取方式
/**
* 通过doReadSync方法直接读取
*/
public static void readSync() {
long start = System.currentTimeMillis();
String fileName = "test.xls";
try (InputStream in = EasyExcelDemo.class.getClassLoader().getResourceAsStream(fileName)) {
//1、可以通过sheetNo读取sheet页
//List<DataDemo> list = EasyExcelFactory.read(in).autoCloseStream(Boolean.TRUE).sheet(0).doReadSync();
//2、可以通过sheetName读取sheet页
List<UserData> list = EasyExcelFactory.read(in)
.autoCloseStream(Boolean.TRUE) //选择自动关闭流
.sheet("个人信息")
.doReadSync();
System.out.println(list.toString());
} catch (IOException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");
}
main方法测试结果:
[{0=张三, 1=男, 2=18.0}, {0=李四, 1=男, 2=19.0}, {0=李思思, 1=女, 2=19.0}, {0=王玲玲, 1=女, 2=18.0}, {0=郭德纲, 1=男, 2=40.0}, {0=范冰冰, 1=女, 2=35.0}, {0=李茂贞, 1=男, 2=37.0}, {0=虞姬, 1=女, 2=19.0}, {0=楚霸王, 1=男, 2=33.0}]
耗时:228ms
2.2、读取excle文件(方式二)
首先需要定义一个自己Listener来继承AnalysisEventListener
,并且实现里面的invoke
和doAfterAllAnalysed
方法
public class UserDatalListener extends AnalysisEventListener<UserData> {
//存放解析数据
List<UserData> datas = new ArrayList<>();
//这个是批量操作的临界值
int count = 5;
@Override
public void invoke(UserData userData, AnalysisContext analysisContext) {
System.out.println(userData.toString());
datas.add(userData);
if(datas.size() >= count){
saveData(datas);
datas.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("解析完成了");
saveData(datas);
}
/**
* 保存数据到数据库
* @param userData
*/
public void saveData(List<UserData> userData){
System.out.println("入库 " + userData.size() + " 条数据");
}
}
读取excle的代码如下:
/**
* 使用继承AnalysisEventListener的Listen方式来读取excle
*/
public static void readExcle() {
long start = System.currentTimeMillis();
String fileName = "test.xls";
try (InputStream in = EasyExcelDemo.class.getClassLoader().getResourceAsStream(fileName);) {
EasyExcelFactory.read(in, UserData.class, new UserDatalListener())
.autoCloseStream(Boolean.TRUE) //选择自动关闭流
.sheet()
.doRead();
} catch (IOException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");
}
main方法测试结果:
DataDemo{name='张三', sex='男', age='18.0'}
DataDemo{name='李四', sex='男', age='19.0'}
DataDemo{name='李思思', sex='女', age='19.0'}
DataDemo{name='王玲玲', sex='女', age='18.0'}
DataDemo{name='郭德纲', sex='男', age='40.0'}
入库 5 条数据
DataDemo{name='范冰冰', sex='女', age='35.0'}
DataDemo{name='李茂贞', sex='男', age='37.0'}
DataDemo{name='虞姬', sex='女', age='19.0'}
DataDemo{name='楚霸王', sex='男', age='33.0'}
解析完成了
入库 4 条数据
耗时:297ms
2.3、读取多个sheet的excle文件
读取两个sheet需要根据每一个sheet匹配不同的实体,当然也可以直接使用LinkedHashMap不定义实体取实现。
/**
* 关于公司信息的解析
*/
public class CompanyDatalListener extends AnalysisEventListener<CompanyData> {
//存放解析数据
List<CompanyData> datas = new ArrayList<>();
//这个是批量操作的临界值
int count = 5;
@Override
public void invoke(CompanyData companyData, AnalysisContext analysisContext) {
System.out.println(companyData.toString());
datas.add(companyData);
if (datas.size() >= count) {
saveData(datas);
datas.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("解析完成了");
saveData(datas);
}
/**
* 保存数据到数据库
*
* @param userData
*/
public void saveData(List<CompanyData> userData) {
System.out.println("入库 " + userData.size() + " 条数据");
}
}
读取两个sheet的代码实现如下
/**
* 读取多个Sheet页的Excle
*/
public static void read2SheetsExcel() {
String fileName = "test.xls";
//开始读取excle
try (InputStream in = EasyExcelDemo.class.getClassLoader().getResourceAsStream(fileName)) {
ExcelReader excelReader = EasyExcelFactory.read(in).build();
//读取Sheet0
ReadSheet readSheet0 = EasyExcelFactory.readSheet("个人信息")
.head(UserData.class)
.registerReadListener(new UserDatalListener())
.build();
//读取Sheet1
ReadSheet readSheet1 = EasyExcelFactory.readSheet("公司信息").
head(CompanyData.class).
registerReadListener(new CompanyDatalListener())
.build();
//读取两个Sheet
excelReader.read(readSheet0, readSheet1);
//读取完了记得关闭
excelReader.finish();
} catch (IOException e) {
e.printStackTrace();
}
}
使用main方法测试结果:
DataDemo{name='张三', sex='男', age='18.0'}
DataDemo{name='李四', sex='男', age='19.0'}
DataDemo{name='李思思', sex='女', age='19.0'}
DataDemo{name='王玲玲', sex='女', age='18.0'}
DataDemo{name='郭德纲', sex='男', age='40.0'}
入库 5 条数据
DataDemo{name='范冰冰', sex='女', age='35.0'}
DataDemo{name='李茂贞', sex='男', age='37.0'}
DataDemo{name='虞姬', sex='女', age='19.0'}
DataDemo{name='楚霸王', sex='男', age='33.0'}
解析完成了
入库 4 条数据
CompanyData{compName='阿里巴巴', address='北京', type='电商', createDate='2000.0'}
CompanyData{compName='百度', address='北京', type='搜索', createDate='1999.0'}
CompanyData{compName='腾讯', address='深圳', type='聊天', createDate='2001.0'}
CompanyData{compName='中原银行', address='郑州', type='银行', createDate='2014.0'}
解析完成了
入库 4 条数据
2.4、写excle文件
通过输出流直接将excle内容输出
/**
* 将数据写入到指定文件
*
* @throws FileNotFoundException
*/
public static void writeExcle() {
UserData userData = new UserData();
userData.setName("leo825");
userData.setAge("25");
userData.setSex("男");
List<UserData> addList = new ArrayList<>();
addList.add(userData);
//定义一个输出流
try(FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\WorkSpace\\IDEA_WorkSpace\\sortalgorithm-demos\\src\\main\\resources\\out.xls"));) {
EasyExcelFactory.write(fileOutputStream, UserData.class)
.autoCloseStream(Boolean.TRUE) //选择自动关闭流
.sheet("个人信息")
.doWrite(addList);
} catch (IOException e) {
e.printStackTrace();
}
}
如果是在web上下载的话可以使用如下代码:
@RequestMapping("/download")
public void download(HttpServletResponse response) throws Exception {
//测试数据
UserData userData = new UserData();
userData.setName("leo825");
userData.setAge("25");
userData.setSex("男");
List<UserData> addList = new ArrayList<>();
addList.add(userData);
//输出流输出文件
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("测试", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
EasyExcelFactory.write(response.getOutputStream(),UserData.class)
.autoCloseStream(Boolean.TRUE) //选择自动关闭流
.sheet("个人信息")
.doWrite(addList);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72656.html