wkhtmltopdf导出pdf的安装与使用
下载安装对应系统的wkhtmltopdf安装包,然后以命令形式执行
安装
1.下载安装包
我这里分别下载了window和centos的两个安装包,顺便提供对应阿里云盘方便下载
官网:wkhtmltopdf,阿里云盘:wkhtmltopdf
2.安装wkhtmltopdf
2.1 Windows
1.直接点击安装包安装,需记录安装路径
2.设置环境变量(win10)
- 打开我的电脑右键此电脑点击属性
- 点击右侧高级系统设置
- 点击环境变量选择系统变量里的path
- 新建一条路径信息,路径为wkhtmltopdf的bin目录,点击确定
3.测试
- 打开cmd命令行界面(win+r输入cmd回车)
wkhtmltopdf https://www.baidu.com/ D:\test.pdf
- 输入命令回车后查看文件是否存在
w
2.2 Linux
1.将rpm安装包上传到系统中,并切换到安装包路径
2.执行安装
- 安装前需先安装对应依赖
yum install xorg-x11-fonts-75dpi.noarch
- 安装
rpm -ivh wkhtmltox-0.12.6-1.centos7.x86_64.rpm
3.测试
wkhtmltopdf https://www.baidu.com/ /tmp/test.pdf
使用
1.中文乱码解决
- html内容需包含字符配置
<meta http-equiv="content-type" content="text/html;charset=utf-8">
- linux需将字体文件放在/usr/share/fonts目录下
可网上下载simsun字体,也可将window中的字体上传
2.页眉图片添加
- 页眉图片只能以html文件方式添加,并且文件中的图片最好以base64展示,否则可能无法展示
--header-html header.html
- html文件开头需包含DOCTYPE声明,否则无法展示
<!DOCTYPE html>
- 若页眉或页脚以html方式展示,则相对的页眉页脚也需存在一个html文件的引用,否则将无法展示
页脚的html文件中仅设置了背景为透明,否则页码与其他内容将不展示
wkhtmltopdf --margin-bottom 10 --header-html D:/header.html --footer-html D:/footer.html --footer-left 测试 --footer-right [page]/[topage] --footer-line --footer-spacing 3
整体使用语句示例
wkhtmltopdf --margin-bottom 10 --header-html D:/header.html --footer-html D:/footer.html --footer-left 测试 --footer-right [page]/[topage] --footer-line --footer-spacing 3 cover D:/cover.html toc --toc-header-text 目录 D:/test.html D:/test.pdf
3.由于Process.waitfor导致的进程挂起问题
在JAVA中使用shell脚本时,由于使Process.waitfor()方法可能会导致进程阻塞,因此无法完成pdf导出。
- 解决方法:在waitfor之前单独启用两个线程分别处理
Process process = Runtime.getRuntime().exec(command);
//处理InputStream的线程
new Thread(() -> {
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
try {
while ((line = in.readLine()) != null) {
System.out.println("output: " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line;
try {
while ((line = err.readLine()) != null) {
System.out.println("err: " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
err.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
process.waitFor(); //这个调用比较关键,就是等当前命令执行完成后再往下执行