Java导出Pdf格式表单

前言

  作为开发人员,工作中难免会遇到复杂表单的导出,接下来介绍一种通过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方法进行测试,并查看导出后的文件

项目文件:链接://pan.baidu.com/s/1xvrtd1HdXuImafMfrFcGrA   提取码:l0qh

写在最后

  1、此种方式对Pdf居中自动换行支持性不好,可以根据文本域的宽度所能容纳的字数,创建多个文本域,对值进行手动分割填充到多个文本域。

​  2、C#开发时处理Excel文件可用NPOI插件进行数据导入导出,处理PDF文件可用ITextSharp插件。

  上述介绍只是导出pdf表单的一种方式,也可以直接利用itext进行手动创作pdf表单或者导出Excel或World后台转换为pdf格式等。如有其它更好的方式或建议,欢迎留言一块交流!