富文本内容(包含图片)转为pdf格式–本人亲测有效
1. 先把富文本内容填到html模板里面
查看此文章根据HTML模板动态生成html文件
2.把html文件转换为pdf
(1). 添加依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
(2)创建itext图片对象,把html中的img转为此对象
package com.sjl.springboot_demo.config;
import com.lowagie.text.BadElementException;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.codec.Base64;
import org.w3c.dom.Element;
import org.xhtmlrenderer.extend.FSImage;
import org.xhtmlrenderer.extend.ReplacedElement;
import org.xhtmlrenderer.extend.ReplacedElementFactory;
import org.xhtmlrenderer.extend.UserAgentCallback;
import org.xhtmlrenderer.layout.LayoutContext;
import org.xhtmlrenderer.pdf.ITextFSImage;
import org.xhtmlrenderer.pdf.ITextImageElement;
import org.xhtmlrenderer.render.BlockBox;
import org.xhtmlrenderer.simple.extend.FormSubmissionListener;
import java.io.IOException;
public class Base64ImgReplacedElementFactory implements ReplacedElementFactory {
/**
* * 实现createReplacedElement 替换html中的Img标签
* *
* * @param c 上下文
* * @param box 盒子
* * @param uac 回调
* * @param cssWidth css宽
* * @param cssHeight css高
* * @return ReplacedElement
*
*/
public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac,int cssWidth, int cssHeight) {
Element e = box.getElement();
if (e == null) {
return null;
}
String nodeName = e.getNodeName();
// 找到img标签
if (nodeName.equals("img")) {
String attribute = e.getAttribute("src");
FSImage fsImage;
try {
// 生成itext图像
fsImage = buildImage(attribute, uac);
} catch (BadElementException e1) {
fsImage = null;
} catch (IOException e1) {
fsImage = null;
}
if (fsImage != null) {
// 对图像进行缩放
if (cssWidth != -1 || cssHeight != -1) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
}
return null;
}
/**
* * 编解码base64并生成itext图像
*
*/
protected FSImage buildImage(String srcAttr, UserAgentCallback uac) throws IOException,
BadElementException {
FSImage fiImg = null;
//图片的src要为src="https://img-blog.csdnimg.cn/2022010619081717015.jpg"这种base64格式
if (srcAttr.toLowerCase().startsWith("data:image/")) {
String base64Code = srcAttr.substring(srcAttr.indexOf("base64,") + "base64,".length(), srcAttr.length());
// 解码
byte[] decodedBytes = Base64.decode(base64Code);
fiImg = new ITextFSImage(Image.getInstance(decodedBytes));
} else {
fiImg = uac.getImageResource(srcAttr).getImage();
}
return fiImg;
}
public void reset() {
}
@Override
public void remove(Element arg0) {
}
@Override
public void setFormSubmissionListener(FormSubmissionListener arg0) {
}
}
(3).创建工具类,把html转为pdf
package com.sjl.springboot_demo.controller;
import com.itextpdf.text.pdf.BaseFont;
import com.sjl.springboot_demo.config.Base64ImgReplacedElementFactory;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class HtmlToPDF {
/**
* 将HTML转成PD格式的文件。html文件的格式比较严格
* @param htmlFile
* @param pdfFile
* @throws Exception
*/
// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
public static void html2pdf(String htmlFile, String pdfFile) throws Exception {
// step 1
String url = new File(htmlFile).toURI().toURL().toString();
System.out.println(url);
// step 2
File file = new File(pdfFile);
File file1 = new File(file.getParent());
if(!file1.isDirectory()){
file1.mkdirs();
}else {
System.out.println("已经创建");
}
if(!file.exists()){
file.createNewFile();
}else {
System.out.println("文件已经存在");
}
OutputStream os = new FileOutputStream(pdfFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
renderer.getSharedContext().setReplacedElementFactory(new Base64ImgReplacedElementFactory());
renderer.getSharedContext().getTextRenderer().setSmoothingThreshold(0);
// step 3 解决中文支持
ITextFontResolver fontResolver = renderer.getFontResolver();
if("linux".equals(getCurrentOperatingSystem())){
fontResolver.addFont("/usr/share/fonts/chiness/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
}else{
fontResolver.addFont("c:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
}
renderer.layout();
renderer.createPDF(os);
os.close();
System.out.println("create pdf done!!");
}
public static String getCurrentOperatingSystem(){
String os = System.getProperty("os.name").toLowerCase();
System.out.println("---------当前操作系统是-----------" + os);
return os;
}
public static void main(String[] args) {
// String htmlFile = "/home/lbj/sign.jsp";
// String pdfFile = "/home/lbj/sign.pdf";
String htmlFile = "D:\\paper-document\\upload\\user.html";
String pdfFile = "D:\\topdf\\user.pdf";
try {
HtmlToPDF.html2pdf(htmlFile, pdfFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:
- html文件里面的标签必须有结束符 " / ",给img,br标签加结束符
content.replace("<br>", "<br/>");
- body里面添加样式
style="font-family: SimSun;"