Junhc

岂止于博客

使用xhtmlrenderer将html转成图片

1、pom.xml新增xhtmlrenderer依赖
<dependency>
  <groupId>org.xhtmlrenderer</groupId>
  <artifactId>core-renderer</artifactId>
  <version>R8</version>
</dependency>
2、模板 template.xhtml 一定要是标准的HTML,否则会报错
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head lang="en">  
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
</head>  
<body style="font-family:SimSun;">
  ...
</body>
</html>
3、核心代码
int width = 600, height = 800;
File template = new File("xxx/template.xhtml");
Java2DRenderer renderer = new Java2DRenderer(template, width, height);
// 自动装载字体..
// 这样就不需要服务器安装字体了..(跳过第4..
AWTFontResolver fontResolver = (AWTFontResolver) renderer.getSharedContext().getFontResolver();
fontResolver.setFontMapping(FontEnums.SIMSUN.getName(), FontEnums.SIMSUN.getFont());
BufferedImage image = renderer.getImage();
FSImageWriter imageWriter = new FSImageWriter();  
imageWriter.write(img, "xxx/xxx.png");
4、Linux服务器缺乏中文字库,导致中文乱码
// 4.1 查看系统字体..
fc-list
// fc-list:command not found...
// 说明没有安装字体库..

// 4.2 安装字体库..
yum -y install fontconfig

// 4.3 将字体.ttf文件拷贝到/usr/share/fonts/文件夹下

// 4.5 重启服务器
5、将字体.ttf文件拷贝到/resources/资源文件下,自动装载字体,部署环境时,就不用操心字体了
public enum FontEnums {
    SIMSUN("SimSun", "simsun.ttf"),
    ;
    private String name;
    private String path;
    private Font font;

    FontEnums(String name, String path) {
        this.name = name;
        this.path = path;
    }

    public String getName() {
        return this.name;
    }

    public Font getFont() {
        if (null == font) {
            InputStream is = null;
            BufferedInputStream bis = null;
            try {
                is = Resources.getResourceAsStream(path);
                bis = new BufferedInputStream(is);
                // 可能会报 "java.awt.FontFormatException: bad table, tag=23592960" 错误..
                font = Font.createFont(Font.TRUETYPE_FONT, bis);
            } catch (Exception e) {
            } finally {
                try {
                    if (bis != null) {
                        bis.close();
                    }
                } catch (Exception e) {
                }
                try {
                    if (is != null) {
                        is.close();
                    }
                } catch (Exception e) {
                }
            }
        }
    }
}
6、解决 “java.awt.FontFormatException: bad table, tag=23592960” 问题

发现本地运行时与使用maven打包之后的ttf文件大小不一致

以下摘自maven文档

Warning: Do not filter files with binary content like images! This will most likely result in corrupt output.

警告:不要过滤含有二进制内容的文件,如图像!这很可能导致输出损坏。

If you have both text files and binary files as resources it is recommended to have two separated folders. One folder src/main/resources (default) for the resources which are not filtered and another folder src/main/resources-filtered for the resources which are filtered.

如果您同时拥有文本文件和二进制文件作为资源,建议使用两个独立的文件夹。一个文件夹src/main/resources(默认)用于未过滤的资源,另一个文件夹src/main/resources-filtered用于已过滤的资源。

在pom.xml文件中,添加maven-resources-plugin插件,通过nonFilteredFileExtension过滤后缀为ttf的文件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <encoding>UTF-8</encoding>
        <nonFilteredFileExtensions>
            <nonFilteredFileExtension>ttf</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
    </configuration>
</plugin>