一 、前言
本文将会基于 SpringBoot版本:2.3.8.RELEASE
使用 wkhtmltopdf
转换成 pdf文件。
在使用wkhtmltopdf之前 同事有尝试用itext
创建的PDF我觉得兼容性不好,然后参考其他博客觉得wkhtmltopdf
兼容性在样式上好一些
tips:仅作为学习笔记记录
二 、安装wkhtmltopdf
2.1 环境
安装包: Github地址
先查看自己安装wkhtmltopdf
的环境
例子:
我这边服务是在k8s的容器里面,进入容器查看
cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
版本:buster
点击上面的安装包链接 ,选择 0.12.5
版本 Assets
里面有两个关于buster
安装的包
wkhtmltox_0.12.5-1.buster_amd64.deb
wkhtmltox_0.12.5-1.buster_i386.deb
2.2 安装
把我们准备好的 wkhtmltox_0.12.5-1.buster_amd64.deb
文件放入容器
kubectl cp ./wkhtmltox_0.12.5-1.buster_amd64.deb app-dataupload-548df6b957-k287b:./wkhtmltox_0.12.5-1.buster_amd64.deb -n namespace
进入容器后发现已经有了文件,切换到文件目录
// 安装 wkhtmltox
dpkg -i wkhtmltox_0.12.5-1.buster_amd64.deb
这里出现需要安装的依赖
// 尝试安装
apt-get install -y fontconfig libfreetype6 libjpeg62-turbo libpng16-16 libx11-6 libxcb1 libxext6 libxrender1 xfonts-75dpi xfonts-base
// 报错
E: Package 'fontconfig' has no installation candidate
E: Package 'libfreetype6' has no installation candidate
E: Package 'libjpeg62-turbo' has no installation candidate
E: Package 'libpng16-16' has no installation candidate
E: Package 'libx11-6' has no installation candidate
E: Package 'libxcb1' has no installation candidate
E: Package 'libxext6' has no installation candidate
E: Package 'libxrender1' has no installation candidate
E: Package 'xfonts-75dpi' has no installation candidate
E: Package 'xfonts-base' has no installation candidate
// 更新apt-get
apt-get update
// 连接超时
Get:1 http://security.debian.org/debian-security buster/updates InRelease [34.8 kB]
Get:2 http://security.debian.org/debian-security buster/updates/main amd64 Packages [379 kB]
Err:3 http://deb.debian.org/debian buster InRelease
Could not connect to deb.debian.org:80 (151.101.110.132), connection timed out
Err:4 http://deb.debian.org/debian buster-updates InRelease
Unable to connect to deb.debian.org:http:
Fetched 414 kB in 30s (13.7 kB/s)
Reading package lists... Done
W: Failed to fetch http://deb.debian.org/debian/dists/buster/InRelease Could not connect to deb.debian.org:80 (151.101.110.132), connection timed out
W: Failed to fetch http://deb.debian.org/debian/dists/buster-updates/InRelease Unable to connect to deb.debian.org:http:
W: Some index files failed to download. They have been ignored, or old ones used instead.
2.3 解决报错
两个问题:
- 安装时缺少关键依赖包
apt-update
连接不上
首先 apt-update
更换成国内源 ,之后再去安装依赖。这里需要注意的是打包成Docker镜像的时候需要提前安装好依赖
再去安装wkhtmltox
,不然打包成镜像会失败。
// 换成国内源
echo > /etc/apt/sources.list
echo -e "deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib \ndeb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib \ndeb http://mirrors.aliyun.com/debian-security stretch/updates main \ndeb-src http://mirrors.aliyun.com/debian-security stretch/updates main \ndeb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib \ndeb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib \ndeb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib \ndeb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib" > /etc/apt/sources.list
// 更新
apt-get update -y
// 安装缺少依赖库
apt-get install -y fontconfig libfreetype6 libjpeg62-turbo libpng16-16 libx11-6 libxcb1 libxext6 libxrender1 xfonts-75dpi xfonts-base
// 安装包
dpkg -i wkhtmltox_0.12.5-1.buster_amd64.deb
还有需要注意的是:
在 Dockerfile
中如果加 -e
选项会将其当作字符串拼接在前面
这样转换的pdf 中文会乱码 需要将字体放在 /usr/share/fonts/
目录下
2.4 DockerFile参考
# 基础镜像 包含jdk
FROM xxxx
COPY wkhtmltox_0.12.5-1.buster_amd64.deb wkhtmltox_0.12.5-1.buster_amd64.deb
COPY font/ /usr/share/fonts/
RUN echo > /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib \ndeb-src http://mirrors.aliyun.com/debian/ stretch main non-free contrib \ndeb http://mirrors.aliyun.com/debian-security stretch/updates main \ndeb-src http://mirrors.aliyun.com/debian-security stretch/updates main \ndeb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib \ndeb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib \ndeb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib \ndeb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib" > /etc/apt/sources.list && apt-get update -y && apt-get install -y fontconfig libfreetype6 libjpeg62-turbo libpng16-16 libx11-6 libxcb1 libxext6 libxrender1 xfonts-75dpi xfonts-base && dpkg -i wkhtmltox_0.12.5-1.buster_amd64.deb
MAINTAINER xxx
ADD *.jar app.jar
EXPOSE 80
ENTRYPOINT ["java","-jar", "-Dspring.profiles.active=test","/app.jar"]
三、Java 使用
/**
* url转换成PDF
* @param url 地址
* @param saveFilePath 存储PDF的地址
*/
@SneakyThrows({Exception.class})
public static void url2Pdf(String url, String saveFilePath) {
String command = String.format("%s %s %s", "wkhtmltopdf", url, saveFilePath);
Process process = null;
try {
process = Runtime.getRuntime().exec(command);
} catch (IOException e) {
throw new Exception("执行命令失败!");
}
// 等待当前命令执行完,再往下执行
process.waitFor();
log.info("=======【地址 {} 】======== FINISH: [{}] ===============", url,command);
}
四、总结
到这里基本上应该可以使用 wkhtmltox
总体的思路就是 把之前的jdk
镜像和 wkhtmltox
集成 制作成新的基础镜像
然后在项目里通过cmd
命令去执行 url
转换成PDF
文章是我后面回忆时候写的如果存在问题 欢迎批评指正~ 谢谢
有些复杂的页面可能无法支持,相对简单些的 兼容性应该可以的,对于我自己的需求基本满足