【工具篇】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

目录
相关文章
|
4天前
|
Java
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
16 5
|
3天前
|
Java 数据库
java小工具util系列1:日期和字符串转换工具
java小工具util系列1:日期和字符串转换工具
11 3
|
4天前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
14 4
|
3天前
|
SQL 安全 Java
JAVA代码审计SAST工具使用与漏洞特征
JAVA代码审计SAST工具使用与漏洞特征
15 1
|
3天前
|
SQL Java 索引
java小工具util系列2:字符串工具
java小工具util系列2:字符串工具
7 2
|
5天前
|
JSON Java fastjson
java小工具util系列3:JSON和实体类转换工具
java小工具util系列3:JSON和实体类转换工具
11 2
|
29天前
|
Arthas Java 测试技术
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
Java字节码文件、组成、详解、分析;常用工具,jclasslib插件、阿里arthas工具;如何定位线上问题;Java注解
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
|
15天前
|
存储 Java
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
34 2
|
24天前
|
监控 IDE Java
【Java性能调优新工具】JDK 22性能分析器:深度剖析,优化无死角!
【9月更文挑战第9天】JDK 22中的性能分析器为Java应用的性能调优提供了强大的支持。通过深度集成、全面监控、精细化分析和灵活报告生成等核心优势,性能分析器帮助开发者实现了对应用性能的全面掌控和深度优化。在未来的Java开发过程中,我们期待性能分析器能够继续发挥重要作用,为Java应用的性能提升贡献更多力量。
|
24天前
|
Java 数据处理
技术分享:高效与灵活并存——Java版通用树形结构转换工具的实现与应用
在软件开发中,树形结构的数据表现形式无处不在,从文件系统的目录树到组织架构的部门树,再到各类产品的分类结构。处理这些具有层级关系的数据时,将其转换为树形结构以便展示和操作显得尤为重要。Java作为一门成熟的编程语言,虽然提供了强大的集合框架,但并未直接提供树形结构转换的内置工具。因此,开发一个高效且灵活的通用树形结构转换工具成为许多项目中的必备需求。
29 2
下一篇
无影云桌面