根据pdf内指定关键字的座标插入图片,实现分为两个步骤。
1:查找出dpf内所有的关键字的座标和关键字所在的页数。
2:根据查到的关键字位置出入图片;
引入
compile('com.itextpdf:itextpdf:5.5.6')
import com.itextpdf.awt.geom.Rectangle2D.Float;
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;
public class PDFUtil {
// 指定关键字
public static String KEY_WORD = "sign";
// PDF当前页数
public static int curPage = 0;
/**
* 获取指定PDF文件中指定关键字的座标
*
* @param fileByte
* @return
* @throws Exception
*/
public static List<float[]> getKeyWordCoordinate(byte [] fileByte,String keyWord) throws ServiceException {
// 座标信息集合
List<float[]> arrays = new ArrayList<>();
final int[] count = {0};
if(keyWord.toCharArray().length < 2){
throw new ServiceException(ErrorConstantsEnum.KEY_WORD_LENGTH_SMALL_TWO);
}
PdfReader pdfReader = null;
try {
pdfReader = new PdfReader(fileByte);
int pageNum = pdfReader.getNumberOfPages();
PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
for (curPage = 1; curPage <= pageNum; curPage++) {
pdfReaderContentParser.processContent(curPage, new RenderListener() {
// 关键字标志
boolean isKeyWord = false;
// PDF读出来的文字与截取关键字的第index位对比,如果在关键字的长度里
/**
* 这里从PDF中是一个一个读取文字的,把读取出来的PDF文字先和关键字的第一个字比较看是否相同:
* 如果相同,则假设已经找到关键字(将isKeyWord设为true),把这个关键字的座标存到集合里面,并计算集合里存放了多少个数据(count++)、设置进入到一个循环(loop
* = true一个循环即为关键字从第一个字到最后一个字依次和读取的PDF文字比较的过程);
* 如果在这个比较过程中发现有的字符和关键字不匹配,则移除与之对应的集合里的数据。
*/
// 关键字的第几位
int index = 0;
// 对比关键字是否进入到一个循环
boolean loop = false;
// 处理数据
public void renderText(TextRenderInfo textRenderInfo) {
String text = textRenderInfo.getText();
if (text.equals(new String(keyWord.toCharArray(), 0, 1)) && text != null) {
// 把当前从PDF文件中读取的文字横座标、纵座标和当前页存到集合里面
Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
float[] resu = new float[3];
resu[0] = boundingRectange.x;
resu[1] = boundingRectange.y;
resu[2] = curPage;
arrays.add(resu);
count[0] = count[0] + 1;
isKeyWord = true;
loop = true;
return;
}
if (isKeyWord) {
// 获取关键字中下一个字符和读取文字比较
index++;
if (index < keyWord.toCharArray().length) {
if (text.equalsIgnoreCase(new String(keyWord.toCharArray(), index, 1)) && text != null) {
isKeyWord = true;
return;
} else {
isKeyWord = false;
// 如果在一个循环中比较时,发现有字符和关键字不匹配,则移除与之对应的集合里的数据
if (loop) {
count[0]--;
arrays.remove(count[0]);
}
}
} else {
// 如果index大于关键字字符数组的长度,则该循环结束
loop = false;
}
}
index = 0;
}
public void renderImage(ImageRenderInfo arg0) {
}
public void endTextBlock() {
}
public void beginTextBlock() {
}
});
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (pdfReader != null) {
pdfReader.close();
}
}
return arrays;
}
测试方法:
//测试
public static void main(String[] args) throws Exception {
String pdfname = "D:\\目标PDF.pdf";
List<float[]> list = getKeyWordCoordinate(IOUtils.toByteArray(new FileInputStream(pdfname)),"sign");
PdfReader pdfReader = new PdfReader(new FileInputStream(pdfname));
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream("D://test/插入图片后的PDF.pdf"));
for (float[] f : list) {
System.out.println("x座标:" + f[0] + ",y座标:" + f[1] + ", 关键字所在页:" + f[2]);
// 读图片
Image image = Image.getInstance("D:\\MyData/java虚拟机内存图.jpg");
// 获取操作的页面
PdfContentByte under = pdfStamper.getOverContent((int)f[2]);
// 根据域的大小缩放图片
image.scaleAbsolute(100, 50);
// 添加图片
image.setAbsolutePosition((int) f[0], (int) f[1]);
under.addImage(image);
}
pdfStamper.close();
pdfReader.close();
}