1、图片插入位置判断优化
写了图片插入脚本后,想着每个图片都遍历一次word,有的项目测试场景多,那插入对比会变很慢。
自动化报告神器:python-docx批量插入图片,性能测试报告秒成
1.1、原始方案
在原始方案中:每一张图片,都去遍历word段落。先文本对比场景描述,找到了为True,开始对比并发数,为True后开始对比性能指标,最后插入图片。
问题是,如果段落过多,图片过多。后面的图片,对比次数越来越多,对比时间就会越来越长。
def insert_image(image_paths, doc, count):
"""
遍历图片路径列表,根据图片信息,判断插入位置,插入图片到文档
:param image_paths: 图片路径
:param doc: 打开的word文档
:param count: 成功图片数
:return count: 成功图片数
"""
for image_path in image_paths:
scene_description, concurrency, metric = get_image_info(image_path)
scene_description_flag = False # 关键词标记,辅助定位图片插入位置
concurrency_flag = False
# 遍历文档中的所有段落
for paragraph in doc.paragraphs[100:]: # 切片,去除目录等
# p = paragraph.text
if scene_description in paragraph.text:
scene_description_flag = True
elif scene_description_flag and concurrency in paragraph.text:
concurrency_flag = True
elif concurrency_flag and metric in paragraph.text:
run = paragraph.add_run() # 创建一个新的Run对象并添加到当前段落
run.add_break() # 添加一个换行符
run.add_picture(image_path, width=Inches(5.5)) # 在当前Run中插入图, 设置宽高, height=Inches(3.0)3.0英寸
# print(f"{image_path}插入成功")
count += 1
scene_description_flag = False # 关键词标记,辅助定位图片插入位置
concurrency_flag = False
return count
1.2、优化想法
先处理图片路径列表,转换成路径字典:{场景描述:{并发数:{性能指标:路径}}}
def get_image_keys(image_paths):
"""
预处理图片路径信息,列表转换字典
:param image_paths: 图片路径列表
:return: 路径字典:{场景描述:{并发数:{性能指标:路径}}}
"""
image_keys = {}
for image_path in image_paths:
scene_description, concurrency, metric = get_image_info(image_path)
# 检查是否需要创建新的字典层级
if scene_description not in image_keys:
image_keys[scene_description] = {}
if concurrency not in image_keys[scene_description]:
image_keys[scene_description][concurrency] = {}
image_keys[scene_description][concurrency][metric] = image_path # 保存文件路径到对应的位置
return image_keys
示例如下:
scene_description = {
"场景描述": {
"50并发": {
"事务响应时间": "交易处理模块/场景描述-50并发-事务响应时间.png",
"每秒点击数": "交易处理模块/场景描述-50并发-每秒点击数.png",
"TPS": "交易处理模块/场景描述-50并发-TPS.png"},
"100并发": {
"事务响应时间": "交易处理模块/场景描述-100并发-事务响应时间.png",
"每秒点击数": "交易处理模块/场景描述-100并发-每秒点击数.png",
"TPS": "交易处理模块/场景描述-100并发-TPS.png"}
}
}
遍历段落时,先将段落对比每一个‘场景描述’,为True后开始对比场景下的“并发数”,最后对比并发下的指标。插入图片,之后删除对应字典,减少后续判断次数。
这样先通过字典,只需要遍历一次word段落,段落文本对比所有图片的‘场景描述’,再对比其下的并发,层层递减,对比数据会越来越少。而且成功插入会删除字典数据,也可以减少后面的对比次数。
def insert_image_two(image_paths, doc, count):
"""
向已打开word,插入图片。优化版:通过预处理图片字典,遍历一次word段落,对比每个图片关键信息。减少了word遍历次数
:param image_paths: 图片路径
:param doc: 打开的word文档
:param count: 成功图片数
:return count: 成功图片数
"""
image_keys = get_image_keys(image_paths)
scene_description_flag = False # 关键词标记,辅助定位图片插入位置
concurrency_flag = False
for paragraph in doc.paragraphs[100:]: # 切片,去除目录等。遍历word's段落
if not scene_description_flag: # 场景描述
for scene_description in image_keys.keys():
if scene_description in paragraph.text:
scene_description_flag = True
break
elif scene_description_flag and not concurrency_flag: # 并发数
for concurrency in image_keys[scene_description].keys():
if concurrency in paragraph.text:
concurrency_flag = True
break
elif concurrency_flag: # 性能指标
for metric in image_keys[scene_description][concurrency].keys():
if metric in paragraph.text:
run = paragraph.add_run() # 创建一个新的Run对象并添加到当前段落
run.add_break() # 添加一个换行符
run.add_picture(image_keys[scene_description][concurrency][metric], width=Inches(5.5)) # 在当前
count += 1
del image_keys[scene_description][concurrency][metric] # 删除已插入图片字典
if not image_keys[scene_description][concurrency]:
del image_keys[scene_description][concurrency]
concurrency_flag = False
if not image_keys[scene_description]:
del image_keys[scene_description]
scene_description_flag = False # 关键词标记,辅助定位图片插入位置
break
if count > 0 and image_keys: # 输出未插入图片信息
print("以下图片未插入:")
for scene_description in image_keys.keys():
for concurrency in image_keys[scene_description].keys():
for metric in image_keys[scene_description][concurrency].keys():
print(f"\t{scene_description} {concurrency} {metric}")
return count
2、优化结果
-
原始方案
-
优化方案
两次图片插入都是已经改名后的图片,报告、图片等因素均一致。包含:5个场景 X 每场景4个并发 X 4个性能指标,共80张图片。时间减少一倍左右,优化方案是有效的。随着图片数增长,两个方案差距可能会进一步增大。完整代码看gitee