package com.sckw.excel.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ServiceException;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.constant.NumberConstant;
import com.sckw.core.model.enums.DictItemEnum;
import com.sckw.core.model.enums.FileEnum;
import com.sckw.core.utils.FileUtils;
import com.sckw.core.web.response.HttpResult;
import com.sckw.excel.annotation.ExcelContext;
import com.sckw.excel.annotation.ExcelSelected;
import com.sckw.excel.config.easyexcel.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;


/**
 * 封装easyexcel
 *
 * @author LengFaQiang
 * @version v1
 * @create 2020-09-24 10:15:49
 * @copyright
 */
@Slf4j
public class ExcelUtil {
    /**
     * 数据导出
     *
     * @param response
     * @param clazz
     * @param data
     * @param <T>
     */
    public static <T> void downData(HttpServletResponse response, Class<T> clazz, List<T> data) {
        Assert.notNull(clazz, "clazz can't be null");
        Assert.isTrue(data != null && !data.isEmpty(), "data can't be empty");
        try {
            ExcelContext excelContext = clazz.getAnnotation(ExcelContext.class);
            buildResponse(response, excelContext.fileName());
            EasyExcel.write(response.getOutputStream(), clazz)
                    .autoCloseStream(Boolean.FALSE)
                    .registerConverter(new LongStringConverter())
                    //设置导出excel的单元格格式为文本
                    .registerWriteHandler(new RowWriteHandlerImpl())
                    // 自定义列宽、行高
                    .registerWriteHandler(new CustomCellWeightWeightConfig())
                    .sheet(excelContext.sheetName()).doWrite(data);
        } catch (Exception e) {
            buildResponse(response, e);
        }
    }

    public static <T> void download(HttpServletResponse response, Class<T> clazz, List<T> data) {
//        StaticComponentContainer.Modules.exportAllToAll();
        Assert.notNull(clazz, "clazz can't be null");
        Assert.isTrue(data != null && !data.isEmpty(), "data can't be empty");
        try {
            ExcelContext excelContext = clazz.getAnnotation(ExcelContext.class);
            buildResponse(response, excelContext.fileName());
            EasyExcel.write(response.getOutputStream(), clazz)
                    .registerConverter(new LocalDateTimeConverter())
                    .registerWriteHandler(new RowWriteHandlerImpl())
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .autoCloseStream(Boolean.FALSE).sheet(excelContext.sheetName())
                    .doWrite(data);
        } catch (Exception e) {
            buildResponse(response, e);
        }
    }

    public static void download(HttpServletResponse response, List<List> source) {
        Assert.isTrue(source != null && source.size() > 0, "source can't be empty");
        ExcelWriter excelWriter = null;
        try {
            String fileName = source.get(NumberConstant.ZERO).get(NumberConstant.ZERO).getClass().getAnnotation(ExcelContext.class).fileName();
            buildResponse(response, fileName);
            excelWriter = EasyExcel.write(response.getOutputStream())
                    .registerConverter(new LocalDateTimeConverter())
                    .registerWriteHandler(new RowWriteHandlerImpl())
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .autoCloseStream(Boolean.FALSE).build();
            for (int i = 0; i < source.size(); i++) {
                List list = source.get(i);
                //Assert.isTrue(!CollectionUtils.isEmpty(list), "source can't be empty");
                if (CollectionUtils.isEmpty(list)) {
                    continue;
                }
                Class<?> clazz = list.get(NumberConstant.ZERO).getClass();
                ExcelContext context = clazz.getAnnotation(ExcelContext.class);
                WriteSheet writeSheet = EasyExcel.writerSheet(i, context.sheetName()).registerWriteHandler(new RowWriteHandlerImpl()).head(clazz).build();
                excelWriter.write(list, writeSheet);
            }
        } catch (Exception e) {
            buildResponse(response, e);
        } finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }

    }

    private static void buildResponse(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
        fileName = URLEncoder.encode(fileName + "-" + DateUtil.localDateTimeToString(LocalDateTime.now()), "UTF-8").replaceAll("\\+", "%20");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
        //下面 浏览器下载正常，但是postman下载文件名称乱码
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        //下面这是用postman测名称正常，换到浏览器会多了filename_=utf-8等字样。。）
//        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")+ ".xlsx" + ";filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8")+ ".xlsx");
    }

    private static void buildResponse(HttpServletResponse response, Exception e) {
        StackTraceElement[] stackTrace = e.getStackTrace();
        log.error("Failed to export data. -> {}", String.valueOf(stackTrace[0]) + stackTrace[1] + stackTrace[2], e);
        //response.reset();
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        try (PrintWriter writer = response.getWriter()) {
            writer.println(JSONObject.toJSONString(HttpResult.error("导出数据失败, " + e.toString())));
        } catch (Exception ignored) {
        }
    }

    /**
     * 判断是否是excel
     *
     * @param file 文件
     * @return 获取结果
     */
    public static boolean checkExcel(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        String match1 = "^.+\\.(?i)(xls)$";
        String match2 = "^.+\\.(?i)(xlsx)$";
        return !fileName.matches(match1) && !fileName.matches(match2);
    }

    /**
     * 导出单元格内容含有下拉框的excel 需要使用@ExcelSelected在对应字段上设置字段的下拉框的值
     *
     * @param response
     * @param source
     */
    public static void writeSelectedSheet(HttpServletResponse response, List<List> source) {
        Assert.isTrue(source != null && source.size() > 0, "source can't be empty");
        ExcelWriter excelWriter = null;
        try {
//            String fileName = source.get(ZERO).get(ZERO).getClass().getAnnotation(ExcelContext.class).fileName();
            String fileName = source.get(NumberConstant.ZERO).get(NumberConstant.ZERO).getClass().getAnnotation(ExcelContext.class).fileName();
            buildResponse(response, fileName);
            excelWriter = EasyExcel.write(response.getOutputStream())
                    .registerConverter(new LocalDateTimeConverter())
                    .registerWriteHandler(new RowWriteHandlerImpl())
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .autoCloseStream(Boolean.FALSE).build();
            for (int i = 0; i < source.size(); i++) {
                List list = source.get(i);
                //Assert.isTrue(!CollectionUtils.isEmpty(list), "source can't be empty");
                if (CollectionUtils.isEmpty(list)) {
                    continue;
                }
                Class<?> clazz = list.get(NumberConstant.ZERO).getClass();
                ExcelContext context = clazz.getAnnotation(ExcelContext.class);
                Map<Integer, ExcelSelectedResolve> selectedMap = resolveSelectedAnnotation(clazz);
                WriteSheet writeSheet = EasyExcel.writerSheet(i, context.sheetName()).head(clazz).registerWriteHandler(new RowWriteHandlerImpl()).registerWriteHandler(new SelectedSheetWriteHandler(selectedMap)).build();
                excelWriter.write(list, writeSheet);
            }
        } catch (Exception e) {
            buildResponse(response, e);
        } finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }

    }


    /**
     * 每个sheet的容量，即超过60000时就会把数据分sheet
     */
    private static final int PAGE_SIZE = 60000;


    /**
     * 导出报表(使用注解方式设置Excel头数据)
     * 用于生成excel文件流并上传oss
     *
     * @param response   响应请求
     * @param data       报表数据
     * @param fileName   文件名字
     * @param excelClass 报表实体类的Class（根据该Class的属性来设置Excel的头属性）
     */
    public static String exportByExcelUploadingToOss(HttpServletResponse response, List<?> data, String fileName, Class<?> excelClass) throws IOException {
        @Cleanup ByteArrayOutputStream os = new ByteArrayOutputStream();
        //log.info("报表导出Size: " + data.size() + "条。");
        String sheetName = excelClass.getAnnotation(ExcelContext.class).sheetName();
        // 把查询到的数据按设置的sheet的容量进行切割
        List<? extends List<?>> lists = com.sckw.core.utils.StringUtils.splitList(data, PAGE_SIZE);
        // 设置响应头
        ExcelUtil.setHead(response, fileName, excelClass);
        // 格式化Excel数据
        // EasyExcelBasic.formatExcel()：设置Excel的格式
        // EasyExcelBasic.ExcelWidthStyleStrategy():设置头部单元格宽度
        ExcelWriter excelWriter = com.alibaba.excel.EasyExcel.write(os, excelClass)
                .autoCloseStream(Boolean.FALSE)
                .registerConverter(new LongStringConverter())
                //设置导出excel的单元格格式为文本
                .registerWriteHandler(new RowWriteHandlerImpl())
                // 自定义列宽、行高
                .registerWriteHandler(new CustomCellWeightWeightConfig())
//                .registerWriteHandler(formatExcel())
                .registerWriteHandler(new ExcelUtil.ExcelWidthStyleStrategy()).build();

        // 浏览器访问url直接下载文件的方式
        //ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), excelClass).registerWriteHandler(com.example.utils.easyexcel.EasyExcel.formatExcel()).registerWriteHandler(new com.example.utils.easyexcel.EasyExcel.ExcelWidthStyleStrategy()).build();

        ExcelWriterSheetBuilder excelWriterSheetBuilder;
        WriteSheet writeSheet;
        for (int i = 1; i <= lists.size(); ++i) {
            excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
            excelWriterSheetBuilder.sheetNo(i).sheetName(sheetName/* + i*/);
            writeSheet = excelWriterSheetBuilder.build();
            excelWriter.write(lists.get(i - 1), writeSheet);
        }
        // 必须要finish才会写入，不finish只会创建empty的文件
        excelWriter.finish();

        byte[] content = os.toByteArray();
        @Cleanup InputStream is = new ByteArrayInputStream(content);

        // 文件落地，
        // @Cleanup:lombok关用来测试文件的格式和数据的完整性流注解
        //FileOutputStream fileOutputStream = new FileOutputStream("/data/logs/" + fileName + ".xlsx");
        //@Cleanup BufferedInputStream bis = new BufferedInputStream(is);
        //@Cleanup BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
        //byte[] buff = new byte[2048];
        //int bytesRead;
        //while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
        //    bos.write(buff, 0, bytesRead);
        // }
        //log.info("文件落地磁盘");


        // 文件上传到OSS
        Map<String, String> map = FileUtils.uploadFileByInfo(is, fileName, FileEnum.FILE_STORE_TYPE_ALIYUN);
//        System.out.println(com.alibaba.fastjson2.JSONObject.toJSONString(map));
        String ossAddressPrefix = FileUtils.getOSSAddressPrefix();
        if (map != null && (map.get("filePath") != null)) {
            ossAddressPrefix = ossAddressPrefix + map.get("filePath");
        }
        return ossAddressPrefix;
    }

    /**
     * 设置响应头
     *
     * @param response 回应的请求数据
     * @param fileName 文件名字
     */
    public static void setHead(HttpServletResponse response, String fileName, Class<?> excelClass) {
        ExcelContext excelContext = excelClass.getAnnotation(ExcelContext.class);
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        try {
            // 这里URLEncoder.encode可以防止中文乱码
            buildResponse(response, excelContext.fileName());
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("编码异常");
        }
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

    }

    /**
     * 设置Excel的格式
     *
     * @return 格式化后的Excel
     */
    public static HorizontalCellStyleStrategy formatExcel() {
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setFillBackgroundColor(IndexedColors.WHITE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 10);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 10);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 设置自动换行
        contentWriteCellStyle.setWrapped(true);
        // 设置垂直居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 设置水平居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

    }

    /**
     * 设置头部单元格宽度
     */
    public static class ExcelWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {

        @Override
        protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
            // 设置宽度
            Sheet sheet = writeSheetHolder.getSheet();
            sheet.setColumnWidth(cell.getColumnIndex(), 5000);
        }
    }

    //    private static void buildResponse(HttpServletResponse response, String fileName,HttpServletRequest request) throws UnsupportedEncodingException {
//        response.reset();
//        response.setContentType("application/octet-stream");
//        response.setCharacterEncoding("utf-8");
//        //解决不同浏览器压缩包名字含有中文时乱码的问题
//        String agent = request.getHeader("USER-AGENT");
//        try {
//            if (agent.contains("MSIE") || agent.contains("Trident")) {
//                fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
//            } else {
//                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        fileName = URLEncoder.encode(fileName + "-" + DateUtil.dateToStr(LocalDate.now()), "UTF-8").replaceAll("\\+", "%20");
//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("UTF-8");
////        response.setHeader("Content-Disposition",String.format("attachment; filename=\"%s\"", fileName));
//        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//    }

//    private static void buildResponse(HttpServletResponse response, String fileName, HttpServletRequest request) throws IOException {
//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("utf-8");
//        // 这里URLEncoder.encode可以防止中文乱码，所有通过后端的文件下载都可以如此处理
//        fileName = URLEncoder.encode(fileName, "UTF-8");
//        //建议加上该段，否则可能会出现前端无法获取Content-disposition
//        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
//        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
////        EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
//    }

    /**
     * 解析表头类中的下拉注解
     *
     * @param head 表头类
     * @param <T>  泛型
     * @return Map<下拉框列索引, 下拉框内容> map
     */
    private static <T> Map<Integer, ExcelSelectedResolve> resolveSelectedAnnotation(Class<T> head) {
        Map<Integer, ExcelSelectedResolve> selectedMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);

        // getDeclaredFields(): 返回全部声明的属性；getFields(): 返回public类型的属性
        Field[] fields = head.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            // 解析注解信息
            ExcelSelected selected = field.getAnnotation(ExcelSelected.class);
            ExcelProperty property = field.getAnnotation(ExcelProperty.class);
            if (selected != null) {
                ExcelSelectedResolve excelSelectedResolve = new ExcelSelectedResolve();
                String[] source = excelSelectedResolve.resolveSelectedSource(selected);
                if (source != null && source.length > 0) {
                    excelSelectedResolve.setSource(source);
                    excelSelectedResolve.setFirstRow(selected.firstRow());
                    excelSelectedResolve.setLastRow(selected.lastRow());
                    if (property != null && property.index() >= 0) {
                        selectedMap.put(property.index(), excelSelectedResolve);
                    } else {
                        selectedMap.put(i, excelSelectedResolve);
                    }
                }
            }
        }

        return selectedMap;
    }

    /**
     * 导出Excel返回FileInputStream
     */
    public static FileInputStream exportExcelStream(Class<?> clazz, List<?> list) {
        try {
            // 临时目录 临时文件名
            String tmp = System.getProperty("java.io.tmpdir");
            String fileName = String.valueOf(new Date().getTime());
            File file = new File(tmp + fileName + ".xlsx");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            ExcelWriter excelWriter = EasyExcel.write(fileOutputStream)
                    .registerWriteHandler(new CustomCellWeightWeightConfig())
                    .registerWriteHandler(new RowWriteHandlerImpl())
                    .registerWriteHandler(new ExcelStyleHandler())
                    .build();
            WriteSheet writeSheet = EasyExcel.writerSheet(1, fileName).head(clazz).build();
            excelWriter.write(list, writeSheet);
            excelWriter.finish();
            return new FileInputStream(file);
        } catch (Exception e) {
            throw new ServiceException("导出Excel异常");
        }
    }


    public static <T> MultipartFile exportReturnToFileNew(List<T> data, Class<T> clazz, HttpServletResponse response) throws IOException {
        Assert.notNull(clazz, "clazz can't be null");
        Assert.isTrue(data != null && !data.isEmpty(), "data can't be empty");
        ExcelContext excelContext = clazz.getAnnotation(ExcelContext.class);
        buildResponse(response, excelContext.fileName());
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        EasyExcel.write(byteArrayOutputStream)
                .autoCloseStream(Boolean.FALSE)
                .registerConverter(new LongStringConverter())
                //设置导出excel的单元格格式为文本
                .registerWriteHandler(new RowWriteHandlerImpl())
                // 自定义列宽、行高
                .registerWriteHandler(new CustomCellWeightWeightConfig())
                .sheet(excelContext.sheetName())
                .doWrite(data);

        MultipartFile file = new MockMultipartFile("file", excelContext.sheetName() + ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", byteArrayOutputStream.toByteArray());
//        String fileName = URLEncoder.encode(excelContext.fileName() + "-" + DateUtil.localDateTimeToString(LocalDateTime.now()), "UTF-8").replaceAll("\\+", "%20");
//        MultipartFile multipartFile = new MockMultipartFile("file", fileName + ".xlsx",
//                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
//                byteArrayOutputStream.toByteArray());
        return file;
    }

    /**
     * 默认样式策略策略
     *
     * @return
     */
    private static HorizontalCellStyleStrategy defaultStylePolicyPolicy() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为浅蓝色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        //设置水平对齐方式
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //设置字体为微软雅黑
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("宋体");
        headWriteCellStyle.setWriteFont(headWriteFont);

        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //设置字体为微软雅黑
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontName("宋体");
        contentWriteCellStyle.setWriteFont(contentWriteFont);

        // 这个策略是 头是头的样式 内容是内容的样式
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

    public static <T> File exportReturnToFile(List<T> data, Class<T> clazz, String fileName) {
        File file = null;
        //名称拆分前后缀
        //1.判断文件名是否有扩展
        try {
            if (StringUtils.isBlank(fileName)) {
                file = File.createTempFile(fileName, "");
            } else {
                String[] parts = fileName.split("\\.");
                String extension = "." + parts[parts.length - 1];
                String name = fileName.substring(0, fileName.length() - extension.length() - 1);
                file = File.createTempFile(name, extension);
            }
        } catch (IOException e) {
            log.error("文件生成失败,文件名异常.异常信息:{}", e.getMessage());
            throw new BusinessException("文件生成失败,文件名异常");
        }

        HorizontalCellStyleStrategy horizontalCellStyleStrategy = defaultStylePolicyPolicy();

        //导出
        EasyExcel.write(file, clazz)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .registerWriteHandler(horizontalCellStyleStrategy)
                .sheet()
                .doWrite(data);
        return file;
    }

    /**
     * 导出报表(使用注解方式设置Excel头数据)
     * 用于生成excel文件流并上传oss
     *
     * @param data       报表数据
     * @param fileName   文件名字
     * @param excelClass 报表实体类的Class（根据该Class的属性来设置Excel的头属性）
     */
    public static String taskExportByExcelUploadingToOss(Map<String,List<Object>> listData,List<?> data, String fileName, Class<?> excelClass,List<String> listHead) throws IOException {
        List<List<String>> listTitle = new ArrayList<>();
        //List<String> head = new ArrayList<>();
        //head.add("ts");
        //listTitle.add(head);
        for(int k=0;k<listHead.size();k++){
            List<String> head1 = new ArrayList<>();
            if(Objects.isNull(DictItemEnum.getName(listHead.get(k)))){
                head1.add(listHead.get(k));
            }else{
                head1.add(DictItemEnum.getName(listHead.get(k)));
            }

            listTitle.add(head1);
        }
        //listTitle.add(listHead);
        @Cleanup ByteArrayOutputStream os = new ByteArrayOutputStream();
        ExcelWriter excelWriter = com.alibaba.excel.EasyExcel.write(os, excelClass)
                .autoCloseStream(Boolean.FALSE)
                .registerConverter(new LongStringConverter())
                //设置导出excel的单元格格式为文本
                .registerWriteHandler(new RowWriteHandlerImpl())
                // 自定义列宽、行高
                .registerWriteHandler(new CustomCellWeightWeightConfig())
                .head(listTitle)
//                .registerWriteHandler(formatExcel())
                .registerWriteHandler(new ExcelUtil.ExcelWidthStyleStrategy()).build();
        List<List<Object>> list = new ArrayList<>();

        for (String key : listData.keySet()) {
            String sheetName = key;
            List<Object> getData = listData.get(key);

            ExcelWriterSheetBuilder excelWriterSheetBuilder;
            WriteSheet writeSheet;
            excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
            excelWriterSheetBuilder.sheetName(sheetName);
            writeSheet = excelWriterSheetBuilder.build();
            excelWriter.write(getData, writeSheet);

        }
        // 必须要finish才会写入，不finish只会创建empty的文件
        excelWriter.finish();
        //String sheetName = excelClass.getAnnotation(ExcelContext.class).sheetName();
        byte[] content = os.toByteArray();
        @Cleanup InputStream is = new ByteArrayInputStream(content);

        // 文件上传到OSS
        Map<String, String> map = FileUtils.uploadFileByInfo(is, fileName, FileEnum.FILE_STORE_TYPE_ALIYUN);
        System.out.println(com.alibaba.fastjson2.JSONObject.toJSONString(map));
        String ossAddressPrefix = FileUtils.getOSSAddressPrefix();
        if (map != null && (map.get("filePath") != null)) {
            ossAddressPrefix = ossAddressPrefix + map.get("filePath");
        }
        return ossAddressPrefix;
    }


}