久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

docxtpl使用手冊

 小小明代碼實體 2021-11-30

作者:小小明

本文鏈接:https://blog.csdn.net/as604049322/article/details/112008531

支持pdf文檔下載:https://download.csdn.net/download/as604049322/13993564

簡介:Pandas數(shù)據(jù)處理專家,10余年編碼經(jīng)驗,。

若你在數(shù)據(jù)處理的問題上遇到什么困難,歡迎與我交流。

大家好,我是小小明,這篇文章將給大家分享一個強大的包docxtpl ,它通過對docx文檔模板加載,使用jinja2網(wǎng)頁模板開發(fā)的語法對其進行修改,。

docxtpl 的簡介

前面我分享過python-docx庫的操作案例,而這次分享的docxtpl 就是基于python-docx和jinja2開發(fā)出來的庫。

docxtpl 的作者開發(fā)出它的原因主要是python-docx擅長創(chuàng)建word文檔,卻不擅長修改,。

對于docxtpl來說,使用MicrosoftWord編輯文檔時,直接在文檔中插入類似于Jinja2的標(biāo)記,。將文檔保存為.docx文件(XML格式):它將是.docx模板文件。

然后使用docxtpl加載這個.docx模板,按照J(rèn)inja2的語法傳入關(guān)聯(lián)的上下文變量,即可生成想要的Word文檔,多次傳入不同的上下文變量即可生成多個基于模板的word文檔,。

docxtpl 主要依賴兩個包

  • python-docx :讀寫word文檔
  • jinja2:管理插入到模板中的標(biāo)簽

jinja2語法可參考:
http://docs./docs/jinja2/templates.html
docxtpl官方文檔:
https://docxtpl./en/latest/

安裝:

pip install docxtpl

基本使用示例:

from docxtpl import DocxTemplate
tpl = DocxTemplate("my_word_template.docx")
context = { 'company_name' : "World company" }
tpl.render(context)
tpl.save("generated_doc.docx")

docxtpl的使用手冊

Jinja2語法

為了掌握docxtpl 的用法,我們需要學(xué)習(xí)或復(fù)習(xí)一下Jinja2的語法,然后再研究docxtpl 特有的類Jinja2語法,。

基本語法:

{% if user %}
<title> hello {{user}} </title>
{% else %}
<title> welcome to docxtpl </title>        
{% endif %}
<ul>
    {% for index in indexs %}
    <li> {{ index }} </li>
    {% endfor %}
</ul>

在模板中{{ variable }}結(jié)構(gòu)表示變量,是一種特殊的占位符,告訴模板引擎這個位置的值,從渲染模板時使用的數(shù)據(jù)中獲取;Jinja2除了能識別基本類型的變量,還能識別字典;

<p>{{mydict['key']}}</p>

<p>{{mylist[1]}}</p>

<p>{{mylist[myvariable]}}</p>

過濾器的本質(zhì)就是函數(shù),使用方式為:變量名 | 過濾器。 過濾器名寫在變量名后面,中間用 | 分隔,。如:{{variable | capitalize}},這個過濾器的作用:把變量variable的值的首字母轉(zhuǎn)換為大寫,其他字母轉(zhuǎn)換為小寫,。 操作列表的常用過濾器如下:

列表操作:

first:取第一個元素

  <p>{{ [1,2,3,4,5,6] | first }}</p>

last:取最后一個元素

  <p>{{ [1,2,3,4,5,6] | last }}</p>

length:獲取列表長度

  <p>{{ [1,2,3,4,5,6] | length }}</p>

sum:列表求和

  <p>{{ [1,2,3,4,5,6] | sum }}</p>

sort:列表排序

  <p>{{ [6,2,3,1,5,4] | sort }}</p>

Jinja自定義過濾器

render() 的 jinja_env 選項參數(shù)可以傳遞一個jinja環(huán)境對象,從而添加一些定制的jinja過濾器:

from docxtpl import DocxTemplate
import jinja2
def multiply_by(value, by):
   return value * by

tpl = DocxTemplate("my_word_template.docx")
context = { 'price_dollars' : 5.00 }
jinja_env = jinja2.Environment()
jinja_env.filters['multiply_by'] = multiply_by
tpl.render(context,jinja_env)
tpl.save("generated_doc.docx")

然后在模板中能夠使用

Euros price : {{ price_dollars|multiply_by(0.88) }}

類Jinja 2語法

4個重要的專屬標(biāo)簽

為了管理段落、表行,、表列,、run,必須使用特殊的語法:

{%p jinja2_tag %} for paragraphs
{%tr jinja2_tag %} for table rows
{%tc jinja2_tag %} for table columns
{%r jinja2_tag %} for runs

正常的Jinja 2語法只有%的普通標(biāo)簽,而docxtpl的類語法包含%p,%tr,%tc,%r

%p:段落,即docx.text.paragraph.Paragraph對象

%tr:表格中的一行,即docx.table._Row對象

%tc:表格中的一列,即docx.table._Column對象

%r:段落中的一個片段,即docx.text.run.Run對象

通過使用這些標(biāo)記,python-docx-template將真正的Jinja 2標(biāo)記放入文檔的XML源代碼中的正確位置。

另外,需注意,這四種標(biāo)簽,起始標(biāo)簽不能在同一行,必須在不同的行上面,。

例如:

{%p if display_paragraph %}Here is my paragraph {%p endif %}

需改寫成:

{%p if display_paragraph %}
Here is my paragraph
{%p endif %}

否則無法正確渲染,。

長文本拆分

包含jinja2標(biāo)簽的文本如果太長,可能無法讀取:

My house is located {% if living_in_town %} in urban area {% else %} in countryside {% endif %} and I love it.

可以使用 {%--%} 標(biāo)簽來拆分整個文本:

My house is located
{%- if living_in_town -%}
 in urban area
{%- else -%}
 in countryside
{%- endif -%}
 and I love it.

注意: {%- xxx -%} 標(biāo)簽必須在單獨在一行中,不可在之前或之后添加其他的文本。

Jinja 2的語法對變量是使用雙括弧:{{ variable }}

但如果variable 是RichText對象時,必須更改為:{{r variable }}

注意

  1. r緊跟左括弧,。variable不能使用r作為變量,因為{{r}} 可以解釋為 {{r 沒有指定變量
  2. 不要在同一run上使用2次 {{r . 使用 RichText.add() 方法在python代碼上連接多個字符串和樣式,在word文檔模板上只需 寫一個 {{r 標(biāo)簽,。

表格處理與合并單元格

列跨越:

如果需要動態(tài)生成一個合并單元格,可以使用colspan標(biāo)記:

{% colspan column_count %}

column_count是一個整數(shù)表示要跨越的列數(shù),。

例如,word模板中:

{% colspan col_labels|count %}Type of thing
{%tc for col in col_labels %}{{ col }}{%tc endfor %}

python渲染代碼:

tpl.render({'col_labels': ['fruit', 'vegetable', 'stone', 'thing']})

渲染結(jié)果:

image-20201231100326466

水平合并單元格:

或者在for循環(huán)中:

{% hm %}

例如,word模板:

{%tc for x in [1, 2, 3, 4] %}{% hm %}Header 2{%tc endfor %}
{%tc for x in [1, 2, 3, 4] %}Subheader {{ x }}{%tc endfor %}

最終渲染結(jié)果:

image-20201231100716535

垂直合并單元格:

在for循環(huán)中:

{% vm %}

例如,word模板:

DescriptionQuantityPrice
{%tr for i in items %}
{% vm %}{{category}}{{ i.desc }}{{ i.qty }}{{ i.price }}
{%tr endfor %}
Total{{total_price}}

python渲染代碼:

context = {
    'items': [
        {'desc': 'Python interpreters', 'qty': 2, 'price': 'FREE'},
        {'desc': 'Django projects', 'qty': 5403, 'price': 'FREE'},
        {'desc': 'Guido', 'qty': 1, 'price': '100,000,000.00'},
    ],
    'total_price': '100,000,000.00',
    'category': 'Book',
}

tpl.render(context)

渲染結(jié)果:

image-20201231100927973

RichText動態(tài)樣式

使用{{ variable }}標(biāo)記,它將保持目前的格式使用variable 變量的值進行字符串替換。但如果要添加動態(tài)變化的樣式,則必須使用{{r variable }}標(biāo)記,同時傳入的variable變量是一個 RichText對象,。RichText對象可以在python代碼中更改顏色,、粗體、斜體,、大小等,。

使用{{r variable }}標(biāo)記時,它在docx模板中原本的樣式將會被刪除,如果沒有在RichText()設(shè)置字體樣式,樣式將返回到Microsoft Word默認(rèn)樣式。

還可以通過Richtext將超鏈接添加到文本中:

tpl=DocxTemplate('your_template.docx')
rt = RichText('You can add an hyperlink, here to ')
rt.add('google',url_id=tpl.build_url_id('http://google.com'))

RichText('my text’)的簡寫是R('my text’)

python代碼示例:

from docxtpl import DocxTemplate, RichText

tpl = DocxTemplate('templates/richtext_and_if_tpl.docx')

context = {'foobar': RichText('Foobar!', color='ff0000')}
tpl.render(context)
tpl.save('output/richtext_and_if.docx')

richtext_and_if_tpl.docx文件模板內(nèi)容:

{%r if foobar %} {{r foobar }}COUCOU{%r endif %}

渲染結(jié)果:

image-20201231103317949

單元格顏色

需要更改表格單元格的背景色時,必須在單元格的開頭放置以下標(biāo)記

{% cellbg variable %}

variable 必須是顏色的十六進制碼,不支持red等顏色單詞,。

比如模板:

DateTypeAlert Description
{%tr for a in alerts %}
{{ a.date }}{% cellbg a.bg %}{{ a.type }}{{r a.desc }}
{%tr endfor %}

python渲染代碼:

context = {
    'alerts': [
        {
            'date': '2015-03-10',
            'desc': RichText('Very critical alert', color='FF0000', bold=True),
            'type': 'CRITICAL',
            'bg': 'FF0000',
        },
        {
            'date': '2015-03-11',
            'desc': RichText('Just a warning'),
            'type': 'WARNING',
            'bg': 'FFDD00',
        },
        {
            'date': '2015-03-12',
            'desc': RichText('Information'),
            'type': 'INFO',
            'bg': '8888FF',
        },
        {
            'date': '2015-03-13',
            'desc': RichText('Debug trace'),
            'type': 'DEBUG',
            'bg': 'FF00FF',
        },
    ],
}

tpl.render(context)

渲染結(jié)果:

image-20201231101202701

Escaping和轉(zhuǎn)義

為了展示{%, %}, {{ or }}, 可以使用:

{_%, %_}, {_{ or  }_}

傳入 {{ variable }}的variable 變量不能使用<, >&等字符,必須轉(zhuǎn)義它們,否則會導(dǎo)致整個文檔錯亂,。

轉(zhuǎn)義方法有 :

  • context = { 'variable':R('my text') } 和在模板中{{r variable }}
  • context = { 'variable':'my text'}和在模板中{{ variable|e }}
  • context = { 'var':escape('my text')} 和在模板中{{ <var> }}
  • 在調(diào)用渲染方法時啟用自動轉(zhuǎn)義:tpl.render(context, autoescape=True) (默認(rèn)值autoescape=False)

RichText()或R()支持換行符,新段落,縮進和分頁符功能:只需使用\n, \a, \t\f 在文本中,它們將作相應(yīng)的轉(zhuǎn)換。

示例:

word模板內(nèi)容:

{{orgin}}

{{r var1}}

{{var2|e}}

{{var3}}

{{ var4}}

python渲染腳本:

context = {
    'var1': R(
        '<>&:必須被轉(zhuǎn)義才能顯示, 可以使用RichText() 或 R()'
    ),
    'var2': '或者使用 "|e" jinja 過濾器來轉(zhuǎn)義 <>& ',
    'var3': escape('或者使用escape函數(shù)來轉(zhuǎn)義: <>& ...'),
    'var4': '多行文本\n\ttab縮進和一些段落\n會自動\a被轉(zhuǎn)換',
}

tpl.render(context)

渲染結(jié)果:

image-20201231123219404

假如不轉(zhuǎn)義,直接傳入這些特殊字符:

context = {
    'orgin': '直接傳入<>&看看渲染結(jié)果:',
    'var1': R(
        '<>&:必須被轉(zhuǎn)義才能顯示, 可以使用RichText() 或 R()'
    ),
    'var2': '或者使用 "|e" jinja 過濾器來轉(zhuǎn)義 <>& ',
    'var3': escape('或者使用escape函數(shù)來轉(zhuǎn)義: <>& ...'),
    'var4': '多行文本\n\ttab縮進和一些段落\n會自動\a被轉(zhuǎn)換',
}

tpl.render(context)

渲染結(jié)果:

image-20201231124708705

結(jié)果就是會導(dǎo)致其他已經(jīng)轉(zhuǎn)義的<>&等字符都無法正常顯示,。

如果希望可以直接安全的轉(zhuǎn)入這些字符,可以開啟自動轉(zhuǎn)義:

context = {
    'orgin': '<>&沒有轉(zhuǎn)義的情況下無法顯示',
    'var1': R(
        '<>&:必須被轉(zhuǎn)義才能顯示, 可以使用RichText() 或 R()'
    ),
    'var2': '或者使用 "|e" jinja 過濾器來轉(zhuǎn)義 <>& ',
    'var3': escape('或者使用escape函數(shù)來轉(zhuǎn)義: <>& ...'),
    'var4': '多行文本\n\ttab縮進和一些段落\n會自動\a被轉(zhuǎn)換',
}

tpl.render(context, autoescape=True)

渲染結(jié)果:

image-20201231125141374

docxtpl的2個高級對象

內(nèi)嵌圖像

doxtpl.inlineImage對象可以動態(tài)地將一個或多個圖像添加到文檔中(支持JPEG和PNG格式),。

from docx.shared import Mm

myimage=InlineImage(tpl,'python_logo.png',width=Mm(20))

對于高度和寬度,必須使用毫米(毫米),英寸(英寸)或點(Pt)類。

示例

word模板:

image-20201231141341612

python渲染代碼:

from docxtpl import DocxTemplate, InlineImage

# for height and width you have to use millimeters (Mm), inches or points(Pt) class :
from docx.shared import Mm
import jinja2

tpl = DocxTemplate('templates/inline_image_tpl.docx')

context = {
    'myimage': InlineImage(tpl, 'templates/python_logo.png', width=Mm(20)),
    'myimageratio': InlineImage(
        tpl, 'templates/python_jpeg.jpg', width=Mm(30), height=Mm(60)
    ),
    'frameworks': [
        {
            'image': InlineImage(tpl, 'templates/django.png', height=Mm(10)),
            'desc': 'The web framework for perfectionists with deadlines',
        },
        {
            'image': InlineImage(tpl, 'templates/zope.png', height=Mm(10)),
            'desc': 'Zope is a leading Open Source Application Server and Content Management Framework',
        },
        {
            'image': InlineImage(tpl, 'templates/pyramid.png', height=Mm(10)),
            'desc': 'Pyramid is a lightweight Python web framework aimed at taking small web apps into big web apps.',
        },
        {
            'image': InlineImage(tpl, 'templates/bottle.png', height=Mm(10)),
            'desc': 'Bottle is a fast, simple and lightweight WSGI micro web-framework for Python',
        },
        {
            'image': InlineImage(tpl, 'templates/tornado.png', height=Mm(10)),
            'desc': 'Tornado is a Python web framework and asynchronous networking library.',
        },
    ],
}
# testing that it works also when autoescape has been forced to True
jinja_env = jinja2.Environment(autoescape=True)
tpl.render(context, jinja_env)
tpl.save('output/inline_image.docx')

渲染結(jié)果:

image-20201231141524121

子文件

Subdoc對象可以作為一個使用python-docx庫從頭開始構(gòu)建word文檔的對象,構(gòu)建的內(nèi)容可以直接嵌入到傳入的變量位置:

sd = tpl.new_subdoc()
p = sd.add_paragraph('This is a sub-document inserted into a bigger one')
p = sd.add_paragraph('It has been ')
p.add_run('dynamically').style = 'dynamic'
p.add_run(' generated with python by using ')
p.add_run('python-docx').italic = True
p.add_run(' library')

context = {
    'mysubdoc': sd,
}
tpl.render(context)

效果:

image-20201231141843340

替換word文檔的圖片或媒體

在頁眉/頁腳中是無法動態(tài)添加圖片和媒體的,但我們可以在模板中放置一個虛擬對象,像往常一樣渲染模板,然后用另一個對象替換虛擬對象,。從而實現(xiàn)圖片和媒體的添加,。

替換可以發(fā)生在頁眉、頁腳和整個文檔正文中,。

替換頁眉/頁腳中的圖片

需要先在頁眉/頁腳中放置一張模板圖片,替換時指定被插入的模板圖片的文件名即可,替換dummy_header_pic.jpg的語法:

tpl.replace_pic('dummy_header_pic.jpg','header_pic_i_want.jpg')

被替換的圖像在word文檔中將保持原始文檔的寬高比,。

替換頁眉/頁腳中的媒體

與替換圖片幾乎一致,替換dummy_header_pic.jpg的語法:

tpl.replace_media('dummy_header_pic.jpg','header_pic_i_want.jpg')

警告:與replace_pic() 方法不同,dummy_header_pic.jpg 必須存在模板目錄中。

替換嵌入對象

它的工作方式類似于媒體替換,只是它適用于嵌入式docx這樣的嵌入式對象,。

替換embedded_dummy.docx的語法:

tpl.replace_embedded('embdded_dummy.docx','embdded_docx_i_want.docx')

警告:與replace_pic()方法不同,embdded_dumy.docx必須存在于模板目錄中,。

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多