ITextPdfUtil.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. package com.om.utils;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import com.itextpdf.io.font.PdfEncodings;
  4. import com.itextpdf.io.image.BmpImageData;
  5. import com.itextpdf.io.image.ImageData;
  6. import com.itextpdf.io.image.ImageDataFactory;
  7. import com.itextpdf.io.image.PngImageData;
  8. import com.itextpdf.kernel.colors.Color;
  9. import com.itextpdf.kernel.colors.DeviceRgb;
  10. import com.itextpdf.kernel.font.PdfFont;
  11. import com.itextpdf.kernel.font.PdfFontFactory;
  12. import com.itextpdf.kernel.geom.PageSize;
  13. import com.itextpdf.kernel.pdf.PdfDocument;
  14. import com.itextpdf.kernel.pdf.PdfReader;
  15. import com.itextpdf.kernel.pdf.PdfWriter;
  16. import com.itextpdf.kernel.pdf.annot.PdfLinkAnnotation;
  17. import com.itextpdf.kernel.pdf.canvas.draw.SolidLine;
  18. import com.itextpdf.layout.Document;
  19. import com.itextpdf.layout.Style;
  20. import com.itextpdf.layout.borders.Border;
  21. import com.itextpdf.layout.element.*;
  22. import com.itextpdf.layout.property.BorderRadius;
  23. import com.itextpdf.layout.property.HorizontalAlignment;
  24. import com.itextpdf.layout.property.TextAlignment;
  25. import com.itextpdf.layout.property.UnitValue;
  26. import com.om.entity.dto.ControlListMap;
  27. import com.om.entity.po.FaultCode;
  28. import org.apache.commons.lang3.StringUtils;
  29. import org.slf4j.Logger;
  30. import org.slf4j.LoggerFactory;
  31. import org.springframework.beans.factory.annotation.Value;
  32. import org.springframework.stereotype.Component;
  33. import javax.annotation.PostConstruct;
  34. import java.io.File;
  35. import java.io.IOException;
  36. import java.io.OutputStream;
  37. import java.net.URL;
  38. import java.time.LocalDate;
  39. import java.time.LocalDateTime;
  40. import java.time.format.DateTimeFormatter;
  41. import java.util.ArrayList;
  42. import java.util.HashMap;
  43. import java.util.List;
  44. import java.util.Map;
  45. /**
  46. * itextpdf 工具类
  47. * iText 7是iText强大的PDF工具包的最新版本,用于PDF生成,PDF编程,处理和操作,如数字签名等。
  48. * https://kb.itextpdf.com/home/it7kb/ebooks
  49. */
  50. @Component
  51. public class ITextPdfUtil {
  52. //字体,我这里使用系统自带的simhei黑体
  53. //private static final String FONT = "C:/Windows/Fonts/simhei.ttf";
  54. private static final Logger log = LoggerFactory.getLogger(ITextPdfUtil.class);
  55. private static final String FONT = "/usr/local/docker/opera/static/simhei.ttf";
  56. @Value("${baseStatic}")
  57. private String baseStatic;
  58. //生成简单PDF
  59. public File MapToPDF(Integer id, List<ControlListMap> controlListMap
  60. , Map<String, String> baseMap, Map<String, String> companyMap) {
  61. System.out.println("baseStatic11: "+baseStatic);
  62. String yyyyMMdd = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
  63. //try (PdfWriter writer = new PdfWriter("src\\main\\resources\\" + yyyyMMdd + "report" + id + ".pdf");
  64. try {
  65. /* // 创建目录对象
  66. File directory = new File(baseStatic);
  67. System.out.println("目录是否存在:"+directory.exists());
  68. // 检查目录是否存在,如果不存在则创建它
  69. if (!directory.exists()) {
  70. directory.mkdirs(); // 创建目录及其父目录
  71. }*/
  72. // 创建文件对象
  73. File pdfFile = new File(baseStatic + yyyyMMdd + "report" + id + ".pdf");
  74. System.out.println("文件是否存在:"+pdfFile.exists());
  75. // 检查文件是否存在,如果不存在则创建它
  76. if (!pdfFile.exists()) {
  77. pdfFile.createNewFile();
  78. }
  79. System.out.println("文件是否存在:"+pdfFile.exists());
  80. } catch (IOException e) {
  81. // 处理文件操作异常
  82. e.printStackTrace();
  83. }
  84. try (PdfWriter writer = new PdfWriter(baseStatic + yyyyMMdd + "report" + id + ".pdf");
  85. //FileOutputStream out = new FileOutputStream(new File("src\\main\\resources\\outpdf\\report.pdf"))
  86. PdfDocument pdf = new PdfDocument(writer);
  87. Document document = new Document(pdf, PageSize.A4);
  88. ) {
  89. DeviceRgb red = new DeviceRgb(255, 59, 48);
  90. DeviceRgb black = new DeviceRgb(34, 34, 34);
  91. //设置文档属性
  92. pdf.getDocumentInfo().setAuthor("bmmx");
  93. pdf.getDocumentInfo().setTitle("诊断报告");
  94. //设置字体
  95. document.setFont(this.getPdfFont());
  96. //页边距
  97. document.setMargins(10, 10, 10, 10);
  98. //诊断报告 + 时间
  99. document.add(new Div()
  100. .add(new Paragraph("诊断报告")
  101. .addStyle(new Style()
  102. .setFontSize(20)
  103. .setBold()))
  104. .add(new Paragraph("— " + LocalDateTime.now()
  105. .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + " —"))
  106. .addStyle(new Style()
  107. .setFontSize(18)
  108. .setFontColor(new DeviceRgb(54, 85, 153)))
  109. .setBackgroundColor(new DeviceRgb(235, 241, 250))
  110. .setTextAlignment(TextAlignment.CENTER));
  111. DeviceRgb c1 = new DeviceRgb(136, 136, 136);
  112. DeviceRgb c2 = new DeviceRgb(40, 40, 40);
  113. Table baseTable = new Table(2);
  114. mapToTable(baseMap, baseTable, c1, c2);
  115. //ImageData imageData = ImageDataFactory.create("src/main/resources/template/static/img.png");
  116. System.out.println("baseStatic: "+baseStatic);
  117. ImageData imageData = ImageDataFactory.create(baseStatic+"img.png");
  118. Image update = new Image(imageData);
  119. update.setWidth(20);
  120. update.setHeight(20);
  121. update.setMarginTop(10);
  122. update.setMarginLeft(540);
  123. // 车辆信息
  124. document.add(new Div()
  125. .setMarginTop(10)
  126. .setHorizontalAlignment(HorizontalAlignment.CENTER)
  127. .setBackgroundColor(new DeviceRgb(235, 241, 250))
  128. .setBorderRadius(new BorderRadius(5))
  129. .add(new Div()
  130. .setBackgroundColor(new DeviceRgb(64, 109, 183))
  131. .setBorderBottomLeftRadius(new BorderRadius(8))
  132. .setBorderBottomRightRadius(new BorderRadius(8))
  133. .setWidth(100)
  134. .setHorizontalAlignment(HorizontalAlignment.CENTER)
  135. .add(new Paragraph("车辆信息")
  136. .setFontSize(18)
  137. .setTextAlignment(TextAlignment.CENTER)
  138. .addStyle(new Style()
  139. .setFontColor(new DeviceRgb(255, 255, 255))
  140. .setBold()
  141. )))
  142. .add(update)
  143. .add(baseTable));
  144. SolidLine solidLine = new SolidLine(0.2f);
  145. solidLine.setColor(new DeviceRgb(64, 109, 183));
  146. //solidLine.setLineWidth(260);
  147. for (ControlListMap listMap : controlListMap) {
  148. String name = listMap.getName();
  149. Map<String, String> versionMap = listMap.getVersionMap();
  150. Map<String, FaultCode> faultCodeMap = listMap.getFaultCodeMap();
  151. log.debug("versionMap::{}",versionMap);
  152. log.debug("faultCodeMap::{}",faultCodeMap);
  153. Table faultCodeTable = new Table(3);
  154. mapToTableFault(faultCodeMap, faultCodeTable, red, red);
  155. Table versionTable = new Table(2);
  156. mapToTable(versionMap, versionTable, black, black);
  157. // 车辆信息
  158. document.add(new Div()
  159. .setMarginTop(10)
  160. .setHorizontalAlignment(HorizontalAlignment.CENTER)
  161. .setBackgroundColor(new DeviceRgb(235, 241, 250))
  162. .setBorderRadius(new BorderRadius(5))
  163. .add(new Div()
  164. .setBackgroundColor(new DeviceRgb(64, 109, 183))
  165. .setBorderBottomLeftRadius(new BorderRadius(8))
  166. .setBorderBottomRightRadius(new BorderRadius(8))
  167. .setWidth(100)
  168. .setHorizontalAlignment(HorizontalAlignment.CENTER)
  169. .add(new Paragraph("诊断详情")
  170. .setFontSize(18)
  171. .setTextAlignment(TextAlignment.CENTER)
  172. .addStyle(new Style()
  173. .setFontColor(new DeviceRgb(255, 255, 255))
  174. .setBold()
  175. )))
  176. .add(new Div()
  177. .setBackgroundColor(new DeviceRgb(64, 109, 183))
  178. .setMarginTop(20)
  179. .setBorderTopRightRadius(new BorderRadius(5))
  180. .setMaxWidth(300)
  181. .add(new Paragraph(name)
  182. .setFontSize(16)
  183. .setFontColor(new DeviceRgb(255, 255, 255))
  184. .setTextAlignment(TextAlignment.CENTER)
  185. )
  186. )
  187. .add(new LineSeparator(solidLine).setMarginRight(10))
  188. .add(new Paragraph("故障码(" + faultCodeMap.size() + ")")
  189. .setFontColor(new DeviceRgb(153, 153, 153))
  190. .setFontSize(16)
  191. .setMarginLeft(10)
  192. .setMarginTop(10)
  193. )
  194. .add(faultCodeTable).setFontSize(10)
  195. .add(new Paragraph("版本信息(" + versionMap.size() + ")")
  196. .setFontColor(new DeviceRgb(153, 153, 153))
  197. .setFontSize(16)
  198. .setMarginLeft(10)
  199. .setMarginTop(10)
  200. )
  201. .add(versionTable).setFontSize(16));
  202. }
  203. Table companyTable = new Table(2);
  204. DeviceRgb grey = new DeviceRgb(136, 136, 136);
  205. mapToTable(companyMap, companyTable, grey, grey);
  206. Text firstCh = new Text("*").setFontColor(red).setFontSize(8);
  207. Text rest = new Text("该车辆检测报告仅对本次检查结果负责")
  208. .setFontSize(14)
  209. .setFontColor(grey);
  210. document.add(new Div()
  211. .add(update)
  212. .setBackgroundColor(new DeviceRgb(235, 241, 250))
  213. .add(companyTable)
  214. .setMarginTop(10)
  215. .add(new Paragraph().add(firstCh).add(rest)
  216. .setMarginLeft(10)
  217. )
  218. );
  219. document.close();
  220. System.out.println("操作完成!");
  221. File file = new File(baseStatic + yyyyMMdd + "report" + id + ".pdf");
  222. return file;
  223. } catch (IOException e) {
  224. e.printStackTrace();
  225. System.err.println("操作异常...");
  226. return null;
  227. }
  228. }
  229. private void mapToTable(Map<String, String> map, Table table, Color one, Color two) {
  230. table.setMargin(10);
  231. table.setWidth(570);
  232. table.setFontSize(16);
  233. table.setFontColor(new DeviceRgb(136, 136, 136));
  234. for (Map.Entry<String, String> entry : map.entrySet()) {
  235. table.addCell(entry.getKey() + ": ")
  236. .setFontColor(one);
  237. String value = entry.getValue();
  238. if (StringUtils.isBlank(value)) {
  239. value = "";
  240. }
  241. table.addCell(new Cell()
  242. .add(new Paragraph(value))
  243. .setFontColor(two));
  244. }
  245. RemoveBorder(table);
  246. }
  247. private void mapToTableFault(Map<String, FaultCode> map, Table table, Color one, Color two) {
  248. table.setMargin(10);
  249. table.setWidth(570);
  250. table.setFontSize(16);
  251. table.setFontColor(new DeviceRgb(136, 136, 136));
  252. table.setWidth(UnitValue.createPercentValue(100)); // 调整宽度以适应页面
  253. for (Map.Entry<String, FaultCode> entry : map.entrySet()) {
  254. String key = entry.getKey();
  255. FaultCode faultCode = entry.getValue();
  256. // 将键、描述和状态添加到同一行
  257. table.addCell(new Cell().add(new Paragraph(key)).setFontColor(one));
  258. if (StringUtils.isNotBlank(faultCode.getDescription())){
  259. table.addCell(new Cell().add(new Paragraph(faultCode.getDescription())).setFontColor(two));
  260. }else {
  261. table.addCell(new Cell().add(new Paragraph()).setFontColor(two));
  262. }
  263. if (StringUtils.isNotBlank(faultCode.getStatus())){
  264. table.addCell(new Cell().add(new Paragraph(faultCode.getStatus())).setFontColor(two));
  265. }else {
  266. table.addCell(new Cell().add(new Paragraph()).setFontColor(two));
  267. }
  268. }
  269. RemoveBorder(table);
  270. }
  271. private void RemoveBorder(Table table) {
  272. for (IElement iElement : table.getChildren()) {
  273. ((Cell) iElement).setBorder(Border.NO_BORDER);
  274. }
  275. }
  276. //获取统一字体
  277. public PdfFont getPdfFont() {
  278. PdfFont pdfFont = null;
  279. try {
  280. pdfFont = PdfFontFactory.createFont(ITextPdfUtil.FONT, PdfEncodings.IDENTITY_H, true);
  281. } catch (IOException e) {
  282. e.printStackTrace();
  283. }
  284. return pdfFont;
  285. }
  286. }