本文提供三大核心功能模块,用于从PPT文件中提取结构化数据:
文本内容提取
支持提取幻灯片中的所有文本内容(包括普通文本框、表格内文字以及分组形状中的文本)
返回按幻灯片页码组织的文本集合
表格数据提取
自动识别PPT中的表格元素
以行列结构返回表格数据,保留原始表格组织形式
支持多表格幻灯片处理
形状位置信息获取
精确定位包含特定文本的形状坐标
返回厘米为单位的精确位置和尺寸信息
当前版本注意事项:
功能限制:对于组合形状(Group Shapes)中的文本和属性,目前暂不支持提取
格式要求:仅支持.pptx格式(Office 2007及以上版本)
单位标准:位置信息统一以厘米(cm)为单位返回
完整代码如下
# -*- coding: utf-8 -*-
"""
PPT内容提取工具
功能:提取PPT中的文本内容、表格数据及形状位置信息
依赖库:python-pptx (需安装:pip install python-pptx)
注意:仅支持.pptx格式,不支持.ppt旧格式
"""
from pptx import Presentation # 主操作库,版本建议>=0.6.21
from pptx.enum.shapes import MSO_SHAPE_TYPE # 形状类型枚举常量
from pptx.util import Inches # 单位转换工具(未使用但建议保留)
class PptAttribution:
"""PPT内容解析核心类,提供三大核心功能:
1. 文本定位提取
2. 表格数据提取
3. 全文本内容提取
"""
def ppt_slide_number(self, ppt_script):
"""
获取PPT总页数(基础方法)
参数:
ppt_script (str): PPT文件路径
返回:
int: 幻灯片总页数
注意:
- 索引从0开始,如10页PPT对应0-9索引
- 会实际加载文件,频繁调用建议缓存结果
"""
prs = Presentation(ppt_script) # 创建Presentation对象
return len(prs.slides) # 获取slides集合长度
def get_high_weight_top_left_position(self, pptx_path, slide_index, str_assign='必要性说明'):
"""
精确定位包含特定文本的形状坐标(单位:厘米)
参数:
pptx_path (str): 文件路径
slide_index (int): 幻灯片索引(0-based)
str_assign (str): 要定位的关键文本
返回:
tuple: (top, left, width, height) 四元组,单位厘米
技术细节:
1. 使用360000 EMU/cm的单位换算系数
2. 只返回第一个匹配到的形状位置
3. 未找到时返回全0坐标
示例:
>>> pos = get_high_weight_top_left_position('test.pptx', 0, '摘要')
>>> print(f"位置:{pos[0]}cm, {pos[1]}cm")
"""
prs = Presentation(pptx_path)
try:
slide = prs.slides[slide_index] # 可能引发IndexError
except IndexError:
raise ValueError(f"无效幻灯片索引 {slide_index},最大应为 {len(prs.slides) - 1}")
# 初始化返回值(单位:厘米)
position = (0.0, 0.0, 0.0, 0.0)
for shape in slide.shapes:
if not shape.has_text_frame:
continue
# 提取形状内所有段落文本
text = "\n".join(p.text for p in shape.text_frame.paragraphs)
if str_assign in text: # 使用in替代find提高可读性
# EMU(English Metric Units)转换为厘米
position = (
shape.top / 360000, # 上边距
shape.left / 360000, # 左边距
shape.width / 360000, # 宽度
shape.height / 360000 # 高度
)
break # 找到第一个匹配即退出
return position
def get_only_table_text_infor_from_ppt(self, template_ppt):
"""
结构化提取PPT中所有表格数据
参数:
template_ppt (str): PPT文件路径
返回:
dict: 双层嵌套数据结构
{
页索引: [
{'行数': 行号, '列数': 列号, '信息': 单元格内容},
...
],
...
}
特殊处理:
- 自动跳过空表格
- 保留原始行列结构
- 文本自动去除首尾空格
"""
prs = Presentation(template_ppt)
table_info_dic = {}
for page_num, slide in enumerate(prs.slides): # 使用enumerate更Pythonic
page_tables = []
for shape in slide.shapes:
if not shape.has_table:
continue
table = shape.table
current_table = []
# 遍历行列(注意:合并单元格会被识别为独立单元格)
for row_idx, row in enumerate(table.rows):
for col_idx, cell in enumerate(row.cells):
text = cell.text_frame.text.strip() # 自动去除空白字符
current_table.append({
'行数': row_idx,
'列数': col_idx,
'信息': text
})
if current_table: # 非空表格才保存
page_tables.extend(current_table)
if page_tables: # 当前页有表格才存入字典
table_info_dic[page_num] = page_tables
return table_info_dic
def get_text_infor_from_ppt(self, template_ppt):
"""
全文本提取(含表格/文本框/分组形状)
参数:
template_ppt (str): PPT文件路径
返回:
dict: {页码: [文本段落1, 文本段落2,...]}
特性:
1. 三重提取机制:
- 表格内容(按行合并)
- 独立文本框
- 分组内的文本框
2. 自动UTF-8编码处理
3. 自动去除文本首尾空白
4. 错误处理机制保障稳定性
"""
prs = Presentation(template_ppt)
txt_dic = {}
for page_num, slide in enumerate(prs.slides):
page_texts = []
# 第一部分:提取表格文本(行合并模式)
for shape in slide.shapes:
try:
if hasattr(shape, "table"):
for row in shape.table.rows:
# 用"-"连接同行单元格,最后去除末尾分隔符
row_text = "-".join(
cell.text_frame.text.strip()
for cell in row.cells
)
if row_text: # 非空行才添加
page_texts.append(row_text)
except Exception as e:
print(f"页面{page_num}表格处理异常:{str(e)}")
continue
# 第二部分:提取独立文本框
for shape in slide.shapes:
try:
if shape.has_text_frame:
text = shape.text.strip()
if text:
page_texts.append(text)
except Exception as e:
print(f"页面{page_num}文本框处理异常:{str(e)}")
continue
# 第三部分:提取分组形状内的文本
for shape in slide.shapes:
if shape.shape_type != MSO_SHAPE_TYPE.GROUP:
continue
try:
for sub_shape in shape.shapes:
if sub_shape.has_text_frame:
text = sub_shape.text.strip()
if text:
page_texts.append(text)
except Exception as e:
print(f"页面{page_num}分组文本处理异常:{str(e)}")
continue
# 存入字典(即使为空列表也保留记录)
txt_dic[page_num] = page_texts
return txt_dic
# ====================== 使用示例 ======================
if __name__ == "__main__":
analyzer = PptAttribution() # 实例化分析器
pptx_path = r'耗材红蓝榜.pptx'
# 示例1:获取全文本
text_data = analyzer.get_text_infor_from_ppt(pptx_path)
print("=== 全文内容 ===")
for page, contents in text_data.items():
print(f"\n第{page + 1}页内容:")
print("\n".join(f" - {text}" for text in contents))
# 示例2:获取表格数据
table_data = analyzer.get_only_table_text_infor_from_ppt(pptx_path)
print("\n=== 表格数据 ===")
for page, cells in table_data.items():
print(f"\n第{page + 1}页表格:")
for cell in cells:
print(f" 行{cell['行数'] + 1}列{cell['列数'] + 1}: {cell['信息']}")
# 示例3:定位特定元素
print("\n=== 元素定位 ===")
for i in range(analyzer.ppt_slide_number(pptx_path)):
pos = analyzer.get_high_weight_top_left_position(
pptx_path,
slide_index=i,
str_assign='红榜示范作用'
)
print(f"第{i + 1}页定位结果:{pos}")