Excel 导出技术文档
1. 模块概述
Excel 导出模块是系统核心功能之一,基于 fastexcel 库实现,提供了简单、高效的 Excel 导出功能。该模块支持自定义文件名、自动调整列宽、Long 类型转换等特性,适用于各种业务场景下的 Excel 数据导出需求。
2. 核心功能
- 简单易用: 提供单方法调用,简化 Excel 导出流程
- 自定义文件名: 支持动态指定导出文件名
- 自动列宽: 自动根据内容调整列宽,提升可读性
- Long 类型转换: 自动将 Long 类型转换为字符串,避免科学计数法问题
- 异常处理: 完善的异常处理机制,确保系统稳定性
- 响应重置: 导出失败时自动重置响应,返回标准错误信息
3. 代码解析
3.1 类定义
java
public class ExcelUtils {
// 类实现
}- 工具类设计,无需实例化即可使用
- 提供静态方法,便于直接调用
3.2 核心方法
java
public static void exportExcel(@NotNull HttpServletResponse response, @NotNull String fileName, Class<?> clazz, Collection<?> list) throws IOException {
// 方法实现
}参数说明:
| 参数名 | 类型 | 描述 |
|---|---|---|
| response | HttpServletResponse | HTTP响应对象,用于输出Excel文件 |
| fileName | String | 导出文件名,不含扩展名 |
| clazz | Class<?> | 数据类型类,用于定义Excel表头 |
| list | Collection<?> | 导出数据集合 |
方法流程:
- 设置响应头信息,包括内容类型、字符编码和文件名
- 获取输出流
- 使用 EasyExcel 写入数据
- 注册写入处理器,自动调整列宽
- 注册类型转换器,处理 Long 类型转换
- 执行写入操作
- 异常处理,重置响应并返回错误信息
3.3 核心实现细节
3.3.1 响应头设置
java
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + ".xlsx");application/vnd.ms-excel: 表示Excel文件类型utf-8: 确保文件名正确显示中文Content-Disposition: 指示浏览器以附件形式下载文件
3.3.2 EasyExcel 配置
java
EasyExcel.write(outputStream, clazz)
.autoCloseStream(true)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerConverter(new LongStringConverter())
.sheet("")
.doWrite(list);autoCloseStream(true): 自动关闭输出流LongestMatchColumnWidthStyleStrategy: 自动调整列宽LongStringConverter: 处理Long类型转换为字符串sheet(""): 创建默认工作表doWrite(list): 执行写入操作
3.3.3 异常处理
java
try {
// 导出逻辑
} catch (Exception e) {
// 重置response
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
Result<?> result = new Result<>().error("下载文件失败" + e.getMessage());
response.getWriter().println(JSONUtil.toJsonStr(result));
}- 捕获所有异常,确保系统稳定性
- 重置响应,返回JSON格式错误信息
- 错误信息包含具体异常描述
4. 使用示例
4.1 定义数据模型
java
@Data
public class UserExcel {
@ExcelProperty("用户ID")
private Long userId;
@ExcelProperty("用户名")
private String username;
@ExcelProperty("邮箱")
private String email;
@ExcelProperty("创建时间")
private Date createTime;
}- 使用
@ExcelProperty注解定义表头名称 - 支持基本数据类型、日期类型等
4.2 在Controller中使用
java
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/export")
public void export(HttpServletResponse response) throws IOException {
// 获取用户列表
List<User> userList = userService.list();
// 转换为Excel数据模型
List<UserExcel> excelList = userList.stream()
.map(user -> {
UserExcel excel = new UserExcel();
BeanUtils.copyProperties(user, excel);
return excel;
})
.collect(Collectors.toList());
// 导出Excel
ExcelUtils.exportExcel(response, "用户列表", UserExcel.class, excelList);
}
}- 直接调用
ExcelUtils.exportExcel()方法 - 传入响应对象、文件名、数据类型和数据集合
4.3 前端调用示例
javascript
// 直接下载
window.location.href = '/user/export';
// 或使用axios下载
axios({
url: '/user/export',
method: 'GET',
responseType: 'blob'
}).then(response => {
const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '用户列表.xlsx';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
});5. 配置说明
5.1 依赖配置
在 pom.xml 中添加 EasyExcel 依赖:
xml
<dependency>
<groupId>cn.idev</groupId>
<artifactId>easy-excel</artifactId>
<version>1.0.0</version>
</dependency>5.2 其他依赖
- Hutool JSON: 用于异常处理时的JSON序列化
- Servlet API: 用于HTTP响应处理
6. 注意事项
方法调用限制:
- 该方法不能与返回值为
Result的方法一起使用 AOP 日志记录,否则会报错:java.lang.IllegalStateException: getOutputStream() has already been called for this response - 原因是 AOP 日志记录可能会提前获取响应输出流
- 该方法不能与返回值为
数据量限制:
- 建议单次导出数据量不超过10万条,否则可能导致内存溢出
- 大数据量导出建议使用分页查询或异步导出
数据类型支持:
- 支持基本数据类型、日期类型、字符串类型等
- 复杂对象需要转换为简单对象后导出
文件名规范:
- 文件名不能包含特殊字符,如
\/:*?"<>| - 建议使用中文或英文文件名,避免使用其他语言
- 文件名不能包含特殊字符,如
浏览器兼容性:
- 支持主流浏览器,包括 Chrome、Firefox、Safari、Edge
- IE浏览器可能需要特殊处理
7. 扩展建议
添加导入功能:
- 实现 Excel 导入功能,支持从 Excel 读取数据并保存到数据库
- 支持导入模板下载和数据验证
支持多种导出格式:
- 支持导出为 CSV、PDF 等格式
- 提供格式选择功能
自定义样式支持:
- 支持自定义表头样式、内容样式、边框样式等
- 支持条件样式,如根据数值范围显示不同颜色
大数据量导出:
- 实现异步导出,支持百万级数据导出
- 提供导出进度查询和下载链接
多工作表支持:
- 支持在一个 Excel 文件中导出多个工作表
- 每个工作表可以有不同的数据和样式
导出模板支持:
- 支持根据模板导出数据
- 支持在模板中指定占位符,动态替换数据
列选择功能:
- 支持用户选择需要导出的列
- 支持保存用户的列选择配置
9. 常见问题排查
9.1 导出文件损坏
问题:导出的Excel文件无法打开,提示文件损坏
可能原因:
- 响应头设置错误
- 输出流未正确关闭
- 数据格式错误
解决方案:
- 检查响应头设置是否正确
- 确保
autoCloseStream(true)配置正确 - 检查数据类型是否与Excel模型匹配
9.2 文件名乱码
问题:导出的文件名显示乱码
可能原因:
- 字符编码设置错误
- 浏览器兼容性问题
解决方案:
- 确保
response.setCharacterEncoding("utf-8")已设置 - 确保文件名使用
URLEncoder.encode()编码
9.3 导出速度慢
问题:导出大量数据时速度很慢
可能原因:
- 数据量过大
- 未使用分页查询
- 数据转换耗时
解决方案:
- 减少单次导出数据量
- 使用分页查询获取数据
- 优化数据转换逻辑
9.4 内存溢出
问题:导出大量数据时出现内存溢出
可能原因:
- 数据量超过JVM内存限制
- 未使用流式导出
解决方案:
- 增加JVM内存
- 使用EasyExcel的流式导出功能
- 实现异步导出