easyExcel需要的依赖的pom内容;easyExcel需要对应的poi版本,下面这个是一套;否则会报错;
(异常java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Font.setBold(Z)V)
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<!--<version>3.8</version>-->
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
<!--<version>3.8</version>-->
</dependency>
<!-- easyExcel处理excel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.2-beta5</version>
</dependency>
--------------
往excel中写内容:
OutputStream os = new FileOutputStream(new File("C:/Users/zwk/Desktop/测试easyExcel.xlsx"));
ExcelWriter writer = EasyExcelFactory.getWriter(os);
com.alibaba.excel.metadata.Sheet sheet = new com.alibaba.excel.metadata.Sheet(1, 0, ModelBrand.class);
sheet.setSheetName("测试表");
writer.write(modelBrandMapper.getBrandList(), sheet);
writer.finish();
os.close();
注:ModelBrand是插入到excel中的对象模型;这里没有添加首页标题,是再ModelBrand类中定义的,且这个类是要继承BaseRowModel类;modelBrandMapper.getBrandList()是数据集合;
public class ModelBrand extends BaseRowModel {
@ExcelProperty(value="id",index=0)
private Long bId;
@ExcelProperty(value="品牌",index=1)
private String brand;
@ExcelProperty(value="图片",index=2)
private String img;
@ExcelProperty(value="状态",index=3)
private Short status;
@ExcelProperty(value="备注",index=4)
private String remark;
@ExcelProperty(value="首字母",index=5)
private String initial;
} value是导出列标题名称,index是列字段位置;
-------------
//导出excel表格(web项目)
@RequestMapping("/easyExcelTest")
public void easyExcelExport(HttpServletResponse response)throws Exception{
String filename = "easyeexcel列表";
response.setContentType("application/force-download");
response.setHeader("Content-Disposition", "attachment;filename=\"" + java.net.URLEncoder.encode(filename, "UTF-8") + ".xlsx" + "\" ");
//OutputStream os = new FileOutputStream(new File("C:/Users/zwk/Desktop/测试easyExcel.xlsx"));
ExcelWriter writer = EasyExcelFactory.getWriter(response.getOutputStream());
com.alibaba.excel.metadata.Sheet sheet = new com.alibaba.excel.metadata.Sheet(1, 0, ModelBrand.class);
sheet.setSheetName("测试表");
writer.write(modelBrandMapper.getBrandList(), sheet);
writer.finish();
response.getOutputStream().close();
}
----------------
读取excel文件数据:这里ModelInfoCopyMapper需要注入进来;这里使用构造方法将该参数传递进来
/**
* 异步读取excel文件中的数据;
* 读取excel文件中的指定数量,分批处理excel文件,解决占用内存的问题。
* 利用poi当遇到表格数据是数值时,实际类中定义的是字符串,读取的时候就需要
* 指定读取单元格的类型;而利用easyExcel模型无需这样,可以为空,null,数值类型,无需特别处理。
* @Author:
* @Date: 2019/10/16 11:58
* @Version 1.0.0
* @Description
*/
public class ExcelModelListener extends AnalysisEventListener<ModelInfoCopy> {
private ModelInfoCopyMapper modelInfoCopyMapper;
public ExcelModelListener(ModelInfoCopyMapper modelInfoCopyMapper){
this.modelInfoCopyMapper = modelInfoCopyMapper;
}
public ExcelModelListener(){
}
//public static ModelInfoCopyMapper modelInfoCopyMapper = SpringBeanUtil.getBean(ModelInfoCopyMapper.class);
//一次读取50条数据,处理50条可以根据具体情况读取(若数据大,可以调整一次读取2000条数据);
private static final int BATCH_COUNT = 2000;
List<ModelInfoCopy> list = new ArrayList<>();
private static int count = 0;
@Override
public void invoke(ModelInfoCopy modelInfoCopy, AnalysisContext analysisContext) {
//System.out.println("解析到一条数据:"+modelBrand.toString());
list.add(modelInfoCopy);
count++;
if(list.size() >= BATCH_COUNT){
saveData(count);
//清理list占用内存空间
list.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//这个方法调用若注释了,那么最后一批的数据就不会处理
saveData(count);
System.out.println("所有数据解析完成!"+"共处理"+count+"条数据");
}
//处理数据的方法
private void saveData(int count){
System.out.println(count+"条数据,开始存储数据库");
for(ModelInfoCopy modelInfoCopy : list){
modelInfoCopyMapper.insert(modelInfoCopy);
//System.out.println(modelBrand.getbId()+","+modelBrand.getBrand()+","+modelBrand.getRemark());
}
System.out.println("存储数据库成功");
}
}
//调用方法:这里处理十万数据,添加到数据库中需要206946毫秒,40个字段;30万条数据需要10分钟。
//使用poi处理的话,4万数据就会出现内存溢出异常。
@Test
public void test16(){
String filePath = "C:/Users/zwk/Desktop/车型数据(含编码)20191014.xlsx";
try{
long beforTime = System.currentTimeMillis();
com.alibaba.excel.metadata.Sheet sheet = new com.alibaba.excel.metadata.Sheet(1,1,ModelInfoCopy.class);
EasyExcelFactory.readBySax(new FileInputStream(new File(filePath)),sheet ,new ExcelModelListener(modelInfoCopyMapper) );
System.out.println("读取数据所花的时间:"+(System.currentTimeMillis()-beforTime)+"毫秒");
}catch (Exception e){
e.printStackTrace();
}
}
注:com.alibaba.excel.metadata.Sheet(1,1,ModelInfoCopy.class);是从第二行读取的,过滤调了标题行;第一个”1“代表的是excel文件中的第一个表格;第二个”1“代表表格的第几行开始读取。
/**
* @Author: 普通类获取spring容器中的bean
* @Date: 2019/10/16 14:42
* @Version 1.0.0
* @Description
*/
public class SpringBeanUtil {
//将管理上下文的applicationContext设置成静态变量,供全局调用
public static ConfigurableApplicationContext applicationContext;
//定义一个获取已经实例化bean的方法
public static <T> T getBean(Class<T> c){
return applicationContext.getBean(c);
}
}