java html转pdf 无法支持中文_java项目实现html转pdf的需求(支持中文和CSS样式)
java项目中用到了html转pdf的需求,现在写一个自己认为最优方案的总结,虽然还是有一些小的bug
为了保证中文的支持需要在被转换的html添加body的添加中文字体样式,保持这个字体和后边转换pdf的字体一致就可以了,不需要必须是SimSun字体
body{
font-family:SimSun;
}
下面放上jar包的引用pom
注意:org.xhtmlrenderer.core-renderer.R8的jar包,其实需要做一些修改,直接用的话不支持中文换行,可以点击下载支持中文换行的jar包,修改jar包名字替掉R8的jar包
org.xhtmlrenderer
core-renderer
R8
org.apache.commons
commons-lang3
3.0
com.itextpdf
itextpdf
5.5.10
com.itextpdf
html2pdf
2.0.0
这种方式对html里的代码样式要求比较严格,类似xhtml的标准,要求html中的标签都是闭合的,像meta和link这样的标签以及空格 ;这类的转义符都会导致转换pdf报错,因此最好在之前将html代码进行处理,以下是处理代码:
import java.io.File;
import java.io.FileInputStream;
import com.itextpdf.html2pdf.jsoup.Jsoup;
import com.itextpdf.html2pdf.jsoup.nodes.Document;
import com.itextpdf.html2pdf.jsoup.nodes.Entities;
public class HtmlToXHtmlJsoup {
public static String html2xhtml(String html) {
Document doc = Jsoup.parse(html);
doc.outputSettings().syntax(Document.OutputSettings.Syntax.xml).escapeMode(Entities.EscapeMode.xhtml);
return doc.html();
}
public static void main(String[] args) throws Exception {
// File file = new File("E:\\html2xhtml.html");
File file = new File("report01.html");
FileInputStream input = new FileInputStream(file);
int size = input.available();
byte[] buff = new byte[size];
input.read(buff);
input.close();
String html = new String(buff, "utf-8");
System.out.println("============html===================");
System.out.println(html);
String xhtml = HtmlToXHtmlJsoup.html2xhtml(html);
System.out.println("============xhtml===================");
System.out.println(xhtml);
}
}
图片Base64支持类,没有用到可以不需要此类
import java.io.IOException;
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 com.lowagie.text.BadElementException;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.codec.Base64;
/**
* * 图片base64支持,把图片转换为itext自己的图片对象 * @author Administrator *
*/
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 e2) {
fsImage = null;
}
if (fsImage != null) {
// 对图像进行缩放
if (cssWidth != -1 || cssHeight != -1) {
fsImage.scale(cssWidth, cssHeight);
}
//if(fsImage.getHeight()>5000) {
//fsImage.scale(cssWidth, 5000);
//}
return new ITextImageElement(fsImage);
}
}
return null;
}
/**
* 编解码base64并生成itext图像
* @param srcAttr
* @param uac
* @return
* @throws IOException
* @throws BadElementException
*/
protected FSImage buildImage(String srcAttr, UserAgentCallback uac) throws IOException,BadElementException {
FSImage fiImg=null;
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;
}
@Override
public void reset() {
}
@Override
public void remove(Element e) {
}
@Override
public void setFormSubmissionListener(FormSubmissionListener listener) {
}
}
具体的java中html转pdf的实现,不需要图片base64支持的可以注释掉if(true)代码块,中文字体支持的Fonts/SimSun.ttc是我自己的字体存放位置,具体的路径需要改为自己的
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
public class HtmltoPDF {
public static void main(String[] ages) throws Exception {
html2pdf("C:/Users/I/Desktop/新建文本文档.html", "C:/Users/I/Desktop/新建文本文档.pdf");
}
public static void html2pdf(String inputFile, String outFile) throws Exception {
String url;
OutputStream os = null;
try {
url = new File(inputFile).toURI().toURL().toString();
os = new FileOutputStream(outFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
// 解决中文不显示问题
ITextFontResolver fontResolver = renderer.getFontResolver();
// 图片base64支持,把图片转换为itext自己的图片对象,如果不需要可以去掉if代码块
if(true) {// 如果携带图片则加上以下代码,将图片标签转换为Itext自己的图片对象
renderer.getSharedContext().setReplacedElementFactory(new Base64ImgReplacedElementFactory());
renderer.getSharedContext().getTextRenderer().setSmoothingThreshold(0);
}
// 解决图片的相对路径问题
//renderer.getSharedContext().setBaseURL("file:D:/");
/* 字体具体路径:Fonts/SimSun.ttc,所选的字体需要与转换的html中的字体一致,可添加多种字体 */
fontResolver.addFont("Fonts/SimSun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);// 宋体字
renderer.layout();
renderer.createPDF(os);
renderer.finishPDF();
} catch (MalformedURLException e) {
e.printStackTrace();
throw new Exception("生成pdf失败");
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Exception("生成pdf失败");
} catch (com.lowagie.text.DocumentException e) {
e.printStackTrace();
throw new Exception("生成pdf失败");
} catch (IOException e) {
e.printStackTrace();
throw new Exception("生成pdf失败");
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
throw new Exception("生成pdf失败");
}
}
}
}
public static void html2pdf2(String html,String outputFile) {
OutputStream os = null;
try {
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver fontResolver = renderer.getFontResolver();
os = new FileOutputStream(outputFile);
fontResolver.addFont("Fonts/SimSun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.setDocumentFromString(html);
// 解决图片的相对路径问题
//renderer.getSharedContext().setBaseURL("file:D:/");
renderer.layout();
renderer.createPDF(os);
} catch (DocumentException | IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
以下基本上就可以进行测试了。
还有一些bug,其中一个就是图片出现在换页的位置就会被截断,暂时没有找到处理的方法,如下:
如果有人解决了,希望能在下方回复下解决方法,不胜感激。
java html转pdf 无法支持中文_java项目实现html转pdf的需求(支持中文和CSS样式)相关推荐
- java生成pdf不支持中文_java生成pdf以及解决中文中文乱码问题
[在网上搜了一下iText的东东,简单的整理了一个Demo,解决了中文乱码问题,这里不贴链接了 网上搜一下就行了package com.westdream.test;import java.io.Fi ...
- java pdf模版的遍历_java使用itext操作填充pdf模板
一.先创建pdf模板 1.先用word做出界面 image.png 2.再转换成pdf格式 image.png image.png 3.用Adobe Acrobat 打开你刚刚用word转换成的pdf ...
- lua 不支持中文字符_英雄联盟跳票?不支持中文?别急看这里!界面最强翻译!...
大家期待英雄联盟手游已经很久了,16 号放出消息苦苦等待 28 号.老范跟大家的心情是一样的,注册拳头账号遇到种种问题,半天注册不成功等,要么就是卡在最后一步. 注册麻烦就不用说了,约定好的日子就跳票 ...
- java jsoup html_使用JAVA中的JSOUP从HTML中提取CSS样式
如果样式嵌入在Element中,则只需使用.attr("style"). JSoup不是Html渲染器,它只是一个HTML解析器,因此您必须从检索到的< style>中 ...
- 在Unix/Linux上令(java)JVM支持中文输出
在Unix/Linux上令(java)JVM支持中文输出 一.在Unix/Linux上令JVM支持中文输出 如 果用户使用的是UNIX的远程服务器,就会遇到中文字体在图像中输出的问题,特别是由于许多管 ...
- Flying Saucer 不支持中文,换行,粗体,CheckBox多选框的解决方案
最近要生成打印版的保单信息,内容比较多,也比较复杂,iText直接生成的话,想必花很多时间,而且可能也很难维护,偶然看到了HTML 在 Fly Saucer的帮助下能转换成PDF,解析CSS还不错,顿 ...
- opencv中的imread不支持中文路径的解决办法
其实严格来说,不是imread不支持中文路径,而是不支持non-ascii.所以不论路径如何转换编码格式,应该都不能解决问题. 解决的思路就是先用其他支持中文的API,把图片数据导入到内存中,然后通过 ...
- php json支持中文,php json 支持中文
支持中文的 php json 函数 /************************************************************** * *使用特定function对数组 ...
- c语言添加输入函数吗,C语言scanf()函数下支持中文输入吗?
C语言scanf()函数下支持中文输入吗? C语言scanf()函数下支持中文输入吗? 如果我编写一个程序,要求是先输入姓,再输入名,然后按照常姓名的方式排列出来,如果我需要输入中文该怎么办? 搜索更 ...
最新文章
- markdown常用操作(特殊字符显示、换行、字体颜色和大小、图片位置和大小)
- (转载)机器学习知识点(十一)隐马尔可夫模型
- Android IPC机制(五)用Socket实现跨进程聊天程序
- 这不是商业互吹,是学习的宝藏
- 中国制造强在哪儿?从美特斯邦威到Shein
- 计算机网络学习笔记(7. 报文交换与分组交换①)
- ssh GSSAPIAuthentication 参数
- java编写万年历的报告,用java编写的万年历代码
- 安卓 MediaRecorder 音频录制效果很差 模糊解决
- Struts1 页面提交到ActionForm,form为null
- 【c++NOIP2015 普及组】 推销员
- 关于匿名者组织(Anonymous),你都知道哪些?
- 基础算法学习大纲(附加yxc大佬算法模板)
- MATLAB 中nargin函数
- HDLBits Lemmings1-4
- 学习【Cesium】第六篇,Cesium地图点云与地形的加载(学不会揍我)
- 一个小公司老板的日常管理
- 北京2008福娃2图标
- “兼并”还是“合作” 宏碁方正各怀鬼胎
- 【云安全】云计算中常见的网络虚拟化