All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feingto.cloud.kit.ExcelKit Maven / Gradle / Ivy

There is a newer version: 2.5.2.RELEASE
Show newest version
package com.feingto.cloud.kit;

import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * Excel工具类
 *
 * @author longfei
 */
@SuppressWarnings("WeakerAccess")
public class ExcelKit {
    public static String EXCEL03 = "xls";
    public static String EXCEL07 = "xlsx";
    private Workbook wb;// 工作表对象
    private Sheet sheet;// 工作表sheet
    private Row row;// 行对象
    private Object[] objs;// 对象数组
    @Setter
    private int sheetIndex = 0;// sheet下标值

    public static ExcelKit NEW(MultipartFile file) {
        ExcelKit excel = new ExcelKit();
        Assert.notNull(file.getOriginalFilename(), "文件名不能为空");
        InputStream in;
        try {
            in = file.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException("文件读取失败", e);
        }

        String ext = FileKit.getFileExt(file.getOriginalFilename());
        if (EXCEL03.equals(ext)) {
            excel.builHSSF(in);
        } else if (EXCEL07.equals(ext)) {
            excel.builXSSF(in);
        }

        return excel;
    }

    private void builXSSF(InputStream inputStream) {
        try {
            wb = new XSSFWorkbook(inputStream);
        } catch (Exception e) {
            throw new RuntimeException("文件解析失败", e);
        }
    }

    private void builHSSF(InputStream inputStream) {
        try {
            wb = new HSSFWorkbook(inputStream);
        } catch (Exception e) {
            throw new RuntimeException("文件解析失败", e);
        }
    }

    /**
     * 获取单元格值
     *
     * @param row   excel行对象
     * @param index excel单元格的位置
     * @return 返回获取单元格值
     */
    private static String getCellValue(Row row, int index) {
        Cell cell = row.getCell((short) index);
        String value = "";
        if (cell != null) {
            CellType cellType = cell.getCellTypeEnum();
            if (CellType.NUMERIC.equals(cellType)) {
                value = DateUtil.isCellDateFormatted(cell)
                        ? DateKit.format(cell.getDateCellValue())
                        : new DecimalFormat("#.##").format(cell.getNumericCellValue());
            } else if (CellType.BOOLEAN.equals(cellType)) {
                value = String.valueOf(cell.getBooleanCellValue());
            } else {
                value = cell.getStringCellValue();
            }
        }
        return value.trim();
    }

    /**
     * 获取单个工作薄的标题栏
     *
     * @param startRow 起始行(从0开始)
     * @return Object[]
     */
    public Object[] getSheetCellTitle(int startRow) {
        sheet = wb.getSheetAt(sheetIndex);
        // 获取第startRow行的总列数
        int cellIndex = sheet.getRow(startRow).getPhysicalNumberOfCells();
        // 获取单元格
        row = sheet.getRow(startRow);
        if (null != row) {
            objs = new Object[cellIndex];
            for (int i = 0; i < cellIndex; i++) {
                objs[i] = getCellValue(row, i);
            }
        }
        return objs;
    }

    /**
     * 获取单个工作薄
     *
     * @return List
     */
    public List getSheetCellValue() {
        return this.getSheetCellValue(0, 0, 0);
    }

    /**
     * 获取单个工作薄
     *
     * @param startRow  起始行(从0开始)
     * @param startCell 起始列(从1开始)
     * @param titleRow  标题栏行
     * @return List
     */
    public List getSheetCellValue(int startRow, int startCell, int titleRow) {
        List resultList = new ArrayList<>();
        sheet = wb.getSheetAt(sheetIndex);
        String value;
        // 获取总行数
        int rowIndex = sheet.getPhysicalNumberOfRows();
        // 获取标题行的总列数
        int cellIndex = sheet.getRow(titleRow).getPhysicalNumberOfCells();

        for (int i = startRow; i < rowIndex; i++) {
            // 获取单元格
            row = sheet.getRow(i);
            if (null != row) {
                objs = new Object[cellIndex - startCell];
                // 整行记录是否为空标识
                boolean isExist = true;
                for (int j = startCell; j < cellIndex; j++) {
                    value = getCellValue(row, j);
                    objs[j - startCell] = value;
                    if (isExist) {
                        isExist = StringUtils.isEmpty(value);
                    }
                }
                // 整行记录中所有单元格有一个不是空,该行获取
                if (!isExist) {
                    resultList.add(objs);
                }
                objs = null;
            } else {
                rowIndex++;
            }
        }
        return resultList;
    }

    /**
     * 获取多个工作薄中的值
     *
     * @param startRow  起始行(从0开始)
     * @param startCell 起始列(从1开始)
     * @return List>
     */
    public List> getMuiltSheetCellValue(Integer[] startRow, Integer[] startCell) {
        boolean flag = false;
        // 保存表集合
        List> tables = new ArrayList<>();
        // 保存行集合
        List rows;
        // 单元格中的值
        String value;
        // 行中有值的单元格总数量
        int cellTotalNum;

        // 获得多个工作薄
        for (int numSheet = 0; numSheet < wb.getNumberOfSheets(); numSheet++) {
            rows = new ArrayList<>();
            // 获取其中一个工作薄
            sheet = wb.getSheetAt(numSheet);
            // 读取单个工作薄中的行
            for (int numRow = startRow[numSheet]; numRow <= sheet.getLastRowNum(); numRow++) {
                row = sheet.getRow(numRow);
                if (null != row) {
                    cellTotalNum = row.getLastCellNum();
                    objs = new Object[cellTotalNum - startCell[numSheet]];
                    // 读取行中单元格的值
                    for (int numCell = startCell[numSheet]; numCell <= cellTotalNum; numCell++) {
                        value = getCellValue(row, numCell);
                        if (!"".equals(value)) {
                            objs[numCell - startCell[numSheet]] = value;
                            flag = true;
                        }
                    }
                    if (flag) {
                        rows.add(objs);
                    }
                    objs = null;
                    flag = false;
                }
            }
            if (rows.size() > 0)
                tables.add(rows);
        }
        return tables;
    }

    /**
     * 导出工作簿
     *
     * @param title    Sheet标题
     * @param rowName  标题栏
     * @param dataList 数据
     */
    public HSSFWorkbook export(String title, String[] rowName, List dataList) {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet(title);
        HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);// 获取列头样式对象
        HSSFCellStyle style = this.getStyle(workbook);// 单元格样式对象
//        HSSFCell cellTitle = sheet.createRow(0).createCell(0);
//        sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (rowName.length - 1)));// 合并1、2行
//        cellTitle.setCellStyle(columnTopStyle);
//        cellTitle.setCellValue(title);

        // 定义所需列数
        int columnNum = rowName.length;
        HSSFRow rowRowName = sheet.createRow(0);// 在索引0的位置创建行(最顶端的行开始的第0行)
        // 将列头设置到sheet的单元格中
        for (int n = 0; n < columnNum; n++) {
            HSSFCell cellRowName = rowRowName.createCell(n);// 创建列头对应个数的单元格
            cellRowName.setCellType(CellType.STRING);// 设置列头单元格的数据类型
            HSSFRichTextString text = new HSSFRichTextString(rowName[n]);
            cellRowName.setCellValue(text);// 设置列头单元格的值
            cellRowName.setCellStyle(columnTopStyle);// 设置列头单元格样式
        }

        // 将查询出的数据设置到sheet对应的单元格中
        for (int i = 0; i < dataList.size(); i++) {
            Object[] obj = dataList.get(i);
            HSSFRow row = sheet.createRow(i + 1);
            for (int j = 0; j < obj.length; j++) {
                HSSFCell cell;
                cell = row.createCell(j, CellType.STRING);
                if (!ObjectUtils.isEmpty(obj[j])) {
                    cell.setCellValue(obj[j].toString());
                }
                cell.setCellStyle(style);
            }
        }

        sheet.autoSizeColumn((short) 0);
        return workbook;
    }

    /**
     * 列头单元格样式
     *
     * @param workbook HSSFWorkbook
     */
    public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {
        HSSFCellStyle style = getStyle(workbook);
        // 设置字体
        HSSFFont font = workbook.createFont();
        // 设置字体大小
        font.setFontHeightInPoints((short) 12);
        // 字体加粗
        font.setBold(true);
        // 在样式用应用设置的字体
        style.setFont(font);
        return style;
    }

    /**
     * 列数据信息单元格样式
     *
     * @param workbook HSSFWorkbook
     */
    public HSSFCellStyle getStyle(HSSFWorkbook workbook) {
        // 设置样式
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置字体
        HSSFFont font = workbook.createFont();
        // 设置字体名字
        font.setFontName("Courier New");
        // 在样式用应用设置的字体
        style.setFont(font);
        // 设置底边框
        style.setBorderBottom(BorderStyle.THIN);
        // 设置底边框颜色
        style.setBottomBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        // 设置左边框
        style.setBorderLeft(BorderStyle.THIN);
        // 设置左边框颜色
        style.setLeftBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        // 设置右边框
        style.setBorderRight(BorderStyle.THIN);
        // 设置右边框颜色
        style.setRightBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        // 设置顶边框
        style.setBorderTop(BorderStyle.THIN);
        // 设置顶边框颜色
        style.setTopBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        // 设置自动换行
        style.setWrapText(false);
        // 设置水平对齐的样式为居中对齐
        style.setAlignment(HorizontalAlignment.CENTER);
        // 设置垂直对齐的样式为居中对齐
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }
}