EasyExcel实现excel导出(多sheet)

本文介绍了EasyExcel,一个阿里巴巴开源的轻量级Excel处理框架,它通过逐行解析避免内存溢出,演示了如何在SpringBoot应用中进行模板填充式Excel导出,包括依赖引入、数据准备和实际操作步骤。
摘要由CSDN通过智能技术生成

EasyExcel官方地址:

EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy ExcelEasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。https://easyexcel.opensource.alibaba.com/

EasyExcel简介

Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或 者JVM频繁的full gc。
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一 行行读取数据,逐个解析。
EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理 (AnalysisEventListener)

SpringBoot整合easyexcel

easyexcel提供读、写、填充三种功能。这里我们采用模板填充的方式实现excel导出。

1.引入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.0</version>
</dependency>

2.模板文件

 我们将模板excel放在resource下:

3.数据准备

4.数据传输对象

@Data
public class FtBranchDTO {
    /**
     * 部门名称
     */
    private String branchName;
    /**
     * 部门人数
     */
    private Integer branchPeople;
    /**
     * 部门电话
     */
    private String branchPhone;
    /**
     * 部门经理
     */
    private String branchManager;
    /**
     * 部门考评
     */
    private String branchGrade;
}

@Data
public class FtUserDTO {
    /**
     * 用户名称
     */
    private String name;
    /**
     * 用户年龄
     */
    private Integer age;
    /**
     * 用户手机号
     */
    private String phone;
    /**
     * 性别
     */
    private String sex;
    /**
     * 成绩
     */
    private BigDecimal grade;
}

@Data
public class GradeAvgDTO {
    /**
     * 员工平均分
     */
    private BigDecimal userAverage;
}

@Data
public class PeopleSumDTO {
    /**
     * 公司总人数
     */
    private Integer sum;
}

 4.导出excel

@Slf4j
@RestController
@RequestMapping("/excelExport")
public class ExcelExportController {
    
    @Autowired
    private FtUserService ftUserService;

    @Autowired
    private FtBranchService ftBranchService;

    @GetMapping
    public void excelExport(HttpServletResponse response){
        //员工信息  平均成绩
        List<FtUserEntity> ftUserEntities = ftUserService.list();
        List<FtUserDTO> ftUserDTOS = ftUserEntities.stream().map(ftUserEntity -> {
            FtUserDTO ftUserDTO = new FtUserDTO();
            BeanUtils.copyProperties(ftUserEntity,ftUserDTO);
            return ftUserDTO;
        }).collect(Collectors.toList());
        GradeAvgDTO gradeAvgDTO = ftUserService.getAverageGrade();
        //部门信息 员工总数
        List<FtBranchEntity> ftBranchEntities = ftBranchService.list();
        List<FtBranchDTO> ftBranchDTOS = ftBranchEntities.stream().map(ftBranchEntity -> {
            FtBranchDTO ftBranchDTO = new FtBranchDTO();
            BeanUtils.copyProperties(ftBranchEntity,ftBranchDTO);
            return ftBranchDTO;
        }).collect(Collectors.toList());
        PeopleSumDTO peopleSumDTO =  ftBranchService.getPeopleSum();

        //获取模板(模板你可以放在任何位置,前提是你能获取到。这里放在resource下)
        ClassPathResource couponOrderTemplateResource = new ClassPathResource("userInfo.xlsx");

        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String excelFileName = URLEncoder.encode("公司信息", StandardCharsets.UTF_8)
                .replaceAll("\\+", "%20");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        // attachment这个代表要下载的,如果去掉就直接打开了(attachment-作为附件下载,inline-在线打开)
        // excelFileName是文件名,另存为或者下载时,为默认的文件名
        response.setHeader("Content-disposition","attachment;filename=" + excelFileName + ".xlsx");
        response.setHeader("Content-Type","application/octet-stream;charset=utf-8");

        InputStream templateInputStream = null;
        ExcelWriter excelWriter = null;
        WriteSheet userSheet = null;
        WriteSheet branchSheet = null;
        ServletOutputStream outputStream = null;

        try {
            outputStream = response.getOutputStream();
            templateInputStream = couponOrderTemplateResource.getInputStream();
        } catch (IOException e) {
            log.error("获取模板失败");
        }

        // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。
        // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
        // 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
        // 如果数据量大 list不是最后一行 参照下一个
        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
        excelWriter = EasyExcel.write(outputStream).withTemplate(templateInputStream).build();

        //创建第一个sheet
        userSheet = EasyExcel.writerSheet("员工信息").build();
        //填充
        excelWriter.fill(ftUserDTOS,fillConfig,userSheet);//员工基础信息
        excelWriter.fill(gradeAvgDTO,userSheet);//员工平均成绩
        //创建第二个sheet
        branchSheet = EasyExcel.writerSheet("部门信息").build();
        //填充
        excelWriter.fill(ftBranchDTOS,fillConfig,branchSheet);//部门基础信息
        excelWriter.fill(peopleSumDTO,branchSheet);//总人数

        //关闭
        excelWriter.finish();
        IOUtils.closeQuietly(templateInputStream);
        IOUtils.closeQuietly(outputStream);
        IOUtils.closeQuietly(excelWriter);
    }
}

5.测试excel导出

 

效果图如下: 

  • 14
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在EasyExcel中读取多个sheet,你可以使用以下步骤: 1. 导入EasyExcel库: ```java import com.alibaba.excel.EasyExcel; ``` 2. 创建一个类来存储从Excel文件中读取的数据: ```java public class SheetData { // 声明你需要存储的数据字段 // ... } ``` 3. 创建一个实现`AnalysisEventListener`接口的类来处理Excel中的数据: ```java public class SheetDataListener extends AnalysisEventListener<SheetData> { private List<SheetData> dataList = new ArrayList<>(); @Override public void invoke(SheetData data, AnalysisContext context) { dataList.add(data); // 将每行数据添加到列表中 } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 数据解析完成后的操作,可以在这里进行后续处理 } public List<SheetData> getDataList() { return dataList; } } ``` 4. 使用EasyExcel读取Excel文件的多个sheet: ```java String fileName = "path/to/your/excel/file.xlsx"; SheetDataListener listener = new SheetDataListener(); EasyExcel.read(fileName, SheetData.class, listener).sheet().doRead(); List<SheetData> dataList = listener.getDataList(); // 处理读取的数据 // ... ``` 在上面的代码中,你需要将`path/to/your/excel/file.xlsx`替换为你实际的Excel文件路径。`SheetData`类应该根据你的实际需求进行定义,并且包含需要读取的字段。 通过这种方式,你可以使用EasyExcel库轻松地读取Excel文件中的多个sheet。希望对你有所帮助!如果有任何问题,请随时向我提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值