Java springboot EasyExcel Excel自定义表头导出demo

一、需求

现有一个业务,需要将列表数据导出excel,并返回给前端。表头有合并、拆分,结构比较复杂,使用EasyExcel将数据导出。这里采用了两种返回方式:导出到本地、直接返回给前端。

二、pom依赖

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

三、创建单行表头实体

package com.example.dto;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * @Author:
 * @Description 表头 需要加@ExcelProperty注解¬
 * @Date: 下午5:25 2023/4/12
 */
@Data
public class ScoreData implements Serializable {

    @ExcelProperty(value = "一年级")
    private Double scoreOne;

    @ExcelProperty(value = "二年级")
    private Double scoreTwo;

    @ExcelProperty(value = "三年级")
    private Double scoreThree;

    @ExcelProperty(value = "四年级")
    private Double scoreFour;

    public ScoreData() {
    }

    public ScoreData(Double scoreOne, Double scoreTwo, Double scoreThree, Double scoreFour) {
        this.scoreOne = scoreOne;
        this.scoreTwo = scoreTwo;
        this.scoreThree = scoreThree;
        this.scoreFour = scoreFour;
    }
}

四、创建多行表头返回实体

package com.example.dto;

import lombok.Data;

import java.io.Serializable;

/**
 * @Author:
 * @Description 二级表头
 * @Date: 下午5:25 2023/4/12
 */
@Data
public class ScoreMergeData implements Serializable {


    /**
     * 序号
     */
    private Integer index;
    /**
     * 小学一年级
     */
    private Double scoreOne;
    /**
     * 小学二年级
     */
    private Double scoreTwo;
    /**
     * 小学三年级
     */
    private Double scoreThree;
    /**
     * 小学四年级
     */
    private Double scoreFour;
    /**
     * 初中一年级
     */
    private Double scoreOne1;
    /**
     * 初中二年级
     */
    private Double scoreTwo1;
    /**
     * 初中三年级
     */
    private Double scoreThree1;
    /**
     * 初中四年级
     */
    private Double scoreFour1;
    /**
     * 大学一年级
     */
    private Double scoreOne2;
    /**
     * 大学二年级
     */
    private Double scoreTwo2;
    /**
     * 大学三年级
     */
    private Double scoreThree2;
    /**
     * 大学四年级
     */
    private Double scoreFour2;

    public ScoreMergeData() {
    }

    public ScoreMergeData(Integer index, Double scoreOne, Double scoreTwo, Double scoreThree, Double scoreFour, Double scoreOne1, Double scoreTwo1, Double scoreThree1, Double scoreFour1, Double scoreOne2, Double scoreTwo2, Double scoreThree2, Double scoreFour2) {
        this.index = index;
        this.scoreOne = scoreOne;
        this.scoreTwo = scoreTwo;
        this.scoreThree = scoreThree;
        this.scoreFour = scoreFour;
        this.scoreOne1 = scoreOne1;
        this.scoreTwo1 = scoreTwo1;
        this.scoreThree1 = scoreThree1;
        this.scoreFour1 = scoreFour1;
        this.scoreOne2 = scoreOne2;
        this.scoreTwo2 = scoreTwo2;
        this.scoreThree2 = scoreThree2;
        this.scoreFour2 = scoreFour2;
    }
}

五、编写service

package com.example.service;

import com.alibaba.excel.EasyExcel;
import com.example.dto.ScoreData;
import com.example.dto.ScoreMergeData;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author:
 * @Description Excel导出
 * @Date: 下午5:30 2023/4/12
 */
@Slf4j
@Service
public class ExcelService {

    //自己修改路径
    private static final String filePath = "/Users/admin/work/2333/excel-demo/excelfiles/";

    /**
     * 最简单样式导出--写到本地
     */
    public static void exportExcelByDto() {
        String fileName = String.format("2023年各年级平均分%s.xlsx", getTimeStr());
        EasyExcel.write(filePath + fileName, ScoreData.class).sheet("各年级平均分").doWrite(getListData());
    }

    /**
     * 自定义表头且有合并导出
     */
    public static void exportExcelMerge() {
        //模拟数据(可以从数据库中查询)
        List<ScoreMergeData> list = Stream.of(new ScoreMergeData(1, 70.9, 80.5, 89.5, 96.7, 70.9, 80.5, 89.5, 96.7, 70.9, 80.5, 89.5, 96.7),
                new ScoreMergeData(2, 40.9, 40.5, 29.5, 76.7, 40.9, 40.5, 29.5, 76.7, 40.9, 40.5, 29.5, 76.7),
                new ScoreMergeData(3, 50.9, 30.5, 19.5, 56.7, 50.9, 30.5, 19.5, 56.7, 50.9, 30.5, 19.5, 56.7),
                new ScoreMergeData(4, 60.9, 70.5, 89.5, 106.7, 60.9, 70.5, 89.5, 106.7, 60.9, 70.5, 89.5, 106.7)).collect(Collectors.toList());
        String fileName = String.format("2023年各年级平均分合并%s.xlsx", getTimeStr());
        EasyExcel.write(filePath + fileName, ScoreMergeData.class).head(dealWithHeads()).sheet("日月湖商品及卡券收入台账").doWrite(list);
    }

    /**
     * 最简单样式导出--响应到浏览器
     * 先将文件写到本地,然后读取文件,返回给前端,最后删除本地文件
     *
     * @param response
     */
    public static void exportExcelByDtoClient(HttpServletResponse response) {
        try {
            String fileName = String.format("2023年各年级平均分%s.xlsx", getTimeStr());
            EasyExcel.write(filePath + fileName, ScoreData.class).sheet("各年级平均分").doWrite(getListData());
            //设置响应头
            setResponseParm(response, fileName);
            ServletOutputStream out = null;
            ByteArrayOutputStream baos = null;
            try {
                File file = new File(filePath + fileName);
                InputStream inStream = new FileInputStream(file);
                byte[] buffer = new byte[1024];
                int len;
                baos = new ByteArrayOutputStream();
                while ((len = inStream.read(buffer)) != -1) {
                    baos.write(buffer, 0, len);
                }
                out = response.getOutputStream();
                out.write(baos.toByteArray());
            } catch (Exception e) {
                log.error("本地文件导出异常{}", e);
                e.printStackTrace();
            } finally {
                baos.flush();
                baos.close();
                out.flush();
                out.close();
                try {
                    //删除本地文件
                    FileUtils.forceDelete(new File(filePath + fileName));
                } catch (IOException e) {
                    log.error("删除本地文件异常{}", e);
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            log.error("文件下载异常{}", e);
            e.printStackTrace();
        }
    }

    /**
     * 最简单样式导出--响应到浏览器
     * 直接返回给前端
     *
     * @param response
     */
    public static void exportExcelByDtoClientNew(HttpServletResponse response) {
        try {
            String fileName = String.format("2023年各年级平均分%s.xlsx", getTimeStr());
            //设置响应头
            setResponseParm(response, fileName);
            EasyExcel.write(response.getOutputStream(), ScoreData.class).sheet("各年级平均分").doWrite(getListData());
        } catch (IOException e) {
            log.error("文件下载异常{}", e);
            e.printStackTrace();
        }
    }

    /**
     * 封装表头
     */
    public static List<List<String>> dealWithHeads() {
        List<List<String>> listParent = new ArrayList<>();
        //第一行 名字重复则自动合并
        listParent.add(Arrays.asList("序号", "小学", "小学", "小学", "小学", "初中", "初中", "初中", "初中", "大学", "大学", "大学", "大学"));
        //第二行
        listParent.add(Arrays.asList("序号", "一年级", "二年级", "三年级", "四年级", "一年级", "二年级", "三年级", "四年级", "一年级", "二年级", "三年级", "四年级"));
        return xzHeadFields(listParent);
    }

    /**
     * 处理表头数据
     *
     * @param headsStr
     * @return
     */
    public static List<List<String>> xzHeadFields(List<List<String>> headsStr) {
        List<List<String>> res = new ArrayList<>();
        for (List<String> str : headsStr) {
            for (int j = 0; j < str.size(); j++) {
                if (res.size() > j) {
                    // 向第j个集合中添加值
                    res.get(j).add(str.get(j));
                } else {
                    // 将集合分割为单个List<String>
                    res.add(new ArrayList<>(Collections.singletonList(str.get(j))));
                }
            }
        }
        return res;
    }

    /**
     * 设置响应头
     *
     * @param response
     * @param fileName
     */
    public static void setResponseParm(HttpServletResponse response, String fileName) {
        try {
            // 设置编码
            response.setCharacterEncoding("UTF-8");
            //设置响应头类型
            response.setContentType("application/application/vnd.ms-excel");
            //设置文件名
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error("设置响应头异常{}", e);
            e.printStackTrace();
        }
    }


    /**
     * 当前时间字符串 用于文件名称
     *
     * @return 返回格式:20230418111613
     */
    public static String getTimeStr() {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        return format.format(new Date());
    }

    /**
     * 模拟数据(可以从数据库中查询)
     *
     * @return
     */
    public static List<ScoreData> getListData() {
        return Stream.of(new ScoreData(70.9, 80.5, 89.5, 96.7),
                new ScoreData(40.9, 40.5, 29.5, 76.7),
                new ScoreData(50.9, 30.5, 19.5, 56.7),
                new ScoreData(60.9, 70.5, 89.5, 106.7)).collect(Collectors.toList());
    }

    /**
     * 本地测试
     *
     * @param args
     */
    public static void main(String[] args) {
        //最简单样式
        exportExcelByDto();
        //表头合并
        exportExcelMerge();

    }

}

六、编写controller

package com.example.api;

import com.example.service.ExcelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

/**
 * @Author:
 * @Description
 * @Date: 下午2:00 2023/4/18
 */
@RestController
@RequestMapping("/excel")
public class ExcelApi {

    @Autowired
    private ExcelService excelService;

    /**
     * 直接输出到前端
     *
     * @param response
     */
    @GetMapping("/export/one")
    public void downloadOne(HttpServletResponse response) {
        excelService.exportExcelByDtoClientNew(response);
    }

    /**
     * 先将文件写到本地,然后读取文件,返回给前端,最后删除本地文件
     *
     * @param response
     */
    @GetMapping("/export")
    public void download(HttpServletResponse response) {
        excelService.exportExcelByDtoClient(response);
    }

}


七、测试

1、直接执行ExcelService中的main方法,将数据保存到本地
2、启动springboot项目,浏览器分别访问http://localhost:8080/excel/exporthttp://localhost:8080/excel/export/one将文件下载下来
结果如下图:
在这里插入图片描述
在这里插入图片描述

八、仓库地址

1、Gitee地址:https://gitee.com/Dev9925/excel-demo
2、GitHub地址:

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Java中的EasyExcel库来实现将数据导出Excel文件。下面是一个简单的示例: 1. 添加EasyExcel依赖 在你的Java项目中,你需要在pom.xml文件中添加EasyExcel的依赖: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.6</version> </dependency> ``` 2. 创建Excel文件 ```java // 定义Excel文件路径和名称 String fileName = "demo.xlsx"; String filePath = "D:\\excel\\"; // 定义Excel表头 List<List<String>> head = new ArrayList<>(); head.add(Arrays.asList("姓名", "年龄", "性别")); // 定义Excel数据 List<Person> dataList = new ArrayList<>(); dataList.add(new Person("张三", 20, "男")); dataList.add(new Person("李四", 22, "女")); dataList.add(new Person("王五", 25, "男")); // 写入Excel文件 EasyExcel.write(filePath + fileName) .head(head) .sheet("Sheet1") .doWrite(dataList); ``` 3. 定义数据模型 在上面的示例中,我们使用了一个Person类来表示Excel中的一行数据。你需要定义一个类来表示你要导出Excel文件中的数据。 ```java public class Person { private String name; private Integer age; private String gender; // 省略getter和setter方法 } ``` 这个类的属性与Excel文件中的列是一一对应的。 4. 运行代码 运行上面的代码,你会在指定的文件夹中看到一个名为demo.xlsx的Excel文件,其中包含了我们定义的表头和数据。 这是一个简单的通过Java使用EasyExcel将数据导出Excel文件的示例。你可以根据自己的需要来修改代码来实现更加复杂的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值