Python 透過python-docx操作Microsoft Word — docx文件
身為上班族的大多數人,想必都曾經使用過Microsoft Word軟體來編輯各式各樣的辦公室文件。並且大家應該都是徒手的打開Microsoft Word軟體,在裡面編輯各式各樣的docx文件。你是否曾經想過,透過程式的幫助讓我們快速建立某些常用的文件,以省去透過徒手複製貼上的繁複步驟?
雖然我們以前學過利用Python中的with open等方式來建立txt文件,但是Word文件的處理與一般純文字txt文件的處理不一樣。由於Word文件屬於2進位(binary)檔,無法只是透過open函式就讀取裡面的資料,處理起來會比文字txt文件要複雜得多了。
即便如此,並不表示Python就無法處理Word文件。實際上只要透過Python的第三方函式python-docx,就可以輕鬆處理Word檔案。
python-docx是一個函式庫,它被設計用來建立與更新副檔名為docx的Microsoft Word文件。從這裡也可以看到Python具有強大的第三方函式庫支援,可以完成各項不同的任務。
安裝python-docx
python-docx的程式碼放在PyPI上面,可以透過pip來安裝。
輸入下面指令安裝python-docx套件(目前版本為0.8.11)。
pip install python-docx
開始體驗:建立docx文件
安裝完畢後,就可以開始體驗python-docx程式。在python-docx的文件中,開宗明義就告訴我們這個套件可以用來建立以及更新微軟Microsoft Word的docx文件。
python-docx is a Python library for creating and updating Microsoft Word (.docx) files.
從範例暸解python-docx
在python-docx文件中,我們還可以找到如下的範例,此範例告訴我們可以透過python-doc套件完成什麼樣子的工作:
from docx import Document
from docx.shared import Inchesdocument = Document()document.add_heading('Document Title', 0)p = document.add_paragraph('A plain paragraph having some ')
p.add_run('bold').bold = True
p.add_run(' and some ')
p.add_run('italic.').italic = Truedocument.add_heading('Heading, level 1', level=1)
document.add_paragraph('Intense quote', style='Intense Quote')document.add_paragraph(
'first item in unordered list', style='List Bullet'
)
document.add_paragraph(
'first item in ordered list', style='List Number'
)document.add_picture('monty-truth.png', width=Inches(1.25))records = (
(3, '101', 'Spam'),
(7, '422', 'Eggs'),
(4, '631', 'Spam, spam, eggs, and spam')
)table = document.add_table(rows=1, cols=3)
hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'Qty'
hdr_cells[1].text = 'Id'
hdr_cells[2].text = 'Desc'
for qty, id, desc in records:
row_cells = table.add_row().cells
row_cells[0].text = str(qty)
row_cells[1].text = id
row_cells[2].text = descdocument.add_page_break()document.save('demo.docx')
先不考慮其他,直接執行此範例,看看會得到什麼樣的結果?
範例程式執行後,會得到一個demo.docx檔案,該檔案位於專案的資料夾裡面。
換句話說,我們透過上面的範例程式碼,建立了一個微軟Microsoft Word的.docx檔案。以下的範例程式碼已經分成幾個區塊,並且標上數字,我們接下來就透過這個檔案來觀察套件的程式碼。
建立(寫入)docx文件
要編寫一個docx文件,必須先建立一個文件的物件,才可以執行編寫的各種程序。因此,我們需要先匯入Document(紅字1)。匯入套件後就可以呼叫docx中的Document()
方法,此方法會返回一個新的空白的docx文件。如紅字2的地方,我們利用建立Document()
一個Document物件。
from docx import Documentdocument = Document()
透過上面的方式建立的空白文件,乃是基於Microsoft Word預設的版型而建立。該過程就像我們平常打開Microsoft Word軟體,並且執行「檔案 \ 新增文件」一樣。
建立一個Document物件後,就可以透過Document物件裡面的其他方法控制各個段落。最後再使用save()方法,將Document物件儲存起來(紅字9),及可完成一個doc檔案。
docx文件檔案結構
與純文字比較,docx檔並不單純,檔案中含有很多結構。這些結構表現在python-docx中是透過三種不同的類型表示。
- Document物件:代表docx整個文件。
- Paragraph物件:代表文件中的段落。
- Run物件:以相同樣式連續鄰接的文字。當文字的樣式有變化時,就需要一個新的Run物件。
以上三種類型之間的關係為:Document物件含有一個Paragraph物件的串列,Paragraph物件含有一個Run物件的串列。
以範例來說(如下圖),整份文件為Document物件,而句子 A plain paragraph having some bold and some italic. 為Paragraph物件。該句子中又可以分為四個不同的Run物件。
新增文件段落
段落(paragraph)是 Word 的基礎。除了用於本文之外,也用於標題和項目表列上,如項目符號。
add_paragraph
建立一個段落最簡單的方法就是透過add_paragraph()來建立:
p = document.add_paragraph('A plain paragraph having some ')
透過上面的方式,會在文件的「末尾」增加新的段落。請注意 add_paragraph()
是在「末尾」添加段落,而不是在前面插入段落。
如果需要兩個段落,可以再次呼叫 add_paragraph()
方法來新增段落。例如紅字5與紅字6。
在這裡,我們使用 p 作為該段落的變數。然而我們在實際使用時,通常增加段落之後不會再對它做任何事情,但因此未必需要將該段落指定給任何變數。可以像下面這樣子處理:
document.add_paragraph('Intense quote', style='Intense Quote')
insert_paragraph_before
當然,將段落指定給一個變數也不是完全沒有用途,使用它的好處是,可以將該段落作為一個基準點,在該段落的上方插入一個新的段落。
例如下面的程式碼:
prior_paragraph = paragraph.insert_paragraph_before('Lorem ipsum')
在這個程式碼中,透過insert_paragraph_before讓我們可以在paragraph的上方插入一個段落。這功能對於有修改現有文件的需求時,就變得很重要。
新增文件標題
一般來說,文件都會分為幾個部分,而每個部分都以標題開頭。可以透過呼叫add_heading
的方法來新增標題:
document.add_heading('Document Title')
在預設的情況下,上面的方法這會新增一個最高等級的標題。它在Microsoft Word中會顯示「階層1」。因此,當你需要一個較小的標題時,只需要對該標題指定等級。等級的範圍有九種,可以選擇1到9之間的整數。例如下面選擇的等級為一( level=1
)
document.add_heading('Heading, level 1', level=1)
但如果將等級指定為 0,則會增加「標題」段落。適合用在文件剛開始的部分(紅字3)。其中第二個引數,我們可以選擇0~4的數字,分別代表不同層級的標題,數字越少代表標題等級越高。
document.add_heading('Document Title', 0)
增加段落風格
基本上,Word 段落樣式很像網站的CSS 樣式,讓您可以將一整套格式選項一次性的套用在段落上面。
您可以在add_paragraph
建立段落時運用段落樣式style
。例如:Intense Quote為引用段落、List Bullet為圓點符號而List Number為數字項目符號(紅字5):
document.add_paragraph('Intense quote', style='Intense Quote')document.add_paragraph('first item in unordered list', style='List Bullet')document.add_paragraph('first item in ordered list', style='List Number')
常見的樣式如下表:
增加字元風格
以Word文件來說,樣式可以分為三種類型:
- 段落樣式
- 字元樣式
- 連結樣式
其中,段落樣式可以套入Paragrath物件;字元樣式可以套入Run物件,連結樣式則以上兩種都可以套入。
以下為常見的字元樣式如下表:
Run屬性
我們可以在Run物件的後面設定各種text的屬性以改變字元的樣式。每個屬性都可以被設定為三個不同狀態,True(啟用)、False(停用)或None。如紅字4的地方,我們可以設定段落p中的某個run物件屬性為粗體(bold)以及另一個run的物件屬性為斜體(italic)
p.add_run('bold').bold = True
p.add_run('italic.').italic = True
以下為Run物件中較常用的text屬性:
新增換頁符號
如紅字8,當我們想要在一段文章的後面加上換頁符號,讓接著的另一段文章可以從另外一個新的頁面開始,可以使用add_page_break
來新增換頁符號。
document.add_page_break()
建立表格
我們常常會需要在Word文件中建立表格來呈現某些內容,python-docx 也可以幫助我們在文件中建立表格。(如紅字7)
table = document.add_table(rows=2, cols=5)
操作儲存格
建立表格時有幾個屬性與方法需要暸解。以表格的最小單位儲存格cell來說,我們可以透過指定Row(列)與Column(行)的方式來觸及它。例如下面的程式碼:
cell = table.cell(0, 1)
透過這個程式碼可以觸及到最上面的一個Row(列)。Column(行)與Row(列)的開始值都是0。當有了儲存格之後,就可以對該儲存格進行其他的操作。例如,我們可以在該儲存格中添加文字。
cell.text = 'Hi, hello World'
通常來說,一次操作一格儲存格是比較容易的。此外,也可以透過.row
屬性對一整列進行操作,每一個列都有一個.cells
屬性就像串列一樣,可以指定位置來觸及每一個Row(列)上面不同位置的cell儲存格。例如變數row代表第一個Row(列):
row = table.rows[1]
row.cells[0].text = 'for you.'
row.cells[1].text = 'And this is for you, too'
row.cells[0]
可以觸及到第一個儲存格,row.cells[0]
則可以觸及到第二個儲存格。上面的方式對於行來說也是一樣的。只要將.row
屬性改為.column
屬性,就可以對一整行進行操作。
行列的迭代
表格上面的.rows
與 .columns
都是可以迭代的。因此,可以透過for迴圈進行迭代。此外,在Column(行)與Row(列)裡面的 .cells
也是可以被迭代的。例如透過下面方式可以把所有的儲存格內容印出來:
table = document.add_table(rows=2, cols=5)for row in table.rows:
for cell in row.cells:
print(cell.text)
行列的數量
如果想要知道表格內有多少行與列,可以透過 len()
的使用得到結果。
row_count = len(table.rows)col_count = len(table.columns)
嗣後追加行列
如果在建立表格之後,想要追加某一列的話,可以使用.add_row()
的方式增加。
row = table.add_row()
新增圖片
就像在Word中透過「插入 \ 圖片 \ 從檔案插入圖片… 」的方式添加圖片一樣,我們可以在Python python-docx
中,透過.add_picture
的方式,替文件插入圖片。
document.add_picture('image-file_name.jpg')
上面例子的圖片放在開發環境系統的目錄中,該圖片會插入文件的尾端。
調整圖片尺寸
如果不做其他特別的設定,插入的圖片會以它原本的尺寸插入文件中。有時候插入圖片的大小尺寸不太適用時,可以透過指定圖片的寬度或高度來調整插入圖片的尺寸。但在調整尺寸之前需要進行以下的匯入作業:
from docx.shared import Inches
從docx裡面Inches匯入此後,就可以讓我們指定長寬的尺寸,其單位為英吋(Inches)。如下程式碼,我們在.add_picture
的第二個引數中指定圖片的寬度為1英寸。
document.add_picture('image-file_name.jpg', width=Inches(1.0))
你可以同時指定圖片的寬度與長度,但是依照經驗,只要指定長度或寬度ㄧ邊的尺寸,就可以讓另外一邊自動達到適當的尺寸。
讀取 docx 文件
除了建立新的docx文件外,我們也可以透過python-docx讀取已經存在的docx檔案。
如果只需要文件裡面的文字資訊而不需要其他的樣式的話,可以透過for迴圈,巡迴讀取docx文件,並將裡面的文字字串取出。
for迴圈可以尋遍文件的paragraphs物件,將裡面的文字逐一新增(append)到_full_text串列中。
from docx import Documentfilename = 'demo.docx'
document = Document(filename)
_full_text = []
for paragraph in document.paragraphs:
_full_text.append(paragraph.text)print(fullText)
迴圈結束後,可以使用join的方式,把 _full_text串列中搜集到的字串,中間加上換行符號加( \\n
),並顯示出來。
print('\\n'.join(_full_text))
結語
以上說明為透過Python的第三方函式python-docx,建立Microsoft Word軟體的docx檔案與讀取docx檔案的操作方式。學會了如何使用這個套件後,就可以利用它來解決各種不同的實務上需求。下一篇將會透過這個套件,實際的建立一個文件套版的程式。