一 简介

因公司业务需求需要做一个生成PDF的功能,采用的是html+freemarker来实现的。其中由于内容是变动的,需要确定签章图片的绝对位置,故选择找到附近关键字的坐标,从而来确定盖章位置。

二 项目依赖

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.2</version>
</dependency>

三 测试代码

package pdf;import com.itextpdf.awt.geom.Rectangle2D.Float;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;import java.io.IOException;
import java.util.Arrays;/*** 获取PDF相对位置,从而确定签章位置** @author yinxinyao* @date 2019/5/20 14:44*/
public class GetPositionTest {public static void main(String[] args) throws Exception {String filePath = "C:\\Users\\Desktop\\hello.pdf";String KEY_WORD = "签章:";Integer[] fontPosition = getFontPosition(filePath, KEY_WORD, null);System.out.println(Arrays.toString(fontPosition));}/*** 根据pdf中的关键字,获取文字的绝对位置,从而确定签章位置** @param filePath pdf文件的绝对地址* @param filePath pdf中的关键字* @param pageNum  pdf页数,可传null,默认设置最大页数* @return x与y值* @throws IOException*/private static Integer[] getFontPosition(String filePath, final String keyWord, Integer pageNum) throws IOException {final Integer[] result = new Integer[2];PdfReader pdfReader = new PdfReader(filePath);if (null == pageNum) {pageNum = pdfReader.getNumberOfPages();}new PdfReaderContentParser(pdfReader).processContent(pageNum, new RenderListener() {public void beginTextBlock() {}public void renderText(TextRenderInfo textRenderInfo) {String text = textRenderInfo.getText();System.out.println("text is :" + text);if (text != null && text.contains(keyWord)) {// 文字在page中的横坐标、纵坐标Float textFloat = textRenderInfo.getBaseline().getBoundingRectange();float x = textFloat.x;float y = textFloat.y;result[0] = (int) x;result[1] = (int) y;System.out.println(String.format("签章文字域绝对位置为x:%s,y:%s", x, y));}}public void endTextBlock() {}public void renderImage(ImageRenderInfo renderInfo) {}});return result;}
}

四 整合加载签章图片功能

import com.itextpdf.awt.geom.Rectangle2D;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;import java.io.FileOutputStream;
import java.io.IOException;/*** @author yinxinyao* @date 2019/5/21 14:42*/
public class AddSignImg {public static void main(String[] args) throws IOException, DocumentException {// 模板文件路径String templatePath = "C:\\Users\\yinxinyao\\Desktop\\part1.pdf";// 生成的文件路径String targetPath = "C:\\Users\\yinxinyao\\Desktop\\part2.pdf";// 图片路径, 需要png透明图片,否则会覆盖文字String imagePath = "C:\\Users\\yinxinyao\\Desktop\\FC001.gif";addSignImg(templatePath, targetPath, imagePath, "签章", null);}/*** 根据pdf中的关键字,获取文字的绝对位置,并进行签章** @param inputPath  未处理pdf* @param targetPath 已签章pdf地址* @param imagePath  签章图片地址* @param inputPath  pdf中的关键字* @param pageNum    pdf页数,可传null,默认设置最大页数* @return float的x与y值* @throws IOException*/private static void addSignImg(String inputPath, String targetPath, final String imagePath, final String keyWord, Integer pageNum) throws IOException, DocumentException {PdfReader pdfReader = new PdfReader(inputPath);// 读图片final Image image = Image.getInstance(imagePath);// 根据域的大小缩放图片image.scaleToFit(120, 120);if (null == pageNum) {pageNum = pdfReader.getNumberOfPages();}new PdfReaderContentParser(pdfReader).processContent(pageNum, new RenderListener() {public void beginTextBlock() {}public void renderText(TextRenderInfo textRenderInfo) {String text = textRenderInfo.getText();if (text != null && text.contains(keyWord)) {// 文字在page中的横坐标、纵坐标Rectangle2D.Float textFloat = textRenderInfo.getBaseline().getBoundingRectange();float x = textFloat.x;float y = textFloat.y;// 设置图片位置image.setAbsolutePosition(x + 50f, y - 30f);}}public void endTextBlock() {}public void renderImage(ImageRenderInfo renderInfo) {}});// 获取操作的页面PdfStamper stamper = new PdfStamper(pdfReader, new FileOutputStream(targetPath));PdfContentByte under = stamper.getOverContent(pageNum);under.addImage(image);stamper.close();pdfReader.close();}
}

使用itextpdf进行动态盖章,解决PDF页数不确定时签章位置变化问题相关推荐

  1. php判断pdf页码,PHP_PHP简单读取PDF页数的实现方法,本文实例讲述了PHP简单读取PDF - phpStudy...

    PHP简单读取PDF页数的实现方法 本文实例讲述了PHP简单读取PDF页数的实现方法.分享给大家供大家参考,具体如下: 还是老外比较厚道, 在老外的网站找到了这样一个方法, 我写成了一个函数, 再将函 ...

  2. python 统计pdf页数

    python 统计pdf页数 import os import PyPDF2 import sys, jm, traceback from PyQt5.QtWidgets import QApplic ...

  3. php获取pdf文件页数,PHP简单读取PDF页数的实现方法

    搜索热词 本文实例讲述了PHP简单读取PDF页数的实现方法.分享给大家供大家参考,具体如下: 还是老外比较厚道,在老外的网站找到了这样一个方法, 我写成了一个函数,再将函数写进自己的LeeLib库里的 ...

  4. python获取pdf页数_Python分割指定页数的pdf文件方法

    Python分割指定页数的pdf文件方法 如下所示: from PyPDF2 import PdfFileWriter, PdfFileReader # 开始页 start_page = 0 # 截止 ...

  5. java读取PDF页数

    1.首先导入依赖jar包 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdf ...

  6. python获取pdf页数_Python读取pdf页面的一部分

    假设您使用的是pdfminer和pypdf2,那么我假设所讨论的PDF文件是生成的PDF而不是扫描的(如您所给出的示例中所示).如果您知道以英寸为单位的列和行的大小,您可以使用^{}(完全公开:我写了 ...

  7. PDF页数太多,怎么拆分成几个PDF

    现在很多资料都是以PDF存在的.有的时候一篇PDF太长,读起来会非常费劲,会大量消耗我们的时间,降低办公的效率.所以,如果能将PDF拆分成几个部分就好了.那么,PDF怎么拆分成几份呢?今天就给大家分享 ...

  8. PYTHON得到pdf页数、遍历当前文件夹

    #第一步安装PyPDF2 pip install PyPDF2#第二步导入相应的模块 from PyPDF2 import PdfFileReader#第三步:定义相对应的函数 def get_num ...

  9. html打印自动生成页数,打印html时打印页面上的页码

    由于@page与pagenumbers在浏览器不工作现在我正在寻找替代品. 我发现Oliver Kohll发布了一个 answer. 我会在这里转贴,所以每个人都可以更容易地找到它: 对于这个答案,我 ...

  10. Excel表格转成PDF后页数变多有空白页怎么办?

    有些时候我们用表格统计大量数据后,会使用一些公式进行计算汇总等,但由于Excel的易被修改特性,为了避免发生错误一般会将表格转成PDF保存,但有时转换成的PDF页数却比原来多了很多,而且很多空白页是怎 ...

最新文章

  1. SAS、R以及SPSS的比较__统计语言大战
  2. Ogre 2011-11-29
  3. 【Python-ML】SKlearn库线性回归器LinearRegression
  4. Linq To Xml学习 - 1.LINQ to XML 概述
  5. 批处理文件将多台连接的手机安装同一个APP
  6. java异常 The origin server did not find a current representation for the target resource or is not
  7. 3分钟,看回归分析模型怎么做
  8. am335x PDK3.0 设置为单网口配置记录
  9. GetVersionEx 获取系统版本信息
  10. 【深度学习框架】Tensorflow Session.run()函数的进一步理解
  11. Python 深度学习库 Keras 发布官方中文文档,这里有你需要了解的一切
  12. Hadoop学习总结(2)——Hadoop入门详解
  13. GitHub五万星中文资源:命令行技巧大合集,新老司机各取所需
  14. [交互设计工具/原型创作工具]Axure RP Pro 5.0新特性 破解版 注册码
  15. Spring通过注解装配Bean
  16. 设计模式-第五篇之命令模式
  17. 百度离线地图瓦片图制作
  18. 一行代码实现F11的功能,即让浏览器窗口全屏
  19. 如何提高C语言程序的可读性
  20. javase_20(Awt初步认识)

热门文章

  1. 中二青年付杰的逆袭故事:从二本生到 ICLR 杰出论文奖,我用了20年
  2. FreeMarker源码分析(八)
  3. CM311-1a YST(2G+16G)刷Armbian后的网络设置
  4. Cassandra启动过程详解
  5. 标准盒子模型和IE盒子模型的区别
  6. MySQL数据库报错:no database selected
  7. 工业计算机控制系统的分类,工业自动化系统组成和产品分类介绍
  8. 看看最新BTA大厂的Java程序员的招聘技术标准,Java篇
  9. 对未来技术方向的思考
  10. Ruby电子书教程、经典脚本合集