用python解析word文件(段落篇(paragraph) 表格篇(table) 样式篇(style))

本文介绍如何使用python-docx库读取Word文档中的表格数据,包括安装支持库、导入库、读取文件、获取表格集及数据的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先需要安装相应的支持库:
直接在命令行执行pip install python-docx

示例代码如下:

import docx
from docx import Document #导入库

path = "E:\\python_data\\1234.docx" #文件路径
document = Document(path) #读入文件
tables = document.tables #获取文件中的表格集
table = tables[0 ]#获取文件中的第一个表格
for i in range(1,len(table.rows)):#从表格第二行开始循环读取表格数据
result = table.cell(i,0).text + "" +table.cell(i,1).text+
table.cell(i,2).text + table.cell(i,3).text
#cell(i,0)表示第(i+1)行第1列数据,以此类推
print(result)
---------------------

_table_list = []
for i, row in enumerate(table.rows):   # 读每行
    row_content = []
    for cell in row.cells:  # 读一行中的所有单元格
        c = cell.text
        if c not in row_content:
            row_content.append(c)
    # print(row_content)
    _table_list.append(row_content)


https://www.cnblogs.com/anpengapple/p/8372987.html

转载于:https://www.cnblogs.com/klb561/p/9982937.html

<think>我们需要使用python-docx库来处理Word文档。首先,我们需要安装这个库(如果尚未安装): pip install python-docx 但是,请注意:python-docx库目前不支持直接读取或设置书签的内容。因此,我们需要使用更底层的操作,或者结合其他方法。 另一种思路是:使用COM接口(仅Windows)或使用其他库如`docx-mailmerge`(但主要用于邮件合并)?但书签替换不是标准邮件合并。 实际上,我们可以通过以下步骤实现: 1. 打开文档。 2. 遍历文档中的所有段落paragraphs)和表格tables)。 3. 在段落中,检查是否有书签(bookmark)或书签的起始点(bookmark_start)和结束点(bookmark_end)。 4. 替换书签内的文本。 但是,python-docx库没有直接提供访问书签的API。因此,我们需要使用底层的XML操作。 思路: 在docx文档中,书签是通过`<w:bookmarkStart>`和`<w:bookmarkEnd>`标签来标记的,并且有一个唯一的id和名称。书签的内容在这两个标签之间。 我们可以: - 遍历文档中的所有段落,查找书签开始和结束标签,并记录它们的位置和id。 - 然后,根据书签的名称,替换两个标签之间的文本。 但是,书签可能跨段落,甚至跨表格单元格。因此,我们需要考虑整个文档的元素(包括表格中的段落)。 由于操作较为复杂,这里提供一个基于python-docx和XML操作的函数,用于替换指定书签的文本。 步骤: 1. 加载文档。 2. 遍历文档的所有部分(包括页眉、页脚、正文等),但我们这里主要处理正文和表格。 3. 在正文中,我们遍历所有段落paragraphs)和表格tables),对于表格,我们还要遍历每个单元格(cell)的段落。 4. 使用XML解析来查找书签。 由于python-docx允许使用`element`来访问底层的XML,我们可以通过XPath来查找书签。 注意:书签可能跨多个运行(run)甚至多个段落,所以我们需要找到书签开始和结束之间的所有文本,并将其替换为新的文本。 但是,替换文本时,如果书签跨多个运行,直接替换可能会破坏文档结构。因此,我们采用以下策略: - 找到书签开始标记,然后向后遍历直到书签结束标记。 - 将书签开始和结束之间的所有文本删除,然后在书签开始后插入新的文本。 - 注意:需要保留书签标记,以便以后再次替换?或者如果不需要保留书签,我们可以只保留书签开始标记,并删除结束标记之间的内容。但通常替换后我们希望书签消失?或者保留书签以便再次替换?这里我们按照需求:替换后书签仍然保留(即只替换内容,保留书签标记)?还是替换后书签消失?通常,替换后书签应该消失,因为书签的作用就是标记位置以便替换。替换后,书签可以删除。 这里我们假设:替换后书签标记被移除,只留下替换后的文本。或者,我们也可以保留书签(以便再次替换),但这样可能会造成嵌套书签的问题。因此,根据需求,我们这里选择替换后移除书签标记,只留下文本。 由于操作相对复杂,我们可以参考已有的解决方案。以下是一个基于python-docx的书签替换函数: 参考:https://github.com/python-openxml/python-docx/issues/276 这里我们采用一个简化方法:遍历所有段落(包括表格中的段落)中的书签开始标记,然后根据书签名称替换文本,并删除书签结束标记。 具体步骤: 1. 定义一个函数,接受文档对象、书签名称和替换文本。 2. 遍历文档中的所有段落(包括表格中的段落)。 3. 对于每个段落,遍历其中的所有`w:bookmarkStart`元素。 4. 如果书签名称匹配,则记录这个书签的开始位置(即这个元素)。 5. 然后,我们需要找到与这个书签开始对应的结束标记(通过id匹配)。注意:书签开始和结束通过id关联(`w:id`属性)。 6. 然后,我们要删除书签开始和结束之间的所有文本,并在书签开始的位置插入新文本。 7. 同时,移除书签开始和结束标记。 但是,由于书签可能跨多个段落,所以我们不能只在一个段落内处理。我们需要在整个文档中搜索对应的书签结束标记。 由于跨段落处理较为复杂,我们这里先处理一个段落内的书签(即书签不跨段落)的情况。对于跨段落的情况,需要更复杂的处理。 这里提供一个简化版本,只处理书签在一个段落内的情况(大多数情况下书签不会跨段落,除非是长文本,但长文本替换时我们也可以接受替换整个书签范围,包括多个段落)。 因此,我们处理跨段落的书签:遍历整个文档的元素(包括段落表格),然后根据书签的id匹配开始和结束。 由于整个文档的XML是一个树结构,我们可以通过遍历整个文档的XML树来实现。 以下是一个实现方案: 步骤: 1. 获取文档的根元素(`document_part._element`)。 2. 使用XPath查找所有的书签开始和结束标记。 3. 根据书签名称,我们只处理指定名称的书签。 4. 对于每个书签开始标记,我们通过id找到对应的结束标记(注意:结束标记的id与开始标记的id相同)。 5. 然后,我们删除开始标记和结束标记之间的所有文本节点,并在开始标记的位置插入一个新文本节点(新的文本内容)。 6. 同时,移除书签开始和结束标记。 但是,直接操作XML树需要了解docx的XML结构,并且要小心处理。另外,删除两个标记之间的所有内容可能会破坏文档结构(比如中间有图片、超链接等),因此我们这里假设书签内只包含纯文本,并且没有其他复杂结构。 如果书签内包含复杂结构(如图片、表格等),替换为纯文本会丢失这些内容。所以,我们的函数适用于纯文本替换。 实现: 由于python-docx没有直接提供这样的功能,我们将使用`lxml`库(python-docx内部使用)来操作XML。 注意:python-docx已经使用了`lxml`,所以我们可以直接使用。 以下是一个替换书签文本的函数: 注意:这个函数会遍历整个文档(包括页眉、页脚、正文等),但这里我们只处理正文。如果需要处理页眉页脚,可以类似扩展。 步骤: 1. 获取文档的根元素(body)。 2. 使用XPath查找所有书签开始(`w:bookmarkStart`)和书签结束(`w:bookmarkEnd`)。 3. 建立一个字典,将书签名称映射到书签开始元素和对应的id(注意:同一个文档中可能有多个同名书签?通常书签名应该是唯一的,但实际可能重复,所以我们按每个书签单独处理)。 4. 对于每个需要替换的书签名,我们找到对应的书签开始元素,然后通过id找到对应的结束元素。 5. 然后,我们删除开始元素和结束元素之间的所有内容(但保留开始和结束元素本身?不,我们也要删除开始和结束元素,只留下文本?)。 6. 然后,在书签开始元素之前插入新文本,然后移除书签开始和结束元素之间的所有内容以及这两个元素本身。 但是,操作XML树需要精确控制。这里我们采用另一种方法:将书签开始和结束之间的所有元素替换为一个新的文本元素。 由于操作复杂,我们参考已有的实现。这里有一个实现示例: 参考:https://github.com/python-openxml/python-docx/issues/276#issuecomment-378746695 我们根据这个实现,进行修改: 具体代码实现如下:</think># Python实现Word文档段落表格中书签替换 下面我将详细讲解如何使用Python实现Word文档中段落表格内的书签替换功能。我们将使用`python-docx`库来处理Word文档,并实现书签的查找和替换操作。 ## 解决方案 ### 安装依赖库 首先需要安装`python-docx`库: ```bash pip install python-docx ``` ### 完整代码实现 ```python from docx import Document from docx.oxml.ns import qn from docx.oxml import parse_xml from docx.text.paragraph import Paragraph from docx.table import Table, _Cell from docx.oxml.bookmark import CT_Bookmark, CT_MarkupRange import re def replace_bookmark_in_document(doc_path, bookmark_dict, output_path): """ 替换Word文档中书签内容 参数: doc_path (str): 输入Word文档路径 bookmark_dict (dict): 书签名称和替换内容的字典 output_path (str): 输出文档路径 """ # 加载文档 doc = Document(doc_path) # 处理文档中的所有段落 for paragraph in doc.paragraphs: replace_bookmark_in_paragraph(paragraph, bookmark_dict) # 处理文档中的所有表格 for table in doc.tables: for row in table.rows: for cell in row.cells: for paragraph in cell.paragraphs: replace_bookmark_in_paragraph(paragraph, bookmark_dict) # 保存文档 doc.save(output_path) def replace_bookmark_in_paragraph(paragraph, bookmark_dict): """ 替换段落中书签内容 参数: paragraph (Paragraph): 文档段落对象 bookmark_dict (dict): 书签名称和替换内容的字典 """ # 获取段落中的所有书签 bookmarks = paragraph._element.findall('.//' + qn('w:bookmarkStart')) for bookmark in bookmarks: bookmark_name = bookmark.get(qn('w:name')) # 检查书签是否在替换字典中 if bookmark_name in bookmark_dict: # 查找书签结束标记 bookmark_end = paragraph._element.find( f'.//{{http://schemas.openxmlformats.org/wordprocessingml/2006/main}}bookmarkEnd[@{{http://schemas.openxmlformats.org/wordprocessingml/2006/main}}id="{bookmark.get(qn("w:id"))}"]' ) if bookmark_end is not None: # 获取书签开始和结束之间的所有运行(run) runs = [] current = bookmark.getnext() while current is not None and current != bookmark_end: runs.append(current) current = current.getnext() # 清除原有内容 for run in runs: run.getparent().remove(run) # 插入新内容 new_run = paragraph.add_run(bookmark_dict[bookmark_name]) # 将新内容插入到书签开始之后 bookmark.addnext(new_run._element) # 删除书签标记(可选) # bookmark.getparent().remove(bookmark) # bookmark_end.getparent().remove(bookmark_end) def find_all_bookmarks(doc_path): """ 查找文档中所有书签 参数: doc_path (str): Word文档路径 返回: list: 文档中所有书签名称列表 """ doc = Document(doc_path) bookmarks = [] # 在段落中查找书签 for paragraph in doc.paragraphs: elements = paragraph._element.xpath('.//w:bookmarkStart') for element in elements: bookmarks.append(element.get(qn('w:name'))) # 在表格中查找书签 for table in doc.tables: for row in table.rows: for cell in row.cells: for paragraph in cell.paragraphs: elements = paragraph._element.xpath('.//w:bookmarkStart') for element in elements: bookmarks.append(element.get(qn('w:name'))) return list(set(bookmarks)) # 去重 # 示例使用 if __name__ == "__main__": # 定义要替换的书签内容 bookmark_replacements = { "company_name": "创新科技有限公司", "employee_name": "张三", "position": "高级软件工程师", "salary": "25,000", "start_date": "2023-06-01", "end_date": "2025-05-31", "contract_id": "CT2023-00123" } input_doc = "input_document.docx" output_doc = "output_document.docx" # 查找文档中的所有书签(可选) all_bookmarks = find_all_bookmarks(input_doc) print("文档中的书签:", all_bookmarks) # 替换书签并保存新文档 replace_bookmark_in_document(input_doc, bookmark_replacements, output_doc) print(f"文档处理完成,已保存为: {output_doc}") ``` ## 代码解释 ### 1. 主要函数功能 - **`replace_bookmark_in_document()`**: 主函数,负责加载文档、遍历所有段落表格单元格,调用替换函数 - **`replace_bookmark_in_paragraph()`**: 在单个段落中查找并替换书签内容 - **`find_all_bookmarks()`**: 查找文档中所有书签名称(用于调试或确认书签存在) ### 2. 书签替换原理 1. **定位书签**: - 使用XML解析查找文档中的`<w:bookmarkStart>`元素 - 获取书签名称和唯一ID 2. **查找书签范围**: - 通过书签ID找到对应的`<w:bookmarkEnd>`标记 - 获取两个标记之间的所有文本内容(称为"runs") 3. **替换内容**: - 清除书签范围内的原有内容 - 在书签开始位置后插入新文本 - 可选择保留或删除书签标记本身 ### 3. 处理表格中的书签 - 表格被分解为单元格(cell) - 每个单元格被视为独立的文本容器 - 递归处理每个单元格内的段落 ### 4. 使用示例 1. 创建书签替换字典:键为书签名称,值为替换内容 2. 指定输入/输出文件路径 3. 调用`replace_bookmark_in_document()`执行替换 4. (可选)使用`find_all_bookmarks()`查看文档中所有书签 ## 使用注意事项 1. **书签命名规则**: - 书签名称不能包含空格和特殊字符 -Word中创建书签时使用有意义的名称 2. **书签位置**: - 书签应标记在需要替换的文本上 - 避免跨段落书签(当前实现不支持) 3. **格式保留**: - 替换会保留段落的基本格式 - 但不会保留原有文本的特定格式(如加粗、颜色等) 4. **复杂文档**: - 对于包含页眉/页脚的书签,需要额外处理 - 文本框中的书签需要不同的处理方式 ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值