PDFBoxService.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package com.example.demo.service;
  2. import com.example.demo.model.*;
  3. import org.apache.pdfbox.Loader;
  4. import org.apache.pdfbox.cos.COSName;
  5. import org.apache.pdfbox.pdmodel.PDDocument;
  6. import org.apache.pdfbox.pdmodel.PDPage;
  7. import org.apache.pdfbox.pdmodel.PDPageContentStream;
  8. import org.apache.pdfbox.pdmodel.PDResources;
  9. import org.apache.pdfbox.pdmodel.common.PDRectangle;
  10. import org.apache.pdfbox.pdmodel.font.PDFont;
  11. import org.apache.pdfbox.pdmodel.font.PDType0Font;
  12. import org.apache.pdfbox.pdmodel.font.PDType1Font;
  13. import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
  14. import org.apache.pdfbox.pdmodel.graphics.PDXObject;
  15. import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
  16. import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
  17. import org.apache.pdfbox.text.PDFTextStripper;
  18. import org.apache.pdfbox.util.Matrix;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.stereotype.Service;
  21. import javax.imageio.ImageIO;
  22. import java.awt.*;
  23. import java.awt.image.BufferedImage;
  24. import java.io.File;
  25. import java.math.BigDecimal;
  26. import java.math.RoundingMode;
  27. import java.util.List;
  28. @Service
  29. public class PDFBoxService {
  30. @Autowired
  31. private GetPictureNumService getPictureNumService;
  32. @Autowired
  33. private DifyService difyService;
  34. public void test() throws Exception {
  35. PDDocument document = Loader.loadPDF(new File("D:\\demo\\file2\\202410725352_CN118294200A.pdf"));
  36. String instruction = this.getPatentInstruction(document);
  37. // List<DifyGetNumVO> difyGetNumVOS = difyService.getAn();
  38. List<DifyGetNumVO> difyGetNumVOS = difyService.getAnswerFromAI(instruction);
  39. int pageNum = 0;
  40. Integer a = document.getNumberOfPages();
  41. System.out.println(a);
  42. for (int pageIndex = 0; pageIndex < document.getNumberOfPages(); pageIndex++) {
  43. PDPage page = document.getPage(pageIndex);
  44. PDResources resources = page.getResources();
  45. // 遍历页面资源中的图片对象
  46. for (COSName name : resources.getXObjectNames()) {
  47. PDXObject xObject = resources.getXObject(name);
  48. if (xObject instanceof PDFormXObject) {
  49. PDFormXObject pdFormXObject = (PDFormXObject) xObject;
  50. PDResources resources2 = pdFormXObject.getResources();
  51. for (COSName name1 : resources2.getXObjectNames()) {
  52. PDXObject xObject2 = resources2.getXObject(name1);
  53. if (xObject2 instanceof PDImageXObject) {
  54. PDImageXObject oldImage = (PDImageXObject) xObject2;
  55. BufferedImage bufferedImage = oldImage.getImage();
  56. String path = "D:\\demo\\file2\\temp_roi" + pageNum + ".jpg";
  57. // ✅ 关键1:获取原图位置和尺寸
  58. File file = new File(path);
  59. ImageIO.write(bufferedImage, "jpg", file);
  60. getPictureNumService.drawPictures(path, difyGetNumVOS);
  61. PDImageXObject newImage = PDImageXObject.createFromFile(path, document);
  62. syncImageProperties(oldImage, newImage);
  63. pageNum++;
  64. resources2.put(name1, newImage);
  65. }
  66. }
  67. }
  68. }
  69. }
  70. document.save(new File("D:\\demo\\file2\\temp_roi41.pdf"));
  71. document.close();
  72. }
  73. private static void syncImageProperties(PDImageXObject src, PDImageXObject dest) throws Exception {
  74. dest.setWidth(src.getWidth());
  75. dest.setHeight(src.getHeight());
  76. dest.setColorSpace(src.getColorSpace());
  77. dest.setBitsPerComponent(src.getBitsPerComponent());
  78. if (src.getMetadata() != null) {
  79. dest.setMetadata(src.getMetadata());
  80. }
  81. }
  82. /**
  83. * 提取pdf具体实施方式部分
  84. */
  85. public String getPatentInstruction(PDDocument document) throws Exception {
  86. Integer numberOfPages = document.getNumberOfPages();
  87. StringBuilder stringBuilder = new StringBuilder();
  88. boolean ifAddText = false;
  89. for (int i = 7; i < numberOfPages; i++) {
  90. PDPage page = document.getPage(i);
  91. // 提取页面文本
  92. PDFTextStripper textStripper = new PDFTextStripper();
  93. textStripper.setStartPage(i + 1);
  94. textStripper.setEndPage(i + 1);
  95. String pageText = textStripper.getText(document);
  96. if (pageText != null) {
  97. String targetText = "具体实施方式";
  98. if (ifAddText) {
  99. stringBuilder.append(pageText);
  100. } else if (pageText.contains(targetText)) {
  101. Integer index = pageText.indexOf("具体实施方式");
  102. pageText = pageText.substring(index + targetText.length());
  103. stringBuilder.append(pageText);
  104. ifAddText = true;
  105. }
  106. }
  107. }
  108. return stringBuilder.toString();
  109. }
  110. public void test2() throws Exception {
  111. PDDocument document = Loader.loadPDF(new File("D:\\demo\\file2\\202410725352_CN118294200A.pdf"));
  112. String instruction = this.getPatentInstruction(document);
  113. List<DifyGetNumVO> difyGetNumVOS = difyService.getAn();
  114. // List<DifyGetNumVO> difyGetNumVOS = difyService.getAnswerFromAI(instruction);
  115. int pageNum = 0;
  116. Integer a = document.getNumberOfPages();
  117. System.out.println(a);
  118. for (int pageIndex = 0; pageIndex < document.getNumberOfPages(); pageIndex++) {
  119. PDPage page = document.getPage(pageIndex);
  120. PDResources resources = page.getResources();
  121. ImageCoordinateExtractor locator = new ImageCoordinateExtractor();
  122. locator.processPage(page);
  123. List<PicturePositionVO> picturePositionVOList = locator.picturePositionVOList;
  124. // 遍历页面资源中的图片对象
  125. for (COSName name : resources.getXObjectNames()) {
  126. PDXObject xObject = resources.getXObject(name);
  127. if (xObject instanceof PDFormXObject) {
  128. PDFormXObject pdFormXObject = (PDFormXObject) xObject;
  129. PDResources resources2 = pdFormXObject.getResources();
  130. for (COSName name1 : resources2.getXObjectNames()) {
  131. PDXObject xObject2 = resources2.getXObject(name1);
  132. if (xObject2 instanceof PDImageXObject) {
  133. PDImageXObject oldImage = (PDImageXObject) xObject2;
  134. BufferedImage bufferedImage = oldImage.getImage();
  135. Integer imgWidth = bufferedImage.getWidth();
  136. Integer imgHeight = bufferedImage.getHeight();
  137. PicturePositionVO picturePositionVO = picturePositionVOList.stream().filter(item -> item.getPdImageXObject().equals(xObject2)).findFirst().orElse(null);
  138. Float basex=picturePositionVO.getX();
  139. Float basey=picturePositionVO.getY();
  140. String path = "D:\\demo\\file2\\temp_roi" + pageNum + ".jpg";
  141. // ✅ 关键1:获取原图位置和尺寸
  142. File file = new File(path);
  143. ImageIO.write(bufferedImage, "jpg", file);
  144. if (picturePositionVO != null) {
  145. List<DrawMessVO> drawMessVOList = getPictureNumService.getPDFDrawMessVO(path, difyGetNumVOS);
  146. for (DrawMessVO drawMessVO : drawMessVOList) {
  147. drawMessVO = getPictureNumService.getTextDrawMessVO(drawMessVO, imgWidth);
  148. Integer textSize=drawMessVO.getTextSize()*72/300;
  149. TextPositionVO textPositionVO= this.getTextPositionVO(drawMessVO,imgWidth,imgHeight,picturePositionVO.getWidth(),picturePositionVO.getHeight());
  150. addTextBox(document, page, new BigDecimal(basex.toString()).add(new BigDecimal(textPositionVO.getX().toString())).floatValue(), new BigDecimal(basey.toString()).add(new BigDecimal(textPositionVO.getY().toString())).floatValue(), drawMessVO.getValue(), "D:\\demo\\src\\main\\resources\\font\\simsun.ttf", textSize, Color.RED);
  151. }
  152. }
  153. pageNum++;
  154. }
  155. }
  156. }
  157. }
  158. }
  159. document.save(new File("D:\\demo\\file2\\temp_roi41.pdf"));
  160. document.close();
  161. }
  162. private static void addTextBox(PDDocument doc, PDPage page, float x, float y,
  163. String text, String fontPath, int fontSize, Color color) throws Exception {
  164. // PDType0Font font = PDType0Font.load(doc, new File(fontPath));
  165. PDFont customFont = PDType0Font.load(doc,new File(fontPath));
  166. try (PDPageContentStream cs = new PDPageContentStream(doc, page,
  167. PDPageContentStream.AppendMode.APPEND, true)) {
  168. cs.setFont(customFont, fontSize);
  169. cs.setNonStrokingColor(color);
  170. cs.beginText();
  171. cs.newLineAtOffset(x, y);
  172. cs.showText(text);
  173. cs.endText();
  174. }
  175. }
  176. public TextPositionVO getTextPositionVO(DrawMessVO drawMessVO, Integer imgWidth, Integer imgHeight, Float pdfImgWidth, Float pdfImgHeight) {
  177. Integer tx = drawMessVO.getX1();
  178. Integer ty = drawMessVO.getY1();
  179. Float a = new BigDecimal(tx.toString()).divide(new BigDecimal(imgWidth.toString()),10, RoundingMode.HALF_UP).multiply(new BigDecimal(pdfImgWidth.toString())).floatValue();
  180. // float a=tx/imgWidth*pdfImgWidth;
  181. Float c = new BigDecimal(imgHeight.toString()).subtract(new BigDecimal(ty.toString())).floatValue();
  182. Float b = new BigDecimal(c.toString()).divide(new BigDecimal(imgHeight.toString()),10, RoundingMode.HALF_UP).multiply(new BigDecimal(pdfImgHeight.toString())).floatValue();
  183. // float b = (imgHeight - ty - drawMessVO.getHeight()) / imgHeight * pdfImgHeight;
  184. TextPositionVO textPositionVO = new TextPositionVO();
  185. textPositionVO.setX(a);
  186. textPositionVO.setY(b);
  187. return textPositionVO;
  188. }
  189. }