原文鏈接: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.效果圖如下: