Java匯出Pdf格式表單

碼農小匠發表於2020-11-04

前言

  作為開發人員,工作中難免會遇到複雜表單的匯出,接下來介紹一種通過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格式等。如有其它更好的方式或建議,歡迎留言一塊交流!

相關文章