首页 > 代码库 > wkhtmltox 使用 和 freemaker 静态页面部分功能
wkhtmltox 使用 和 freemaker 静态页面部分功能
真正关注博客园的时间不算长,参加工作的时间也很短,仅作为笔记记录工作,便于自己对技术的积累和巩固,有不对的地方大家直接抨击点评.
在工作中,遇到了这样的一个问题,原型展示的是下载功能,其实后台程序的处理过程是这样的; 将要下载下来的内容从html 转换成pdf 我使用了wkhtmltox 它; 再用流把转换好的pdf 下载下来; 首先说下 html 是通过freemaker 静态化来生成的 这中间就设计到了 ftl模板的加载,和 freemaker页面标签的使用;
一 ,首先加载 模板所在位置; 自己在resources下创建了 pageTemplate包这个包下放所有的静态模板ftl, 这个目录下的所有东西都会编译到classes文件下,所以我们需要手动的去获取项目的绝对路径 通过这个方法获取项目目录
new DefaultResourceLoader().getResource("").getFile().getAbsolutePath();
返回结果类似如下这个结构 D:\project\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ost.web\WEB-INF\classes
在通过手动拼装到 pageTemplate 和 模板名称 需要设置的内容装到map里面 (具体代码略过,有需要的联系);
通过配置文件 配置 生成路径 Global.getConfig("generate.certificatePath"); 这个方法会将配置文件中的html 生成位置传递进来;
二,Ftl 中使用到的简单标签取值
1,对象中的属性和 c 标签一致 通过${对象.属性} or ${对象.对象.属性}
2, list 的取值遍历 : <#list orderDetail.products as prod>切记不能少这个闭合标签</#list> List里面还有list需要继续
3, 同时 还有if 的判断 :
性 别:
<#if sex=="F">
女
<#elseif sex=="M">
男
<#else>
其他
</#if>
<br/>
成 绩:${score}分<br/>
级 别:
<#if (score >= 90) > <#-- 此处不加括号,则系统认为 “score >” 将scroe作为了条件 -->
非常优秀
<#elseif (score >= 80 && score < 90)>
优秀
<#elseif (score >= 70 && score < 80)>
良好
<#elseif (score >= 60 && score < 70)>
一般
<#else>
差劲
</#if>
<br/>
三,接下来 wkhtmltox 的使用了
1, http://wkhtmltopdf.org/ 下载应用,解压,安装
2,现今大多项目是部署在 linux 上的 wkhtmltox 很好的做到了这一点同样兼容 win 和linux
3,使用 参数1, htmlpath (html生成路径); 参数2, pafPath (转成pdf保存路径)当然html不使用freemarker 同样可以使用;
4,同样在java程序中需要将 wkhtmltopdf 直接放入自己的项目中的classes适应不同的服务;
5,调用的是 他的可执行文件;
6,需要手动的添加接口方法 ;
public class HtmlToPdf {
// wkhtmltopdf在系统中的路径 private static String toPdfTool = "";
public static String getWkPath() { toPdfTool = ""; if(ConverterUtil.isEmpty(toPdfTool)){ try { toPdfTool += SpringContextHolder.getApplicationContext().getResource("/WEB-INF/classes/wkhtmltox/bin").getFile().getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); } toPdfTool += (File.separator + "wkhtmltopdf"); if (!SystemPath.isLinuxOS()) { toPdfTool += ".exe"; } } return toPdfTool; }
/** * html转pdf * * @param htmlPath html路径,可以是硬盘上的路径,也可以是网络路径 * @param pafPath pdf保存路径 * @return 转换成功返回true * */ public static boolean convert(String htmlPath,String pafPath){ File file = new File(pafPath); File parent = file.getParentFile(); // 如果pdf保存路径不存在则创建路径 if(!parent.exists()){ parent.mkdirs(); }
StringBuilder cmd = new StringBuilder(); cmd.append(getWkPath()); cmd.append(" "); cmd.append("--page-size A4");// 参数 cmd.append(" "); cmd.append(htmlPath); cmd.append(" "); cmd.append(pafPath);
boolean result = true; try { Process proc = Runtime.getRuntime().exec(cmd.toString()); HtmlToPdfInterceptor error = new HtmlToPdfInterceptor(proc.getErrorStream()); HtmlToPdfInterceptor output = new HtmlToPdfInterceptor(proc.getInputStream()); error.start(); output.start(); proc.waitFor(); } catch (Exception e) { result = false; e.printStackTrace(); } return result;
} } |
接口方法
* 当调用wkhtmltopdf时,用于获取wkhtmltopdf返回的内容 * */
public class HtmlToPdfInterceptor extends Thread{ private InputStream is;
public HtmlToPdfInterceptor(InputStream is){ this.is = is; }
public void run(){ try { InputStreamReader isr = new InputStreamReader(is, "utf-8"); BufferedReader br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { System.out.println(line.toString()); //输出内容 } } catch (IOException e) { e.printStackTrace(); } }
} |
四, Linux下 wkhtmltox 的使用存在问题
1,转换出来的pdf中文可能会显示方块,需要将linux 下安装中文字体;
linux命令=> yum install fonts-chinese.noarch及缓存 fc-cache-fv
2,同时wkhtmltox 是每次部署的权限也会存在问题;
linux命令=>
用#ls -l wkhtmltox命令看看,如果显示类似如:
-rw-rw-rw- 1 root root ....
则表示任何用户都没有可执行权限(即使是root用户).
解决方法:
#chmod a+x wkhtmltox
PS:用字符串来设定文件访问权限。其中读用 r 表示,写用 w 表示,执行用 x 表示;所有者用 u 表示,组用户用 g 表示,其他用户用 o 表示,所有用户用 a 表示。例子:
chmod a+r,u+w,u+x,g+w a.txt
wkhtmltox 使用 和 freemaker 静态页面部分功能