項目需求:獲取列表數據之后直接將數據生成一個pdf。因此需要使用到?itext?對pdf進行直接操作。
環境配置
需要為pdf添加文字域,因此需要安裝Adobe Acrobat
準備一個空的PDF文件,如果有現成的模板更好
依賴配置,我們使用itext的7版本
<dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.2.3</version><type>pom</type></dependency>
?
快速使用
使用Adobe Acrobat Pro DC打開空PDF,使用 文字域 工具為PDF添加文字域,要注意為每個文字域命名。
如果你有現成的模板PDF,直接使用識別域可以識別空白區域然后自動生成文字域,但是一般都不太準確
如果你的單個數據很多的話,可以在屬性中設置多行?
?
設置完文字域之后記得保存。
代碼實現
@SpringBootTest
class StickerApplicationTests {private static final String TEMP_PATH = "C:\\Users\\An1ong\\Desktop\\Stickers.pdf";//生成PDF的位置private static final String DEST_PATH = "C:\\Users\\An1ong\\Desktop\\StickersOut.pdf";//本地上字體的路徑private static final String FONT_PATH = "";@Autowiredprivate StickerService stickerService;@Testvoid contextLoads() throws IOException {//創建一個新的PDF文件,并寫入數據PdfReader reader = new PdfReader(TEMP_PATH);// 創建一個 PdfWriter 對象以寫入新的PDFPdfWriter writer = new PdfWriter(DEST_PATH);// 創建一個 PdfDocument 對象PdfDocument pdfDoc = new PdfDocument(reader, writer);// 獲取 PDF 表單PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, false);//獲得數據,準備填充List<Sticker> stickerList = stickerService.list(10);//文本填充for(int i = 0; i < stickerList.size();i++){Sticker sticker = stickerList.get(i);// 生成自定義序號,格式為 "001"、"002"、"003"String customId = String.format("%03d", i + 1);String idFieldName = "id" + (i + 1);String nameFieldName = "name" + (i + 1);PdfFormField idField = form.getField(idFieldName);if (idField != null) {idField.setValue(customId);}PdfFormField nameField = form.getField(nameFieldName);if (nameField != null) {nameField.setValue(sticker.getStickerName());}}//消除掉表單域form.flattenFields();//關閉流pdfDoc.close();}
}
行數也不算少,但里面的邏輯其實也很簡單。這是一個Springboot的單元測試,我調用service中方法獲取了一個裝著對象的列表。
用PdfReader讀取你要套寫的模板,用PdfWriter將數據寫入模板。創建出一個PdfDocument對象并將這兩個參數傳入就可以開始對PDF操作了。
注意,這個過程不會直接在原PDF上操作,而是生成一個新的PDF進行操作,程序結束后原PDF模版還是空白的。
?PdfAcroFrom獲取PDF表單,然后PdfFormField獲取其中的文字域,最后使用for循環動態的將數據套打在模板上就完成了。
最終會生成一個新的文件
最終效果:
之所以要在最后調用form.flattenFields消除掉表單域是因為如果不消除表單域的話就會變成這樣。
封裝
我們可以把這個在單元測試中的程序封裝成工具類重復使用
public class PdfPrintUtil {// private static final String TEMP_PATH = "C:\\Users\\An1ong\\Desktop\\Stickers.pdf";
//
// private static final String DEST_PATH = "C:\\Users\\An1ong\\Desktop\\StickersOut.pdf";public static void printPDF(String TEMP_PATH,String DEST_PATH,List<Sticker> stickerList) throws IOException {//創建一個新的PDF文件,并寫入數據PdfReader reader = new PdfReader(TEMP_PATH);// 創建一個 PdfWriter 對象以寫入新的PDFPdfWriter writer = new PdfWriter(DEST_PATH);// 創建一個 PdfDocument 對象PdfDocument pdfDoc = new PdfDocument(reader, writer);// 獲取 PDF 表單PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, false);//文本填充for(int i = 0; i < stickerList.size();i++){Sticker sticker = stickerList.get(i);// 生成自定義序號,格式為 "001"、"002"、"003"String customId = String.format("%03d", i + 1);String idFieldName = "id" + (i + 1);String nameFieldName = "name" + (i + 1);PdfFormField idField = form.getField(idFieldName);if (idField != null) {idField.setValue(customId);}PdfFormField nameField = form.getField(nameFieldName);if (nameField != null) {nameField.setValue(sticker.getStickerName());}}//消除掉表單域form.flattenFields();//關閉流pdfDoc.close();}}