1. 程式人生 > >java通過itext方法往pdf中插入圖片(互動式pdf插入圖片無法顯示)

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;
}