天天看點

python下對文檔(*.docx)和表格(*.xlsx)的簡單操作1. 根據模闆批量生成文檔 2. 合并多個文檔3. 讀取一個xlsx檔案

1. 根據模闆批量生成文檔

想要運用python來編輯word是有些難度的,主要是因為文檔涉及到的因素比較多,僅僅是字型就有顔色、大小、加粗等等屬性,這也就造成了使用python“無中生有”一個文檔的困難性。

這裡推薦一個使用模闆批量生成文檔的包:mailmerge。

1.1 制定模闆檔案docx

我個人使用的是WPS,office的Word操作大同小異。

首先點選插入,

python下對文檔(*.docx)和表格(*.xlsx)的簡單操作1. 根據模闆批量生成文檔 2. 合并多個文檔3. 讀取一個xlsx檔案

之後點選文檔部件,并選擇域,之後在彈出的對話框中選擇郵件合并:

python下對文檔(*.docx)和表格(*.xlsx)的簡單操作1. 根據模闆批量生成文檔 2. 合并多個文檔3. 讀取一個xlsx檔案

在域代碼那一欄後面寫上變量名,

python下對文檔(*.docx)和表格(*.xlsx)的簡單操作1. 根據模闆批量生成文檔 2. 合并多個文檔3. 讀取一個xlsx檔案

點選确定後得到:

python下對文檔(*.docx)和表格(*.xlsx)的簡單操作1. 根據模闆批量生成文檔 2. 合并多個文檔3. 讀取一個xlsx檔案

重複操作得到如下所示結果:

python下對文檔(*.docx)和表格(*.xlsx)的簡單操作1. 根據模闆批量生成文檔 2. 合并多個文檔3. 讀取一個xlsx檔案

上面的操作可以簡單地了解為建立了幾個“變量”,“變量”的格式就是之後生成的真實文檔的格式,這樣也就簡化了多屬性操作,之後我們就可以在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'是換行符。

導出的文檔内容結果如下:

python下對文檔(*.docx)和表格(*.xlsx)的簡單操作1. 根據模闆批量生成文檔 2. 合并多個文檔3. 讀取一個xlsx檔案

 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