> For the complete documentation index, see [llms.txt](https://go.raymondctw.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://go.raymondctw.dev/technology/office-automation/word-document-template.md).

# Word Template with Python

相信在大家的工作生涯當中，在一般的辦公室中最常用到的三寶應該就是Word、Excel與PowerPoint吧？像我過去在金融業，常常相關文件與簽呈等內容都必須使用Word來處理格式，以符合老人們喜歡的八股模式，相當多是需要人工排版再複製貼上，不同部門中這種重複枯燥的工作的比重不同，通常比重高的部門的可取代性高且人員素質較低，我曾經看過一整個部門都在做這種工作......，從業人員的科技技能真的應該增加。

## Python-docx-template

大家比較常看到的是python-doc，python-doc可以透過Python從零到一地建立並編寫一份Word文件，由上而下線性的建立起來，但不免的到時候某些東西還是需要人工調整，所以我必較少使用python-doc。

取而代之的是透過人工建立文件格式後，在Word文件中放入變數，到時候使用Python與Jinja2來渲染這份文件反而是更為方便直覺的，尤其像金融業有相當多既有格式的文件，這時候就不需要重新刻一個，只需要將相關參數的位置留好即可。

### 1. 安裝

```
pip install docxtpl
```

### 2. Word文件範本建立

首先我們先建立一個Word文件，並將你需要的格式先建立完成，之後我就會從這個版型做為模組帶入參數或延伸。

<figure><img src="https://730373893-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9xNjWoUrvu3uV8eperj5%2Fuploads%2FR7DhxlbDQ16cTMDujKFc%2F%E6%88%AA%E5%9C%96%202023-09-14%2012.16.01.png?alt=media&amp;token=4bbc6199-3c98-44ba-b27e-f9675a6c0db8" alt=""><figcaption><p>WarrantTemplate.docx</p></figcaption></figure>

接下來就可以將我們要的變數利用Jinja2的語法插入，像是下圖中，利用兩組大括弧包起來，裡面放數變數名稱。

<figure><img src="https://730373893-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9xNjWoUrvu3uV8eperj5%2Fuploads%2FysndZa3i4lD7e8XSGol9%2F%E6%88%AA%E5%9C%96%202023-09-14%2012.25.24.png?alt=media&amp;token=56adbc0b-5c60-412d-8c4d-5117d931d3b6" alt=""><figcaption><p>WarrantTemplate.docx</p></figcaption></figure>

### 3. 撰寫與執行Python主程式

{% code title="main.py" lineNumbers="true" %}

```python
from docxtpl import DocxTemplate

doc  = DocxTemplate("WarrantTemplate.docx")

context = {'warrant_name': '888888',
           'underlying': '2330',
           'warrant_type': 'Call',
           'execution_type': 'European',
           'method': 'Cash Payment',
           'Duration': '10 months',
           'conversion_ratio': '10',
           'total_number': 1000000,
           'listing_date': '2023/10/01 ~ 2023/12/31'}

doc.render(context)
doc.save('Warrant01.docx')
```

{% endcode %}

執行以上程式後就可以看到在相對目錄下產生了一個Warrant01.docx的檔案，打開來看就是已經將變數導入Word文件後的成品了，是不是很簡單呢？

<figure><img src="https://730373893-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9xNjWoUrvu3uV8eperj5%2Fuploads%2FDpSJrnEUj4Od2M0sak3v%2F%E6%88%AA%E5%9C%96%202023-09-14%2012.30.17.png?alt=media&amp;token=105e9124-23f2-4081-a044-39c134477ce1" alt=""><figcaption><p>Warrant01.docx</p></figcaption></figure>

### 補充：利用For迴圈建立多個表格

常常我們要輸出的東西絕對不止一個表格，而是可能從資料庫中抓取出來的一大堆參數，這時候就可以利用Jinja2的迴圈來一次產出多個表格。

<figure><img src="https://730373893-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9xNjWoUrvu3uV8eperj5%2Fuploads%2Fb1n8NoUNDE2dHNCI0SO7%2F%E6%88%AA%E5%9C%96%202023-09-14%2012.34.55.png?alt=media&amp;token=b50a3732-f58e-4318-972d-00306b96ccda" alt=""><figcaption><p>WarrantTemplate.docx</p></figcaption></figure>

可以看到在表格的上下多了幾行，我想要一次產生十次一樣內容的表格，就可以直接加上這幾行，實際使用上則可以建立一個dict丟回context，透過一層一層的拆解，就可以批次產生囉！

<figure><img src="https://730373893-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9xNjWoUrvu3uV8eperj5%2Fuploads%2FkMy74R9igqDlFjuvR6EC%2F%E6%88%AA%E5%9C%96%202023-09-14%2012.38.57.png?alt=media&amp;token=3a6729c1-15ea-4d26-add2-23dd69f06f3b" alt=""><figcaption><p>Warrant02.docx</p></figcaption></figure>

實際狀況就像是這樣，是不是非常簡單且直覺呢？想查看完整的功能請自行查找[python-docx-template官方文件](https://docxtpl.readthedocs.io/en/latest/)。
