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

目录
打赏
0
0
0
0
27
分享
相关文章
银行转账虚拟生成器app,银行卡转账截图制作软件,java实现截图生成工具【仅供装逼娱乐用途】
本项目提供了一套基于Java的图片处理教学方案,包含自定义图片生成、图像水印添加及合法电子凭证生成技术示例。
银行转账虚拟生成器app,银行卡转账截图制作软件,java实现截图生成工具【仅供装逼娱乐用途】
本内容提供Java生成自定义图片的示例代码,涵盖基础图像创建、文本添加及保存功能,适合学习2D图形编程。包括教学示例图片生成、文本图层处理和数字水印技术实现方案。
|
24天前
|
JD-GUI,java反编译工具及原理: JavaDecompiler一个Java反编译器
Java Decompiler (JD-GUI) 是一款由 Pavel Kouznetsov 开发的图形化 Java 反编译工具,支持 Windows、Linux 和 Mac Os。它能将 `.class` 文件反编译为 Java 源代码,支持多文件标签浏览、高亮显示,并兼容 Java 5 及以上版本。JD-GUI 支持对整个 Jar 文件进行反编译,可跳转源码,适用于多种 JDK 和编译器。其原理基于将字节码转换为抽象语法树 (AST),再通过反编译生成代码。尽管程序可能带来安全风险,但可通过代码混淆降低可读性。最新版修复了多项识别错误并优化了内存管理。
382 1
使用CodeBuddy实现批量转换PPT、Excel、Word为PDF文件工具
通过 CodeBuddy 实现本地批量转换工具,让复杂的文档处理需求转化为 “需求描述→代码生成→一键运行” 的极简流程,真正实现 “技术为效率服务” 的目标。感兴趣的快来体验下把
96 10
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
91 0
从Excel到高级工具:数据分析进阶指南
从Excel到高级工具:数据分析进阶指南
151 54
6个Java 工具,轻松分析定位 JVM 问题 !
本文介绍了如何使用 JDK 自带工具查看和分析 JVM 的运行情况。通过编写一段测试代码(启动 10 个死循环线程,分配大量内存),结合常用工具如 `jps`、`jinfo`、`jstat`、`jstack`、`jvisualvm` 和 `jcmd` 等,详细展示了 JVM 参数配置、内存使用、线程状态及 GC 情况的监控方法。同时指出了一些常见问题,例如参数设置错误导致的内存异常,并通过实例说明了如何排查和解决。最后附上了官方文档链接,方便进一步学习。
259 4
列表结构与树结构转换分析与工具类封装(java版)
本文介绍了将线性列表转换为树形结构的实现方法及工具类封装。核心思路是先获取所有根节点,将其余节点作为子节点,通过递归构建每个根节点的子节点。关键在于节点需包含 `id`、`parentId` 和 `children` 三个属性。文中提供了两种封装方式:一是基于基类 `BaseTree` 的通用工具类,二是使用函数式接口实现更灵活的方式。推荐使用后者,因其避免了继承限制,更具扩展性。代码示例中使用了 Jackson 库进行 JSON 格式化输出,便于结果展示。最后总结指出,理解原理是进一步优化和封装的基础。
Probly:开源 AI Excel表格工具,交互式生成数据分析结果与可视化图表
Probly 是一款结合电子表格功能与 Python 数据分析能力的 AI 工具,支持在浏览器中运行 Python 代码,提供交互式电子表格、数据可视化和智能分析建议,适合需要强大数据分析功能又希望操作简便的用户。
522 2
从Excel到大数据:别让工具限制你的思维!
从Excel到大数据:别让工具限制你的思维!
231 85
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问