update:修改参会信息的导入为接收一个压缩包

This commit is contained in:
sunzheng
2024-09-19 13:59:03 +08:00
parent e70bf5ce52
commit eca5251c66
2 changed files with 131 additions and 21 deletions
@@ -3,8 +3,10 @@ package com.jero.modules.laws.club.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.api.vo.Result; import com.jero.common.api.vo.Result;
import com.jero.common.constant.enums.LanguageEnum;
import com.jero.common.exception.JeroBootException; import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.DictModel; import com.jero.common.system.vo.DictModel;
import com.jero.common.util.MessageUtils;
import com.jero.modules.laws.club.entity.LawsClubMeeting; import com.jero.modules.laws.club.entity.LawsClubMeeting;
import com.jero.modules.laws.club.mapper.LawsClubMeetingMapper; import com.jero.modules.laws.club.mapper.LawsClubMeetingMapper;
import com.jero.modules.laws.club.service.ILawsClubMeetingService; import com.jero.modules.laws.club.service.ILawsClubMeetingService;
@@ -13,6 +15,7 @@ import com.jero.modules.laws.club.vo.excel.LawsClubMeetingExcel;
import com.jero.modules.laws.club.vo.excel.LawsClubMeetingMemberExcel; import com.jero.modules.laws.club.vo.excel.LawsClubMeetingMemberExcel;
import com.jero.modules.oss.entity.OSSFile; import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService; import com.jero.modules.oss.service.IOSSFileService;
import com.jero.modules.split.common.FileUnZip;
import com.jero.modules.system.entity.SysDepart; import com.jero.modules.system.entity.SysDepart;
import com.jero.modules.system.entity.SysUser; import com.jero.modules.system.entity.SysUser;
import com.jero.modules.system.service.ISysDepartService; import com.jero.modules.system.service.ISysDepartService;
@@ -20,11 +23,14 @@ import com.jero.modules.system.service.ISysDictService;
import com.jero.modules.system.service.ISysUserService; import com.jero.modules.system.service.ISysUserService;
import com.jero.modules.tag.entity.LawsTag; import com.jero.modules.tag.entity.LawsTag;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -32,17 +38,19 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.*;
import java.io.OutputStream;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.*; import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/** /**
* <p> * <p>
@@ -63,6 +71,8 @@ public class LawsClubMeetingServiceImpl extends ServiceImpl<LawsClubMeetingMappe
private ISysDictService sysDictService; private ISysDictService sysDictService;
@Resource @Resource
private IOSSFileService iossFileService; private IOSSFileService iossFileService;
@Value(value = "${jero.path.upload}")
private String uploadpath;
@Override @Override
@@ -76,21 +86,36 @@ public class LawsClubMeetingServiceImpl extends ServiceImpl<LawsClubMeetingMappe
String fieldTxts = "会议名称,会议日期,会议费用,线上/线下地点,计划完成日期,通知人,通知部门,通知部门专业模块," + String fieldTxts = "会议名称,会议日期,会议费用,线上/线下地点,计划完成日期,通知人,通知部门,通知部门专业模块," +
"是否宣贯,会议组织人,会议内容,参会人员,参会部门,参会部门专业模块,参会报告,备注"; "是否宣贯,会议组织人,会议内容,参会人员,参会部门,参会部门专业模块,参会报告,备注";
String mustInputFlags = "no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no"; String mustInputFlags = "no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no";
String fieldTypeLists = "1,2,1,1,2,3,1,1,1,1,1,3,1,1,1,1"; // 1代表是文本输入类型 2代表日期输入 3代表 文本输入,姓名(工号) String fieldTypeLists = "1,2,1,1,2,3,1,1,1,1,1,3,1,1,1,1"; // 1代表文本输入类型, 2代表日期输入, 3代表文本输入, 姓名(工号)
List<LawsTag> lawsTags = ExcelUtil.createLawsTags(fieldTxts, mustInputFlags, fieldTypeLists); List<LawsTag> lawsTags = ExcelUtil.createLawsTags(fieldTxts, mustInputFlags, fieldTypeLists);
// 生成 Excel 文件并写入字节数组
try (Workbook workbook = ExcelUtil.createWorkBookWithLawsTags(lawsTags, "参会信息", describe); try (Workbook workbook = ExcelUtil.createWorkBookWithLawsTags(lawsTags, "参会信息", describe);
OutputStream out = response.getOutputStream()) { ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
// 将Excel写入到字节数组
workbook.write(baos);
byte[] excelBytes = baos.toByteArray();
// 生成ZIP文件
ByteArrayOutputStream baosZip = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baosZip)) {
// 将Excel文件放入ZIP包中的目录下
ZipEntry entry = new ZipEntry( "参会信息导入模板.xls");
zos.putNextEntry(entry);
zos.write(excelBytes);
zos.closeEntry();
}
// 设置HTTP响应头 // 设置HTTP响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setContentType("application/zip;charset=UTF-8");
response.setCharacterEncoding("UTF-8"); // 确保响应流使用UTF-8编码 response.setCharacterEncoding("UTF-8"); // 确保响应流使用UTF-8编码
// 处理文件名乱码问题 // 处理文件名乱码问题
String encodedFileName = URLEncoder.encode("基本信息", StandardCharsets.UTF_8.name()).replace("+", "%20"); String encodedFileName = URLEncoder.encode("导出模板", StandardCharsets.UTF_8.name()).replace("+", "%20");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName + ".xls"); response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName + ".zip");
// 写入Excel并输出 // 输出ZIP文件到响应流中
workbook.write(out); try (OutputStream out = response.getOutputStream()) {
out.flush(); baosZip.writeTo(out);
out.flush();
}
} catch (IOException e) { } catch (IOException e) {
log.error("导出Excel失败", e); log.error("导出模板失败", e);
} }
} }
@@ -99,19 +124,33 @@ public class LawsClubMeetingServiceImpl extends ServiceImpl<LawsClubMeetingMappe
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
List<LawsClubMeeting> lawsClubMeetingList = new ArrayList<>(); List<LawsClubMeeting> lawsClubMeetingList = new ArrayList<>();
File saveDirectory = null;
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) { for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象 MultipartFile file = entity.getValue();// 获取上传文件对象
try { try {
Map<String, File> unZipFileMap = analyzeZipFile(file);
saveDirectory = unZipFileMap.get("saveDirectory");
// 移除键为 "saveDirectory" 的文件
unZipFileMap.remove("saveDirectory");
// 拿到excel的导入文件
File meetingCnTemplate = unZipFileMap.get("参会信息导入模板.xls");
File meetingEnTemplate = unZipFileMap.get("Conference InformationImport Template.xls");
// 确定哪个文件不为空,并赋值给 excelImportFile
File excelImportFile = (meetingCnTemplate != null) ? meetingCnTemplate : meetingEnTemplate;
// 将模板文件移除
unZipFileMap.remove("参会信息导入模板.xls");
unZipFileMap.remove("Conference InformationImport Template.xls");
ImportParams params = new ImportParams(); ImportParams params = new ImportParams();
params.setNeedSave(false); params.setNeedSave(false);
List<LawsClubMeetingExcel> excelList = ExcelImportUtil.importExcel(file.getInputStream(), LawsClubMeetingExcel.class, params); List<LawsClubMeetingExcel> excelList = ExcelImportUtil.importExcel(new FileInputStream(excelImportFile), LawsClubMeetingExcel.class, params);
excelList = excelList.stream().skip(2).filter(item -> !Objects.isNull(item)).collect(Collectors.toList()); excelList = excelList.stream().skip(2).filter(item -> !Objects.isNull(item)).collect(Collectors.toList());
if (CollectionUtils.isEmpty(excelList)) { if (CollectionUtils.isEmpty(excelList)) {
throw new JeroBootException("没有数据可导入"); throw new JeroBootException("没有数据可导入");
} }
// 处理分类数据 // 处理分类数据
List<LawsClubMeetingExcel> meetingExcels = processingMeetingData(excelList); List<LawsClubMeetingExcel> meetingExcels = processingMeetingData(excelList);
StringBuilder msg = validateExcelData(meetingExcels); // 校验数据 // 校验数据
StringBuilder msg = validateExcelData(meetingExcels, unZipFileMap);
if (StringUtils.isNotEmpty(msg.toString())) { if (StringUtils.isNotEmpty(msg.toString())) {
return Result.error(msg.toString()); return Result.error(msg.toString());
} }
@@ -127,6 +166,10 @@ public class LawsClubMeetingServiceImpl extends ServiceImpl<LawsClubMeetingMappe
log.error(e.getMessage(),e); log.error(e.getMessage(),e);
return Result.error("文件导入失败:"+e.getMessage()); return Result.error("文件导入失败:"+e.getMessage());
} finally { } finally {
//删除原上传文件
if (!Objects.isNull(saveDirectory)) {
FileUnZip.deleteDir(saveDirectory);
}
try { try {
file.getInputStream().close(); file.getInputStream().close();
} catch (IOException e) { } catch (IOException e) {
@@ -137,7 +180,68 @@ public class LawsClubMeetingServiceImpl extends ServiceImpl<LawsClubMeetingMappe
return Result.OK(lawsClubMeetingList); return Result.OK(lawsClubMeetingList);
} }
private StringBuilder validateExcelData(List<LawsClubMeetingExcel> meetingExcels) { public Map<String, File> analyzeZipFile(MultipartFile file) throws IOException {
int pos = file.getOriginalFilename().lastIndexOf(".");
String str = file.getOriginalFilename().substring(pos+1).toLowerCase();
String filenameorg = file.getOriginalFilename().substring(0,pos);
String resultMsg = "";
if (!str.equals("zip")) {
if(MessageUtils.getLanguage().getValue().equals(LanguageEnum.CN.getValue())){
resultMsg = "请上传zip文件";
}else{
resultMsg = "Please upload a zip file";
}
throw new JeroBootException(resultMsg);
}
String path = uploadpath + File.separator + "modal" + File.separator + filenameorg + System.currentTimeMillis();
File saveDirectory = new File(path);
if(!saveDirectory.isDirectory()){
saveDirectory.mkdir();
}
FileUtils.copyInputStreamToFile(file.getInputStream(), new File(path +File.separator+ file.getOriginalFilename()));
try {
//解压缩
String zipEntryName = FileUnZip.unZipFiles2(path +File.separator+ file.getOriginalFilename(), path);
// 1.获取其中的文件,
List<File> fileList = FileUnZip.readExcelFile(zipEntryName);
if (fileList.size() < 1) {
FileUnZip.deleteDir(saveDirectory);
if(MessageUtils.getLanguage().getValue().equals(LanguageEnum.CN.getValue())){
resultMsg = "没有可导入的数据,请检查!";
}else{
resultMsg = "No data to import, please check";
}
throw new JeroBootException(resultMsg);
}
Map<String, File> fileMap = fileList.stream().collect(Collectors.toMap(File::getName, Function.identity()));
File meetingCnTemplate = fileMap.get("参会信息导入模板.xls");
File meetingEnTemplate = fileMap.get("Conference InformationImport Template.xls");
if (Objects.isNull(meetingCnTemplate) && Objects.isNull(meetingEnTemplate)) {
//删除原上传文件
FileUnZip.deleteDir(saveDirectory);
if(MessageUtils.getLanguage().getValue().equals(LanguageEnum.CN.getValue())){
resultMsg = "压缩包内没有Excel模板文件";
}else{
resultMsg = "In the cabinet did not upload the Excel template file";
}
throw new JeroBootException(resultMsg);
}
fileMap.put("saveDirectory", saveDirectory);
return fileMap;
} catch (StringIndexOutOfBoundsException e){
//删除原上传文件
FileUnZip.deleteDir(saveDirectory);
if(MessageUtils.getLanguage().getValue().equals(LanguageEnum.CN.getValue())){
resultMsg = "读取失败,压缩包内需要把所有导入文件放入一个父级文件夹下";
}else{
resultMsg = "The data fails to be read. In the compressed package, all imported files need to be placed in a parent folder";
}
throw new JeroBootException(resultMsg);
}
}
private StringBuilder validateExcelData(List<LawsClubMeetingExcel> meetingExcels, Map<String, File> unZipFileMap) throws IOException{
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
// 拿到这个流程的名称 // 拿到这个流程的名称
List<DictModel> specializedModuleList = sysDictService.getDictItems("professional_module"); List<DictModel> specializedModuleList = sysDictService.getDictItems("professional_module");
@@ -235,14 +339,15 @@ public class LawsClubMeetingServiceImpl extends ServiceImpl<LawsClubMeetingMappe
} }
// 校验参会报告 // 校验参会报告
if (StringUtils.isNotBlank(lawsClubMeetingMemberExcel.getMeetingFileId())) { if (StringUtils.isNotBlank(lawsClubMeetingMemberExcel.getMeetingFileId())) {
List<OSSFile> ossFiles = iossFileService.list(new LambdaQueryWrapper<OSSFile>() File file = unZipFileMap.get(lawsClubMeetingMemberExcel.getMeetingFileId());
.eq(OSSFile::getFileName, lawsClubMeetingMemberExcel.getMeetingFileId()) if (Objects.isNull(file)) {
.orderByDesc(OSSFile::getCreateTime) msgSub.append(getErrorMsg(i, "参会报告:" + lawsClubMeetingMemberExcel.getMeetingFileId() + "在压缩包内不存在;"));
.last("LIMIT 1"));
if (CollectionUtils.isEmpty(ossFiles)) {
msgSub.append(getErrorMsg(i, "参会报告:" + lawsClubMeetingMemberExcel.getMeetingFileId() + "不存在;"));
}else { }else {
lawsClubMeetingMemberExcel.setMeetingFileId(ossFiles.get(0).getId()); FileInputStream input = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(), "application/octet-stream", input);
// 上传该文件
Result<OSSFile> ossFileResult = iossFileService.commonUpload(multipartFile, "");
lawsClubMeetingMemberExcel.setMeetingFileId(ossFileResult.getResult().getId());
} }
} }
} }
@@ -1,5 +1,6 @@
package com.jero.modules.laws.club.vo.excel; package com.jero.modules.laws.club.vo.excel;
import com.jero.common.aspect.annotation.Dict;
import lombok.Data; import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel; import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable; import java.io.Serializable;
@@ -8,15 +9,19 @@ import java.io.Serializable;
public class LawsClubMeetingMemberExcel implements Serializable { public class LawsClubMeetingMemberExcel implements Serializable {
@Excel(name = "参会人员", width = 20) @Excel(name = "参会人员", width = 20)
@Dict(dictTable = "sys_user", dicCode = "id", dicText = "realname")
private String memberId; private String memberId;
@Excel(name = "参会部门", width = 20) @Excel(name = "参会部门", width = 20)
@Dict(dictTable = "sys_depart", dicCode = "id", dicText = "depart_name")
private String departId; private String departId;
@Excel(name = "参会部门专业模块", width = 20) @Excel(name = "参会部门专业模块", width = 20)
@Dict(dicCode = "professional_module")
private String meetingSpecializedModule; private String meetingSpecializedModule;
@Excel(name = "参会报告", width = 20) @Excel(name = "参会报告", width = 20)
@Dict(dictTable = "oss_file", dicCode = "id", dicText = "file_name")
private String meetingFileId; private String meetingFileId;
@Excel(name = "备注", width = 20) @Excel(name = "备注", width = 20)