java根據模板匯出pdf(動態增加模板頁數)
阿新 • • 發佈:2018-12-15
這兩天碰到了一個根據模板匯出pdf的需求,研究了幾天以後,發現網上的資料不太齊全,主要是沒找到既根據模板匯出,又可以動態增加頁數的例子。只能通過各種資料結合來實現這個需求了(其實是懶得看iText英文文件,這個以後得改過來)。 下面先來說下pdf匯出主要的兩種方式: 1.直接使用iText的api,寫出原生的pdf文件,但是樣式和排版很難控制,比較方便的是,可以動態的新增文件資料,還可以增加頁數等操作。關於樣式和排版可以通過結合XmlWorker,從HTML模板生成PDF。 2.根據pdf模板匯出,這裡會涉及到使用adobe acrobat這個軟體。通過adobe acrobat來製作表單域,然後在應用程式裡動態向表單域新增資料。 (1)在adobe acrobat中開啟一個pdf文件,然後點選右側的“準備表單”,選擇檔案後點擊“開始” 圖片步驟為:
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.6</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> </dependency>
(1)多頁匯出,包含圖片。如果匯出的中文無法顯示,需要重新設定字型。
import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.*; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class PdfTest { // 利用模板生成pdf public static void fillTemplate() { // 原pdf模板路徑 String templatePath = "D:/old.pdf"; // 生成的新檔案路徑 String newPDFPath = "D:/new.pdf"; //圖片路徑 String imgPath = "D:/test.jpg"; FileOutputStream out; int num = 2;//頁數 ByteArrayOutputStream bos[] = new ByteArrayOutputStream[num]; try { out = new FileOutputStream(newPDFPath);// 輸出流 Document doc = new Document(); //新建一個文件 PdfCopy copy = new PdfCopy(doc, out); //用於儲存原頁面內容,然後輸出 doc.open(); for (int i = 0; i < num; i++) { bos[i] = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(templatePath);// 讀取pdf模板 PdfStamper stamper = new PdfStamper(reader, bos[i]); //生成輸出流 AcroFields form = stamper.getAcroFields(); //獲取文字域 form.setField("title", "這是標題"); int pageNo = form.getFieldPositions("img").get(0).page; Rectangle rectangle = form.getFieldPositions("img").get(0).position; float x = rectangle.getLeft(); float y = rectangle.getBottom(); //根據路徑讀取圖片 Image image = Image.getInstance("D:/test.jpg"); //獲取圖片頁面 PdfContentByte under = stamper.getOverContent(pageNo); //圖片大小自適應 image.scaleToFit(rectangle.getWidth(), rectangle.getHeight()); //新增圖片 image.setAbsolutePosition(x, y); under.addImage(image); stamper.setFormFlattening(true);// 如果為false那麼生成的PDF檔案還能編輯,一定要設為true stamper.close(); } PdfImportedPage page = null; for (int i = 0; i < num; i++) { page = copy.getImportedPage(new PdfReader(bos[i].toByteArray()), i + 1); copy.addPage(page); } doc.close(); out.close(); } catch (IOException e) { System.out.println("匯出異常"); } catch (DocumentException e) { System.out.println("文件異常"); } } public static void main(String[] args) { fillTemplate(); } }
(2)此時的需求是需要根據應用程式,動態複製第二頁的模板,那麼程式碼改為下面這種
// 利用模板生成pdf
public static void fillTemplate() {
// 原pdf模板路徑
String templatePath = "D:/old.pdf";
// 生成的新檔案路徑
String newPDFPath = "D:/new.pdf";
//圖片路徑
String imgPath = "D:/test.jpg";
FileOutputStream out;
int num = 4;//頁數
ByteArrayOutputStream bos[] = new ByteArrayOutputStream[num];
try {
out = new FileOutputStream(newPDFPath);// 輸出流
Document doc = new Document(); //新建一個文件
PdfCopy copy = new PdfCopy(doc, out); //用於儲存原頁面內容,然後輸出
doc.open();
for (int i = 0; i < 2; i++) {
bos[i] = new ByteArrayOutputStream();
PdfReader reader = new PdfReader(templatePath);// 讀取pdf模板
PdfStamper stamper = new PdfStamper(reader, bos[i]); //生成輸出流
AcroFields form = stamper.getAcroFields(); //獲取文字域
form.setField("title", "這是標題");
int pageNo = form.getFieldPositions("img").get(0).page;
Rectangle rectangle = form.getFieldPositions("img").get(0).position;
float x = rectangle.getLeft();
float y = rectangle.getBottom();
//根據路徑讀取圖片
Image image = Image.getInstance("D:/test.jpg");
//獲取圖片頁面
PdfContentByte under = stamper.getOverContent(pageNo);
//圖片大小自適應
image.scaleToFit(rectangle.getWidth(), rectangle.getHeight());
//新增圖片
image.setAbsolutePosition(x, y);
under.addImage(image);
stamper.setFormFlattening(false);// 如果為false那麼生成的PDF檔案還能編輯,一定要設為true
stamper.close();
}
//將之前的兩次輸出
PdfImportedPage page = null;
for (int i = 0; i < 2; i++) {
page = copy.getImportedPage(new PdfReader(bos[i].toByteArray()), i + 1);
copy.addPage(page);
}
//複製兩次
for (int j=0;j<2;j++){
PdfReader reader = new PdfReader(templatePath);// 重新讀取pdf模板
bos[j]=new ByteArrayOutputStream();
reader.selectPages("2-2");//擷取模板的第二頁
PdfStamper stamper = new PdfStamper(reader, bos[j]);
AcroFields fields = stamper.getAcroFields();
fields.setField("img", "這是第"+j+"張圖片");
page = copy.getImportedPage(reader, 1);//輸出當前頁
copy.addPage(page);
}
doc.close();
out.close();
} catch (IOException e) {
System.out.println("匯出異常");
} catch (DocumentException e) {
System.out.println("文件異常");
}