package api.common.util;


import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

/**
 * <dependency>
 * <groupId>org.apache.poi</groupId>
 * <artifactId>poi</artifactId>
 * <version>${poi.version}</version>
 * </dependency>
 * <dependency>
 * <groupId>org.apache.poi</groupId>
 * <artifactId>poi-ooxml</artifactId>
 * <version>${poi-ooxml.version}</version>
 * </dependency>
 */
public class ExcelUtil {

    /**
     * 获取 Excel 对象
     */
    public static Workbook getExcel(String path) {
        try {
            File excel = new File(path);
            Workbook result;
            //1 获取 Excel 文件输入流
            String excelName = excel.getName();
            String suffix = excelName.substring(excelName.lastIndexOf(".") + 1);
            InputStream inputStream = Files.newInputStream(excel.toPath());

            //2 获取 Workbook 对象，".xls"和".xlsx"文件不同。
            if ("xls".equalsIgnoreCase(suffix)) {
                result = new HSSFWorkbook(inputStream);
            } else if ("xlsx".equalsIgnoreCase(suffix)) {
                result = new XSSFWorkbook(inputStream);
            } else {
                throw new RuntimeException("文件" + excel.getAbsolutePath() + "不是 excel 文件");
            }
            inputStream.close();
            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取 Excel 对象
     */
    public static Workbook getExcel(InputStream inputStream, String suffix) {
        try {
            Workbook result;
            //2 获取 Workbook 对象，".xls"和".xlsx"文件不同。
            if ("xls".equalsIgnoreCase(suffix)) {
                result = new HSSFWorkbook(inputStream);
            } else if ("xlsx".equalsIgnoreCase(suffix)) {
                result = new XSSFWorkbook(inputStream);
            } else {
                throw new RuntimeException("getExcel() 后缀为 " + suffix + " 的文件不是 excel 文件");
            }
            inputStream.close();
            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取 Sheet 对象
     *
     * @param excel
     * @param name
     * @return
     */
    public static Sheet getSheetByName(Workbook excel, String name) {
        try {
            Sheet sheet = excel.getSheet(name);
            if (sheet == null) {
                throw new RuntimeException("excel 不存在名为 " + name + "的 sheet ！");
            }
            return sheet;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 获取 Sheet 对象
     *
     * @param excel
     * @param index
     * @return
     */
    public static Sheet getSheetByIndex(Workbook excel, int index) {
        try {
            Sheet sheet = excel.getSheetAt(index);
            if (sheet == null) {
                throw new RuntimeException("excel 不存在下标为 " + index + " 的 sheet ！");
            }
            return sheet;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 读取 Excel 文件的某一行
     *
     * @param row 行数
     * @return 结果列表
     */
    public static List<String> getRow(Sheet sheet, int row, int startColumn, int stopColumn) {
        try {
            List<String> result = new ArrayList<>();
            //1 获取行
            Row dataRow = sheet.getRow(row);
            //2 开始解析每一列
            for (int columnIndex = startColumn; columnIndex <= stopColumn; columnIndex++) {

                Cell cell = dataRow.getCell(columnIndex);
                CellType cellType = cell.getCellType();
                String cellValue = "";
                switch (cellType) {
                    case NUMERIC:
                        cellValue = String.valueOf(cell.getNumericCellValue());
                        break;
                    case STRING:
                        cellValue = cell.getStringCellValue();
                        break;
                    case BLANK:
                        cellValue = "";
                        break;
                    default:
                        throw new RuntimeException("单元格类型为：" + cellType + "，暂时无法解析！");
                }
                result.add(cellValue);
            }
            return result;
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读取 Excel 所有数据
     *
     * @return 二维数组
     */
    public static List<List<String>> getAll(Sheet sheet) {
        try {

            List<List<String>> table = new ArrayList<>();
            int lastRowNum = sheet.getLastRowNum(); // （最后一行下标）即（总行数-1）（下标从0开始）
            //1 循环获取行
            for (int i = 0; i <= lastRowNum; i++) {
                Row row = sheet.getRow(i);
                short lastCellNum = row.getLastCellNum();// （最后一列下标+1）即（总列数）（下标从0开始）
                //2 开始解析每一列
                List<String> cellList = new ArrayList<>();
                for (int columnIndex = 0; columnIndex < lastCellNum; columnIndex++) {
                    Cell cell = row.getCell(columnIndex);
                    CellType cellType = cell.getCellType();
                    String cellValue;
                    switch (cellType) {
                        case NUMERIC:
                            cellValue = String.valueOf(cell.getNumericCellValue());
                            break;
                        case STRING:
                            cellValue = cell.getStringCellValue();
                            break;
                        case BLANK:
                            cellValue = "";
                            break;
                        default:
                            throw new RuntimeException("单元格类型为：" + cellType + "，暂时无法解析！");
                    }
                    cellList.add(cellValue);
                }
                table.add(cellList);
            }
            return table;
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读取 Excel 文件中某一块二维表格
     *
     * @param stopRow    Integer.MAX_VALUE 代表到最后一行
     * @param stopColumn Integer.MAX_VALUE 代表到最后一列
     * @return 结果列表
     */
    public static List<List<String>> getTable(Sheet sheet, int startRow, int stopRow, int startColumn, int stopColumn) {
        try {
            List<List<String>> table = new ArrayList<>();
            //1 循环获取行（下标从0开始）
            if (stopRow == Integer.MAX_VALUE) {
                stopRow = sheet.getLastRowNum();
            }

            for (int i = startRow; i <= stopRow; i++) {
                Row row = sheet.getRow(i);
                //2 开始解析每一列
                List<String> cellList = new ArrayList<>();
                if (stopColumn == Integer.MAX_VALUE) {
                    stopColumn = row.getLastCellNum() - 1;
                }
                for (int columnIndex = startColumn; columnIndex <= stopColumn; columnIndex++) {
                    Cell cell = row.getCell(columnIndex);
                    CellType cellType = cell.getCellType();
                    String cellValue;
                    switch (cellType) {
                        case NUMERIC:
                            cellValue = String.valueOf(cell.getNumericCellValue());
                            break;
                        case STRING:
                            cellValue = cell.getStringCellValue();
                            break;
                        case BLANK:
                            cellValue = "";
                            break;
                        default:
                            throw new RuntimeException("getTable() 单元格类型为 " + cellType + "，暂时无法解析！");
                    }
                    cellList.add(cellValue);
                }
                table.add(cellList);
            }
            return table;
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        }
    }
}
