目录
一、前言
之前听到公司同事在讨论用jdk原生api生成图片,但是awt原生api操作比较麻烦,样式也不好控制,因此想到了根据html文件转,搜罗了一番,发现了flyingsaucer。介绍如下:
二、html转图片
1、添加依赖
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-core</artifactId>
<version>9.1.22</version>
</dependency>
2、代码示例
(1)测试html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
<style>
body {
font-family: SimSun;
background: aliceblue;
margin: 0px;
padding: 0px;
}
div{
margin: 20px 0px;
}
</style>
</head>
<body>
<div>
<a href="https://test-img.yudhabhakti.co.id/bnc-public-bucket/bnc/file/xC3ABZ5mJv28iP_1KaB8Abb6BDOArvPeX-ijVpbjlms.pdf" download="fileName">
点击下载
</a>
</div>
<div style="color:burlywood">
首页内容
</div>
<div>
<table border="1px" cellspacing="0px">
<tr>
<th>姓名</th>
<th>电话</th>
</tr>
<tr>
<td>刘亚楼</td>
<td>13347293021</td>
</tr>
</table>
</div>
<script>
</script>
</body>
</html>
注意:这里我们设置了字体为宋体。
(2)代码示例
import org.xhtmlrenderer.simple.Graphics2DRenderer;
import org.xhtmlrenderer.swing.Java2DRenderer;
import org.xhtmlrenderer.util.FSImageWriter;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageRender {
public static void main(String[] args) throws IOException {
String basePath = System.getProperty("user.home") + File.separator + "flyingsaucer";
File source = new File(basePath, "test.html");
File orginalDest = new File(basePath, "original.png");
File g2drDest = new File(basePath, "G2DR.png");
// 有些css样式不支持,如背景颜色
Java2DRenderer renderer = new Java2DRenderer(source, 1024);
renderer.setBufferedImageType(BufferedImage.TYPE_INT_RGB);
BufferedImage java2dImage = renderer.getImage();
new FSImageWriter().write(java2dImage, orginalDest.toString());
// 支持css样式,如背景颜色
BufferedImage g2drImage = Graphics2DRenderer.renderToImageAutoSize(source.toURI().toURL().toExternalForm(), 1024, BufferedImage.TYPE_INT_ARGB);
ImageIO.write(g2drImage, "png", g2drDest);
}
}
3、演示结果
-
使用Java2DRenderer渲染的
original.png
,可以看到渲染的图片是没有背景颜色的。如下:
-
使用Graphics2DRenderer渲染的
G2DR.png
,是有背景颜色的,如下:
三、html转pdf
1、添加依赖
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.22</version>
</dependency>
备注:官方有标注说iText 2.x版本有尚未解决的安全bug,所以我们这里引入flying-saucer-pdf-itext5。
2、代码示例
import com.itextpdf.text.pdf.BaseFont;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.file.Paths;
public class PDFRender {
public static void main(String[] args) throws Exception {
String basePath = System.getProperty("user.home") + File.separator + "flyingsaucer";
String source = Paths.get(basePath, "test.html").toString();
File dest = Paths.get(basePath, "saucer.pdf").toFile();
try (OutputStream os = new FileOutputStream(dest)) {
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver fontResolver = renderer.getFontResolver();
// 必须添加能支持中文的字体,否则html内容有中文会不显示,同时body标签要设置font-family: SimSun
String fontPath = PDFRender.class.getResource("/font/simsun.ttc").getPath();
fontResolver.addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.setDocument(new File(source));
renderer.layout();
renderer.createPDF(os);
}
}
}
备注:
1、html文件内容和转图片的一致。
2、html转pdf时,如果html文件内容有中文,则必须设置能支持中文的字体,否则转pdf后中文不会显示。这里我们用的是宋体,字体simsun.ttc
文件可以直接在C:\Windows\Fonts
目录下找到,复制即可,如下:
3、演示结果
四、注意点
1、html转图片的源url
html转图片时,Graphics2DRenderer#renderToImageAutoSize方法的第一个参数为url,即
java.net.URL
实例的字符串形式,如:file:/C:/Users/liuyl1/flyingsaucer/test.html
。
2、部署到linux上后中文乱码
无论是html转图片还是html转pdf,如果服务器上没有支持中文的字体,就会出现中文乱码或者不显示问题,下面会介绍如何在Linux上安装字体。
五、Linux上安装字体
1、拷贝字体
上面我们说过在
C:\Windows\Fonts
目录下能找到simsun.ttc(宋体)
,创建目录将字体复制到下面目录:
mkdir -pv /usr/share/fonts/chinese/TrueType
2、赋予权限
chmod 755 /usr/share/fonts/chinese/TrueType
3、建立字体缓存
mkfontscale
(如果没有该命令需要安装一下:yum install mkfontscale)
fc-cache -fv
(如果没有该命令需要安装一下:yum install fontconfig)
4、查看安装的字体
fc-list
查看当前安装的字体,如下: