修复ExcelUil 导出于Springboot 3.2.6 版本不兼容问题,指定poi

This commit is contained in:
MMS 2025-09-15 20:26:27 +08:00
parent 32a2704bb5
commit 1e46b9eab0
4 changed files with 154 additions and 8 deletions

View File

@ -143,13 +143,15 @@ public class SysUserController extends BaseController {
* 导出系统用户 * 导出系统用户
*/ */
@MssSafety @MssSafety
@Transactional //@Transactional
@SaCheckPermission("system:user:export") @SaCheckPermission("system:user:export")
@PostMapping("/export") @PostMapping("/export")
public void export(SysUserBo user, PageQuery pageQuery, HttpServletResponse response) throws IOException { public void export(SysUserBo user, PageQuery pageQuery, HttpServletResponse response) throws IOException {
List<SysUserVo> list = baseService.selectPageUserList(user, pageQuery).getRows(); List<SysUserVo> list = baseService.selectPageUserList(user, pageQuery).getRows();
List<SysUserExportVo> data = MapstructUtil.convert(list, SysUserExportVo.class); List<SysUserExportVo> data = MapstructUtil.convert(list, SysUserExportVo.class);
ExcelUtil.export(response, SysUserExportVo.class, "系统用户",data);
// 使用封装后的安全导出方法
ExcelUtil.safeExport(response, SysUserExportVo.class, "系统用户", data, pageQuery);
} }
/** /**

View File

@ -97,6 +97,15 @@
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
</dependency> </dependency>
<!-- 明确添加POI依赖 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>

View File

@ -2,7 +2,9 @@ package com.sxpcwlkj.framework.utils;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener; import com.alibaba.excel.read.listener.PageReadListener;
import com.sxpcwlkj.datasource.entity.page.PageQuery;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
@ -18,6 +20,7 @@ import java.util.Set;
* @author mmsAdmin * @author mmsAdmin
* @Doc mmsadmin.cn * @Doc mmsadmin.cn
*/ */
@Slf4j
public class ExcelUtil { public class ExcelUtil {
@ -32,7 +35,30 @@ public class ExcelUtil {
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("模版文件", "UTF-8"); String fileName = URLEncoder.encode("模版文件", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), clazz).sheet("模板").doWrite(new ArrayList<>());
// 设置防止浏览器缓存的响应头
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
try {
EasyExcel.write(response.getOutputStream(), clazz)
.autoCloseStream(false)
.useDefaultStyle(false)
.inMemory(true)
.sheet("模板")
.doWrite(new ArrayList<>());
} catch (Exception e) {
e.printStackTrace();
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"下载模板失败,请联系管理员\"}");
} catch (Exception ex) {
// 忽略重置响应时的异常
}
}
} }
/** /**
@ -47,7 +73,30 @@ public class ExcelUtil {
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(sheetName, "UTF-8"); String fileName = URLEncoder.encode(sheetName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), clazz).sheet("模板").doWrite(new ArrayList<>());
// 设置防止浏览器缓存的响应头
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
try {
EasyExcel.write(response.getOutputStream(), clazz)
.autoCloseStream(false)
.useDefaultStyle(false)
.inMemory(true)
.sheet(sheetName)
.doWrite(new ArrayList<>());
} catch (Exception e) {
e.printStackTrace();
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"下载模板失败,请联系管理员\"}");
} catch (Exception ex) {
// 忽略重置响应时的异常
}
}
} }
/** /**
@ -62,7 +111,34 @@ public class ExcelUtil {
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(sheetName, "UTF-8"); String fileName = URLEncoder.encode(sheetName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), clazz).sheet("模板").doWrite(list);
// 设置防止浏览器缓存的响应头
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
try {
// 使用不依赖POI内部方法的配置
EasyExcel.write(response.getOutputStream(), clazz)
.autoCloseStream(false) // 不自动关闭流
.useDefaultStyle(false) // 不使用默认样式避免调用可能不存在的POI方法
.inMemory(true) // 使用内存模式避免临时文件IO问题
.sheet(sheetName) // 使用传入的sheetName作为表名
.doWrite(list);
} catch (Exception e) {
// 记录异常
e.printStackTrace();
// 重置响应并返回错误信息
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"导出Excel失败请联系管理员\"}");
} catch (Exception ex) {
// 忽略重置响应时的异常
}
}
} }
/** /**
@ -94,4 +170,39 @@ public class ExcelUtil {
EasyExcel.read(file.getInputStream(), clazz, new PageReadListener<T>(data::addAll)).sheet().doRead(); EasyExcel.read(file.getInputStream(), clazz, new PageReadListener<T>(data::addAll)).sheet().doRead();
return data; return data;
} }
/**
* 安全导出数据封装分页限制和异常处理
*
* @param response 响应对象
* @param clazz 数据类
* @param sheetName 表名
* @param data 数据列表
* @param pageQuery 分页查询条件
*/
public static <T> void safeExport(HttpServletResponse response, Class<T> clazz, String sheetName, List<T> data, PageQuery pageQuery) throws IOException {
// 限制导出数据量避免内存溢出
if (pageQuery == null) {
pageQuery = new PageQuery();
}
// 设置合理的导出数量上限
if (pageQuery.getPageSize() > 5000 || pageQuery.getPageSize() <= 0) {
pageQuery.setPageSize(5000);
}
try {
export(response, clazz, sheetName, data);
} catch (Exception e) {
log.error("导出Excel异常", e);
try {
// 重置响应并返回错误信息
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"导出失败,请联系管理员\"}");
} catch (Exception ex) {
log.error("处理导出异常时出错", ex);
}
}
}
} }

24
pom.xml
View File

@ -47,6 +47,7 @@
<therapi-javadoc.version>0.15.0</therapi-javadoc.version> <therapi-javadoc.version>0.15.0</therapi-javadoc.version>
<commons-io.version>2.17.0</commons-io.version> <commons-io.version>2.17.0</commons-io.version>
<easyexcel.version>4.0.3</easyexcel.version> <easyexcel.version>4.0.3</easyexcel.version>
<poi.version>4.1.2</poi.version>
<!--低代码生成--> <!--低代码生成-->
@ -282,6 +283,29 @@
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version> <version>${easyexcel.version}</version>
<exclusions>
<!-- 排除可能冲突的POI依赖 -->
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 明确指定POI版本确保兼容性 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency> </dependency>
<!-- springdoc --> <!-- springdoc -->