导入Excel工具类

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

@Component
public class ImportExcelUtil {
    /**
     * 导入Excel将每行数据存为List<String>
     *
     * @param file:文件
     * @param cellTypes:key:=列数 列下标从0开始
     *                          value:列类型:  0:numeric
     *                          1:string
     * @param requiredCol:必填列
     * @return List<List < String>>
     */
    public static List<List<String>> importExcel(MultipartFile file, LinkedHashMap<Integer, Integer> cellTypes, List<Integer> requiredCol) throws Exception {
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file.getInputStream());
        XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
        //存储所有行数据
        List<List<String>> rows = new ArrayList<>();
        if (xssfSheet != null) {
            //从文件第二行开始解析数据
            for (int i = 1; i <= xssfSheet.getLastRowNum(); i++) {
                XSSFRow xssfRow = xssfSheet.getRow(i);
                //本行不为空且列数size不为0
                if (xssfRow != null && xssfRow.getPhysicalNumberOfCells() != 0) {
                    //存储单行数据
                    List<String> row = new ArrayList<>();
                    //解析列数据 key;第几列   value:列类型
                    int blankCellCount = 0;
                    int cellCount = cellTypes.size();
                    Integer[] cellNums = new Integer[cellCount];
                    for (Map.Entry<Integer, Integer> m : cellTypes.entrySet()) {//循环每列
                        String cellData = null;
                        Integer cellNum = m.getKey();
                        Integer cellType = m.getValue();
                        XSSFCell cell = xssfRow.getCell(cellNum);
                        //当前单元格不为空
                        if (cell != null && cell.getCellType() != 3) {
                            xssfRow.getCell(cellNum).setCellType(cellType);
                            if (cellType == 0) {//数值型
                                cellData = String.valueOf(xssfRow.getCell(cellNum).getNumericCellValue()).trim();
                            }
                            if (cellType == 1) {//字符串型
                                cellData = xssfRow.getCell(cellNum).getStringCellValue().trim();
                            }
                            row.add(cellData);
                        } else if (cell != null && cell.getCellType() == 5) {//错误型
                            throw new Exception((i + 1) + "行" + (cellNum + 1) + "列为错误单元格");
                        } else if (cell == null || cell.getCellType() == 3) {//空值型
                            blankCellCount++;
                            cellNums[blankCellCount - 1] = cellNum;
                            cellData = "0";
                            row.add(cellData);
                        }
                    }

                    if (blankCellCount != 0 && blankCellCount != cellCount) {
                        //存在为空的列且不是所有列都为空,找为空的列判断该列是否是必填列
                        for (Integer cellNum : cellNums) {
                            if (requiredCol.size() > 0 && requiredCol.contains(cellNum)) {
                                row.clear();
                                throw new Exception("第"+(i + 1) + "行第" + (cellNum + 1) + "列数据错误,必填项不可为空");
                            } else {
                                continue;
                            }
                        }
                        //存在为空的列且所有列都为空
                    } else if (blankCellCount == cellCount) {
                        row.clear();
                    }
                    if (row.size() != 0) {
                        rows.add(row);
                    }

                }
            }
        }
        return rows;
    }
}

原文地址:https://www.cnblogs.com/xiaoyinger/p/12103734.html

时间: 2024-11-05 13:50:17

导入Excel工具类的相关文章

使用回调方式写POI导入excel工具类

场景是这样的:为了做一个excel导入的功能,为了尽可能的写一个通用的工具类,将与poi有关的东西都封装起来,以便以其他人员只用关心自己的业务,不用和poi打交道. 写到最后,现在还是会有poi的东西暴漏出来一点,暴漏出来的这个应该是必须的. 为了模拟这个场景,先写两个service方法,用于和数据库交互,存入从模板中读取的数据.代码如下: 1.berthservice public class BerthService { public void update(){ System.out.pr

java中excel导入\导出工具类

1.导入工具 1 package com.linrain.jcs.test; 2 3 4 import jxl.Cell; 5 import jxl.Sheet; 6 import jxl.Workbook; 7 import jxl.write.Label; 8 import jxl.write.WritableSheet; 9 10 import java.io.InputStream; 11 import java.lang.reflect.Field; 12 import java.te

一个基于POI的通用excel导入导出工具类的简单实现及使用方法

前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴.经过思考,认为一百个客户在录入excel的时候,就会有一百个格式版本,所以在实现这个功能之前,所以要统一excel的格式.于是提供了一个通用excel模版的下载功能.当所有客户用模版录入好数据再上传到系统,后端对excel进行解析,然后再持久化到数据库. 概述: 此工具类的几大特点 1.基本导入导出

配置简单功能强大的excel工具类搞定excel导入导出工具类(一)

对于J2EE项目导入导出Excel是最普通和实用功能,本工具类使用步骤简单,功能强大,只需要对实体类进行简单的注解就能实现导入导出功能,导入导出操作的都是实体对象. 请看一下这个类都有哪些功能:????? 1.实体属性配置了注解就能导出到excel中,每个属性都对应一列.????? 2.列名称可以通过注解配置.????? 3.导出到哪一列可以通过注解配置.????? 4.鼠标移动到该列时提示信息可以通过注解配置.????? 5.用注解设置只能下拉选择不能随意填写功能.???? ? 6.用注解设置

javaEE开发之导出excel工具类

web开发中,一个系统的普通需求也包含导出excel,一般採用POI做统计报表导出excel. 导出excel工具类: import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import o

Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类

Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类 ============================== ?Copyright 蕃薯耀 2017年9月13日 http://www.cnblogs.com/fanshuyao/ 直接上代码: import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.ref

web开发之导出excel工具类

web开发中,一个系统的普通需求也包括导出excel,一般采用POI做统计报表导出excel. 导出excel工具类: import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import o

【原创】POI操作Excel导入导出工具类ExcelUtil

关于本类线程安全性的解释: 多数工具方法不涉及共享变量问题,至于添加合并单元格方法addMergeArea,使用ThreadLocal变量存储合并数据,ThreadLocal内部借用Thread.ThreadLocalMap以当前ThreadLocal为key进行存储,设置一次变量,则其他线程也会有上次数据的残留,因此在addMergeArea方法中进行清空的操作.为了保证原子性, 采用ReentrantLock确保一次只有一个线程可以进行添加合并数据的操作. 线程安全性从以上两个方面保证. 水

JXL导出Excel工具类

将Excel中的数据读取到List<Map<String, Object>>集合中 package com.mvc.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field;