Python-docx庫

PiggThird發表於2024-07-22

python-docx庫

  • 1、document物件
  • 2、插入標題
  • 3、插入段落
  • 4、插入一個表格
  • 5、插入圖片
  • 6、插入頁首

document物件

整個操作過程實際就是圍繞著document物件進行“增刪改查”。因此,首先需要建立一個文件物件

# pip install python-docx
from docx import Document
document = Document()

上述操作會建立一個新的空白文件,如果我們想開啟已有的模板文件,只需指定其路徑即可

document = Document('xxx.docx')

當所有的操作完成後我們需要儲存文件

document.save(os.path.join(os.getcwd(), 'xx報告.docx'))

插入標題

from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

# 標題等級只需將你想要的級別指定為 1 到 9 之間的整數
# 新增一個二級標題
head = document.add_heading(level=2)
# 標題居中
head.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 標題的內容
run = head.add_run('綠水青山就是金山銀山')
# 字型
run.font.name = 'Times New Roman'

插入一個段落

from docx.shared import Pt


# 先獲得段落物件
p = document.add_paragraph()
# 首行縮排20磅
p.paragraph_format.first_line_indent = Pt(20)
# 設定段落格式
fmt = p.paragraph_format
# 設定行間距
fmt.line_spacing = 1.5
# 一個段落可以有多個run物件,主要考慮同一段落文字可能有多種樣式
run = p.add_run('段落內容1')

# 在文件末尾新增新段落
paragraph = document.add_paragraph('我要學Python!')
# 可以把一個段落作為"游標",在其正上方插入一個新段落
prior_paragraph = paragraph.insert_paragraph_before('我是劉亦菲')

這個run物件,一開始我也沒太理解。已經新增了一個段落物件,直接填充段落內容不就行了嘛。段落物件下面再新增一個run物件是什麼意思?原來這個run物件就是一段文字整體,這樣你可以對這個整體進行統一樣式設定。沒有run物件的話,你就只能對段落物件進行統一設定,那就無法實現下面的效果

對一個run物件設定字型、顏色、大小等方法如下

from docx.shared import RGBColor
 
# 設定字型
run.font.name = 'Times New Roman'
# 字型大小
run.font.size = Pt(20)
# 字型顏色
run.font.color.rgb = RGBColor(255, 0, 0)
# 加粗
run.font.bold = True
# 斜體
run.font.italic = True

插入一個表格

# 指定圖片檔案目錄,指定插入後圖片所佔尺寸(會根據原始尺寸和指定尺寸自動縮放)
document.add_picture('xx.png', width=Pt(500), height=Pt(400))

插入頁首

from docx.shared import Cm

section = document.sections[0]
header = section.header
paragraph = header.paragraphs[0]
# 也可以直接插入文字
run = paragraph.add_run()
# 這裡是插入logo圖片
run.add_picture("logo.png", height=Cm(0.91))

常見問題

指定中文字型

前面我們指定的字型是新羅馬體,沒什麼問題。但如果我們直接將其改為'宋體'或'Sim Sun',都不會生效。這是因為宋體是非西文字型,預設是西文字型,因此不識別。需要如下操作

from docx.oxml.ns import qn

run.font.name = '宋體'
# 設定東亞字型
run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋體')

自定義樣式

from docx.enum.style import WD_STYLE_TYPE

# 自定義一個樣式物件
style = document.styles.add_style('my_style', WD_STYLE_TYPE.CHARACTER)

style.font.color.rgb = RGBColor(255, 0, 0)
style.font.name = '黑體'
style._element.rPr.rFonts.set(qn('w:eastAsia'), '黑體')
style.font.size = Pt(20)
style.font.bold = True


run1 = p.add_run('社會主義核心價值觀是社會主義核心價值體系的核心')
run2 = p.add_run('比心')
# 將自定義的樣式應用在run2上
run2.style = 'my_style'
run3 = p.add_run('體現社會主義核心價值體系的根本性質和基本特徵')

替換模板文件中文字

如果我們想基於一個模板文件進行二次編輯,可以在模板文件中設定一些佔位。透過替換佔位達到編輯的目的。如果是替換表格內容,可遍歷單元格cell,透過對cell.text重新賦值即可。

for p in document.paragraphs:
    if p.text == '佔位1':
        # 清除原有內容:也可以令p.text = '新的內容'
        p._element.clear()
        run = p.add_run('新的內容')
        run.font.size = Pt(18)

使用模板文件時有一個巨坑,新建的空白文件是支援預定義的樣式的,而模板檔案不一定。比如你在建立表格時指定style='Colorful List',實際並不一定會生效。具體原因目前還沒搞清楚。具體模板檔案有哪些預定義的樣式,可以透過下述方法獲知。

for style in document.styles:
    print(style.name)

合併多個文件

new_doc = Document() 
 
# 以此類推,將多個文件(doc2,doc3)的內容新增進去
for elem in document1.element.body:
    new_doc.element.body.append(elem)

但這種方法有一個缺點,無法複製圖片。下面提供一種不使用python-docx但有效的方法。

from win32com.client import Dispatch
 
cwd = os.getcwd()
word = Dispatch('Word.Application')
doc_files = word.Documents.Add()
# 插入文件
doc_files.Application.Selection.Range.InsertFile(os.path.join(cwd, 'tmp1.docx'))
doc_files.Application.Selection.Range.InsertFile(os.path.join(cwd, 'tmp2.docx'))
doc_files.SaveAs(os.path.join(cwd, '合併.docx'))
# 一定要關閉
word.Quit()

設定表格列寬

from docx import Document
from docx.shared import Cm
 
doc = Document()
 
rows = 3
cols = 4
table = doc.add_table(rows, cols, style='Colorful List')
# 設定每列的寬度,這裡實際是一個比例,根據總寬度14.6計算每個單元格寬度
col_widths = (1, 1, 1, 3)
for idx, width in enumerate(col_widths):
    table.cell(0, idx).width = Cm(14.6 * col_widths[idx] / sum(col_widths))
# 填充內容
for i in range(rows):
    for j in range(cols):
        table.cell(i, j).text = f'Cell {i + 1},{j + 1}'
 
doc.save('table_with_col_width.docx')

相關文章