spring boot如何使用POI读取Excel文件

目录
  • spring boot 使用POI读取Excel文件
    • Excel文件目录
    • 重要说明
    • 读取Excel文件
    • 获取sheet表格及读写单元格内容
    • 合并单元格
  • SpringBoot解析Excel
    • 以批量导入课程为例

spring boot 使用POI读取Excel文件

Excel文件目录

Excel模板文件存了resourse目录下,如下图:

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

重要说明

如果是xls格式,使用HSSFWorkbook,HSSFSheet,HSSFRow来进行相关操作

如果是xlsx格式,使用XSSFWorkbook,XSSFSheet,XSSFRow来进行相关操作

读取Excel文件

// 定义一个数据格式化对象
XSSFWorkbook wb = null;
try {
    //excel模板路径
    File cfgFile = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "static/ExcelTemplate/ContradictionMatrix.xlsx");
    InputStream in = new FileInputStream(cfgFile);
    //读取excel模板
    wb = new XSSFWorkbook(in);
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

获取sheet表格及读写单元格内容

//获取sheet表格,及读取单元格内容
XSSFSheet sheet = null;
try{
    sheet = wb.getSheetAt(0);
    //先将获取的单元格设置为String类型,下面使用getStringCellValue获取单元格内容
    //如果不设置为String类型,如果单元格是数字,则报如下异常
    //java.lang.IllegalStateException: Cannot get a STRING value from a NUMERIC cell
    sheet.getRow(2).getCell(2).setCellType(CellType.STRING);
    //读取单元格内容
    String cellValue = sheet.getRow(2).getCell(2).getStringCellValue();

    //添加一行
    XSSFRow row = sheet.createRow(1); //第2行开始写数据
    row.setHeight((short)400); //设置行高
    //向单元格写数据
    row.createCell(1).setCellValue("名称");
}
catch (Exception e){
    e.printStackTrace();
}

合并单元格

使用下面的语句合并单元格:

sheet.addMergedRegion(new CellRangeAddress(0,2,15,18));

看一下CellRangeAddress的构造函数:

/**
 * Creates new cell range. Indexes are zero-based.
 *
 * @param firstRow Index of first row
 * @param lastRow Index of last row (inclusive), must be equal to or larger than {@code firstRow}
 * @param firstCol Index of first column
 * @param lastCol Index of last column (inclusive), must be equal to or larger than {@code firstCol}
 */
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
    super(firstRow, lastRow, firstCol, lastCol);

    if (lastRow < firstRow || lastCol < firstCol)
        throw new IllegalArgumentException("lastRow < firstRow || lastCol < firstCol");
}

SpringBoot解析Excel

现在很多web应用中,导入excel导出excel很常见,这篇文章就讲讲导入excel文件。

以批量导入课程为例

首先加入需要的jar包

<!--解析excel-->
  <dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>RELEASE</version>
  </dependency>
  <dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>RELEASE</version>
  </dependency>

数据库中创建一个表course

DROP TABLE IF EXISTS `course`;
CREATE TABLE `course`  (
  `course_id` int(10) NOT NULL AUTO_INCREMENT COMMENT '课程id',
  `course_code` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '课程代码',
  `course_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '课程名称',
  `teacher_id` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '教师id',
  `course_time` date NOT NULL DEFAULT '1996-01-01' COMMENT '开课时间',
  `class_room` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '开课地点',
  `course_week` int(5) UNSIGNED NOT NULL DEFAULT 0 COMMENT '课程学时',
  `course_type` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '必修课' COMMENT '课程类型',
  `college_id` int(11) UNSIGNED NOT NULL COMMENT '所属院系id',
  `score` int(5) UNSIGNED NOT NULL DEFAULT 0 COMMENT '学分',
  `is_on` tinyint(2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否开启了选课,默认0未开启',
  PRIMARY KEY (`course_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '课程表' ROW_FORMAT = Dynamic;

新建一个ExcelUtil.java

/**
 * excel工具类
 */
public class ExcelUtils {
    private static Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
    /**
     * 课程excel
     * @param in
     * @param fileName
     * @return
     * @throws Exception
     */
    public static List getCourseListByExcel(InputStream in, String fileName) throws Exception {
        List list = new ArrayList<>();
        // 创建excel工作簿
        Workbook work = getWorkbook(in, fileName);
        if (null == work) {
            throw new Exception("创建Excel工作薄为空!");
        }
        Sheet sheet = null;
        Row row = null;
        Cell cell = null;
        for (int i = 0; i < work.getNumberOfSheets(); i++) {
            sheet = work.getSheetAt(i);
            if(sheet == null) {
                continue;
            }
            // 滤过第一行标题
            for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {
                row = sheet.getRow(j);
                if (row == null || row.getFirstCellNum() == j) {
                    continue;
                }
                List<Object> li = new ArrayList<>();
                for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
                    cell = row.getCell(y);
                    // 日期类型转换
                    if(y == 3) {
                        //cell.setCellType(CellType.STRING);
                        double s1 = cell.getNumericCellValue();
                        Date date = HSSFDateUtil.getJavaDate(s1);
                        li.add(date);
                        continue;
                    }
                    li.add(cell);
                }
                list.add(li);
            }
        }
        work.close();
        return list;
    }
    /**
     * 判断文件格式
     * @param in
     * @param fileName
     * @return
     */
    private static Workbook getWorkbook(InputStream in, String fileName) throws Exception {
        Workbook book = null;
        String filetype = fileName.substring(fileName.lastIndexOf("."));
        if(".xls".equals(filetype)) {
            book = new HSSFWorkbook(in);
        } else if (".xlsx".equals(filetype)) {
            book = new XSSFWorkbook(in);
        } else {
            throw new Exception("请上传excel文件!");
        }
        return book;
    }
}

这里主要注意一下上面的日期转换,在excel中的日期,通过Java读出来之后,变成了26 四月 2019这样的形式,而数据库中我们的字段类型为date,所以总是插入失败。

上面我的写法直接是知道那个字段是Date类型,所以直接使用y==3,这样写可复用性很差。

接下来直接看和数据库交互的逻辑代码

   /**
     * 通过excel文件,批量增加课程
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/upload/course")
    public String uploadCourseExcel(HttpServletRequest request) {
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartHttpServletRequest.getFile("courseFile");
        if(file.isEmpty()) {
            return "redirect:/admin/course/list";
        }
        try {
            InputStream inputStream = file.getInputStream();
            List<List<Object>> list = ExcelUtils.getCourseListByExcel(inputStream, file.getOriginalFilename());
            inputStream.close();
            for (int i = 0; i < list.size(); i++) {
                List<Object> courseList = list.get(i);
                Course course = new Course();
                course.setCourseCode(courseList.get(0).toString());
                course.setCourseName(courseList.get(1).toString());
                // 通过教师姓名查教师id
                String teacherId = teacherService.getTeacByName(courseList.get(2).toString());
                // 教师信息错误,直接跳过这条记录
                if(teacherId == null) {
                    continue;
                }
                course.setTeacherId(teacherId);
                // 格式化时间
                Date date = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US).parse(courseList.get(3).toString());
                course.setCourseTime(new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(date)));
                course.setClassRoom(courseList.get(4).toString());
                course.setCourseWeek(Integer.parseInt(new DecimalFormat("0").format(Double.parseDouble(courseList.get(5).toString()))));
                course.setCourseType(courseList.get(6).toString());
                // 通过院系名称查询院系id
                Integer collegeId = collegeService.getCollegeByName(courseList.get(7).toString());
                // 院系有误,直接跳过这条记录
                if(collegeId == null || collegeId == 0) {
                    continue;
                }
                course.setCollegeId(collegeId);
                course.setScore(Integer.parseInt(new DecimalFormat("0").format(Double.parseDouble(courseList.get(8).toString()))));
                // 默认不开启选课
                course.setIsOn(0);
                logger.error("course = " + course);
                // 判断课程是否重复(同一门课程可以有多个教师教师course_code, course_name, teacher_id联合)
                Integer courseId = null;
                courseId = courseService.getCourseByThree(course);
                // 存在重复的
                if(courseId != null) {
                    // 跳过不添加
                    continue;
                }
                // 执行插入操作
                courseService.addCourse(course);
            }
        } catch (Exception e) {
            return "redirect:/admin/course/list";
        }
        return "redirect:/admin/course/list";
    }

可以看到,我又对时间类型进行了处理,才能最终插入数据库

// 格式化时间
Date date = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US).parse(courseList.get(3).toString());
course.setCourseTime(new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(date)));

同时,在excel中的整数类型,取出来之后就会变成Double类型比如5变成5.0,所以我对此也进行了处理

course.setCourseWeek(Integer.parseInt(new DecimalFormat("0").format(Double.parseDouble(courseList.get(5).toString()))));

最后调用代码进行插入操作。

看看前端代码

<button class="btn btn-default col-md-2" style="margin-top: 20px">
<a data-toggle="modal" href="#uploadExcel" rel="external nofollow"  role="button" style="color: black; text-decoration: none">
批量添加<sapn class="glyphicon glyphicon-plus"/>
</a>
</button>
<!--批量添加模态框-->
<div class="modal fade" tabindex="-1" role="dialog" id="uploadExcel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form class="form-horizontal" role="form" th:action="@{/admin/upload/course}"
enctype="multipart/form-data" method="post">
<div class="modal-body">
请选择文件:<input type="file" name="courseFile">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-success">添加</button>
</div>
</form>
</div>
</div>
</div>

这里我通过button唤醒一个模态框来添加

最后测试结果

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 使用Springboot+poi上传并处理百万级数据EXCEL

    1 Excel上传 针对Excel的上传,采用的是比较常规的方法,其实和文件上传是相同的.具体源码如下: @PostMapping(value = "", consumes = "multipart/*", headers = "content-type=multipart/form-data") public Map<String, Object> addBlacklist( @RequestParam("file&quo

  • Springboot+Poi导入Excel表格实现过程详解

    导入表格的主要思路就是:首先从前端页面上传文件,这里先区分一下Multipartfile和File,前者代表的是HTML中form data方式上传的文件,后者是文件系统的抽象,前者信息较少,只有二进制数据+文件名称,所以我们一般先上传的Multipartfile文件要转换成File文件我们才可以读取文件的内容.下面一步一步的讲解 Tips: 1.先生成临时文件,同时记得使用transferTo()方法把MultipartFile文件类型转成File类型: File excelFile=exce

  • SpringBoot+easypoi实现数据的Excel导出

    本文实例为大家分享了SpringBoot+easypoi实现数据的Excel导出的具体代码,供大家参考,具体内容如下 maven <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-spring-boot-starter</artifactId> <version>4.1.0</version> </dependency> Contr

  • SpringBoot使用POI进行Excel下载

    本文实例为大家分享了SpringBoot使用POI进行Excel下载的具体代码,供大家参考,具体内容如下 使用poi处理Excel特别方便,此处将处理Excel的代码分享出来. 1.maven引用 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependenc

  • Springboot POI导出Excel(浏览器)

    本文实例为大家分享了Springboot POI导出Excel的具体代码,供大家参考,具体内容如下 需求:页面根据查询条件导出(浏览器) 由于本次导出数据量较大,这里采用XSSFWorkbook多线程进行导出,注:XSSFWorkbook导出excel文件结尾为:".xlsx". 导出不需要返回,如有返回则会报异常! //Controller @RequestMapping("/stateExport") public void stateExport(HttpSe

  • SpringBoot整合POI导出通用Excel的方法示例

    一.准备工作 1.pom依赖 在pom.xml中加入POI的依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.11-beta1</version> </dependency> <dependency> <groupId>org.apache.poi

  • java springboot poi 从controller 接收不同类型excel 文件处理

    根据poi接收controller层的excel文件导入 可使用后缀名xls或xlsx格式的excel. 1.pom引入 <!-- poi 操作Excel --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <d

  • Springboot使用POI实现导出Excel文件示例

    前面讲述了使用POI导出Word文件和读取Excel文件,这两个例子都相对简单,接下来要讲述的使用POI导出Excel文件要复杂得多,内容也会比较长. 创建表头信息 表头信息用于自动生成表头结构及排序 public class ExcelHeader implements Comparable<ExcelHeader>{ /** * excel的标题名称 */ private String title; /** * 每一个标题的顺序 */ private int order; /** * 说对

  • SpringBoot中使用JeecgBoot的Autopoi导出Excel的方法步骤

    说到导出 Excel,我们首先会想到 poi.jsxl 等,使用这些工具会显得笨重,学习难度大.今天学习使用 JeecgBoot 中的 Autopoi 导出 Excel,底层基于 easypoi,使用简单,还支持数据字典方式 一.开发前戏 1.引入 maven 依赖 <!-- AutoPoi Excel工具类--> <dependency> <groupId>org.jeecgframework</groupId> <artifactId>aut

  • spring boot如何使用POI读取Excel文件

    目录 spring boot 使用POI读取Excel文件 Excel文件目录 重要说明 读取Excel文件 获取sheet表格及读写单元格内容 合并单元格 SpringBoot解析Excel 以批量导入课程为例 spring boot 使用POI读取Excel文件 Excel文件目录 Excel模板文件存了resourse目录下,如下图: <dependency> <groupId>org.apache.poi</groupId> <artifactId>

  • java利用POI读取excel文件的方法

    摘要:利用java读取excel文件,读取文件并获取文件中每一个sheet中的值. 一.需要提前导入的包: import java.io.File; import java.io.FileInputStream; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook

  • java poi读取excel操作示例(2个代码)

    项目中要求读取excel文件内容,并将其转化为xml格式.常见读取excel文档一般使用POI和JExcelAPI这两个工具.这里我们介绍使用POI实现读取excel文档. 复制代码 代码如下: /* * 使用POI读取EXCEL文件 */import java.io.File;import java.io.FileInputStream;import java.util.ArrayList; import org.apache.poi.hssf.usermodel.HSSFCell;impor

  • java使用POI读取properties文件并写到Excel的方法

    本文实例讲述了java使用POI读取properties文件并写到Excel的方法.分享给大家供大家参考.具体实现方法如下: package com.hubberspot.code; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import

  • Spring Boot项目如何优雅实现Excel导入与导出功能

    目录 背景 EasyExcel 问题 分析与解决 Spring Boot Excel 导入与导出 依赖引入 Excel 导入 基本导入功能 进阶导入功能 Excel 导出 Excel 导入参数校验 开启校验 校验规则定义 Bean Validation 定义校验规则 ExcelValidator 接口定义校验规则 校验结果接收 异常捕获接收校验结果 controller 方法参数接收校验结果 总结 背景 Excel 导入与导出是项目中经常用到的功能,在 Java 中常用 poi 实现 Excel

  • 关于Poi读取Excel引发内存溢出问题的解决方法

    前言 最近生产环境有个老项目一直内存报警,不时的还出现内存泄漏,导致需要重启服务器,已经严重影响正常服务了. 分析 1.dump内存文件 liunx使用如下命令: ./jmap -dump:format=b,file=heap.hprof pid 2.使用Eclipse Memory Analysis进行分析 异常如下: at org.apache.poi.xssf.usermodel.XSSFRow.<init>(Lorg/openxmlformats/schemas/spreadsheet

  • JavaWeb使用POI操作Excel文件实例

    1.为项目添加POI POI官网链接 点进去之后下载(上边的是编译好的类,下边的是源代码) 解压文件夹,把下面三个文件复制到WebComtent>WEB-INF>lib文件夹下 再把这三个文件复制到Tomcat的lib文件夹下,否则Tomcat会因为找不到类而报错(这个地方郁闷了一上午) 读取".xls"格式使用  import org.apache.poi.hssf.usermodel.*;包的内容,例如:HSSFWorkbook 读取".xlsx"格

  • java读取excel文件并复制(copy)文件到指定目录示例

    复制代码 代码如下: mport java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.List; import org.apach

  • java使用POI操作excel文件

    一.POI的定义 JAVA中操作Excel的有两种比较主流的工具包: JXL 和 POI .jxl 只能操作Excel 95, 97, 2000也即以.xls为后缀的excel.而poi可以操作Excel 95及以后的版本,即可操作后缀为 .xls 和 .xlsx两种格式的excel. POI全称 Poor Obfuscation Implementation,直译为"可怜的模糊实现",利用POI接口可以通过JAVA操作Microsoft office 套件工具的读写功能.官网:htt

  • java 读取excel文件转换成json格式的实例代码

    需要读取excel数据转换成json数据,写了个测试功能,转换正常: JSON转换:org.json.jar 测试类:  importFile.java: package com.siemens.util; import java.util.ArrayList; import java.util.List; import org.json.JSONException; import org.json.JSONObject; import org.apache.poi.ss.usermodel.R

随机推荐