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.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.util.TableTools;
|
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.yuanchu.mom.common.GetLook;
|
import com.yuanchu.mom.common.PrintChina;
|
import com.yuanchu.mom.dto.InsReportDto;
|
import com.yuanchu.mom.dto.InsReportDto1;
|
import com.yuanchu.mom.dto.ReportPageDto;
|
import com.yuanchu.mom.dto.SampleProductDto;
|
import com.yuanchu.mom.exception.ErrorException;
|
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.vo.Result;
|
import org.apache.commons.io.IOUtils;
|
import org.apache.poi.xwpf.usermodel.*;
|
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.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.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
|
* @description 针对表【ins_report(检验报告)】的数据库操作Service实现
|
* @createDate 2024-03-17 22:10:02
|
*/
|
@Service
|
public class InsReportServiceImpl extends ServiceImpl<InsReportMapper, InsReport>
|
implements InsReportService {
|
|
@Resource
|
private GetLook getLook;
|
|
@Resource
|
private UserMapper userMapper;
|
|
@Resource
|
private InsReportMapper insReportMapper;
|
|
@Value("${wordUrl}")
|
private String wordUrl;
|
|
@Value("${file.path}")
|
private String imgUrl;
|
|
@Value("${twoCode}")
|
private String twoCode;
|
|
@Resource
|
private InsOrderMapper insOrderMapper;
|
|
@Resource
|
private StandardMethodListMapper standardMethodListMapper;
|
|
@Resource
|
private InsOrderStateMapper insOrderStateMapper;
|
|
@Resource
|
private InsProductMapper insProductMapper;
|
|
@Resource
|
private InsProductResultMapper insProductResultMapper;
|
|
@Resource
|
private InsProductResult2Mapper insProductResult2Mapper;
|
|
@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) {
|
Map<String, Object> map = new HashMap<>();
|
map.put("head", PrintChina.printChina(ReportPageDto.class));
|
Map<String, Integer> map1 = getLook.selectPowerByMethodAndUserId("pageInsReport");
|
if (map1.get("look") == 1) reportPageDto.setCreateUser(map1.get("userId"));
|
User user = userMapper.selectById(map1.get("userId"));//当前登录的人
|
//获取当前人所属实验室id
|
String departLimsId = user.getDepartLimsId();
|
String laboratory = null;
|
if (ObjectUtils.isNotEmpty(departLimsId) && !departLimsId.equals("")) {
|
String[] split = departLimsId.split(",");
|
//查询对应架构名称(通信实验室,电力实验室,检测办)
|
String departLims = insOrderMapper.seldepLimsId(Integer.parseInt(split[split.length - 1]));
|
if (departLims.contains("实验室")) {
|
laboratory = departLims;
|
}
|
}
|
map.put("body", insReportMapper.pageInsReport(page, QueryWrappers.queryWrappers(reportPageDto), laboratory));
|
return map;
|
}
|
|
@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) {
|
return insReportMapper.update(null, Wrappers.<InsReport>lambdaUpdate().eq(InsReport::getId, id).set(InsReport::getUrlS, null));
|
}
|
|
//提交
|
@Override
|
public int writeReport(Integer id) {
|
InsReport insReport = insReportMapper.selectById(id);
|
insReport.setId(id);
|
insReport.setState(1);
|
insReport.setWriteUserId(getLook.selectPowerByMethodAndUserId(null).get("userId"));//提交人
|
insReport.setWriteTime(LocalDateTime.now());//提交时间
|
//获取提交人的签名地址
|
String signatureUrl;
|
try {
|
signatureUrl = userMapper.selectById(insReport.getWriteUserId()).getSignatureUrl();
|
} catch (Exception e) {
|
throw new ErrorException("找不到编制人的签名");
|
}
|
//系统生成报告地址
|
String url = insReport.getUrl();
|
//手动上传报告地址
|
String urlS = insReport.getUrlS();
|
wordInsertUrl(new HashMap<String, Object>() {{
|
put("writeUrl", Pictures.ofLocal(imgUrl + "/" + signatureUrl).create());
|
}}, (urlS == null ? url : urlS).replace("/word", wordUrl));
|
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(getLook.selectPowerByMethodAndUserId(null).get("userId"));//审核人
|
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<String, Object>() {{
|
put("examineUrl", Pictures.ofLocal(imgUrl + "/" + signatureUrl).create());
|
}}, (urlS == null ? url : urlS).replace("/word", wordUrl));
|
return insReportMapper.updateById(insReport);
|
}
|
|
//批准
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int ratifyReport(Integer id, Integer isRatify, String ratifyTell, String sealUrl) {
|
InsReport insReport = insReportMapper.selectById(id);
|
insReport.setIsRatify(isRatify);
|
if (ObjectUtils.isNotEmpty(ratifyTell)) {
|
insReport.setRatifyTell(ratifyTell);
|
}
|
insReport.setRatifyUserId(getLook.selectPowerByMethodAndUserId(null).get("userId"));//批准人
|
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<String, Object>() {{
|
put("ratifyUrl", Pictures.ofLocal(imgUrl + "/" + signatureUrl).create());
|
put("seal1", Pictures.ofLocal(imgUrl + "/" + sealUrl).create());
|
put("seal2", Pictures.ofLocal(imgUrl + "/" + sealUrl).create());
|
}}, finalUrl);
|
wordToPdf(finalUrl, sealUrl);
|
|
InsOrder insOrder = new InsOrder();
|
insOrder.setId(insReportMapper.selectById(id).getInsOrderId());
|
insOrder.setState(4);
|
insOrderMapper.updateById(insOrder);
|
return insReportMapper.updateById(insReport);
|
}
|
|
@Override
|
public int wordInsertUrl(Map<String, Object> 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<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
|
String name = f.getName();
|
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) {
|
generateReport(insReportDto.getId(), insReportDto.getInsReportDto1s());
|
} else {
|
//结束订单
|
InsOrder insOrder = new InsOrder();
|
insOrder.setId(insReportDto.getId());
|
insOrder.setState(4);
|
insOrderMapper.updateById(insOrder);
|
}
|
} else {
|
throw new ErrorException("该订单还未结束试验,无法生产报告!");
|
}
|
return 0;
|
}
|
|
//查出该订单下每个站点下的检验次数
|
@Override
|
public List<InsOrderState> getInsOrderStateCount(Integer id) {
|
List<InsOrderState> insOrderStates = insOrderStateMapper.getInsOrderStateCount(id);
|
return insOrderStates;
|
}
|
|
|
//解压文件夹
|
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);
|
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);
|
TableCollection tables = doc.getFirstSection().getBody().getTables();
|
for (Table table : tables) {
|
RowCollection rows = table.getRows();
|
table.setAllowAutoFit(false);
|
for (Row row : rows) {
|
CellCollection cells = row.getCells();
|
for (Cell cell : cells) {
|
CellFormat cellFormat = cell.getCellFormat();
|
cellFormat.setFitText(false); //设置自适应关闭
|
cellFormat.setWrapText(true); // 设置自动换行
|
}
|
}
|
}
|
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();
|
}
|
|
//生成报告
|
private void generateReport(Integer orderId, List<InsReportDto1> insReportDto1s) {
|
LocalDateTime now = LocalDateTime.now();
|
InsOrder insOrder = insOrderMapper.selectById(orderId);
|
//委托部门 departLims
|
String departLims = userMapper.selectDepartLims(insOrder.getPrepareUser());
|
//samples是过滤掉没有检验项目的样品
|
List<SampleProductDto> samples = insSampleMapper.selectSampleProductListByOrderId(orderId);
|
String sampleCode = samples.get(0).getSampleCode();
|
InsReport insReport = new InsReport();
|
insReport.setCode(insOrder.getEntrustCode().replace("WT","TXJC"));
|
insReport.setInsOrderId(orderId);
|
List<Map<String, Object>> tables = new ArrayList<>();
|
Set<String> standardMethod = new HashSet<>();
|
Set<String> deviceSet = new HashSet<>();
|
Set<String> models = new HashSet<>();
|
AtomicReference<Integer> productSize = new AtomicReference<>(0);
|
AtomicReference<Integer> productSize1 = new AtomicReference<>(0);
|
AtomicReference<Integer> productSize2 = new AtomicReference<>(0);
|
AtomicReference<Integer> productSize3 = new AtomicReference<>(0);
|
String[] monthNames = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
|
samples.forEach(s -> {
|
models.add(s.getModel());
|
standardMethod.addAll(standardMethodListMapper.selectList(Wrappers.<StandardMethodList>lambdaQuery()
|
.in(StandardMethodList::getId,Arrays.stream(s.getStandardMethodListId().replaceAll("[\\[\\]]", "").split(","))
|
.map(String::trim).map(Integer::parseInt).collect(Collectors.toList()))).stream().map(aa->{return aa.getCode()+" "+aa.getName();}).distinct().collect(Collectors.toList()));
|
//总数
|
Long productCount = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery()
|
.eq(InsProduct::getInsSampleId, s.getId()));
|
productSize.set(productSize.get() + Integer.parseInt(productCount + ""));
|
//不判定
|
Long productCount1 = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery()
|
.eq(InsProduct::getInsSampleId, s.getId())
|
.eq(InsProduct::getInsResult, 3));
|
productSize1.set(productSize1.get() + Integer.parseInt(productCount1 + ""));
|
//不合格
|
Long productCount2 = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery()
|
.eq(InsProduct::getInsSampleId, s.getId())
|
.eq(InsProduct::getInsResult, 0));
|
productSize2.set(productSize2.get() + Integer.parseInt(productCount2 + ""));
|
//合格
|
Long productCount3 = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery()
|
.eq(InsProduct::getInsSampleId, s.getId())
|
.eq(InsProduct::getInsResult, 1));
|
productSize3.set(productSize3.get() + Integer.parseInt(productCount3 + ""));
|
//将项目按照站点进行分类
|
Map<String, List<InsProduct>> listMap = s.getInsProduct().stream().collect(Collectors.groupingBy(InsProduct::getLaboratory));
|
// 创建一个 Map 将站点和项目ID的映射关系
|
Map<String, Set<Integer>> labToDeviceMap = new HashMap<>();
|
// 获取所有站点的项目ID 列表
|
for (Map.Entry<String, List<InsProduct>> entry : listMap.entrySet()) {
|
Set<Integer> deviceIds = entry.getValue().stream()
|
.map(InsProduct::getId)
|
.collect(Collectors.toSet());
|
labToDeviceMap.put(entry.getKey(), deviceIds);
|
}
|
for (InsReportDto1 insReportDto1 : insReportDto1s) {
|
String laboratory = insReportDto1.getLaboratory();
|
if (!labToDeviceMap.containsKey(laboratory)) {
|
continue;
|
}
|
Set<Integer> deviceIds = labToDeviceMap.get(laboratory);
|
Integer num = insReportDto1.getNum();
|
List<InsProductResult> insProductResults = insProductResultMapper.selectList(
|
Wrappers.<InsProductResult>lambdaQuery()
|
.eq(InsProductResult::getNum, num)
|
.in(InsProductResult::getInsProductId, deviceIds));
|
for (InsProductResult insProductResult : insProductResults) {
|
List<JSONObject> jsonObjects = JSON.parseArray(insProductResult.getEquipValue(), JSONObject.class);
|
for (JSONObject jsonObject : jsonObjects) {
|
String value = jsonObject.getString("v");
|
if (value != null && !value.isEmpty()) {
|
deviceSet.add(value);
|
}
|
}
|
}
|
List<InsProductResult2> insProductResult2s = insProductResult2Mapper.selectList(
|
Wrappers.<InsProductResult2>lambdaQuery()
|
.eq(InsProductResult2::getNum, num)
|
.in(InsProductResult2::getInsProductId, deviceIds));
|
for (InsProductResult2 result2 : insProductResult2s) {
|
String equipValue = result2.getEquipValue();
|
if (equipValue != null && !equipValue.isEmpty()) {
|
deviceSet.add(equipValue);
|
}
|
}
|
}
|
});
|
String url;
|
try {
|
InputStream inputStream = this.getClass().getResourceAsStream("/static/report-template.docx");
|
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);
|
}
|
StringBuilder standardMethod2 = new StringBuilder();
|
for (String s : standardMethod) {
|
standardMethod2.append(";\n").append(s);
|
}
|
standardMethod2.append(";\n").append("GB/T 9410-2008 《移动通信天线通用技术规范》");
|
standardMethod2.replace(0, 1, "");
|
tables.forEach(table -> {
|
table.put("tableSize", tables.size() + 1);
|
});
|
List<Map<String, String>> deviceList = null;
|
if (deviceSet.size() != 0) {
|
deviceList = insOrderMapper.selectDeviceList(deviceSet);
|
}
|
Map<String, String> codeStr = new HashMap<>();
|
codeStr.put("报告编号", insReport.getCode());
|
codeStr.put("样品名称", insOrder.getSample());
|
codeStr.put("规格型号", samples.get(0).getModel());
|
codeStr.put("发放日期", now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
String codePath;
|
try {
|
codePath = new MatrixToImageWriter().code(JackSonUtil.marshal(codeStr).replaceAll("\\{", "")
|
.replaceAll("}", "").replaceAll(",", "").replaceAll("\"", ""), twoCode);
|
} catch (Exception e) {
|
throw new RuntimeException(e);
|
}
|
String modelStr = "";
|
for (String model : models) {
|
modelStr += "," + model;
|
}
|
String finalModelStr = modelStr;
|
String sampleEn = insSampleMapper.getSampleEn(insOrder.getSample());
|
String orderType = insOrderMapper.getEnumLabelByValue(insOrder.getOrderType());
|
String formType = insOrderMapper.getEnumLabelByValue(insOrder.getFormType());
|
ConfigureBuilder builder = Configure.builder();
|
builder.useSpringEL(true);
|
List<Map<String, String>> finalDeviceList = deviceList;
|
List<Map<String, String>> sampleList = insSampleMapper.selectSampleList(orderId);
|
Integer userId = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery()
|
.eq(InsSampleUser::getInsSampleId, orderId).last("limit 1")).getUserId();
|
String signatureUrl;
|
try {
|
signatureUrl = userMapper.selectById(userId).getSignatureUrl();
|
} catch (Exception e) {
|
throw new ErrorException("找不到检验人的签名");
|
}
|
if (ObjectUtils.isEmpty(signatureUrl) || signatureUrl.equals("")) {
|
throw new ErrorException("找不到检验人的签名");
|
}
|
Custom custom = customMapper.selectById(insOrder.getCompanyId());
|
|
/*获取附件图片类型*/
|
List<Map<String, Object>> images = new ArrayList<>();
|
List<InsOrderFile> insOrderFiles = insOrderFileMapper.selectList(Wrappers.<InsOrderFile>lambdaQuery().eq(InsOrderFile::getType, 1).eq(InsOrderFile::getInsOrderId, orderId));
|
if (CollectionUtils.isNotEmpty(insOrderFiles)) {
|
insOrderFiles.forEach(insOrderFile -> {
|
Map<String, Object> image = new HashMap<>();
|
PictureRenderData pictureRenderData = Pictures.ofLocal(imgUrl + "/" + insOrderFile.getFileUrl()).sizeInCm(17, 20).create();
|
image.put("url", pictureRenderData);
|
image.put("report", insReport);
|
images.add(image);
|
});
|
}
|
//委托人和电话字段判断
|
if (ObjectUtils.isEmpty(insOrder.getPrepareUser())) {
|
insOrder.setPrepareUser("/");
|
}
|
if (ObjectUtils.isEmpty(insOrder.getPhone())) {
|
insOrder.setPhone("/");
|
}
|
//检验项目的环境
|
InsProduct insProduct = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery().eq(InsProduct::getState, 1).eq(InsProduct::getInsSampleId, samples.get(0).getId())).get(0);
|
String environment = "";
|
environment = (ObjectUtils.isNotEmpty(insProduct.getTemperature()) ? insProduct.getTemperature() + "℃ " : "") + (ObjectUtils.isNotEmpty(insProduct.getHumidity()) ? insProduct.getHumidity() + "%" : "");
|
String finalEnvironment = environment;
|
List<SampleProductDto> finalSamples = samples;
|
XWPFTemplate template = XWPFTemplate.compile(url, builder.build()).render(
|
new HashMap<String, Object>() {{
|
put("order", insOrder);
|
put("report", insReport);
|
put("departLims", departLims);
|
put("sampleCode", sampleCode);
|
put("environment", finalEnvironment);
|
put("custom", custom);
|
put("sampleSize", finalSamples.size());
|
put("tables", tables);
|
put("tableSize", tables.size() + 1);
|
put("standardMethod", (standardMethod2.toString().equals("null") ? "" : standardMethod2));
|
put("deviceList", finalDeviceList);
|
put("sampleList", sampleList);
|
put("twoCode", Pictures.ofLocal(codePath).create());
|
put("models", finalModelStr.replace(",", ""));
|
put("productSize", productSize);
|
put("productSize1", productSize1);
|
put("productSize2", productSize2);
|
put("productSize3", productSize3);
|
put("createTime", now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
|
put("createTimeEn", monthNames[now.getMonthValue() - 1] + " " + now.getDayOfMonth() + ", " + now.getYear());
|
put("insTime", insOrder.getInsTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
|
put("insTimeEn", monthNames[insOrder.getInsTime().getMonthValue() - 1] + " " + insOrder.getInsTime().getDayOfMonth() + ", " + insOrder.getInsTime().getYear());
|
put("writeUrl", null);
|
put("insUrl", Pictures.ofLocal(imgUrl + "/" + signatureUrl).create());
|
put("images", images);
|
put("examineUrl", null);
|
put("ratifyUrl", null);
|
put("sampleEn", sampleEn);
|
put("orderType", orderType);
|
put("getTime", insOrder.getExamineTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
|
put("getTimeEn", monthNames[insOrder.getExamineTime().getMonthValue() - 1] + " " + insOrder.getExamineTime().getDayOfMonth() + ", " + insOrder.getExamineTime().getYear());
|
put("seal1", null);
|
put("seal2", null);
|
put("formTypeCh", formType);
|
put("formTypeEn", insOrder.getFormType());
|
}});
|
try {
|
String name = insReport.getCode().replace("/", "") + ".docx";
|
template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl + "/" + name)));
|
insReport.setUrl("/word/" + name);
|
insReportMapper.insert(insReport);
|
insOrder.setInsState(5);
|
insOrderMapper.updateById(insOrder);
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
// 处理合并单元格的问题
|
String path = wordUrl + "/" + insReport.getCode().replace("/", "") + ".docx";
|
try {
|
FileInputStream stream = new FileInputStream(path);
|
XWPFDocument document = new XWPFDocument(stream);
|
List<XWPFTable> xwpfTables = document.getTables();
|
for (int i = 1; i < xwpfTables.size() - (deviceList == null ? 1 : 2); i++) {
|
Set<String> set1 = new HashSet<>();
|
Map<String, Map<String, Integer>> maps = new HashMap<>();
|
for (int j = 0; j < xwpfTables.get(i).getRows().size(); j++) {
|
for (int k = 0; k < xwpfTables.get(i).getRows().get(j).getTableCells().size(); k++) {
|
if (xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().indexOf("∑") > -1) {
|
String[] split = xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().split("∑");
|
if (set1.add(split[1])) {
|
Map<String, Integer> map = new HashMap<>();
|
map.put("sr", j);
|
map.put("sc", k);
|
map.put("er", j + 0);
|
map.put("ec", k + 0);
|
maps.put(split[1], map);
|
} else {
|
Map<String, Integer> map1 = maps.get(split[1]);
|
if (j == map1.get("sr")) {
|
map1.put("ec", map1.get("ec") + 1);
|
} else if (k == map1.get("sc")) {
|
map1.put("er", map1.get("er") + 1);
|
}
|
}
|
String str = xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().split("∑")[0];
|
xwpfTables.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
|
xwpfTables.get(i).getRows().get(j).getTableCells().get(k).setText(str);
|
xwpfTables.get(i).getRows().get(j).getTableCells().get(k).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
|
xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getParagraphArray(0).setAlignment(org.apache.poi.xwpf.usermodel.ParagraphAlignment.CENTER);
|
}
|
}
|
}
|
List<String> list = new ArrayList<>();
|
for (String s : maps.keySet()) {
|
list.add(s);
|
}
|
for (int a = list.size() - 1; a >= 0; a--) {
|
Map<String, Integer> v = maps.get(list.get(a));
|
for (int j = 0; j < v.get("er") - v.get("sr") + 1; j++) {
|
if (v.get("ec") > v.get("sc")) {
|
try {
|
TableTools.mergeCellsHorizonal(xwpfTables.get(i), v.get("sr") + j, v.get("sc"), v.get("ec"));
|
} catch (Exception e) {
|
}
|
}
|
}
|
if (v.get("er") > v.get("sr")) {
|
try {
|
TableTools.mergeCellsVertically(xwpfTables.get(i), v.get("sc"), v.get("sr"), v.get("er"));
|
} catch (Exception e) {
|
}
|
}
|
}
|
}
|
FileOutputStream fileOutputStream = new FileOutputStream(path);
|
document.write(fileOutputStream);
|
fileOutputStream.close();
|
} catch (FileNotFoundException e) {
|
throw new RuntimeException(e);
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
//处理中英文换行的问题
|
try {
|
FileInputStream stream1 = new FileInputStream(path);
|
XWPFDocument document1 = new XWPFDocument(stream1);
|
List<XWPFTable> xwpfTables1 = document1.getTables();
|
for (int i = 1; i < xwpfTables1.size() - (deviceList == null ? 1 : 2); i++) {
|
for (int j = 0; j < xwpfTables1.get(i).getRows().size(); j++) {
|
for (int k = 0; k < xwpfTables1.get(i).getRows().get(j).getTableCells().size(); k++) {
|
if (xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText().contains("@")) {
|
String text = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText();
|
String[] split = text.split("@");
|
xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
|
XWPFParagraph xwpfParagraph = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).addParagraph();
|
XWPFRun run = xwpfParagraph.createRun();
|
run.setText(split[0]);
|
if (ObjectUtils.isNotNull(split[1])) {
|
run.addBreak();
|
run.setText(split[1]);
|
}
|
xwpfParagraph.setAlignment(org.apache.poi.xwpf.usermodel.ParagraphAlignment.CENTER);
|
}
|
}
|
}
|
}
|
FileOutputStream fileOutputStream1 = new FileOutputStream(path);
|
document1.write(fileOutputStream1);
|
fileOutputStream1.close();
|
} catch (FileNotFoundException e) {
|
throw new RuntimeException(e);
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
}
|
|
|
// 计算行高的方法
|
private int calculateRowHeight(RowRenderData rowRenderData) {
|
// 实现计算逻辑,可能需要根据单元格内容和字体等参数进行计算
|
int height = 0;
|
for (CellRenderData cell : rowRenderData.getCells()) {
|
int cellHeight = estimateCellHeight(cell); // 根据内容估算单元格高度
|
if (cellHeight > height) {
|
height = cellHeight;
|
}
|
}
|
return height;
|
}
|
|
//根据单元格的文本内容计算实际行高
|
private int estimateCellHeight(CellRenderData cellRenderData) {
|
// 假设默认行高是40
|
int defaultHeight = 40;
|
// 获取单元格中的所有段落
|
List<ParagraphRenderData> paragraphs = cellRenderData.getParagraphs();
|
int estimatedHeight = 0;
|
// 遍历段落,估算每个段落的高度
|
for (ParagraphRenderData paragraph : paragraphs) {
|
List<RenderData> contents = paragraph.getContents();
|
for (RenderData content : contents) {
|
if (content instanceof TextRenderData) {
|
TextRenderData text = (TextRenderData) content;
|
Style style = text.getStyle();
|
// 假设每行文本的高度为字体大小的1.2倍
|
Double fontSize = Objects.isNull(style.getFontSize()) ? 12.0 : style.getFontSize();
|
int lines = (int) Math.ceil(text.getText().length() / 15.0); // 假设每行约15个字符
|
int textHeight = (int) (fontSize * 1.2 * lines);
|
// 累加段落的高度
|
estimatedHeight += textHeight;
|
}
|
}
|
}
|
// 返回最大值,确保高度不低于默认高度
|
return Math.max(estimatedHeight, defaultHeight);
|
}
|
}
|