当前位置: 安卓之星 -> Java开发 -> Java实现Html转PDF

Java实现Html转PDF

作者:网络 发表于: 2016-12-28 点击: 1,388 次

项目上的客户提出一个需求,把政务流程中的表单数据导出成pdf或者图片格式,用来作电子档案材料。表单基于公司的电子政务构建平台实现,在数据库保存的都是html格式,因此打算直接把表单html转成pdf或者图片。由于表单是已经写好了html页面,那我要做的就是能完美解析html+css的pdf生成工具。在百度上搜索html转pdf的结果,大部分都是用itext,itext的确是Java开源组件的第一选择。不过itext也有局限,就是要自己写模版,系统中的表单数量有好几百个,为每个表单做一个导出模版不现实。 
最后,wkhtmltopdf进入了我的选择范围。wkhtmltopdf是一个使用webkit网页渲染引擎开发的用来将 html转成 pdf的工具,可以跟多种脚本语言进行集成来转换文档。
官网地址 http://wkhtmltopdf.org/
github地址 https://github.com/wkhtmltopdf/wkhtmltopdf
wkhtmltopdf把html转成pdf很简单,只要在windows命令行中输入
d:\wkhtmltopdf.exe http://www.csdn.NET d:\csdn.pdf
就可以把csdn网页转成pdf,并保存到C盘根目录。
在java中调用wkhtmltopdf的命令Runtime.getRuntime().exec(“d:\wkhtmltopdf.exe http://www.csdn.Net d:\csdn.pdf”)就可以实现转换。
下面把命令封装成java工具类,方便调用。

public class HtmlToPdf {  
    //wkhtmltopdf在系统中的路径  
    private static final String toPdfTool = "d:\\wkhtmltopdf.exe";  
      
    /** 
     * html转pdf 
     * @param srcPath html路径,可以是硬盘上的路径,也可以是网络路径 
     * @param destPath pdf保存路径 
     * @return 转换成功返回true 
     */  
    public static boolean convert(String srcPath, String destPath){  
        File file = new File(destPath);  
        File parent = file.getParentFile();  
        //如果pdf保存路径不存在,则创建路径  
        if(!parent.exists()){  
            parent.mkdirs();  
        }  
          
        StringBuilder cmd = new StringBuilder();  
        cmd.append(toPdfTool);  
        cmd.append(" ");  
        cmd.append(srcPath);  
        cmd.append(" ");  
        cmd.append(destPath);  
          
        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;  
    }  
}

接收Process的输入和错误信息时,需要创建另外的线程,否则当前线程会一直等待(在Tomcat中有这种现象)。

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
  
/** 
 * 当java调用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.outlprintln(line.toString()); //输出内容  
            }  
        }catch (IOException e){  
            e.printStackTrace();  
        }  
    }  
}

在Servlet中调用

/** 
 * Html转PDF 
 */  
@WebServlet("/htmltopdf/servlet")  
public class HtmlToPdfServlet extends HttpServlet {  
    private static final long serialVersionUID = 1L;  
      
    /** 
     * Servlet接收参数path,获取html的url 
     */  
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        String path = request.getParameter("path");  
        if(path == null || path.equals("")){  
            return;  
        }  
          
        //获取pdf的临时保存路径  
        //tmp为网站下的目录  
        //把生成的pdf放到网站下以便下载  
        String pdfPath = request.getSession().getServletContext().getRealPath("/tmp");  
        String pdfName = UUID.randomUUID().toString() + ".pdf";  
          
        if(HtmlToPdf.convert(path, pdfPath + "/" + pdfName)){  
            response.sendRedirect(request.getContextPath() + "/tmp/" + pdfName);  
        }  
    }  
}

在浏览器中输入http://<网站路径>/htmltopdf/servlet?path=http://blog.csdn.net
java_html_pdf

相关文章

相关文章

赶快留言冒泡

  • 评论 (0)
  • 引用通告 (0)
目前还没有任何评论.
目前还没有任何Trackbacks和Pingbacks.
吐个泡浮上去.