package com.ruoyi.common.importExcel.excel;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.excel.export.ExcelBatchExportService;
import com.ruoyi.common.exception.ServiceErrorException;
import com.ruoyi.common.importExcel.constant.MultipleListImport;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Description:
 * @Param:
 * @return:
 * @Author: Csy
 * @Date: 2021/10/31
 */
@Slf4j
public class EasyPoiHelper {

    private static String TEMPLATE_PATH = "static/template/";

    public static String DEFAULT_EXCEL_TITLE = "配送单导出";

    public static String makeToGroupExcelFile(String templateName, String suffix, Map<String, Object> map, HttpServletResponse response) {
        // 取得模板路径
        String templatePath = TEMPLATE_PATH + templateName + suffix;
        TemplateExportParams params = new TemplateExportParams(templatePath);

        // 替换数据
        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        // 生成文件
        String fileName = DEFAULT_EXCEL_TITLE + templateName + "_" + suffix;
        try {
            //准备将Excel的输出流通过response输出到页面下载
            //八进制输出流
            response.setContentType("application/octet-stream");

            //这后面可以设置导出Excel的名称，此例中名为student.xls
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName);

            //刷新缓冲
            /*response.flushBuffer();*/
            response.setCharacterEncoding("UTF-8");
            //workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();

            workbook.write(os);

            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            fileName = "";
        }
        System.gc();
        return fileName;
    }

    /**
     * 导出
     * @param templateName 文件名
     * @param list 导出的数据
     * @param c 数据的对象CLASS
     * @param suffix
     * @param response
     * @return
     */
    public static String makeToGroupBigExcelFile(String templateName, List<? extends Object> list, Class c, String suffix, HttpServletResponse response) {
        if(CollectionUtils.isEmpty(list)){
            throw new ServiceErrorException("导出数据为空");
        }

        ExportParams params = null;
        ExcelBatchExportService batchServer = null;
        Workbook workbook = null;

        if (params == null) {
            params = new ExportParams(null, "sheet1");
            params.setMaxNum(1000000);
            params.setStyle(ExcelStyleUtil.class);
            batchServer = new ExcelBatchExportService();
            batchServer.init(params, c);
        }
        workbook = batchServer.appendData(list);
//        Sheet sheet = workbook.getSheetAt(0);
//        // 设置自适应行高,i为需要自适应行高的起始行号, 起始行号为17 但是因为下标从0开始17需要减一, i<=20, 因为表格是循环生成,需要一行一行设置自适应高度
//        for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
//            Row row = sheet.getRow(i);
//            if (row == null) {
//                System.out.println("Data in row " + (i + 1) + " is null");
//            } else {
//                row.setHeight((short) -1);
//            }
//        }

        // 生成文件
        String fileName = DEFAULT_EXCEL_TITLE + templateName + "_" + suffix;
        try {
            //准备将Excel的输出流通过response输出到页面下载
            //八进制输出流
            response.setContentType("application/octet-stream");

            //这后面可以设置导出Excel的名称
            response.addHeader("content-Type", "application/vnd.ms-excel");
            response.addHeader("Content-disposition", "attachment;filename=" + fileName);
            response.addHeader("Cache-Control", "no-cache");
            //刷新缓冲
            /*response.flushBuffer();*/
            response.setCharacterEncoding("UTF-8");
            //workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();

            workbook.write(os);

            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            fileName = "";
        }
        System.gc();
        return fileName;
    }


    public static String exportMultipleSheets(String templateName, List<? extends MultipleListImport> multipleListImports, HttpServletResponse response) throws ClassNotFoundException {
        if(Objects.isNull(multipleListImports) ||  CollectionUtils.isEmpty(multipleListImports)){
            throw new ServiceErrorException("导出数据不能空");
        }
        Workbook workbook = null;
        ExportParams params = null;
        ExcelBatchExportService batchServer = null;

        for(MultipleListImport multipleListImport : multipleListImports){
            List<? extends Object>  list =  multipleListImport.getDataList();
            if(CollectionUtils.isEmpty(list)){
                throw new ServiceErrorException("导出数据不能空");
            }

            if (params == null) {
                params = new ExportParams(null,multipleListImport.getSheetName());
                params.setMaxNum(1000000);
                params.setStyle(ExcelStyleUtil.class);
                batchServer = new ExcelBatchExportService();
                batchServer.init(params, Class.forName(multipleListImport.getClassName()));
                workbook = batchServer.appendData(multipleListImport.getDataList());
            }else{
                params = new ExportParams(null,multipleListImport.getSheetName());
                params.setMaxNum(1000000);
                params.setStyle(ExcelStyleUtil.class);
                batchServer.createSheet(workbook,params, Class.forName(multipleListImport.getClassName()),list);
            }
        }



        // 生成文件
        String fileName = DEFAULT_EXCEL_TITLE + templateName + "_" + ".xlsx";
        try {
            //准备将Excel的输出流通过response输出到页面下载
            //八进制输出流
            response.setContentType("application/octet-stream");

            //这后面可以设置导出Excel的名称
            response.addHeader("content-Type", "application/vnd.ms-excel");
            response.addHeader("Content-disposition", "attachment;filename=" + fileName);
            response.addHeader("Cache-Control", "no-cache");
            //刷新缓冲
            /*response.flushBuffer();*/
            response.setCharacterEncoding("UTF-8");
            //workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();

            workbook.write(os);

            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            fileName = "";
        }
        System.gc();
        return fileName;
    }

    /**
     * 一对多导入
     * @param file
     * @param titleRows
     * @param headerRows
     * @param pojoClass
     * @param <T>
     * @return
     */
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows,
                                          Class<T> pojoClass) {
        if (file == null) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        //指定第一个sheet
        params.setStartSheetIndex(1);
        params.setNeedVerify(true);
        ExcelImportResult<T> result = null;
        try (InputStream inputStream = file.getInputStream();) {
            result = ExcelImportUtil.importExcelMore(inputStream, pojoClass, params);
        } catch (NoSuchElementException e) {
            // 日志记录错误
            log.error("excel cannot empty:", e.getMessage());
        } catch (Exception e) {
            // 日志记录错误
            log.error("excel import failed:", e.getMessage());
        }
        if (ObjectUtils.isEmpty(result)) {
            return null;
        }
        if (result.isVerfiyFail()) {
            // 如果有错误，把错误数据返回到前端(让前端下载一个错误的excel)
//            Workbook failWorkbook = result.getFailWorkbook();
//            downLoadExcel("error_record.xls", response, failWorkbook);
            return result.getFailList();
        }
        return result.getList();
    }

    public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
        try {
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            response.setCharacterEncoding("utf-8");
            response.setHeader("content-Type", "application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            // 一个自定义枚举 错误信息的
            log.error("excel import failed:", e.getMessage());
        }
    }

}