package com.zcxk.core.utils.export;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
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.fastjson.JSON;
import com.zcxk.core.common.pojo.AjaxMessage;
import com.zcxk.core.utils.DateUtil;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * @ClassName EasyExcelUtil
 * @Description: Excel导出通用工具类
 * @Author :Andy
 * @Date 2021/7/20
 * @Version V1.0
 **/
public  class EasyExcelUtil {

    /**
    * 仅仅输出明细数据到excel文件, 增加自定义的头部
    * @author Andy
    * @date 15:02 2021/8/23
    * @param response:
    * @param excelName:
    * @param head:
    * @param list:
    * @return void
    **/
    public static void excelWriteWithHeader(HttpServletResponse response, String excelName, List<List<String>> head, List list) throws IOException {
        setHeader(excelName, response);
        // 这里 需要指定写用哪个class去写，指定模板名称及数据
        EasyExcel.write(response.getOutputStream())
                .head(head)
                .excelType(ExcelTypeEnum.XLSX)
                .registerWriteHandler(new CustemhandlerUtils())
                .registerWriteHandler(getStyleStrategy())
                .sheet("sheet")
                .doWrite(list);
    }

    /**
    * 仅仅输出明细数据到excel文件, 增加自定义的头部
    * @author Andy
    * @date 15:02 2021/8/23
    * @param path:
    * @param excelName:
    * @param head:
    * @param list:
    * @return java.lang.String
    **/
    public static String excelWriteWithHeader(String path, String excelName, List<List<String>> head, List list) {
        String filePath = "";
        String fileName = DateFormatUtils.format(new Date(), "yyyy/MM/dd") + File.separator;
        fileName = fileName + excelName + System.currentTimeMillis() + ".xlsx";
        try {
            // 这里 需要指定写用哪个class去写，指定模板名称及数据
            EasyExcel.write(path + fileName)
                    .head(head)
                    .excelType(ExcelTypeEnum.XLSX)
                    .registerWriteHandler(new CustemhandlerUtils())
                    .registerWriteHandler(getStyleStrategy())
                    .sheet("sheet")
                    .doWrite(list);
            filePath = getPathFileName(path, fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filePath;
    }

    /**
    * Excel导出
    * @author Andy
    * @date 10:05 2021/8/23
    * @param path:
    * @param t:
    * @param excelName:
    * @param data:
    * @return java.lang.String
    **/
    public static String excelWrite(String path,Class t, String excelName,List data) {
        String filePath = "";
        String fileName = DateUtil.format(new Date(), "yyyy/MM/dd") + File.separator;
        fileName = fileName + excelName +"-"+ DateUtil.format(new Date(), "yyyyMMddHHmmss")  + ".xlsx";
        try {
            getAbsoluteFile(path, fileName);
            EasyExcel.write(path + fileName, t)
                    .excelType(ExcelTypeEnum.XLSX)
                    .registerWriteHandler(new CustemhandlerUtils())
                    .registerWriteHandler(getStyleStrategy())
                    .sheet("Export")
                    .doWrite(data);
            filePath = getPathFileName(path, fileName);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
        return filePath;
    }

    /**
    * 直接导出
    * @author Andy
    * @date 15:03 2021/8/23
    * @param response:
    * @param obj:
    * @param excelName:
    * @param data:
    * @return void
    **/
    public static void excelWrite(HttpServletResponse response,Class obj, String excelName, List data) throws Exception {
        setHeader(excelName, response);
        EasyExcel.write(response.getOutputStream(), obj)
                .excelType(ExcelTypeEnum.XLSX)
                .registerWriteHandler(new CustemhandlerUtils())
                .registerWriteHandler(EasyExcelUtil.getStyleStrategy())
                .sheet("sheet")
                .doWrite(data);
    }


    public static void excelDynamicWrite(HttpServletResponse response,String excelName, List<String> head,  List<List<Object>> dataList) throws Exception {
        String fileName =  excelName +"-"+ DateUtil.format(new Date(), "yyyyMMddHHmmss") ;
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf8");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "no-store");
        response.addHeader("Cache-Control", "max-age=0");


        List<List<String>> headList = new ArrayList<>();
        head.forEach(h -> headList.add(Collections.singletonList(h)));


        EasyExcel.write(response.getOutputStream())
                .excelType(ExcelTypeEnum.XLSX)
                .registerWriteHandler(new CustemhandlerUtils())
                .registerWriteHandler(EasyExcelUtil.getStyleStrategy())
                .sheet("sheet").head(headList).doWrite(dataList);


    }


    /**
     * 导出文件时为Writer生成OutputStream.
     *
     * @param fileName 文件名
     * @param response response
     * @return ""
     */
    private static OutputStream getOutputStream(String fileName,
                                                HttpServletResponse response) throws Exception {
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e) {
            throw new Exception("导出excel表格失败!", e);
        }
    }


    private static final String getPathFileName(String uploadDir, String fileName) throws IOException {
        String pathFileName = uploadDir  + "/" + fileName;
        return ToolUtil.path(pathFileName);
    }

    private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
        File desc = new File(uploadDir + File.separator + fileName);

        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }

        return desc;
    }

    private static HorizontalCellStyleStrategy getStyleStrategy(){
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为灰色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)12);
        // 字体样式
        headWriteFont.setFontName("Frozen");
        headWriteCellStyle.setWriteFont(headWriteFont);
        //自动换行
        headWriteCellStyle.setWrapped(false);
        // 水平对齐方式
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 垂直对齐方式
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
//        contentWriteCellStyle.setFillPatternType(FillPatternType.SQUARES);
        // 背景白色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short)12);
        // 字体样式
        contentWriteFont.setFontName("Calibri");
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

    private static void setHeader(String excelName, HttpServletResponse response) throws UnsupportedEncodingException {
        String fileName =  excelName +"-"+ DateUtil.format(new Date(), "yyyyMMddHHmmss") ;
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf8");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "no-store");
        response.addHeader("Cache-Control", "max-age=0");
    }

}