1. 程式人生 > >Django 實現HTML轉PDF 用通用檢視編寫PDF 並且讓PDF支援中文

Django 實現HTML轉PDF 用通用檢視編寫PDF 並且讓PDF支援中文

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

待續…