首页 > 代码库 > 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;

    }

   

    /**

     * htmlpdf

     *

     * @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 静态页面部分功能