Commit 0da67341 authored by 盖献康's avatar 盖献康

Merge branch 'gaixiankang' into 'dev'

原始记录PDF

See merge request !288
parents f24f19a0 42d30b8a
...@@ -66,6 +66,11 @@ ...@@ -66,6 +66,11 @@
<artifactId>xmlworker</artifactId> <artifactId>xmlworker</artifactId>
<version>5.5.13</version> <version>5.5.13</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
</dependency>
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId> <artifactId>ruoyi-framework</artifactId>
...@@ -81,6 +86,17 @@ ...@@ -81,6 +86,17 @@
<artifactId>commonmark</artifactId> <artifactId>commonmark</artifactId>
<version>0.15.2</version> <version>0.15.2</version>
</dependency> </dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<!-- iText 7 pdfHTML -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>4.0.5</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
...@@ -6,6 +6,8 @@ import com.itextpdf.text.Font; ...@@ -6,6 +6,8 @@ import com.itextpdf.text.Font;
import com.itextpdf.text.Image; import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle; import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*; import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.ElementList;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PdfBaseWriter; import com.ruoyi.common.utils.PdfBaseWriter;
...@@ -24,6 +26,8 @@ import lombok.SneakyThrows; ...@@ -24,6 +26,8 @@ import lombok.SneakyThrows;
import org.commonmark.node.Node; import org.commonmark.node.Node;
import org.commonmark.parser.Parser; import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer; import org.commonmark.renderer.html.HtmlRenderer;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Entities;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -266,6 +270,7 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe ...@@ -266,6 +270,7 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe
* 原始记录PDF下载 * 原始记录PDF下载
* @param taskId * @param taskId
* @return * @return
* @throws Exception
*/ */
@Override @Override
public String generateOriginalRecord(Long taskId) throws Exception{ public String generateOriginalRecord(Long taskId) throws Exception{
...@@ -273,12 +278,14 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe ...@@ -273,12 +278,14 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe
// 创建一张PDF文件 // 创建一张PDF文件
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfBaseWriter document = new PdfBaseWriter(outputStream); PdfBaseWriter document = new PdfBaseWriter(outputStream);
document.setMargins(50, 50, 80, 40); document.setMargins(50, 50, 85, 40);
PdfWriter writer = PdfWriter.getInstance(document, outputStream); PdfWriter writer = PdfWriter.getInstance(document, outputStream);
OriginalRecordHeaderFooter headerFooter = new OriginalRecordHeaderFooter(); OriginalRecordHeaderFooter headerFooter = new OriginalRecordHeaderFooter();
writer.setPageEvent(headerFooter); writer.setPageEvent(headerFooter);
// open // open
document.open(); document.open();
document.setParagraph(" ", 10f, Element.ALIGN_LEFT, 0,2f, 10f);
document.newPage();
// 内容 // 内容
// 1.检验依据 // 1.检验依据
PdfPTable reportNumberTable = new PdfPTable(new float[]{30, 15}); PdfPTable reportNumberTable = new PdfPTable(new float[]{30, 15});
...@@ -287,7 +294,7 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe ...@@ -287,7 +294,7 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe
document.writeNoBorderCell("报告编号:", Element.ALIGN_RIGHT, 1, 1, reportNumberTable); document.writeNoBorderCell("报告编号:", Element.ALIGN_RIGHT, 1, 1, reportNumberTable);
document.writeBottomCell("", Element.ALIGN_RIGHT, 1, 1, reportNumberTable); document.writeBottomCell("", Element.ALIGN_RIGHT, 1, 1, reportNumberTable);
document.addContent(reportNumberTable); document.addContent(reportNumberTable);
document.setParagraph("1.检验依据", 10f, Element.ALIGN_LEFT, 0,10f, 10f); document.setParagraph("1.检验依据", 10f, Element.ALIGN_LEFT, 0,2f, 10f);
document.setParagraph("口《汽车整车信息安全技术要求》", 10f, Element.ALIGN_LEFT, 14,0f, 0f); document.setParagraph("口《汽车整车信息安全技术要求》", 10f, Element.ALIGN_LEFT, 14,0f, 0f);
// 2.样品情况 // 2.样品情况
document.setParagraph("2.样品情况", 10f, Element.ALIGN_LEFT, 0,10f, 10f); document.setParagraph("2.样品情况", 10f, Element.ALIGN_LEFT, 0,10f, 10f);
...@@ -329,15 +336,82 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe ...@@ -329,15 +336,82 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe
document.writeBottomCell("检验地点:", Element.ALIGN_LEFT, 1, 1, inspectorTable); document.writeBottomCell("检验地点:", Element.ALIGN_LEFT, 1, 1, inspectorTable);
document.writeBottomCell("口中汽研软件测评有限公司 口其他:", Element.ALIGN_LEFT, 1, 1, inspectorTable); document.writeBottomCell("口中汽研软件测评有限公司 口其他:", Element.ALIGN_LEFT, 1, 1, inspectorTable);
inspectorTable.writeSelectedRows(0, -1, document.left(), document.bottom() + 60, writer.getDirectContent()); inspectorTable.writeSelectedRows(0, -1, document.left(), document.bottom() + 60, writer.getDirectContent());
// 开启下一页
document.newPage();
// 4.检验结果(循环遍历用例)
document.setParagraph("4.检验结果", 10f, Element.ALIGN_LEFT, 0,10f, 0f);
// 获取数据 - 渲染
document.setParagraph("4.1硬件安全-关键芯片丝印信息测试", 10f, Element.ALIGN_LEFT, 0,2f, 10f);
PdfPTable useCaseTable = new PdfPTable(new float[]{15, 35, 15, 35});
useCaseTable.setWidthPercentage(100);
document.writeCell("测试编号", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("激光雷达_001", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("测试时间", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("2021年8月23日", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("样品编号", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("STCS-2021-08-0013(01)", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("测试人员", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("简述", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("检测PCB板上的核心芯片是否存在可用丝印信息。", Element.ALIGN_LEFT, 3, 1, useCaseTable);
document.writeCell("风险等级", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("中危", Element.ALIGN_LEFT, 3, 1, useCaseTable);
document.writeCell("测试方法", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("1.使用专用工具将雷达拆卸至PCB板;", Element.ALIGN_LEFT, 3, 1, useCaseTable);
document.writeCell("测试结果", Element.ALIGN_LEFT, 1, 1, useCaseTable);
document.writeCell("芯片丝印未擦除,且PCB板上暴露的丝印信息较多,有泄露电路设计的风险。", Element.ALIGN_LEFT, 3, 1, useCaseTable);
document.writeCell("测试详情", Element.ALIGN_LEFT, 1, 1, useCaseTable);
PdfPCell cell = new PdfPCell();
cell.setColspan(3);
cell.setRowspan(1);
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
// String htmlContent = convertMarkdownToHtml("**请依次完成以下操作:**\\n\\n1)使用电动螺丝刀拆开车机外壳,注意不要造成物理性破坏;\\n\\n2)肉眼观察板子上是否有明显的JTAG调试接口,需要注意CPU附近的点和引脚的各种信息;\\n\\n注:JTAG通常主要由以下4个针脚组成:\\n\\n①TCK ... Test Clock\\n\\n②TMS ... Test Mode Select \\n\\n③TDI ... Test Data In\\n\\n④TDO ... Test Data Out\\n\\n3)通过五倍光学放大镜仔细查看PCB板上的信息,找到带有JTAG、TCK、TMS、TDI、TDO等相关的信息的点位,比如下图:\\n\\n![](http://10.12.48.80:8089/file_server/api_v1/downloadSysFile?key=e45566a4ebf14eb299d60b180473f9c84c&ts=2024_03_05&token=7f5ac770a013f7ce74205992257f5d9b&tmp=false&inline=true)\\n\\n4)将测试过程中的 PCB 板照片等作为测试证明材料上传至平台。\\n\\n<br>\\n\\n**请根据PCB板上是否存在明显的JTAG调试接口对节点结果进行判断。**");
// CSS样式,设置默认字体
String css = "body { font-family: Arial, sans-serif; }";
// h5渲染到cell
String htmlContent = "<h1 style=\"font-size: 36pt;\">Hello, World!</h1><h2>我的</h2><p style=\"color: red;\">This is some HTML content.</p><img src=\"http://49.232.167.247:22038/vehicle-quality-review-oss/2024/04/11/1712827970222_20240411173255A009.jpg\" />";
ElementList elementList = XMLWorkerHelper.parseToElementList(htmlContent, css);
for (Element element : elementList) {
cell.addElement(element);
}
useCaseTable.addCell(cell);
document.add(useCaseTable);
// 5.附录
document.setParagraph("5.附录", 10f, Element.ALIGN_LEFT, 0,10f, 0f);
document.setParagraph("图1 样品照片", 10f, Element.ALIGN_CENTER, 0,20f, 0f);
document.setParagraph("图2 试验照片", 10f, Element.ALIGN_CENTER, 0,20f, 0f);
// close // close
document.close(); document.close();
writer.close(); writer.close();
String templateName = uploadMinio(outputStream, "原始记录临时");
return uploadMinio(outputStream, "原始记录"); Document currentDoc = new Document();
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
PdfCopy copy = new PdfCopy(currentDoc, arrayOutputStream);
currentDoc.open();
PdfReader templateReader = new PdfReader(minioUrl() + templateName);
PdfStamper stamper = new PdfStamper(templateReader, arrayOutputStream);
int numberOfPages = templateReader.getNumberOfPages();
for (int i = 2; i <= numberOfPages; i++) {
copy.addPage(copy.getImportedPage(templateReader, i));
}
currentDoc.close();
templateReader.close();
copy.close();
return uploadMinio(arrayOutputStream, "原始记录");
} }
public static class OriginalRecordHeaderFooter extends PdfPageEventHelper { public static class OriginalRecordHeaderFooter extends PdfPageEventHelper {
private int totalNum = 0;
// PdfTemplate totalPage;
// @Override
// public void onOpenDocument (PdfWriter writer, Document document) {
// PdfContentByte contentByte = writer.getDirectContent();
// totalPage = contentByte.createTemplate(30, 16);
// }
/** /**
* 一页加载完成触发,写入页眉和页脚 * 一页加载完成触发,写入页眉和页脚
*/ */
...@@ -362,7 +436,16 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe ...@@ -362,7 +436,16 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe
table.addCell(new Paragraph("检验记录", new Font(font))); table.addCell(new Paragraph("检验记录", new Font(font)));
table.getDefaultCell().setRowspan(1); table.getDefaultCell().setRowspan(1);
table.getDefaultCell().setColspan(1); table.getDefaultCell().setColspan(1);
table.addCell(new Paragraph("第 " + writer.getPageNumber() + " 页", new Font(font))); table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(Rectangle.BOTTOM + Rectangle.TOP + Rectangle.LEFT + Rectangle.RIGHT);
table.addCell(new Paragraph("第 " + (writer.getCurrentPageNumber() - 1) + " 页 / 共 "+ totalNum +" 页", new Font(font)));
// 总页数
// table.getDefaultCell().setBorder(Rectangle.BOX);
// table.getDefaultCell().setColspan(1);
// table.getDefaultCell().setRowspan(1);
// table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);
// table.getDefaultCell().setBorder(Rectangle.BOTTOM + Rectangle.TOP + Rectangle.RIGHT);
// table.addCell(Image.getInstance(totalPage));
// 将页眉写到document中,位置可以指定,指定到下面就是页脚 // 将页眉写到document中,位置可以指定,指定到下面就是页脚
table.writeSelectedRows(0, -1, 40, PageSize.A4.getHeight() - 20, writer.getDirectContent()); table.writeSelectedRows(0, -1, 40, PageSize.A4.getHeight() - 20, writer.getDirectContent());
// 页脚 // 页脚
...@@ -374,9 +457,20 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe ...@@ -374,9 +457,20 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe
bottomTable.getDefaultCell().setBorder(Rectangle.NO_BORDER); bottomTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
bottomTable.getDefaultCell().setBorderWidth(0.5f); bottomTable.getDefaultCell().setBorderWidth(0.5f);
bottomTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER); bottomTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
bottomTable.addCell(new Paragraph(String.valueOf(writer.getPageNumber()), new Font(font))); bottomTable.addCell(new Paragraph(String.valueOf(writer.getPageNumber() - 1), new Font(font)));
bottomTable.writeSelectedRows(0, -1, 40, 40, writer.getDirectContent()); bottomTable.writeSelectedRows(0, -1, 40, 40, writer.getDirectContent());
} }
@Override
@SneakyThrows
public void onCloseDocument(PdfWriter writer, Document document) {
// BaseFont font = BaseFont.createFont("/fonts/STSong.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
// String text = " 共 " + (writer.getPageNumber()) + " 页";
// ColumnText.showTextAligned(totalPage, Element.ALIGN_CENTER, new Paragraph(String.valueOf(text), new Font(font, 8f)), 2, 4 ,0);
totalNum = writer.getPageNumber();
System.out.println(totalNum);
}
} }
/** /**
...@@ -395,7 +489,12 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe ...@@ -395,7 +489,12 @@ public class PdfTemplateManagementServiceImpl implements PdfTemplateManagementSe
HtmlRenderer renderer = HtmlRenderer.builder().build(); HtmlRenderer renderer = HtmlRenderer.builder().build();
// 渲染 HTML // 渲染 HTML
return renderer.render(document); org.jsoup.nodes.Document doc = Jsoup.parse(renderer.render(document).replaceAll("\\n", "<br>"));
// jsoup标准化标签,生成闭合标签
doc.outputSettings().syntax(org.jsoup.nodes.Document.OutputSettings.Syntax.xml);
doc.outputSettings().escapeMode(Entities.EscapeMode.xhtml);
return doc.html();
} }
private static String headerText; private static String headerText;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment