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