ceshi

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 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> dealWithHeads() {
        List> listParent = new ArrayList<>();
        //第一行 名字重复则自动合并
        listParent.add(Arrays.asList("序号", "小学", "小学", "小学", "小学", "初中", "初中", "初中", "初中", "大学", "大学", "大学", "大学"));
        //第二行
        listParent.add(Arrays.asList("序号", "一年级", "二年级", "三年级", "四年级", "一年级", "二年级", "三年级", "四年级", "一年级", "二年级", "三年级", "四年级"));
        return xzHeadFields(listParent);
    }

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

    }

}

你可能感兴趣的:(java)