| | |
| | | package com.yuanchu.mom.service.impl; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.aspose.words.*; |
| | | import com.aspose.words.Document; |
| | | 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.Pictures; |
| | | import com.deepoove.poi.config.Configure; |
| | | import com.deepoove.poi.config.ConfigureBuilder; |
| | | import com.deepoove.poi.data.*; |
| | | import com.deepoove.poi.data.style.*; |
| | | import com.deepoove.poi.data.style.Style; |
| | | import com.deepoove.poi.data.style.TableStyle; |
| | | import com.deepoove.poi.util.TableTools; |
| | | import com.itextpdf.text.BadElementException; |
| | | import com.itextpdf.text.DocumentException; |
| | | import com.itextpdf.text.pdf.PdfContentByte; |
| | |
| | | import com.itextpdf.text.pdf.PdfStamper; |
| | | import com.yuanchu.mom.common.GetLook; |
| | | import com.yuanchu.mom.common.PrintChina; |
| | | import com.yuanchu.mom.dto.ReportPageDto; |
| | | import com.yuanchu.mom.dto.*; |
| | | import com.yuanchu.mom.exception.ErrorException; |
| | | import com.yuanchu.mom.mapper.InsOrderMapper; |
| | | import com.yuanchu.mom.mapper.InsReportMapper; |
| | | import com.yuanchu.mom.mapper.UserMapper; |
| | | import com.yuanchu.mom.pojo.InsOrder; |
| | | import com.yuanchu.mom.pojo.InsReport; |
| | | import com.yuanchu.mom.mapper.*; |
| | | import com.yuanchu.mom.pojo.*; |
| | | import com.yuanchu.mom.service.InsReportService; |
| | | import com.yuanchu.mom.service.StandardTemplateService; |
| | | import com.yuanchu.mom.utils.JackSonUtil; |
| | | import com.yuanchu.mom.utils.MatrixToImageWriter; |
| | | import com.yuanchu.mom.utils.QueryWrappers; |
| | | import com.yuanchu.mom.utils.WordUtils; |
| | | import com.yuanchu.mom.vo.Result; |
| | | import org.apache.commons.io.IOUtils; |
| | | import org.apache.logging.log4j.util.Strings; |
| | | import org.apache.poi.xwpf.usermodel.*; |
| | | import org.apache.poi.xwpf.usermodel.ParagraphAlignment; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.core.io.ClassPathResource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.*; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.*; |
| | | 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.util.HashMap; |
| | | import java.util.Map; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.List; |
| | | import java.util.concurrent.CompletableFuture; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import java.util.concurrent.atomic.AtomicReference; |
| | | import java.util.stream.Collectors; |
| | | import java.util.zip.ZipEntry; |
| | | import java.util.zip.ZipFile; |
| | | import java.util.zip.ZipOutputStream; |
| | | |
| | | /** |
| | | * @author Administrator |
| | |
| | | @Resource |
| | | private InsReportMapper insReportMapper; |
| | | |
| | | @Autowired |
| | | ProcessReportMapper1 processReportMapper; |
| | | |
| | | @Value("${wordUrl}") |
| | | private String wordUrl; |
| | | |
| | | @Value("${file.path}") |
| | | private String imgUrl; |
| | | |
| | | @Value("${twoCode}") |
| | | private String twoCode; |
| | | |
| | | @Resource |
| | | private InsOrderMapper insOrderMapper; |
| | | |
| | | @Resource |
| | | private InsOrderStateMapper insOrderStateMapper; |
| | | |
| | | @Resource |
| | | WordUtils wordUtils; |
| | | |
| | | @Resource |
| | | private InsProductMapper insProductMapper; |
| | | |
| | | @Resource |
| | | private InsProductResultMapper insProductResultMapper; |
| | | |
| | | @Resource |
| | | private InsProductResult2Mapper insProductResult2Mapper; |
| | | |
| | | @Resource |
| | | private InsOrderUserMapper insOrderUserMapper; |
| | | |
| | | @Resource |
| | | private InsSampleMapper insSampleMapper; |
| | | |
| | | @Resource |
| | | private InsSampleUserMapper insSampleUserMapper; |
| | | |
| | | @Resource |
| | | private CustomMapper customMapper; |
| | | |
| | | @Resource |
| | | private InsOrderFileMapper insOrderFileMapper; |
| | | |
| | | @Resource |
| | | private StandardTemplateService standardTemplateService; |
| | | |
| | | @Override |
| | | public Map<String, Object> pageInsReport(Page page, ReportPageDto reportPageDto) { |
| | |
| | | //批准 |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int ratifyReport(Integer id, Integer isRatify, String ratifyTell) { |
| | | public int ratifyReport(Integer id, Integer isRatify, String ratifyTell, String sealUrl) { |
| | | InsReport insReport = insReportMapper.selectById(id); |
| | | insReport.setIsRatify(isRatify); |
| | | if (ObjectUtils.isNotEmpty(ratifyTell)) { |
| | |
| | | } 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(); |
| | | //手动上传报告地址 |
| | |
| | | put("seal1", Pictures.ofLocal(imgUrl + "/" + sealUrl).create()); |
| | | put("seal2", Pictures.ofLocal(imgUrl + "/" + sealUrl).create()); |
| | | }}, finalUrl); |
| | | wordToPdf(finalUrl,sealUrl); |
| | | |
| | | /* String replace = finalUrl.replace(".docx", ".pdf"); |
| | | CompletableFuture.supplyAsync(() -> { |
| | | try { |
| | | stamperCheckMarkPDF(replace,replace,sealUrl); |
| | | return null; |
| | | } catch (Exception e) { |
| | | throw new ErrorException("骑缝章插入失败"); |
| | | } |
| | | }).thenAccept(res -> { |
| | | }).exceptionally(e -> { |
| | | e.printStackTrace(); |
| | | return null; |
| | | });*/ |
| | | |
| | | InsOrder insOrder = new InsOrder(); |
| | | insOrder.setId(insReportMapper.selectById(id).getInsOrderId()); |
| | | insOrder.setState(4); |
| | | insOrderMapper.updateById(insOrder); |
| | | wordToPdf(finalUrl, sealUrl); |
| | | /*新增cnas7.8报告结果*/ |
| | | ProcessReport processReport = new ProcessReport(); |
| | | processReport.setInsReportCode(insReport.getCode()); |
| | | processReportMapper.insert(processReport); |
| | | return insReportMapper.updateById(insReport); |
| | | } |
| | | |
| | |
| | | return 1; |
| | | } |
| | | |
| | | |
| | | //报告批量下载 |
| | | @Override |
| | | public void wordToPdf(String path,String sealUrl) { |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public String downAll(String ids) { |
| | | List<Long> list = Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList()); |
| | | List<InsReport> 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)); |
| | | File destinationFile = new File(tempFolder, sourceFile.getName()); |
| | | 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) throws IOException { |
| | | 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 |
| | | InsReport insReport = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery().like(InsReport::getCode, f.getName().replace(".docx", ""))); |
| | | if (ObjectUtils.isEmpty(insReport)) { |
| | | throw new ErrorException("没有找到 " + f.getName() + " 这个文件对应的报告数据"); |
| | | } |
| | | 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")) + "_" + f.getName(); |
| | | 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; |
| | | } |
| | | |
| | | //是否需要生成报告: 0不需要;1需要 |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int isReport(InsReportDto insReportDto) { |
| | | //先判断该订单是否可以去生产报告(是否结束试验) |
| | | Long count = insOrderStateMapper.selectCount(Wrappers.<InsOrderState>lambdaQuery() |
| | | .eq(InsOrderState::getInsOrderId, insReportDto.getId()).eq(InsOrderState::getInsState, 5)); |
| | | if (count > 0) { |
| | | if (insReportDto.getState() == 1) { |
| | | List<InsReportDto1> insReportDto1s = insReportDto.getInsReportDto1s(); |
| | | for (InsReportDto1 insReportDto1 : insReportDto1s) { |
| | | if (ObjectUtils.isNotEmpty(insReportDto1.getInsReportDto2s())){ |
| | | wordUtils.generateReport(insReportDto.getId(), insReportDto1); |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | throw new ErrorException("该订单还未结束试验,无法生成报告!"); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | //查出该订单下每个站点下的检验次数 |
| | | @Override |
| | | public List<InsOrderStateDto> getInsOrderStateCount(Integer id) { |
| | | List<InsOrderStateDto> insOrderStateDtos = new ArrayList<>(); |
| | | List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, id)); |
| | | for (InsSample insSample : insSamples) { |
| | | InsOrderStateDto insOrderStateDto = new InsOrderStateDto(); |
| | | insOrderStateDto.setInsSample(insSample); |
| | | List<InsOrderState> insOrderStates = insOrderStateMapper.getInsOrderStateCount(id, insSample.getId()); |
| | | insOrderStateDto.setInsOrderStates(insOrderStates); |
| | | insOrderStateDtos.add(insOrderStateDto); |
| | | } |
| | | return insOrderStateDtos; |
| | | } |
| | | |
| | | |
| | | //解压文件夹 |
| | | private void unzip(File zipFile, File destDir) throws IOException { |
| | | try (ZipFile zip = new ZipFile(zipFile)) { |
| | | Enumeration<? extends ZipEntry> 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()); |
| | | } |
| | | |
| | | @Override |
| | | public void wordToPdf(String path, String sealUrl) { |
| | | CompletableFuture.supplyAsync(() -> { |
| | | try { |
| | | wordToPdf(path, path.replace(".docx", ".pdf"),sealUrl); |
| | | wordToPdf(path, path.replace(".docx", ".pdf"), sealUrl); |
| | | return null; |
| | | } catch (Exception e) { |
| | | throw new ErrorException("转换失败"); |
| | |
| | | }); |
| | | } |
| | | |
| | | public String wordToPdf(String wordPath, String pdfPath,String sealUrl) { |
| | | 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); |
| | |
| | | return null; |
| | | } |
| | | //生成一个空的PDF文件 |
| | | File file = new File(pdfPath.replace(".pdf","-1.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); |
| | | |
| | | stamperCheckMarkPDF(pdfPath.replace(".pdf", "-1.pdf"), pdfPath, imgUrl + "/" + sealUrl); |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | |
| | | |
| | | /** |
| | | * 切割图片 |
| | | * @param Path 图片路径 |
| | | * @param n 切割份数 |
| | | * |
| | | * @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]; |
| | | 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++){ |
| | | 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块均匀切 |
| | | 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); |
| | | ImageIO.write(subImg, Path.substring(Path.lastIndexOf('.') + 1), out); |
| | | nImage[i] = com.itextpdf.text.Image.getInstance(out.toByteArray()); |
| | | |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * 盖骑缝章 |
| | | * 盖骑缝章 |
| | | * |
| | | * @param infilePath 原PDF路径 |
| | | * @param outFilePath 输出PDF路径 |
| | | * @param infilePath 原PDF路径 |
| | | * @param outFilePath 输出PDF路径 |
| | | */ |
| | | public static void stamperCheckMarkPDF(String infilePath,String outFilePath,String picPath) throws IOException, DocumentException { |
| | | 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(); |
| | | float width = pageSize.getWidth(); |
| | | |
| | | int nums = reader.getNumberOfPages(); |
| | | com.itextpdf.text.Image[] nImage = slicingImages(picPath,nums);//生成骑缝章切割图片 |
| | | com.itextpdf.text.Image[] nImage = slicingImages(picPath, nums);//生成骑缝章切割图片 |
| | | |
| | | for(int n=1;n<=nums;n++){ |
| | | for (int n = 1; n <= nums; n++) { |
| | | PdfContentByte over = stamp.getOverContent(n);//设置在第几页打印印章 |
| | | com.itextpdf.text.Image img = nImage[n-1];//选择图片 |
| | | 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);//控制图片位置 |
| | | float newWidth = img.getWidth() / (img.getHeight() / 100); |
| | | img.scaleAbsolute(newWidth, newHeight);//控制图片大小 |
| | | img.setAbsolutePosition(width - newWidth, height / 2 - newHeight / 2);//控制图片位置 |
| | | over.addImage(img); |
| | | } |
| | | stamp.close(); |