package com.om.utils; import cn.hutool.core.bean.BeanUtil; import com.itextpdf.io.font.PdfEncodings; import com.itextpdf.io.image.BmpImageData; import com.itextpdf.io.image.ImageData; import com.itextpdf.io.image.ImageDataFactory; import com.itextpdf.io.image.PngImageData; import com.itextpdf.kernel.colors.Color; import com.itextpdf.kernel.colors.DeviceRgb; import com.itextpdf.kernel.font.PdfFont; import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.annot.PdfLinkAnnotation; import com.itextpdf.kernel.pdf.canvas.draw.SolidLine; import com.itextpdf.layout.Document; import com.itextpdf.layout.Style; import com.itextpdf.layout.borders.Border; import com.itextpdf.layout.element.*; import com.itextpdf.layout.property.BorderRadius; import com.itextpdf.layout.property.HorizontalAlignment; import com.itextpdf.layout.property.TextAlignment; import com.itextpdf.layout.property.UnitValue; import com.om.entity.dto.ControlListMap; import com.om.entity.po.FaultCode; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * itextpdf 工具类 * iText 7是iText强大的PDF工具包的最新版本,用于PDF生成,PDF编程,处理和操作,如数字签名等。 * https://kb.itextpdf.com/home/it7kb/ebooks */ @Component public class ITextPdfUtil { //字体,我这里使用系统自带的simhei黑体 //private static final String FONT = "C:/Windows/Fonts/simhei.ttf"; private static final Logger log = LoggerFactory.getLogger(ITextPdfUtil.class); private static final String FONT = "/usr/local/docker/opera/static/simhei.ttf"; @Value("${baseStatic}") private String baseStatic; //生成简单PDF public File MapToPDF(Integer id, List controlListMap , Map baseMap, Map companyMap) { System.out.println("baseStatic11: "+baseStatic); String yyyyMMdd = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); //try (PdfWriter writer = new PdfWriter("src\\main\\resources\\" + yyyyMMdd + "report" + id + ".pdf"); try { /* // 创建目录对象 File directory = new File(baseStatic); System.out.println("目录是否存在:"+directory.exists()); // 检查目录是否存在,如果不存在则创建它 if (!directory.exists()) { directory.mkdirs(); // 创建目录及其父目录 }*/ // 创建文件对象 File pdfFile = new File(baseStatic + yyyyMMdd + "report" + id + ".pdf"); System.out.println("文件是否存在:"+pdfFile.exists()); // 检查文件是否存在,如果不存在则创建它 if (!pdfFile.exists()) { pdfFile.createNewFile(); } System.out.println("文件是否存在:"+pdfFile.exists()); } catch (IOException e) { // 处理文件操作异常 e.printStackTrace(); } try (PdfWriter writer = new PdfWriter(baseStatic + yyyyMMdd + "report" + id + ".pdf"); //FileOutputStream out = new FileOutputStream(new File("src\\main\\resources\\outpdf\\report.pdf")) PdfDocument pdf = new PdfDocument(writer); Document document = new Document(pdf, PageSize.A4); ) { DeviceRgb red = new DeviceRgb(255, 59, 48); DeviceRgb black = new DeviceRgb(34, 34, 34); //设置文档属性 pdf.getDocumentInfo().setAuthor("bmmx"); pdf.getDocumentInfo().setTitle("诊断报告"); //设置字体 document.setFont(this.getPdfFont()); //页边距 document.setMargins(10, 10, 10, 10); //诊断报告 + 时间 document.add(new Div() .add(new Paragraph("诊断报告") .addStyle(new Style() .setFontSize(20) .setBold())) .add(new Paragraph("— " + LocalDateTime.now() .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + " —")) .addStyle(new Style() .setFontSize(18) .setFontColor(new DeviceRgb(54, 85, 153))) .setBackgroundColor(new DeviceRgb(235, 241, 250)) .setTextAlignment(TextAlignment.CENTER)); DeviceRgb c1 = new DeviceRgb(136, 136, 136); DeviceRgb c2 = new DeviceRgb(40, 40, 40); Table baseTable = new Table(2); mapToTable(baseMap, baseTable, c1, c2); //ImageData imageData = ImageDataFactory.create("src/main/resources/template/static/img.png"); System.out.println("baseStatic: "+baseStatic); ImageData imageData = ImageDataFactory.create(baseStatic+"img.png"); Image update = new Image(imageData); update.setWidth(20); update.setHeight(20); update.setMarginTop(10); update.setMarginLeft(540); // 车辆信息 document.add(new Div() .setMarginTop(10) .setHorizontalAlignment(HorizontalAlignment.CENTER) .setBackgroundColor(new DeviceRgb(235, 241, 250)) .setBorderRadius(new BorderRadius(5)) .add(new Div() .setBackgroundColor(new DeviceRgb(64, 109, 183)) .setBorderBottomLeftRadius(new BorderRadius(8)) .setBorderBottomRightRadius(new BorderRadius(8)) .setWidth(100) .setHorizontalAlignment(HorizontalAlignment.CENTER) .add(new Paragraph("车辆信息") .setFontSize(18) .setTextAlignment(TextAlignment.CENTER) .addStyle(new Style() .setFontColor(new DeviceRgb(255, 255, 255)) .setBold() ))) .add(update) .add(baseTable)); SolidLine solidLine = new SolidLine(0.2f); solidLine.setColor(new DeviceRgb(64, 109, 183)); //solidLine.setLineWidth(260); for (ControlListMap listMap : controlListMap) { String name = listMap.getName(); Map versionMap = listMap.getVersionMap(); Map faultCodeMap = listMap.getFaultCodeMap(); log.debug("versionMap::{}",versionMap); log.debug("faultCodeMap::{}",faultCodeMap); Table faultCodeTable = new Table(3); mapToTableFault(faultCodeMap, faultCodeTable, red, red); Table versionTable = new Table(2); mapToTable(versionMap, versionTable, black, black); // 车辆信息 document.add(new Div() .setMarginTop(10) .setHorizontalAlignment(HorizontalAlignment.CENTER) .setBackgroundColor(new DeviceRgb(235, 241, 250)) .setBorderRadius(new BorderRadius(5)) .add(new Div() .setBackgroundColor(new DeviceRgb(64, 109, 183)) .setBorderBottomLeftRadius(new BorderRadius(8)) .setBorderBottomRightRadius(new BorderRadius(8)) .setWidth(100) .setHorizontalAlignment(HorizontalAlignment.CENTER) .add(new Paragraph("诊断详情") .setFontSize(18) .setTextAlignment(TextAlignment.CENTER) .addStyle(new Style() .setFontColor(new DeviceRgb(255, 255, 255)) .setBold() ))) .add(new Div() .setBackgroundColor(new DeviceRgb(64, 109, 183)) .setMarginTop(20) .setBorderTopRightRadius(new BorderRadius(5)) .setMaxWidth(300) .add(new Paragraph(name) .setFontSize(16) .setFontColor(new DeviceRgb(255, 255, 255)) .setTextAlignment(TextAlignment.CENTER) ) ) .add(new LineSeparator(solidLine).setMarginRight(10)) .add(new Paragraph("故障码(" + faultCodeMap.size() + ")") .setFontColor(new DeviceRgb(153, 153, 153)) .setFontSize(16) .setMarginLeft(10) .setMarginTop(10) ) .add(faultCodeTable).setFontSize(10) .add(new Paragraph("版本信息(" + versionMap.size() + ")") .setFontColor(new DeviceRgb(153, 153, 153)) .setFontSize(16) .setMarginLeft(10) .setMarginTop(10) ) .add(versionTable).setFontSize(16)); } Table companyTable = new Table(2); DeviceRgb grey = new DeviceRgb(136, 136, 136); mapToTable(companyMap, companyTable, grey, grey); Text firstCh = new Text("*").setFontColor(red).setFontSize(8); Text rest = new Text("该车辆检测报告仅对本次检查结果负责") .setFontSize(14) .setFontColor(grey); document.add(new Div() .add(update) .setBackgroundColor(new DeviceRgb(235, 241, 250)) .add(companyTable) .setMarginTop(10) .add(new Paragraph().add(firstCh).add(rest) .setMarginLeft(10) ) ); document.close(); System.out.println("操作完成!"); File file = new File(baseStatic + yyyyMMdd + "report" + id + ".pdf"); return file; } catch (IOException e) { e.printStackTrace(); System.err.println("操作异常..."); return null; } } private void mapToTable(Map map, Table table, Color one, Color two) { table.setMargin(10); table.setWidth(570); table.setFontSize(16); table.setFontColor(new DeviceRgb(136, 136, 136)); for (Map.Entry entry : map.entrySet()) { table.addCell(entry.getKey() + ": ") .setFontColor(one); String value = entry.getValue(); if (StringUtils.isBlank(value)) { value = ""; } table.addCell(new Cell() .add(new Paragraph(value)) .setFontColor(two)); } RemoveBorder(table); } private void mapToTableFault(Map map, Table table, Color one, Color two) { table.setMargin(10); table.setWidth(570); table.setFontSize(16); table.setFontColor(new DeviceRgb(136, 136, 136)); table.setWidth(UnitValue.createPercentValue(100)); // 调整宽度以适应页面 for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); FaultCode faultCode = entry.getValue(); // 将键、描述和状态添加到同一行 table.addCell(new Cell().add(new Paragraph(key)).setFontColor(one)); if (StringUtils.isNotBlank(faultCode.getDescription())){ table.addCell(new Cell().add(new Paragraph(faultCode.getDescription())).setFontColor(two)); }else { table.addCell(new Cell().add(new Paragraph()).setFontColor(two)); } if (StringUtils.isNotBlank(faultCode.getStatus())){ table.addCell(new Cell().add(new Paragraph(faultCode.getStatus())).setFontColor(two)); }else { table.addCell(new Cell().add(new Paragraph()).setFontColor(two)); } } RemoveBorder(table); } private void RemoveBorder(Table table) { for (IElement iElement : table.getChildren()) { ((Cell) iElement).setBorder(Border.NO_BORDER); } } //获取统一字体 public PdfFont getPdfFont() { PdfFont pdfFont = null; try { pdfFont = PdfFontFactory.createFont(ITextPdfUtil.FONT, PdfEncodings.IDENTITY_H, true); } catch (IOException e) { e.printStackTrace(); } return pdfFont; } }