Files
ks/ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/EasyExcelUtils.java
sh 47351f41eb 1.添加微信小程序验证登录
2.添加敏感词上传
3.保存工作描述时,验证敏感词
2025-10-20 09:54:51 +08:00

198 lines
7.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ruoyi.cms.util;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
/**
* EasyExcel 工具类(基于 alibaba easyexcel 3.x+
*/
public class EasyExcelUtils {
/**
* 读取 Excel 文件(一次性读取所有数据)
*
* @param file 上传的 Excel 文件
* @param head 实体类字节码(需使用 @ExcelProperty 注解映射表头)
* @param <T> 实体类泛型
* @return 解析后的数据集
*/
public static <T> List<T> readExcel(File file, Class<T> head) {
return EasyExcel.read(file)
.head(head)
.sheet()
.doReadSync();
}
/**
* 读取 Excel 输入流(一次性读取所有数据)
*
* @param inputStream Excel 输入流(如 MultipartFile 的 getInputStream()
* @param head 实体类字节码
* @param <T> 实体类泛型
* @return 解析后的数据集
*/
public static <T> List<T> readExcel(InputStream inputStream, Class<T> head) {
return EasyExcel.read(inputStream)
.head(head)
.sheet()
.doReadSync();
}
/**
* 分批读取 Excel适用于大数据量避免内存溢出
*
* @param inputStream Excel 输入流
* @param head 实体类字节码
* @param batchSize 每批处理的数据量
* @param consumer 数据处理函数(如批量保存到数据库)
* @param <T> 实体类泛型
*/
public static <T> void readExcelByBatch(InputStream inputStream, Class<T> head, int batchSize, Consumer<List<T>> consumer) {
EasyExcel.read(inputStream)
.head(head)
.sheet()
.registerReadListener(new AnalysisEventListener<T>() {
private List<T> batchList; // 临时存储批数据
@Override
public void invoke(T data, AnalysisContext context) {
if (batchList == null) {
batchList = new java.util.ArrayList<>(batchSize);
}
batchList.add(data);
// 达到批处理量时执行消费逻辑
if (batchList.size() >= batchSize) {
consumer.accept(batchList);
batchList.clear(); // 清空集合,释放内存
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 处理剩余不足一批的数据
if (batchList != null && !batchList.isEmpty()) {
consumer.accept(batchList);
}
}
})
.doRead();
}
/**
* 生成 Excel 并写入到输出流(通用样式)
*
* @param outputStream 输出流(如 HttpServletResponse 的 getOutputStream()
* @param data 数据集
* @param head 实体类字节码
* @param sheetName 工作表名称
* @param <T> 实体类泛型
*/
public static <T> void writeExcel(OutputStream outputStream, List<T> data, Class<T> head, String sheetName) {
// 构建通用样式策略(表头居中加粗,内容居中)
HorizontalCellStyleStrategy styleStrategy = getDefaultStyleStrategy();
ExcelWriterSheetBuilder writerBuilder = EasyExcel.write(outputStream, head)
.sheet(sheetName)
.registerWriteHandler(styleStrategy);
writerBuilder.doWrite(data);
}
/**
* 生成 Excel 并通过 HttpServletResponse 下载(前端直接触发下载)
*
* @param response HttpServletResponse
* @param data 数据集
* @param head 实体类字节码
* @param sheetName 工作表名称
* @param fileName 下载的文件名(不带后缀)
* @param <T> 实体类泛型
* @throws IOException IO异常
*/
public static <T> void downloadExcel(HttpServletResponse response, List<T> data, Class<T> head,
String sheetName, String fileName) throws IOException {
// 设置响应头,触发前端下载
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("UTF-8");
// 文件名编码,避免中文乱码
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=UTF-8''" + encodedFileName + ".xlsx");
// 写入数据到响应流
writeExcel(response.getOutputStream(), data, head, sheetName);
}
/**
* 填充 Excel 模板(适用于带固定格式的模板文件)
*
* @param templateInputStream 模板文件输入流
* @param outputStream 输出流(如响应流或文件流)
* @param dataMap 填充数据key为模板中的占位符value为填充值
* @param sheetName 工作表名称
*/
public static void fillTemplate(InputStream templateInputStream, OutputStream outputStream,
Map<String, Object> dataMap, String sheetName) {
EasyExcel.write(outputStream)
.withTemplate(templateInputStream)
.sheet(sheetName)
.doFill(dataMap);
}
/**
* 获取默认单元格样式策略(表头加粗居中,内容居中)
*/
private static HorizontalCellStyleStrategy getDefaultStyleStrategy() {
// 表头样式
WriteCellStyle headStyle = new WriteCellStyle();
WriteFont headFont = new WriteFont();
headFont.setBold(true); // 加粗
headFont.setFontHeightInPoints((short) 11);
headStyle.setWriteFont(headFont);
headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 水平居中
headStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
// 内容样式
WriteCellStyle contentStyle = new WriteCellStyle();
WriteFont contentFont = new WriteFont();
contentFont.setFontHeightInPoints((short) 11);
contentStyle.setWriteFont(contentFont);
contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 返回样式策略
return new HorizontalCellStyleStrategy(headStyle, contentStyle);
}
/**
* 关闭流(工具类内部使用)
*/
private static void closeStream(Closeable... closeables) {
if (closeables != null) {
for (Closeable closeable : closeables) {
if (Objects.nonNull(closeable)) {
try {
closeable.close();
} catch (IOException e) {
// 日志记录(建议替换为实际项目的日志框架)
e.printStackTrace();
}
}
}
}
}
}