记录一下需求功能
之前做的模板文件转图片,联系到实际业务需要做很多pdf模板比较麻烦
现用freemarker 处理,将页面html存到数据库中,减少代码量模板多的情况下选择某个模板
<dependency>
<groupId>net.sf.cssbox</groupId>
<artifactId>cssbox</artifactId>
<version>4.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
代码:
public static void main(String[] args) throws Exception {
String StrTemplate = "<html>\n" +
"<head>\n" +
"<title></title>\n" +
"</head>\n" +
"<body>\n" +
"<form>\n" +
"姓名:<input type=\"text\" value=\"\" name=\"user\"><br><br>\n" +
"密码:<input type=\"password\" value=\"\" name=\"pass\"><br><br>\n" +
"性别:<tr><td>\n" +
" <input type=\"radio\" name=\"sex\" value=\"1\">男\n" +
" <input type=\"radio\" name=\"sex\" value=\"1\">女\n" +
" </td></tr><br><br>\n" +
" 喜爱的运动:<br><input type=\"checkbox\" name=\"baskball\" value=\"1\">篮球\n" +
" <input type=\"checkbox\" name=\"football\" value=\"1\">足球\n" +
" <input type=\"checkbox\" name=\"baseball\" value=\"1\">棒球\n" +
" <input type=\"checkbox\" name=\"volleyball\" value=\"1\">排球 <br><br>\n" +
" <input type=\"submit\"><br><br>\n" +
" <!-- 提交 -->\n" +
" 地址:<tr><td>\n" +
" <select multiple=\"multiple\">\n" +
" <option>北京</option>\n" +
" <option>上海</option>\n" +
" <option>天津</option>\n" +
" <option>深圳</option>\n" +
" <option>秦皇岛</option>\n" +
" </select>\n" +
" </td></tr><br><br>\n" +
" 个人简介:<br><textarea name=\"info\" cols=\"30\" rows=\"10\">填写信息</textarea><br><br>\n" +
" <fieldset>\n" +
" <legend>健康信息</legend>\n" +
" 身高:<input type=\"text\"> 体重:<input type=\"text\">\n" +
" </fieldset>\n" +
" <input type=\"button\" value=\"提交\">\n" +
" <input type=\"button\" value=\"重置\">\n" +
"</form>\n" +
"</body>\n" +
"</html>"; // 测试模板数据(一般存储在数据库中)
Map<String,Object> map = new HashMap<String,Object>(); // map,需要动态填充的数据
map.put("name", "张三");//需要赋值的属性 例: ${name}
FreemarkerUtils.turnImage(StrTemplate,map);
}
import cz.vutbr.web.css.MediaSpec;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.fit.cssbox.css.CSSNorm;
import org.fit.cssbox.css.DOMAnalyzer;
import org.fit.cssbox.demo.ImageRenderer;
import org.fit.cssbox.layout.BrowserCanvas;
import org.jsoup.Jsoup;
import org.jsoup.helper.W3CDom;
import org.jsoup.nodes.Document;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.util.Map;
public class FreemarkerUtils {
private static String mediaType = "screen";
private static Dimension windowSize = new Dimension(1200, 600);
private static boolean cropWindow = false;
private static boolean loadImages = true;
private static boolean loadBackgroundImages = true;
private static String getTemplate(String template, Map<String, Object> model) throws IOException, TemplateException, NoSuchFieldException {
if (template == null) {
return null;
}
StringWriter out = new StringWriter();
new Template("template", new StringReader(template)).process(model, out);
return out.toString();
}
public static void turnImage(String template, Map<String, Object> map) throws Exception {
String html = getTemplate(template, map);
Document document = Jsoup.parse(html);
W3CDom w3CDom = new W3CDom();
org.w3c.dom.Document w3cDoc = w3CDom.fromJsoup(document);
DOMAnalyzer da = new DOMAnalyzer(w3cDoc, null);
MediaSpec media = new MediaSpec(mediaType);
media.setDimensions((float) windowSize.width, (float) windowSize.height);
media.setDeviceDimensions((float) windowSize.width, (float) windowSize.height);
da.setMediaSpec(media);
da.attributesToStyles();
da.addStyleSheet((URL) null, CSSNorm.stdStyleSheet(), DOMAnalyzer.Origin.AGENT);
da.addStyleSheet((URL) null, CSSNorm.userStyleSheet(), DOMAnalyzer.Origin.AGENT);
da.addStyleSheet((URL) null, CSSNorm.formsStyleSheet(), DOMAnalyzer.Origin.AGENT);
da.getStyleSheets();
BrowserCanvas contentCanvas = new BrowserCanvas(w3cDoc.getDocumentElement(), da, null);
contentCanvas.setAutoMediaUpdate(false);
contentCanvas.getConfig().setClipViewport(cropWindow);
contentCanvas.getConfig().setLoadImages(loadImages);
contentCanvas.getConfig().setLoadBackgroundImages(loadBackgroundImages);
contentCanvas.createLayout(new Dimension(297, 210));
OutputStream out = new FileOutputStream("d:\\html111.png");
ImageIO.write(contentCanvas.getImage(), "png", out);
/**
*图片转base64
*/
contentCanvas.createLayout(new Dimension(297, 210));
ImageIO.write(contentCanvas.getImage(), "png", outputStream);
byte[] bytes = outputStream.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
String string = encoder.encode(bytes);
}
}
在网上找了好久没找到资料后来发现ImageRenderer里有demo!
相对于pdfbox 用pdf模板的方式改起来方便些
数据库设计及代码逻辑在实现这些功能的基础上再做修改就好了