1. 制作模板
  2. 引入依赖
  3. 引入所需字体文件
  4. 工具类的编写
  5. 业务实现

一、模板制作
(1)编写html代码 ,需要替换的值与内容预留出来,用${name}代替,需循环处.表格前加上<#list listKey as t> ${t.name}
(2)将写好的html文件用文本打开,复制代码,用xml格式工具格式一下。最后将html文件后缀改为.ftl

<!DOCTYPE html>
<html><head><meta charset="utf-8"/><title>PDF导出</title><style type="text/css">*{box-sizing: border-box;}body{font-family: SimSun;}.content {width: 100%;height: 100%;text-align: center;font-size: 16px;}.contentHeader {height: 60px;line-height: 60px;font-size: 30px;}.title {width: 100%;height: 25px;line-height: 25px;}.titleLeft {padding-left: 20px;float: left;}.titleRight {padding-right: 20px;float: right;}table {width: 98%;height: 100%;border-collapse: collapse;text-align: center;font-size: 16px;margin: 0 2%;}td {padding: 8px;}.tdOne {width: 120px;}.footerTable {width: 98%;height: 100%;border-collapse: collapse;text-align: center;font-size: 16px;}.footerTd{border-bottom: 1px solid transparent;}</style></head><body><div class='content'><div class='contentHeader'>设备任务单</div><div class='title'><span class='titleLeft'>所属组织: ${pkcompany}</span><span class='titleRight'>打印人:${psnname}</span></div><table border="1"><tr><td class='tdOne'>标题</td><td class='tdTwo'>${contractno}设备任务单</td><td class='tdOne'>流水号</td><td class='tdTwo'>${pk_equtask}</td></tr><tr><td class='tdOne'>提交人</td><td class='tdTwo'>${creatorname}</td><td class='tdOne'>所属部门</td><td class='tdTwo'>${creatordepname}</td></tr><tr><td class='tdOne'>申请日期</td><td class='tdTwo'>${createdate}</td><td class='tdOne'>生产代码</td><td class='tdTwo'>${shengchandaima}</td></tr><tr><td class='tdOne'>合同号</td><td class='tdTwo'>${contractno}</td><td class='tdOne'>制号</td><td class='tdTwo'>${zhihao}</td></tr><tr><td class='tdOne'>客户所在地</td><td class='tdTwo'>${cusaddress}</td><td class='tdOne'>数量</td><td class='tdTwo'>1.0</td></tr><tr><td class='tdOne'>内部型号</td><td class='tdTwo'>${equxinghao_task}</td><td class='tdOne'>内部设备名称</td><td class='tdTwo'>${equname_task}</td></tr><tr><td class='tdOne'>合同型号</td><td class='tdTwo'>${innerEquxinghao}</td><td class='tdOne'>合同设备名称</td><td class='tdTwo'>${innerEquname}</td></tr><tr><td class='tdOne'>开始日期~要求交货时间</td><td class='tdTwo' colspan="3">${begindate}~${jiaohuodate}</td></tr><tr><td class='tdOne'>操作画面语言</td><td class='tdTwo'>${caozuoxitong}</td><td class='tdOne'>电气图纸语言</td><td class='tdTwo'>${def1}</td></tr><tr><td class='tdOne'>说明书语言</td><td class='tdTwo'>${def2}</td><td class='tdOne'>设备标识、标牌语言</td><td class='tdTwo'>${def3}</td></tr><tr><td class='tdOne'>电压要求</td><td class='tdTwo'>${dianya}</td><td class='tdOne'>CE认证</td><td class='tdTwo'>${cerenzheng}</td></tr><tr><td class='tdOne'>技术要求</td><td class='tdTwo'>${jishuyaoqiu}</td><td class='tdOne'>客户环境(温度)说明</td><td class='tdTwo'>${kehuhuanjing}</td></tr><tr><td class='tdOne'>所属制造部</td><td class='tdTwo'>${makedept}</td><td class='tdOne'>所属技术组</td><td class='tdTwo'>${tecdept}</td></tr><tr><td class='tdOne'>合同负责人</td><td class='tdTwo'>${salername}</td><td class='tdOne'>紧急程度</td><td class='tdTwo'>${jinjichengdu}</td></tr><tr><td colspan="4" class='footerTd'>审批记录</td></tr></table><table border="1" class='footerTable'><tr><td>节点名称</td><td>审批操作</td><td>审批意见</td><td>审批人</td><td>审批时间</td></tr><#list listKey as t><tr><td>${t.taskdefname}</td><td>${t.approveresult}</td><td>${t.approvecontentvalue}</td><td>${t.noticename}</td><td>${t.approvedatevalue}</td></tr></#list></table></div></body></html>

二、所需pom依赖

  <dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version></dependency><dependency><groupId>org.xhtmlrenderer</groupId><artifactId>flying-saucer-pdf</artifactId><version>9.0.9</version></dependency>

三、引入字体所需文件,我的放在resources下新建一个template ===》font目录下 simsun.ttc


四、实体类
没啥说的,自己去改路径,debug走一下,需要图片就放开注释的代码

```java
package com.tjk.tjkcom.util;import com.lowagie.text.pdf.BaseFont;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.xhtmlrenderer.pdf.ITextRenderer;import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Locale;
import java.util.Map;public class PDFTemplateUtil {/*** 通过模板导出pdf文件* @param data 数据* @param templateFileName 模板文件名* @throws Exception*/public static ByteArrayOutputStream createPDF(Map<String,Object> data, String templateFileName) throws Exception {// 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);// 指定FreeMarker模板文件的位置cfg.setClassForTemplateLoading(PDFTemplateUtil.class,"/mailtemplate");ITextRenderer renderer = new ITextRenderer();OutputStream out = new ByteArrayOutputStream();try {// 设置 css中 的字体样式(暂时仅支持宋体和黑体) 必须,不然中文不显示renderer.getFontResolver().addFont("/mailtemplate/font/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);// 设置模板的编码格式cfg.setEncoding(Locale.CHINA, "UTF-8");// 获取模板文件Template template = cfg.getTemplate(templateFileName, "UTF-8");StringWriter writer = new StringWriter();// 将数据输出到html中template.process(data, writer);writer.flush();String html = writer.toString();// 把html代码传入渲染器中renderer.setDocumentFromString(html);// 设置模板中的图片路径 (这里的images在resources目录下) 模板中img标签src路径需要相对路径加图片名 如
//            String url = PDFTemplateUtil.class.getClassLoader().getResource("images").toURI().toString();
//            renderer.getSharedContext().setBaseURL(url);renderer.layout();renderer.createPDF(out, false);renderer.finishPDF();out.flush();return (ByteArrayOutputStream)out;} finally {if(out != null){out.close();}}}
}

五、业务实现
(1)写你的代码,controller -service -serviceimpl - mapper

package com.example.demo.controller;import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/pdf")
public class PdfController {@RequestMapping("/export")public void exportPdf(HttpServletResponse response) throws Exception{ByteArrayOutputStream baos = null;OutputStream out = null;try {// 模板中的数据,实际运用从数据库中查询------------------------------------------------------------------------------------------------------------baos = PDFTemplateUtil.createPDF(resultMap, "Test.ftl");// 设置响应消息头,告诉浏览器当前响应是一个下载文件response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");response.setCharacterEncoding("utf-8");response.setContentType("application/x-msdownload");// 告诉浏览器,当前响应数据要求用户干预保存到文件中,以及文件名是什么 如果文件名有中文,必须URL编码String fileName = URLEncoder.encode("设备任务单:"+hashMap.get("contractno").toString()+".pdf", "UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName);/*response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));*/out = response.getOutputStream();baos.writeTo(out);baos.close();} catch (Exception e) {e.printStackTrace();throw new Exception("导出失败:" + e.getMessage());} finally{if(baos != null){baos.close();}if(out != null){out.close();}}}
}

六、最后建议,前后分离,如果调不通,看看前端代码,console.log(error) 多输出日志,debug跟踪一下

Java通过freemarker实现导出PDF相关推荐

  1. java 通过模板生成导出PDF方案对比

    需求背景 目前项目中有通过 上传word模板,结合用户填写数据,导出渲染后的PDF数据,提升数据安全性.现记录一下使用过程及遇到的问题 项目方案 Adobe Acrobat Pro 打开刚刚制作的pd ...

  2. freemarker html 换行,java使用freemarker模板导出word,合并单元格,单元格内换行

    之前使用[XWPFDocument][]动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所 ...

  3. java使用freemarker模板导出word,合并单元格,单元格内换行

    之前使用XWPFDocument动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所以使用f ...

  4. java使用freemarker模版导出分页word

    1.模版的制作 (1).先用word制作好模版的样式,我的模版样式如下图 (2).将制作好的word模版另存为word 2003 XML文件,具体内容如下 <?xml version=" ...

  5. java iText 的jar导出pdf格式,禁止浏览器预览,直接下载功能

    后台使用iText来生成一个pdf文件,提供一个服务器的pdf访问地址,让前端拿到,浏览器下载,不过直接使用loaction.href的形式,浏览器都会默认进入一个预览的界面,这就导致很不好用,需要回 ...

  6. Java 用Freemarker完美导出word文档(带图片)

    第一步:制作word模板 第二步:格式转换,将word另存为xml 第三步:找到图片base64,删除base64替换成占位符${image},只修改图片的,其余的不用动 第四步:加入依赖 <d ...

  7. java根据excel模板导出pdf

    可以使用 Apache POI 库读取 excel 文件,然后使用 iText 或者 Apache PDFBox 库生成 PDF 文件.这两个库都提供了从已有文件或数据生成 PDF 的功能. 例如,使 ...

  8. java 图片 word文档_【Java】用Freemarker完美导出word文档(带图片)

    Java  用Freemarker完美导出word文档(带图片) 前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. ...

  9. java freemarker word_Java 用Freemarker完美导出word文档(带图片)(示例代码)

    Java  用Freemarker完美导出word文档(带图片) 前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. ...

最新文章

  1. Mac下编译Android源码,并导入IntelliJ IDEA进行源码阅读
  2. 97.PC 的串口是同步还是异步
  3. lecture6-mini批量梯度训练及三个加速的方法
  4. php ob 缓存,php中ob函数缓冲机制深入理解
  5. 数据结构-链表4-企业链表
  6. [Cocoa]NSApplication简介
  7. python自动给头像添加圣诞帽
  8. python 数据分析论文_用Python数据处理分析入门必备系列文章:基本类型与运算...
  9. 【编程软件】keli烧录代码点击Download或者Debug界面卡死
  10. 手机视频水印去不掉有马赛克
  11. 2020年CISP线下考试逐渐恢复啦
  12. 主成分分析结果成分不显著_主成分分析结果
  13. 基于TCP的socket详解(Linux系统)
  14. 【JVM基础】垃圾回收算法详解(引用计数、标记、清除、压缩、复制)
  15. C语言 学生成绩统计
  16. Matlab:生成日期与时间的序列
  17. Stream流学习记录
  18. Luogu 4844 LJJ爱数数
  19. Go Global 之怎样在全球Azure上使用Azure Free Account
  20. LeetCode算法题-Goat Latin Easy(Java实现)

热门文章

  1. 如何用CSS制作可以转动的魔方
  2. Could not create an instance of type T. Type is an interface or abstract class
  3. 第16章 潘多拉的盒子
  4. 2021-12-13 股票模拟交易心得8
  5. java 加密解密时间戳
  6. bytebuf池_Netty ByteBuf原理剖析
  7. tensorflow中tfrecord数据操作
  8. Redis高级类型(统计全站访问量,日活跃用户)
  9. 2020数据挖掘算法工程师面试总结
  10. Excel对数据区域按字体颜色统计个数的操作