package com.ruoyi.requier.service.impl; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; import com.aspose.words.Document; import com.aspose.words.License; import com.aspose.words.SaveFormat; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.FilePictureRenderData; import com.itextpdf.text.BadElementException; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.ruoyi.common.core.domain.entity.User; import com.ruoyi.common.utils.QueryWrappers; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.exception.ErrorException; import com.ruoyi.inspect.dto.ReportPageDto; import com.ruoyi.inspect.mapper.InsOrderMapper; import com.ruoyi.inspect.mapper.InsOrderStateMapper; import com.ruoyi.inspect.mapper.InsReportApproveConfigMapper; import com.ruoyi.inspect.mapper.InsReportMapper; import com.ruoyi.inspect.pojo.InsOrder; import com.ruoyi.inspect.pojo.InsOrderState; import com.ruoyi.inspect.pojo.InsReport; import com.ruoyi.process.mapper.ProcessReportMapper; import com.ruoyi.process.pojo.ProcessReport; import com.ruoyi.requier.service.InsReportService; import com.ruoyi.system.mapper.UserMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.util.Strings; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.*; import java.math.BigDecimal; import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; /** * @author Administrator * @description 针对表【ins_report(检验报告)】的数据库操作Service实现 * @createDate 2024-03-17 22:10:02 */ @Service @Slf4j public class InsReportServiceImpl extends ServiceImpl implements InsReportService { @Resource private UserMapper userMapper; @Resource private InsReportMapper insReportMapper; @Resource ProcessReportMapper processReportMapper; @Value("${wordUrl}") private String wordUrl; @Value("${file.licenseUrl}") private String licenseUrl; @Value("${file.path}") private String imgUrl; @Resource private InsOrderMapper insOrderMapper; @Resource private RedisTemplate redisTemplate; @Resource private ThreadPoolTaskExecutor threadPoolTaskExecutor; @Resource private InsOrderStateMapper insOrderStateMapper; private static final String SYNC_REPORT_KEY_PREFIX = "syncApprovalReport_lock_"; @Resource private InsReportApproveConfigMapper insReportApproveConfigMapper; @Override public IPage pageInsReport(Page page, ReportPageDto reportPageDto) { Map map = new HashMap<>(); User user = userMapper.selectById(SecurityUtils.getUserId());//当前登录的人 //获取当前人所属实验室id String departLimsId = user.getDepartLimsId(); String laboratory = null; if (ObjectUtils.isNotEmpty(departLimsId) && !departLimsId.isEmpty()) { String[] split = departLimsId.split(","); //查询对应架构名称(通信实验室,电力实验室,检测办) String departLims = insOrderMapper.seldepLimsId(Integer.parseInt(split[split.length - 1])); if (departLims.contains("实验室")) { laboratory = departLims; } } QueryWrapper wrapper = QueryWrappers.queryWrappers(reportPageDto); if(Objects.nonNull(reportPageDto.getCreateTimeRange())){ wrapper.gt(reportPageDto.getCreateTimeRange().size()>1,"create_time",reportPageDto.getCreateTimeRange().get(0)) .lt(reportPageDto.getCreateTimeRange().size()>1,"create_time",reportPageDto.getCreateTimeRange().get(1)); } return insReportMapper.pageInsReport(page, wrapper ,laboratory); } @Override public int inReport(String url, Integer id) { InsReport insReport = new InsReport(); insReport.setId(id); insReport.setUrlS(url); return insReportMapper.updateById(insReport); } // 还原 @Override public int upReportUrl(Integer id) { InsReport insReport = insReportMapper.selectById(id); String fileName = insReport.getUrlS().replace("/word/", ""); if(Strings.isNotEmpty(fileName)) { String path = wordUrl + File.separator + fileName; File file = new File(path); if (file.exists()) { file.delete(); } } return insReportMapper.update(null, Wrappers.lambdaUpdate().eq(InsReport::getId, id).set(InsReport::getUrlS, null)); } @Override public void downReport(Integer id,Integer type, HttpServletResponse response) { InsReport insReport = insReportMapper.selectById(id); String url = ""; // 0 下载docx 1 下载pdf if(type == 0) { url = Strings.isNotEmpty(insReport.getUrlS()) ? insReport.getUrlS() : insReport.getUrl(); }else { url = insReport.getTempUrlPdf(); } if(Strings.isEmpty(url)){ throw new ErrorException("报告地址为空"); } File file = new File(wordUrl + File.separator + url.replace("/word/", "")); try { String fileName = file.getName(); if(fileName.indexOf("_") != -1) { fileName = fileName.split("_")[1]; } fileName = URLEncoder.encode(fileName, "UTF-8"); response.setContentType("application/octet-stream"); response.setHeader("Content-disposition","attachment;filename=" + fileName); ServletOutputStream stream = response.getOutputStream(); FileInputStream fileInputStream = new FileInputStream(file); byte[] bytes = new byte[1024]; int byteRead; while((byteRead = fileInputStream.read(bytes)) != -1){ stream.write(bytes, 0, byteRead); stream.flush(); } fileInputStream.close(); stream.close(); }catch (Exception e){ throw new ErrorException("下载失败"); } } //提交 @Override public int writeReport(Integer id) { InsReport insReport = insReportMapper.selectById(id); insReport.setId(id); insReport.setState(1); insReport.setWriteTime(LocalDateTime.now());//提交时间 insReport.setWriteUserId(SecurityUtils.getUserId().intValue());//提交人 //获取提交人的签名地址 String signatureUrl; try { signatureUrl = userMapper.selectById(SecurityUtils.getUserId().intValue()).getSignatureUrl(); } catch (Exception e) { throw new ErrorException("找不到编制人的签名"); } //系统生成报告地址 String url = insReport.getUrl(); //手动上传报告地址 String urlS = insReport.getUrlS(); wordInsertUrl(new HashMap() {{ put("writeUrl", new FilePictureRenderData(100,50,imgUrl + "/" + signatureUrl)); }}, (urlS == null ? url : urlS).replace("/word", wordUrl)); // 修改临时pdf String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl)); insReport.setTempUrlPdf("/word/" + tempUrlPdf); return insReportMapper.updateById(insReport); } //审核 @Override public int examineReport(Integer id, Integer isExamine, String examineTell) { InsReport insReport = insReportMapper.selectById(id); insReport.setIsExamine(isExamine); if (ObjectUtils.isNotEmpty(examineTell)) { insReport.setExamineTell(examineTell); } insReport.setExamineUserId(SecurityUtils.getUserId().intValue());//审核人 insReport.setExamineTime(LocalDateTime.now());//审核时间 if (isExamine == 0) { //如果审核不通过 insReport.setState(0);//提交状态改为待提交 return insReportMapper.updateById(insReport); } //获取审核人的签名地址 String signatureUrl; try { signatureUrl = userMapper.selectById(insReport.getExamineUserId()).getSignatureUrl(); } catch (Exception e) { throw new ErrorException("找不到审核人的签名"); } //系统生成报告地址 String url = insReport.getUrl(); //手动上传报告地址 String urlS = insReport.getUrlS(); wordInsertUrl(new HashMap() {{ put("examineUrl", new FilePictureRenderData(100,50,imgUrl + "/" + signatureUrl)); }}, (urlS == null ? url : urlS).replace("/word", wordUrl)); // 修改临时pdf String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl)); insReport.setTempUrlPdf("/word/" + tempUrlPdf); return insReportMapper.updateById(insReport); } //批准 @Override @Transactional(rollbackFor = Exception.class) public int ratifyReport(Integer id, Integer isRatify, String ratifyTell) { InsReport insReport = insReportMapper.selectById(id); insReport.setIsRatify(isRatify); if (ObjectUtils.isNotEmpty(ratifyTell)) { insReport.setRatifyTell(ratifyTell); } insReport.setRatifyUserId(SecurityUtils.getUserId().intValue());//批准人 insReport.setRatifyTime(LocalDateTime.now());//批准时间 if (isRatify == 0) { //如果批准不通过 insReport.setState(0);//提交状态改为待提交 return insReportMapper.updateById(insReport); } //获取批准人的签名地址 String signatureUrl; try { signatureUrl = userMapper.selectById(insReport.getRatifyUserId()).getSignatureUrl(); } catch (Exception e) { throw new ErrorException("找不到批准人的签名"); } //获取场所的报告专用章 String sealUrl; try { String laboratory = insOrderMapper.selectById(insReport.getInsOrderId()).getLaboratory(); sealUrl = insReportMapper.getLaboratoryByName(laboratory); } catch (Exception e) { throw new ErrorException("找不到报告专用章"); } if (sealUrl == null) throw new ErrorException("找不到报告专用章"); //系统生成报告地址 String url = insReport.getUrl(); //手动上传报告地址 String urlS = insReport.getUrlS(); String finalUrl = (urlS == null ? url : urlS).replace("/word", wordUrl); wordInsertUrl(new HashMap() {{ put("ratifyUrl", new FilePictureRenderData(100,50,imgUrl + "/" + signatureUrl)); put("seal1", new FilePictureRenderData(600,600,imgUrl + "/" + sealUrl)); put("seal2", new FilePictureRenderData(600,600,imgUrl + "/" + sealUrl)); }}, finalUrl); wordToPdf(finalUrl, sealUrl); InsOrder insOrder = new InsOrder(); insOrder.setId(insReportMapper.selectById(id).getInsOrderId()); insOrder.setState(4); insOrderMapper.updateById(insOrder); // 修改临时pdf String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl)); insReport.setTempUrlPdf("/word/" + tempUrlPdf); /*新增cnas7.8报告结果*/ ProcessReport processReport = new ProcessReport(); processReport.setInsReportCode(insReport.getCode()); processReportMapper.insert(processReport); return insReportMapper.updateById(insReport); } @Override public int wordInsertUrl(Map map, String url) { XWPFTemplate template = XWPFTemplate.compile(url).render(map); try { template.writeAndClose(Files.newOutputStream(Paths.get(url))); } catch (IOException e) { throw new RuntimeException(e); } return 1; } //报告批量下载 @Override @Transactional(rollbackFor = Exception.class) public String downAll(String ids) { List list = Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList()); List insReports = insReportMapper.selectBatchIds(list); String zipFilePath = null; // 临时文件夹路径 try { String tempFolderPath = wordUrl + "/tempFolder"; File tempFolder = new File(tempFolderPath); if (tempFolder.exists()) { deleteDirectory(tempFolder); // 删除旧的临时文件夹 } tempFolder.mkdirs(); // 创建新的临时文件夹 for (InsReport insReport : insReports) { File sourceFile = new File((ObjectUtils.isNotEmpty(insReport.getUrlS()) ? insReport.getUrlS() : insReport.getUrl()).replace("/word", wordUrl)); // 下载文件名称去除时间 String destinationFileName = sourceFile.getName(); if(destinationFileName.indexOf("_") != -1) { destinationFileName = destinationFileName.split("_")[1]; } File destinationFile = new File(tempFolder, destinationFileName); Files.copy(sourceFile.toPath(), destinationFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } // 压缩临时文件夹 zipFilePath = wordUrl + "/zip/output.zip"; zipDirectory(tempFolderPath, zipFilePath); // 清理临时文件夹 deleteDirectory(tempFolder); System.out.println("ZIP文件创建完成!"); } catch (IOException e) { e.printStackTrace(); } return "/word/zip/output.zip"; } //批量上传 @Override @Transactional(rollbackFor = Exception.class) public int upAll(MultipartFile file) { if (file != null) { // 根据文件名查询id String fileName = file.getOriginalFilename(); String code = fileName.replace(".docx", "").replace("JCZX", "JCZX/"); if(fileName.lastIndexOf("_") != -1) { code = code.substring(file.getOriginalFilename().lastIndexOf("_") + 1); } //查询未审核的报告数据 InsReport insReport = insReportMapper.selectOne(Wrappers.lambdaQuery().eq(InsReport::getCode, code).eq(InsReport::getIsExamine,-9)); if (ObjectUtils.isEmpty(insReport)) { throw new ErrorException("没有编号为" + code + "的报告或该报告已审核通过"); } // 如果UrlS有值 先将该文件删除 if(Strings.isNotEmpty(insReport.getUrlS())) { String url = wordUrl + File.separator + insReport.getUrlS().replace("/word/", ""); File file1 = new File(url); if(file1.exists()) { file1.delete(); } } String urlString; String pathName; String path = wordUrl; File realpath = new File(path); if (!realpath.exists()) { realpath.mkdirs(); } pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + insReport.getCode().replace("/", "") + ".docx"; urlString = realpath + "/" + pathName; // 复制文件到指定路径 try { Files.copy(file.getInputStream(), new File(urlString).toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); } inReport("/word/" + pathName, insReport.getId()); } // File tempFile = null; // File unzipDir = null; // try { // tempFile = File.createTempFile(wordUrl, ".zip"); // file.transferTo(tempFile); // // unzipDir = new File("uploaded_files"); // if (!unzipDir.exists()) { // unzipDir.mkdir(); // } // unzip(tempFile, unzipDir); // // 处理解压后的文件 // File[] files = unzipDir.listFiles(); // if (files != null) { // for (File f : files) { // // 根据文件名查询id // String name = f.getName(); // String code = f.getName().replace(".docx", "").replace("JCZX", "JCZX/"); // if(f.getName().lastIndexOf("_") != -1) { // code = code.substring(f.getName().lastIndexOf("_") + 1); // } // //InsReport insReport = insReportMapper.selectOne(Wrappers.lambdaQuery().eq(InsReport::getCode, f.getName().replace(".docx", "").replace("JCZX", "JCZX/"))); // InsReport insReport = insReportMapper.selectOne(Wrappers.lambdaQuery().eq(InsReport::getCode, code)); // if (ObjectUtils.isEmpty(insReport)) { // throw new ErrorException("没有找到 " + f.getName() + " 这个文件对应的报告数据"); // } // // 如果UrlS有值 先将该文件删除 // if(Strings.isNotEmpty(insReport.getUrlS())) { // String url = wordUrl + File.separator + insReport.getUrlS().replace("/word/", ""); // File file1 = new File(url); // if(file1.exists()) { // file1.delete(); // } // } // String urlString; // String pathName; // try { // String path = wordUrl; // File realpath = new File(path); // if (!realpath.exists()) { // realpath.mkdirs(); // } // pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + insReport.getCode().replace("/", "") + ".docx"; // urlString = realpath + "/" + pathName; // // 复制文件到指定路径 // Files.copy(f.toPath(), new File(urlString).toPath(), StandardCopyOption.REPLACE_EXISTING); // inReport("/word/" + pathName, insReport.getId()); // } // catch (IOException e) { // throw new ErrorException("文件上传失败"); // } // } // } // } catch (IOException e) { // throw new ErrorException("文件处理失败"); // } finally { // if (tempFile != null && tempFile.exists()) { // tempFile.delete(); // } // // 递归删除解压目录及其中的文件 // if (unzipDir.exists()) { // deleteDirectory(unzipDir); // 删除旧的临时文件夹 // } // } return 0; } @Override @Transactional(rollbackFor = Exception.class) public void withdraw(Map map) { Integer id = Integer.parseInt(map.get("id").toString()); List list = JSONArray.parseArray(map.get("laboratory").toString(), String.class); Integer insOrderId = insReportMapper.selectById(id).getInsOrderId(); List insOrderStateS = insOrderStateMapper.selectList(new LambdaQueryWrapper() .eq(InsOrderState::getInsOrderId, insOrderId) .in(CollectionUtils.isNotEmpty(list),InsOrderState::getLaboratory, list)); if(CollectionUtils.isNotEmpty(insOrderStateS)) { List collect = insOrderStateS.stream().map(InsOrderState::getId).collect(Collectors.toList()); // 修改该单子试验室的状态为待复核,删除报告信息 insOrderStateMapper.update(null,new LambdaUpdateWrapper() .set(InsOrderState::getInsState,3) // 待复核 .in(InsOrderState::getId,collect)); insReportMapper.delete(new LambdaQueryWrapper().eq(InsReport::getId,id)); } } @Override public List> getLaboratoryByReportId(Integer id) { List> list = new ArrayList<>(); Integer insOrderId = insReportMapper.selectById(id).getInsOrderId(); insOrderStateMapper.selectList(new LambdaQueryWrapper() .eq(InsOrderState::getInsOrderId,insOrderId)) .forEach(insOrderState -> { Map map = new HashMap<>(); map.put("label",insOrderState.getLaboratory()); map.put("value",insOrderState.getLaboratory()); list.add(map); }); return list; } @Override public Map getReportCountInfo(ReportPageDto reportPageDto) { HashMap map = new HashMap<>(); User user = userMapper.selectById(SecurityUtils.getUserId());//当前登录的人 //获取当前人所属实验室id String departLimsId = user.getDepartLimsId(); String laboratory = null; if (ObjectUtils.isNotEmpty(departLimsId) && !departLimsId.isEmpty()) { String[] split = departLimsId.split(","); //查询对应架构名称(通信实验室,电力实验室,检测办) String departLims = insOrderMapper.seldepLimsId(Integer.parseInt(split[split.length - 1])); if (departLims.contains("实验室")) { laboratory = departLims; } } QueryWrapper wrapper = QueryWrappers.queryWrappers(reportPageDto); if(Objects.nonNull(reportPageDto.getCreateTimeRange())){ wrapper.gt(reportPageDto.getCreateTimeRange().size()>1,"create_time",reportPageDto.getCreateTimeRange().get(0)) .lt(reportPageDto.getCreateTimeRange().size()>1,"create_time",reportPageDto.getCreateTimeRange().get(1)); } map.put("unSubmitCount",insReportMapper.findReportCountInfo(wrapper,laboratory,"ir.write_user_id").size()); map.put("unExamineCount",insReportMapper.findReportCountInfo(wrapper,laboratory,"ir.is_examine").size()); map.put("unRatifyCount",insReportMapper.findReportCountInfo(wrapper,laboratory,"ir.is_ratify").size()); return map; } @Override @Transactional(rollbackFor = Exception.class) public void batchApprovalReport(List ids) { redisTemplate.setKeySerializer(new StringRedisSerializer()); Integer userId = SecurityUtils.getUserId().intValue(); String key = SYNC_REPORT_KEY_PREFIX+userId; //执行前删除之前的keys deleteRedisKeys(key); synchronized (key) { redisTemplate.opsForValue().set(key,1); RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(),true); //异步执行审批操作 CompletableFuture.runAsync(() -> { try { runBatchApproval(ids,key); }catch (Exception e){ //删除key deleteRedisKeys(key); redisTemplate.opsForValue().set(key+"_exception",e.getMessage()); } },threadPoolTaskExecutor); } } /** * 删除redis key * @param key */ private void deleteRedisKeys(String key){ redisTemplate.delete(key); redisTemplate.delete(key+"_num"); redisTemplate.delete(key+"_count"); redisTemplate.delete(key+"_surplus"); redisTemplate.delete(key+"_exception"); } /** * 执行审批操作 * @param ids 报告id列表 */ private void runBatchApproval(List ids,String keyPrefix) { if(ids.isEmpty()){ return; } long start = System.currentTimeMillis(); String surplusKey = keyPrefix + "_surplus";//剩余条数 String numKey = keyPrefix + "_num";//总进度 String countKey = keyPrefix + "_count";//总条数 redisTemplate.opsForValue().set(countKey, ids.size()); redisTemplate.opsForValue().set(surplusKey, ids.size()); Object countObj = redisTemplate.opsForValue().get(countKey); long parsed2 = Long.parseLong(String.valueOf(countObj)); AtomicLong count = new AtomicLong(parsed2); for (Integer id : ids) { //业务代码 InsReport insReport = insReportMapper.selectById(id); String laboratory = insOrderMapper.selectById(insReport.getInsOrderId()).getLaboratory(); //获取签名和印章 String sealUrl; String writeUrl; String examineUrl; String ratifyUrl; int writeId; int examineId; int ratifyId; try { sealUrl = insReportMapper.getLaboratoryByName(laboratory);//印章 Map urlMap = insReportApproveConfigMapper.selectApprovalConfigByLaboratory(laboratory);//签名 writeUrl = imgUrl + "/" + (Objects.isNull(urlMap.get("writeUrl"))?"":urlMap.get("writeUrl").toString());//编制人签名url examineUrl = imgUrl + "/" + (Objects.isNull(urlMap.get("examineUrl"))?"":urlMap.get("examineUrl").toString());//审核人签名url ratifyUrl = imgUrl + "/" + (Objects.isNull(urlMap.get("ratifyUrl"))?"":urlMap.get("ratifyUrl").toString());//批准人签名url writeId = Integer.parseInt(urlMap.get("writeId").toString());//编制人 examineId = Integer.parseInt(urlMap.get("examineId").toString());//审核人签 ratifyId =Integer.parseInt(urlMap.get("ratifyId").toString());//批准人 } catch (Exception e) { throw new ErrorException("找不到签名和印章"); } //设置报告信息 insReport.setIsExamine(1); insReport.setIsRatify(1); insReport.setState(1); insReport.setWriteUserId(writeId); insReport.setExamineUserId(examineId); insReport.setRatifyUserId(ratifyId); if(Objects.isNull(insReport.getWriteTime())){ insReport.setWriteTime(LocalDateTime.now()); } if(Objects.isNull(insReport.getExamineTime())){ insReport.setExamineTime(LocalDateTime.now()); } if(Objects.isNull(insReport.getRatifyTime())){ insReport.setRatifyTime(LocalDateTime.now()); } //更新订单状态 InsOrder insOrder = new InsOrder(); insOrder.setId(insReport.getInsOrderId()); insOrder.setState(4); insOrderMapper.updateById(insOrder); //系统生成报告地址 String url = insReport.getUrl(); //手动上传报告地址 String urlS = insReport.getUrlS(); String finalUrl = (StringUtils.isBlank(urlS) ? url : urlS).replace("/word", wordUrl); wordInsertUrl(new HashMap() {{ put("writeUrl", new FilePictureRenderData(100,50,writeUrl)); put("examineUrl", new FilePictureRenderData(100,50,examineUrl)); put("ratifyUrl", new FilePictureRenderData(100,50,ratifyUrl)); put("seal1", new FilePictureRenderData(600,600,imgUrl + "/" +sealUrl)); put("seal2", new FilePictureRenderData(600,600,imgUrl + "/" +sealUrl)); }}, finalUrl); wordToPdf(finalUrl, sealUrl); // 修改临时pdf String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl)); insReport.setTempUrlPdf("/word/" + tempUrlPdf); //更新报告状态 insReportMapper.updateById(insReport); //更新redis的key Object o = redisTemplate.opsForValue().get(numKey); if (Objects.isNull(o)) { redisTemplate.opsForValue().set(numKey, 1); } else { long parsed = Long.parseLong(String.valueOf(o)); redisTemplate.opsForValue().set(numKey, parsed + 1); } redisTemplate.opsForValue().set(surplusKey, count.decrementAndGet()); } long end = System.currentTimeMillis(); long useTime = (end-start)/1000; log.info("线程{}报告审批结束,耗时:{}s",keyPrefix,useTime); } @Override public Map getBatchApprovalProgress() { Integer userId = SecurityUtils.getUserId().intValue(); String key = SYNC_REPORT_KEY_PREFIX + userId; Map map = new HashMap<>(); map.put("hasProgress",false); map.put("hasNum",0); map.put("hasCount",0); map.put("surplus",0); Object o = redisTemplate.opsForValue().get(key); if(Objects.nonNull(o)){ map.put("hasProgress",true); } Object o1 = redisTemplate.opsForValue().get(key+"_num"); Object o2 = redisTemplate.opsForValue().get(key+"_count"); Object surplus = redisTemplate.opsForValue().get(key+"_surplus"); Object exception = redisTemplate.opsForValue().get(key+"_exception"); if(Objects.nonNull(surplus)){ map.put("surplus",surplus); } if (Objects.nonNull(o1)&&Objects.nonNull(o2)){ //得到进度 BigDecimal multiply = new BigDecimal(String.valueOf(o1)).divide(new BigDecimal(String.valueOf(o2)), 2,BigDecimal.ROUND_DOWN).multiply(BigDecimal.valueOf(100)); map.put("hasNum",multiply); map.put("hasCount",Long.parseLong(String.valueOf(o2))); } map.put("hasException",exception); return map; } //解压文件夹 private void unzip(File zipFile, File destDir) throws IOException { try (ZipFile zip = new ZipFile(zipFile)) { Enumeration entries = zip.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); File file = new File(destDir, entry.getName()); if (entry.isDirectory()) { file.mkdirs(); } else { file.getParentFile().mkdirs(); try (InputStream in = zip.getInputStream(entry); OutputStream out = new FileOutputStream(file)) { byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } } } } } } // 压缩文件夹 public static void zipDirectory(String sourceDirPath, String zipFilePath) throws IOException { try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath))) { Path sourceDir = Paths.get(sourceDirPath); Files.walk(sourceDir) .filter(path -> !Files.isDirectory(path)) .forEach(path -> { ZipEntry zipEntry = new ZipEntry(sourceDir.relativize(path).toString()); try { zipOut.putNextEntry(zipEntry); Files.copy(path, zipOut); zipOut.closeEntry(); } catch (IOException e) { e.printStackTrace(); } }); } } // 删除文件夹及其内容 public static void deleteDirectory(File directory) throws IOException { if (directory.isDirectory()) { File[] files = directory.listFiles(); if (files != null) { for (File file : files) { deleteDirectory(file); } } } Files.delete(directory.toPath()); } /** * word转换pdf * @param path * @return */ public String wordToPdfTemp(String path) { try { return wordToPdf(path, path.replace(".docx", ".pdf")); } catch (Exception e) { throw new ErrorException("转换失败"); } } public String wordToPdf(String wordPath, String pdfPath) { FileOutputStream os = null; try { //凭证 不然切换后有水印 InputStream is = Files.newInputStream(new File(licenseUrl).toPath()); License license = new License(); license.setLicense(is); if (!license.getIsLicensed()) { System.out.println("License验证不通过..."); return null; } //生成一个空的PDF文件 File file; //判断是否是进厂报告 file = new File(pdfPath); os = new FileOutputStream(file); //要转换的word文件 Document doc = new Document(wordPath); doc.save(os, SaveFormat.PDF); String name = file.getName(); return file.getName(); } catch (Exception e) { e.printStackTrace(); } finally { if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } // @Override // public void wordToPdf(String path, String sealUrl) { // CompletableFuture.supplyAsync(() -> { // try { // wordToPdf(path, path.replace(".docx", ".pdf"), sealUrl); // return null; // } catch (Exception e) { // throw new ErrorException("转换失败"); // } // }).thenAccept(res -> { // }).exceptionally(e -> { // e.printStackTrace(); // return null; // }); // } // public String wordToPdf(String wordPath, String pdfPath, String sealUrl) { // FileOutputStream os = null; // try { // //凭证 不然切换后有水印 //// InputStream inputStream = this.getClass().getResourceAsStream("/lib/license.xml"); // /*String url; // try { // InputStream inputStream = this.getClass().getResourceAsStream("/lib/license.xml"); // File file = File.createTempFile("temp", ".tmp"); // OutputStream outputStream = new FileOutputStream(file); // IOUtils.copy(inputStream, outputStream); // url = file.getAbsolutePath(); // } catch (FileNotFoundException e) { // throw new ErrorException("找不到模板文件"); // } catch (IOException e) { // throw new RuntimeException(e); // }*/ // InputStream is = new ClassPathResource("/lib/license.xml").getInputStream(); // License license = new License(); // license.setLicense(is); // if (!license.getIsLicensed()) { // System.out.println("License验证不通过..."); // return null; // } // //生成一个空的PDF文件 // File file = new File(pdfPath.replace(".pdf", "-1.pdf")); // os = new FileOutputStream(file); // //要转换的word文件 // com.aspose.words.Document doc = new com.aspose.words.Document(wordPath); // doc.save(os, SaveFormat.PDF); // // //添加骑缝章 // stamperCheckMarkPDF(pdfPath.replace(".pdf", "-1.pdf"), pdfPath, imgUrl + "/" + sealUrl); // // // } catch (Exception e) { // e.printStackTrace(); // } finally { // if (os != null) { // try { // os.close(); // } catch (IOException e) { // e.printStackTrace(); // } // } // } // return null; // } /** * 切割图片 * * @param Path 图片路径 * @param n 切割份数 */ public static com.itextpdf.text.Image[] slicingImages(String Path, int n) throws IOException, BadElementException { com.itextpdf.text.Image[] nImage = new com.itextpdf.text.Image[n]; BufferedImage img = ImageIO.read(new File(Path)); int h = img.getHeight(); int w = img.getWidth(); int sw = w / n; for (int i = 0; i < n; i++) { BufferedImage subImg; if (i == n - 1) {//最后剩余部分 subImg = img.getSubimage(i * sw, 0, w - i * sw, h); } else {//前n-1块均匀切 subImg = img.getSubimage(i * sw, 0, sw, h); } ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageIO.write(subImg, Path.substring(Path.lastIndexOf('.') + 1), out); nImage[i] = com.itextpdf.text.Image.getInstance(out.toByteArray()); } return nImage; } /** * 盖骑缝章 * * @param infilePath 原PDF路径 * @param outFilePath 输出PDF路径 */ public static void stamperCheckMarkPDF(String infilePath, String outFilePath, String picPath) throws IOException, DocumentException { PdfReader reader = new PdfReader(infilePath);//选择需要印章的pdf PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(outFilePath));//加完印章后的pdf com.itextpdf.text.Rectangle pageSize = reader.getPageSize(1);//获得第一页 float height = pageSize.getHeight(); float width = pageSize.getWidth(); int nums = reader.getNumberOfPages(); com.itextpdf.text.Image[] nImage = slicingImages(picPath, nums);//生成骑缝章切割图片 for (int n = 1; n <= nums; n++) { PdfContentByte over = stamp.getOverContent(n);//设置在第几页打印印章 com.itextpdf.text.Image img = nImage[n - 1];//选择图片 float newHeight = 100f; float newWidth = img.getWidth() / (img.getHeight() / 100); img.scaleAbsolute(newWidth, newHeight);//控制图片大小 img.setAbsolutePosition(width - newWidth, height / 2 - newHeight / 2);//控制图片位置 over.addImage(img); } stamp.close(); } }