1. 根據模板批量生成文檔
想要運用python來編輯word是有些難度的,主要是因爲文檔涉及到的因素比較多,僅僅是字體就有顏色、大小、加粗等等屬性,這也就造成了使用python“無中生有”一個文檔的困難性。
這裏推薦一個使用模板批量生成文檔的包:mailmerge。
1.1 制定模板文件docx
我個人使用的是WPS,office的Word操作大同小異。
首先點擊插入,
之後點擊文檔部件,並選擇域,之後在彈出的對話框中選擇郵件合併:
在域代碼那一欄後面寫上變量名,
點擊確定後得到:
重複操作得到如下所示結果:
上面的操作可以簡單地理解爲創建了幾個“變量”,“變量”的格式就是之後生成的真實文檔的格式,這樣也就簡化了多屬性操作,之後我們就可以在python中通過docx-mailmerge庫用實際的值來替換模板中的“變量”而得到真實文檔。
(注:文件的擴展名必須是經由WPS/Office生成的.docx)。
1.2 安裝包
安裝則比較簡單:
pip3 install docx-mailmerge
1.3 生成單文檔
from mailmerge import MailMerge
def write2docx(datum, template_name, output):
doc = MailMerge(template_name)
doc.merge(**datum)
doc.write(output)
if __name__ == '__main__':
datum = {'teacher_name': '路人甲', 'day': '365', 'name': '路人乙', 'date': '2019-01-01'}
write2docx(datum, 'template.docx', '請假單.docx')
代碼比較簡單,需要注意的是變量的值必須是字符串,如果是其他的類型的話則可能會報錯。上面的代碼是根據模板生成的單文檔, 如果要生成多個文檔的話可以重複調用上面的函數。
1.4 生成一個多文檔
mailmerge還可以根據模板生成一個多文檔,這裏所說的多文檔就相當於若干個相同模板生成的單文檔的合併,代碼也比較簡潔:
def write2one_docx(data, template, output, separator='page_break'):
"""
根據data數組生成一個len(data)個的一個總文檔
:param data: 數組,鍵值對用來替換模板
:param template: 模板完整名稱
:param output: 輸出文件名稱
:param separator: 分隔符 默認爲換頁符
:return:
"""
doc = MailMerge(template)
doc.merge_templates(data, separator=separator)
doc.write(output)
if __name__ == '__main__':
data = [
{'teacher_name': 'sky', 'day': '3', 'name': 'moon', 'date': '2019/11/26'},
{'teacher_name': '周志華', 'day': '3', 'name': 'moon', 'date': '2019/11/26'},
]
write2one_docx(data, 'template.docx', 'two.docx', separator='textWrapping_break')
'page_break'是換頁符,'textWrapping_break'是換行符。
導出的文檔內容結果如下:
2. 合併多個文檔
把多個文件合併成爲一個文件的解決辦法是:打開一個文件,讀取該文件的內容並添加到新文件的末尾。文檔的合併也與此類似。
2.1 安裝
pip install python-docx
2.2 代碼的編寫
def combine_word_documents(files, output):
from docx import Document
"""
合併多個文檔爲一個文檔 目前會造成部分格式問題 需要保證輸出文件所在的路徑存在
:param files: 數組,保存着要合併的文件路徑
:param output: 合併文件名稱
:return:
"""
merged_document = Document()
for index, file in enumerate(files):
sub_doc = Document(file)
# 在文檔和文檔之間添加一個換頁
if index < len(files) - 1:
sub_doc.add_page_break()
# 添加到總文件裏
for element in sub_doc.element.body:
merged_document.element.body.append(element)
merged_document.save(output)
實現起來並不算困難,不過我在合併文檔的時候發現某些文字的格式會發生改變。
3. 讀取一個xlsx文件
openpyxl可以對xlsx文件進行操作。
3.1 安裝
pip install openpyxl
3.2 讀取xlsx並生成字典數組
def read_xlsx2dict(filename, sheet=None, callback=None):
"""
讀取excel文件,並得到[{}] 以第一行爲鍵,其他行爲指
:param filename: 擴展名爲xlsx的文件
:param sheet: 要讀取的sheet名稱
:param callback: callback(key, value)返回值用以代替原來的value
:return: 數組
"""
workbook = load_workbook(filename=filename)
# 獲取sheet
sheet_names = workbook.sheetnames
sheet = sheet_names[0] if not sheet else sheet
table = workbook[sheet]
# 把第一行作爲鍵
keys, index = None, 0
# 按照行進行遍歷
for row in table.rows:
line = []
is_none = True
# 獲取每一個列
for col in row:
line.append(col.value)
is_none = is_none and col.value is None
# 第一列作爲鍵
if index == 0:
keys = [key for key in line if key is not None]
elif not is_none:
datum = {}
for i in range(len(keys)):
if not callback:
datum[keys[i]] = callback(keys[i], line[i])
else:
datum[keys[i]] = line[i]
yield datum
index += 1
默認讀取第一個sheet。因爲要生成鍵值對,所以該函數把第一行當作鍵,其他行則作爲值,據此生成一個字典數組。
相關代碼:https://github.com/sky94520/tools
word.py和src/template.docx