Java使用Apache POI读取写入Excel

2 篇文章 0 订阅
1 篇文章 0 订阅

目录

Apache POI介绍

本文主要是提供一些Apache POI 常用读取、写入功能的封装方法。

引入POI依赖 

使用注解配置Java类属性和Excel列名/工作簿名

POI工具类


简介

Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

POI 中主要提供的读写 Microsoft Office 功能点如下:

HSSF -- 提供读写Microsoft Excel格式档案的功能。

XSSF -- 提供读写Microsoft Excel OOXML格式档案的功能。

HWPF -- 提供读写Microsoft Word格式档案的功能。

HSLF -- 提供读写Microsoft PowerPoint格式档案的功能。

HDGF -- 提供读写Microsoft Visio格式档案的功能。

本文主要是提供一些Apache POI 常用读取、写入Excel功能的封装方法。

引入POI依赖 

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>

使用注解配置Java类属性和Excel列名/工作簿名

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelField {
    /**
     * 列索引
     */
    int columnIndex() default 0;

    /**
     * 列名
     */
    String columnName() default "未知列名";

    /**
     * 合并列数据
     */
    boolean mergeColumnCell() default false;

}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelSheet {
    String value();
}

POI工具类


import com.alibaba.excel.util.DateUtils;
import org.apache.commons.lang3.ArrayUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class PoiUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(PoiUtil.class);
    public static final String EXCEL_XLS = ".xls";
    public static final String EXCEL_XLSX = ".xlsx";

    /**
     * 写入本地文件
     *
     * @param data 数据集
     * @param path 文件路径
     */
    public void write(List<?> data, String path) {
        if (data.size() == 0) {
            return;
        }
        write(data, data.getClass(), path);
    }

    /**
     * 写入本地文件
     *
     * @param data  数据集
     * @param clazz 列名基于实体注解
     * @param path  文件路径
     */
    public static <T> void write(List<?> data, Class<T> clazz, String path) {
        createFile(path);
        File file = new File(path);
        Workbook workbook = writeWorkbook(data, clazz, file.getName());
        try (FileOutputStream outputStream = new FileOutputStream(file)) {
            assert workbook != null;
            workbook.write(outputStream);
        } catch (Exception e) {
            LOGGER.error("写入Excel文件失败", e);
        }
    }

    /**
     * 多种数据写入同一个workbook
     */
    public static Workbook writeWorkbook(List<List<?>> data, String fileName, Boolean isMultiSheet) {
        int total = data.stream().mapToInt(List::size).sum();
        Workbook workbook = buildWorkbook(fileName, total);
        Integer startRowNum = 0;
        if (isMultiSheet) {
            for (int i = 0; i < data.size(); i++) {
                startRowNum = 0;
                List<?> list = data.get(i);
                if (list.size() == 0) {
                    continue;
                }
                Class<?> clazz = list.get(0).getClass();
                // 判断是否设置“工作铺名称”
                String sheetName = "sheet" + (i + 1);
                if (clazz.isAnnotationPresent(ExcelSheet.class)) {
                    sheetName = clazz.getAnnotation(ExcelSheet.class).value();
                }
                Sheet sheet = workbook.createSheet(sheetName);
                writeSheet(sheet, workbook, list, clazz, startRowNum);
            }
        } else {
            // 判断是否设置“工作铺名称”
            String sheetName = "sheet";
            Sheet sheet = workbook.createSheet(sheetName);
            for (List<?> list : data) {
                if (list.size() == 0) {
                    continue;
                }
                Class<?> clazz = list.get(0).getClass();
                writeSheet(sheet, workbook, list, clazz, startRowNum);
                startRowNum += 4;
            }
        }

        return workbook;
    }

    /**
     * 写入Workbook
     *
     * @param data 数据集合
     */
    public static Workbook writeWorkbook(List<?> data, List<String> fieldNames, String fileName) {
        if (data.size() == 0 || fieldNames.size() == 0) {
            return null;
        }

        Workbook workbook = buildWorkbook(fileName, data.size());

        Class<?> aClass = data.get(0).getClass();
        // 判断是否设置“工作铺名称”
        String sheetName = "sheet";
        if (aClass.isAnnotationPresent(ExcelSheet.class)) {
            sheetName = aClass.getAnnotation(ExcelSheet.class).value();
        }
        Sheet sheet = workbook.createSheet(sheetName);

        // 设置表头(列名)
        Row row = sheet.createRow(0);

        // 设置单元格样式
        CellStyle headerStyle = buildHeaderStyle(workbook);

        // 列索引
        int columnIndex = 0;
        // 列名称
        String columnName;
        ExcelField excelField;
        for (String fieldName : fieldNames) {
            Field field = existsField(aClass, fieldName);
            if (field != null) {
                // 设置属性可访问
                field.setAccessible(true);
                if (field.isAnnotationPresent(ExcelField.class)) {
                    // 获取注解
                    excelField = field.getAnnotation(ExcelField.class);
                    columnName = excelField.columnName();
                    // 创建单元格
                    createCell(row, columnIndex, columnName, headerStyle);
                    columnIndex++;
                }
            }
        }

        // 行索引  因为表头已经设置,索引行索引从1开始
        int rowIndex = 1;
        for (Object obj : data) {
            // 创建新行,索引加1,为创建下一行做准备
            row = sheet.createRow(rowIndex++);
            columnIndex = 0;
            for (String fieldName : fieldNames) {
                Field field = existsField(aClass, fieldName);
                if (field != null) {
                    // 设置属性可访问
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(ExcelField.class)) {
                        try {
                            Object value = typeConvert(field.get(obj), field);
                            // 创建单元格  field.get(obj)从obj对象中获取值设置到单元格中
                            createCell(row, columnIndex, value, null);
                        } catch (IllegalAccessException e) {
                            LOGGER.error("对象非法访问异常", e);
                        }
                        columnIndex++;
                    }
                }
            }
        }

        return workbook;
    }

    /**
     * 写入Workbook
     *
     * @param data 数据集合
     */
    private static <T> Workbook writeWorkbook(List<?> data, Class<T> clazz, String fileName) {
        if (data.size() == 0) {
            return null;
        }

        Workbook workbook = buildWorkbook(fileName, data.size());

        // 判断是否设置“工作铺名称”
        String sheetName = "sheet";
        if (clazz.isAnnotationPresent(ExcelSheet.class)) {
            sheetName = clazz.getAnnotation(ExcelSheet.class).value();
        }
        Sheet sheet = workbook.createSheet(sheetName);

        // 设置表头(列名)
        Row row = sheet.createRow(0);

        CellStyle headerStyle = buildHeaderStyle(workbook);

        // 列索引
        int columnIndex = 0;
        // 列名称
        String columnName;
        ExcelField excelField;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field != null) {
                // 设置属性可访问
                field.setAccessible(true);
                if (field.isAnnotationPresent(ExcelField.class)) {
                    // 获取注解
                    excelField = field.getAnnotation(ExcelField.class);
                    columnName = excelField.columnName();
                    // 创建单元格
                    createCell(row, columnIndex, columnName, headerStyle);
                    columnIndex++;
                }
            }
        }

        // 行索引  因为表头已经设置,索引行索引从1开始
        int rowIndex = 1;
        JsonFormat jsonFormat;
        for (Object obj : data) {
            // 创建新行,索引加1,为创建下一行做准备
            row = sheet.createRow(rowIndex++);
            columnIndex = 0;
            for (Field field : declaredFields) {
                if (field != null) {
                    // 设置属性可访问
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(ExcelField.class)) {
                        try {
                            Object value = typeConvert(field.get(obj), field);
                            // 创建单元格  field.get(obj)从obj对象中获取值设置到单元格中
                            createCell(row, columnIndex, value, null);
                        } catch (IllegalAccessException e) {
                            LOGGER.error("对象非法访问异常", e);
                        }
                        columnIndex++;
                    }
                }
            }
        }

        return workbook;
    }

    /**
     * 写入workbook,可重复传入使用
     *
     * @param data 数据集合
     */
    private static <T> Workbook writeWorkbook(List<?> data, Class<T> clazz, List<String> fieldNames, String fileName, Workbook workbook) {
        Sheet sheet;
        Row row;
        // 行索引
        int rowIndex = 1;
        // 列索引
        int columnIndex = 0;

        if (workbook == null) {
            workbook = buildWorkbook(fileName, data.size());
            // 判断是否设置“工作铺名称”
            String sheetName = "sheet";
            if (clazz.isAnnotationPresent(ExcelSheet.class)) {
                sheetName = clazz.getAnnotation(ExcelSheet.class).value();
            }
            sheet = workbook.createSheet(sheetName);

            // 设置表头(列名)
            row = sheet.createRow(0);

            // 设置样式
            CellStyle headerStyle = buildHeaderStyle(workbook);

            // 列名称
            String columnName;
            ExcelField excelField;
            for (String fieldName : fieldNames) {
                Field field = existsField(clazz, fieldName);
                if (field != null) {
                    // 设置属性可访问
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(ExcelField.class)) {
                        // 获取注解
                        excelField = field.getAnnotation(ExcelField.class);
                        columnName = excelField.columnName();
                        // 创建单元格
                        createCell(row, columnIndex, columnName, headerStyle);
                        columnIndex++;
                    }
                }
            }
        } else {
            sheet = workbook.getSheetAt(0);
            rowIndex = sheet.getLastRowNum() + 1;
        }

        for (Object obj : data) {
            // 创建新行,索引加1,为创建下一行做准备
            row = sheet.createRow(rowIndex++);
            columnIndex = 0;
            for (String fieldName : fieldNames) {
                Field field = existsField(clazz, fieldName);
                if (field != null) {
                    // 设置属性可访问
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(ExcelField.class)) {
                        try {
                            // 创建单元格  field.get(obj)从obj对象中获取值设置到单元格中
                            createCell(row, columnIndex, field.get(obj), null);
                        } catch (IllegalAccessException e) {
                            LOGGER.error("对象非法访问异常", e);
                        }
                        columnIndex++;
                    }
                }
            }
        }

        return workbook;
    }


    /**
     * 读取Excel文件内容
     *
     * @param path  读取Excel文件的路径
     * @param clazz 返回的实体类泛型
     * @param <T>   泛型
     * @return 文件内容
     */
    public static <T> List<T> read(String path, Class<T> clazz) {
        return read(path, clazz, 0);
    }

    /**
     * 读取Excel文件内容
     *
     * @param path     读取Excel文件的路径
     * @param clazz    返回的实体类泛型
     * @param sheetNum sheet下标
     * @param <T>      泛型
     * @return 文件内容
     */
    public static <T> List<T> read(String path, Class<T> clazz, int sheetNum) {
        File file = new File(path);
        try (FileInputStream inputStream = new FileInputStream(file)) {
            return read(inputStream, file.getName(), clazz, sheetNum);
        } catch (Exception e) {
            LOGGER.error("读取Excel文件失败", e);
            return Collections.emptyList();
        }
    }

    /**
     * 读取Excel文件内容
     *
     * @param inputStream 读取Excel文件流
     * @param clazz       返回的实体类泛型
     * @param <T>         泛型
     * @return 文件内容
     */
    public static <T> List<T> read(InputStream inputStream, String fileName, Class<T> clazz) {
        return read(inputStream, fileName, clazz, 0);
    }

    /**
     * 读取Excel文件内容
     *
     * @param inputStream 读取Excel文件流
     * @param clazz       返回的实体类泛型
     * @param sheetNum    sheet下标
     * @param <T>         泛型
     * @return 文件内容
     */
    public static <T> List<T> read(InputStream inputStream, String fileName, Class<T> clazz, int sheetNum) {
        Workbook workbook = readWorkbook(inputStream, fileName);
        assert workbook != null;
        Sheet sheet = workbook.getSheetAt(sheetNum);
        // 判断是否设置“工作铺名称”
        if (clazz.isAnnotationPresent(ExcelSheet.class)) {
            String sheetName = clazz.getAnnotation(ExcelSheet.class).value();
            sheet = workbook.getSheet(sheetName);
        }
        // 获取总行数
        int rows = sheet.getLastRowNum() + 1;
        // 获取列名和列索引关系
        Map<String, Integer> columnMap = getColumnMap(sheet, clazz);

        // 获取类所有属性
        Field[] fields = getAllField(clazz);
        ExcelField excelField;
        // 存储读取到的excel数据
        List<T> list = new ArrayList<>();
        T t;
        Row row;
        Cell cell;
        int columnIndex;
        // 遍历Excel每行
        for (int i = 1; i < rows; i++) {
            row = sheet.getRow(i);
            // 判断空行
            if (isRowEmpty(row)) {
                continue;
            }

            try {
                t = clazz.newInstance();
                for (Field field : fields) {
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(ExcelField.class)) {
                        excelField = field.getAnnotation(ExcelField.class);
                        columnIndex = columnMap.get(excelField.columnName());
                        if (columnIndex != -1) {
                            cell = row.getCell(columnIndex);
                            setFieldValue(t, field, cell);
                        }
                    }
                }
                list.add(t);
            } catch (Exception e) {
                LOGGER.error("读取Excel文件失败", e);
            }
        }
        try {
            workbook.close();
        } catch (IOException e) {
            LOGGER.error("关闭workbook失败", e);
        }

        return list;
    }

    /**
     * 读取Excel文件内容
     */
    public static <T> List<T> read(String path, String[] fields, Class<T> clazz, int startRow) {
        List<T> content = new ArrayList<>();
        T t;
        File file = new File(path);
        Workbook workbook = readWorkbook(file);
        assert workbook != null;
        Sheet sheet = workbook.getSheetAt(0);
        // 得到总行数
        int rowNum = sheet.getLastRowNum();
        Row row = sheet.getRow(0);
        int colNum = row.getPhysicalNumberOfCells();
        for (int i = startRow; i <= rowNum; i++) {
            row = sheet.getRow(i);
            // 判断空行
            if (isRowEmpty(row)) {
                continue;
            }

            int j = 0;
            try {
                t = clazz.newInstance();
                while (j < colNum) {
                    //当 j 等于传入的 fields 数组长度时 跳过循环 防止出现数组越界异常
                    if (j == fields.length) {
                        break;
                    }
                    Field declaredField = clazz.getDeclaredField(fields[j]);
                    declaredField.setAccessible(true);
                    setFieldValue(t, declaredField, row.getCell(j));
                    j++;
                }
                content.add(t);
            } catch (InstantiationException | IllegalAccessException | NoSuchFieldException e) {
                LOGGER.error("读取Excel文件失败", e);
            }
        }
        return content;
    }

    /**
     * 读取Excel文件内容
     *
     * @param path 读取Excel文件的路径
     * @return 文件内容Map集合
     */
    public static List<Map<String, Object>> read(String path) {
        File file = new File(path);
        Workbook workbook = readWorkbook(file);
        assert workbook != null;
        Sheet sheet = workbook.getSheetAt(0);
        // 获取总行数
        int rows = sheet.getLastRowNum() + 1;
        // 获取所有列名

        Row columnNameRow = sheet.getRow(0);
        String[] columnNameArr = new String[columnNameRow.getLastCellNum()];
        for (int i = 0; i < columnNameArr.length; i++) {
            columnNameArr[i] = columnNameRow.getCell(i).getStringCellValue();
        }

        // 存储读取到的excel数据
        List<Map<String, Object>> list = new ArrayList<>();

        Map<String, Object> data;
        Row row;
        // 遍历Excel每行
        for (int i = 1; i < rows; i++) {
            row = sheet.getRow(i);
            // 判断空行
            if (isRowEmpty(row)) {
                continue;
            }

            try {
                data = new HashMap<>();

                for (int j = 0; j < columnNameArr.length; j++) {
                    data.put(columnNameArr[j], getCellValue(row.getCell(j)));
                }
                list.add(data);
            } catch (Exception e) {
                LOGGER.error("读取Excel文件失败", e);
            }
        }
        try {
            workbook.close();
        } catch (IOException e) {
            LOGGER.error("关闭workbook失败", e);
        }

        return list;
    }

    /**
     * 创建sheet列名称
     */
    private static <T> void createSheetColumnName(Sheet sheet, CellStyle cellStyle, Class<T> clazz, int startRowNum) {
        Row row = sheet.createRow(startRowNum);
        row.setHeight((short) (20 * 20));
        int columnIndex = 0;
        String columnName;
        ExcelField excelField;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field != null) {
                // 设置属性可访问
                field.setAccessible(true);
                if (field.isAnnotationPresent(ExcelField.class)) {
                    // 获取注解
                    excelField = field.getAnnotation(ExcelField.class);
                    columnName = excelField.columnName();
                    // 创建单元格
                    createCell(row, columnIndex, columnName, cellStyle);
                    columnIndex++;
                }
            }
        }

    }

    /**
     * 创建sheet数据
     */
    private static <T> void createSheetColumnValue(Sheet sheet, CellStyle cellStyle, List<?> data, Class<T> clazz, Integer startRowNum) {
        int tempStartRowNum = startRowNum;
        Row row;
        int columnIndex;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Object obj : data) {
            // 创建新行,索引加1,为创建下一行做准备
            row = sheet.createRow(startRowNum++);
            row.setHeight((short) (20 * 20));
            columnIndex = 0;
            for (Field field : declaredFields) {
                if (field != null) {
                    // 设置属性可访问
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(ExcelField.class)) {
                        try {
                            Object value = typeConvert(field.get(obj), field);
                            // 创建单元格  field.get(obj)从obj对象中获取值设置到单元格中
                            createCell(row, columnIndex, value, cellStyle);
                        } catch (IllegalAccessException e) {
                            LOGGER.error("对象非法访问异常", e);
                        }
                        columnIndex++;
                    }
                }
            }
        }

        ExcelField excelField;
        Field field;
        for (int i = 0; i < declaredFields.length; i++) {
            field = declaredFields[i];
            if (field != null) {
                // 设置属性可访问
                field.setAccessible(true);
                if (field.isAnnotationPresent(ExcelField.class)) {
                    // 获取注解
                    excelField = field.getAnnotation(ExcelField.class);
                    if (excelField.mergeColumnCell()) {
                        mergeColCell(sheet, i, tempStartRowNum, startRowNum - 1);
                    }
                }
            }
        }

    }

    /**
     * 生成Workbook
     */
    private static Workbook buildWorkbook(String fileName, int total) {
        Workbook workbook = null;
        if (fileName.endsWith(EXCEL_XLS)) { // Excel 2003
            workbook = new HSSFWorkbook();
        } else if (fileName.endsWith(EXCEL_XLSX)) { // Excel 2007/2010
            if (total < 1000) {
                workbook = new XSSFWorkbook();
            } else {
                workbook = new SXSSFWorkbook();
            }
        }
        return workbook;
    }

    /**
     * 读取文件的Workbook
     */
    private static Workbook readWorkbook(File file) {
        Workbook workbook = null;
        try (FileInputStream inputStream = new FileInputStream(file)) {
            checkExcelValid(file);
            if (file.getName().endsWith(EXCEL_XLS)) { // Excel 2003
                workbook = new HSSFWorkbook(inputStream);
            } else if (file.getName().endsWith(EXCEL_XLSX)) { // Excel 2007/2010
                workbook = new XSSFWorkbook(inputStream);
            }
        } catch (Exception e) {
            LOGGER.error("读取Workbook异常", e);
        }
        return workbook;
    }

    /**
     * 读取文件的Workbook
     */
    private static Workbook readWorkbook(InputStream inputStream, String fileName) {
        Workbook workbook = null;
        try {
            if (fileName.endsWith(EXCEL_XLS)) { // Excel 2003
                workbook = new HSSFWorkbook(inputStream);
            } else if (fileName.endsWith(EXCEL_XLSX)) { // Excel 2007/2010
                workbook = new XSSFWorkbook(inputStream);
            }
        } catch (Exception e) {
            LOGGER.error("读取Workbook异常", e);
        }
        return workbook;
    }

    /**
     * 获取列名和列索引关系
     */
    private static <T> Map<String, Integer> getColumnMap(Sheet sheet, Class<T> clazz) {
        // 获取类所有属性
        Field[] fields = getAllField(clazz);
        ExcelField excelField;
        // 获取列名和列索引关系
        Map<String, Integer> columnMap = new HashMap<>();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(ExcelField.class)) {
                excelField = field.getAnnotation(ExcelField.class);
                columnMap.put(excelField.columnName(), getColumnIndex(sheet, excelField.columnName()));
            }
        }

        return columnMap;
    }

    /**
     * 创建Excel单元格
     */
    private static void createCell(Row row, int c, Object cellValue, CellStyle style) {
        Cell cell = row.createCell(c);
        cell.setCellStyle(style);
        //        cell.setCellType(Cell.CELL_TYPE_STRING);
        if (cellValue != null) {
            cell.setCellValue(String.valueOf(cellValue));
        } else {
            cell.setCellValue("");
        }
    }

    /**
     * 获取Excel单元格内容
     */
    private static String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }
        // 把数字当成String来读,避免出现1读成1.0的情况
    /*if(cell.getCellType() == CellType.NUMERIC){
        cell.setCellType(CellType.STRING);
    }*/
        // 判断数据的类型
        switch (cell.getCellType()) {
            case NUMERIC: // 数字
                SimpleDateFormat sdf = null;
                if (HSSFDateUtil.isCellDateFormatted(cell)) { // 处理日期格式、时间格式
                    if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
                        sdf = new SimpleDateFormat("HH:mm");
                    } else { // 日期
                        sdf = new SimpleDateFormat("yyyy-MM-dd");
                    }
                    Date date = cell.getDateCellValue();
                    cellValue = sdf.format(date);
                } else if (cell.getCellStyle().getDataFormat() == 58) {
                    // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    double value = cell.getNumericCellValue();
                    Date date = DateUtil.getJavaDate(value);
                    cellValue = sdf.format(date);
                } else {
                    cell.setCellType(CellType.STRING);
                    cellValue = String.valueOf(cell.getStringCellValue());
                }
                break;
            case STRING: // 字符串
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case BOOLEAN: // Boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA: // 公式
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case BLANK: // 空值
                cellValue = "";
                break;
            case ERROR: // 故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }

    /**
     * 设置对象属性值
     *
     * @param obj   操作对象
     * @param field 对象属性
     * @param cell  excel单元格
     */
    private static void setFieldValue(Object obj, Field field, Cell cell) {
        try {
            if (cell != null) {
                String cellValue = getCellValue(cell);
                if (!(cellValue == null || cellValue.length() == 0)) {
                    if (field.getType() == int.class || field.getType() == Integer.class) {
                        field.set(obj, Integer.valueOf(cellValue));
                    } else if (field.getType() == Double.class) {
                        field.set(obj, Double.parseDouble(cellValue));
                    } else if (field.getType() == LocalDate.class) {
                        field.set(obj, LocalDate.parse(cellValue, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                    } else {
                        field.set(obj, cellValue);
                    }
                }
            } else {
                if (field.getType() == Number.class) {
                    field.setInt(obj, 0);
                } else {
                    field.set(obj, null);
                }
            }
        } catch (Exception e) {
            LOGGER.error("设置对象属性值", e);
        }
    }

    /**
     * 创建文件
     *
     * @param path 文件路径
     */
    private static void createFile(String path) {
        if (!Files.exists(Paths.get(path))) {
            try {
                Files.createDirectories(Paths.get(path).getParent());
                Files.createFile(Paths.get(path));
            } catch (IOException e) {
                LOGGER.error("创建文件失败:{}", path, e);
            }
        }
    }

    /**
     * 校验Excel文件
     */
    private static void checkExcelValid(File file) {
        if (file == null || !Files.exists(file.toPath())) {
            throw new RuntimeException("文件不存在");
        }
        if (!((file.getName().endsWith(EXCEL_XLS) || file.getName().endsWith(EXCEL_XLSX)))) {
            throw new RuntimeException("不是Excel文件");
        }
    }

    /**
     * 根据列名(第一行)获取列索引
     *
     * @param sheet      工作铺
     * @param columnName 列名
     * @return 列索引
     */
    private static int getColumnIndex(Sheet sheet, String columnName) {
        int coefficient = -1;
        Row row = sheet.getRow(0);
        int cellNum = row.getPhysicalNumberOfCells();
        for (int i = 0; i < cellNum; i++) {
            if ((row.getCell(i).toString()).equals(columnName)) {
                coefficient = i;
            }
        }
        return coefficient;
    }

    /**
     * 检验是否空行
     */
    private static boolean isRowEmpty(Row row) {
        if (row == null) {
            return true;
        }
        for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
            Cell cell = row.getCell(c);
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                return false;
            }
        }
        return true;
    }

    /**
     * 数据转换
     */
    private static Object typeConvert(Object value, Field field) {
        if (value != null) {
            JsonFormat jsonFormat;
            String pattern = "yyyy-MM-dd";
            if (field.getType() == Date.class || field.getType() == LocalDateTime.class || field.getType() == LocalDate.class) {
                if (field.isAnnotationPresent(JsonFormat.class)) {
                    jsonFormat = field.getAnnotation(JsonFormat.class);
                    pattern = jsonFormat.pattern();
                }
                if (field.getType() == Date.class) {
                    value = DateUtils.format((Date) value, pattern);
                } else if (field.getType() == LocalDate.class) {
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
                    value = formatter.format((LocalDate) value);
                } else if (field.getType() == LocalDateTime.class) {
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
                    value = formatter.format((LocalDateTime) value);
                }
            }
        }

        return value;
    }

    /**
     * 合并单元格
     */
    private static void mergeColCell(Sheet sheet, int colNum, int startRow, int endRow) {
        sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, colNum, colNum));
    }

    /**
     * 写入sheet
     */
    private static <T> void writeSheet(Sheet sheet, Workbook workbook, List<?> data, Class<T> clazz, Integer startRowNum) {
        sheet.setDefaultRowHeightInPoints(20);
        // 设置列名样式
        CellStyle headerStyle = buildHeaderStyle(workbook);
        createSheetColumnName(sheet, headerStyle, clazz, startRowNum);
        startRowNum++;
        // 内容样式
        CellStyle contentStyle = buildContentStyle(workbook);
        createSheetColumnValue(sheet, contentStyle, data, clazz, startRowNum);
    }

    /**
     * 生成列名样式
     */
    private static CellStyle buildHeaderStyle(Workbook workbook) {
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.TEAL.getIndex());
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        Font font = workbook.createFont();
        font.setFontName("黑体");
        font.setColor(IndexedColors.WHITE.getIndex());
        font.setFontHeightInPoints((short) 12);
        headerStyle.setFont(font);
        return headerStyle;
    }

    /**
     * 生成内容样式
     */
    private static CellStyle buildContentStyle(Workbook workbook) {
        CellStyle contentStyle = workbook.createCellStyle();
        contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        return contentStyle;
    }

    /**
     * 判断是否存在某一字段,存在则返回,否则返回null
     */
    private static Field existsField(Class<?> clazz, String fieldName) {
        Field[] fields = clazz.getDeclaredFields();

        clazz = clazz.getSuperclass();
        while (clazz != null) {
            fields = ArrayUtils.addAll(fields, clazz.getDeclaredFields());
            clazz = clazz.getSuperclass();
        }

        for (Field field : fields) {
            if (fieldName.equals(field.getName())) {
                return field;
            }
        }
        return null;
    }

    /**
     * 获得所有字段,包括父类的所有字段
     */
    private static Field[] getAllField(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();

        clazz = clazz.getSuperclass();
        while (clazz != null) {
            fields = ArrayUtils.addAll(fields, clazz.getDeclaredFields());
            clazz = clazz.getSuperclass();
        }

        return fields;
    }

}

注意:导出任务数据量近100W甚至更多,导出的项目就会内存溢出,挂掉。

推荐使用:EasyExcel,Java使用EasyExcel读取写入Excel

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值