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