公司最近做一个交易所项目,里面涉及一个需求就是将html模板,在填充数据后转换为pdf,这样防止数据更改,下面是具体实现

1 pom文件

     <dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>7.1.2</version>
</dependency>

2 html转pdf

itext7进行html转换使用类:com.itextpdf.html2pdf.HtmlConverter
  它主要有三类操作:convertToPdf直接转换为pdf文件
           convertToDocument转为document文档,这样有利于进行pdf页面调整
           convertToElements拆解pdf标签
我这里因为html转换后会有多页,这里通过convertToDocument调整页面大小,在一页上显示所有内容;
同时我使用ByteArrayOutputStream类,这个的好处是不在本地生成文件,减少磁盘操作,但是这种方式也有人说效率不高,使用者可以斟酌后使用.
因为spring boot存在打包后resources目录文件获取不到的问题,所以我将pdf依赖的字体文件放到项目的根路径下(跟src目录同级).
package com.ssth.exchanage.excenter.common.uitls;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.canvas.draw.ILineDrawer;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.LineSeparator; public class PDFUtil {
private static final String FONT = "./pdf/font/NotoSansCJKsc-Regular.otf"; /**
* @Description 将html转换为pdf文件
* @param html html页面字符串
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public ByteArrayOutputStream html2Pdf(String html) throws FileNotFoundException, IOException {
ConverterProperties props = new ConverterProperties();
DefaultFontProvider defaultFontProvider = new DefaultFontProvider(false, false, false);
defaultFontProvider.addFont(font);
props.setFontProvider(defaultFontProvider);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(bao);
PdfDocument pdf = new PdfDocument(writer);
pdf.setDefaultPageSize(new PageSize(595, 14400));
Document document = HtmlConverter.convertToDocument(html, pdf, props);
EndPosition endPosition = new EndPosition();
LineSeparator separator = new LineSeparator(endPosition);
document.add(separator);
document.getRenderer().close();
PdfPage page = pdf.getPage(1);
float y = endPosition.getY() - 36;
page.setMediaBox(new Rectangle(0, y, 595, 14400 - y));
document.close();
return bao;
} /**
* 定义操作区域
*/
class EndPosition implements ILineDrawer {
// y坐标
protected float y; /**
* @Description: 获取y坐标
* @return
*/
public float getY() {
return y;
} /**
* @Description: 操作画布特定区域
* @param pdfCanvas:操作画布
* @param rect:操作区域
*/
@Override
public void draw(PdfCanvas pdfCanvas, Rectangle rect) {
this.y = rect.getY();
} /**
* @Description: 获取行颜色
* @return
*/
@Override
public Color getColor() {
return null;
} /**
* @Description: 获取行宽
* @return
*/
@Override
public float getLineWidth() {
return 0;
} /**
* @Description: 设置行颜色
* @param color
*/
@Override
public void setColor(Color color) {
} /**
* @Description: 设置行宽
* @param lineWidth:宽度
*/
@Override
public void setLineWidth(float lineWidth) {
}
}
}

3 流响应

核心是通过ByteArrayOutputStream.writeTo(HttpServletResponse.getOutputStream())方法

package com.huishi;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import com.ssth.exchanage.excenter.common.exception.ResException;
import com.ssth.exchanage.excenter.common.uitls.DateUtil;
import com.ssth.exchanage.excenter.common.uitls.PDFUtil;
import com.ssth.exchanage.excenter.controller.response.RecordApplyParamRep;
import com.ssth.exchanage.excenter.service.ProductRecordService; @Service
public class ProductRecordServiceImp implements ProductRecordService { /**
* @Description 打印备案申请书
* @param res http响应
*/
@Override
public void printRecord(HttpServletResponse res){
try {
  String htmlStr = FileUtil.readFile(null);
  PDFUtil pdfUtil = new PDFUtil();
  ByteArrayOutputStream stream = pdfUtil.html2Pdf(htmlStr);
  res.setHeader("Expires", "0");
  res.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
  res.setHeader("Pragma", "public");
  res.setContentType("application/pdf");
  OutputStream os = res.getOutputStream();
  stream.writeTo(os);
  os.flush();
  os.close();
} catch (IOException e) {
  log.error("printRecord {}",e.getMessage());
  throw new ResException("-1","服务内部错误,请稍后再试!");
}
}
}

备注:

itext7解决中文显示问题有两种解决方式:

1 引入对应的语言包,火狐浏览器预览生成的pdf可能存在部分中文乱码问题,同时因为加载了语言包,生成的pdf更大
使用NotoSansCJKsc-Regular.otf,同时在pom中引入com.itextpdf.font-asian包.
2 设置字体:通过默认字体生成,pdf文件和html大小几乎相同,不存在浏览器预览乱码问题
PdfFont font = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);

使用示例链接: https://github.com/liulei3/html2pdf 

参考文件:

html转pdf: https://developers.itextpdf.com/content/itext-7-examples/itext-7-converting-html-pdf

流响应:https://developers.itextpdf.com/content/best-itext-questions-stackoverview/general-questions-about-itext/itext7-how-can-i-serve-pdf-browser-without-storing-file-server-side

itext7 html转pdf实现的更多相关文章

  1. itext5和itext7操作pdf平铺和图层叠加(tiling, and N-upping)

    区别 itext5 生成pdf版本:1.4(Acrobat5.x) itext7 生成pdf版本:1.7(Acrobat8.x) iText7生成的pdf文件大, itext7 Java库更加系统和完 ...

  2. itext7史上最全实战总结

    1. itext7史上最全实战总结 1.1. 前言 最近有个需求需要我用Java手动写一份PDF报告,经过考察几种pdf开源代码,最终选取了itext7,此版本为7.1.11,由于发现网上关于该工具的 ...

  3. C# iText 7 切分PDF,处理PDF页面大小

    一.itext 我要使用itext做一个pdf的页面大小一致性处理,然后再根据数据切分出需要的pdf. iText的官网有关于它的介绍,https://itextpdf.com/ 然后在官网可以查找a ...

  4. Pdf文件处理组件对比(Aspose.Pdf,Spire.Pdf,iText7)

    目的 因为公司是做医疗相关软件的,所以经常和文档打交道,其中就包含了Pdf.医院的Pdf(通常是他们的报告)都千奇百怪,而我们一直以来都是在用一些免费且可能已经没人维护了的组件来处理Pdf,所以就经常 ...

  5. Java使用iText7生成PDF

    前言 我们之前使用js库html2canvas + jspdf实现html转PDF.图片,并下载(详情请戳:html页面转PDF.图片操作记录),大致原理是将页面塞到画布里,以图片的方式放到PDF中, ...

  6. C#生成pdf -- iText7 设置自定义字体和表格

    itextsharp已经不再更新,由iText 7来替代 安装 nuget 安装 itext7 注册自定义字体 下载字体文件 .ttc或.ttf到项目目录,设置更新则拷贝到输出目录,这样构建的时候会把 ...

  7. itext7知识点研究(PDF编辑)

    取出pdf文档文字 String sourceFolder2 = "E:\\picture2\\租赁合同2.pdf"; PdfDocument doc = new PdfDocum ...

  8. iText7生成pdf

    1 官网 http://developers.itextpdf.com/itext-java 2 form中加入表格 http://developers.itextpdf.com/content/be ...

  9. Java实现Html转PDF的方法

    写在前面 以下路径问题根据项目结构自己修改,以下是我使用spring boot打成jar包的写法. 一.需求背景 在前端编辑器中输入任意的文本,包括css样式变化,保存为html文本.通过Java后台 ...

随机推荐

  1. xml文件操作帮助类

    xml文件的节点值获取和节点值设置 /// <summary> /// 保存单个点节点的值 /// </summary> /// <param name="Up ...

  2. Java 之 匿名对象

    一.匿名对象 创建对象时,只有创建对象的语句,却没有把对象地址赋值给某个变量. 虽然是创建对象的简化写法,但是应用场景非常有限. 匿名对象:没有变量名的对象. 语法格式: new 类名(参数列表): ...

  3. 在iOS平台使用ffmpeg解码h264视频流

    来源:http://www.aichengxu.com/view/37145 在iOS平台使用ffmpeg解码h264视频流,有需要的朋友可以参考下. 对于视频文件和rtsp之类的主流视频传输协议,f ...

  4. Nginx 反向代理与负载均衡的配置

    已经很久没有写博了,因为最近学车加上各种问题一直没时间, 今天刚好想起有好多的东西还没来得及记录.回到正题: Nginx是一个非常强大的web轻量级服务器,许多大厂也用Nginx进行负载均衡和反向代理 ...

  5. Springboot 2.1.1.RELEASE 版本 session保存到MySQL里面

    1,pom.xml添加依赖: <!-- 数据库session管理 --> <dependency> <groupId>org.springframework.ses ...

  6. Httpd服务进阶知识-基于Apache Modele的LAMP架构之WordPress案例

    Httpd服务进阶知识-基于Apache Modele的LAMP架构之WordPress案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装依赖包及数据库授权 博主推荐阅读 ...

  7. MapReduce工程(IDEA)

    MapReduce工程(IDEA) hadoop 1. maven工程 1.1 创建maven工程 1.2 修改配置文件 1.3 Mapper类 1.4 Reduces类 1.5 Driver类 1. ...

  8. The 2016 ACM-ICPC Asia China-Final D. Ice Cream Tower 二分 + 贪心

    题目大意: 对于给出的n个冰激凌球的大小,满足下面的球的大小是上一个的至少2倍,对于给出的k(由k的冰激凌球才能算作一个冰激凌塔),问n个冰激凌球可以最多堆出多少个高度为k的冰激凌塔 题目分析: 对于 ...

  9. django项目中form表单和ajax的文件上传功能。

    form表单文件上传 路由 # from表单上传 path('formupload/',apply.formupload,name='formupload/'), 方法 # form表单文件上传 de ...

  10. jenkins邮件配置以及邮件添加附件详解

    1.在系统管理-系统设置  中找到邮件配置模块 填写情况如下图 第一步,填写系统管理员邮箱 第二步,填写邮箱配置 第三步,然后在项目中添加邮箱配置 项目中邮件设置中关于附件添加 因为我的项目目录中分3 ...