完成添加金风动态图片函数

This commit is contained in:
Voge1imkafig 2025-08-01 18:02:19 +08:00
parent 78ab1e3962
commit e39e04cdc0
11 changed files with 265 additions and 91 deletions

View File

@ -4,7 +4,7 @@ from tools.document_tools import (
add_table_to_document,add_dynamic_table,add_section,
process_server_images_table,add_header,add_landscape_section,
merge_documents,add_table,add_defect_info_table,add_table_title,
add_title,change_heading,add_auto_toc_at_end
add_title,change_heading,add_auto_toc_at_end,add_jf_picture_table
)
# 内容处理工具
@ -310,13 +310,22 @@ async def generate_jf_report(base_info, baogao_info):
table_list = tree_dict_to_table_data(defect_part_type_list) # 服务器获取的树形结构转化为表格数据
table_list = defect_list_addtitle(table_list, jizu_bianhao) # 增加每列标题,机组
add_table_title(output_dir, DEFECT_TABLE_TITLE) # 增加表格标题
total_table_num += 1
table_json = list_to_json_with_merges(table_list, style_config=STYLE_CONFIG, merge_columns=2) #将list转换为json形式前两列检查相同合并
json_to_docx(table_json, output_dir).save(output_dir) #jsontodocx
total_table_num += 1
#使用器具记录表
add_table_title(output_dir, USE_TOOL_TABLE_TITLE)
total_table_num += 1
json_to_docx(list_to_json_with_merges(use_tool_table, style_config=STYLE_CONFIG, detect_merges=False),output_dir).save(output_dir)
total_table_num += 1
#添加目录节
add_section(output_dir).save(output_dir)
@ -330,33 +339,87 @@ async def generate_jf_report(base_info, baogao_info):
print(add_heading(output_dir, f"1. 机组号:{jizu_bianhao}", 1))
print(add_heading(output_dir, f"1.1 叶片编号:{Y_Code[0]}", 2))
#add_header(output_dir, TEMPLATE_HEADER.JINFENG_HEADER.ENUM, if_section=False, text = " " + TEMPLATE_HEADER.JINFENG_HEADER.PARA)
add_table_to_document(
output_dir,
get_resource_path(MUBAN_DIR + '/jfempty.docx'),
3,
5,
total_table_num,
if_merge=False,
Report_Enum=TEMPLATE_HEADER.JINFENG_HEADER.ENUM,
if_para=False
)
"""
典型图片dict 典型图片的描述固定
{
图片描述 : 图片地址, #情况一
描述部位缺陷数量 : 缺陷类型数量, #情况二
...
}
缺陷图片dict 缺陷图片的描述从信息来源获取
{
图片描述 : 图片地址,
}
typical_picture_list: #每列有两种情况
[
[str(图片描述), int(n), ...],
[str(图片地址), str(缺陷类型), ...]
]
defect_picture_list: #只有一种情况
[
[str(图片描述), str(图片描述), ...],
[str(图片地址), str(图片地址), ...]
]
"""
typical_picture_list = []
typical_picture_dict = {}
for description, url in zip(typical_picture_description, typical_picture_list):
typical_picture_dict[description] = url
print(typical_picture_dict)
defect_picture_dict = {}
defect_picture_list = []
typical_picture_list = [
[
"外观检查迎、背风面是否有漆面脱落、裂纹等1",
"外观检查前、后缘如前缘漆面脱落、合模缝开裂等2",
"外观检查迎、背风面是否有漆面脱落、裂纹等3",
"外观检查前、后缘如前缘漆面脱落、合模缝开裂等4",
"外观检查迎、背风面是否有漆面脱落、裂纹等5",
"外观检查前、后缘如前缘漆面脱落、合模缝开裂等6",
"外观检查迎、背风面是否有漆面脱落、裂纹等7",
"外观检查前、后缘如前缘漆面脱落、合模缝开裂等8",
"外观检查迎、背风面是否有漆面脱落、裂纹等9",
"外观检查前、后缘如前缘漆面脱落、合模缝开裂等10",
],
[
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
2,
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
2,
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
2,
2,
],
[
"",
"图层脱落",
"",
"",
"图层脱落",
"",
"",
"",
"图层脱落",
"图层脱落",
]
]
defect_picture_list = [
[
"1",
"2",
"3456",
"456",
"56",
"6",
"12",
"123",
],
[
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
"/home/dtyx/桌面/yhh/Report_Generate_Server/muban/wechat_2025-07-29_123404_038.png",
]
]
total_table_num = add_jf_picture_table(
typical_picture_list,
defect_picture_list,
get_resource_path(MUBAN_DIR + '/typical_picture_table.docx'),
get_resource_path(MUBAN_DIR + '/defect_picture_table.docx'),
output_dir,
total_table_num
)

Binary file not shown.

Binary file not shown.

View File

@ -307,16 +307,16 @@ async def add_table(filename: str, rows: int, cols: int, data: Optional[List[Lis
except Exception as e:
return f"Failed to add table: {str(e)}"
async def add_picture_to_table(
def add_picture_to_table(
target_doc: Document,
target_filename: str,
row: int,
col: int,
image_path: str,
table_num: int = -1,
width: Optional[float] = None
width: Optional[float] = None,
height: Optional[float] = None
) -> str:
"""修正版图片添加函数(解决图片不显示问题)"""
from PIL import Image
from io import BytesIO
import requests
@ -361,13 +361,13 @@ async def add_picture_to_table(
# 添加图片(带异常捕获)
try:
if width:
run.add_picture(final_bytes, width=Inches(width))
run.add_picture(final_bytes, width=Inches(width), height=Inches(height))
else:
run.add_picture(final_bytes)
except Exception:
final_bytes.seek(0) # 再次重置指针
if width:
run.add_picture(final_bytes, width=Inches(width))
run.add_picture(final_bytes, width=Inches(width), height=Inches(height))
else:
run.add_picture(final_bytes)
@ -656,39 +656,3 @@ def search_and_replace(filename: str, find_text: str, replace_text: str) -> str:
return f"No occurrences of '{find_text}' found."
except Exception as e:
return f"Failed to search and replace: {str(e)}"
def add_jf_picture_table(
typical_picture_dict : dict,
defect_picture_dict : dict,
TYPICAL_MUBAN_DIR : str,
DEFECT_MUBAN_DIR : str,
output_dir : str,
):
"""添加金风版本的图片展示表格
逻辑
典型图模板是三行五列的表格一列对应一张典型图图片信息
缺陷图模板是二行五列的表格一列对应一张缺陷图图片信息
1.每次循环添加一次典型图片
第一行为dict的key
第二行为图片如有缺陷则不是图片url而是字符串 损伤n处详见下表此时要有变量记录总损伤数
第三行看情况如果正常则保持默认如果有缺陷则字段为 损伤类型n处
2.如果上一次循环没有缺陷图则回到1否则前往3
3.如果上一次循环中有缺陷图存在则进入对应的缺陷图添加模式,使用缺陷图表格模板
根据上一行每列的总缺陷数遍历缺陷字典
当缺陷数大于5时也要调用模板进行下一行的添加
缺陷图表格使用缺陷图模板第一行为defect_picture_dict的key第二行为图片url第三行为损伤类型
Args:
typical_picture_dict: #有两种情况
{
str(图片描述) : str(图片地址), #情况一
str(损伤有n处见下表) : str({缺陷类型}n处), #情况二
...
}
defect_picture_dict: #只有一种情况
{
str(图片描述) : str(图片地址),
}
TYPICAL_MUBAN_DIR: 典型图模板路径
DEFECT_MUBAN_DIR: 缺陷图模板路径
"""

View File

@ -208,7 +208,7 @@ def add_documents(target_filename: str, source_filename: str) -> str:
def write_table(target_filename: str, rows: int, cols: int, table_num: int, data: Optional[List[List[str]]] = None, ifadjustheight: Optional[bool] = True, height: Optional[float] = 1, key_words: re.Pattern[str] = None, ALIGMENT: Optional[str] = 'CENTER') -> Document:
def write_table(target_filename: str, rows: int, cols: int, table_num: int, data: Optional[List[List[str]]] = None, ifadjustheight: Optional[bool] = True, height: Optional[float] = None, key_words: re.Pattern[str] = None, ALIGMENT: Optional[str] = 'CENTER', width: Optional[float] = None) -> Document:
"""填写word文档里的表格返回填写后的文档
Args:
@ -252,25 +252,49 @@ def write_table(target_filename: str, rows: int, cols: int, table_num: int, data
for j, cell_text in enumerate(row_data):
if j >= cols + 1:
break
if cell_text.endswith((".png", ".jpg", ".jpeg")):
target_doc.save(target_filename)
target_doc.tables[table_num].cell(i,j).text = ""
print(f"在[{i},{j}]处添加图片{cell_text}")
if os.path.exists(cell_text):
if height:
target_doc.tables[table_num].cell(i,j).add_paragraph().add_run().add_picture(cell_text, height=Inches(height), width=Inches(width))
else:
target_doc.tables[table_num].cell(i,j).add_paragraph().add_run().add_picture(cell_text,)
continue
else:
print(f"本地没有图片{cell_text},从服务器下载图片")
if height:
add_picture_to_table(target_doc, target_filename, i, j, cell_text, height=Inches(height), width=Inches(width))
else:
add_picture_to_table(target_doc, target_filename, i, j, get_full_picture_url(cell_text))
continue
if str(cell_text) == "": continue
print(f"在[{i},{j}]处写入{str(cell_text)}")
print(f"在的[{i},{j}]处写入{str(cell_text)}")
target_doc.tables[table_num].cell(i,j).text = str(cell_text)
print(key_words, cell_text)
if key_words and key_words.search(str(cell_text)):
print(f'{cell_text}包含关键之,已置红')
print(f'{cell_text}包含关键,已置红')
target_doc.tables[table_num].cell(i,j).paragraphs[0].runs[0].font.color.rgb = RGBColor(255, 0, 0)
target_doc.tables[table_num].cell(i,j).paragraphs[0].runs[0].font.name = "Times New Roman" #设置英文字体
target_doc.tables[table_num].cell(i,j).paragraphs[0].runs[0].font.size = Pt(10.5) # 字体大小
target_doc.tables[table_num].cell(i,j).paragraphs[0].runs[0]._element.rPr.rFonts.set(qn('w:eastAsia'), '仿宋') #设置中文字体
target_doc.tables[table_num].cell(i,j).paragraphs[0].runs[0].font.size = Pt(9) # 字体大小
target_doc.tables[table_num].cell(i,j).paragraphs[0].runs[0]._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体') #设置中文字体
if ALIGMENT == 'CENTER':
target_doc.tables[table_num].cell(i,j).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
elif ALIGMENT == 'LEFT':
target_doc.tables[table_num].cell(i,j).paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.LEFT
target_doc.tables[table_num].cell(i,j).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
if ifadjustheight:
target_doc.tables[table_num].rows[i].height = Cm(height)
except Exception as e:
print(f"写入{target_filename}tables.cell({i},{j})失败:{str(e)}")
print("表格写入完成")
return target_doc
@ -290,7 +314,7 @@ def set_document_para(target_doc: Document) -> Document:
return target_doc
def add_table_to_document(target_filename: str, source_filename: str, rows: int, cols: int, table_num: int, data: Optional[List[List[str]]] = None, ifadjustheight: Optional[bool] = True, height: Optional[float] = 1, key_words: re.Pattern[str] = None, ALIGMENT: Optional[str] = 'CENTER', if_merge : Optional[bool] = True, Report_Enum = 'DT', if_para : Optional[bool] = True) -> str:
def add_table_to_document(target_filename: str, source_filename: str, rows: int, cols: int, table_num: int, data: Optional[List[List[str]]] = None, ifadjustheight: Optional[bool] = True, height: Optional[float] = None, key_words: re.Pattern[str] = None, ALIGMENT: Optional[str] = 'CENTER', if_merge : Optional[bool] = True, Report_Enum = 'DT', if_para : Optional[bool] = True, width : Optional[float] = None) -> str:
"""复制源文件中的文字与表格(先文字后表格格式)到目标文档
Args:
target_filename: 目标文档路径
@ -358,10 +382,11 @@ def add_table_to_document(target_filename: str, source_filename: str, rows: int,
copy_table(source_doc.tables[0], target_doc, ifadjustheight, height, if_merge, REPORT_ENUM=Report_Enum)
except Exception as e:
print(f"添加表格失败:{str(e)}")
target_doc.save(target_filename)
print(f"{target_doc}写入表格{source_doc.tables[0]}成功")
if data:
try:
target_doc = write_table(target_filename, rows, cols, table_num, data, ifadjustheight, height, key_words, ALIGMENT)
target_doc = write_table(target_filename, rows, cols, table_num, data, ifadjustheight, height, key_words, ALIGMENT, width)
except Exception as e:
print(f"{target_filename}写入{data}失败:{str(e)}")
target_doc.save(target_filename)
@ -617,7 +642,7 @@ async def add_dynamic_table(output_doc, output_dir, table_num, TABLES, JIANCHA_X
try:
print(f"添加 {picturedir} {type(picturedir)}到表格{table_idx}")
resize_and_reduce_quality(picturedir, picturedir)
await add_picture_to_table(output_doc, output_dir, 4, 0, picturedir, i, 4.7232)
add_picture_to_table(output_doc, output_dir, 4, 0, picturedir, i, 4.7232)
except Exception as e:
print(f"添加图片失败:{e}")
@ -672,7 +697,7 @@ async def process_images_table(data_dict, output_dir, start_i, JIANCHA_NEIRONG_P
if picture_index < picture_num:
pic_path = items[picture_index][1] # 图片路径
print(f"当前为图片表格,在(0,{k})位置插入图片: {pic_path}")
print(await add_picture_to_table(output_doc, output_dir, 0, k, pic_path, i, 1.8898))
print(add_picture_to_table(output_doc, output_dir, 0, k, pic_path, i, 1.8898))
picture_index += 1
i += 1
print(message)
@ -747,7 +772,7 @@ async def process_server_images_table(data_list, image_source_list, output_dir,
if picture_index < picture_num:
pic_path = items[picture_index][1] # 图片路径
print(f"当前为图片表格,在(0,{k})位置插入图片: {pic_path}")
print(await add_picture_to_table(output_doc, output_dir, 0, k, get_full_picture_url(pic_path), i, 1.8898))
print(add_picture_to_table(output_doc, output_dir, 0, k, get_full_picture_url(pic_path), i, 1.8898))
picture_index += 1
i += 1
print(message)
@ -989,3 +1014,125 @@ def add_auto_toc_at_end(doc_path):
}
doc.render(context)
doc.save(doc_path)
def add_jf_picture_table(
typical_picture_list: list,
defect_picture_list: list,
TYPICAL_MUBAN_DIR: str,
DEFECT_MUBAN_DIR: str,
output_dir: str,
total_table_num: int,
):
"""添加金风版本的图片展示表格
Args:
typical_picture_list: 每列有两种情况
[
[str(图片描述), str(图片描述), ...],
[str(图片地址), int(n), ...],
[str(""), str(缺陷类型), ...]
]
defect_picture_list: 只有一种情况
[
[str(图片描述), str(图片描述), ...],
[str(图片地址), str(图片地址), ...]
]
TYPICAL_MUBAN_DIR: 典型图模板路径
DEFECT_MUBAN_DIR: 缺陷图模板路径
"""
def add_table(table_type, data, rows, cols):
nonlocal total_table_num
template = TYPICAL_MUBAN_DIR if table_type == "typical" else DEFECT_MUBAN_DIR
key_words = re.compile(r'损伤|处') if table_type == "typical" else re.compile(r'损伤')
print(f"添加{table_type}表格:{data}")
add_table_to_document(
output_dir,
template,
rows, cols, total_table_num,
data,
Report_Enum='JF',
if_merge=False,
height=1.4173,
width=1.8898,
if_para=False,
key_words=key_words
)
total_table_num += 1
return list(list("" for _ in range(5)) for _ in range(rows)) # 返回新表格
print(f"获得典型图列表:{typical_picture_list}")
print(f"获得缺陷图列表:{defect_picture_list}")
# 初始化表格
typical_table = [[""] * 5 for _ in range(3)] # 三行五列
defect_table = [[""] * 5 for _ in range(2)] # 二行五列
typical_col_idx = 0
defect_count = 0 # 需要添加的缺陷图数量
pending_defects = False
# 处理典型图
while all(typical_picture_list) and all(len(lst) > 0 for lst in typical_picture_list):
desc = typical_picture_list[0].pop(0)
content = typical_picture_list[1].pop(0)
defect_type = typical_picture_list[2].pop(0)
# 检查是否需要新建表格
if typical_col_idx >= 5:
typical_table = add_table("typical", typical_table, 3, 5)
typical_col_idx = 0
# 如果有待处理的缺陷图,先处理
if pending_defects:
defect_col_idx = 0
while defect_picture_list[0] and defect_picture_list[1] and defect_count > 0:
if defect_col_idx >= 5:
defect_table = add_table("defect", defect_table, 2, 5)
defect_col_idx = 0
defect_table[0][defect_col_idx] = defect_picture_list[0].pop(0)
defect_table[1][defect_col_idx] = defect_picture_list[1].pop(0)
defect_col_idx += 1
defect_count -= 1
if defect_col_idx > 0:
defect_table = add_table("defect", defect_table, 2, 5)
pending_defects = False
# 填充典型图表
if isinstance(content, int):
typical_table[0][typical_col_idx] = desc
typical_table[1][typical_col_idx] = f"损伤有{content}处,详见下表"
typical_table[2][typical_col_idx] = f"{defect_type}{content}"
defect_count += content
pending_defects = True
else:
typical_table[0][typical_col_idx] = desc
typical_table[1][typical_col_idx] = content
typical_col_idx += 1
# 添加剩余的典型图表
if typical_col_idx > 0:
add_table("typical", typical_table, 3, 5)
# 处理剩余的缺陷图
if pending_defects and defect_picture_list[0] and defect_picture_list[1]:
defect_col_idx = 0
while defect_picture_list[0] and defect_picture_list[1] and defect_count > 0:
if defect_col_idx >= 5:
defect_table = add_table("defect", defect_table, 2, 5)
defect_col_idx = 0
defect_table[0][defect_col_idx] = defect_picture_list[0].pop(0)
defect_table[1][defect_col_idx] = defect_picture_list[1].pop(0)
defect_col_idx += 1
defect_count -= 1
if defect_col_idx > 0:
add_table("defect", defect_table, 2, 5)
return total_table_num

View File

@ -91,7 +91,7 @@ async def process_images_table(data_dict, output_dir, start_i, JIANCHA_NEIRONG_P
if picture_index < picture_num:
pic_path = items[picture_index][1] # 图片路径
print(f"当前为图片表格,在(0,{k})位置插入图片: {pic_path}")
print(await add_picture_to_table(output_doc, output_dir, 0, k, pic_path, i, 1.8898))
print(add_picture_to_table(output_doc, output_dir, 0, k, pic_path, i, 1.8898))
picture_index += 1
i += 1
print(message)
@ -128,7 +128,7 @@ async def add_dynamic_table(output_doc, output_dir, table_num, TABLES, JIANCHA_X
try:
print(f"添加 {picturedir} {type(picturedir)}到表格{table_idx}")
resize_and_reduce_quality(picturedir, picturedir)
await add_picture_to_table(output_doc, output_dir, 4, 0, picturedir, i, 4.7232)
add_picture_to_table(output_doc, output_dir, 4, 0, picturedir, i, 4.7232)
except Exception as e:
print(f"添加图片失败:{e}")