业务场景
最近的工作中,会比较频繁的使用到导出功能,封装工具类后,通过简单的模板创建,就可以实现导出业务:
一、环境配置
pom引入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version> 1.2.83</version>
</dependency>
二、工具类创建
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map;
/**
* 使用com.alibaba.easyexcel导出excel
*/
public class TemplateExcelUtil {
/**
* 导出excel
* @param response controller方法入参response
* @param fileName 导出文件名称
* @param filePath excel模板路径
* @param map 数据map
* @param list 数据集合list
* @throws IOException
*/
public static void templateExcelExport(HttpServletResponse response, String fileName,String filePath, Map<String, Object> map, List<?> list) throws IOException {
//1.response设置
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码
response.setHeader("Content-disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
//2.获取文件下载输出流
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
//3.获取模板文件输出流
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources(filePath);
Resource resource = resources[0];
boolean exists = resource.exists();
System.out.println(exists);
//获得文件流,因为在jar文件中,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流
InputStream is = resource.getInputStream();
//4.读取Excel
ExcelWriter excelWriter = EasyExcel.write(bos).withTemplate(is).excelType(ExcelTypeEnum.XLSX).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
//5.填充数据
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
//填充 list 数据
excelWriter.fill(list, fillConfig, writeSheet);
// 填充 map 数据
excelWriter.fill(map, writeSheet);
excelWriter.finish();
bos.flush();
//6.关闭流
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 导出excel
* @param response controller方法入参response
* @param fileName 导出文件名称
* @param filePath excel模板路径
* @param map 数据map
* @param list 数据集合list
* @throws IOException
*/
public static void templatePdfExport(HttpServletResponse response, String fileName,String filePath, Map<String, Object> map, List<?> list) throws IOException {
//1.response设置
response.setContentType("application/pdf");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码
response.setHeader("Content-disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
//2.获取文件下载输出流
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
//3.获取模板文件输出流
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources(filePath);
Resource resource = resources[0];
boolean exists = resource.exists();
System.out.println(exists);
//获得文件流,因为在jar文件中,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流
InputStream is = resource.getInputStream();
//4.读取Excel
ExcelWriter excelWriter = EasyExcel.write(bos).withTemplate(is).excelType(ExcelTypeEnum.XLSX).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
//5.填充数据
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
//填充 list 数据
excelWriter.fill(list, fillConfig, writeSheet);
// 填充 map 数据
excelWriter.fill(map, writeSheet);
excelWriter.finish();
bos.flush();
//6.关闭流
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 导出excel
* @param filePath excel模板路径
* @param map 数据map
* @param list 数据集合list
* @throws IOException
*/
public static File templateExcelGenerate(String filePath, Map<String, Object> map, List<?> list) throws IOException {
File file = new File("sample.xlsx");
//3.获取模板文件输出流
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources(filePath);
Resource resource = resources[0];
boolean exists = resource.exists();
System.out.println(exists);
//获得文件流,因为在jar文件中,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流
InputStream is = resource.getInputStream();
//4.读取Excel
ExcelWriter excelWriter = EasyExcel.write(file).withTemplate(is).excelType(ExcelTypeEnum.XLSX).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
//5.填充数据
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
//填充 list 数据
excelWriter.fill(list, fillConfig, writeSheet);
// 填充 map 数据
excelWriter.fill(map, writeSheet);
excelWriter.finish();
//6.关闭流
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
}
三、模板创建(表中表样式:表中嵌套列表)
四、测试类demo
@PostMapping("/ExportLe05VO")
@ApiOperation(value = "excel导出", notes = "excel导出", response = ExportLe05VO.class)
public void ExportLe05(@RequestBody @Valid ExportDTO dto, HttpServletResponse response, HttpServletRequest request) throws IOException {
// 数据源查询
ExportLe05VO vo = dyPlanBpo.Le05CompanyExcel(dto);
if(ObjectUtil.isEmpty(vo)){
throw new BusinessException("当前业务批次号数据不存在");
}
//拼凑文档参数
Map<String, Object> dataMap = new HashMap<String, Object>();
// list 对应是模板中 {.字段名}格式数据
List<Le05ListVO> list = vo.getList();
// dataMap对应的是模板中 {字段名}格式
dataMap.put("aaz654", vo.getAaz654());
dataMap.put("peopleNumTotalAll", vo.getPeopleNumTotalAll());
dataMap.put("aae019TotalAll", vo.getAae019TotalAll());
dataMap.put("ywjb00", Optional.ofNullable(vo.getYwjb00()).orElse(""));
dataMap.put("ywfh00", Optional.ofNullable(vo.getYwfh00()).orElse(""));
dataMap.put("cwjb00", Optional.ofNullable(vo.getCwjb00()).orElse(""));
dataMap.put("cwfh00", Optional.ofNullable(vo.getCwfh00()).orElse(""));
dataMap.put("bbrq00", vo.getBbrq00());
dataMap.put("dyrq00", vo.getDyrq00());
dataMap.put("aab360", vo.getAab360());
TemplateExcelUtil.templateExcelExport(response,"XXX表.xlsx","template/thybjj.xlsx",dataMap,list);
}
五、小结
关于模板
1、在使用过程中,由于数据的长度,生成的行可能不会自动合并,所以模板构建的过程需要考虑到list遍历后生成的行格式,尽可能把数据项都用单行构建,这样生成的excel格式会相对整齐
2、数据方面,生成的数据默认情况下会自动取整,我们可以在创建模板的过程中,对特殊字段的单元格进行格式设置,如常用的金额类,可以参考一下设置等。
尾言
以上便是alibaba.excel.EasyExcel的简单使用总结,后续的相关经验也会同步到文档上,感谢阅读。
0725补充-jar包冲突问题、maven help插件引入
1、问题场景
最近笔者项目运行过程中发现这样的问题,上述的模板导出简易做成工具类在使用的过程中,出现如下异常:
2、分析与处理
(1)后面发现 EasyExcel底层也是使用了apache/poi,后面用了 idea 的插件 Maven Help
(2)安装后重启idea,打开项目的pom.xml文件后,在底部会多出一个Dependency Analyzer选项,点开这个选项刷新,找到冲突,点击右键,然后选择Exclude即可排除冲突版本的Jar包。显示No conflicts这个异常就处理好了。