django+wkhtmltopdf后端生成pdf

django+wkhtmltopdf后端生成pdf

在写系统时,总是会遇见需要给用户提供pdf下载的功能,实际上pdf生成方式多种多样,有前端生成pdf也有后端生成pdf的方式。在之前已经有写过生成pdf的文章,之前是使用php调用wkhtmltopdf方式,部署在windows上,这一次使用django搭建后台,部署在ubuntu上,并且生成的pdf中有echarts绘制的图,所以写一篇新的文章,有兴趣的可以去我看看之前写过的文章最完美的html转化为pdf的方法

wkhtmltopdf安装

wkhtmltopdf是一个使用 Qt WebKit 引擎做渲染的,能够把html 文档转换成 pdf 文档 或 图片(image) 的命令行工具,支持多个平台,可在win,linux,os x 等系统下运行。

多平台的优势让你可以无痛切换系统使用

可以前往官网下载符合条件的安装包wkhtmltopdf下载官网

我这边服务器是ubuntu20.04,直接使用命令wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb下载安装包。(有时候命令行很酷,但是被网速限制死,选择好能下载的方式)

下载晚使用进行安装sudo dpkg -i wkhtmltox_0.12.6-1.focal_amd64.deb

输入 wkhtmltopdf -V显示版本号即安装成功

image-20220328142041485

这是一个命令行工具,可以简单地拿百度主页尝试一下wkhtmltopdf http://baidu.com test.pdf

django+wkhtmltopdf后端生成pdf_第1张图片

在当前目录下出现一个test.pdf,直接看见效果。

django+wkhtmltopdf后端生成pdf_第2张图片

python调用wkhtmlpdf

现在只需要用python代码来执行该软件就能生成pdf,将pdf提供给用户下载,后台框架使用的是django,python控制wkhtmltopdf十分方便,只需要安装一个包,pip install pdfkit

先简单的写一个html界面




    
    Title


   

控制器views.py代码

from django.shortcuts import render
def test(request):
    return render(request, 'index/test.html')

路由规则urls.py代码

path('test', views.test),

显示界面

django+wkhtmltopdf后端生成pdf_第3张图片

这个时候为点击按钮赋予一个点击事件,向下载pdf界面请求pdf下载




    
    Title


   

 

需要引入js文件奥,如果麻烦,可以直接改成a标签




    
    Title


   点击我下载

效果都是一样的,然后需要在views.py里在写一个控制器,来提供pdf下载

import pdfkit
from django.http import FileResponse
def pdf_download(request):
        root_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
        pdf_path = os.path.join(root_path, 'test.pdf')# pdf路径可以自己修改
        options = {
            'encoding': "utf-8",
            # 'javascript-delay': '1000',  # 添加页面延时js执行时间段 echarts
        }
        url = 'http://baidu.com' # 简单使用百度来实验,可以换成自己需要下载的页面,自己的图表什么的
        pdfkit.from_url(url, pdf_path, options=options)
        file = open(pdf_path, 'rb')
        response = FileResponse(file)
        response['Content-Type'] = 'application/octet-stream'
        download_file_name = '嘎嘎嘎.pdf' # 如果取中文名,需要urlquote()编码转换
        response['Content-Disposition'] = 'attachment;filename="' + urlquote(download_file_name) + '"'
        return response

上面代码需要注意,如果是自己制作的有echarts的界面,需要加上'javascript-delay': '1000',不然图会还没绘制就被下载,点击下载效果

image-20220328150507943

上面使用的都是最简单的示例,有其他需求可以自己加入,像生成的pdf会保存在本地,那么需要命令规范,可以使用时间戳来命名,当然随着时间久了pdf文件会很多,这需要代码来维持pdf的数量,定时清理。示例中pdf下载是直接返回一个一个fileresponse对象。如果是异步请求下载,那么返回需要另做处理。

排版

上述写的都是简单的界面,在实际中需要生成的pdf往往是页数很多,像这种页数很多的网页需要排版,分页的地方要是会被截断则需要做特别处理,我们可以使用css属性调整,处理最基础的设置高度外,可以利用打印属性来调整。使用一下就可以知道效果,最简单的在某一块div加上css属性style="page-break-after:always",那么在生成pdf时候后面的内容会出现在下一页。

属性 简介
page 检索或指定显示对象容器时使用的页面类型
Page-break-before 检索或设置对象之前出现的页分割符
Page-break-after 检索或设置对象之后出现的页分割符
Page-break-inside 检索或设置对象容器内部出现的页分割符

心得

使用wkhtmltopdf次数已经是比较多了,无论是换了框架还是换了系统,都可以轻松的转换,使用起来十分方便,各种语言的调用十分完善,除了pdf还可以生成图片。功能真的强大。

你可能感兴趣的:(django+wkhtmltopdf后端生成pdf)