package com.artfess.poi.util;

import cn.hutool.json.JSONUtil;
import com.artfess.poi.Excel;
import com.artfess.poi.HeaderNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

/**
 * @Description:
 * @Auther: tsy
 * @Date: 2022/10/09/5:27 下午
 */
@Slf4j
public class CustomHeader {

    public  static void export(List<HeaderNode> headerNodes, HttpServletResponse response, String fileName) throws IOException {
        Excel excel = new Excel();
        excel.sheet().sheetName("年度成绩信息");
       // 产生工作薄对象
        HSSFWorkbook workbook = excel.getWorkBook();
        HSSFSheet sheet = workbook.getSheet("年度成绩信息");

        HSSFCellStyle headStyle = workbook.createCellStyle();
        defaultHeadStyle(headStyle);
        //表头层级
        int deep = headerNodes.stream().map(HeaderNode::getRow).reduce(Integer::max).orElse(1);
        for (int i = 0; i <= 3; i++) {
            sheet.createRow(i);
        }
        for (HeaderNode headerNode : headerNodes) {
            int row = headerNode.getRow();
            if(row <= 3) {
                int col = headerNode.getColumn();
                excel.cell(headerNode.getRow(), headerNode.getColumn()).value(headerNode.getHeaderName()).style(headStyle);
                CellRangeAddress region;
                //是否跨列
                if (headerNode.isOverNode()) {
                    region = new CellRangeAddress(row, 3, col, col);
                } else {
                    region = new CellRangeAddress(row, row, col, (col + headerNode.getOverNodeCount() - 1));
                }
                if (region.getNumberOfCells() > 1) {
                    sheet.addMergedRegionUnsafe(region);
                    //合并后设置下边框
                    RegionUtil.setBorderTop(BorderStyle.THIN, region, sheet);
                    RegionUtil.setBorderLeft(BorderStyle.THIN, region, sheet);
                    RegionUtil.setBorderBottom(BorderStyle.THIN, region, sheet);
                    RegionUtil.setBorderRight(BorderStyle.THIN, region, sheet);
                }
            }else {
                excel.cell(headerNode.getRow(), headerNode.getColumn()).value(headerNode.getHeaderName());
            }
        }
        ExcelUtil.downloadExcel(workbook, fileName, response);

    }



    public static void main(String[] args) {
        String customizeLabel = "[{\"headerName\":\"机构名称\",\"column\":0,\"row\":0},{\"headerName\":\"卡类型代码\",\"column\":1,\"row\":0},{\"headerName\":\"卡类型名称\",\"column\":2,\"row\":0},{\"headerName\":\"期初库存量\",\"column\":3,\"row\":0},{\"headerName\":\"本期入库情况\",\"column\":4,\"row\":0,\"overNodeCount\":4,\"overNode\":false},{\"headerName\":\"本期入库小计\",\"column\":4,\"row\":1},{\"headerName\":\"本期入库明细\",\"column\":5,\"row\":\"1\",\"overNodeCount\":3,\"overNode\":false},{\"headerName\":\"印刷入库\",\"column\":5,\"row\":2},{\"headerName\":\"领用入库\",\"column\":6,\"row\":2},{\"headerName\":\"回收入库\",\"column\":7,\"row\":2},{\"headerName\":\"本期出库情况\",\"column\":8,\"row\":0,\"overNodeCount\":7,\"overNode\":false},{\"headerName\":\"本期出库小计\",\"column\":8,\"row\":\"1\"},{\"headerName\":\"本期出库明细\",\"column\":9,\"row\":\"1\",\"overNodeCount\":6,\"overNode\":false},{\"headerName\":\"机构/部门下发出库\",\"column\":9,\"row\":2},{\"headerName\":\"员工下发出库\",\"column\":10,\"row\":2},{\"headerName\":\"回收提交出库\",\"column\":11,\"row\":2},{\"headerName\":\"清理出库\",\"column\":12,\"row\":2},{\"headerName\":\"销毁出库\",\"column\":13,\"row\":2},{\"headerName\":\"其他方式出库\",\"column\":14,\"row\":2},{\"headerName\":\"剩余库存量\",\"column\":15,\"row\":0}]";
        List<HeaderNode> headerNodes = JSONUtil.toList(JSONUtil.parseArray(customizeLabel), HeaderNode.class);
        SXSSFWorkbook book = new SXSSFWorkbook();
        SXSSFSheet sxssfSheet = book.createSheet("测试");
        CellStyle headStyle = book.createCellStyle();
        defaultHeadStyle(headStyle);
        //表头层级
        int deep = headerNodes.stream().map(HeaderNode::getRow).reduce(Integer::max).orElse(1);
        for (int i = 0; i < deep; i++) {
            sxssfSheet.createRow(i);
        }
        //创建单元格
        for (HeaderNode headerNode : headerNodes) {
            int row = headerNode.getRow();
            int col = headerNode.getColumn();
            SXSSFCell sxssfCell = sxssfSheet.getRow(row).createCell(col);
            sxssfSheet.setColumnWidth(col, headerNode.getWidth() * 256);
            sxssfCell.setCellStyle(headStyle);
            sxssfCell.setCellValue(headerNode.getHeaderName());

            CellRangeAddress region;
            //是否跨列
            if (headerNode.isOverNode()) {
                region = new CellRangeAddress(row, deep, col, col);
            } else {
                region = new CellRangeAddress(row, row, col, (col + headerNode.getOverNodeCount() - 1));
            }
            if (region.getNumberOfCells() > 1) {
                sxssfSheet.addMergedRegionUnsafe(region);
                //合并后设置下边框
                RegionUtil.setBorderTop(BorderStyle.THIN, region, sxssfSheet);
                RegionUtil.setBorderLeft(BorderStyle.THIN, region, sxssfSheet);
                RegionUtil.setBorderBottom(BorderStyle.THIN, region, sxssfSheet);
                RegionUtil.setBorderRight(BorderStyle.THIN, region, sxssfSheet);
            }
        }

        FileOutputStream fileOut = null;
        try {
            File file = new File("D:/excel/myExcel.xls");
            fileOut = new FileOutputStream(file);
            book.write(fileOut);
            System.out.println("----Excle文件已生成------");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileOut != null) {
                try {
                    fileOut.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 表头样式
     *
     * @param headStyle
     */
    private static void defaultHeadStyle(CellStyle headStyle) {
        headStyle.setBorderTop(BorderStyle.THIN);
        headStyle.setBorderLeft(BorderStyle.THIN);
        headStyle.setBorderBottom(BorderStyle.THIN);
        headStyle.setBorderRight(BorderStyle.THIN);

        headStyle.setAlignment(HorizontalAlignment.CENTER);
        headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
    }

}
