1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > java html转pdf 无法支持中文_java项目实现html转pdf的需求(支持中文和CSS样式)

java html转pdf 无法支持中文_java项目实现html转pdf的需求(支持中文和CSS样式)

时间:2023-12-08 09:59:37

相关推荐

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

mons

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 .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,其中一个就是图片出现在换页的位置就会被截断,暂时没有找到处理的方法,如下:

如果有人解决了,希望能在下方回复下解决方法,不胜感激。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。