有人私信我说看了上篇文章,但是不知道怎么创建pdf模板,而且有一些代码不明白。更了那么久博客总算有人私信问我问题/(ㄒoㄒ)/~~,正好今天又做这个功能所以更一篇文章详细讲述从使用Adobe Acrobat DC创建模板,到生成pdf文件以及对一些数据的处理操作。😚😚

在这里插入图片描述

一、利用Adobe Acrobat DC软件创建pdf模板

​ 古人云:工欲善其事必先利其器,所以小弟特地给大佬们备好Adobe Acrobat DC软件压缩包,🤜自取哦。百度网盘链接 提取码:b8ow

1…jpg、.png文件转pdf文件

​ 有些时候我们收到的并不是pdf文件,而是客户发过来的.jpg或者png图片,这时候就需要我们将文件先转为pdf文件。

右击打开我们要转换的文件

在这里插入图片描述

在这里插入图片描述

执行保存操作,保存的就是pdf文件。(Ctrl+s

2.创建pdf模板

​ 🤜其实上一步我们不保存也可以,创建模板完毕后再保存。下面的页面右击pdf文件,选择编辑操作如果pdf模板没有创建打开的页面和直接打开图片文件是一样的。

① 点击准备表单

在这里插入图片描述

② 点击开始,其实上两步也可以不这么操作,不过感觉这么方便,点击开始那儿也可以选择文件,下面是创建表单的页面。。。。红色圈出来的就是你要动态渲染的值,当然这是因为我打开的是已经更改的,毕竟为了写博客我也要自己先走一遍流程。
在这里插入图片描述

③ 添加文本域

点击文本按钮,然后在你想动态改变的位置添加,然后在域名称输入你的参数名,如果是必选项可以在必选项打勾。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这时候就有小伙伴问了,如果俺文本太长放不下可咋整。( •̀ ω •́ )✧

下面最最最重要的来了,通过双击文本域,或者点击所有属性操作,切换到选项栏目卡,然后选中多行

在这里插入图片描述

如果是编辑好文本域的模板打开会提示:

在这里插入图片描述

那些灰色的就是你添加的文本域,可以选择编辑表单域然后修改。

将你所需的文本域都添加好然后保存,模板就做好啦。。。下面才是重头戏🤭

二、导入MAVEN依赖

1.使用maven的项目
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>  
2.未使用maven的项目

俺也为你们准备了所需要的jar包,找了好久才找到。。。。。🤜点击下载CSDN资源 不需要积分哦

三、插入数据和图片到pdf模板并保存pdf文件

​ 咱身为一个程序员即使技术菜,但咱也要有写出优雅代码的心。首先创建一个pdfUtils.java工具类,这样以后可以复用,下面我贴上我的工具类代码,并且对每个我认为重要的地方加上注释,另外字体是宋体,至于使用其他的字体可以动动小手百度一下,面向百度编程嘛,不寒碜。

Controller里面调用生成pdf方法。

 // 保存路径 生成
String savePath =GlConfig.getDownloadResourcePath() + "student/worksSafetyknowledgeCertificate/" + student.getName()+"WorksSafetyknowledgeCertificate.pdf";
PdfUtil.exportCertificateTemplateByPdf(savePath, info.toJson(), qrCodePath,1);

​ 这是实体类中加的将对象转为json格式的方法:

    public JSONObject toJson() {
        return JSONUtil.parseObj(this);
    }

​ pdf工具类中方法:

/**
 * 生成安全生产知识和管理能力考核证书
 */
public static final URL SpecialAnquanshengchan = ResourceUtil.getResource("template/anquanshengchan.pdf");
/**
 * pdf生成
 */
public static void exportCertificateTemplateByPdf(String savePath, JSONObject obj, String qrCodePath,int type) {
        PdfReader reader = null;
        ByteArrayOutputStream bos = null;
        PdfStamper stamper = null;
        OutputStream os = null;
        FileOutputStream out = null;
        File file;
        Document document = null;
        PdfCopy copy = null;
        Document doc = null;
        try {
            /** 实例化文档对象 */
            document = new Document(PageSize.A4, 50, 40, 40, 50);
            /** 创建 PdfWriter 对象 */
            // 打开文档
            document.open();
            /** pdf文档中中文字体的设置,注意一定要添加iTextAsian.jar包 */
            String localFontPath = "c:\\windows\\fonts\\";
            BaseFont bfChinese =
                    BaseFont.createFont(localFontPath + "simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            // 这里是删除以前上传的附件 毕竟为了节省空间
            FileUtils.deleteFile(savePath);
            file = new File(savePath);
            // 如果文件夹不存在 创建文件夹
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            out = new FileOutputStream(file);
            // 根据type判断获取不同的模板
            if (type == 0) {
                reader = new PdfReader(SpecialOperationCertificate);
            } else {
                reader = new PdfReader(SpecialAnquanshengchan);
            }
            bos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, bos);
            AcroFields form = stamper.getAcroFields();
            // 文字类的内容处理
            form.addSubstitutionFont(bfChinese);
            String vlaues;
            for (Map.Entry<String, Object> entry : obj.entrySet()) {
                vlaues = String.valueOf(entry.getValue());
                // 判断是否插入图片 如果不需要可以删除不用
                if ("picname".equals(entry.getKey())) {
                    try {
                        // 通过域名获取所在页和坐标,左下角为起点
                        int pageNo = form.getFieldPositions(entry.getKey()).get(0).page;
                        Rectangle signRect = form.getFieldPositions(entry.getKey()).get(0).position;
                        // qrCode位置
                        Rectangle qrcode_signRect = form.getFieldPositions("qrcode").get(0).position;
                        float x = signRect.getLeft();
                        float y = signRect.getBottom();
                        // qrcode坐标位置
                        float qrcode_x = qrcode_signRect.getLeft();
                        float qrcode_y = qrcode_signRect.getBottom();
                        // 读图片
                        Image image = Image.getInstance(vlaues);
                        Image qrcode_image = Image.getInstance(qrCodePath);
                        // 获取操作的页面
                        PdfContentByte under = stamper.getOverContent(pageNo);
                        // 根据域的大小缩放图片
                        image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                        qrcode_image.scaleToFit(qrcode_signRect.getWidth(), qrcode_signRect.getHeight());
                        // 添加图片
                        image.setAbsolutePosition(x, y);
                        qrcode_image.setAbsolutePosition(qrcode_x, qrcode_y);
                        under.addImage(image);
                        under.addImage(qrcode_image);
                    } catch (Exception e) {
                        log.info(e.getMessage());
                    }

                } else {
                    // 对文本的处理
                    if ("fileCoding".equals(entry.getKey())) {
                        // 设置文本的大小  有的标题字体会比较大
                        form.setFieldProperty(entry.getKey(), "textsize", 55f, null);
                    } else {
                        form.setFieldProperty(entry.getKey(), "textsize", 20f, null);
                    }
                    form.setField(entry.getKey(), vlaues);
                }
            }
            // 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
            stamper.setFormFlattening(true);
            stamper.close();
            doc = new Document();
            copy = new PdfCopy(doc, out);
            doc.open();
            PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
            copy.addPage(importPage);
            doc.close();
            document.close();
            copy.flush();
            copy.close();

        } catch (Exception e) {
            log.info(e.getMessage());
        } finally {
            try {
                if (stamper != null) {
                    stamper.close();
                    stamper = null;
                }
                if (reader != null) {
                    reader.close();
                    reader = null;
                }
                IOUtils.closeQuietly(os);
                IOUtils.closeQuietly(bos);
                IOUtils.closeQuietly(out);
                if (document != null) {
                    document.close();
                    document = null;
                }
                if (doc != null) {
                    doc.close();
                    doc = null;
                }
                if (copy != null) {
                    copy.flush();
                    copy.close();
                    copy = null;
                }
            } catch (Exception ignored) {
            }
        }
    }

看在俺那么认真、详细整理的份上,如果对你有帮助麻烦点个赞👍,谢谢。看着访问量一点点的涨感觉很上瘾,本来就打算记录自己在项目中遇到的问题,以后需要的话可以直接查看,也没想着运营一下,一是因为如果只是为了访问量去复制别人的代码,自己连用都没用过就贴上去,有点。。。咱还是要脸的,二呢,咱技术水平也不咋的高,咳😅。因为俺也是面向百度编程,不会的也是需要找资料,但是在找的过程中发现好多有问题的也贴上去,一个功能不同博客代码都一摸一样,然后找着找着也不能用,很烦躁也浪费时间,我能做的就是对得起点开我博客文章的小伙伴,可能我水平不怎么高😅,但是我更的博客都是我在项目中、或者学习中使用到的内容,嘿嘿嘿。。。。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐