前言:接上篇freemarker生成word后,因为我们生成的是假word文档,底层还是xml,微信等app识别不了(目前还没有较好的技术解决这个问题)。所以产生了新的需求,把word的内容生成张图片。这样就可以在app端查看。
导包
<!-- html生成图片-->
<dependency>
<groupId>com.github.xuwei-k</groupId>
<artifactId>html2image</artifactId>
<version>0.1.0</version>
</dependency>
生成一个ftl的html模板,就像利用freemarker生成word一样。然后替换模板的内容,这些就不在写了。可参考freemarker生成word文档
这里我转化的图片后缀用的是png,因为jpg下出来带背景颜色。由于时间原因没在研究
模板替换好后使用html2image将html转化为图片
html2image相关方法:
loadUrl(url) - Loads HTML from URL object or URL string. (从url载入html)
loadHtml(html) - Loads HTML source. (载入本地html)
saveAsImage(file) - Save loaded HTML as image. (以图片形式保存html)
saveAsHtmlWithMap(file, imageUrl) - Creates an HTML file containing client-side image-map
自定义utils
FreemarkerUtils jar 项目
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import gui.ava.html.image.generator.HtmlImageGenerator;
import freemarker.template.Configuration;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;
public class FreemarkerUtils {
private static String getTemplate(String template, Map<String, Object> map, String filePath, String fileName) throws IOException, TemplateException {
@SuppressWarnings("deprecation")
Configuration cfg = new Configuration();
// String templatePath = FreemarkerUtils.class.getResource("/").getPath() + "/ftl"; windows 上
// cfg.setDirectoryForTemplateLoading(new File(templatePath));
cfg.setClassForTemplateLoading(FreemarkerUtils.class, "/ftl/");
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
Template temp = cfg.getTemplate(template);
StringWriter stringWriter = new StringWriter();
temp.process(map, stringWriter);
stringWriter.flush();
stringWriter.close();
return stringWriter.getBuffer().toString();
}
public static void turnImage(String template, Map<String, Object> map, String filePath, String fileName, HttpServletResponse response) throws Exception {
String html = getTemplate(template, map, filePath, fileName);
HtmlImageGenerator imageGenerator = new HtmlImageGenerator();
try {
imageGenerator.loadHtml(html);
Thread.sleep(500);//加入睡眠时间给充分的转化图片时间
imageGenerator.getBufferedImage();
Thread.sleep(500);
imageGenerator.saveAsImage(filePath + File.separator + fileName);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("将HTML文件转换成图片异常");
}
}
}
FreemarkerUtils war 项目
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import gui.ava.html.image.generator.HtmlImageGenerator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
public class FreemarkerUtils {
private static String getTemplate(HttpServletRequest request, String template, Map<String, Object> map, String filePath, String fileName) throws IOException, TemplateException {
@SuppressWarnings("deprecation")
Configuration cfg = new Configuration();
// String templatePath = FreemarkerUtils.class.getResource("/").getPath() + "/ftl";
// cfg.setDirectoryForTemplateLoading(new File(templatePath));
cfg.setServletContextForTemplateLoading(request.getServletContext(), "/ftl");
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
Template temp = cfg.getTemplate(template);
StringWriter stringWriter = new StringWriter();
temp.process(map, stringWriter);
stringWriter.flush();
stringWriter.close();
return stringWriter.getBuffer().toString();
}
public static void turnImage(HttpServletRequest request, String template, Map<String, Object> map, String filePath, String fileName, HttpServletResponse response) throws Exception {
String html = getTemplate(request, template, map, filePath, fileName);
HtmlImageGenerator imageGenerator = new HtmlImageGenerator();
try {
imageGenerator.loadHtml(html);
Thread.sleep(500);
imageGenerator.getBufferedImage();
Thread.sleep(500);
imageGenerator.saveAsImage(filePath + File.separator + fileName);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("将HTML文件转换成图片异常");
}
}
实际应用
前后分离项目返回base64字符串,前端处理
转base64用的包org.apache.commons.codec.binary;
String fileName = fileName + customerInfoId + ".png";
File file = null;
try {
FreemarkerUtils.turnImage("drawImgTemplate.ftl", map, filePath, fileName, response);
// 通过文件路径获得File对象(假如此路径中有一个download.pdf文件)
file = new File(filePath + File.separator + fileName);
return file2Base64(file);
} catch (Exception e) {
logger.error("图纸下载图片失败", e);
} finally {
if (file != null) {
file.delete();
}
}
private String file2Base64(File file) {
if (file == null) {
return null;
}
String base64 = null;
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
byte[] buff = new byte[fin.available()];
fin.read(buff);
base64 = Base64.encodeBase64String(buff);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return base64;
}
war项目:
String fileName = fileName + customer.getId() + ".png";
try {
FreemarkerUtils.turnImage(request, "drawImgTemplate.ftl", map, filePath, fileName, response);
DownloadUtils.fileDownload(response, filePath, fileName);
} catch (Exception e) {
logger.error("图纸下载图片失败", e);
} finally {
File file = new File(filePath + fileName);
if (file != null) {
file.delete();
}
}
这里都别忘了删除存在我们项目下的图片
问题
如果放在liunx上,中文字体乱码,因为linux没有该字体,服务器放上该字体后即可
写的有点乱,就是记录下自己遇到的。