参考博客:修改文本的
参考博客:插入图片的

这里基于修改文本的博客编写的,主要解决了几个问题:
1、文件乱码
2、设置区域背景色
3、设置文字字体颜色
4、插入图片空指针
5、指定位置插入偏移
等等问题

准备工作
1、创建一个或者自己找一个pdf。使用编辑器,编辑PDF(你也可以使用word,然后转PDF),在你期望的位置打上标记,比如我的是:${userName} 这个标记后面会被替换成文本,也是插入图片的相对位置
2、准备一个图片。 再想好操作完PDF后要输出PDF的路径

添加依赖

pom文件添加:

       <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.3</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency>

工具类

我命名为:ItextPDFUtil 。下面代码可直接粘贴

public static final float defaultHeight = 16;public static final float fixHeight = 10;/*** @description: 查找插入签名图片的最终位置,因为是插入签名图片,所以之前的关键字应只会出现一次* 这里直接使用了第一次查找到关键字的位置,并返回该关键字之后的坐标位置* @return: float[0]:页码,float[1]:最后一个字的x坐标,float[2]:最后一个字的y坐标*/public static float[] getAddImagePositionXY(String pdfName, String keyword) throws IOException {float[] temp = new float[3];List<float[]> positions = findKeywordPostions(pdfName, keyword);temp[0] = positions.get(0)[0];temp[1] = positions.get(0)[1] + positions.get(0)[3];temp[2] = positions.get(0)[2] - (positions.get(0)[3] / 2);return temp;}/*** findKeywordPostions*  返回查找到关键字的首个文字的左上角坐标值** @param pdfName* @param keyword* @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y* @throws IOException*/public static List<float[]> findKeywordPostions(String pdfName, String keyword) throws IOException {File pdfFile = new File(pdfName);byte[] pdfData = new byte[(int) pdfFile.length()];FileInputStream inputStream = new FileInputStream(pdfFile);//从输入流中读取pdfData.length个字节到字节数组中,返回读入缓冲区的总字节数,若到达文件末尾,则返回-1inputStream.read(pdfData);inputStream.close();List<float[]> result = new ArrayList<>();List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {List<float[]> charPositions = findPositions(keyword, pdfPageContentPosition);if (charPositions == null || charPositions.size() < 1) {continue;}result.addAll(charPositions);}return result;}/*** findKeywordPostions** @param pdfData 通过IO流 PDF文件转化的byte数组* @param keyword 关键字* @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y* @throws IOException*/public static List<float[]> findKeywordPostions(byte[] pdfData, String keyword) throws IOException {List<float[]> result = new ArrayList<float[]>();List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {List<float[]> charPositions = findPositions(keyword, pdfPageContentPosition);if (charPositions == null || charPositions.size() < 1) {continue;}result.addAll(charPositions);}return result;}private static List<PdfPageContentPositions> getPdfContentPostionsList(byte[] pdfData) throws IOException {PdfReader reader = new PdfReader(pdfData);List<PdfPageContentPositions> result = new ArrayList<PdfPageContentPositions>();int pages = reader.getNumberOfPages();for (int pageNum = 1; pageNum <= pages; pageNum++) {float width = reader.getPageSize(pageNum).getWidth();float height = reader.getPageSize(pageNum).getHeight();PdfRenderListener pdfRenderListener = new PdfRenderListener(pageNum, width, height);//解析pdf,定位位置PdfContentStreamProcessor processor = new PdfContentStreamProcessor(pdfRenderListener);PdfDictionary pageDic = reader.getPageN(pageNum);PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);try {processor.processContent(ContentByteUtils.getContentBytesForPage(reader, pageNum), resourcesDic);} catch (IOException e) {reader.close();throw e;}String content = pdfRenderListener.getContent();List<CharPosition> charPositions = pdfRenderListener.getcharPositions();List<float[]> positionsList = new ArrayList<float[]>();for (CharPosition charPosition : charPositions) {float[] positions = new float[]{charPosition.getPageNum(), charPosition.getX(), charPosition.getY(), charPosition.getWidth(), charPosition.getHeight()};positionsList.add(positions);}PdfPageContentPositions pdfPageContentPositions = new PdfPageContentPositions();pdfPageContentPositions.setContent(content);pdfPageContentPositions.setPostions(positionsList);result.add(pdfPageContentPositions);}reader.close();return result;}private static List<float[]> findPositions(String keyword, PdfPageContentPositions pdfPageContentPositions) {List<float[]> result = new ArrayList<float[]>();String content = pdfPageContentPositions.getContent();List<float[]> charPositions = pdfPageContentPositions.getPositions();for (int pos = 0; pos < content.length(); ) {int positionIndex = content.indexOf(keyword, pos);if (positionIndex == -1) {break;}float[] postions = charPositions.get(positionIndex);//此处较为关键通过第一个关键字计算出整个关键字的宽度for (int i = 1; i < keyword.length(); i++) {float[] postionsNew = charPositions.get(positionIndex + i);postions[3] = postions[3] + postionsNew[3];}result.add(postions);pos = positionIndex + 1;}return result;}private static class PdfPageContentPositions {private String content;private List<float[]> positions;public String getContent() {return content;}public void setContent(String content) {this.content = content;}public List<float[]> getPositions() {return positions;}public void setPostions(List<float[]> positions) {this.positions = positions;}}private static class PdfRenderListener implements RenderListener {private int pageNum;private float pageWidth;private float pageHeight;private StringBuilder contentBuilder = new StringBuilder();private List<CharPosition> charPositions = new ArrayList<CharPosition>();public PdfRenderListener(int pageNum, float pageWidth, float pageHeight) {this.pageNum = pageNum;this.pageWidth = pageWidth;this.pageHeight = pageHeight;}public void beginTextBlock() {}public void renderText(TextRenderInfo renderInfo) {List<TextRenderInfo> characterRenderInfos = renderInfo.getCharacterRenderInfos();for (TextRenderInfo textRenderInfo : characterRenderInfos) {String word = textRenderInfo.getText();if (word.length() > 1) {word = word.substring(word.length() - 1, word.length());}Rectangle2D.Float rectangle = textRenderInfo.getAscentLine().getBoundingRectange();float x = (float) rectangle.getX();float y = (float) rectangle.getY();
//                float x = (float)rectangle.getCenterX();
//                float y = (float)rectangle.getCenterY();
//                double x = rectangle.getMinX();
//                double y = rectangle.getMaxY();//这两个是关键字在所在页面的XY轴的百分比float xPercent = Math.round(x / pageWidth * 10000) / 10000f;float yPercent = Math.round((1 - y / pageHeight) * 10000) / 10000f;//                CharPosition charPosition = new CharPosition(pageNum, xPercent, yPercent);CharPosition charPosition = new CharPosition(pageNum, x, y - fixHeight, (float) rectangle.getWidth(), (float) (rectangle.getHeight() == 0 ? defaultHeight : rectangle.getHeight()));charPositions.add(charPosition);contentBuilder.append(word);}}public void endTextBlock() {}public void renderImage(ImageRenderInfo renderInfo) {}public String getContent() {return contentBuilder.toString();}public List<CharPosition> getcharPositions() {return charPositions;}}private static class CharPosition {private int pageNum = 0;private float x = 0;private float y = 0;private float width;private float height;public CharPosition(int pageNum, float x, float y, float width, float height) {this.pageNum = pageNum;this.x = x;this.y = y;this.width = width;this.height = height;}public int getPageNum() {return pageNum;}public float getX() {return x;}public float getY() {return y;}public float getWidth() {return width;}public float getHeight() {return height;}@Overridepublic String toString() {return "CharPosition{" +"pageNum=" + pageNum +", x=" + x +", y=" + y +", width=" + width +", height=" + height +'}';}}

调用的示例代码

改一下main方法的命名就可以直接测试了

public class ItextPDFUtilDemo {//输入的模版路径public static String inputFilePath = "C:\\Users\\Administrator\\Desktop\\TEST.pdf";//插入的文件路径public static String imgFilePath = "C:\\Users\\Administrator\\Desktop\\test图.png";//输出路径public static String out = "C:\\Users\\Administrator\\Desktop\\3.pdf";public static String keyword = "${userName}";//测试标记//插入图片的例子public static void main(String[] args) throws IOException, DocumentException {//查找位置float[] position= ItextPDFUtil.getAddImagePositionXY(inputFilePath,keyword);//Read file using PdfReaderPdfReader pdfReader = new PdfReader(inputFilePath);System.out.println("x:"+position[1]+" y:"+position[2]);//Modify file using PdfReaderPdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(out));Image image = Image.getInstance(imgFilePath);//Fixed Positioning
//        image.scaleToFit(100, 50);image.scaleAbsolute(100, 50);//Scale to new height and new width of imageimage.setAbsolutePosition(position[1], position[2]);System.out.println("pages:"+pdfReader.getNumberOfPages());PdfContentByte content = pdfStamper.getUnderContent((int) position[0]);content.addImage(image);pdfStamper.close();}//修改文字的示例public static void main1(String[] args) {//1.给定文件File pdfFile = new File(inputFilePath);File imgFile = new File(imgFilePath);//2.定义一个byte数组,长度为文件的长度byte[] pdfData = new byte[(int) pdfFile.length()];//3.IO流读取文件内容到byte数组FileInputStream inputStream = null;try {inputStream = new FileInputStream(pdfFile);inputStream.read(pdfData);} catch (IOException e) {e.printStackTrace();} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {}}}//4.指定关键字String replace = " 王文博 先生";//5.调用方法,给定关键字和文件List<float[]> positions = null;try {positions = ItextPDFUtil.findKeywordPostions(pdfData, keyword);} catch (IOException e) {e.printStackTrace();}PdfReader pdfReader = null;PdfStamper stamper = null;try {pdfReader = new PdfReader(pdfData);stamper = new PdfStamper(pdfReader, new FileOutputStream(out));if (positions != null) {for (int i = 0; i < positions.size(); i++) {float[] position = positions.get(i);PdfContentByte canvas = stamper.getOverContent((int) position[0]);//修改背景色canvas.saveState();BaseColor baseColor = new BaseColor(23,71,158);
//                    canvas.setColorFill(BaseColor.WHITE);canvas.setColorFill(baseColor);// canvas.setColorFill(BaseColor.BLUE);// 以左下点为原点,x轴的值,y轴的值,总宽度,总高度:
//                     canvas.rectangle(mode.getX() - 1, mode.getY(),
//                     mode.getWidth() + 2, mode.getHeight());canvas.rectangle(position[1]-1, position[2]-1, position[3]+1, position[4]+4);/* PdfGState gs = new PdfGState();gs.setFillOpacity(0.3f);// 设置透明度为0.8canvas.setGState(gs);*/canvas.fill();canvas.restoreState();//替换关键字canvas.beginText();BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);canvas.setFontAndSize(bf, 13);canvas.setTextMatrix(position[1]+3, position[2]);/*修正背景与文本的相对位置*///下面两行代码再次设置,设设置的字体的颜色BaseColor baseColor1 = new BaseColor(255,255,255);canvas.setColorFill(baseColor1);canvas.showText(replace);canvas.endText();}}} catch (IOException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();} finally {if (stamper != null)try {stamper.close();} catch (DocumentException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}if (pdfReader != null) {pdfReader.close();}}//6.返回值类型是  List<float[]> 每个list元素代表一个匹配的位置,分别为 float[0]所在页码  float[1]所在x轴 float[2]所在y轴 float[3]关键字宽度 floatt[4]关键字高度System.out.println("total:" + positions.size());if (positions != null && positions.size() > 0){for (float[] position : positions) {System.out.print("pageNum: " + (int) position[0]);System.out.print("\tx: " + position[1]);System.out.println("\ty: " + position[2]);System.out.println("\tw: " + position[3]);System.out.println("\th: " + position[4]);}}}}

使用Itext操作PDF,修改文本内容及指定位置插入图片相关推荐

  1. java pdf添加图片_java实现在pdf模板的指定位置插入图片

    本文实例为大家分享了java在pdf模板的指定位置插入图片的具体代码,供大家参考,具体内容如下 java操作pdf有个非常好用的库itextpdf,maven: com.itextpdf itextp ...

  2. java pdf域插入img_java实现在pdf模板的指定位置插入图片

    本文实例为大家分享了java在pdf模板的指定位置插入图片的具体代码,供大家参考,具体内容如下 java操作pdf有个非常好用的库itextpdf,maven: com.itextpdf itextp ...

  3. java pdf 插入图片_java实现在pdf模板的指定位置插入图片

    本文实例为大家分享了java在pdf模板的指定位置插入图片的具体代码,供大家参考,具体内容如下 java操作pdf有个非常好用的库itextpdf,maven: com.itextpdf itextp ...

  4. poi在指定位置插入图片,图片可以浮动内容上方下方

    在使用poi操作docx模板文件时,总会出现需要插入类似印章签名的图片.poi直接插入图片是插入内嵌图片 这个图片是占位置的. 会撑高当前的那一行类似效果 行使得制作出来的word样式辣眼睛. 一般印 ...

  5. ExtJS4.1.1 设置表格背景颜色 修改文本颜色 在表格中插入图片

    由于ExtJS版本不断更新,各种渲染方式也随之有所改变,目前大部分书籍还是停留在3版本,对于ExtJS4.1.1版本的表格渲染,设置表格行背景颜色的方式如下: 首先,定义行的样式: 1 .yellow ...

  6. java pdf 插入图片_java在pdf模板的指定位置插入图片

    个人感觉pdf的操作比word舒心多了 java操作pdf有个非常好用的库itextpdf,maven: com.itextpdf itextpdf 5.5.6 com.itextpdf itext- ...

  7. fme和python-docx结合实现批量按指定位置插入图片、文本等信息

    最近悟空因为项目上的需求,需要批量实现一个word邮件合并的案例,项目要求如下 1.拥有N个图斑编号命名的照片,一个含有属性信息的Excel表格,以及一个模板 当然,按照以前的思维,是可以通过word ...

  8. Pdf 插入图片 | 指定位置插入图片 不改变原格式 直接操作 pdf

    // 获得pdf页数 int pdfPage = DocUtil.getPdfPage(filePath); //指定将和 图片拼接的 PDF// 获取第一页宽和高 PdfReader pdfread ...

  9. Pdf 插入图片 | 指定位置插入图片 不改变原格式 直接操作

    直接可用 大神链接地址: https://blog.csdn.net/qq_35077107/article/details/102653651?utm_medium=distribute.pc_re ...

最新文章

  1. Windows 7 Beta(32位\64位)官方镜像文件下载
  2. nginx lua mysql 性能_深入浅出 nginx lua 为什么高性能
  3. 移除input框type=number在部分浏览器的默认上下按钮
  4. 敏捷无敌之重任在肩(7)
  5. 查看python安装位置和已安装库的相关操作
  6. Leetcode: Reorder List Summary: Reverse a LinkedList
  7. Hadoop学习笔记(基于《10小时入门大数据》)
  8. jz2440裸机开发与分析:S3c2440ARM异常与中断体系详解8---定时器中断程序示例
  9. 在线CHM阅读器(1)——CHM文件格式概述
  10. Camera2 YUV420_888
  11. 滑铁卢大学开发了一套AI工具,教泥瓦匠初学者搬砖诀窍
  12. Linux cat命令使用
  13. vue中使用require动态获取图片地址
  14. 手势操作实用教程 | 实现「滑动清除」效果
  15. 【解决方案】城市道路如何管控渣土车?EasyCVR助力搭建渣土车运输联网监控系统
  16. 阿龙的学习笔记---3.26---常用的各种树
  17. R 语言将数据的 jan 换为 1
  18. 基于微信小程序的校园自助打印系统小程序
  19. 八十年代出生人的尴尬
  20. java platform performance_Java Performance

热门文章

  1. 2020年2月北京BGP机房网络质量评测报告
  2. wireshark过滤协议大全
  3. 趋动科技猎户座OrionX AI加速器资源池化软件——产品介绍
  4. SpringBean依赖和三级缓存
  5. 分治法的基本思想与例子解析
  6. 从开始学习爬虫到真正赚钱只用了一个月——一个普通专科生的逆袭之路
  7. 新型高熵合金:谁说强度和延展性不可以相容!鱼与熊掌可以兼得!
  8. 重庆市计算机专科学校排名榜公办,2021年重庆公办大专院校名单及排名,重庆公办专科学校排名榜...
  9. 北京3加2计算机专业衔接学校,北京3+2学校名单
  10. 利用UItraISO软碟通制作U盘启动盘安装Ubuntu16.04系统