python-docx -- 读取word文档中的文本

ops/2024/10/20 17:58:17/

文章目录

  • word文档案例
  • 基于python-docx读取段落
  • 基于pywin32读取段落
  • 基于pywin32读取表格

word_1">word文档案例

在这里插入图片描述
需求:

  1. 读取所有的段落文本,并使用字典表示每一个段落;
  2. 段落字典格式如下:
python">{"type": "text","content": "2. Python的程序结构","runs": [{}, {}], # 每个run字典放入列表"page_num": 1 # 页码
}
  1. 所有的段落放入一个列表中;

 

pythondocx_20">基于python-docx读取段落

  • 未读取章节的编号;
python">
# 遍历所有的段落
paragraphs_list = []
word">for paragraph word">in docx.paragraphs:temp = {}temp["type"] = "text"temp["content"] = paragraph.text # 未读出章节编号  paragraph.style 获取temp["runs"] = []word">for run word">in paragraph.runs:run_dict = {}run_dict["content"] = run.textrun_dict["family"] = run.font.namerun_dict["bold"] = run.font.boldrun_dict["italic"] = run.font.italicrun_dict["size"] = run.font.sizerun_dict["color"] = run.font.color.rgb # ColorFormat.rgbrun_dict["underline"] = run.font.underlinetemp["runs"].append(run_dict)# 统计页面idtemp["page_num"] = 1 # ?paragraphs_list.append(temp)word">print("all:", paragraphs_list)

深入理解docx处理的段落
word docx文件本质是一个压缩文件,修改后缀名为.zip,即可解压得到对应的xml文件;
基于底层的 lxml 对象:

  • CT_R, Run 文本对象,对应lxml标签 <w:r>,内部包含:
    • <w:rPr> run属性
    • <w:t> 文本标签
    • obj.text
  • CT_RPr,Run对象的属性; 对应lxml标签 <w:rPr>
  • CT_P,段落对象,对应lxml标签 <w:p>,内部包含:
    • <w:pPr>
      • <w:pStyle>
      • <w:numPr>
      • <w:rPr>
    • <w:r> 可有多个run标签属性;
  • CT_PPr, 段落的属性
  • CT_Tbl,表格对象
  • CT_NumPr 对应lxml标签<w:numPr>, 最终对象(不再迭代)
    • obj.ilvl,
    • obj.numId,
    • obj.tag
  • CT_String 对应lxml标签<w:pStyle>, 最终对象(不再迭代)
    • obj.tag, {http://schemas.openxmlformats.org/wordprocessingml/2006/main}pStyle
    • obj.val, “a7” 与.values()函数类似;
    • obj.text 获取为None;
  • CT_SectPr,图片
    在这里插入图片描述
python">word">from docx word">import Documentdocx = Document("xxx.docx")
word">for i word">in docx.element.body: # lxml元素word">print(i)

 

基于pywin32读取段落

python">在这里插入代码片

 

基于pywin32读取表格

在这里插入图片描述

python"># pip install pywin32
word">from win32com.client word">import Dispatch# 打开 word应用程序
word = Dispatch("Word.Application")
# word界面不可见
word.Visible = 0
word.DisplayAlerts = 0# 打开word文档,必须是一个绝对路径
docx = word.Documents.Open("C:/Users/lenovo/Desktop/cc/lauf_chapter.docx", ReadOnly=True)table_data = []
# 遍历文档中的表格
word">for table word">in docx.Tables:# 获取行数、列数row_num = table.Rows.Countcol_num = table.Columns.Count# 初始化表格数据cur_table = [["" word">for j word">in range(col_num)] word">for i word">in range(row_num)]# 遍历单元格word">for cell word">in table.Range.Cells:  # 无内容的cell会被自动删除# cell.RowIndex, cell.ColumnIndex 均从1开始row_idx = cell.RowIndex - 1col_idx = cell.ColumnIndex - 1# 获取cell内容cur_table[row_idx][col_idx] = cell.Range.Text.strip().replace("\r", "").replace("\x07", "") # \x07 水平制表符号table_data.append(cur_table)word">print("一个表格的数据:", table_data[0])
# 关闭word文档
docx.Close(False)
# 退出word应用程序
word.Quit()

结果:
在这里插入图片描述注意:
word中的 \x07 表示水平制表符;
table.Rows 所有的单独行,迭代时不能有合并的行,否则报错;
table.Columns 所有单独列;
table.Cell 根据rid,cid 获取单元格对象;
table.Range 表格的范围对象
table.Range.Start 开始
table.Range.End 结束
table.Range.Cells 所有单元格,内容为空的单元格会被自动删除;


http://www.ppmy.cn/ops/127047.html

相关文章

.net core 3.0 与 6.0 有哪些不同

.NET Core 3.0 和 .NET 6.0&#xff08;注意&#xff0c;从 .NET 5.0 开始&#xff0c;微软将 .NET Core 和 .NET Framework 合并为一个统一的 .NET 平台&#xff09;之间有许多重要的区别。这些区别包括性能改进、新功能、API 的变化以及对不同平台的支持。下面是一些主要的区…

网络爬虫-数美滑块验证码

仅供研究学习使用。 今天带来的是数美滑块验证码的逆向 目标站 --> 传送门 解决此类验证码 首先要解决滑动距离的判定 无论是使用selenium还是使用协议的方式来破解 都绕不开滑动距离的识别 滑动距离可以参考以前我博客上的方式&#xff0c;或者找一找开源的一些算法&am…

SpringBoot中的RedisTemplate对象中的setIfAbsent()方法有什么作用?

文章目录 原子性操作用于分布式锁可选的过期时间 setIfAbsent() 方法是 Redis 中用于设置一个键值对的命令&#xff0c;只有在该键不存在时才会设置成功。它通常用于实现分布式锁的逻辑 主要功能: 原子性操作 setIfAbsent() 是一个原子性操作&#xff0c;意味着在执行该操作的…

理解ES6中的Generator

Generator是ES6引入的一种特殊的函数&#xff0c;允许函数执行过程可以暂停和恢复&#xff0c;具有异步编程的优势。通过function*声明生成器函数&#xff0c;使用yield关键字来暂停函数执行&#xff0c;并通过next()方法来恢复执行。 特点与机制&#xff1a; 暂停执行&#…

基于FPGA的以太网设计(三)

通过前文介绍了RGMII接口时序我们可以知道&#xff0c;RGMII接口是在时钟信号的上升沿和下降沿均进行数据的传输&#xff0c;而FPGA则在时钟的单沿传输数据&#xff0c;因此我们需要编写代码将RGMII接口转换为GMII接口。 由于前面的介绍我们知道RTL8211默认工作在延时状态&…

【STM32】C语言复习以及底层寄存器映射

位操作 &运算 通过与一堆1111&#xff0c;来筛选想要的位并保留 通过与一堆0000&#xff0c;来将不想要的位置置0 110011011 111111000 |运算 通过或一堆1111&#xff0c;用来全置1 通过或一堆0000&#xff0c;来筛选想要的位 右移 2 >> 1&#xff1a;相当…

JSONArray根据指定字段去重

JSONArray dataList new JSONArray();这儿省略dataList 加数据的过程 dataList new JSONArray(dataList.stream().distinct().collect(Collectors.toList())); Set<String> timestamps new HashSet<>();根据时间字段去重 dataList dataList.stream().map(obj -…

【日志】关于多益网申

2024.10.19 早先听闻多益的测试题非常抽象&#xff0c;凡是测过的人都说太抽象了&#xff0c;我还以为他考我各种算法或者编程语言呢。我今天也去做了一下&#xff0c;测试题里面大多都考些计算题&#xff0c;找规律题&#xff0c;判断推理题&#xff0c;还有一些图形转换&…