黑豹程序员-EasyExcel实现导出

需求

将业务数据导出到excel中,老牌的可以选择POI,也有个新的选择EasyExcel。

有个小坑,客户要求样式比较美观,数字列要求千位符,保留2位小数。

可以用代码实现但非常繁琐,用模板就特别方便,模板定义好格式,填充数据即可。

于是开干!

模板

在项目的src\main\resources\templates,静态模板资源目录下,如果templates不存在,创建即可

settle.xlsx

注意下面的模板格式,填充列表,下面{.name}代表entity对应的字段

修改Entity实体,加控制注解

注意两个注解:

@ExcelIgnore 标识这个字段不会处理

@ExcelProperty("结算金额") 要处理的字段,已经如果写入时,列头的名称

bash 复制代码
package com.rlcloud.system.entity;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @version v1.0 创建时间:2023/11/27 16:36
 * @author: 作者:陈子枢
 * @web CSDN:https://blog.csdn.net/nutony
 * @description 描述:
 */

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_settle")           //映射数据库表
public class Settle {
    //序列化时,不采用long类型,而采用string类型,防止雪花精度丢失问题
    @JsonSerialize(using= ToStringSerializer.class)
    @TableId(type = IdType.ASSIGN_ID)   //主键生成策略,雪花
    @ExcelIgnore
    private Long id;

    @NotNull(message = "结算批次不能为空")
    @ExcelProperty("结算批次")
    private String batch;

    @NotNull(message = "结算日期不能为空")
    @ExcelProperty("结算日期")
    private String dtTimeArr;

    @NotNull(message = "业务量不能为空")
    @ExcelProperty("业务量")
    private BigDecimal volumeAmt;

    @NotNull(message = "结算金额不能为空")
    @ExcelProperty("结算金额")
    private BigDecimal settleAmt;

    @ExcelIgnore
    private String createBy;
    @ExcelIgnore
    private Date createTime;
}

Controller代码

bash 复制代码
    @GetMapping("/ljt/settle/export")
    public void export(HttpServletResponse response) throws IOException {
        QueryWrapper qw = new QueryWrapper();
        qw.orderByDesc("create_time");
        //查询数据
        List<Settle> dataList = settleService.list(qw);

        //此处getResourceAsStream 用于获取服务器打包后的Excel模板文件流;
        //如果采用getPath方法获取文件地址本地ieda环境可以获取到,上传到服务器后会失效。采用流可以都生效,具体原因暂未仔细查看。有兴趣的童鞋可以自己去尝试!
        InputStream resourceAsStream = ResourceUtil.getStream("classpath:templates/settle.xlsx");
        //读取Excel 根据指定模板导出
        ExcelWriter excelWriter = EasyExcel.write(getOutputStream("结算数据.xlsx",response)).withTemplate(resourceAsStream).excelType(ExcelTypeEnum.XLSX).build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();     //关键,多组数据填充需要另起一行,默认为false

        //直接写入Excel数据(list是我查询并需导出的数据,并且里面的字段和excel需要导出的字段对应)
        excelWriter.fill(dataList, fillConfig, writeSheet);     //注意模板中需要写变量{.name}
        excelWriter.finish();
    }

    public static OutputStream getOutputStream(String fileName, HttpServletResponse response)  {
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xls");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e) {
            log.error("导出excel表格失败", e);
        }
        return null;
    }
相关推荐
布朗克16841 分钟前
Java 10 新特性及具体应用
java·开发语言·新特性·java10
ZZHow10244 小时前
JavaWeb开发_Day05
java·笔记·web
CHEN5_024 小时前
【Java虚拟机】垃圾回收机制
java·开发语言·jvm
Warren984 小时前
Lua 脚本在 Redis 中的应用
java·前端·网络·vue.js·redis·junit·lua
艾伦~耶格尔8 小时前
【数据结构进阶】
java·开发语言·数据结构·学习·面试
爪洼传承人8 小时前
18- 网络编程
java·网络编程
smileNicky8 小时前
SpringBoot系列之从繁琐配置到一键启动之旅
java·spring boot·后端
祈祷苍天赐我java之术8 小时前
Java 迭代器(Iterator)详解
java·开发语言
David爱编程9 小时前
为什么必须学并发编程?一文带你看懂从单线程到多线程的演进史
java·后端
我命由我123459 小时前
软件开发 - 避免过多的 if-else 语句(使用策略模式、使用映射表、使用枚举、使用函数式编程)
java·开发语言·javascript·设计模式·java-ee·策略模式·js