Python實(shí)現(xiàn)快速提取Word表格并轉(zhuǎn)Markdown
一、為什么需要這個(gè)工具
在測(cè)試工作中,我們常遇到這樣的場(chǎng)景:
- 需求文檔是Word格式,但需要將表格數(shù)據(jù)提取出來(lái)生成測(cè)試用例
- 手動(dòng)復(fù)制粘貼效率低且易出錯(cuò)
- 大模型需要結(jié)構(gòu)化數(shù)據(jù)輸入,但Word表格格式復(fù)雜
本文提供一套零基礎(chǔ)可操作的代碼方案,幫助測(cè)試工程師3分鐘內(nèi)完成表格提取與轉(zhuǎn)換,直接對(duì)接自動(dòng)化測(cè)試或大模型。
二、代碼實(shí)戰(zhàn):三步搞定表格提取
第一步:安裝依賴
pip install python-docx
注意:
- 如果提示權(quán)限問(wèn)題,可在命令前加 sudo(Linux/macOS)或以管理員身份運(yùn)行命令行(Windows)。
- 如果文檔包含復(fù)雜格式(如合并單元格),需確保 python-docx 版本 ≥ 0.8.11。
第二步:核心代碼解析
1. 標(biāo)題檢測(cè):精準(zhǔn)定位目標(biāo)段落
def is_heading_enhanced(paragraph): # 標(biāo)題特征:樣式名稱含關(guān)鍵詞 + 字體加粗 + 字體足夠大 style_name = (paragraph.style.name or "").lower() if "標(biāo)題" in style_name or "heading" in style_name: return True try: font = paragraph.style.font return (font.size.pt >= 14 and font.bold) if font.size else False except: return False
關(guān)鍵點(diǎn)詳解:
樣式名稱匹配:
- 優(yōu)先檢查標(biāo)題樣式名稱是否包含 標(biāo)題(中文)或 heading(英文),如 Heading 1、標(biāo)題1。
- 這一設(shè)計(jì)能快速定位到文檔中明確標(biāo)記的標(biāo)題段落。
格式兜底判斷:
- 字體大?。簶?biāo)題通常比正文大,這里設(shè)置閾值為14pt(可調(diào)整)。
- 加粗要求:標(biāo)題一般需要加粗,確保格式一致性。
- 如果段落樣式名稱未包含關(guān)鍵詞,但滿足格式條件,也會(huì)被識(shí)別為標(biāo)題。
異常處理:
使用 try-except 捕獲字體信息缺失的異常,避免程序崩潰。
2. 表格抓?。喊次臋n順序提取
def get_tables_under_heading(doc_path, target_title): from docx import Document doc = Document(doc_path) target_tables = [] found = False for element in doc.element.body.iter(): if element.tag.endswith('p'): # 段落 par = Paragraph(element, doc) if target_title in par.text and is_heading_enhanced(par): found = True elif found and is_heading_enhanced(par): # 遇到新標(biāo)題停止 break elif element.tag.endswith('tbl') and found: # 表格 table = Table(element, doc) data = [[cell.text.strip() for cell in row.cells] for row in table.rows] target_tables.append(data) return target_tables
實(shí)戰(zhàn)技巧詳解:
文檔元素遍歷:
- 通過(guò) doc.element.body.iter() 直接遍歷Word文檔底層元素,確保段落和表格的順序與實(shí)際文檔一致。
- element.tag.endswith('p') 和 element.tag.endswith('tbl') 分別識(shí)別段落和表格的XML標(biāo)簽。
雙重標(biāo)記機(jī)制:
- found 標(biāo)記:當(dāng)找到目標(biāo)標(biāo)題后,標(biāo)記為 True,開(kāi)始收集后續(xù)的表格。
- 新標(biāo)題終止:一旦遇到新標(biāo)題(同樣滿足標(biāo)題檢測(cè)條件),立即停止收集,避免誤取其他章節(jié)的表格。
數(shù)據(jù)提取:
使用列表推導(dǎo)式逐行提取表格內(nèi)容,cell.text.strip() 去除單元格中的多余空格。
3. 轉(zhuǎn)換Markdown:結(jié)構(gòu)化輸出
def to_markdown(table_data): if not table_data: return "" headers = table_data[0] md = f"| {' | '.join(headers)} |\n" md += f"| {' | '.join(['---']*len(headers))} |\n" for row in table_data[1:]: md += f"| {' | '.join(row)} |\n" return md
效果示例:
| 用戶角色 | 創(chuàng)建權(quán)限 | 刪除權(quán)限 | 修改權(quán)限 |
|----------|----------|----------|----------|
| 管理員 | 是 | 是 | 是 |
| 普通用戶 | 否 | 否 | 是 |
細(xì)節(jié)說(shuō)明:
表頭與分隔符:第一行數(shù)據(jù)作為表頭,用 --- 分隔表頭與數(shù)據(jù)行。
空表格處理:如果輸入表格為空,直接返回空字符串,避免錯(cuò)誤。
兼容性:適用于大多數(shù)表格,但若表格包含合并單元格,需額外處理(見(jiàn)后續(xù)優(yōu)化建議)。
第三步:調(diào)用代碼(5分鐘上手)
def main(): doc_path = "需求文檔_v2.0.docx" # 替換為你的文檔路徑 target_title = "功能權(quán)限矩陣" # 替換為目標(biāo)標(biāo)題 # 提取表格 tables = get_tables_under_heading(doc_path, target_title) # 輸出Markdown for idx, table in enumerate(tables, 1): print(f"--- 表格{idx} ---\n") print(to_markdown(table)) print("\n-------------------\n") if __name__ == "__main__": main()
執(zhí)行步驟:
- 將代碼保存為 extract_tables.py。
- 修改 doc_path 和 target_title 為實(shí)際文檔路徑和標(biāo)題。
- 運(yùn)行 python extract_tables.py,即可在控制臺(tái)看到Markdown格式的表格。
三、常見(jiàn)問(wèn)題與解決方案
Q1:檢測(cè)不到標(biāo)題
可能原因:
- 標(biāo)題樣式名稱不符合 標(biāo)題 或 heading 關(guān)鍵詞。
- 標(biāo)題字體大小或加粗格式未達(dá)標(biāo)。
解決方案:
1.檢查標(biāo)題樣式:
- 在Word中右鍵標(biāo)題段落 → 選擇「段落樣式」,確認(rèn)樣式名稱是否包含關(guān)鍵詞。
- 例如:將樣式改為「標(biāo)題 1」或「Heading 2」。
2.手動(dòng)調(diào)整格式判斷:
# 在 is_heading_enhanced 中,降低字體大小要求 return (font.size.pt >= 12 and font.bold) if font.size else False
Q2:表格提取不完整
可能原因:
- 表格與標(biāo)題不在同一章節(jié),中間有其他標(biāo)題阻隔。
- 文檔中存在多個(gè)同名標(biāo)題,代碼只提取第一個(gè)。
解決方案:
強(qiáng)制遍歷所有表格:
# 移除遇到新標(biāo)題停止的邏輯 # 刪除以下代碼: elif found and is_heading_enhanced(par): break
精確匹配標(biāo)題:
如果標(biāo)題文本唯一,可直接使用 par.text.strip() == target_title 完全匹配。
Q3:Markdown格式混亂
可能原因:
單元格內(nèi)容包含換行符或特殊符號(hào)。
解決方案:
清理數(shù)據(jù):
# 在提取單元格時(shí)去除換行符 cell.text.strip().replace('\n', ' ')
手動(dòng)調(diào)整:
將輸出結(jié)果復(fù)制到Markdown編輯器(如Typora),通過(guò)可視化界面調(diào)整格式。
四、真實(shí)場(chǎng)景應(yīng)用案例
場(chǎng)景1:生成接口測(cè)試用例
# 提取"接口參數(shù)表"后,直接生成測(cè)試用例模板 table_data = get_tables_under_heading("接口文檔.docx", "接口參數(shù)表")[0] for row in table_data[1:]: param, type_, example = row print(f"測(cè)試點(diǎn):{param}參數(shù)為{example}時(shí),接口應(yīng)返回{type_}類(lèi)型")
輸出示例:
測(cè)試點(diǎn):user_id參數(shù)為123時(shí),接口應(yīng)返回int類(lèi)型
測(cè)試點(diǎn):username參數(shù)為"admin"時(shí),接口應(yīng)返回str類(lèi)型
場(chǎng)景2:自動(dòng)化測(cè)試數(shù)據(jù)生成
# 將表格數(shù)據(jù)寫(xiě)入CSV文件供測(cè)試框架讀取 import csv tables = get_tables_under_heading("測(cè)試數(shù)據(jù).docx", "登錄用例數(shù)據(jù)") with open("test_data.csv", "w", newline="") as f: writer = csv.writer(f) for table in tables: writer.writerows(table)
五、代碼擴(kuò)展與優(yōu)化建議
1. 支持多級(jí)標(biāo)題
def get_tables_under_heading(doc_path, target_title, level=1): # 新增參數(shù):level表示標(biāo)題層級(jí)(如1級(jí)標(biāo)題) # 在is_heading_enhanced中增加層級(jí)判斷 if f"heading{level}" in style_name: return True
2. 處理合并單元格
def extract_cell(cell): # 處理合并單元格時(shí)的空值 if cell.text.strip(): return cell.text.strip() else: return "[合并單元格]"
3. 日志記錄與錯(cuò)誤提示
import logging logging.basicConfig(level=logging.INFO) def main(): try: tables = get_tables_under_heading(...) except FileNotFoundError: logging.error("文檔路徑錯(cuò)誤,請(qǐng)檢查文件是否存在!")
六、總結(jié)
通過(guò)這套方案,你可以:
- 快速定位文檔中指定標(biāo)題的表格
- 自動(dòng)化輸出結(jié)構(gòu)化Markdown數(shù)據(jù)
- 無(wú)縫對(duì)接測(cè)試用例生成、自動(dòng)化測(cè)試腳本等下游流程
立即嘗試:
- 將代碼保存為extract_tables.py。
- 替換文檔路徑和標(biāo)題。
- 運(yùn)行代碼,查看輸出結(jié)果。
以上就是Python實(shí)現(xiàn)快速提取Word表格并轉(zhuǎn)Markdown的詳細(xì)內(nèi)容,更多關(guān)于Python提取Word轉(zhuǎn)Markdown的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
新手如何發(fā)布Python項(xiàng)目開(kāi)源包過(guò)程詳解
這篇文章主要介紹了新手如何發(fā)布Python項(xiàng)目開(kāi)源包過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07一波神奇的Python語(yǔ)句、函數(shù)與方法的使用技巧總結(jié)
這篇文章主要介紹了一波神奇的Python函數(shù)與方法的使用技巧總結(jié),包括裝飾器和with語(yǔ)句等的不常見(jiàn)用法,需要的朋友可以參考下2015-12-12Python實(shí)現(xiàn)查找數(shù)組中任意第k大的數(shù)字算法示例
這篇文章主要介紹了Python實(shí)現(xiàn)查找數(shù)組中任意第k大的數(shù)字算法,涉及Python針對(duì)數(shù)組的排序、查找等相關(guān)操作技巧,需要的朋友可以參考下2019-01-01詳細(xì)分析Python collections工具庫(kù)
這篇文章主要介紹了詳解Python collections工具庫(kù)的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07關(guān)于jupyter代碼自動(dòng)補(bǔ)全設(shè)置方式
這篇文章主要介紹了關(guān)于jupyter代碼自動(dòng)補(bǔ)全設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06解讀opencv中cv2.imread()返回值為None問(wèn)題及解決
這篇文章主要介紹了解讀opencv中cv2.imread()返回值為None問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11