当前位置: 首页 > news >正文

Spring Boot中Excel处理完全指南

文章目录

    • 1. Excel处理基础知识
      • 1.1 为什么需要在应用中处理Excel文件?
      • 1.2 Java中的Excel处理库介绍
        • 1.2.1 Apache POI
        • 1.2.2 EasyExcel
        • 1.2.3 JExcel
        • 1.2.4 Apache POI SXSSF
      • 1.3 Spring Boot中集成Excel处理
    • 2. 在Spring Boot中集成Excel处理库
      • 2.1 集成Apache POI
        • 2.1.1 添加依赖
        • 2.1.2 创建基本配置类
      • 2.2 集成EasyExcel
        • 2.2.1 添加依赖
        • 2.2.2 创建配置类
    • 3. 使用Apache POI读取Excel文件
      • 3.1 创建数据模型
      • 3.2 创建Excel读取服务
      • 3.3 创建Controller处理Excel上传
      • 3.4 创建HTML上传页面
      • 3.5 处理更复杂的Excel结构
    • 4. 使用Apache POI创建和导出Excel文件
      • 4.1 创建基本Excel文件
      • 4.2 创建导出控制器
      • 4.3 创建导出页面
      • 4.4 创建复杂的Excel文件
      • 4.5 使用模板导出Excel
    • 5. 使用EasyExcel处理Excel文件
      • 5.1 使用EasyExcel读取Excel
        • 5.1.1 创建数据模型
        • 5.1.2 创建读取监听器
        • 5.1.3 创建Excel读取服务
        • 5.1.4 创建Controller
      • 5.2 使用EasyExcel导出Excel
        • 5.2.1 简单导出示例
        • 5.2.2 创建Controller
    • 6. 处理大型Excel文件的策略
      • 6.1 使用Apache POI SXSSF模式
      • 6.2 使用EasyExcel处理大文件
      • 6.3 使用CSV代替Excel
      • 6.4 分页导出大型数据集
    • 7. 实际应用场景和最佳实践
      • 7.1 动态列导出
      • 7.2 Excel模板填充
      • 7.3 Excel文件校验
      • 7.4 统一异常处理
    • 8. 性能优化和注意事项
      • 8.1 性能优化建议
      • 8.2 注意事项
    • 9. 总结

1. Excel处理基础知识

1.1 为什么需要在应用中处理Excel文件?

在企业应用开发中,Excel文件处理是一个非常常见的需求,主要用于以下场景:

  • 数据导入:允许用户通过Excel上传批量数据到系统
  • 数据导出:将系统数据导出为Excel供用户下载分析
  • 报表生成:生成复杂的报表并格式化为Excel
  • 数据交换:作为不同系统间交换数据的媒介
  • 批量数据处理:处理大量结构化数据

1.2 Java中的Excel处理库介绍

Java中处理Excel文件的主要库有以下几种:

1.2.1 Apache POI

Apache POI是Java中使用最广泛的Excel处理库,提供了全面的API来创建、读取和修改Office文档。

优点

  • 功能全面,支持Excel所有功能
  • 支持.xls (HSSF - Excel 97-2003)和.xlsx (XSSF - Excel 2007+)格式
  • 社区活跃,文档丰富
  • 支持公式计算、图表、合并单元格等高级功能

缺点

  • API相对复杂
  • 处理大文件时内存消耗大(尤其是XSSF)
1.2.2 EasyExcel

EasyExcel是阿里巴巴开源的Excel处理库,基于POI,但做了大量优化。

优点

  • 内存占用低,使用SAX模式读取,避免OOM
  • API简单易用,注解驱动
  • 读写速度快
  • 适合处理大型Excel文件

缺点

  • 功能不如POI全面
  • 灵活性相对较低
1.2.3 JExcel

JExcel是另一个处理Excel的Java库。

优点

  • API较简单
  • 速度较快

缺点

  • 仅支持旧版Excel (.xls)格式
  • 不再积极维护
  • 功能有限
1.2.4 Apache POI SXSSF

SXSSF是POI提供的一种流式处理模式,专为处理大型Excel文件设计。

优点

  • 大大降低内存占用
  • 适合生成大型Excel文件

缺点

  • 仅支持写入操作,不支持读取
  • 功能比XSSF受限

1.3 Spring Boot中集成Excel处理

Spring Boot本身不提供Excel处理功能,但可以轻松集成上述各种Excel处理库。本指南将主要介绍:

  1. 如何在Spring Boot项目中集成Apache POI和EasyExcel
  2. 如何实现Excel导入导出的常见功能
  3. 如何处理常见问题和优化性能

2. 在Spring Boot中集成Excel处理库

2.1 集成Apache POI

2.1.1 添加依赖

pom.xml文件中添加以下依赖:

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

如果使用Gradle,在build.gradle中添加:

implementation 'org.apache.poi:poi:5.2.3'
implementation 'org.apache.poi:poi-ooxml:5.2.3'
2.1.2 创建基本配置类

创建一个配置类来处理Excel相关的配置:

package com.example.excel.config;import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;@Configuration
public class ExcelConfig {@Beanpublic MultipartResolver multipartResolver() {CommonsMultipartResolver resolver = new CommonsMultipartResolver();resolver.setMaxUploadSize(10485760); // 设置上传文件最大为10MBreturn resolver;}
}

2.2 集成EasyExcel

2.2.1 添加依赖

pom.xml文件中添加以下依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.2.1</version>
</dependency>

如果使用Gradle,在build.gradle中添加:

implementation 'com.alibaba:easyexcel:3.2.1'
2.2.2 创建配置类
package com.example.excel.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;@Configuration
public class EasyExcelConfig {@Beanpublic MultipartResolver multipartResolver() {CommonsMultipartResolver resolver = new CommonsMultipartResolver();resolver.setMaxUploadSize(10485760); // 设置上传文件最大为10MBreturn resolver;}
}

3. 使用Apache POI读取Excel文件

3.1 创建数据模型

首先,创建一个模型类来映射Excel中的数据:

package com.example.excel.model;import lombok.Data;@Data
public class User {private Long id;private String name;private Integer age;private String email;private String department;
}

3.2 创建Excel读取服务

创建一个服务类来处理Excel文件读取:

package com.example.excel.service;import com.example.excel.model.User;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;@Service
public class ExcelService {public List<User> readUsersFromExcel(MultipartFile file) throws IOException {List<User> userList = new ArrayList<>();// 获取工作簿try (InputStream inputStream = file.getInputStream()) {Workbook workbook = WorkbookFactory.create(inputStream);// 获取第一个工作表Sheet sheet = workbook.getSheetAt(0);// 跳过标题行Iterator<Row> rowIterator = sheet.rowIterator();if (rowIterator.hasNext()) {rowIterator.next(); // 跳过标题行}// 遍历数据行while (rowIterator.hasNext()) {Row row = rowIterator.next();User user = new User();// 读取单元格数据user.setId((long) row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getNumericCellValue());user.setName(getCellValueAsString(row.getCell(1)));user.setAge((int) row.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getNumericCellValue());user.setEmail(getCellValueAsString(row.getCell(3)));user.setDepartment(getCellValueAsString(row.getCell(4)));userList.add(user);}workbook.close();}return userList;}// 获取单元格的字符串值private String getCellValueAsString(Cell cell) {if (cell == null) {return "";}switch (cell.getCellType()) {case STRING:return cell.getStringCellValue();case NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {return cell.getDateCellValue().toString();} else {return String.valueOf((int) cell.getNumericCellValue());}case BOOLEAN:return String.valueOf(cell.getBooleanCellValue());case FORMULA:return cell.getCellFormula();default:return "";}}
}

3.3 创建Controller处理Excel上传

创建一个Controller来处理Excel文件上传:

package com.example.excel.controller;import com.example.excel.model.User;
import com.example.excel.service.ExcelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.List;@RestController
@RequestMapping("/api/excel")
public class ExcelController {@Autowiredprivate ExcelService excelService;@PostMapping("/upload")public ResponseEntity<List<User>> uploadExcel(@RequestParam("file") MultipartFile file) {try {List<User> users = excelService.readUsersFromExcel(file);return ResponseEntity.ok(users);} catch (IOException e) {e.printStackTrace();return ResponseEntity.badRequest().build();}}
}

3.4 创建HTML上传页面

src/main/resources/templates目录下创建upload.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Excel上传</title><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body><div class="container mt-5"><div class="card"><div class="card-header"><h3>上传Excel文件</h3></div><div class="card-body"><form id="uploadForm" enctype="multipart/form-data"><div class="form-group"><label for="file">选择Excel文件:</label><input type="file" class="form-control-file" id="file" name="file" accept=".xls,.xlsx"></div><button type="button" class="btn btn-primary" onclick="uploadExcel()">上传</button></form><div class="mt-4"><h4>上传结果:</h4><div id="resultContainer"></div></div></div></div></div><script src="https://code.jquery.com/jquery-3.5.1.min.js"></script><script>function uploadExcel() {var formData = new FormData(document.getElementById('uploadForm'));$.ajax({url: '/api/excel/upload',type: 'POST',data: formData,processData: false,contentType: false,success: function(response) {var resultHtml = '<table class="table table-striped">' +'<thead><tr><th>ID</th><th>姓名</th><th>年龄</th><th>邮箱</th><th>部门</th></tr></thead>' +'<tbody>';for (var i = 0; i < response.length; i++) {var user = response[i];resultHtml += '<tr>' +'<td>' + user.id + '</td>' +'<td>' + user.name + '</td>' +'<td>' + user.age + '</td>' +'<td>' + user.email + '</td>' +'<td>' + user.department + '</td>' +'</tr>';}resultHtml += '</tbody></table>';$('#resultContainer').html(resultHtml);},error: function(error) {$('#resultContainer').html('<div class="alert alert-danger">上传失败: ' + error.responseText + '</div>');}});}</script>
</body>
</html>

3.5 处理更复杂的Excel结构

在实际应用中,Excel结构可能更复杂,如多个工作表、合并单元格、公式等。以下是处理这些情况的示例:

public List<Department> readComplexExcel(MultipartFile file) throws IOException {List<Department> departments = new ArrayList<>();try (InputStream inputStream = file.getInputStream()) {Workbook workbook = WorkbookFactory.create(inputStream);// 读取部门信息(第一个工作表)Sheet departmentSheet = workbook.getSheetAt(0);for (int i = 1; i <= departmentSheet.getLastRowNum(); i++) {Row row = departmentSheet.getRow(i);if (row == null) continue;Department department = new Department();department.setId((long) row.getCell(0).getNumericCellValue());department.setName(row.getCell(1).getStringCellValue());department.setManager(row.getCell(2).getStringCellValue());department.setEmployees(new ArrayList<>());departments.add(department);}// 读取员工信息(第二个工作表)Sheet employeeSheet = workbook.getSheetAt(1);for (int i = 1; i <= employeeSheet.getLastRowNum(); i++) {Row row = employeeSheet.getRow(i);if (row == null) continue;User employee = new User();employee.setId((long) row.getCell(0).getNumericCellValue());employee.setName(row.getCell(1).getStringCellValue());employee.setAge((int) row.getCell(2).getNumericCellValue());employee.setEmail(row.getCell(3).getStringCellValue());// 获取部门ID并关联到相应部门long departmentId = (long) row.getCell(4).getNumericCellValue();for (Department dept : departments) {if (dept.getId() == departmentId) {dept.getEmployees().add(employee);break;}}}workbook.close();}return departments;
}

4. 使用Apache POI创建和导出Excel文件

4.1 创建基本Excel文件

以下是一个创建简单Excel文件的示例:

package com.example.excel.service;import com.example.excel.model.User;
import org.apache.poi.ss.usermodel.*

相关文章:

  • 基于chatgpt和deepseek解答显卡的回答
  • PyTorch数据操作基础教程:从张量创建到高级运算
  • STM32 外部中断EXTI
  • 原生localStorage到zustand + persist改造
  • [密码学基础]密码学发展简史:从古典艺术到量子安全的演进
  • 碰一碰发视频系统源码搭建全解析:定制化开发
  • 芝法酱躺平攻略(21)——kafka安装和使用
  • LabVIEW 程序维护:为何选靠谱团队?
  • 纯FPGA控制AD9361的思路和实现之一 概述
  • JVM 系列:JVM 内存结构深度解析
  • Day10【基于encoder- decoder架构实现新闻文本摘要的提取】
  • 面向对象设计中的类的分类:实体类、控制类和边界类
  • 暨南大学 2024年ACM程序设计校赛 题解与知识点分析
  • SOA 核心三要素:服务、构件与对象的深度解析
  • 毕业答辩的PPT应该包括哪些内容?
  • Grallvm技术介绍
  • 从 LabelImg 到 Label Studio!AI 数据标注神器升级,Web 版真香
  • 【网络初识】从零开始彻底了解网络编程(一)
  • 企业网站安装 SSL安装的必要性
  • C++学习之路,从0到精通的征途:vector类的模拟实现
  • 第六季了,姐姐们还能掀起怎样的风浪
  • 梅德韦杰夫:如果欧盟和美国 “撒手不管”,俄罗斯会更快解决俄乌冲突
  • 同比增长4.2%!一季度全国财政支出持续增长
  • “不可见社会”:一周城市生活
  • 1672万!大乐透8.8亿派奖第4期松江彩民18元中头奖
  • 河南省委书记人民日报撰文:坚定不移贯彻总体国家安全观,为谱写中国式现代化河南篇章提供安全保障