使用Wkhtmltopdf导出PDF

Wkhtmltopdf是什么?引用官网的一句话

wkhtmltopdf and wkhtmltoimage are open source (LGPLv3) command line tools to render HTML into PDF and various image formats using the Qt WebKit rendering engine. These run entirely “headless” and do not require a display or display service.

为什么要用这个工具?

项目需要每个月自动在后台生成PDF报告存储到文件服务器,不能使用前端生成PDF的方法,所以找到了这个工具。

下载安装:https://wkhtmltopdf.org/downloads.html

​ Windows安装直接下一步到最后就可以。安装之后要配置环境变量,在path中加入C:\Program Files\wkhtmltopdf\bin根据自己的安装目录。然后就可以在运行命令,打开cmd:

C:\Users\Administrator>wkhtmltopdf https://www.baidu.com C:\Users\Administrator\Desktop\demo.pdf
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done

此时桌面就会生成一个百度首页的PDF文件。

命令格式

wkhtmltopdf [GLOBAL OPTION]... [OBJECT]... <output file>

常用的参数选项

  • –cookie 设置访问网页时的cookie,value 需要进行url编码(可重复使用此参数指定多个cookie)
  • –javascript-delay 延迟一定的毫秒,等待javascript执行完成(默认值是200)
  • –debug-javascript Show javascript debugging output(默认是不开启的)

更多参数选项参考官方文档

问题

​ 有的web页面导出的PDF文件内容不全,可以延长JavaScript执行等待时间。但是有的web页面怎么延长都还是内容缺失,甚至生成空白页,目前没搞明白什么原因导致的。

最后给一段参考demo代码

package com.company.project.demo;

import javax.servlet.http.Cookie;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

public class WkhtmltopdfDemo implements Runnable {

    private int consId = 1;

    // wkhtmltopdf工作目录
    public static final String WKHTMLTOPDF_WORKDIR = "C:\\Program Files\\wkhtmltopdf\\bin";
    // wkhtmltopdf启动程序
    public static final String WKHTMLTOPDF_PROGRAM = "C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe";
    // 生成pdf存储路径
    public static final String FILE_PATH = "C:\\Users\\Administrator\\Desktop\\test";

    public boolean processTool(ArrayList<String> command) {
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        processBuilder.directory(new File(WkhtmltopdfDemo.WKHTMLTOPDF_WORKDIR));
        processBuilder.redirectErrorStream(true);
        try {
            Process process = processBuilder.start();
            assert process.getInputStream().read() == -1;
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println("cmd" + line);
            }
            bufferedReader.close();
            process.waitFor();
            if (process.exitValue() != 0) {
                System.out.println("非正常结束");
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static String createFileDirectory(String filePath) {
        File file = new File(filePath);
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        return filePath;
    }

    public boolean wkhtmltopdfTool(String htmlURL, String filePath, Cookie[] cookies) {
        ArrayList<String> command = new ArrayList<>();
        command.add(WkhtmltopdfDemo.WKHTMLTOPDF_PROGRAM);
        for (Cookie cookie : cookies) {
            String value = cookie.getValue();
            command.add("--cookie");
            command.add(cookie.getName());
            command.add((value == null || "".equals(value.trim()) ? "null" : value));
        }
//        command.add("--javascript-delay");
//        command.add("5000");
//        command.add("--debug-javascript");
        command.add(htmlURL);
        command.add(filePath);
        boolean result = new WkhtmltopdfDemo().processTool(command);
        return result;
    }

    public boolean wkhtmltopdfTool(String htmlURL, String filePath) {
        ArrayList<String> command = new ArrayList<>();
        command.add(WkhtmltopdfDemo.WKHTMLTOPDF_PROGRAM);
//        command.add("--javascript-delay");
//        command.add("5000");
//        command.add("--debug-javascript");
        command.add(htmlURL);
        command.add(filePath);
        boolean result = new WkhtmltopdfDemo().processTool(command);
        return result;
    }

    public byte[] htmltopdfByte(String htmlURL, String fileName) {
        String filePath = WkhtmltopdfDemo.FILE_PATH + "\\" + fileName;
        byte[] bytes = null;
        WkhtmltopdfDemo wkhtmltopdfDemo = new WkhtmltopdfDemo();
        boolean result = wkhtmltopdfDemo.wkhtmltopdfTool(htmlURL, WkhtmltopdfDemo.createFileDirectory(filePath));
        if (result) {
            File file = new File(filePath);
            try {
                FileInputStream inputStream = new FileInputStream(file);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] b = new byte[1024];
                int n;
                while ((n = inputStream.read(b)) != -1) {
                    outputStream.write(b, 0, n);
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
                bytes = outputStream.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                file.delete();
            }
        }
        return bytes;
    }

    public File htmltopdfFile(String htmlURL, String fileName) {
        String filePath = WkhtmltopdfDemo.FILE_PATH + "\\" + fileName;
        File file = null;
        boolean result = new WkhtmltopdfDemo().wkhtmltopdfTool(htmlURL, WkhtmltopdfDemo.createFileDirectory(filePath));
        if (result) {
            file = new File(filePath);
        }
        return file;
    }

    @Override
    public void run() {
        WkhtmltopdfDemo wkhtmltopdfDemo = new WkhtmltopdfDemo();
        String htmlURL = "\"https://www.baidu.com\"";
        while (consId > 0) {
            String fileName = "test" + consId + ".pdf";
            String filePath = WkhtmltopdfDemo.FILE_PATH + "\\" + fileName;
            wkhtmltopdfDemo.wkhtmltopdfTool(htmlURL, WkhtmltopdfDemo.createFileDirectory(filePath));
            consId--;
        }
    }
    
    public static void main(String[] args) {
        WkhtmltopdfDemo wkhtmltopdfDemo = new WkhtmltopdfDemo();
        String htmlURL = "\"https://www.baidu.com\"";
        String fileName = "test.pdf";
        String filePath = WkhtmltopdfDemo.FILE_PATH + "\\" + fileName;
        wkhtmltopdfDemo.wkhtmltopdfTool(htmlURL, WkhtmltopdfDemo.createFileDirectory(filePath));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值