package com.ruoyi.common.utils.poi;

import com.ruoyi.common.config.RuoYiConfig;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author sun
 */
public class DrawExcel {

    /**
     * 读取对象
     */
    private XSSFWorkbook readWorkbook;

    /**
     * 写入对象
     */
    private Workbook writeWorkbook;

    /**
     * 提交行数，默认：100
     */
    private int commitNum = 100;

    /**
     * 输入路径
     */
    private String inPath = "";

    /**
     * 输出路径
     */
    private String outPath = "";

    /**
     * 输入流
     */
    private FileInputStream fis;

    /**
     * 输出流
     */
    private FileOutputStream fos;

    /**
     * 当前操作Sheet
     */
    private Sheet sheet;

    /**
     * 当前操作行
     */
    private Row row;

    /**
     * 构造方法一：输入路径 + 输出路径
     *
     * @param inPath  输入路径
     * @param outPath 输出路径
     */
    public DrawExcel(String inPath, String outPath) {
        try {
            this.inPath = inPath;
            this.outPath = outPath;
            fis = new FileInputStream(inPath);
            fos = new FileOutputStream(outPath);
            readWorkbook = new XSSFWorkbook(fis);
            writeWorkbook = new SXSSFWorkbook(readWorkbook, commitNum);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 构造方法二：输入路径 + 输出路径
     *
     * @param inPath    输入路径
     * @param outPath   输出路径
     * @param commitNum 提交数
     */
    public DrawExcel(String inPath, String outPath, int commitNum) {
        try {
            this.inPath = inPath;
            this.outPath = outPath;
            this.commitNum = commitNum;
            fis = new FileInputStream(inPath);
            fos = new FileOutputStream(outPath);
            readWorkbook = new XSSFWorkbook(fis);
            writeWorkbook = new SXSSFWorkbook(readWorkbook, commitNum);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 构造方法三：输出路径
     *
     * @param outPath 输出路径
     */
    public DrawExcel(String outPath) {
        try {
            this.outPath = outPath;
            fos = new FileOutputStream(outPath);
            writeWorkbook = new SXSSFWorkbook(commitNum);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 构造方法四：输出路径
     *
     * @param outPath   输出路径
     * @param commitNum 提交数
     */
    public DrawExcel(String outPath, int commitNum) {
        try {
            this.outPath = outPath;
            this.commitNum = commitNum;
            fos = new FileOutputStream(outPath);
            writeWorkbook = new SXSSFWorkbook(commitNum);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取Sheet
     */
    public Sheet getSheet(int index) {
        try {
            sheet = writeWorkbook.getSheetAt(index);
        } catch (Exception e) {
            e.printStackTrace();
            sheet = writeWorkbook.createSheet();
        }

        return sheet;
    }

    /**
     * 创建Sheet
     */
    public void createSheet() {
        sheet = writeWorkbook.createSheet();
    }

    /**
     * 创建列的宽度
     */
    public void setColumnWidth(int column, int width) {
        sheet.setColumnWidth(column, width);
    }

    /**
     * 创建行高
     */
    public void setHeightInPoints(int height) {
        row.setHeightInPoints(height);
    }

    public void setCellStr(int cellIdx, String cellStr) {
        Cell cell = row.createCell(cellIdx);
        cell.setCellValue(cellStr);
    }

    /**
     * 创建行
     *
     * @param rowNum 行号
     */
    public Row createRow(int rowNum) {
        row = sheet.createRow(rowNum);
        return row;
    }

    /**
     * 创建数据
     *
     * @param cellNum 列号
     * @param cellVal 数值
     */
    public void createCell(int cellNum, String cellVal) {
        row.createCell(cellNum).setCellValue(cellVal);
    }

    /**
     * 写文件
     */
    public void write() {
        try {
            writeWorkbook.write(fos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取读取对象
     */
    public XSSFWorkbook getReadWorkbook() {
        return readWorkbook;
    }

    /**
     * 设置读取对象
     */
    public void setReadWorkbook(XSSFWorkbook readWorkbook) {
        this.readWorkbook = readWorkbook;
    }

    /**
     * 获取写入对象
     */
    public Workbook getWriteWorkbook() {
        return writeWorkbook;
    }

    /**
     * 设置写入对象
     */
    public void setWriteWorkbook(Workbook writeWorkbook) {
        this.writeWorkbook = writeWorkbook;
    }

    /**
     * 获取提交数量
     */
    public int getCommitNum() {
        return commitNum;
    }

    /**
     * 设置提交数量
     */
    public void setCommitNum(int commitNum) {
        this.commitNum = commitNum;
    }

    /**
     * 获取输入路径
     */
    public String getInPath() {
        return inPath;
    }

    /**
     * 设置输入路径
     */
    public void setInPath(String inPath) {
        this.inPath = inPath;
    }

    /**
     * 获取输出路径
     */
    public String getOutPath() {
        return outPath;
    }

    /**
     * 设置输出路径
     */
    public void setOutPath(String outPath) {
        this.outPath = outPath;
    }

    /**
     * 获取输入流
     */
    public FileInputStream getFileInputStream() {
        return fis;
    }

    /**
     * 设置输入流
     */
    public void setFileInputStream(FileInputStream fis) {
        this.fis = fis;
    }

    /**
     * 获取输出流
     */
    public FileOutputStream getFileOutputStream() {
        return fos;
    }

    /**
     * 设置输出流
     */
    public void setFileOutputStream(FileOutputStream fos) {
        this.fos = fos;
    }

    /**
     * 获取Sheet
     */
    public Sheet getSheet() {
        return sheet;
    }

    /**
     * 设置Sheet
     */
    public void setSheet(Sheet sheet) {
        this.sheet = sheet;
    }

    /**
     * 获取当前行
     */
    public Row getRow() {
        return row;
    }

    /**
     * 设置当前行
     */
    public void setRow(Row row) {
        this.row = row;
    }

    /**
     * 释放方法
     */
    public void free() {
        try {
            if (fis != null) {
                fis.close();
            }
            if (fos != null) {
                fos.close();
            }
            System.gc();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取下载路径
     *
     * @param filename 文件名称
     */
    public static String getAbsoluteFile(String filename) {
        String downloadPath = RuoYiConfig.getDownloadPath() + filename;
        File file = new File(downloadPath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        return downloadPath;
    }

    private void example() {
        DrawExcel ioExcel = new DrawExcel(getAbsoluteFile("案例.xlsx"));
        // 获取sheet
        ioExcel.createSheet();
        Sheet sheet = ioExcel.getSheet(0);

        // 设置第一行为标题 和基本格式 具体不清楚
        Row firstRow = ioExcel.createRow(0);
        ioExcel.setCellStr(0, "测试");
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 11));
        firstRow.setHeightInPoints(25);
        Workbook wk = ioExcel.getWriteWorkbook();
        CellStyle cellStyle = wk.createCellStyle();
        Font font = wk.createFont();
        // 加粗
        font.setBold(true);
        font.setFontHeightInPoints((short) 20);

        cellStyle.setFont(font);
        // 设置字体水平居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        // 设置字体垂直居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        firstRow.setHeightInPoints(51F);
        firstRow.getCell(0).setCellStyle(cellStyle);
        // 设置字段宽度 高度
        ioExcel.createRow(1).setHeightInPoints(25);
        for (int titleArrCount = 0; titleArrCount < 11; titleArrCount++) {
            ioExcel.setCellStr(titleArrCount, "12");
        }

        for (int i = 0; i < 12; i++) {
            sheet.setColumnWidth(i, 7500);
            sheet.getColumnStyle(0).setAlignment(HorizontalAlignment.CENTER);
        }

        int cowNum = 2;
        // //创建行

        // //这部分是测试放入数据
        for (int cellNum = 0; cellNum < 12; cellNum++) {
            ioExcel.createRow(cowNum);
            ioExcel.createCell(cellNum, "++++++");
            cowNum++;
        }

        ioExcel.write();
        ioExcel.free();
    }

}
