业务场景

最近的工作中,会比较频繁的使用到导出功能,封装工具类后,通过简单的模板创建,就可以实现导出业务:

一、环境配置

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;
    }

}

三、模板创建(表中表样式:表中嵌套列表)

templates导出excel样式 导出excel模板_阿里云

四、测试类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、数据方面,生成的数据默认情况下会自动取整,我们可以在创建模板的过程中,对特殊字段的单元格进行格式设置,如常用的金额类,可以参考一下设置等。

templates导出excel样式 导出excel模板_java_02

尾言

以上便是alibaba.excel.EasyExcel的简单使用总结,后续的相关经验也会同步到文档上,感谢阅读。



0725补充-jar包冲突问题、maven help插件引入

1、问题场景

最近笔者项目运行过程中发现这样的问题,上述的模板导出简易做成工具类在使用的过程中,出现如下异常:

templates导出excel样式 导出excel模板_excel_03

2、分析与处理

(1)后面发现 EasyExcel底层也是使用了apache/poi,后面用了 idea 的插件 Maven Help

templates导出excel样式 导出excel模板_excel_04


(2)安装后重启idea,打开项目的pom.xml文件后,在底部会多出一个Dependency Analyzer选项,点开这个选项刷新,找到冲突,点击右键,然后选择Exclude即可排除冲突版本的Jar包。显示No conflicts这个异常就处理好了。

templates导出excel样式 导出excel模板_spring boot_05


templates导出excel样式 导出excel模板_templates导出excel样式_06