JAVA用很多第三方库可以实现html转pdf,最出名的为Itextpdf。但是Itextpdf使用很容易碰到个各种样式问题、字体问题使用体验不是很好。
本文推荐使用flying-saucer-pdf,使用简单、兼容性、支持中文字体。
FlyingSaucer (https://github.com/flyingsaucerproject/flyingsaucer))
支持输入XML/XHtml + CSS2.1,除转换为PDF外,还支持转换为图片等其他格式。
引入以下依赖(flyingsaucer 底层需要依赖itexpdf)
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
<dependency>
<groupId>com.github.jtidy</groupId>
<artifactId>jtidy</artifactId>
<version>1.0.3</version>
</dependency>
注意:flyingsaucer只接受xml/xhtml,所以如果不能确保html内容严格遵守xml或者xhtml;由于现实开发很多页面不一定会严格按照html语法进行,如果不进行xhtm转载就会出现标签不闭合的报错。本文推荐使用JSoup或者JTidy进行解析和转换。本文使用JTidy;
废话不多说上代码,支持中文转换,亲测可以使用
/**
* html转pdf
* @param htmlFilePath
* @param outputFilePath
*/
public static void convertToPdf(String htmlFilePath, String outputFilePath) throws Exception{
try {
final String read = IoUtil.read(new FileReader(htmlFilePath));
String xhtml = convertHtmlToXhtml(read);
byte[] pdfData = convertHtmlToPDFData(xhtml);
FileUtils.writeByteArrayToFile(new File(outputFilePath), pdfData);
} catch (IOException e) {
e.printStackTrace();
}
}
private static byte[] convertHtmlToPDFData(String xhtml) throws Exception {
ITextRenderer renderer = new ITextRenderer();
//指定字体,字体放在resources下
renderer.getFontResolver().addFont("font/msyh.ttf", BaseFont.IDENTITY_H,true);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
renderer.setDocumentFromString(xhtml);
renderer.layout();
renderer.createPDF(outputStream);
return outputStream.toByteArray();
}
private static String convertHtmlToXhtml(String htmlContent){
Tidy tidy = new Tidy();
tidy.setXHTML(true);
tidy.setQuiet(true);
tidy.setShowWarnings(false);
StringWriter stringWriter =new StringWriter();
//转换为xhtml
tidy.parse(new StringReader(htmlContent), stringWriter);
return stringWriter.toString();
}
常见问题:
- Invalid nested tag head found, expected closing tag meta.
使用JSoup或者JTidy将html转换为xhtml;
- Table 'name' does not exist in font/msyh.ttf
解决方案,在maven中添加如下配置
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>utf-8</encoding>
<useDefaultDelimiters>true</useDefaultDelimiters>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
<nonFilteredFileExtension>woff</nonFilteredFileExtension>
<nonFilteredFileExtension>woff2</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>