前言
作為開發人員,工作中難免會遇到複雜表單的匯出,接下來介紹一種通過Java利用模板便捷匯出Pdf表單的方式
模擬需求
需求:按照下面格式匯出pdf格式的學生成績單
準備工作
- Excel軟體
- Adobe Acrobat XI Pro軟體
模板製作
第一步:利用Excel製作出上述表單,設定好字型、行高、列寬等,如下:
第二步:按照給定模板做好Excel表單後,刪除需要後期填充的資料
第三步:開啟Adobe Acrobat XI Pro軟體,開始依據Excel模板製作PDF模板
1、單擊建立、選擇建立表單按鈕
2、選擇從現有文件建立,選擇前面製作的Excel模板
3、點選工具,編輯表單
4、此時表單中只有一個文字域,我們可以點選新增新的文字域的形式來新增表頭和結尾。也可以在pdf上新增一些其他控制元件。製作完成後如下:
5、可以通過滑鼠在域中右鍵和屬性中修改域的位置,字型、顏色、換行等
6、將製作好的表單儲存
專案實現
第一步:建立基於maven的Java專案
第二步:引入itext的pom依賴
<!-- itextpdf依賴 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
第六步:將上面製作的pdf模板放到Resources目錄下,編寫PdfUtils工具類
package com.whw.pdf;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.*;
import java.io.*;
import java.util.ArrayList;
public class PdfUtils {
public static void exportMapMZydPdf(String templatePath,String savePath,String fileName) throws DocumentException {
ByteArrayOutputStream byteArrayOutputStream = null;
PdfReader pdfReader = null;
FileOutputStream fileOutputStream=null;
try {
fileOutputStream=new FileOutputStream(savePath+"//"+fileName);
byteArrayOutputStream = new ByteArrayOutputStream();
pdfReader = new PdfReader(templatePath);
PdfStamper pdfStamper = new PdfStamper(pdfReader, byteArrayOutputStream);
//獲取模板所有域引數
AcroFields acroFields = pdfStamper.getAcroFields();
//解決中文字型不顯示的問題
BaseFont baseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
ArrayList<BaseFont> fontArrayList = new ArrayList<BaseFont>();
fontArrayList.add(baseFont);
acroFields.setSubstitutionFonts(fontArrayList);
acroFields.setField("head", "xxx同學成績單");
acroFields.setField("yuwen", "116");
acroFields.setField("shuxue", "115");
acroFields.setField("yingyu", "110");
acroFields.setField("zhengzhi", "89");
acroFields.setField("lishi", "90");
acroFields.setField("shengwu", "85");
acroFields.setField("dili", "83");
acroFields.setField("yinyue", "78");
acroFields.setField("tiyu", "88");
acroFields.setField("meishu", "80");
acroFields.setField("xiguan", "優秀");
acroFields.setField("nengli", "優秀");
acroFields.setField("xuexi", "優秀");
acroFields.setField("jl", "優秀");
acroFields.setField("weisheng", "良好");
acroFields.setField("pingyu", " 在校表現優秀。你關心同學,有很強的集體榮譽感,對待工作細緻負責,學習上也比較踏實。老師相信你還有很大潛力沒有挖掘出來,你要相信自己,不斷挑戰自我,加油!");
acroFields.setField("jc", "三號學生");
acroFields.setField("school", "xx市第一高階中學");
pdfStamper.setFormFlattening(true);//如果為false那麼生成的PDF檔案還能編輯,一定要設為true
pdfStamper.flush();
pdfStamper.close();
//設定紙張,可以在Excel製作是設定好紙張大小
Document doc = new Document(PageSize.A5);
PdfCopy copy = new PdfCopy(doc,fileOutputStream);
doc.open();
PdfImportedPage importPage = copy.getImportedPage(new PdfReader(byteArrayOutputStream.toByteArray()), 1);
try {
copy.addPage(importPage);
} catch (BadPdfFormatException e) {
e.printStackTrace();
}
doc.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (byteArrayOutputStream != null) {
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (pdfReader != null) {
pdfReader.close();
}
}
}
public static void main(String[] args) throws IOException {
try {
String savePath="C://Users//hua//Desktop//";
String fileName="xxx同學成績單.pdf";
exportMapMZydPdf("/成績單模板.pdf",savePath,fileName);
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
第三步:執行main方法進行測試,並檢視匯出後的檔案
專案檔案:連結:https://pan.baidu.com/s/1xvrtd1HdXuImafMfrFcGrA 提取碼:l0qh
寫在最後
1、此種方式對Pdf居中自動換行支援性不好,可以根據文字域的寬度所能容納的字數,建立多個文字域,對值進行手動分割填充到多個文字域。
2、C#開發時處理Excel檔案可用NPOI外掛進行資料匯入匯出,處理PDF檔案可用ITextSharp外掛。
上述介紹只是匯出pdf表單的一種方式,也可以直接利用itext進行手動創作pdf表單或者匯出Excel或World後臺轉換為pdf格式等。如有其它更好的方式或建議,歡迎留言一塊交流!