diff --git a/laws-modules/src/main/java/com/jero/modules/laws/common/service/impl/LawsCommonServiceImpl.java b/laws-modules/src/main/java/com/jero/modules/laws/common/service/impl/LawsCommonServiceImpl.java index 0de24e43..b55ec7e6 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/common/service/impl/LawsCommonServiceImpl.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/common/service/impl/LawsCommonServiceImpl.java @@ -1,5 +1,6 @@ package com.jero.modules.laws.common.service.impl; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -9,6 +10,7 @@ import com.jero.common.constant.enums.YesOrNoEnum; import com.jero.common.exception.JeroBootException; import com.jero.common.system.vo.LoginUser; import com.jero.common.util.MessageUtils; +import com.jero.common.util.MinioUtil; import com.jero.modules.laws.common.constant.FieldCommon; import com.jero.modules.laws.common.constant.ResultCommon; import com.jero.modules.laws.common.mapper.LawsCommonMapper; @@ -16,8 +18,10 @@ import com.jero.modules.laws.common.service.ILawsCommonService; import com.jero.modules.laws.common.vo.ManyStandardSelectionBox; import com.jero.modules.laws.common.vo.ManyStandardSelectionBoxVO; import com.jero.modules.laws.standard.entity.LawsNodeRelation; +import com.jero.modules.laws.standard.entity.LawsStandardFile; import com.jero.modules.laws.standard.service.ILawsNodeRelationService; import com.jero.modules.laws.standard.service.ILawsReplacedStandardService; +import com.jero.modules.laws.standard.service.ILawsStandardFileService; import com.jero.modules.laws.standard.service.ILawsUpdateRecordService; import com.jero.modules.oss.entity.OSSFile; import com.jero.modules.oss.service.IOSSFileService; @@ -47,11 +51,15 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * @Author: liao @@ -82,6 +90,8 @@ public class LawsCommonServiceImpl implements ILawsCommonService { private ILawsNodeRelationService lawsNodeRelationService; @Autowired private ILawsReplacedStandardService lawsReplacedStandardService; + @Autowired + private ILawsStandardFileService lawsStandardFileService; /** * @Author: liao @@ -877,17 +887,29 @@ public class LawsCommonServiceImpl implements ILawsCommonService { public void exportDataWithFile(HttpServletResponse response, Map parameterMap, String sheetName, String fileName) { try { // 创建表头 - List headers = this.getExportHeader(parameterMap); + List headers = this.getExportHeaderWithFile(parameterMap); // 获取数据 IPage> commonPage = this.getExportData(parameterMap, headers); List> records = commonPage.getRecords(); - // 获取所有标准主键id + + // 获取表头中的文件相关类型的对象集合 + List standardNos = records.stream().map(r -> r.get("standard_number").toString()).collect(Collectors.toList()); + List fileHeaders = headers.stream().filter(h -> h.getFieldShowType().equals("8")).collect(Collectors.toList()); + Map fileNameByTypeMap = fileHeaders.stream() + .collect(Collectors.toMap(LawsTag::getDbFieldName, LawsTag::getDbFieldTxt)); - // 将文件名设置回数据列表 + // 获取所有文件 + Map> fileMap = lawsStandardFileService.getAllFiles(standardNos); + // 设置文件字段 + lawsStandardFileService.setRecordFile(records, standardNos, fileHeaders); + + // 创建Excel + ByteArrayOutputStream excelOutputStream = new ByteArrayOutputStream(); XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet(sheetName); + // Excel填充内容 Row headerRow = sheet.createRow(0); for (int i = 0; i < headers.size(); i++) { Cell headerCell = headerRow.createCell(i); @@ -907,19 +929,117 @@ public class LawsCommonServiceImpl implements ILawsCommonService { } } - // 设置响应头和内容类型 - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx"); - - // 写出到响应流 - workbook.write(response.getOutputStream()); + // 保存Excel到OutputStream + workbook.write(excelOutputStream); workbook.close(); + + // 准备ZIP + response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".zip"); + ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream()); + + // 将Excel加入ZIP + ZipEntry excelEntry = new ZipEntry(fileName + ".xlsx"); + zipOut.putNextEntry(excelEntry); + byte[] bytes = excelOutputStream.toByteArray(); + zipOut.write(bytes, 0, bytes.length); + zipOut.closeEntry(); + + // 将文件和文件夹加入ZIP + for (Map.Entry> entry : fileMap.entrySet()) { + String folderName = entry.getKey(); + List files = entry.getValue(); + + // 收集所有文件id + List fileIds = files.stream() + .map(LawsStandardFile::getFileId) + .collect(Collectors.toList()); + + // 找到所有文件记录 + Map ossFileMap = ossFileService.listByIds(fileIds) + .stream() + .collect(Collectors.toMap(OSSFile::getId, Function.identity())); + + List filePathList = new ArrayList<>(); + Map nameCountMap = new HashMap<>(); + + for (LawsStandardFile file : files) { + String fileNameByType = fileNameByTypeMap.get(file.getFileType()); + String baseFilePath = folderName + "/" + fileNameByType; + String currentFilePath = baseFilePath; + + if (filePathList.contains(currentFilePath)) { + int count = nameCountMap.getOrDefault(baseFilePath, 1); + + // 更新之前的名字 + int index = filePathList.indexOf(currentFilePath); + filePathList.set(index, baseFilePath + count); + + // 更新当前名字 + count++; + currentFilePath = baseFilePath + count; + + nameCountMap.put(baseFilePath, count + 1); + } else if (nameCountMap.containsKey(baseFilePath)) { + int count = nameCountMap.get(baseFilePath); + currentFilePath = baseFilePath + count; + nameCountMap.put(baseFilePath, count + 1); + } + + filePathList.add(currentFilePath); + } + + Iterator iterator = filePathList.iterator(); + + for (LawsStandardFile file : files) { + if (iterator.hasNext()) { + String updatedFilePath = iterator.next(); + file.setFileName(updatedFilePath); + } + } + + for (LawsStandardFile file : files) { + OSSFile ossFile = ossFileMap.get(file.getFileId()); + String fileExtension = FileUtil.extName(ossFile.getFileName()); + String filePath = file.getFileName() + "." + fileExtension; + ZipEntry fileEntry = new ZipEntry(filePath); + zipOut.putNextEntry(fileEntry); + + // 将文件取出存入流中 + bytes = getMinioFileContent(ossFile); + zipOut.write(bytes, 0, bytes.length); + zipOut.closeEntry(); + } + } + zipOut.close(); } catch (Exception e) { - log.error("导出excel异常", e); - throw new JeroBootException("导出excel异常", e); + log.error("导出zip异常", e); + throw new JeroBootException("导出zip异常", e); } } + private byte[] getMinioFileContent(OSSFile file) throws Exception { + String fileUrl = file.getUrl(); + String minioUrl = MinioUtil.getMinioUrl(); + minioUrl = minioUrl + MinioUtil.getBucketName() + "/"; + String url = fileUrl.replace(minioUrl, ""); + + try (InputStream inputStream = MinioUtil.getMinioFile(MinioUtil.getBucketName(), url); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream() + ) { + byte[] buf = new byte[1024]; + int len; + while ((len = inputStream.read(buf)) > 0) { + outputStream.write(buf, 0, len); + } + return outputStream.toByteArray(); + } catch (Exception e) { + log.error(e.getMessage()); + throw e; + } + } + + /** * @Author: liao diff --git a/laws-modules/src/main/java/com/jero/modules/laws/standard/entity/LawsStandardFile.java b/laws-modules/src/main/java/com/jero/modules/laws/standard/entity/LawsStandardFile.java index 1e1b31d9..c2fa9c68 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/standard/entity/LawsStandardFile.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/standard/entity/LawsStandardFile.java @@ -18,10 +18,10 @@ import lombok.experimental.Accessors; * @TableName laws_standard_file */ @Data -@TableName("laws_update_record") +@TableName("laws_standard_file") @Accessors(chain = true) @EqualsAndHashCode(callSuper = false) -@ApiModel(value="laws_update_record对象", description="更新记录") +@ApiModel(value="laws_standard_file对象", description="标准文件") public class LawsStandardFile implements Serializable { /** * 主键ID @@ -84,6 +84,20 @@ public class LawsStandardFile implements Serializable { @ApiModelProperty(value = "所属模块编码") private String moduleCode; + /** + * 文件名 + */ + @TableField(exist = false) + @ApiModelProperty(value = "文件名") + private String fileName; + + /** + * 真实存储的文件名 + */ + @TableField(exist = false) + @ApiModelProperty(value = "真实存储的文件名") + private String fileDiskName; + @TableField(exist = false) private static final long serialVersionUID = 1978687668756786786L; } \ No newline at end of file diff --git a/laws-modules/src/main/java/com/jero/modules/laws/standard/mapper/LawsStandardFileMapper.java b/laws-modules/src/main/java/com/jero/modules/laws/standard/mapper/LawsStandardFileMapper.java index 24c6c500..c1f4ca14 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/standard/mapper/LawsStandardFileMapper.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/standard/mapper/LawsStandardFileMapper.java @@ -2,6 +2,9 @@ package com.jero.modules.laws.standard.mapper; import com.jero.modules.laws.standard.entity.LawsStandardFile; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** * @author ThinkBook @@ -11,6 +14,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; */ public interface LawsStandardFileMapper extends BaseMapper { + List getFilesByStandardNos(@Param("standardNos") List standardNos); } diff --git a/laws-modules/src/main/java/com/jero/modules/laws/standard/mapper/xml/LawsStandardFileMapper.xml b/laws-modules/src/main/java/com/jero/modules/laws/standard/mapper/xml/LawsStandardFileMapper.xml index db1d6e51..4e517859 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/standard/mapper/xml/LawsStandardFileMapper.xml +++ b/laws-modules/src/main/java/com/jero/modules/laws/standard/mapper/xml/LawsStandardFileMapper.xml @@ -23,4 +23,20 @@ standard_no,file_id,file_type, module_code + + diff --git a/laws-modules/src/main/java/com/jero/modules/laws/standard/service/ILawsStandardFileService.java b/laws-modules/src/main/java/com/jero/modules/laws/standard/service/ILawsStandardFileService.java index 86af8cd7..7355f893 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/standard/service/ILawsStandardFileService.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/standard/service/ILawsStandardFileService.java @@ -2,6 +2,10 @@ package com.jero.modules.laws.standard.service; import com.jero.modules.laws.standard.entity.LawsStandardFile; import com.baomidou.mybatisplus.extension.service.IService; +import com.jero.modules.tag.entity.LawsTag; + +import java.util.List; +import java.util.Map; /** * @author ThinkBook @@ -10,4 +14,12 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface ILawsStandardFileService extends IService { + /** + * 根据标准编号集合获取文件列表 + * @param standardNos + * @return + */ + Map> getAllFiles(List standardNos); + + void setRecordFile(List> records, List standardNos, List fileHeaders); } diff --git a/laws-modules/src/main/java/com/jero/modules/laws/standard/service/impl/LawsStandardFileServiceImpl.java b/laws-modules/src/main/java/com/jero/modules/laws/standard/service/impl/LawsStandardFileServiceImpl.java index 70ce162a..bfc75243 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/standard/service/impl/LawsStandardFileServiceImpl.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/standard/service/impl/LawsStandardFileServiceImpl.java @@ -1,23 +1,89 @@ package com.jero.modules.laws.standard.service.impl; +import cn.hutool.core.io.FileUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.jero.common.exception.JeroBootException; +import com.jero.common.system.api.ISysBaseAPI; import com.jero.modules.laws.standard.entity.LawsStandardFile; import com.jero.modules.laws.standard.service.ILawsStandardFileService; import com.jero.modules.laws.standard.mapper.LawsStandardFileMapper; +import com.jero.modules.tag.entity.LawsTag; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + /** -* @author ThinkBook -* @description 针对表【laws_standard_file】的数据库操作Service实现 -* @createDate 2023-09-20 10:45:16 -*/ + * @author ThinkBook + * @description 针对表【laws_standard_file】的数据库操作Service实现 + * @createDate 2023-09-20 10:45:16 + */ @Service @Transactional(rollbackFor = JeroBootException.class) public class LawsStandardFileServiceImpl extends ServiceImpl - implements ILawsStandardFileService { + implements ILawsStandardFileService { + @Resource + private LawsStandardFileMapper standardFileMapper; + + @Override + public Map> getAllFiles(List standardNos) { + // 找到所有相关文件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(LawsStandardFile::getStandardNo, standardNos); + List list = list(queryWrapper); + + // 将List转成Map + return list.stream() + .collect(Collectors.groupingBy(LawsStandardFile::getStandardNo)); + } + + @Override + public void setRecordFile(List> records, List standardNos, List fileHeaders) { + // 找到所有相关文件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(LawsStandardFile::getStandardNo, standardNos); + List list = standardFileMapper.getFilesByStandardNos(standardNos); + // 按照标准编号和文件类型分组 + Map> groupMap = list.stream() + .collect(Collectors.groupingBy( + sf -> sf.getStandardNo() + "-" + sf.getFileType() // Key: standardNo-fileType + )); + + // 遍历每个记录 + for (Map record : records) { + String standardNo = (String) record.get("standard_number"); + for (LawsTag tag : fileHeaders) { + String fileName = tag.getDbFieldTxt(); + String key = standardNo + "-" + tag.getDbFieldName(); + List lawsStandardFiles = groupMap.get(key); + if (lawsStandardFiles == null) { + continue; + } + StringBuilder allFileName = new StringBuilder(); + // 遍历找到的结果 + if (lawsStandardFiles.size() == 1) { + String fileExtension = "." + FileUtil.extName(lawsStandardFiles.get(0).getFileDiskName()); + allFileName = new StringBuilder(standardNo + "/" + fileName + fileExtension); + } else { + for (int i = 1; i <= lawsStandardFiles.size(); i++) { + String fileExtension = "." + FileUtil.extName(lawsStandardFiles.get(0).getFileDiskName()); + allFileName.append(standardNo).append("/").append(fileName).append(i).append(fileExtension).append(","); + } + // 去除最后一个, + allFileName = new StringBuilder(allFileName.substring(0, allFileName.length() - 1)); + } + // 最终设置 + record.put(tag.getDbFieldName(), allFileName.toString()); + } + } + } }