【工具篇】java导入excel工具类,简单通用,绝对值得你收藏

简介: 【工具篇】java导入excel工具类,简单通用,绝对值得你收藏

定义导入的excel模板


定义需要导入的EXCEL模板,EXCEL格式变更,只需要变更对应的枚举信息就可以,如果定义多个EXCEL模板,

只要定义多个枚举就行

package org.util.excel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @author zhangfuzeng
 * @date 2021/9/12
 */
public class ImportExcelTitle {
    @Getter
    @AllArgsConstructor
    public enum TaskImportExcel {
        /**
         * 表头信息
         */
        PUBLIC_DATA_ID("ID", "publicDataId", 0, true),
        PUBLIC_DATA_NAME("名称", "publicDataName", 40, true),
        TASK_USER_NAME("任务担当人", "taskUserName", 0, false),
        END_TIME("任务到期日", "endTime", 0, false),
        ;
        /**
         * 中文标题,对应EXCEL的标题,不一致会报错
         */
        private final String titleCn;
        /**
         * 查出的值对应Map的key
         */
        private final String valueKey;
        /**
         * 对应的字段长度
         * 为0时代表不限制
         */
        private final Integer titleLength;
        /**
         * 是否必填
         */
        private final Boolean isRequired;
        /**
         * 获取excel对应的数据
         */
        public static Map<String, String> getKeyValue() {
            return Arrays.stream(TaskImportExcel.values()).collect(
                    Collectors.toMap(TaskImportExcel::getTitleCn, TaskImportExcel::getValueKey));
        }
        /**
         * 根据值获取对应的信息
         */
        public static Map<String, TaskImportExcel> getExcelTitle() {
            return Arrays.stream(TaskImportExcel.values()).collect(
                    Collectors.toMap(TaskImportExcel::getValueKey, title -> title));
        }
        public static List<String> checkData(TaskImportExcel taskImportExcel, String value) {
            return checkDataCommon(value, taskImportExcel.getIsRequired(), taskImportExcel.getTitleCn(), taskImportExcel.getTitleLength());
        }
    }
    /**
     * 校验导入信息长度和必填选项
     */
    private static List<String> checkDataCommon(String value, Boolean isRequired, String titleCn, Integer titleLength) {
        List<String> result = new ArrayList<>();
        if (Boolean.TRUE.equals(isRequired) && StringUtils.isBlank(value)) {
            result.add(String.format("%s信息未填", titleCn));
        }
        if (titleLength != 0 && value != null && value.length() > titleLength) {
            result.add(String.format("%s过长", titleCn));
        }
        return result;
    }
}

导入的excel处理


对导入的excel进行处理,按照上述ImportExcelTitle.java中的配置,将导入的excel转化成List<Map<String, String>>格式,

Map<String, String>中key是ImportExcelTitle.java中定义的valueKey,value对应的是excel导入的值。

package org.util.excel;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @author zhangfuzeng
 * @date 2021/9/16
 */
@Slf4j
public class ImportExcelUtil {
    private ImportExcelUtil() {
    }
    /**
     * 2003- 版本的excel
     */
    private static final String EXCEL_2003L = ".xls";
    /**
     * 2007+ 版本的excel
     */
    private static final String EXCEL_2007U = ".xlsx";
    private static final String GENERAL = "General";
    private static final String M_D_YY = "m/d/yy";
    /**
     * 将流中的Excel数据转成List<Map>
     *
     * @param in       输入流
     * @param fileName 文件名(判断Excel版本)
     * @return EXCEL转化后的数据
     */
    public static List<Map<String, String>> parseExcel(InputStream in, String fileName, Map<String, String> titleKey) throws IOException {
        // 根据文件名来创建Excel工作薄
        Workbook work = getWorkbook(in, fileName);
        Sheet sheet;
        Row row;
        Cell cell;
        // 返回数据
        List<Map<String, String>> ls = new ArrayList<>();
        // 遍历Excel中所有的sheet
        sheet = work.getSheetAt(0);
        if (sheet == null) {
            return ls;
        }
        // 取第一行标题
        Row topRow = sheet.getRow(0);
        if (null == topRow) {
            return ls;
        }
        row = sheet.getRow(0);
        String[] title;
        if (row == null) {
            return ls;
        }
        title = new String[row.getLastCellNum()];
        for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
            cell = row.getCell(y);
            title[y] = (String) getCellValue(cell);
        }
        // 遍历当前sheet中的所有行
        // 坑:sheet.getLastRowNum()  最后一行行标,比行数小1
        for (int j = 1; j <= sheet.getLastRowNum(); j++) {
            row = sheet.getRow(j);
            Map<String, String> m = new HashMap<>(row.getLastCellNum());
            // 遍历所有的列
            for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
                cell = row.getCell(y);
                String key = title[y].replace(" ", "");
                if (titleKey.get(key) == null) {
                    log.error("导入excel出现错误的标题:" + key);
                    throw new RuntimeException("excel出现错误的标题:" + key);
                }
                m.put(titleKey.get(key), getCellValue(cell).toString().trim());
            }
            ls.add(m);
        }
        work.close();
        return ls;
    }
    /**
     * 描述:根据文件后缀,自适应上传文件的版本
     *
     * @param inStr ,fileName
     * @return 返回的数据
     */
    public static Workbook getWorkbook(InputStream inStr, String fileName) throws IOException {
        Workbook wb;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        if (EXCEL_2003L.equals(fileType)) {
            // 2003-
            wb = new HSSFWorkbook(inStr);
        } else if (EXCEL_2007U.equals(fileType)) {
            // 2007+
            wb = new XSSFWorkbook(inStr);
        } else {
            throw new RuntimeException("解析的文件格式有误!");
        }
        return wb;
    }
    public static Object getCellValue(Cell cell) {
        Object value = new Object();
        // 日期格式化
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");
        if (cell == null) {
            return "";
        }
        switch (cell.getCellType()) {
            case STRING:
            case FORMULA:
                value = cell.getRichStringCellValue().getString();
                break;
            case NUMERIC:
                if (GENERAL.equals(cell.getCellStyle().getDataFormatString())) {
                    double cellValue = cell.getNumericCellValue();
                    value = replace(String.valueOf(cellValue));
                } else if (M_D_YY.equals(cell.getCellStyle().getDataFormatString())) {
                    value = sdf.format(cell.getDateCellValue());
                } else {
                    DataFormatter formatter = new DataFormatter();
                    // 直接获取到单元格的值
                    value = formatter.formatCellValue(cell);
                }
                break;
            case BOOLEAN:
                value = cell.getBooleanCellValue();
                break;
            case BLANK:
                value = "";
                break;
            default:
                break;
        }
        return value;
    }
    public static String replace(String s) {
        char a = '.';
        if (s.indexOf(a) >= 0) {
            //去掉多余的0  
            s = s.replaceAll("0+$", "");
            //如最后一位是.则去掉  
            s = s.replaceAll("[.]$", "");
        }
        return s;
    }
}

调用导入任务信息


测试调用, 拿到List<Map<String, String>> excelList就是解析excel的结果,后续根据自己的业务做相应的处理。

    @ApiOperation(value = "导入任务信息")
    @PostMapping("/importTask")
    public void importTask(@RequestParam(value = "file") MultipartFile fileToUpload) {
        List<Map<String, String>> excelList;
        try {
            excelList = ImportExcelUtil.parseExcel(
                    fileToUpload.getInputStream(),
                    fileToUpload.getOriginalFilename(),
                    ImportExcelTitle.TaskImportExcel.getKeyValue());
        } catch (IOException e) {
            log.error("解析excel时失败" + e.getMessage());
        }
    }

如果你觉着本文配置太过复杂,想直接可以使用,或者导入的数据量过大,想优化性能,可以看我的另一篇博客,使用阿里的easyExcel工具包,上手绝对快的一批

JAVA使用EasyExcel导入excel

目录
相关文章
|
21天前
|
Java API Apache
Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
【10月更文挑战第29天】Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
88 5
|
1月前
|
监控 Java 测试技术
Java开发现在比较缺少什么工具?
【10月更文挑战第15天】Java开发现在比较缺少什么工具?
36 1
|
1月前
|
人工智能 Python
读取excel工具:openpyxl | AI应用开发
`openpyxl` 是一个 Python 库,专门用于读写 Excel 2010 xlsx/xlsm/xltx/xltm 文件。它是处理 Excel 文件的强大工具,可以让你在不需要安装 Excel 软件的情况下,对 Excel 文件进行创建、修改、读取和写入操作【10月更文挑战第3天】
74 0
|
16天前
|
SQL 数据可视化 数据挖掘
想让Excel表格设计更美观?试试这几款好用工具!
Excel表格设计在项目管理和数据分析中至关重要。本文推荐四款辅助工具:板栗看板、Excel自动图表助手、Think-Cell Chart 和 Power BI,分别在任务管理、图表生成、数据可视化等方面表现突出,帮助你设计出更专业、美观的表格。
33 2
|
21天前
|
Java API Apache
|
24天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
33 4
|
27天前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
|
27天前
|
Java API Maven
如何使用 Java 字节码工具检查类文件的完整性
本文介绍如何利用Java字节码工具来检测类文件的完整性和有效性,确保类文件未被篡改或损坏,适用于开发和维护阶段的代码质量控制。
|
27天前
|
数据处理
在Excel中,通配符是一种强大的工具
【10月更文挑战第23天】在Excel中,通配符是一种强大的工具
22 4
|
29天前
|
Web App开发 Java
使用java操作浏览器的工具selenium-java和webdriver下载地址
【10月更文挑战第12天】Selenium-java依赖包用于自动化Web测试,版本为3.141.59。ChromeDriver和EdgeDriver分别用于控制Chrome和Edge浏览器,需确保版本与浏览器匹配。示例代码展示了如何使用Selenium-java模拟登录CSDN,包括设置驱动路径、添加Cookies和获取页面源码。
下一篇
无影云桌面