python基于python-docx庫自動化處理Word文檔的完整指南
python-docx是一款純Python實(shí)現(xiàn)的第三方庫,專門用于創(chuàng)建和修改Microsoft Word的.docx格式文檔。該庫無需依賴 Microsoft Word軟件即可運(yùn)行,具備優(yōu)秀的跨平臺特性,可在Windows、Mac、Linux等系統(tǒng)上使用。需要注意的是,python-docx僅兼容.docx 格式(對應(yīng) Word 2007 及以上版本),不支持舊版的.doc 格式文件。.docx是基于XML的開放壓縮格式,而.doc是二進(jìn)制私有格式,前者體積更小、兼容性更優(yōu)。
python-docx官方代碼倉庫見:python-docx,詳細(xì)文檔見:python-docx docs。截至本文撰寫時,python-docx的穩(wěn)定版本為1.2.0,python-docx安裝命令如下:
pip install python-docx
使用說明
快速入門
Python-docx中的Word文檔內(nèi)存對象模型采用樹狀結(jié)構(gòu)分層映射文檔元素,使得程序能夠精準(zhǔn)控制文檔的內(nèi)容、格式與布局。該樹狀結(jié)構(gòu)示意如下:
Document(文檔)
├── Sections(節(jié))
├── Paragraphs(段落)
│ ├── Runs(文本片段)
│ └── InlineShapes(內(nèi)聯(lián)形狀,如圖片)
├── Tables(表格)
│ ├── Rows(行)
│ │ └── Cells(單元格)
│ │ └── Paragraphs(單元格內(nèi)的段落)
└── Core Properties(文檔屬性)
各個對象簡介如下:
| 核心對象 | 代表含義 | 在文檔樹中的位置 | 主要功能與說明 |
|---|---|---|---|
| Document | 整個Word文檔對象 | 根對象 | 用于打開或創(chuàng)建一個.docx文件 |
| Sections | 文檔的節(jié) | Document.sections | 管理頁面設(shè)置(如頁邊距、紙張方向) |
| Paragraph | 段落 | Document.paragraphs或Table.cell.paragraphs | 文檔的基本單元由一個或多個Run組成,并擁有統(tǒng)一的段落格式 |
| Run | 具有相同格式的連續(xù)文本 | Paragraph.runs | 格式控制的最小單位,可以對Run單獨(dú)設(shè)置字體、大小等字符級格式 |
| Table | 表格 | Document.tables | 代表文檔中的一個表格,由行(Table.rows)、列(Table.columns)和單元格(Table.cell)組成 |
| Cell | 表格單元格 | Table.cell(row,col) | 每個Cell本身可以包含多個Paragraph,就像一個微縮文檔 |
| InlineShape | 內(nèi)嵌形狀(如圖片) | Paragraph.add_picture()創(chuàng)建 | 代表文檔中與文本在同一層的圖形對象,最常用的是圖片 |
| Styles | 樣式集合 | Document.styles | 管理文檔中定義的所有樣式(如“標(biāo)題1”、“正文”等) |

以下代碼示例描述了如何通過python-docx庫快速實(shí)現(xiàn)文檔的創(chuàng)建,完成段落、標(biāo)題、表格、圖片等內(nèi)容添加及字符段落樣式設(shè)置,并保存為docx文件:
# 1. 初始化文檔
from docx import Document
from docx.shared import Inches, Cm
# 新建空白文檔,不添加參數(shù),默認(rèn)新建
doc = Document()
# 2. 添加段落
# 默認(rèn)都會把內(nèi)容追加到文檔的末尾
doc.add_paragraph("這是文檔正文段落") # 直接添加段落
para = doc.add_paragraph("主段落") # 該方法返回新段落的引用對象
para.insert_paragraph_before("插入在主段落上方的段落") # 主段落的引用之前插入段落
para = doc.add_paragraph("插入在主段落下方的段落") # 主段落的引用之后插入段落
# 3. 添加標(biāo)題(級別1-9,0為文檔標(biāo)題)
doc.add_heading("文檔總標(biāo)題", level=0) # 一份報告的封面標(biāo)題
doc.add_heading("第一章 概述", level=1) # 一級標(biāo)題
doc.add_heading("1.1 核心功能", level=2) # 二級標(biāo)題
# 4. 分頁符
doc.add_page_break() # 強(qiáng)制后續(xù)內(nèi)容另起一頁
# 5. 添加表格(固定行+動態(tài)行+樣式)
# 5.1 固定表格(2行2列)
table1 = doc.add_table(rows=2, cols=2)
table1.cell(0, 0).text = "姓名"
table1.cell(0, 1).text = "年齡"
table1.cell(1, 0).text = "張三"
table1.cell(1, 1).text = "25"
# 5.2 動態(tài)表格(表頭+數(shù)據(jù)行)
table2 = doc.add_table(rows=1, cols=3)
# 將鼠標(biāo)懸停在Word表格樣式庫中的表格樣式縮略圖上,即可找到表格樣式名稱
table2.style = "Light Shading Accent 1" # 應(yīng)用預(yù)設(shè)樣式
headers = ["數(shù)量", "產(chǎn)品編號", "描述"]
for i, header in enumerate(headers):
table2.rows[0].cells[i].text = header
# 批量添加數(shù)據(jù)
items = [(7, "1024", "毛絨小貓"), (3, "2042", "菲比精靈"), (1, "1288", "豪華項(xiàng)圈")]
for item in items:
row = table2.add_row().cells
row[0].text = str(item[0])
row[1].text = item[1]
row[2].text = item[2]
# 6. 添加圖片(本地文件+尺寸調(diào)整)
doc.add_picture("test.png", width=Inches(1.5)) # 1.5英寸寬(自動等比縮放)
doc.add_picture("test2.jpg", width=Cm(5),height=Cm(1)) # 同時指定寬高
# 7. 段落樣式(項(xiàng)目符號/編號)
doc.add_paragraph("項(xiàng)目符號列表項(xiàng)1", style="ListBullet")
doc.add_paragraph("項(xiàng)目符號列表項(xiàng)2", style="ListBullet")
doc.add_paragraph("編號列表項(xiàng)1", style="ListNumber")
# 8. 字符格式(粗體/斜體)
para = doc.add_paragraph()
para.add_run("普通文本 ").bold = False
para.add_run("粗體文本").bold = True
para.add_run(" 普通文本 ").italic = False
para.add_run("斜體文本").italic = True
# 9. 字符樣式(預(yù)設(shè)樣式)
para2 = doc.add_paragraph("普通文本,")
para2.add_run("帶強(qiáng)調(diào)的文本", style="Emphasis") # 應(yīng)用"強(qiáng)調(diào)"樣式
# 10. 保存文檔
doc.save("test_output.docx")
后續(xù)內(nèi)容將對python-docx的各個核心對象進(jìn)行具體介紹。
Python-docx的核心對象
Document對象
Python-docx本質(zhì)上是一個文檔修改工具。即使創(chuàng)建新文檔,其原理也是基于一個預(yù)設(shè)的空白模板進(jìn)行修改。因此,文檔的格式(如樣式、頁眉、頁腳)與正文內(nèi)容是分離存儲的,即使清空模板文字也不會刪除格式設(shè)定。以下示例展示了如何創(chuàng)建文檔或打開已有文檔:
from docx import Document
from io import BytesIO, StringIO # 用于類文件對象操作
"""演示python-docx操作文檔的核心功能"""
# ===================== 1. 創(chuàng)建新文檔并保存 =====================
print("1. 創(chuàng)建新文檔并保存...")
# 基于默認(rèn)模板創(chuàng)建空文檔
new_doc = Document()
new_doc.add_heading('python-docx 文檔操作示例', level=1)
new_doc.add_paragraph('這是通過python-docx創(chuàng)建的新文檔')
# 保存新文檔到本地
new_doc.save('新建文檔.docx')
print("? 新文檔已保存為:新建文檔.docx")
# ===================== 2. 打開現(xiàn)有文檔并修改保存 =====================
print("\n2. 打開現(xiàn)有文檔并修改...")
# 打開剛才創(chuàng)建的文檔
existing_doc = Document('新建文檔.docx')
# 向文檔追加內(nèi)容
existing_doc.add_paragraph('這是打開現(xiàn)有文檔后追加的內(nèi)容')
# 另存為新文件(避免覆蓋原文件)
existing_doc.save('修改后的文檔.docx')
print("? 修改后的文檔已保存為:修改后的文檔.docx")
# ===================== 3. 通過類文件對象(BytesIO)讀寫文檔 =====================
print("\n3. 通過類文件對象操作文檔...")
# 3.1 讀?。簩⒈镜匚臋n讀取到BytesIO流中
with open('修改后的文檔.docx', 'rb') as f: # 必須用rb(二進(jìn)制讀),跨平臺兼容
doc_stream = BytesIO(f.read()) # 用BytesIO而非StringIO
# 從流中打開文檔
stream_doc = Document(doc_stream)
# 追加內(nèi)容
stream_doc.add_paragraph('這是通過類文件對象添加的內(nèi)容')
# 3.2 保存:將文檔保存到BytesIO流中(不落地到本地文件)
output_stream = BytesIO()
stream_doc.save(output_stream)
# 可選:將流中的內(nèi)容寫入本地文件,驗(yàn)證結(jié)果
with open('類文件對象生成的文檔.docx', 'wb') as f:
f.write(output_stream.getvalue())
print("? 類文件對象操作的文檔已保存為:類文件對象生成的文檔.docx")
# 關(guān)閉流
doc_stream.close()
output_stream.close()
Table對象
Word軟件中的表格功能相當(dāng)復(fù)雜,這導(dǎo)致在使用python-docx操作表格時,往往難以提前明確表格的具體內(nèi)容和結(jié)構(gòu),增加了處理的難度。本節(jié)將從簡單表格到復(fù)雜表格來介紹如何使用python-docx操作表格。
規(guī)整表格
規(guī)整表格也就是一個行列數(shù)固定、無合并或省略單元格的標(biāo)準(zhǔn)表格,這是最基礎(chǔ)的表格形式。關(guān)系型數(shù)據(jù)庫表和pandas數(shù)據(jù)表都是規(guī)整表格的典型示例:
+---+---+---+
| a | b | c |
+---+---+---+
| d | e | f |
+---+---+---+
| g | h | i |
+---+---+---+
通過控制表格行列數(shù)即可創(chuàng)建規(guī)整表格:
from docx import Document
from docx.shared import Inches
# 創(chuàng)建新文檔
doc = Document()
# 添加3行2列的規(guī)整表格
table = doc.add_table(rows=3, cols=2)
table.style = 'Table Grid' # 顯示表格邊框,便于查看
# 填充單元格內(nèi)容(a-i 對應(yīng)示例中的規(guī)整表格)
cell_texts = ['a', 'b', 'c', 'd', 'e', 'f']
idx = 0
for row in table.rows:
for cell in row.cells:
cell.text = cell_texts[idx]
idx += 1
# 保存文檔
doc.save('規(guī)整表格示例.docx')
# 讀取并驗(yàn)證規(guī)整表格的行列數(shù)(每行單元格數(shù)相同)
print("規(guī)整表格每行的單元格數(shù):")
for i, row in enumerate(table.rows):
print(f"第{i+1}行:{len(row.cells)}個單元格")
合并單元格
將多個連續(xù)的橫向或縱向單元格合并為一個單元格,是實(shí)際使用中非常常見的方式:
+---+---+---+ +---+---+---+
| a | b | | | b | c |
+---+---+---+ + a +---+---+
| c | d | e | | | d | e |
+---+---+---+ +---+---+---+
| f | g | h | | f | g | h |
+---+---+---+ +---+---+---+
實(shí)現(xiàn)方式為先創(chuàng)建規(guī)整表格,再通過cell.merge()實(shí)現(xiàn)單元格的橫向或縱向合并:
from docx import Document
doc = Document()
table = doc.add_table(rows=2, cols=3)
table.style = 'Table Grid'
# 示例1:橫向合并(第一行第一個單元格合并右側(cè)單元格)
cell_1_1 = table.cell(0, 0) # 第1行第1列(索引從0開始)
cell_1_2 = table.cell(0, 1)
cell_1_1.merge(cell_1_2)
cell_1_1.text = '合并單元格(橫向)'
# 示例2:縱向合并(第三列前兩個單元格合并)
cell_1_3 = table.cell(0, 2)
cell_2_3 = table.cell(1, 2)
cell_1_3.merge(cell_2_3)
cell_1_3.text = '合并單元格(縱向)'
# 填充其他單元格
table.cell(1, 0).text = 'd'
table.cell(1, 1).text = 'e'
# 查看合并后每行的單元格數(shù)
# 注意以下內(nèi)容返回的是原始表格結(jié)構(gòu)
print("合并單元格后每行的單元格數(shù):")
for i, row in enumerate(table.rows):
print(f"第{i+1}行:{len(row.cells)}個單元格")
doc.save('合并單元格示例.docx')
遞歸表格
表格處理的另一個復(fù)雜點(diǎn)是其遞歸特性,Word中的表格單元格本身可以包含一個或多個表格。可以通過_Cell.tables或_Cell.iter_inner_content()檢測嵌套表格:
_Cell.tables:直接返回單元格內(nèi)包含的所有表格。_Cell.iter_inner_content():按文檔順序返回單元格內(nèi)的所有內(nèi)容(包括段落和表格),保持表格與段落的相對位置不變。
示例代碼如下:
from docx import Document
from docx.shared import Inches
from docx.table import Table
from docx.text.paragraph import Paragraph
def generate_nested_table_doc():
"""生成帶嵌套表格的示例Word文檔(示例數(shù)據(jù))"""
# 1. 創(chuàng)建新文檔
doc = Document()
# 2. 創(chuàng)建外層表格(2行2列)
outer_table = doc.add_table(rows=2, cols=2)
outer_table.style = 'Table Grid' # 顯示表格邊框
# 3. 填充外層表格的普通單元格
cell_1_1 = outer_table.cell(0, 0)
cell_1_1.text = "下方單元格包含嵌套表格"
cell_1_2 = outer_table.cell(0, 1)
cell_1_2.text = "普通單元格(無嵌套)"
# 4. 關(guān)鍵:在 (1,0) 單元格中嵌套一個子表格
cell_2_1 = outer_table.cell(1, 0)
# 先給嵌套表格前加一個段落(模擬真實(shí)文檔的混合內(nèi)容)
para = cell_2_1.add_paragraph("嵌套表格前的段落內(nèi)容:")
# 在單元格內(nèi)創(chuàng)建嵌套表格(3行1列)
inner_table = cell_2_1.add_table(rows=3, cols=1)
inner_table.style = 'Table Grid'
# 填充嵌套表格
inner_table.cell(0, 0).text = "嵌套表格-行1"
inner_table.cell(1, 0).text = "嵌套表格-行2"
inner_table.cell(2, 0).text = "嵌套表格-行3"
# 嵌套表格后再加一個段落
cell_2_1.add_paragraph("嵌套表格后的段落內(nèi)容")
# 5. 填充外層表格最后一個單元格
cell_2_2 = outer_table.cell(1, 1)
cell_2_2.text = "普通單元格(無嵌套)"
# 6. 保存文檔(生成示例數(shù)據(jù))
doc.save("嵌套表格.docx")
print("=" * 50)
print("? 嵌套表格.docx")
print("=" * 50)
def traverse_table(table, level=0):
"""
遞歸遍歷表格,處理嵌套表格
:param table: 要遍歷的表格對象
:param level: 表格嵌套層級(外層為0,內(nèi)層+1)
"""
indent = " " * level # 縮進(jìn),方便區(qū)分層級
print(f"\n{indent}=== 遍歷【層級{level}】表格 ===")
# 遍歷表格的每一行
for row_idx, row in enumerate(table.rows):
# 遍歷行中的每一個單元格
for col_idx, cell in enumerate(row.cells):
print(f"\n{indent}單元格 ({row_idx+1}, {col_idx+1}):")
# --------------------------
# 方法1:_Cell.tables - 直接獲取單元格內(nèi)的所有表格
# --------------------------
inner_tables = cell.tables
if inner_tables:
print(f"{indent} ?? 檢測到 {len(inner_tables)} 個嵌套表格:")
# 遞歸遍歷每個嵌套表格
for inner_table in inner_tables:
traverse_table(inner_table, level + 1)
else:
print(f"{indent} ?? 無嵌套表格")
# --------------------------
# 方法2:_Cell.iter_inner_content() - 按順序獲取單元格內(nèi)所有內(nèi)容(段落+表格)
# --------------------------
print(f"{indent} ?? 單元格內(nèi)完整內(nèi)容(按順序):")
for content in cell.iter_inner_content():
if isinstance(content, Paragraph):
# 處理段落內(nèi)容(過濾空段落)
text = content.text.strip()
if text:
print(f"{indent} [段落]:{text}")
elif isinstance(content, Table):
# 遇到表格時的提示(避免重復(fù)遍歷,僅演示位置)
print(f"{indent} [表格]:嵌套表格(層級{level+1})")
def parse_nested_tables():
"""解析生成的嵌套表格文檔,演示核心方法"""
# 1. 打開示例文檔
doc = Document("嵌套表格.docx")
# 2. 遍歷文檔中的所有外層表格
print("\n開始解析嵌套表格:")
print("-" * 50)
for table in doc.tables:
traverse_table(table)
# 主程序入口
if __name__ == "__main__":
# 生成帶嵌套表格的示例文檔
generate_nested_table_doc()
# 第二步:解析嵌套表格,演示_Cell.tables和iter_inner_content的使用
parse_nested_tables()
print("\n" + "=" * 50)
print("? 嵌套表格解析完成!")
print("=" * 50)
文本處理
在Word文檔中,內(nèi)容的組織邏輯分為兩個主要層級:塊級對象和行內(nèi)對象。
- 塊級對象(如段落、表格)是占據(jù)整行的大模塊,其寬度由頁面邊距、分欄或單元格邊界決定,文本會在其左右邊界內(nèi)自動換行。
- 行內(nèi)對象則存在于這些大模塊內(nèi)部,如加粗的詞語或句子,最常見的表現(xiàn)形式是文本片段(runs)。一個段落就是由一個或多個文本片段組成的。
相應(yīng)地,格式控制也分為兩類:
- 塊級屬性(如縮進(jìn)、間距、對齊方式)控制模塊在頁面上的布局位置;
- 行內(nèi)屬性(如字體、加粗、顏色)則控制模塊內(nèi)部文字的具體外觀。
下面通過Python-docx的代碼示例,展示這兩類格式的實(shí)際應(yīng)用:
from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import (
WD_ALIGN_PARAGRAPH,
WD_TAB_ALIGNMENT,
WD_TAB_LEADER,
WD_UNDERLINE
)
from docx.enum.dml import MSO_THEME_COLOR
# 創(chuàng)建一個新的 Word 文檔
doc = Document()
# ==================== 1. 塊級格式設(shè)置:段落布局控制 ====================
# 1.1 標(biāo)題段落(居中對齊、段后間距)
title_para = doc.add_paragraph("Python-docx 文本格式示例")
title_format = title_para.paragraph_format # 塊級格式對象
title_format.alignment = WD_ALIGN_PARAGRAPH.CENTER # 居中對齊(塊級屬性)
title_format.space_after = Pt(18) # 段后間距(塊級屬性)
# 1.2 正文段落(縮進(jìn)與行間距)
content_para = doc.add_paragraph("這是一個帶縮進(jìn)和自定義行間距的正文段落。")
content_format = content_para.paragraph_format
content_format.left_indent = Inches(0.5) # 左縮進(jìn)
content_format.first_line_indent = Inches(-0.25) # 懸掛縮進(jìn)
content_format.line_spacing = 1.5 # 1.5倍行間距
content_format.space_before = Pt(12) # 段前間距
# 1.3 帶制表位的段落(塊級定位)
tab_para = doc.add_paragraph("姓名:\t張三\t年齡:\t25")
tab_format = tab_para.paragraph_format
tab_stops = tab_format.tab_stops
# 添加三個制表位(位置、對齊方式、前導(dǎo)符)
tab_stops.add_tab_stop(Inches(1.5), WD_TAB_ALIGNMENT.RIGHT, WD_TAB_LEADER.DOTS)
tab_stops.add_tab_stop(Inches(2.5), WD_TAB_ALIGNMENT.LEFT, WD_TAB_LEADER.SPACES)
tab_stops.add_tab_stop(Inches(3.5), WD_TAB_ALIGNMENT.RIGHT, WD_TAB_LEADER.DOTS)
# 1.4 分頁控制(塊級保持與孤行控制)
page_para1 = doc.add_paragraph("這是章節(jié)標(biāo)題(確保與下一段同頁)")
page_para1.paragraph_format.keep_with_next = True # 與下段同頁
page_para2 = doc.add_paragraph("這是章節(jié)內(nèi)容,啟用了孤行控制,避免段落首行/末行單獨(dú)顯示在一頁。" * 20)
page_para2.paragraph_format.widow_control = True # 避免孤行
# ==================== 2. 行內(nèi)格式設(shè)置:文字外觀控制 ====================
char_para = doc.add_paragraph("字符格式示例:")
# 粗體
bold_run = char_para.add_run("粗體文本")
bold_run.font.bold = True
char_para.add_run(" | ")
# 斜體
italic_run = char_para.add_run("斜體文本")
italic_run.font.italic = True
char_para.add_run(" | ")
# 下劃線(雙下劃線)
underline_run = char_para.add_run("雙下劃線文本")
underline_run.font.underline = WD_UNDERLINE.DOUBLE
char_para.add_run(" | ")
# 不同字號和顏色
color_run = char_para.add_run("16號紅色文本")
color_run.font.size = Pt(16) # 字號
color_run.font.color.rgb = RGBColor(255, 0, 0) # 顏色
char_para.add_run(" | ")
# 上標(biāo)
sup_run = char_para.add_run("上標(biāo)")
sup_run.font.superscript = True
# ==================== 3. 保存文檔 ====================
doc.save("文本格式示例.docx")
print("文檔已保存為:文本格式示例.docx")
Sections對象
Word引入了節(jié)(section)的概念,它指文檔中具有相同頁面布局(如頁邊距、紙張方向)的連續(xù)部分。通過分節(jié),用戶可以在同一份文檔中混合使用不同版式,例如同時包含縱向頁面和橫向頁面。此外,每個節(jié)還可以獨(dú)立設(shè)置其頁眉與頁腳的樣式。絕大多數(shù)Word文檔默認(rèn)僅包含一個節(jié),通常也無需更改頁面布局。然而,當(dāng)確實(shí)需要對頁面布局進(jìn)行調(diào)整時,理解節(jié)的功能與設(shè)置方法就變得至關(guān)重要。以下示例展示了如何使用python-docx庫創(chuàng)建包含多個節(jié)、各節(jié)擁有不同頁面設(shè)置的Word文檔:
from docx import Document
from docx.enum.section import WD_SECTION_START
from docx.enum.section import WD_ORIENT
from docx.shared import Inches
# 1. 創(chuàng)建新文檔并查看默認(rèn)節(jié)
document = Document()
print("初始文檔的節(jié)數(shù)量:", len(document.sections)) # 默認(rèn)1個節(jié)
# 獲取默認(rèn)節(jié)并修改其基礎(chǔ)布局(縱向,常規(guī)邊距)
default_section = document.sections[0]
# 設(shè)置默認(rèn)節(jié)的邊距:左1.5英寸、右1英寸、上下各1英寸
default_section.left_margin = Inches(1.5)
default_section.right_margin = Inches(1)
default_section.top_margin = Inches(1)
default_section.bottom_margin = Inches(1)
# 2. 給默認(rèn)節(jié)添加內(nèi)容(縱向頁面內(nèi)容)
document.add_heading('第一節(jié):縱向頁面內(nèi)容', level=1)
document.add_paragraph('這是默認(rèn)節(jié)的內(nèi)容,頁面為縱向,邊距:左1.5英寸、右1英寸。')
# 3. 添加新節(jié)(奇數(shù)頁開始,橫向布局)
# 創(chuàng)建新節(jié),指定分節(jié)符類型為奇數(shù)頁開始
new_section = document.add_section(WD_SECTION_START.ODD_PAGE)
# 修改新節(jié)的頁面方向?yàn)闄M向(需同時交換寬高)
new_section.orientation = WD_ORIENT.LANDSCAPE
# 先交換寬高值,避免頁面尺寸異常
new_width, new_height = new_section.page_height, new_section.page_width
new_section.page_width = new_width
new_section.page_height = new_height
# 設(shè)置新節(jié)的邊距:左右各1.25英寸,上下各0.8英寸
new_section.left_margin = Inches(1.25)
new_section.right_margin = Inches(1.25)
new_section.top_margin = Inches(0.8)
new_section.bottom_margin = Inches(0.8)
# 4. 給新節(jié)添加內(nèi)容(橫向頁面內(nèi)容)
document.add_heading('第二節(jié):橫向頁面內(nèi)容', level=1)
document.add_paragraph('這是新節(jié)的內(nèi)容,頁面為橫向,邊距:左右1.25英寸、上下0.8英寸。')
# 5. 再添加一個新節(jié)(偶數(shù)頁開始,縱向布局)
third_section = document.add_section(WD_SECTION_START.EVEN_PAGE)
# 恢復(fù)縱向布局
third_section.orientation = WD_ORIENT.PORTRAIT
third_section.page_width = Inches(8.5)
third_section.page_height = Inches(11)
# 設(shè)置特殊邊距(添加裝訂線)
third_section.gutter = Inches(0.2) # 裝訂線0.2英寸
third_section.header_distance = Inches(0.6) # 頁眉距離0.6英寸
# 6. 給第三個節(jié)添加內(nèi)容
document.add_heading('第三節(jié):帶裝訂線的縱向頁面', level=1)
document.add_paragraph('這一節(jié)包含0.2英寸的裝訂線,頁眉距離頁面頂部0.6英寸。')
# 7. 遍歷所有節(jié),打印關(guān)鍵屬性
print("\n=== 所有節(jié)的關(guān)鍵屬性 ===")
for idx, section in enumerate(document.sections):
print(f"\n第{idx+1}節(jié):")
print(f" 起始類型:{section.start_type}")
print(f" 頁面方向:{section.orientation}")
print(f" 左右邊距:{section.left_margin/914400:.2f}英寸 / {section.right_margin/914400:.2f}英寸")
print(f" 裝訂線:{section.gutter/914400:.2f}英寸")
# 保存文檔
document.save("多節(jié)文檔示例.docx")
print("\n文檔已保存為:多節(jié)文檔示例.docx")
頁眉頁腳對象
頁眉是指顯示在每一頁上頁邊距區(qū)域的文本,與正文內(nèi)容相互獨(dú)立,通常用于展示文檔標(biāo)題、作者、創(chuàng)建日期或頁碼等上下文信息。同一文檔中的頁眉在各頁面間基本保持一致,僅在部分內(nèi)容上可能存在細(xì)微差異,例如章節(jié)標(biāo)題或頁碼的變化。頁腳在功能和特性上與頁眉完全類似,唯一的區(qū)別是頁腳位于頁面底部。頁腳與腳注不同,腳注在各頁面間并不統(tǒng)一。以下是操作文檔頁眉頁腳的示例代碼:
from docx import Document
# -------------------------- 1. 初始化文檔并創(chuàng)建基礎(chǔ)頁眉 --------------------------
# 創(chuàng)建新文檔
doc = Document()
# 獲取文檔的第一個節(jié)(新建文檔默認(rèn)只有1個節(jié))
section1 = doc.sections[0]
header1 = section1.header
# 檢查初始狀態(tài):新建文檔的頁眉默認(rèn)關(guān)聯(lián)到前一節(jié)頁眉設(shè)置(此處無前置節(jié),故無實(shí)際頁眉)
print(f"初始頁眉關(guān)聯(lián)狀態(tài): {header1.is_linked_to_previous}") # 輸出: True
# 為第一節(jié)添加簡單頁眉(僅左側(cè)文本)
# 直接編輯頁眉的第一個段落(新建頁眉默認(rèn)包含1個空段落)
para1 = header1.paragraphs[0]
para1.text = "文檔主標(biāo)題 - 第一節(jié)頁眉"
# 自動創(chuàng)建獨(dú)立頁眉定義,關(guān)聯(lián)狀態(tài)變?yōu)镕alse
print(f"添加頁眉后關(guān)聯(lián)狀態(tài): {header1.is_linked_to_previous}") # 輸出: False
# -------------------------- 2. 添加帶分區(qū)(左/中/右)的頁眉 --------------------------
# 先清空第一節(jié)原有頁眉內(nèi)容,重新設(shè)置分區(qū)頁眉
para1.clear()
# 使用制表符\t分隔左、中、右三部分內(nèi)容
para1.text = "左側(cè):文檔名稱\t居中:2026年1月\t右側(cè):頁碼"
# 應(yīng)用Word默認(rèn)的"Header"樣式(確保制表位生效)
para1.style = doc.styles["Header"]
# -------------------------- 3. 添加新節(jié)并設(shè)置獨(dú)立頁眉 --------------------------
# 向文檔末尾添加新節(jié)(section2)
section2 = doc.add_section()
header2 = section2.header
# 初始狀態(tài):新節(jié)的頁眉默認(rèn)關(guān)聯(lián)到前一節(jié)(section1)
print(f"第二節(jié)初始關(guān)聯(lián)狀態(tài): {header2.is_linked_to_previous}") # 輸出: True
# 驗(yàn)證:此時編輯header2的內(nèi)容會直接修改section1的頁眉(繼承特性)
# 先取消關(guān)聯(lián),創(chuàng)建第二節(jié)的獨(dú)立頁眉
header2.is_linked_to_previous = False
# 為第二節(jié)添加專屬頁眉
para2 = header2.paragraphs[0]
para2.text = "第二節(jié)獨(dú)立頁眉 - 僅本節(jié)顯示"
# -------------------------- 4. 添加頁腳(與頁眉用法完全一致) --------------------------
# 為第一節(jié)添加頁腳(包含頁碼)
footer1 = doc.sections[0].footer
footer1.is_linked_to_previous = False # 取消關(guān)聯(lián),創(chuàng)建獨(dú)立頁腳
footer_para1 = footer1.paragraphs[0]
footer_para1.text = "\t第 {PAGE} 頁 / 共 {NUMPAGES} 頁\t" # 居中顯示頁碼
footer_para1.style = doc.styles["Footer"]
# 為第二節(jié)添加不同的頁腳
footer2 = doc.sections[1].footer
footer2.is_linked_to_previous = False
footer_para2 = footer2.paragraphs[0]
footer_para2.text = "第二節(jié)頁腳 - 聯(lián)系人:測試賬號"
# -------------------------- 5. 刪除頁眉(恢復(fù)關(guān)聯(lián)狀態(tài)) --------------------------
# 若需刪除第二節(jié)的獨(dú)立頁眉,只需將其關(guān)聯(lián)狀態(tài)設(shè)為True(會永久刪除內(nèi)容)
# 此處僅演示,注釋掉避免影響最終效果
# header2.is_linked_to_previous = True
# -------------------------- 6. 保存文檔 --------------------------
doc.save("頁眉頁腳示例.docx")
print("文檔已保存為:頁眉頁腳示例.docx")
非文本內(nèi)容管理
樣式管理
在Word中,內(nèi)置樣式會出現(xiàn)在Word界面的樣式面板中,但不會自動加入文檔中,直到你第一次使用它。這樣避免了文件因所有樣式定義而臃腫。一旦某樣式被使用,其定義就會永久加入文檔,即使后來刪除應(yīng)用內(nèi)容也不會消失。因此,若要用python-docx使樣式生效,必須在初始文檔中包含其定義,否則樣式會靜默失效。
以下是一個綜合性的示例,它整合了文檔中所有核心的樣式操作功能,包括樣式的訪問、應(yīng)用、創(chuàng)建、刪除,以及字符段落格式的定義等:
from docx import Document
from docx.enum.style import WD_STYLE_TYPE
from docx.shared import Pt, Inches
from docx.enum.text import WD_UNDERLINE
# 1. 創(chuàng)建新文檔并訪問樣式集合
doc = Document()
styles = doc.styles
print(f"初始樣式數(shù)量: {len(styles)}")
# 2. 訪問并篩選特定類型的樣式
# 篩選所有段落樣式并打印名稱
print("\n=== 所有段落樣式 ===")
paragraph_styles = [s for s in styles if s.type == WD_STYLE_TYPE.PARAGRAPH]
for style in paragraph_styles[:5]: # 只打印前5個避免輸出過長
print(f"- {style.name}")
# 3. 應(yīng)用現(xiàn)有樣式到新段落
# 方式1: 創(chuàng)建時指定樣式名稱
doc.add_heading("樣式操作示例", level=0)
heading1_para = doc.add_paragraph("這是應(yīng)用 Heading 1 樣式的段落", style="Heading 1")
# 方式2: 先創(chuàng)建段落再賦值樣式對象
normal_para = doc.add_paragraph()
normal_para.text = "這是先創(chuàng)建再應(yīng)用 Normal 樣式的段落"
normal_para.style = styles["Normal"]
# 4. 創(chuàng)建自定義樣式
# 4.1 創(chuàng)建段落樣式并設(shè)置基礎(chǔ)樣式、字符格式、段落格式
citation_style = styles.add_style("Citation", WD_STYLE_TYPE.PARAGRAPH)
# 設(shè)置基礎(chǔ)樣式(繼承 Normal 樣式的格式)
citation_style.base_style = styles["Normal"]
# 設(shè)置字符格式
citation_style.font.name = "宋體"
citation_style.font.size = Pt(10)
citation_style.font.italic = True # 斜體
citation_style.font.underline = WD_UNDERLINE.DOT_DASH # 點(diǎn)劃線下劃線
# 設(shè)置段落格式(懸掛縮進(jìn)、段前間距)
citation_style.paragraph_format.left_indent = Inches(0.25)
citation_style.paragraph_format.first_line_indent = Inches(-0.25)
citation_style.paragraph_format.space_before = Pt(6)
# 設(shè)置后續(xù)段落樣式
citation_style.next_paragraph_style = styles["Normal"]
# 應(yīng)用自定義樣式
citation_para = doc.add_paragraph("這是自定義 Citation 樣式的引用文本", style="Citation")
print(f"\n自定義樣式應(yīng)用后名稱: {citation_para.style.name}")
# 5. 控制樣式在 Word 中的顯示(快速樣式、優(yōu)先級)
body_text_style = styles["Body Text"]
body_text_style.hidden = False
body_text_style.quick_style = True
body_text_style.priority = 1
# 6. 處理潛在樣式(Latent Styles)
latent_styles = styles.latent_styles
print(f"\n潛在樣式總數(shù): {len(latent_styles)}")
# 為 List Bullet 添加潛在樣式定義
if "List Bullet" not in latent_styles:
latent_list_bullet = latent_styles.add_latent_style("List Bullet")
latent_list_bullet.hidden = False
latent_list_bullet.priority = 2
latent_list_bullet.quick_style = True
print(f"List Bullet 潛在樣式優(yōu)先級: {latent_styles['List Bullet'].priority}")
# 7. 刪除樣式
print(f"\n刪除前樣式數(shù)量: {len(styles)}")
if "Citation" in styles:
styles["Citation"].delete()
print(f"刪除后樣式數(shù)量: {len(styles)}")
# 8. 保存文檔
doc.save("樣式操作示例.docx")
print("\n文檔已保存為: 樣式操作示例.docx")
批注管理
Word支持在文檔中添加批注,這是審閱功能的一部分,通常用于他人在不修改原文的情況下提供反饋。Word文檔里操作步驟如下:
- 選取文本范圍;
- 點(diǎn)擊審閱工具欄中的新建批注;
- 輸入或粘貼批注內(nèi)容。
批注僅能添加至文檔主體,不可插入頁眉、頁腳或其他批注內(nèi)。Word文檔里腳注和尾注中理論上允許添加批注,但當(dāng)前python-docx暫不支持該操作。此外高版本W(wǎng)ord支持解決批注和回復(fù)批注功能,但python-docx暫未實(shí)現(xiàn)。以下是包含批注創(chuàng)建、富文本批注、元數(shù)據(jù)修改及批注遍歷的完整示例:
# 導(dǎo)入必要的庫
from docx import Document
from datetime import datetime, timezone
"""
創(chuàng)建文檔并演示批注的完整操作流程:
1. 創(chuàng)建基礎(chǔ)批注
2. 創(chuàng)建富文本格式批注
3. 修改批注元數(shù)據(jù)
4. 訪問和遍歷所有批注
"""
# 1. 初始化文檔對象
doc = Document()
doc.add_heading("Python-docx 批注演示文檔", level=1)
# 2. 示例1:創(chuàng)建基礎(chǔ)文本批注
para1 = doc.add_paragraph("這是第一段測試文本,用于添加基礎(chǔ)批注。")
# 為整段文本添加基礎(chǔ)批注
basic_comment = doc.add_comment(
runs=para1.runs, # 關(guān)聯(lián)的文本塊
text="基礎(chǔ)批注:這段文本表述清晰,建議保留。", # 批注純文本內(nèi)容
author="張三", # 批注作者
initials="ZS" # 作者縮寫
)
print(f"? 基礎(chǔ)批注創(chuàng)建完成")
# 3. 示例2:創(chuàng)建富文本格式批注(包含粗體、斜體等樣式)
para2 = doc.add_paragraph("這是第二段測試文本,用于添加富文本批注。")
# 創(chuàng)建空內(nèi)容批注(后續(xù)手動添加富文本)
rich_comment = doc.add_comment(
runs=para2.runs,
text="", # 初始為空,后續(xù)添加富文本
author="李四",
initials="LS"
)
# 向批注中添加富文本內(nèi)容
cmt_para = rich_comment.paragraphs[0] # 獲取批注的默認(rèn)段落
cmt_para.add_run("富文本批注:") # 普通文本
cmt_para.add_run("重點(diǎn)建議:").bold = True # 粗體文本
cmt_para.add_run("這段文本需要補(bǔ)充案例,").italic = True # 斜體文本
cmt_para.add_run("建議參考行業(yè)標(biāo)準(zhǔn)。") # 普通文本
# 4. 示例3:修改批注元數(shù)據(jù)(作者、縮寫)
basic_comment.author = "張小三" # 修改作者名
basic_comment.initials = "ZXS" # 修改作者縮寫
print(f"? 基礎(chǔ)批注元數(shù)據(jù)已更新:作者={basic_comment.author},縮寫={basic_comment.initials}")
# 5. 示例4:訪問和遍歷所有批注
print("\n?? 文檔中所有批注信息:")
for idx, comment in enumerate(doc.comments):
print(f"\n批注 {idx+1}:")
print(f" 作者:{comment.author}")
print(f" 縮寫:{comment.initials}")
# 提取批注的完整文本(兼容富文本)
comment_text = "\n ".join([para.text for para in comment.paragraphs])
print(f" 內(nèi)容:{comment_text}")
# 6. 保存文檔
doc.save("批注演示文檔.docx")
print("\n?? 文檔已保存為:批注演示文檔.docx")
圖片對象
Word文檔中的內(nèi)容分為兩個圖層:文本層和繪圖層。文本層按從左到右、自上而下的順序排列,頁滿則自動換頁。繪圖層中的對象稱為形狀,可自由放置。圖片是一種特殊形狀,可置于文本層或繪圖層。位于文本層的圖片稱為嵌入式圖片,它在排版中被視為一個大型文本字符:行高會自動調(diào)整以容納圖片,并支持類似文本的換行效果。若在其前方插入文本,圖片會隨之向后移動。嵌入式圖片通常獨(dú)占一個段落,但也可與前后文本共存于同一段落中。
當(dāng)前python-docx庫僅支持嵌入式圖片。通過Document.add_picture()方法可將圖片默認(rèn)添加至文檔末尾的獨(dú)立段落中,但經(jīng)過適當(dāng)設(shè)置,也能實(shí)現(xiàn)靈活的圖文混排效果,示例如下:
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
# 1. 創(chuàng)建一個新的Word文檔
doc = Document()
# 2. 基礎(chǔ)用法:在文檔末尾插入圖片(單獨(dú)占一個段落)
doc.add_heading('1. 基礎(chǔ)插入圖片', level=2)
# 添加圖片,設(shè)置寬度為2英寸(高度會按比例自動調(diào)整)
doc.add_picture('test.png', width=Inches(2))
# 3. 進(jìn)階用法:圖文混排(圖片和文本在同一個段落)
doc.add_heading('2. 圖文混排示例', level=2)
# 創(chuàng)建一個新段落
mixed_paragraph = doc.add_paragraph()
# 添加文本到段落開頭
mixed_paragraph.add_run('這是圖片左側(cè)的文本,')
# 在段落中插入圖片(非單獨(dú)段落)
img_run = mixed_paragraph.add_run()
img_run.add_picture('test.png', width=Inches(1))
# 在圖片右側(cè)添加文本
mixed_paragraph.add_run('這是圖片右側(cè)的文本。')
# 4. 自定義圖片尺寸+段落對齊
doc.add_heading('3. 自定義尺寸與對齊', level=2)
align_para = doc.add_paragraph()
align_para.alignment = WD_ALIGN_PARAGRAPH.CENTER # 段落居中對齊
align_run = align_para.add_run()
# 同時設(shè)置寬度和高度(注意:可能導(dǎo)致圖片變形)
align_run.add_picture('test.png', width=Inches(1.5), height=Inches(1))
align_para.add_run('\n這是居中顯示的圖片')
# 5. 保存文檔
doc.save('形狀圖片示例.docx')
print("文檔已保存為形狀圖片示例.docx")
綜合示例
在實(shí)際應(yīng)用中,python-docx主要被用于文檔修改和自動化生成,而非從頭創(chuàng)建文檔。本節(jié)將通過一個綜合示例,展示如何對一個包含標(biāo)題、段落、多種表格、多張圖片和分頁符的多頁文檔進(jìn)行針對性修改,并提供相應(yīng)的文檔生成代碼。

文檔生成
以下代碼生成一個示例多頁文檔,涵蓋了日常辦公中常見的文檔結(jié)構(gòu):
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn
import os
def ensure_test_images():
# 簡單生成測試圖片(如果沒有的話)
try:
from PIL import Image
for i in range(1, 3):
img_path = f"image{i}.jpg"
if not os.path.exists(img_path):
img = Image.new('RGB', (800, 600), color='lightblue')
img.save(img_path)
print("測試圖片已準(zhǔn)備完成")
except ImportError:
print("請安裝pillow庫:pip install pillow")
exit(1)
# 生成Word文檔
def generate_complex_doc():
# 創(chuàng)建新文檔
doc = Document()
# 設(shè)置文檔默認(rèn)字體(解決中文顯示問題)
doc.styles['Normal'].font.name = '微軟雅黑'
doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
# ========== 第一頁內(nèi)容 ==========
# 標(biāo)題
title = doc.add_heading('XX項(xiàng)目調(diào)研報告', 0)
title.alignment = WD_ALIGN_PARAGRAPH.CENTER # 居中對齊
title_run = title.runs[0]
title_run.font.size = Pt(24)
title_run.font.bold = True
# 副標(biāo)題/說明
sub_para = doc.add_paragraph('報告生成時間:2026年1月 報告編制人:測試用戶')
sub_para.alignment = WD_ALIGN_PARAGRAPH.RIGHT
sub_para_run = sub_para.runs[0]
sub_para_run.font.size = Pt(10)
# 正文段落
doc.add_heading('一、項(xiàng)目概述', level=1)
overview_para = doc.add_paragraph()
overview_para.add_run('本項(xiàng)目針對企業(yè)數(shù)字化轉(zhuǎn)型需求,重點(diǎn)解決現(xiàn)有業(yè)務(wù)系統(tǒng)數(shù)據(jù)孤島、流程不規(guī)范、決策效率低等核心問題。').font.size = Pt(12)
overview_para.add_run('\n項(xiàng)目覆蓋范圍包括:').font.bold = True
overview_para.add_run('\n1) 生產(chǎn)管理模塊:實(shí)現(xiàn)生產(chǎn)流程自動化監(jiān)控')
overview_para.add_run('\n2) 銷售管理模塊:打通客戶數(shù)據(jù)與訂單系統(tǒng)')
overview_para.add_run('\n3) 財務(wù)管理模塊:實(shí)現(xiàn)財務(wù)數(shù)據(jù)實(shí)時匯總分析')
# 第一個表格:項(xiàng)目基礎(chǔ)信息表(2行4列)
doc.add_heading('1.1 項(xiàng)目基礎(chǔ)信息', level=2)
table1 = doc.add_table(rows=2, cols=4)
table1.alignment = WD_TABLE_ALIGNMENT.CENTER # 表格居中
table1.style = 'Table Grid' # 帶邊框樣式
# 填充表格1表頭
hdr_cells = table1.rows[0].cells
hdr_cells[0].text = '項(xiàng)目編號'
hdr_cells[1].text = '項(xiàng)目名稱'
hdr_cells[2].text = '啟動時間'
hdr_cells[3].text = '預(yù)計工期'
# 填充表格1內(nèi)容
row_cells = table1.rows[1].cells
row_cells[0].text = 'XM2026001'
row_cells[1].text = '企業(yè)數(shù)字化轉(zhuǎn)型項(xiàng)目'
row_cells[2].text = '2026-01-01'
row_cells[3].text = '12個月'
# 調(diào)整表格1單元格字體
for row in table1.rows:
for cell in row.cells:
for paragraph in cell.paragraphs:
for run in paragraph.runs:
run.font.size = Pt(10)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
# 插入第一張圖片
doc.add_heading('1.2 項(xiàng)目架構(gòu)圖', level=2)
img1_para = doc.add_paragraph()
img1_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
img1_run = img1_para.add_run()
img1_run.add_picture('image1.jpg', width=Inches(5)) # 圖片寬度5英寸
img1_para.add_run('\n圖1:項(xiàng)目整體架構(gòu)圖').font.size = Pt(10)
# 插入分頁符(第一頁結(jié)束)
doc.add_page_break()
# ========== 第二頁內(nèi)容 ==========
doc.add_heading('二、項(xiàng)目資源配置', level=1)
resource_para = doc.add_paragraph('本項(xiàng)目所需資源包括人力資源、硬件資源、軟件資源三大類,具體配置如下表所示:')
# 第二個表格:資源配置表(5行3列)
table2 = doc.add_table(rows=5, cols=3)
table2.style = 'Table Grid'
table2.alignment = WD_TABLE_ALIGNMENT.CENTER
# 填充表格2
table2_data = [
['資源類型', '規(guī)格/數(shù)量', '備注'],
['人力資源', '項(xiàng)目經(jīng)理1人,開發(fā)工程師5人,測試工程師2人', '均為全職'],
['服務(wù)器', '8核16G云服務(wù)器3臺', '阿里云ECS'],
['數(shù)據(jù)庫', 'MySQL 8.0 主從架構(gòu)', '數(shù)據(jù)實(shí)時備份'],
['軟件授權(quán)', 'Python、Office、開發(fā)工具', '企業(yè)版授權(quán)']
]
for i, row_data in enumerate(table2_data):
row_cells = table2.rows[i].cells
for j, cell_text in enumerate(row_data):
row_cells[j].text = cell_text
# 設(shè)置單元格字體
for paragraph in row_cells[j].paragraphs:
for run in paragraph.runs:
run.font.size = Pt(10)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
# 表頭加粗
if i == 0:
for cell in table2.rows[i].cells:
for paragraph in cell.paragraphs:
for run in paragraph.runs:
run.font.bold = True
# 插入第二張圖片
doc.add_heading('2.1 資源部署示意圖', level=2)
img2_para = doc.add_paragraph()
img2_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
img2_run = img2_para.add_run()
img2_run.add_picture('image2.jpg', width=Inches(5))
img2_para.add_run('\n圖2:資源部署拓?fù)鋱D').font.size = Pt(10)
# 補(bǔ)充段落內(nèi)容
doc.add_paragraph('資源配置遵循「夠用且預(yù)留擴(kuò)展」原則,硬件資源可根據(jù)項(xiàng)目進(jìn)度彈性擴(kuò)容,人力資源采用「核心+外協(xié)」模式保障交付進(jìn)度。')
# 插入分頁符(第二頁結(jié)束)
doc.add_page_break()
# ========== 第三頁內(nèi)容 ==========
doc.add_heading('三、項(xiàng)目風(fēng)險評估', level=1)
risk_para = doc.add_paragraph('通過對技術(shù)、人員、成本、進(jìn)度四個維度的評估,識別出以下核心風(fēng)險點(diǎn)及應(yīng)對措施:')
# 第三個表格:風(fēng)險評估表(4行4列)
table3 = doc.add_table(rows=4, cols=4)
table3.style = 'Table Grid'
table3.alignment = WD_TABLE_ALIGNMENT.CENTER
table3_data = [
['風(fēng)險類型', '風(fēng)險等級', '影響范圍', '應(yīng)對措施'],
['技術(shù)風(fēng)險', '中', '核心功能模塊', '提前進(jìn)行技術(shù)預(yù)研,制定備選方案'],
['進(jìn)度風(fēng)險', '低', '整體交付', '設(shè)置里程碑節(jié)點(diǎn),每周進(jìn)度復(fù)盤'],
['成本風(fēng)險', '低', '預(yù)算管控', '建立成本臺賬,超支提前預(yù)警']
]
for i, row_data in enumerate(table3_data):
row_cells = table3.rows[i].cells
for j, cell_text in enumerate(row_data):
row_cells[j].text = cell_text
for paragraph in row_cells[j].paragraphs:
for run in paragraph.runs:
run.font.size = Pt(10)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
if i == 0:
for cell in table3.rows[i].cells:
for paragraph in cell.paragraphs:
for run in paragraph.runs:
run.font.bold = True
# 結(jié)尾段落
doc.add_paragraph('\n綜上所述,本項(xiàng)目整體可控,通過科學(xué)的資源配置和風(fēng)險管控措施,能夠保障項(xiàng)目按計劃交付并達(dá)到預(yù)期目標(biāo)。')
# 保存文檔
doc.save('項(xiàng)目報告.docx')
print("項(xiàng)目報告文檔已生成")
if __name__ == '__main__':
ensure_test_images() # 準(zhǔn)備測試圖片
generate_complex_doc()
文檔修改
文檔修改代碼針對上述生成的文檔,實(shí)現(xiàn)以下常見修改需求:
- 修改標(biāo)題和段落文本
- 修改表格中的內(nèi)容
- 替換圖片
- 添加新的段落和表格
- 修改字體樣式
示例代碼如下:
from docx import Document
from docx.shared import Inches, Pt
from docx.shared import RGBColor
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
import os
# 修改已生成的Word文檔
def modify_complex_doc(file_path):
# 打開已生成的文檔
doc = Document(file_path)
print("已打開待修改的文檔")
# ========== 1. 修改標(biāo)題 ==========
# 第一個標(biāo)題是級別0的標(biāo)題(主標(biāo)題)
main_title = doc.paragraphs[0]
main_title.runs[0].text = 'XX企業(yè)數(shù)字化轉(zhuǎn)型項(xiàng)目終版報告' # 修改主標(biāo)題文本
main_title.runs[0].font.color.rgb = RGBColor(0, 0, 255) # 標(biāo)題改為藍(lán)色
main_title.runs[0].font.size = Pt(20)
main_title.runs[0].font.name = '微軟雅黑'
main_title.runs[0]._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
main_title.alignment = WD_ALIGN_PARAGRAPH.CENTER
# ========== 2. 修改段落文本 ==========
# 找到"項(xiàng)目概述"下的段落(可通過文本特征定位)
for para in doc.paragraphs:
if '本項(xiàng)目針對企業(yè)數(shù)字化轉(zhuǎn)型需求' in para.text:
# 清空原有內(nèi)容,重新寫入
para.clear()
new_run = para.add_run('本項(xiàng)目針對大型制造企業(yè)數(shù)字化轉(zhuǎn)型需求,重點(diǎn)解決現(xiàn)有業(yè)務(wù)系統(tǒng)數(shù)據(jù)孤島、流程不規(guī)范、決策效率低等核心問題。')
new_run.font.size = Pt(12)
new_run.font.name = '微軟雅黑'
new_run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
# 追加內(nèi)容
para.add_run('\n項(xiàng)目升級后新增:')
para.add_run('\n4) 供應(yīng)鏈管理模塊:打通上下游供應(yīng)商數(shù)據(jù)')
break
# ========== 3. 修改表格內(nèi)容并添加表格名 ==========
# 表格1:項(xiàng)目基礎(chǔ)信息表(第一個表格)
table1 = doc.tables[0]
# 修改項(xiàng)目編號
table1.rows[1].cells[0].text = 'XM2026001-FINAL'
# 修改預(yù)計工期
table1.rows[1].cells[3].text = '10個月'
# 給修改后的單元格文字標(biāo)紅
for cell in [table1.rows[1].cells[0], table1.rows[1].cells[3]]:
for para in cell.paragraphs:
for run in para.runs:
run.font.color.rgb = RGBColor(255, 0, 0)
run.font.size = Pt(11)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
# 為表格1添加表格名(表題)
# 找到表格1的位置,在表格上方插入表名
table1_elem = table1._element
table_caption1 = doc.add_paragraph('表1 項(xiàng)目基礎(chǔ)信息表')
table_caption1.alignment = WD_ALIGN_PARAGRAPH.CENTER # 居中對齊
table_caption1.paragraph_format.space_before = Pt(0)
table_caption1.paragraph_format.space_after = Pt(0)
# 設(shè)置表名字體格式
for run in table_caption1.runs:
run.font.size = Pt(11)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
run.font.bold = True # 加粗
# 將表名插入到表格上方
table1_elem.addprevious(table_caption1._element)
# 表格2:資源配置表(第二個表格)
table2 = doc.tables[1]
# 修改服務(wù)器配置
table2.rows[3].cells[1].text = '16核32G云服務(wù)器3臺(升級配置)'
# 設(shè)置表格2單元格字體
for row in table2.rows:
for cell in row.cells:
for para in cell.paragraphs:
for run in para.runs:
run.font.size = Pt(11)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
# 為表格2添加表格名(表題)
table2_elem = table2._element
table_caption2 = doc.add_paragraph('表2 項(xiàng)目資源配置表')
table_caption2.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in table_caption2.runs:
run.font.size = Pt(11)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
run.font.bold = True
table2_elem.addprevious(table_caption2._element)
# ========== 4. 替換圖片并規(guī)范圖名 ==========
# 先準(zhǔn)備一張新的測試圖片
from PIL import Image
new_img_path = 'test.png'
if not os.path.exists(new_img_path):
img = Image.new('RGB', (800, 600), color='lightgreen')
img.save(new_img_path)
# 找到第一張圖片所在的段落(通過圖片相關(guān)特征)
img_para_index = -1
for i, para in enumerate(doc.paragraphs):
if '圖1:項(xiàng)目整體架構(gòu)圖' in para.text or 'graphicData' in str(para._element.xml):
img_para_index = i
break
if img_para_index != -1:
# 清空段落中的圖片和文字,重新添加
img_para = doc.paragraphs[img_para_index]
img_para.clear()
# 重新添加新圖片
img_run = img_para.add_run()
img_run.add_picture(new_img_path, width=Inches(5))
# 添加規(guī)范的圖名(圖題)
img_caption = img_para.add_run('\n圖1 項(xiàng)目整體架構(gòu)圖(終版)')
img_caption.font.size = Pt(10)
img_caption.font.name = '微軟雅黑'
img_caption._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
img_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
# ========== 5. 添加新內(nèi)容并為新表格加表名 ==========
# 在第三頁風(fēng)險評估后添加新的段落和表格
# 先找到風(fēng)險評估標(biāo)題的位置,在其后添加內(nèi)容
for i, para in enumerate(doc.paragraphs):
if '三、項(xiàng)目風(fēng)險評估' in para.text:
# 添加新的子標(biāo)題
new_sub_heading = doc.add_heading('3.1 風(fēng)險應(yīng)對預(yù)案', level=2)
# 插入到指定位置
doc.paragraphs.insert(i+1, new_sub_heading)
# 添加新段落
new_para = doc.add_paragraph('針對高優(yōu)先級風(fēng)險,制定專項(xiàng)應(yīng)對預(yù)案,包括應(yīng)急響應(yīng)流程、備用資源調(diào)配方案等,確保風(fēng)險發(fā)生時可快速處置。')
new_para.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
for run in new_para.runs:
run.font.size = Pt(12)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
doc.paragraphs.insert(i+2, new_para)
# 添加新表格(應(yīng)急預(yù)案表)
new_table = doc.add_table(rows=2, cols=2)
new_table.style = 'Table Grid'
new_table.alignment = WD_TABLE_ALIGNMENT.CENTER
# 填充新表格
new_table.rows[0].cells[0].text = '風(fēng)險類型'
new_table.rows[0].cells[1].text = '應(yīng)急聯(lián)系人'
new_table.rows[1].cells[0].text = '技術(shù)風(fēng)險'
new_table.rows[1].cells[1].text = '張工 13800138000'
# 設(shè)置新表格字體
for row in new_table.rows:
for cell in row.cells:
for para_cell in cell.paragraphs:
for run in para_cell.runs:
run.font.size = Pt(10)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
# 為新表格添加表名
new_table_caption = doc.add_paragraph('表3 風(fēng)險應(yīng)急聯(lián)系人表')
new_table_caption.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in new_table_caption.runs:
run.font.size = Pt(11)
run.font.name = '微軟雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微軟雅黑')
run.font.bold = True
# 插入新表格名和新表格
doc.element.body.insert(i+3, new_table_caption._element)
doc.element.body.insert(i+4, new_table._element)
break
# ========== 保存修改后的文檔 ==========
doc.save('項(xiàng)目報告_修改版.docx')
print("修改后的文檔已保存:項(xiàng)目報告_修改版.docx")
if __name__ == '__main__':
# 確保原文檔存在
file_path = '項(xiàng)目報告.docx'
if not os.path.exists(file_path):
print("請先運(yùn)行生成代碼創(chuàng)建原始文檔!")
else:
modify_complex_doc(file_path)
到此這篇關(guān)于python基于python-docx庫自動化處理Word文檔的完整指南的文章就介紹到這了,更多相關(guān)python自動化處理Word內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python實(shí)現(xiàn)兩數(shù)之和的畫解算法
這篇文章主要介紹了使用python實(shí)現(xiàn)兩數(shù)之和的畫解算法,采用實(shí)例問題的描述來進(jìn)行問題分析,并給出用暴力求解和哈希表兩種方法解決方案,有需要的朋友可以參考下2021-08-08
使用opencv-python如何打開USB或者筆記本前置攝像頭
這篇文章主要介紹了使用opencv-python如何打開USB或者筆記本前置攝像頭的過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
Python3.6實(shí)現(xiàn)帶有簡單界面的有道翻譯小程序
本文通過實(shí)例代碼給大家介紹了基于Python3.6實(shí)現(xiàn)帶有簡單界面的有道翻譯小程序,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧2019-04-04

