Java 实现 HTML 转 PDF 文件

一、概述

我们在实际开发中会遇到各种不同的需求,接到一个需求把页面报告图表生成 PDF 格式。刚开始我的初步想法是用 IText 生成 PDF,但是 CSS 和 JS 样式,有的不兼容!最后还是基于WKHtmlToPdf 生成 PDF ,解决样式兼容和图表格式。

二、wkhtmltopdf 下载

wkhtmltopdf是一个用webkit网页渲染引擎开发的用来将html转成 pdf的工具,可跟多种脚本语言进行集成来转换文档,有windows、linux等平台版本。官网地址

技术特点:

Wkhtmltopdf可直接把浏览器中浏览的网页转换成一个pdf,他是一个把html页面转换成pdf的软件(需要安装在服务器上)。使用时可通过java代码调用cmd指令完成网页转换为pdf的功能。

安装:

点击 wkhtmltox.exe 安装

功能测试:

直接在cmd里输入测试指令,可查看处理进度。

在安装目录 bin 执行如下命令生成 PDF

wkhtmltopdf.exe https://www.baidu.com/ C:Usersuser.DESKTOP-8A9L631Desktop遂人	estaidu.pdf

三、Java 实现 HTML 转 PDF

@Slf4j(topic = "HtmlToPdfUtil")
public class HtmlToPdfUtil {

    /**
     * wkhtmltopdf在系统中的路径
     */
    private static String toPdfTool = Consts.CONVERSION_PLUGSTOOL_PATH_WINDOW;

    /**
     * html转pdf
     *
     * @param srcPath  html路径,可以是硬盘上的路径,也可以是网络路径
     * @param destPath pdf保存路径
     * @return 转换成功返回true
     */
    public static boolean convert(String srcPath, String destPath) {

        log.info("convert.req srcPath={} ,destPath={}",srcPath,destPath);
        File file = new File(destPath);
        File parent = file.getParentFile();
        // 如果pdf保存路径不存在,则创建路径
        if (!parent.exists()) {
            parent.mkdirs();
        }
        StringBuilder cmd = new StringBuilder();
        if (System.getProperty("os.name").indexOf("Windows") == -1) {
            // 非windows 系统
            toPdfTool = Consts.CONVERSION_PLUGSTOOL_PATH_LINUX;
        }
        cmd.append(toPdfTool);
        cmd.append(" ");
        cmd.append(" "");
        cmd.append(srcPath);
        cmd.append("" ");
        cmd.append(" ");
        cmd.append(destPath);

        System.out.println(cmd.toString());
        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;
    }

    public static void main(String[] args) {

        long startTime = System.currentTimeMillis();
        log.info("generate pdf start ... ");
//        HtmlToPdfUtil.convert("http://baijiahao.baidu.com/s?id=1701222360380918660&wfr=spider&for=pc", "D:\file\test\pdf" + StrUtil.SLASH + IdUtil.simpleUUID() + ".pdf");
        HtmlToPdfUtil.convert("https://blog..net/Hug_rj/article/details/89643290", "D:\file\test\pdf" + StrUtil.SLASH + IdUtil.simpleUUID() + ".pdf");
//        HtmlToPdfUtil.convert("https://www.aliyun.com/jiaocheng/285649.html", "F:/pdf/baidu.pdf");
        log.info("Time-consuming to generate pdf time(ms)={}",System.currentTimeMillis()-startTime);
    }
}

利用线程处理

public class HtmlToPdfInterceptor extends Thread {

    private InputStream is;
 
    protected HtmlToPdfInterceptor(InputStream is){
        this.is = is;
    }
 
    @Override
    public void run(){
        try{
            InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
            BufferedReader br = new BufferedReader(isr);
            String line ;
            while ((line = br.readLine()) != null) {
                System.out.println(line); //输出内容
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

生成 PDF


经验分享 程序员 微信小程序 职场和发展