package com.ruoyi.system.utils; import cn.idev.excel.FastExcel; import cn.idev.excel.context.AnalysisContext; import cn.idev.excel.event.AnalysisEventListener; import com.ruoyi.common.exception.ServiceException; import lombok.extern.slf4j.Slf4j; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import java.util.List; /** * @author mitao * @date 2025/10/22 */ @Slf4j public class FastExcelUtil { public static void exportData(HttpServletResponse response, String fileName, String sheetName, Class clazz, List data) { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); try { fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); FastExcel.write(response.getOutputStream(), clazz) .sheet(sheetName) .doWrite(data); } catch (IOException e) { log.error("导出数据异常", e); throw new ServiceException("导出数据异常"); } } /** * 读取文件数据,并返回一个包含指定类型数据的列表。 * * @param inputStream 文件对象输入流 * @param clazz 数据对象的类型 * @param 泛型类型,表示数据对象的类型 * @return 包含解析后数据对象的列表 */ public static List readMultipartFile(InputStream inputStream, Class clazz) { return FastExcel.read(inputStream, clazz, new AnalysisEventListener() { @Override public void invoke(Object o, AnalysisContext analysisContext) { Integer rowIndex = analysisContext.readRowHolder().getRowIndex(); rowIndex += 1; // 行号从0开始,需要加1 try { // 调用字段校验方法 ExcelImportValid.valid(o); } catch (Exception e) { throw new ServiceException(String.format("第%d行:%s", rowIndex, e.getMessage())); } } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } }).sheet().doReadSync(); // 读取 Excel 文件中的第一个工作表 } }