根據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();
}