工作中想必会大量使用到导入导出数据的场景,之前一直使用poi,不仅性能比较差,很吃内存,实现起来也很复杂,后来开始使用easyexecl,发现真的好简单。
第一步:
如果你使用的是maven工具构建项目,导入easyexecl的pom依赖,版本根据需要自行更换:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
导入实体类定义:
@Data
public class TestData {
private String partnerMobile;
private String role;
写导入的监听类,一行一行读取
@Slf4j
public class TestListener extends AnalysisEventListener<TestData> {
/**
* 每隔100条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
List<TestData> list = new ArrayList<TestData>();
@Override
public void invoke(TestData data, AnalysisContext context) {
log.info("解析到一条数据:{}", JSONObject.toJSON(data));
list.add(data);
if (list.size() >= BATCH_COUNT) {
saveData();
list.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
saveData();
log.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
private void saveData() {
log.info("{}条数据,开始存储数据库!", list.size());
log.info("存储数据库成功!");
}
}
第二步:编写导入导出的接口
@RequestMapping(value = "/testImport", method = RequestMethod.POST)
@ResponseBody
public BaseResponse testImport(@RequestParam("file") MultipartFile multipartFile){
BaseResponse baseResponse = BackResponseUtil.getBaseResponse(ReturnCodeEnum.CODE_1000.getCode());
try{
EasyExcel.read(multipartFile.getInputStream(), TestData.class, new TestListener()).sheet().doRead();
}catch (Exception e){
baseResponse = BackResponseUtil.getBaseResponse(ReturnCodeEnum.CODE_1005.getCode());
}
return baseResponse;
}
导出实体定义:此处用来导出待填写的模板
package com.donlim.fms.model.excelModel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author 李安山
* @date 2023/3/17
* @version 1.0
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class DeptCsrScoreTemplate {
/**
* 制造群名称
*/
@ExcelProperty("所属制造群")
@ColumnWidth(20)
private String group_name;
/**
* 单位名称
*/
@ExcelProperty("单位名称")
@ColumnWidth(30)
private String company_name;
/**
* 单位人数
*/
@ExcelProperty("单位人数")
@ColumnWidth(10)
private Integer company_person_sum;
/**
* 验厂次数
*/
@ExcelProperty("验厂次数")
@ColumnWidth(10)
private Integer check_number;
/**
* 预审扣分
*/
@ExcelProperty("预审扣分")
@ColumnWidth(10)
private Double ys_demerit;
/**
* 验厂通过次数
*/
@ExcelProperty("验厂通过次数")
@ColumnWidth(10)
private Integer check_pass_num;
/**
* 验厂总次数
*/
@ExcelProperty("验厂总次数")
@ColumnWidth(10)
private Integer check_sum;
/**
* 预警得分
*/
@ExcelProperty("预警得分")
@ColumnWidth(10)
private Double opinion_score;
}
接口:
/**
* 导出评分模板
* @param request
* @param response
*/
@SneakyThrows(IOException.class)
@GetMapping("/score/reportExcelTemplate")
public void reportExcelTemplate(HttpServletRequest request, HttpServletResponse response) {
deptCsrScoreService.reportExcelTemplate(request,response);
}
接口实现:
@Override
public void reportExcelTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException {
//查询所有部门
List<DeptLevel> list = deptLevelMapper.findDeptLevelByItem(null,null,null);
List<DeptCsrScoreTemplate> templates = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
DeptCsrScoreTemplate template = new DeptCsrScoreTemplate();
template.setGroup_name(list.get(i).getGroup_name());
template.setCompany_name(list.get(i).getCompany_name());
templates.add(template);
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("UTF-8");
String fileName = URLEncoder.encode("各单位csr评分模板","UTF-8").replaceAll("\\+","%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''"+fileName+".xlsx");
EasyExcel.write(response.getOutputStream())
.head(DeptCsrScoreTemplate.class)
.excelType(ExcelTypeEnum.XLSX)
.sheet("各单位csr评分模板")
.doWrite(templates);
}
完结,至此,导出模板实现,导出数据可以根据前端传进来的查询参数到数据库搜索数据后再按上面的方式,创建数据实体,将数据组装后,调用 EasyExcel.write即可实现导出数据。