Spring boot 通过 wkhtmltopdf 实现URL转PDF

一 、前言

本文将会基于 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 解决报错

两个问题:

  1. 安装时缺少关键依赖包
  2. 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

文章是我后面回忆时候写的如果存在问题 欢迎批评指正~ 谢谢
有些复杂的页面可能无法支持,相对简单些的 兼容性应该可以的,对于我自己的需求基本满足

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值