Django 实现HTML转PDF 用通用视图编写PDF 并且让PDF支持中文

如何使用django-easy-pdf

你好! 这是我第一次使用 CSDN 发布文章,django工作有半年了,今天有个需求就是使用django视图来编写可浏览的PDF,但是研究许久未果。后来在度娘上找到了django-easy-pdf,也实现了我的需求,但是使用的过程中遇到了好多问题,接下来教你如何使用django-easy-pdf,并且分享我遇到的问题解决方案。 如果你想学习或了解更多关于django的知识,可以加Q群哦[828816138]。

django-easy-pdf的依赖

这个应用程序使Django中的PDF文件变得非常容易。它可用于从简单的HTML标记和CSS样式创建发票,账单和其他文档。您甚至可以嵌入图像并使用自定义字体。

该库提供了基于类的视图,只需要继承它 PDFTemplateView或 PDFTemplateResponseMixin 便可以呈现PDF

django-easy-pdf 依赖于取决于:

  1. django>=1.10
  2. xhtml2pdf>=0.2b1
  3. reportlab

安装django-easy-pdf

// An highlighted block
pip3.6 install xhtml2pdf> = 0.2b1

添加easy_pdf到INSTALLED_APPS
然后您就可以这样去使用了

{% extends "easy_pdf/base.html" %}

{% block content %}
    <div id="content">
        <h1>Hi there!</h1>
    </div>
{% endblock %}

编写CBV视图

from easy_pdf.views import PDFTemplateView

class PDFContract(PDFTemplateView):
    template_name = 'PDFContract.html'

	def get_context_data(self, **kwargs):
		return super(PDFContract, self).get_context_data(
            pagesize='A4',
            title='XXXX采购协议供货合同',
            **kwargs
        )

from easy_pdf.views import PDFTemplateResponseMixin

class HelloPDFView(PDFTemplateResponseMixin, TemplateView):
    template_name = 'hello.html'

	def get_context_data(self, **kwargs):
		return super(PDFContract, self).get_context_data(
            pagesize='A4',
            title='XXXX采购协议供货合同',
            **kwargs
        )

使用过程中遇到的问题总结

按照上面编写完成视图后,写一个简单的html相信你是没问题的,但是当你使用table绘制表格的时候,当你使用中文开始编写PDF的时候,你会遇到麻烦

关于django-easy-pdf 中文支持问题汇总[xhtml2pdf]

度娘参考了一些解决方案,发现行不通,关于字体,其实每个系统,应该都有一个黑体吧,为了兼容大部分系统,我们就添加一个系统字体 黑体 SimHei

很简单,只需要修改一个文件,添加一个文件,共2处位置,就可以实现中文喽!
先来看看效果吧
示例图片

安装 django-easy-pdf 后,找到它的位置 [Python36\Lib\site-packages\xhtml2pdf]
我们修改的是 xhtml2pdf 所以是这个路径,因为安装django-easy-pdf 的时候会安装上他

然后我们找到这个路径
Python36\Lib\site-packages\xhtml2pdf\default.py

......

DEFAULT_FONT = { 
    "courier": "Courier",
    "courier-bold": "Courier-Bold",
    "courier-boldoblique": "Courier-BoldOblique",
    "courier-oblique": "Courier-Oblique",

    # 修改这一行为 ["helvetica": "SimHei"]
    "helvetica": "helvetica", 
    
    # SimHei 为黑体,是系统的自带字体大部分系统都有这个字体,所以就用了它
    "helvetica": "SimHei"
    
    ........
}

......

然后在这里添加并注册字体
Python36\Lib\site-packages_init_,py

......

from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

# 只要你系统中存在这个字体,就可以这样写,这里的SimHei.ttf我没有添加如何路径哦,它会从系统字库里面找
pdfmetrics.registerFont(TTFont('SimHei', 'SimHei.ttf'))

# 这一个方法,只有这个字体xhtml2pdf内部存在时可用
# from reportlab.pdfbase.cidfonts import UnicodeCIDFont
# pdfmetrics.registerFont(UnicodeCIDFont('STSong-Light'))

完整的例子:
Python36\Lib\site-packages\xhtml2pdf\default.py

......
DEFAULT_FONT = { 
    "courier": "Courier",
    "courier-bold": "Courier-Bold",
    "courier-boldoblique": "Courier-BoldOblique",
    "courier-oblique": "Courier-Oblique",
    "helvetica": "SimHei"
    ........
}
......

Python36\Lib\site-packages_init_,py

......

from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

pdfmetrics.registerFont(TTFont('SimHei', 'SimHei.ttf'))

至此,中文支持的问题已经解决了,注册字体的时候要格外注意这里
TTFont(‘SimHei’, ‘SimHei.ttf’)
SimHei.ttf 为系统字体,是不需要添加路径的,他会从系统字体里面找

相关代码下载[我穷,如果可以请支持一下]

https://download.csdn.net/download/qq_17776977/10755249

当你使用table绘制表格的时候,如果表格太大会报错

当你的Table表格撑满一个页面的时候,通常会报如下错误
当你的Table表格撑满一个页面的时候,通常会报如下错误

解决方案:
适当拆分大表格为小表格,可以将一个表格拆分为若干个
拆分表格

当你遇到list index out of range错误时

这是由于你表格 行或列[rowspan,colspan]的索引大于或者小于实际的表格 行或列时会报错
这是由于你表格 行或列[rowspan,colspan]的索引大于或者小于实际的表格 行或列时会报错

可以看出,它的列是一行,然而是错误的

在这里插入图片描述

实际展示效果是,看到了吧,他是1列的
在这里插入图片描述

解决方案:
请认真设置行或列

什么,字体不换行?如何解?

是不是崩溃了?是不是看到这里感觉很麻烦,其实我也觉得
字体不换行?

解决方案:
很简单,手动换行,或者字体里面添加空格,就会自动换行
如果怕麻烦,可以直接看下面的方法

好了,是我骗了你,其实还有个更好的实现方法,我们用WeasyPrint后端作为PDF的渲染

嘿嘿,真正的干货,永远是献给坚持的人,如果你不想做了,可以离开。关于前面的方法是可以实现的,但是也会面临诸多问题。我都快把PDF的模板做完了,才发现这种方法。但是我没有尝试,因为之前尝试过,报错。偶然间看到了官方文档的解决方法。特此记录一下 [并未实践]

参考:
WeasyPrint安装方法 https://weasyprint.readthedocs.io/en/latest/install.html
django-easy-pdf安装方法 https://django-easy-pdf.readthedocs.io/en/v0.2.0-dev1/installation.html

关于WeasyPrint的报错
关于WeasyPrint的报错

后来我知道了这是因为没有安装某些依赖所导致,这些依赖并不是py的某些库,而是一些GTK +库。。。

这里给出django-easy-pdf和WeasyPrint的安装方法

安装前请先卸载之前安装的django-easy-pdf,也要卸载所安装的依赖

  1. django>=1.10
  2. xhtml2pdf>=0.2b1
  3. reportlab

然后就是安装了,一条指令的事情

pip3.6 install -U django-easy-pdf WeasyPrint

有关WeasyPrint依赖的安装说明,请参阅http://weasyprint.readthedocs.io/en/latest/install.html

待续…

猜你喜欢

转载自blog.csdn.net/qq_17776977/article/details/83580814
今日推荐