pdf、ofd内容填充
1. pdf文本定位,内容图片填充
-
pdf操作依赖
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.1.7</version> <type>pom</type> </dependency>
-
代码
@Test public void test1() throws IOException { String pdfPath = "C:\\Users\\DELL\\Desktop\\xxx.pdf"; String targetPath = "C:\\Users\\DELL\\Desktop\\3.pdf"; Map<String, String> keyWords = new HashMap<>(); keyWords.put("定位文字1", "文字替换"); keyWords.put("定位文字2", "20231"); keyWords.put("定位存放图片位置", ""); //加载源文件 PdfWriter pdfWriter = new PdfWriter(targetPath); pdfWriter.setSmartMode(true); PdfReader pdfReader = new PdfReader(pdfPath); PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter); int numberOfPages = pdfDocument.getNumberOfPages(); for (int i = 1; i <= numberOfPages; i++) { PdfPage page = pdfDocument.getPage(i); //获取关键字坐标 List<IPdfTextLocation> keyWordPositions = PdfFillUtil.getKeyWordPositions(page, keyWords); if (CollectionUtils.isEmpty(keyWordPositions)) { continue; } //根据坐标覆盖替换文件 PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDocument); //设置行间距 canvas.setLineWidth(0.5f); for (IPdfTextLocation location : keyWordPositions) { float x = 0; float y = 0; if (location.getText().equals("机下关时")) { //白色遮罩层覆盖原文本 canvas.setFillColor(ColorConstants.WHITE); //修正遮罩背景位置 Rectangle rectangle = location.getRectangle(); canvas.rectangle(rectangle); canvas.fill(); y = location.getRectangle().getY() + 2; x = location.getRectangle().getX(); } else if (location.getText().equals("期限至")) { x = location.getRectangle().getX() + location.getRectangle().getWidth() + 3; y = location.getRectangle().getY() + 2; } if (location.getText().equals("(接关印)")) { PdfCanvas pdfCanvas = new PdfCanvas(pdfDocument.getPage(i)); ImageData imageData = ImageDataFactory.create("C:\\Users\\DELL\\Desktop\\showSeal.jpg"); Image image = new Image(imageData); //设置图片透明度 // PdfExtGState tranState = new PdfExtGState(); // tranState.setFillOpacity(0.4f); // pdfCanvas.saveState().setExtGState(tranState); Rectangle rectangle = new Rectangle(location.getRectangle().getX(), location.getRectangle().getY(), 80, 80); Canvas canvas1 = new Canvas(pdfCanvas, pdfDocument, rectangle); canvas1.add(image); } else { //开始文本填充 canvas.beginText(); //设置字体和大小 PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false); canvas.setFontAndSize(font, 14); canvas.setFillColor(ColorConstants.BLACK); //修正填充文字位置 canvas.setTextMatrix(x, y); Optional<Map.Entry<String, String>> first = keyWords.entrySet().stream().filter(item -> item.getKey().equals(location.getText())).findFirst(); canvas.showText(first.get().getValue()); //结束文本填充 canvas.endText(); canvas.closePath(); } } } pdfDocument.close(); pdfWriter.close(); pdfReader.close(); }
public class PdfFillUtil { public static void fillPdf(OutputStream outputStream, InputStream inputStream, List<FillVo> fillVos) throws IOException, SQLException { //加载源文件 PdfWriter pdfWriter = new PdfWriter(outputStream); pdfWriter.setSmartMode(true); PdfDocument pdfDocument = new PdfDocument(new PdfReader(inputStream), pdfWriter); //根据页数分组,分页填充 Map<Integer, List<FillVo>> collect = fillVos.stream() .sorted(Comparator.comparing(FillVo::getPage)).collect(Collectors.groupingBy(FillVo::getPage)); //根据Key页数值填充数据 for (Map.Entry<Integer, List<FillVo>> val : collect.entrySet()) { Integer key = val.getKey(); List<FillVo> fillConfig = val.getValue(); for (FillVo fillVo : fillConfig) { if (key != null) { PdfPage page = pdfDocument.getPage(key); //获取关键字坐标 IPdfTextLocation keyWordPosition = getKeyWordPosition(page, fillVo.getKeyWord()); fillVo.setiPdfTextLocation(keyWordPosition); } } } for (FillVo fillVo : fillVos) { extracted(pdfDocument, fillVo); } pdfDocument.close(); pdfWriter.close(); outputStream.close(); inputStream.close(); } private static void extracted(PdfDocument pdfDocument, FillVo fillVo) throws IOException, SQLException { PdfPage page = pdfDocument.getPage(fillVo.getPage()); //获取关键字坐标 IPdfTextLocation keyWordPosition = fillVo.getiPdfTextLocation(); if (keyWordPosition == null) { return; } //文字填充X坐标 float positionX = keyWordPosition.getRectangle().getX() + Float.parseFloat(fillVo.getShiftX()); //根据规则,看是否正向,反向偏移关键词长度坐标 positionX = KeyWidthMoveEnum.calculatePosition(positionX, fillVo.getKeywordWidthX(), keyWordPosition.getRectangle().getWidth()); //获取Y坐标 float positionY = keyWordPosition.getRectangle().getY() + Float.parseFloat(fillVo.getShiftY()); //判断是否是靠边框,需要动态测距 if (CommonEnum.IS_TRUE.getCode().equals(fillVo.getIsBorderFill())) { //页面最右侧坐标,减去空白宽度,计算实际内容最右侧坐标 float contentRight = page.getPageSize().getRight() - Float.parseFloat(fillVo.getConPageDic()); //X坐标超出最右侧内容宽度,则进行换行 if (positionX > contentRight) { positionX = positionX - contentRight + Float.parseFloat(fillVo.getConPageDic()); positionY = positionY - Float.parseFloat(fillVo.getRowSpacing()); } //X坐标超出最左侧坐标内容宽度,则向上进行换行 if (positionX < Float.parseFloat(fillVo.getConPageDic())) { positionX = contentRight - positionX; positionY = positionY + Float.parseFloat(fillVo.getRowSpacing()); } } //根据坐标覆盖替换文件 PdfCanvas canvas = new PdfCanvas(page.setIgnorePageRotationForContent(true).newContentStreamAfter(), page.getResources(), pdfDocument); //设置行间距 canvas.setLineWidth(0.5f); //白色覆盖原字 // canvas.setFillColor(ColorConstants.WHITE); //修正遮罩背景位置 // Rectangle rectangle = keyWordPosition.getRectangle(); // canvas.rectangle(rectangle); // canvas.fill(); if (fillVo.isSign() && fillVo.getSign() == null) { return; } //开始文本填充 canvas.beginText(); //公章填充 if (fillVo.isSign()) { byte[] bytes = FileUtil.BlobToBytes(fillVo.getSign()); ImageData imageData = ImageDataFactory.create(bytes); // imageData.setWidth(80); // imageData.setHeight(80); // canvas.addImage(imageData, positionX, positionY, false); Image image = new Image(imageData); image.setTextAlignment(TextAlignment.JUSTIFIED); Rectangle rectangle = new Rectangle(positionX, positionY, 85, 85); PdfExtGState tranState = new PdfExtGState(); tranState.setFillOpacity(0.4f); canvas.saveState().setExtGState(tranState); new Canvas(canvas, pdfDocument, rectangle) .setFontColor(ColorConstants.LIGHT_GRAY) .add(image); // ImageData imageData = ImageDataFactory.create("C:\\Users\\DELL\\Desktop\\公章截图.jpg"); // Image image = new Image(imageData); // image.setTextAlignment(TextAlignment.JUSTIFIED); // Rectangle rectangle = new Rectangle(positionX, positionY, 80, 80); // // PdfExtGState tranState = new PdfExtGState(); // tranState.setFillOpacity(0.4f); // canvas.saveState().setExtGState(tranState); // new Canvas(canvas, pdfDocument, rectangle) // .setFontColor(ColorConstants.LIGHT_GRAY) // .add(image); } else { //设置字体和大小 PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false); canvas.setFontAndSize(font, Float.parseFloat(fillVo.getFontSize())); canvas.setFillColor(ColorConstants.BLACK); //修正填充文字位置 canvas.setTextMatrix(positionX, positionY); canvas.showText(fillVo.getReplaceWord()); } //结束文本填充 canvas.endText(); } /** * @return * @Author xiangyong.zeng * @Description 获取关键词坐标位置 * @Date 16:30 2023/2/22 * @Param **/ public static List<IPdfTextLocation> getKeyWordPositions(PdfPage page, Map<String, String> keyWords) { List<IPdfTextLocation> locations = new ArrayList<>(); for (Map.Entry<String, String> val : keyWords.entrySet()) { RegexBasedLocationExtractionStrategy strategy = new RegexBasedLocationExtractionStrategy(val.getKey()); PdfCanvasProcessor canvasProcessor = new PdfCanvasProcessor(strategy); canvasProcessor.processPageContent(page); Collection<IPdfTextLocation> resultantLocations = strategy.getResultantLocations(); locations.addAll(resultantLocations); } return locations; } /** * @return * @Author xiangyong.zeng * @Description 获取关键词坐标位置 * @Date 16:30 2023/2/22 * @Param **/ public static IPdfTextLocation getKeyWordPosition(PdfPage page, String keyWord) { RegexBasedLocationExtractionStrategy strategy = new RegexBasedLocationExtractionStrategy(keyWord); PdfCanvasProcessor canvasProcessor = new PdfCanvasProcessor(strategy); canvasProcessor.processPageContent(page); List<IPdfTextLocation> resultantLocations = (List<IPdfTextLocation>) strategy.getResultantLocations(); if (CollectionUtils.isEmpty(resultantLocations)) { return null; } return resultantLocations.get(0); }
2. ofd文本定位,内容图片填充
-
ofd依赖
参考:https://gitee.com/ofdrw/ofdrw#/ofdrw/ofdrw/blob/master/ofdrw-full
<dependency> <groupId>org.ofdrw</groupId> <artifactId>ofdrw-full</artifactId> <version>1.20.2</version> </dependency>
-
ofd定位填充代码
@Test public void testTemplateTextBaseKeyword() throws IOException, DocumentException { Path inP = Paths.get("C:\\Users\\DELL\\Desktop\\xxxxx.ofd"); Path outP = Paths.get("C:\\Users\\DELL\\Desktop\\32.ofd"); try (OFDReader reader = new OFDReader(inP); OFDDoc ofdDoc = new OFDDoc(reader, outP)) { String t1 = "定位文字1"; String f1 = "替换文本"; String t2 = "定位文字2"; String[] keywords = {t1, t2}; List<KeywordPosition> positionList = KeywordExtractor.getKeyWordPositionList(reader, keywords); //偏移量需要模板制作确认 float offset = 5; Annotation annotation = null; int num = 0; for (KeywordPosition position : positionList) { //创建可追加的虚拟页面 AdditionVPage page = ofdDoc.getAVPage(position.getPage()); //创建一个可以自动换行的段落 Paragraph paragraph = new Paragraph(); paragraph.setPosition(Position.Absolute) .setWidth(f1.length() * 5.0).setHeight(10D) //设置外接矩形宽高 .setX(position.getBox().getTopLeftX() + position.getBox().getWidth() + offset) //设置x坐标 .setY(position.getBox().getTopLeftY() + 1); //设置y坐标 //创建 Span 文本控件对象 Span span = null; if (t1.equals(position.getKeyword())) { span = new Span(f1); //设置Span的属性 span.setFontSize(5.0); span.setColor(0, 0, 0); //段落添加Span文本控件 paragraph.add(span); //页面添加段落 page.add(paragraph); } num++; if (num == 2) { Double width = ofdDoc.getPageLayout().getWidth(); Double height = ofdDoc.getPageLayout().getHeight(); annotation = new Annotation(new ST_Box(0d, 0d, width, height), AnnotType.Watermark, ctx -> { ctx.drawImage(Paths.get("C:\\Users\\DELL\\Desktop\\2222.jpg"), position.getBox().getTopLeftX(), position.getBox().getTopLeftY() - 20, 40, 40); ctx.restore(); }); } } //水印添加页 ofdDoc.addAnnotation(3, annotation); } }
3. pdf复制拆分
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.7</version>
<type>pom</type>
</dependency>
public static void main(String[] args) throws IOException {
PdfReader pdfReader = new PdfReader("C:\\Users\\DELL\\Desktop\\换xxx.pdf");
PdfDocument pdfDocument = new PdfDocument(pdfReader);
PdfWriter pdfWriter = new PdfWriter("C:\\Users\\DELL\\Desktop\\test111.pdf");
PdfDocument outPdfDocument = new PdfDocument(pdfWriter);
pdfDocument.copyPagesTo(1, 1, outPdfDocument);
//关闭
outPdfDocument.close();
pdfWriter.close();
pdfDocument.close();
pdfReader.close();
}