java通過itext方法往pdf中插入圖片(互動式pdf插入圖片無法顯示)
本文參考自: 原文地址
一、:首先明確pdf的型別,在自己的開發過程中發現pdf也分幾種型別。
我目前這裡就指出常用兩種:
一種是互動式pdf,他的元件可以讀取,可以被編輯,比如liveCycle(Adobe LiveCycle Designer ES2)一款用於編輯pdf的軟體。 (如果強行執行插入方法,不會報錯,pdf記憶體也變大,但是就是無法看到圖片)
一種是靜態pdf,它裡面的元件可以讀取,不可編輯。
二、往pdf插入圖片的兩種方式
插入圖片需要對插入位置進行定位,這就有兩種方式
1:獲取元件名,以元件為中心進行插入。同時可以將圖片大小適應元件大小(比如我獲取pdf一個簽章域的名字)
public static void main(String[] args) throws Exception {
// 模板檔案路徑
String templatePath = "E://source.pdf";
// 生成的檔案路徑
String targetPath = "E://out.pdf";
// 關鍵字名
String fieldName = "SignatureField1";
// 圖片路徑
String imagePath = "E://00.jpg";
FileOutputStream fos = new FileOutputStream(targetPath);
// 讀取模板檔案
InputStream input = new FileInputStream(new File(templatePath));
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, fos);
// 提取pdf中的表單
AcroFields form = stamper.getAcroFields();
form.addSubstitutionFont(BaseFont.createFont("STSong-Light","UniGB-UCS2-H", BaseFont.NOT_EMBEDDED));
// 通過域名獲取所在頁和座標,左下角為起點
int pageNo = form.getFieldPositions(fieldName).get(0).page;
Rectangle signRect = form.getFieldPositions(fieldName).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
//x = 20f;
//y = 40f;
// 讀圖片
Image image = Image.getInstance(imagePath);
// 獲取操作的頁面
PdfContentByte under = stamper.getOverContent(pageNo);
// 根據域的大小縮放圖片
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 新增圖片
image.setAbsolutePosition(x, y);
under.addImage(image);
fos.flush();
fos.close();
/*stamper.close();*/
reader.close();
}
2:關鍵字簽章,該方式是讀取pdf裡面的文字,以文字為中心進行定位。其實和上面差不多,只是定位方式變化了而已。
public static byte[] signPdfByStampKeyNocert(Object source, URL imagePath, String stampKey) throws Exception {
//source:待插入圖片的pdf ,imagePath :待插入圖片 , stampKey:關鍵字(比如 “圖片插入在我這”)
// 臨時檔案路徑
String targetPath = "E://source.pdf";
// 讀取模板檔案
PdfReader reader = null;
if(source instanceof String){
reader = new PdfReader((String)source);
}else if(source instanceof byte[]){
reader = new PdfReader((byte[])source);
}else if(source instanceof URL){
reader = new PdfReader((URL)source);
}
byte [] by1 = null;
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(targetPath));
// 則使用座標籤章,獲取關鍵字的各類引數 (這個方法我整合了,各位可自行查詢)
Map<String, Object> params = PDFUtil.getSignaturePostionInfo(reader, imagePath, stampKey);
// 關鍵字
Rectangle signRect = (Rectangle) params.get("sign8PositionRectangle");
// 獲取圖片的絕對位置,距離
float x = signRect.getLeft();
float y = signRect.getBottom();
// 獲取關鍵字所在頁碼
int pageno = (int) params.get("sign8PositionKeywordsPageIndex");
// 獲取操作的頁面
PdfContentByte overContent = stamper.getOverContent(pageno);
Image image = Image.getInstance(imagePath);
// 設定圖片寬高
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// image.scaleAbsolute(x, y);
// 設定圖片位置
image.setAbsolutePosition(x, y);// 左邊距、底邊距
overContent.addImage(image);
overContent.stroke();
stamper.close();
reader.close();
byte [] bytes = FileUtil.getFile(targetPath);
FileUtil.delFile(targetPath);
return bytes;
}