SpringBoot整合POI实现Excel文件读写操作

1.环境准备


1、导入sql脚本:

create database if not exists springboot default charset utf8mb4;

use springboot;

create table if not exists `user`
(
    `id`       bigint(20) primary key auto_increment comment '主键id',
    `username` varchar(255)   not null comment '用户名',
    `sex`      char(1)        not null comment '性别',
    `phone`    varchar(22)    not null comment '手机号',
    `city`     varchar(255)   not null comment '所在城市',
    `position` varchar(255)   not null comment '职位',
    `salary`   decimal(18, 2) not null comment '工资:长度18位,保留2位小数'
) engine InnoDB comment '用户表';

INSERT INTO `user` (`username`, `sex`, `phone`, `city`, `position`, `salary`) VALUES
('张三', '男', '13912345678', '北京', '软件工程师', 10000.00),
('李四', '女', '13723456789', '上海', '数据分析师', 12000.00),
('王五', '男', '15034567890', '广州', '产品经理', 15000.00),
('赵六', '女', '15145678901', '深圳', '前端工程师', 11000.00),
('刘七', '男', '15856789012', '成都', '测试工程师', 9000.00),
('陈八', '女', '13967890123', '重庆', 'UI设计师', 8000.00),
('朱九', '男', '13778901234', '武汉', '运维工程师', 10000.00),
('杨十', '女', '15089012345', '南京', '数据工程师', 13000.00),
('孙十一', '男', '15190123456', '杭州', '后端工程师', 12000.00),
('周十二', '女', '15801234567', '天津', '产品设计师', 11000.00);

image-20231001224214707

2、创建springboot工程 (springboot版本为2.7.13)

3、引入依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.13</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.2</version>
    </dependency>
</dependencies>

4、修改yml配置:

server:
  port: 8001

# 数据库配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
    username: root
    password: 123456

# mybatisplus配置
mybatis-plus:
  mmapper-locations: classpath:mapper/*.xml #mapper文件存放路径
  type-aliases-package: cn.z3inc.exceldemo.entity # 类型别名(实体类所在包)
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #配置标准sql输出

5、使用 MyBatisPlus 插件生成基础代码:

image-20231001224944713

① 配置数据库:

image-20231001224418894

image-20231001224520414

② 使用代码生成器生成代码:

image-20231001224612743

image-20231001225559406

image-20231002165231209


2. POI


Excel报表的两种方式:

在企业级应用开发中,Excel报表是一种常见的报表需求,Excel报表开发一般分为两种形式:

  • 把Excel中的数据导入到系统中;(上传)

  • 通过Java代码生成Excel报表。(下载)


Excel版本:

目前世面上的Excel分为两个大版本:Excel2003 和 Excel2007及以上版本;

Excel2003是一个特有的二进制格式,其核心结构是复合文档类型的结构,存储数据量较小;Excel2007 的核心结构是 XML 类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小,操作效率更高。

Excel 2003Excel 2007
后缀xlsxlsx
结构二进制格式,其核心结构是复合文档类型的结构XML类型结构
单sheet数据量(sheet,工作表)表格共有65536行,256列表格共有1048576行,16384列
特点存储容量有限基于xml压缩,占用空间小,操作效率高

Apache POI:

Apache POI(全称:Poor Obfuscation Implementation),是Apache软件基金会的一个开源项目,它提供了一组API,可以让Java程序读写 Microsoft Office 格式的文件,包括 word、excel、ppt等。

Apache POI是目前最流行的操作Microsoft Office的API组件,借助POI可以为工作提高效率,如 数据报表生成,数据批量上传,数据备份等工作。

官网地址:https://poi.apache.org/

POI针对Excel的API如下:

  • Workbook:工作薄,Excel的文档对象,针对不同的Excel类型分为:HSSFWorkbook(2003)和XSSFWorkbook(2007);
  • Sheet:Excel的工作单(表);
  • Row:Excel的行;
  • Cell:Excel的格子,单元格。

Java中常用的excel报表工具有:POI、easyexcel、easypoi等。


POI快速入门:

引入POI依赖:

<!--excel  POI依赖-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.0.1</version>
</dependency>

示例1:批量写操作(大数据量时会出现内存异常问题)

写入excel文件步骤:

  • 创建工作簿:workbook
  • 创建工作表:sheet
  • 创建行:row
  • 创建列(单元格):cell
  • 具体数据写入
package cn.z3inc.exceldemo.controller;


import cn.z3inc.exceldemo.entity.User;
import cn.z3inc.exceldemo.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author 白豆五
 * @since 2023-10-01
 */
@CrossOrigin
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class UserController {

    private final IUserService userService;

    /**
     * 导出excel
     */
    @RequestMapping("/export")
    public void exportExcel(HttpServletResponse response) throws IOException {
        // 1. 创建excel工作簿(workbook):excel2003使用HSSF,excel2007使用XSSF,excel2010使用SXSSF(大数据量)
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 2. 创建excel工作表(sheet)
        Sheet sheet = workbook.createSheet("用户表");

        // 3. 在表中创建标题行(row): 表头
        Row titleRow = sheet.createRow(0); // 通过索引表示行,0表示第一行

        // 4. 在标题行中创建7个单元格 且 为每个单元格设置内容数据
        String[] titleArr = {"用户ID", "姓名", "性别", "电话", "所在城市", "职位", "薪资"};
        for (int i = 0; i < titleArr.length; i++) {
            Cell cell = titleRow.createCell(i); //设置单元格的位置,从0开始
            cell.setCellValue(titleArr[i]); // 为单元格填充数据
        }

        // 5. 查询所有用户数据
        List<User> userList = userService.list();

        // 6. 遍历用户list,获取每个用户,并填充每一行单元格的数据
        for (int i = 0; i < userList.size(); i++) {
            User user = userList.get(i);
            // 创建excel的行
            Row row = sheet.createRow(i+1); // 从第二行开始,索引为1
            // 为每个单元格填充数据
            row.createCell(0).setCellValue(user.getId());
            row.createCell(1).setCellValue(user.getUsername());
            row.createCell(2).setCellValue(user.getSex());
            row.createCell(3).setCellValue(user.getPhone());
            row.createCell(4).setCellValue(user.getCity());
            row.createCell(5).setCellValue(user.getPosition());
            row.createCell(6).setCellValue(user.getSalary().doubleValue());
        }

        // 7. 输出文件
        // 7.1 把excel文件写到磁盘上
        FileOutputStream outputStream = new FileOutputStream("d:/1.xlsx");
        workbook.write(outputStream); // 把excel写到输出流中
        outputStream.close(); // 关闭流

        // 7.2 把excel文件输出到浏览器上
        // 设置响应头信息
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment; filename=1.xlsx");

        ServletOutputStream servletOutputStream = response.getOutputStream();
        workbook.write(servletOutputStream);
        servletOutputStream.flush(); // 刷新缓冲区
        servletOutputStream.close(); // 关闭流
        workbook.close();
    }
}

image-20231004224921153


示例2:大数量写操作

/**
 * 大数据量批量导出excel:SXSSF(同样兼容XSSF)
 * 官方提供了SXSSF来解决大文件写入问题,它可以写入非常大量的数据,比如上百万条数据,并且写入速度更快,占用内存更少
 * SXSSF在写入数据时会将数据分批写入硬盘(会产生临时文件),而不是一次性将所有数据写入硬盘。
 * SXSSF通过滑动窗口限制内存读取的行数(默认100行,超过100行就会写入磁盘),而XSSF将文档中所有行加载到内存中。那些不在滑动窗口中的数据是不能访问的,因为它们已经被写到磁盘上了。这样可以节省大量内存空间 。
 */
@RequestMapping("/export2")
public void exportExcel2(HttpServletResponse response) throws IOException {

    long star = System.currentTimeMillis();

    // 1. 创建excel工作簿(workbook):SXSSFWorkbook
    SXSSFWorkbook workbook = new SXSSFWorkbook();//默认窗口大小为100

    // 2. 创建excel工作表(sheet)
    Sheet sheet = workbook.createSheet("用户表");

    // 3. 在表中创建标题行(row): 表头
    Row titleRow = sheet.createRow(0); // 通过索引表示行,0表示第一行

    // 4. 在标题行中创建7个单元格 且 为每个单元格设置内容数据
    String[] titleArr = {"用户ID", "姓名", "性别", "电话", "所在城市", "职位", "薪资"};
    for (int i = 0; i < titleArr.length; i++) {
        Cell cell = titleRow.createCell(i); //设置单元格的位置,从0开始
        cell.setCellValue(titleArr[i]); // 为单元格填充数据
    }

    // 5. 查询所有用户数据
    List<User> userList = userService.list();

    // 6. 遍历用户list,获取每个用户,并填充每一行单元格的数据
    for (int i = 0; i < 65536; i++) {
        User user;
        if (i > userList.size() - 1) {
            user = userList.get(userList.size() - 1);
        } else {
            user = userList.get(i);
        }

        // 创建excel的行
        Row row = sheet.createRow(i + 1); // 从第二行开始,索引为1
        // 为每个单元格填充数据
        row.createCell(0).setCellValue(user.getId());
        row.createCell(1).setCellValue(user.getUsername());
        row.createCell(2).setCellValue(user.getSex());
        row.createCell(3).setCellValue(user.getPhone());
        row.createCell(4).setCellValue(user.getCity());
        row.createCell(5).setCellValue(user.getPosition());
        row.createCell(6).setCellValue(user.getPosition());
    }

    // 7. 输出文件
    // 7.1 把excel文件写到磁盘上
    FileOutputStream outputStream = new FileOutputStream("d:/2.xlsx");
    workbook.write(outputStream); // 把excel写到输出流中
    outputStream.close(); // 关闭流
    workbook.close();
    long end = System.currentTimeMillis();
    log.info("大数据量批量数据写入用时: {} ms", end - star);
}

经测试XSSF大概十秒左右输出excel文件,而SXSSF一秒左右输出excel文件。


示例:读取excel文件

读取excel文件步骤:(通过文件流读取)

  • 获取工作簿
  • 获取工作表(sheet)
  • 获取行(row)
  • 获取单元格(cell)
  • 读取数据
// 读取excel文件
@RequestMapping("/upload")
public void readExcel(MultipartFile file) {
    InputStream is = null;
    XSSFWorkbook workbook = null;
    try {
        // 1. 创建excel工作簿(workbook)
        is = file.getInputStream();
        workbook = new XSSFWorkbook(is);

        // 2. 获取要解析的工作表(sheet)
        Sheet sheet = workbook.getSheetAt(0); // 获取第一个sheet

        // 3. 获取表格中的每一行,排除表头,从第二行开始
        User user;
        List<User> list = new ArrayList<>();
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i); // 获取第i行

            // 4. 获取每一行的每一列,并为user对象的属性赋值,添加到list集合中
            user = new User();
            user.setUsername(row.getCell(1).getStringCellValue());
            user.setSex(row.getCell(2).getStringCellValue());
            user.setPhone(row.getCell(3).getStringCellValue());
            user.setCity(row.getCell(4).getStringCellValue());
            user.setPosition(row.getCell(5).getStringCellValue());
            user.setSalary(new BigDecimal(row.getCell(6).getNumericCellValue()));
            list.add(user);
        }

        // 5. 批量保存
        userService.saveBatch(list);
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException("批量导入失败");
    } finally {
        try {
            if (is != null) {
                is.close();
            }
            if (workbook != null) {
                workbook.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("批量导入失败");
        }
    }
}

image-20231007062047348

image-20231007062527489

image-20231007062019296


3. EasyExcel


EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。

官网地址:https://easyexcel.opensource.alibaba.com/

文档地址:https://easyexcel.opensource.alibaba.com/docs/current/

示例代码:https://github.com/alibaba/easyexcel/tree/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo

pom依赖:

<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.2.1</version>
</dependency>

最后,EasyExcel的官方文档非常全面,我就不一一赘述了。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Spring Boot整合POI可以实现Excel文件的导出。具体步骤如下: 1. 添加POI依赖 在pom.xml文件中添加POI的依赖: ``` <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> ``` 2. 创建Excel文件 使用POI创建Excel文件,可以使用HSSFWorkbook或XSSFWorkbook类。HSSFWorkbook适用于xls格式的Excel文件,XSSFWorkbook适用于xlsx格式的Excel文件。 ``` // 创建HSSFWorkbook对象 HSSFWorkbook workbook = new HSSFWorkbook(); // 创建sheet HSSFSheet sheet = workbook.createSheet("Sheet1"); // 创建行 HSSFRow row = sheet.createRow(); // 创建单元格 HSSFCell cell = row.createCell(); // 设置单元格的值 cell.setCellValue("Hello World"); ``` 3. 导出Excel文件 使用HttpServletResponse将Excel文件输出到浏览器。 ``` // 设置响应头 response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=test.xls"); // 输出Excel文件 workbook.write(response.getOutputStream()); ``` 完整的代码示例: ``` @GetMapping("/export") public void export(HttpServletResponse response) throws IOException { // 创建HSSFWorkbook对象 HSSFWorkbook workbook = new HSSFWorkbook(); // 创建sheet HSSFSheet sheet = workbook.createSheet("Sheet1"); // 创建行 HSSFRow row = sheet.createRow(); // 创建单元格 HSSFCell cell = row.createCell(); // 设置单元格的值 cell.setCellValue("Hello World"); // 设置响应头 response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=test.xls"); // 输出Excel文件 workbook.write(response.getOutputStream()); } ``` ### 回答2: Spring BootSpring框架的一个轻量级解决方案。它的特点是简单易用、快速开发、集成度高。POI是Apache软件基金会的一个开源项目,用于支持在Java平台上处理Microsoft Office文件格式。Spring BootPOI的结合,使得在开发导出Excel文件的功能时,能够更加方便快捷,大幅降低开发难度。 整合POI导出Excel的过程中,在pom.xml文件中添加POI的依赖,然后创建一个ExcelUtil工具类。这个ExcelUtil工具类主要包含以下功能: 1. 创建工作簿(Workbook)对象 2. 创建工作表(Sheet)对象 3. 创建行(Row)对象 4. 创建单元格(Cell)对象 5. 对单元格进行赋值 6. 设置格式 其次,在需要导出Excel文件的Controller中,创建相应的方法。这个方法主要包含以下步骤: 1. 获得数据 2. 调用ExcelUtil工具类,创建工作簿对象 3. 调用ExcelUtil工具类,创建工作表对象 4. 循环遍历数据,创建行和单元格对象,并对单元格进行赋值 5. 调用ExcelUtil工具类,将工作簿写入输出流中 6. 设置响应头,告知浏览器当前响应的文件类型 7. 将响应输出流写到浏览器中 最后,访问这个Controller的对应地址即可下载导出的Excel文件。 总体来说,springboot整合poi导出excel的过程比较简单,只需要按照上述步骤完成即可。这种方式不仅可以用于导出简单的Excel文件,还适用于更复杂的数据格式,提高了开发效率,方便了数据的导出和共享。 ### 回答3: 近年来,随着企业信息化建设的日益推进,导出Excel文件已经成为了不少企业常用的统计工具之一。而Spring Boot是一个非常流行的开发框架,它本身提供了很多优秀的功能和工具,如何在Spring Boot框架中集成Poi组件,实现Excel的导出功能,是一个非常值得探讨的话题。 Poi是Apache软件基金会的开源项目,可以用于处理各种Office文档格式,包括Word、Excel和PowerPoint等。它提供了很多接口和实现类,可以方便地完成Excel文件的读写操作。下面我们就来看一下Spring Boot如何整合Poi实现Excel导出的功能。 1. 添加Poi依赖 首先,在项目的pom.xml文件中,添加Poi的依赖: ``` <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> ``` 这里使用的是Poi的3.17版本,也可以根据自己的需要选择其他版本。 2. 创建导出Excel的工具类 在Spring Boot项目中,可以创建一个导出Excel的工具类,用于完成Excel文件的生成和导出。下面给出一个简单的示例: ``` public class ExcelUtil { /** * 导出Excel文件 * @param dataList 导出数据列表 * @param headers Excel表头 * @param fileName 导出文件名 * @param response 响应对象 */ public static void export(List<Map<String, Object>> dataList, String[] headers, String fileName, HttpServletResponse response) throws Exception { // 创建Excel工作簿 Workbook workbook = new XSSFWorkbook(); // 创建Excel表格 Sheet sheet = workbook.createSheet(); // 创建表头行并写入数据 Row headerRow = sheet.createRow(0); for(int i = 0; i < headers.length; i++) { headerRow.createCell(i).setCellValue(headers[i]); } // 写入数据行 int currentRow = 1; for(Map<String, Object> data : dataList) { Row row = sheet.createRow(currentRow++); for(int i = 0; i < headers.length; i++) { Object value = data.get(headers[i]); if(value != null) { if(value instanceof Date) { row.createCell(i).setCellValue((Date)value); } else { row.createCell(i).setCellValue(value.toString()); } } else { row.createCell(i).setCellValue(""); } } } // 设置响应头信息 response.setContentType("application/octet-stream;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); // 将Excel文件写入响应输出流中 OutputStream outputStream = response.getOutputStream(); workbook.write(outputStream); outputStream.flush(); outputStream.close(); } } ``` 这里使用了Poi中的XSSFWorkbook和Sheet等类,实现Excel文件的创建和写入操作。同时,还通过HttpServletResponse对象向浏览器发送了响应头信息和Excel文件数据。 3. 调用导出Excel的方法 在Spring Boot项目中,只需要在Controller中调用ExcelUtil的export方法,即可实现Excel导出功能。下面给出一个简单的示例: ``` @RestController public class ExcelController { /** * 导出Excel文件 * @param response 响应对象 */ @GetMapping("/excel") public void exportExcel(HttpServletResponse response) throws Exception { List<Map<String, Object>> dataList = new ArrayList<>(); Map<String, Object> data1 = new HashMap<>(); data1.put("id", 1); data1.put("name", "张三"); data1.put("gender", "男"); data1.put("birthday", new Date()); dataList.add(data1); Map<String, Object> data2 = new HashMap<>(); data2.put("id", 2); data2.put("name", "李四"); data2.put("gender", "女"); data2.put("birthday", new Date()); dataList.add(data2); String[] headers = {"id", "name", "gender", "birthday"}; ExcelUtil.export(dataList, headers, "data.xlsx", response); } } ``` 这里在Controller中创建了一个Excel文件导出的请求处理方法,在方法中调用了ExcelUtil的export方法,传入数据列表、表头和文件名等参数。 总结 通过以上步骤的操作,我们就可以在Spring Boot项目中集成Poi组件,实现Excel文件的导出功能了。当然,在实际应用中,还可能需要对Excel样式、单元格格式等进行调整,使得导出的Excel文件更符合自己的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白豆五

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值