博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动态数据写入pdf模板心得
阅读量:6191 次
发布时间:2019-06-21

本文共 4631 字,大约阅读时间需要 15 分钟。

前言

1.背景:
在项目中前段时间遇到一个问题,就是客户要求学生在线填写一些基础信息,保存到数据库的同时,给学生提供下载填写好的信息的pdf文件供下载,一开始我选择用Itext类去解析word文档模板,生成rtf文件,之后将学生填写的信息保存到数据时将数据同时写入到rtf模板中,在进行转为pdf,但是实现之后下载查看发现,中文不会乱码,纯数字也不会乱码,但是中文加数字,和特殊符号会出现名义上的乱码,(其实不是程序的乱码,只是写到word的rtf文件中的数据不会自动识别要用那些字体导致的),上网,×××,茶不思饭不想的去找解决办法,终于在我不懈的努力下还是没有解决,故放弃.
注:程序员要有一个舍得的心,不能在一个方向上钻牛角尖,跳跳代码同我家,有舍必有得.
2.正文:
好了,废话不大多说,上正确的代码和思路(其中有完成之前我所遇到的问题和踩的坑):
材料:
itext的jar包包:官网:
Word文档模板-->转为pdf(不会的,网上有教程)
Adobe Acrobat软件编辑pdf加载文本域填充数据用(网上有关于此软件的使用教程)

Demo展示:

public void test1_1(){           BaseFont bf;           Font font = null;           try {                bf = BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H",                         BaseFont.NOT_EMBEDDED);//创建字体                font = new Font(bf,12);//使用字体             } catch (DocumentException | IOException e) {                e.printStackTrace();             }             Document document = new Document();             try {                 PdfWriter.getInstance(document, new FileOutputStream("pdfFolder/2.pdf"));                 document.open();                document.add(new Paragraph("hello word 你好 世界",font));//引用字体                 document.close();             } catch (FileNotFoundException | DocumentException e) {                 System.out.println("file create exception");            }         }

上处代码会产生一个pdf文件,如下:

动态数据写入pdf模板心得
以上掌握之后,只是塞个牙缝,总不能用代码去向pdf中花一些复杂的表格吧,要死人不说,还不能优化和变通,最主要的是不能控制样式.
---编辑pdf模板文件:
网上截图(展示利用此软件进行编辑pdf的文本域):
动态数据写入pdf模板心得
Word模板(部分截图):
动态数据写入pdf模板心得
代码展示:

public void fillTemplate(){//利用模板生成pdf        //模板路径        String templatePath = "pdfFolder/template_demo.pdf";        //生成的新文件路径        String newPDFPath = "pdfFolder/newPdf.pdf";        PdfReader reader;        FileOutputStream out;        ByteArrayOutputStream bos;        PdfStamper stamper;        try {         out = new FileOutputStream(newPDFPath);//输出流         reader = new PdfReader(templatePath);//读取pdf模板         bos = new ByteArrayOutputStream();         stamper = new PdfStamper(reader, bos);         AcroFields form = stamper.getAcroFields();            String[] str = {"123456789","传智播客","男","1994-00-00","110","郑州市"};         int i = 0;         java.util.Iterator
it = form.getFields().keySet().iterator();         while(it.hasNext()){            String name = it.next().toString();            System.out.println(name);            form.setField(name, str[i++]);         }            stamper.setFormFlattening(true);//如果为false那么生成的PDF文件还能编辑,一定要设为true            stamper.close();            Document doc = new Document();            PdfCopy copy = new PdfCopy(doc, out);            doc.open();            PdfImportedPage importPage =copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);            copy.addPage(importPage);            doc.close();           } catch (IOException e) {            System.out.println(1);        } catch (DocumentException e) {            System.out.println(2);        }         }           

3.成品代码:

上述代码只是一个小的demo,下面是进行再开发中自己写的符合业务需求的代码配合上述的word文档模板进行编写,代码改变度不大,自己可以琢磨一下:

public void save(Page page,HttpServletResponse          response,httpServletRequest request){//利用模板生成pdf  //模板路径  String templatePath = "项目中的模板路径";  //生成的新文件路径  String newPDFPath = "要生成的文件的存放文件";  PdfReader reader;  FileOutputStream out;  ByteArrayOutputStream bos;  PdfStamper stamper;  try {//设置种字体,默认选中的是下面这个,在windows系统中是这样的,在其他的非windows系统中不敢保证:(不想用这种,可以在Adobe Acrobat去设置一个为Adobe 宋体 SL的字体,一下代码可以省略,并且不用在塞入数据是加入font字体,以下代码中的三处①一起使用,一起死亡)        //BaseFont bfChinese = BaseFont.createFont("STSongStd-Light",   "UniGB-UCS2-H", false);--①              //Font font = new Font(bfChinese, 10, Font.NORMAL); --①    out = new FileOutputStream(newPDFPath);//输出流    reader = new PdfReader(templatePath);//读取pdf模板    bos = new ByteArrayOutputStream();   stamper = new PdfStamper(reader, bos);      //读取pdf模板中的文本域们,(此处的用Adobe Acrobat编辑的模板没有截图,仿照上面的demo中的盗图进行对比)      AcroFields form = stamper.getAcroFields();      //form .setField("studentName", "font",null,”数据”);//姓名中文 --①      foem.setField("studentName", ”数据”);                      form .setField("sex", "男");//婚前姓名   stamper.setFormFlattening(true);//如果为false那么生成的PDF文件还能编辑,一定要设为true   stamper.close();   Document doc = new Document();   PdfCopy copy = new PdfCopy(doc, out);      //打开模板文档进行开始编辑:   doc.open();   PdfImportedPage importPage =copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);   copy.addPage(importPage);//此处一定要关闭,否则有一个进程会一直使用此模板文件,就会造成下载时报异常,此异常自己体会是什么异常:   doc.close();    } catch (IOException e) {   System.out.println(1); } catch (DocumentException e) {   System.out.println(2);}     } 

到此处已经完成了此小小功能,希望能帮助一些遇到此问题的人,以下附上本人参考的大神播客地址:

转载于:https://blog.51cto.com/13587708/2139746

你可能感兴趣的文章
指针面试题
查看>>
java Date时间的各种转换方式和Mysql存时间类型字段的分析
查看>>
collectionview 的相关设置
查看>>
【node.js】回调函数
查看>>
Phalcon 訪问控制列表 ACL(Access Control Lists ACL)
查看>>
Android Categroy 详解大全
查看>>
java中的定时器
查看>>
【翻译】EXTJS 编码风格指南与实例
查看>>
下MFC中对象、句柄、ID之间的区别.
查看>>
如何构建Win32汇编的编程环境(ONEPROBLEM个人推荐)
查看>>
Asp.Net MVC 分页、检索、排序整体实现
查看>>
php上传$_FILES 无法取值
查看>>
python 输出当前行号
查看>>
vue21 slot占位
查看>>
12C -- 配置Application Continuity
查看>>
Redis从入门到精通:初级篇(转)
查看>>
刨根问底 | Elasticsearch 5.X集群多节点角色配置深入详解【转】
查看>>
python怎么写可读性好的面向过程的长篇代码?
查看>>
怎样轻松将SD卡照片数据恢复
查看>>
Gsoap编译
查看>>