原文鏈接:https://www.cnblogs.com/wangpeng00700/p/8418594.html
在網上看了一些Java生成pdf文件的,寫的有點亂,有的不支持寫入中文字體,有的不支持模板,有的只是隨便把數據放里面生成文件,完全不考慮數據怎樣放置的以及以后的維護性,想想還是自己總結一個完全版的導出pdf的工具類吧,總結一下網上的方法,加上自己的完善。
本次完善綜合特點:
一對一,點對點的給對應的地方寫值,比如模板里面放了個name標識,在程序里把“張三”賦給name,那么輸出的pdf里面name的地方就變成了張三,准確方便快捷
支持中文,可以使用自己下載的字體。
支持圖片:圖片的大小范圍可以在模板隨意調,生成出來的圖片不會超過范圍。而且不需要根據坐標去算,程序里面自動計算的。
支持多頁模板,即使是好幾頁的模板,只要每個變量對應的范圍確定好了,生成出來的格式就不會錯亂。
詳細步驟和完整代碼在下面。
先放個效果圖:

下面是詳細的步驟:
1.首先,新建一個word文檔,內容如下,另存為pdf格式,我的命名:mytest.pdf。

2.用Adobe Acrobat Pro 打開剛剛制作的pdf文件。如下圖:

3.點擊創建-->PDF表單-->使用當前文檔-->使用當前文檔,一直點下一步完成。(有的版本Adobe Acrobat Pro軟件右邊有准備表單,直接點擊准備表單是同樣的效果)



4.上面好多給框,雙擊黑框可以修改名稱,還可以設置字體大小,如下圖


5.圖片的地方沒有黑框,我們可以在空白處點擊右鍵,選擇文本域,給圖片的域起名為img。



6.如下圖是制作好的pdf模板,直接保存即可。注意:黑框里面的名稱,是后面程序要用到的,程序根據名稱給對應的位置賦值的。不管你去什么名字,只要保證和程序里面的名字一直即可。

7.pom.xml文件:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.3</version>
</dependency>
8.工具類文件:
我的模板是放在C盤下面的,所以路徑是C:/mytest.pdf,另外,我還在C盤下面放了一張圖片 c:/50336.jpg ,字體使用的是系統的字體,也可以自己到網上下載自己喜歡的字體文件,路徑指向自己下載的字體文件路徑即可
package wp.util;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
/**
* Created by wangpeng on 2018/02/01.
*/
public class PdfUtils {
// 利用模板生成pdf
public static void pdfout(Map<String,Object> o) {
// 模板路徑
String templatePath = "C:/mytest.pdf";
// 生成的新文件路徑
String newPDFPath = "C:/testout1.pdf";
PdfReader reader;
FileOutputStream out;
ByteArrayOutputStream bos;
PdfStamper stamper;
try {
BaseFont bf = BaseFont.createFont("c://windows//fonts//simsun.ttc,1" , BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font FontChinese = new Font(bf, 5, Font.NORMAL);
out = new FileOutputStream(newPDFPath);// 輸出流
reader = new PdfReader(templatePath);// 讀取pdf模板
bos = new ByteArrayOutputStream();
stamper = new PdfStamper(reader, bos);
AcroFields form = stamper.getAcroFields();
//文字類的內容處理
Map<String,String> datemap = (Map<String,String>)o.get("datemap");
form.addSubstitutionFont(bf);
for(String key : datemap.keySet()){
String value = datemap.get(key);
form.setField(key,value);
}
//圖片類的內容處理
Map<String,String> imgmap = (Map<String,String>)o.get("imgmap");
for(String key : imgmap.keySet()) {
String value = imgmap.get(key);
String imgpath = value;
int pageNo = form.getFieldPositions(key).get(0).page;
Rectangle signRect = form.getFieldPositions(key).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
//根據路徑讀取圖片
Image image = Image.getInstance(imgpath);
//獲取圖片頁面
PdfContentByte under = stamper.getOverContent(pageNo);
//圖片大小自適應
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
//添加圖片
image.setAbsolutePosition(x, y);
under.addImage(image);
}
stamper.setFormFlattening(true);// 如果為false,生成的PDF文件可以編輯,如果為true,生成的PDF文件不可以編輯
stamper.close();
Document doc = new Document();
Font font = new Font(bf, 32);
PdfCopy copy = new PdfCopy(doc, out);
doc.open();
PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
copy.addPage(importPage);
doc.close();
} catch (IOException e) {
System.out.println(e);
} catch (DocumentException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
Map<String,String> map = new HashMap();
map.put("name","張三");
map.put("creatdate","2018年1月1日");
map.put("weather","晴朗");
map.put("sports","打羽毛球");
Map<String,String> map2 = new HashMap();
map2.put("img","c:/50336.jpg");
Map<String,Object> o=new HashMap();
o.put("datemap",map);
o.put("imgmap",map2);
pdfout(o);
}
}
9.效果圖如下:

