Java生成PDF文档 iText使用PDF模板一

妖狐艹你老母 2022-04-03 11:06 581阅读 0赞
  1. 最近在弄这个java生成pdf,哎,在网上查找了各种各样的学习资料,弄了几天,今天终于把这个效果简单的弄出来,所以,也把这个,我所走过的坑,作一个记录,提供接下来需要学习的人。

参考文献文档:https://blog.csdn.net/u012377333/article/details/51264122#

https://my.oschina.net/lujianing/blog/894365

iText

iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。

iText 官网:http://itextpdf.com/

iText 开发文档: http://developers.itextpdf.com/developers-home

iText目前有两套版本iText5和iText7。iText5应该是网上用的比较多的一个版本。iText5因为是很多开发者参与贡献代码,因此在一些规范和设计上存在不合理的地方。iText7是后来官方针对iText5的重构,两个版本差别还是挺大的。不过在实际使用中,一般用到的都比较简单,所以不用特别拘泥于使用哪个版本。比如我们在http://mvnrepository.com/中搜索iText,出来的都是iText5的依赖。

整个项目结构如下:

20181222002256189.png

第一步:下载AdobeAcrobat DC,必须使用这个来制作from域。

第二步:使用AdobeAcrobat DC将Word导成PDF文档。

第三步:添加“文本域”到我们想要添加内容的位置:

效果如下,博主这里的模板如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwNzY0OTkx_size_16_color_FFFFFF_t_70

第四步:保存PDF文档;

接下来就是代码部分:

首先创建一个maven项目,这里博主就不多介绍了,如果这个不会,那就没有办法了。

一:引入iText所需要的依赖

  1. <dependency>
  2. <groupId>com.itextpdf</groupId>
  3. <artifactId>itextpdf</artifactId>
  4. <version>5.4.2</version>
  5. </dependency>
  6. <!--pdf itext 的jar依赖 -->
  7. <dependency>
  8. <groupId>com.itextpdf</groupId>
  9. <artifactId>itext-asian</artifactId>
  10. <version>5.2.0</version>
  11. </dependency>

对应的jar包

201812212330225.png

二:开户账票所对应的实体类如下:

  1. package com.demo;
  2. //账票实体
  3. public class Ticket {
  4. private String ticketId;// 流水号
  5. private String homesId;
  6. private String ticketCreateTime;// 创建时间
  7. private String ticketCompany;// 账票单位
  8. private String sysName;// 系统名称
  9. private String moneyLittle;// 小写金额
  10. private String moneyBig;// 大写金额
  11. private String accountCompany;// 公司名称
  12. private String bedNumber;// 编号
  13. private String username;// 用户名
  14. private String password;// 密码
  15. // 无参构造
  16. public Ticket() {
  17. super();
  18. }
  19. // 有参构造
  20. public Ticket(String ticketId, String homesId, String ticketCreateTime, String ticketCompany, String sysName,
  21. String moneyLittle, String moneyBig, String accountCompany, String bedNumber, String username,
  22. String password) {
  23. this.ticketId = ticketId;
  24. this.homesId = homesId;
  25. this.ticketCreateTime = ticketCreateTime;
  26. this.ticketCompany = ticketCompany;
  27. this.sysName = sysName;
  28. this.moneyLittle = moneyLittle;
  29. this.moneyBig = moneyBig;
  30. this.accountCompany = accountCompany;
  31. this.bedNumber = bedNumber;
  32. this.username = username;
  33. this.password = password;
  34. }
  35. public String getTicketId() {
  36. return ticketId;
  37. }
  38. public void setTicketId(String ticketId) {
  39. this.ticketId = ticketId;
  40. }
  41. public String getHomesId() {
  42. return homesId;
  43. }
  44. public void setHomesId(String homesId) {
  45. this.homesId = homesId;
  46. }
  47. public String getTicketCreateTime() {
  48. return ticketCreateTime;
  49. }
  50. public void setTicketCreateTime(String ticketCreateTime) {
  51. this.ticketCreateTime = ticketCreateTime;
  52. }
  53. public String getTicketCompany() {
  54. return ticketCompany;
  55. }
  56. public void setTicketCompany(String ticketCompany) {
  57. this.ticketCompany = ticketCompany;
  58. }
  59. public String getSysName() {
  60. return sysName;
  61. }
  62. public void setSysName(String sysName) {
  63. this.sysName = sysName;
  64. }
  65. public String getMoneyLittle() {
  66. return moneyLittle;
  67. }
  68. public void setMoneyLittle(String moneyLittle) {
  69. this.moneyLittle = moneyLittle;
  70. }
  71. public String getMoneyBig() {
  72. return moneyBig;
  73. }
  74. public void setMoneyBig(String moneyBig) {
  75. this.moneyBig = moneyBig;
  76. }
  77. public String getAccountCompany() {
  78. return accountCompany;
  79. }
  80. public void setAccountCompany(String accountCompany) {
  81. this.accountCompany = accountCompany;
  82. }
  83. public String getBedNumber() {
  84. return bedNumber;
  85. }
  86. public void setBedNumber(String bedNumber) {
  87. this.bedNumber = bedNumber;
  88. }
  89. public String getUsername() {
  90. return username;
  91. }
  92. public void setUsername(String username) {
  93. this.username = username;
  94. }
  95. public String getPassword() {
  96. return password;
  97. }
  98. public void setPassword(String password) {
  99. this.password = password;
  100. }
  101. }

三:账票模板:这与参考的文献不一样,但实现的目的都一样。博主这里采用的是这种方法

3.1:因:iText 不支持中文,所以需要引入中文字体,引入下载字体:https://www.fontke.com/这里介绍一个字体网。

  1. package com.demo;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import com.itextpdf.text.Font;
  6. import com.itextpdf.text.FontFactory;
  7. import com.itextpdf.text.pdf.AcroFields;
  8. import com.itextpdf.text.pdf.BaseFont;
  9. import com.itextpdf.text.pdf.PdfReader;
  10. import com.itextpdf.text.pdf.PdfStamper;
  11. //账票模板
  12. public class PDFTempletTicket {
  13. private String templatePdfPath;//模板路径
  14. private String ttcPath;//生成的新路径
  15. private String targetPdfpath;//源路径
  16. private Ticket ticket;//账票实体
  17. private static final String FONT = "中黑体.ttf";//引入的字体
  18. //get与set
  19. public String getTemplatePdfPath() {
  20. return templatePdfPath;
  21. }
  22. public void setTemplatePdfPath(String templatePdfPath) {
  23. this.templatePdfPath = templatePdfPath;
  24. }
  25. public String getTtcPath() {
  26. return ttcPath;
  27. }
  28. public void setTtcPath(String ttcPath) {
  29. this.ttcPath = ttcPath;
  30. }
  31. public String getTargetPdfpath() {
  32. return targetPdfpath;
  33. }
  34. public void setTargetPdfpath(String targetPdfpath) {
  35. this.targetPdfpath = targetPdfpath;
  36. }
  37. public Ticket getTicket() {
  38. return ticket;
  39. }
  40. public void setTicket(Ticket ticket) {
  41. this.ticket = ticket;
  42. }
  43. //无参构造
  44. public PDFTempletTicket() {
  45. super();
  46. }
  47. //有参构造
  48. public PDFTempletTicket(String templatePdfPath, String ttcPath, String targetPdfpath, Ticket ticket) {
  49. this.templatePdfPath = templatePdfPath;
  50. this.ttcPath = ttcPath;
  51. this.targetPdfpath = targetPdfpath;
  52. this.ticket = ticket;
  53. }
  54. // 使用中文字体
  55. Font f1 = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
  56. //获取
  57. public void templetTicket(File file) throws Exception {
  58. //创建一个pdf读取对象
  59. PdfReader reader = new PdfReader(templatePdfPath);
  60. //创建一个输出流
  61. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  62. //创建pdf模板,参数reader bos
  63. PdfStamper ps = new PdfStamper(reader, bos);
  64. //封装数据
  65. AcroFields s = ps.getAcroFields();
  66. s.setField("ticketId", ticket.getTicketId());
  67. s.setField("ticketCreateTime", ticket.getTicketCreateTime());
  68. s.setField("ticketCompany", ticket.getTicketCompany());
  69. s.setField("sysName", ticket.getSysName());
  70. s.setField("moneyLittle", ticket.getMoneyLittle());
  71. s.setField("moneyBig", ticket.getMoneyBig());
  72. s.setField("accountCompany", ticket.getAccountCompany());
  73. s.setField("bedNumber", ticket.getBedNumber());
  74. s.setField("username", ticket.getUsername());
  75. s.setField("password", ticket.getPassword());
  76. ps.setFormFlattening(true);//这里true表示pdf可编辑
  77. ps.close();//关闭PdfStamper
  78. FileOutputStream fos = new FileOutputStream(file);//创建文件输出流
  79. fos.write(bos.toByteArray());//写入数据
  80. fos.close();//关闭输出流
  81. }
  82. }

四:测试类-TestTempletTicket

  1. package com.demo;
  2. import java.io.File;
  3. public class TestTempletTicket {
  4. public static void main(String[] args) throws Exception {
  5. //账票对象
  6. Ticket ticket = new Ticket();
  7. ticket.setTicketId("201812212710000");
  8. ticket.setTicketCreateTime("2018年12月21日");
  9. ticket.setTicketCompany("中国人民银行");
  10. ticket.setSysName("智能看护系统");
  11. ticket.setMoneyLittle("50,000.00");
  12. ticket.setMoneyBig("伍万元整");
  13. ticket.setAccountCompany("中国政府");
  14. ticket.setBedNumber("500床位");
  15. ticket.setUsername("qiu");
  16. ticket.setPassword("123456");
  17. //模板对象
  18. PDFTempletTicket Ticketpdf = new PDFTempletTicket();
  19. //模板源路径
  20. Ticketpdf.setTemplatePdfPath("D:\\pdfDemo\\开户账票.pdf");
  21. //设置tarGet的路径,这个是项目中的源路径
  22. //Ticketpdf.setTargetPdfpath("D:\\a.pdf");
  23. //set封装账票信息
  24. Ticketpdf.setTicket(ticket);
  25. //指定生成的新路径
  26. File file = new File("D:\\pdfDemo\\demo.pdf");
  27. //创建文件
  28. file.createNewFile();
  29. //使生成的文件file生效,这个必须有
  30. Ticketpdf.templetTicket(file);
  31. }
  32. }

运行结果如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwNzY0OTkx_size_16_color_FFFFFF_t_70 1

效果有点丑:这里也不做调试了,这里主要是功能做出来,其他的效果可以自己慢慢调 了。相信介绍的这样清楚,不是这行的的人估计也能看懂了吧。加油!!!!!!以后遇到类似的,相信大家至少有个映像,如果还是不会做,没关系,参考这篇,相信你一定做好的,加油!谁也不是天生就是天才,都是不断的去学习!这个效果其实已经是相对简单的,真正在实际项目中,业务逻辑可能要复杂些。加油!!!

如果参照别人的,会出现以下问题:

备注:导出PDF文档,From域的内容不可见问题;iText找不到字体;

问题1:我开始导出的From域内容看不到,将ps.setFormFlattening(true);设置为flase后,可以看到From域,还是看不到内容,我点击进入From后可以看到内容,该方法是将From域隐藏;后来看到有人设置From域内容的字体:BaseFontbf = BaseFont.createFont(PDFTicket.class.getResource(“/“) + “org/csun/ns/util/simsun.ttc,1”,

  1. BaseFont.IDENTITY\_H, BaseFont.EMBEDDED);

以及:

s.setSubstitutionFonts(fontList);

问题2:别人的代码:

BaseFont bf = BaseFont.createFont(“STSong-Light”, “UniGB-UCS2-H”, BaseFont.NOT_EMBEDDED);

会报找不到字体的错误,这里的解决方式就是通过使用自己的字体就好,simsun.ttc是Windows下面自带的字体(简体宋体:C:\Windows\Fonts下面有很多字体可以使用)

以上两个问题,可以参照博主的这种做法就可化解,如果你有更好的方法,不妨可以留言也介绍给博主

发表评论

表情:
评论列表 (有 0 条评论,581人围观)

还没有评论,来说两句吧...

相关阅读

    相关 itext 生成pdf

      iText是著名的开 放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将 XM