diff --git a/tagApi-common/src/main/java/hw/tagApi/common/utils/poi/ExcelUtil.java b/tagApi-common/src/main/java/hw/tagApi/common/utils/poi/ExcelUtil.java index 1297885..d8b6edf 100644 --- a/tagApi-common/src/main/java/hw/tagApi/common/utils/poi/ExcelUtil.java +++ b/tagApi-common/src/main/java/hw/tagApi/common/utils/poi/ExcelUtil.java @@ -107,7 +107,7 @@ public class ExcelUtil /** * Excel sheet最大行数,默认65536 */ - public static final int sheetSize = 65536; + public static final int sheetSize = 60000; /** * 工作表名称 diff --git a/tagApi-service/src/main/java/hw/tagApi/service/constant/ApiConstants.java b/tagApi-service/src/main/java/hw/tagApi/service/constant/ApiConstants.java index 0c78984..5304e4e 100644 --- a/tagApi-service/src/main/java/hw/tagApi/service/constant/ApiConstants.java +++ b/tagApi-service/src/main/java/hw/tagApi/service/constant/ApiConstants.java @@ -27,9 +27,9 @@ public class ApiConstants { public static final Integer TE_LENGTH = 24; /** - * 导出条数限制,导出为zip文件 + * 每个Excel文件最大记录数 */ - public static final Long ZIP_MAX_DATA = 100000L; + public static final Integer MAX_RECORDS_PER_EXCEL = 300000; // /** * 回调返回请求 @@ -45,7 +45,7 @@ public class ApiConstants { /** * 导入模式 */ - //“新增”模式需要 TID和 EPC查重,确保新添加的内容唯一性,建立新的记录; + //“新增”模式需要 TID和 EPC查重,确保新添加的内容唯一性,建立新记录; public static final String MODE_ADD = "新增"; //“更新”模式则无需查重TID,按照导入表格中的TID去查找相关记录,并逐条更新TID对应的其他记录,如EPC等(只更新导入表格中含有的信息,没有的信息保持原状,而不是替换为空白内容) public static final String MODE_UPDATE = "更新"; diff --git a/tagApi-service/src/main/java/hw/tagApi/service/controller/KDocsApiController.java b/tagApi-service/src/main/java/hw/tagApi/service/controller/KDocsApiController.java index 37ea16e..6721f49 100644 --- a/tagApi-service/src/main/java/hw/tagApi/service/controller/KDocsApiController.java +++ b/tagApi-service/src/main/java/hw/tagApi/service/controller/KDocsApiController.java @@ -174,7 +174,6 @@ public class KDocsApiController extends BaseController { } // 设置响应头 - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(attachInfo.getAttachName(), "UTF-8")); diff --git a/tagApi-service/src/main/java/hw/tagApi/service/domain/HwTagRecord.java b/tagApi-service/src/main/java/hw/tagApi/service/domain/HwTagRecord.java index 31af2c9..33f6ba4 100644 --- a/tagApi-service/src/main/java/hw/tagApi/service/domain/HwTagRecord.java +++ b/tagApi-service/src/main/java/hw/tagApi/service/domain/HwTagRecord.java @@ -10,6 +10,7 @@ import hw.tagApi.common.core.domain.BaseEntity; import hw.tagApi.common.annotation.Excel.Type; import lombok.Data; import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; /** * 标签记录对象 hw_tag_record @@ -150,16 +151,16 @@ public class HwTagRecord extends BaseEntity { @Excel(name = "备注") private String remark; - @Excel(name = "", type = Type.EXPORT) + @Excel(name = "", headerBackgroundColor = IndexedColors.WHITE1, type = Type.EXPORT) private String placeholderOne; - @Excel(name = "", type = Type.EXPORT) + @Excel(name = "", headerBackgroundColor = IndexedColors.WHITE1, type = Type.EXPORT) private String placeholderTwo; @Excel(name = "团队中心", type = Type.EXPORT, align = HorizontalAlignment.LEFT) private String teamCenter; - @Excel(name = "标签数据总库导出", type = Type.EXPORT, align = HorizontalAlignment.LEFT) + @Excel(name = "标签数据总库导出", type = Type.EXPORT, align = HorizontalAlignment.LEFT, width = 24) private String databaseExport; /** diff --git a/tagApi-service/src/main/java/hw/tagApi/service/utils/TagExcelUtil.java b/tagApi-service/src/main/java/hw/tagApi/service/utils/TagExcelUtil.java index db1ebef..189769d 100644 --- a/tagApi-service/src/main/java/hw/tagApi/service/utils/TagExcelUtil.java +++ b/tagApi-service/src/main/java/hw/tagApi/service/utils/TagExcelUtil.java @@ -16,9 +16,15 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import java.io.InputStream; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import static hw.tagApi.service.constant.ApiConstants.MAX_RECORDS_PER_EXCEL; /** * 标签Excel工具类 @@ -27,6 +33,7 @@ import java.util.*; public class TagExcelUtil { private static final Logger log = LoggerFactory.getLogger(TagExcelUtil.class); + /** * 解析标签数据Excel * @@ -240,7 +247,7 @@ public class TagExcelUtil { } /** - * 生成标签Excel文件 + * 生成标签Excel文件,支持大数据量分片导出 * * @param records 标签记录列表 * @param fileName 文件名 @@ -248,24 +255,12 @@ public class TagExcelUtil { */ public static String generateTagExcel(List records, String fileName) { try { - // 使用ExcelUtil导出 - ExcelUtil util = new ExcelUtil<>(HwTagRecord.class); - // 导出Excel并获取结果 - AjaxResult result = util.exportExcel(records, "标签数据"); - if (result != null && HttpStatus.SUCCESS == Integer.parseInt(String.valueOf(result.get(AjaxResult.CODE_TAG)))) { - String exportFileName = (String) result.get(AjaxResult.MSG_TAG); - if (exportFileName == null || exportFileName.isEmpty()) { - throw new RuntimeException("导出文件名不能为空"); - } - String fileUrl = ApiConstants.BASE_URL + UUID.randomUUID(); - String absoluteFile = ExcelUtil.getAbsoluteFile(exportFileName); - // 存储文件信息 - saveFileInfo(fileUrl, fileName, absoluteFile); - log.info("Excel文件生成成功: {}", absoluteFile); - return fileUrl; + if (records.size() <= MAX_RECORDS_PER_EXCEL) { + // 数据量小于等于100,直接导出单个Excel + return generateSingleExcel(records, fileName); } else { - String errorMsg = result != null ? (String) result.get(AjaxResult.MSG_TAG) : "导出失败"; - throw new RuntimeException("导出Excel失败: " + errorMsg); + // 数据量大于100,分片导出并压缩 + return generateMultipleExcelAndZip(records, fileName); } } catch (Exception e) { log.error("生成Excel文件失败", e); @@ -273,6 +268,88 @@ public class TagExcelUtil { } } + /** + * 生成单个Excel文件 + */ + private static String generateSingleExcel(List records, String fileName) { + ExcelUtil util = new ExcelUtil<>(HwTagRecord.class); + AjaxResult result = util.exportExcel(records, "团队中心-标签数据总库导出"); + if (result != null && HttpStatus.SUCCESS == Integer.parseInt(String.valueOf(result.get(AjaxResult.CODE_TAG)))) { + String exportFileName = (String) result.get(AjaxResult.MSG_TAG); + if (exportFileName == null || exportFileName.isEmpty()) { + throw new RuntimeException("导出文件名不能为空"); + } + String fileUrl = ApiConstants.BASE_URL + UUID.randomUUID(); + String absoluteFile = ExcelUtil.getAbsoluteFile(exportFileName); + saveFileInfo(fileUrl, fileName, absoluteFile); + log.info("Excel文件生成成功: {}", absoluteFile); + return fileUrl; + } else { + String errorMsg = result != null ? (String) result.get(AjaxResult.MSG_TAG) : "导出失败"; + throw new RuntimeException("导出Excel失败: " + errorMsg); + } + } + + /** + * 生成多个Excel文件并压缩成zip + */ + private static String generateMultipleExcelAndZip(List records, String fileName) { + try { + // 计算需要多少个Excel文件 + int totalFiles = (int) Math.ceil((double) records.size() / MAX_RECORDS_PER_EXCEL); + List excelFiles = new ArrayList<>(); + ExcelUtil util = new ExcelUtil<>(HwTagRecord.class); + + // 分片生成Excel文件 + for (int i = 0; i < totalFiles; i++) { + int fromIndex = i * MAX_RECORDS_PER_EXCEL; + int toIndex = Math.min(fromIndex + MAX_RECORDS_PER_EXCEL, records.size()); + List subList = records.subList(fromIndex, toIndex); + + // 生成Excel文件 + AjaxResult result = util.exportExcel(subList, "团队中心-标签数据总库导出_" + (i + 1)); + if (result != null && HttpStatus.SUCCESS == Integer.parseInt(String.valueOf(result.get(AjaxResult.CODE_TAG)))) { + String exportFileName = (String) result.get(AjaxResult.MSG_TAG); + if (exportFileName != null && !exportFileName.isEmpty()) { + excelFiles.add(ExcelUtil.getAbsoluteFile(exportFileName)); + } + } + } + + // 生成zip文件名 + String zipFileName = fileName.replace(".xlsx", ".zip"); + String zipFilePath = ExcelUtil.getAbsoluteFile(zipFileName); + + // 创建zip文件 + try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(Paths.get(zipFilePath)))) { + for (String excelFile : excelFiles) { + File fileToZip = new File(excelFile); + try (FileInputStream fis = new FileInputStream(fileToZip)) { + ZipEntry zipEntry = new ZipEntry(fileToZip.getName()); + zipOut.putNextEntry(zipEntry); + byte[] bytes = new byte[1024]; + int length; + while ((length = fis.read(bytes)) >= 0) { + zipOut.write(bytes, 0, length); + } + } + // 删除临时Excel文件 + fileToZip.delete(); + } + } + + // 保存zip文件信息 + String fileUrl = ApiConstants.BASE_URL + UUID.randomUUID(); + saveFileInfo(fileUrl, zipFileName, zipFilePath); + log.info("ZIP文件生成成功: {}", zipFilePath); + return fileUrl; + + } catch (Exception e) { + log.error("生成ZIP文件失败", e); + throw new RuntimeException("生成ZIP文件失败: " + e.getMessage()); + } + } + /** * 保存文件信息到数据库 *