Python快速生成定制化的Word(docx)文檔
1.1. 前言
眾所周知,安服工程師又叫做Word工程師,在打工或者批量SRC的時(shí)候,如果產(chǎn)出很多,又需要一個(gè)一個(gè)的寫報(bào)告的情況下會(huì)非常的折磨人,因此查了一些相關(guān)的資料,發(fā)現(xiàn)使用python的docxtpl
庫批量寫報(bào)告效果很不錯(cuò),記錄一下。
1.2. 介紹
docxtpl
是一個(gè)用于生成 Microsoft Word 文檔的模板引擎庫,它結(jié)合了 docx 模塊和 Jinja2 模板引擎,使用戶能夠使用 Microsoft Word 模板文件并在其中填充動(dòng)態(tài)數(shù)據(jù)。它提供了一種方便的方式來生成個(gè)性化的 Word 文檔,并支持條件語句、循環(huán)語句和變量等控制結(jié)構(gòu),以滿足不同的文檔生成需求。
官方GitHub地址:https://github.com/elapouya/python-docx-template
官方文檔地址:https://docxtpl.readthedocs.io/en/latest/
簡單來說:就是創(chuàng)建一個(gè)類似Jinja2語法的模板文檔,然后往里面動(dòng)態(tài)填充內(nèi)容就可以了
安裝:
pip3 install docxtpl
1.3. 基礎(chǔ)使用
from docxtpl import DocxTemplate doc = DocxTemplate("test.docx") context = {'whoami': "d4m1ts"} doc.render(context) doc.save("generated_doc.docx")
其中,test.docx內(nèi)容如下:
生成后的結(jié)果如下:
1.4. 案例介紹
1.4.1. 需求假設(shè)
寫一份不考慮美觀的漏掃報(bào)告,需要有統(tǒng)計(jì)結(jié)果圖和漏洞詳情,每個(gè)漏洞包括漏洞名、漏洞地址、漏洞等級(jí)、漏洞危害、復(fù)現(xiàn)過程、修復(fù)建議六個(gè)部分。
1.4.2. 模板文檔準(zhǔn)備
編寫的模板文檔如下,使用到了常見的if
、for
、賦值
等,保存為template.docx
,后續(xù)只需要向里面填充數(shù)據(jù)即可。
1.4.3. 數(shù)據(jù)結(jié)構(gòu)分析
傳入數(shù)據(jù)需要一串json字符串,因此我們根據(jù)模板文檔梳理好json結(jié)構(gòu),然后傳入即可。
梳理好的數(shù)據(jù)結(jié)構(gòu)如下:
{
"餅圖": "111",
"柱狀圖": "222",
"漏洞簡報(bào)": [
{
"漏洞名": "測試漏洞名1",
"漏洞等級(jí)": "高危"
}
],
"漏洞詳情": [
{
"漏洞名": "測試漏洞名1",
"漏洞地址": "http://blog.gm7.org/",
"漏洞等級(jí)": "高危",
"漏洞危害": "危害XXX",
"復(fù)現(xiàn)過程": "先xxx,再xxx,最后xxx",
"修復(fù)建議": "更新到最新版本即可"
}
]
}
編寫代碼測試一下可行性:
from docxtpl import DocxTemplate doc = DocxTemplate("template.docx") context = { "餅圖": "111", "柱狀圖": "222", "漏洞簡報(bào)": [ { "漏洞名": "測試漏洞名1", "漏洞等級(jí)": "高危" }, { "漏洞名": "測試漏洞名2", "漏洞等級(jí)": "嚴(yán)重" }, { "漏洞名": "測試漏洞名2", "漏洞等級(jí)": "中危" } ], "漏洞詳情": [ { "漏洞名": "測試漏洞名1", "漏洞地址": "http://blog.gm7.org/", "漏洞等級(jí)": "高危", "漏洞危害": "危害XXX", "復(fù)現(xiàn)過程": "先xxx,再xxx,最后xxx", "修復(fù)建議": "更新到最新版本即可" }, { "漏洞名": "測試漏洞名2", "漏洞地址": "http://bblog.gm7.org/", "漏洞等級(jí)": "嚴(yán)重", "漏洞危害": "危害XXX", "復(fù)現(xiàn)過程": "先xxx,再xxx,最后xxx", "修復(fù)建議": "更新到最新版本即可" }, { "漏洞名": "測試漏洞名3", "漏洞地址": "http://cblog.gm7.org/", "漏洞等級(jí)": "中危", "漏洞危害": "危害XXX", "復(fù)現(xiàn)過程": "先xxx,再xxx,最后xxx", "修復(fù)建議": "更新到最新版本即可" } ] } doc.render(context) doc.save("generated_doc.docx")
很好,達(dá)到了預(yù)期的效果。
1.4.4. 加入圖表
在上面的過程中,內(nèi)容幾乎是沒問題了,但是圖表還是沒有展示出來。生成圖表我們使用plotly
這個(gè)庫,并將生成內(nèi)容寫入ByteIO
。
相關(guān)代碼如下:
import plotly.graph_objects as go from io import BytesIO def generatePieChart(title: str, labels: list, values: list, colors: list): """ 生成餅圖 https://juejin.cn/post/6911701157647745031#heading-3 https://juejin.cn/post/6950460207860449317#heading-5 :param title: 餅圖標(biāo)題 :param labels: 餅圖標(biāo)簽 :param values: 餅圖數(shù)據(jù) :param colors: 餅圖每塊的顏色 :return: """ # 基礎(chǔ)餅圖 fig = go.Figure(data=[go.Pie( labels=labels, values=values, hole=.4, # 中心環(huán)大小 insidetextorientation="horizontal" )]) # 更新顏色 fig.update_traces( textposition='inside', # 文本顯示位置 hoverinfo='label+percent', # 懸停信息 textinfo='label+percent', # 餅圖中顯示的信息 textfont_size=15, marker=dict(colors=colors) ) # 更新標(biāo)題 fig.update_layout( title={ # 設(shè)置整個(gè)標(biāo)題的名稱和位置 "text": title, "y": 0.96, # y軸數(shù)值 "x": 0.5, # x軸數(shù)值 "xanchor": "center", # x、y軸相對(duì)位置 "yanchor": "top" } ) image_io = BytesIO() fig.write_image(image_io, format="png") return image_io def generateBarChart(title: str, x: list, y: list): """ 生成柱狀圖 https://cloud.tencent.com/developer/article/1817208 https://blog.csdn.net/qq_25443541/article/details/115999537 https://blog.csdn.net/weixin_45826022/article/details/122912484 :param title: 標(biāo)題 :param x: 柱狀圖標(biāo)簽 :param y: 柱狀圖數(shù)據(jù) :return: """ # x軸長度最為18 b = x x = [] for i in b: if len(i) >= 18: x.append(f"{i[:15]}...") else: x.append(i) # 基礎(chǔ)柱狀圖 fig = go.Figure(data=[go.Bar( x=x, y=y, text=y, textposition="outside", marker=dict(color=["#3498DB"] * len(y)), width=0.3 )]) # 更新標(biāo)題 fig.update_layout( title={ # 設(shè)置整個(gè)標(biāo)題的名稱和位置 "text": title, "y": 0.96, # y軸數(shù)值 "x": 0.5, # x軸數(shù)值 "xanchor": "center", # x、y軸相對(duì)位置 "yanchor": "top" }, xaxis_tickangle=-45, # 傾斜45度 plot_bgcolor='rgba(0,0,0,0)' # 背景透明 ) fig.update_xaxes( showgrid=False ) fig.update_yaxes( zeroline=True, zerolinecolor="#17202A", zerolinewidth=1, showgrid=True, gridcolor="#17202A", showline=True ) image_io = BytesIO() fig.write_image(image_io, format="png") return image_io
1.4.5. 最終結(jié)果
要插入圖片內(nèi)容,代碼語法如下:
myimage = InlineImage(tpl, image_descriptor='test_files/python_logo.png', width=Mm(20), height=Mm(10))
完整代碼如下:
from docxtpl import DocxTemplate, InlineImage from docx.shared import Mm import plotly.graph_objects as go from io import BytesIO def generatePieChart(title: str, labels: list, values: list, colors: list): """ 生成餅圖 https://juejin.cn/post/6911701157647745031#heading-3 https://juejin.cn/post/6950460207860449317#heading-5 :param title: 餅圖標(biāo)題 :param labels: 餅圖標(biāo)簽 :param values: 餅圖數(shù)據(jù) :param colors: 餅圖每塊的顏色 :return: """ # 基礎(chǔ)餅圖 fig = go.Figure(data=[go.Pie( labels=labels, values=values, hole=.4, # 中心環(huán)大小 insidetextorientation="horizontal" )]) # 更新顏色 fig.update_traces( textposition='inside', # 文本顯示位置 hoverinfo='label+percent', # 懸停信息 textinfo='label+percent', # 餅圖中顯示的信息 textfont_size=15, marker=dict(colors=colors) ) # 更新標(biāo)題 fig.update_layout( title={ # 設(shè)置整個(gè)標(biāo)題的名稱和位置 "text": title, "y": 0.96, # y軸數(shù)值 "x": 0.5, # x軸數(shù)值 "xanchor": "center", # x、y軸相對(duì)位置 "yanchor": "top" } ) image_io = BytesIO() fig.write_image(image_io, format="png") return image_io def generateBarChart(title: str, x: list, y: list): """ 生成柱狀圖 https://cloud.tencent.com/developer/article/1817208 https://blog.csdn.net/qq_25443541/article/details/115999537 https://blog.csdn.net/weixin_45826022/article/details/122912484 :param title: 標(biāo)題 :param x: 柱狀圖標(biāo)簽 :param y: 柱狀圖數(shù)據(jù) :return: """ # x軸長度最為18 b = x x = [] for i in b: if len(i) >= 18: x.append(f"{i[:15]}...") else: x.append(i) # 基礎(chǔ)柱狀圖 fig = go.Figure(data=[go.Bar( x=x, y=y, text=y, textposition="outside", marker=dict(color=["#3498DB"] * len(y)), width=0.3 )]) # 更新標(biāo)題 fig.update_layout( title={ # 設(shè)置整個(gè)標(biāo)題的名稱和位置 "text": title, "y": 0.96, # y軸數(shù)值 "x": 0.5, # x軸數(shù)值 "xanchor": "center", # x、y軸相對(duì)位置 "yanchor": "top" }, xaxis_tickangle=-45, # 傾斜45度 plot_bgcolor='rgba(0,0,0,0)' # 背景透明 ) fig.update_xaxes( showgrid=False ) fig.update_yaxes( zeroline=True, zerolinecolor="#17202A", zerolinewidth=1, showgrid=True, gridcolor="#17202A", showline=True ) image_io = BytesIO() fig.write_image(image_io, format="png") return image_io doc = DocxTemplate("template.docx") context = { "餅圖": InlineImage(doc, image_descriptor=generatePieChart( title="漏洞數(shù)量", labels=["嚴(yán)重", "高危", "中危", "低危"], values=[1, 1, 1, 0], colors=["#8B0000", "red", "orange", "aqua"] ), width=Mm(130)), "柱狀圖": InlineImage(doc, image_descriptor=generateBarChart( title="漏洞類型", x=["測試漏洞名1", "測試漏洞名2", "測試漏洞名3"], y=[1, 1, 1] ), width=Mm(130)), "漏洞簡報(bào)": [ { "漏洞名": "測試漏洞名1", "漏洞等級(jí)": "高危" }, { "漏洞名": "測試漏洞名2", "漏洞等級(jí)": "嚴(yán)重" }, { "漏洞名": "測試漏洞名2", "漏洞等級(jí)": "中危" } ], "漏洞詳情": [ { "漏洞名": "測試漏洞名1", "漏洞地址": "http://blog.gm7.org/", "漏洞等級(jí)": "高危", "漏洞危害": "危害XXX", "復(fù)現(xiàn)過程": "先xxx,再xxx,最后xxx", "修復(fù)建議": "更新到最新版本即可" }, { "漏洞名": "測試漏洞名2", "漏洞地址": "http://bblog.gm7.org/", "漏洞等級(jí)": "嚴(yán)重", "漏洞危害": "危害XXX", "復(fù)現(xiàn)過程": "先xxx,再xxx,最后xxx", "修復(fù)建議": "更新到最新版本即可" }, { "漏洞名": "測試漏洞名3", "漏洞地址": "http://cblog.gm7.org/", "漏洞等級(jí)": "中危", "漏洞危害": "危害XXX", "復(fù)現(xiàn)過程": "先xxx,再xxx,最后xxx", "修復(fù)建議": "更新到最新版本即可" } ] } doc.render(context) doc.save("generated_doc.docx")
結(jié)果如下:
以上就是Python快速生成定制化的Word文檔的詳細(xì)內(nèi)容,更多關(guān)于Python生成定制化Word的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python OpenCV基于霍夫圈變換算法檢測圖像中的圓形
這篇文章主要介紹了通過霍夫圈變換算法檢測圖像中的圓形,文中用到的函數(shù)為cv2.HoughCircles(),該函數(shù)可以很好地檢測圓心。感興趣的小伙伴可以了解一下2021-12-12python 將json數(shù)據(jù)提取轉(zhuǎn)化為txt的方法
今天小編就為大家分享一篇python 將json數(shù)據(jù)提取轉(zhuǎn)化為txt的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-10-10Python循環(huán)結(jié)構(gòu)的應(yīng)用場景詳解
這篇文章主要介紹了Python循環(huán)結(jié)構(gòu)的應(yīng)用場景詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07python爬蟲 2019中國好聲音評(píng)論爬取過程解析
這篇文章主要介紹了python爬蟲 2019中國好聲音評(píng)論爬取過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08Python的Django框架中自定義模版標(biāo)簽的示例
這篇文章主要介紹了Python的Django框架中自定義模版標(biāo)簽的示例,標(biāo)簽的用處比過濾器更多,需要的朋友可以參考下2015-07-07教你學(xué)會(huì)通過python的matplotlib庫繪圖
今天教大家如何學(xué)會(huì)通過python的matplotlib庫繪圖,文中有非常詳細(xì)的圖文解說及代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們很有幫助,需要的朋友可以參考下2021-05-05wxPython電子表格功能wx.grid實(shí)例教程
這篇文章主要介紹了wxPython電子表格功能wx.grid實(shí)例教程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11