完成标题分级样式配置,添加横向页面,设计添加金风图片表格的函数。更改某些函数的样式获取等。
This commit is contained in:
parent
8402a2cb7f
commit
78ab1e3962
|
@ -31,7 +31,7 @@ def main():
|
|||
elif merged['json2']['choose_template'] == 'JF':
|
||||
asyncio.run(generate_jf_report(merged['json1'], merged['json2']))
|
||||
else:
|
||||
print('指定了不存在的,请检查配置文件')
|
||||
print('指定了不存在的模板,请检查配置文件')
|
||||
print('文档生成完毕')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
72
Jf_report.py
72
Jf_report.py
|
@ -1,15 +1,15 @@
|
|||
# 文档处理工具
|
||||
from tools.document_tools import (
|
||||
create_document, add_documents,add_table_and_replace,
|
||||
add_table_to_document,add_dynamic_table,
|
||||
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
|
||||
merge_documents,add_table,add_defect_info_table,add_table_title,
|
||||
add_title,change_heading,add_auto_toc_at_end
|
||||
)
|
||||
|
||||
# 内容处理工具
|
||||
from tools.content_tools import (
|
||||
add_picture,split_table_by_row_content,
|
||||
search_and_replace
|
||||
search_and_replace,add_heading
|
||||
)
|
||||
|
||||
from tools.get_pictures import (
|
||||
|
@ -146,6 +146,7 @@ async def generate_jf_report(base_info, baogao_info):
|
|||
neirong2 = []
|
||||
use_tool_table = []
|
||||
table_index = 1
|
||||
typical_picture_description = []
|
||||
#获取对应枚举字段
|
||||
if if_waibu:
|
||||
baogao_label.append("外观")
|
||||
|
@ -166,6 +167,7 @@ async def generate_jf_report(base_info, baogao_info):
|
|||
jiancha.append("无人机外观检查")
|
||||
neirong.append(f"、".join(Y_Code) + f"共{len(Y_Code)}支叶片的前缘、后缘、迎风面、背风面。")
|
||||
neirong2.append("前缘、后缘、迎风面、背风面。")
|
||||
typical_picture_description.extend(TEMPLATE_HEADER.JINFENG_HEADER.WAIBU.TYPICAL_LIST)
|
||||
if if_neibu:
|
||||
baogao_label.append("内部")
|
||||
image_source_to_find.append(baogao_info['neibu_enum'])
|
||||
|
@ -184,6 +186,7 @@ async def generate_jf_report(base_info, baogao_info):
|
|||
jiancha.append("叶片内部检查")
|
||||
neirong.append(f"、".join(Y_Code) + f"共{len(Y_Code)}支叶片的内部导雷卡、腹板、透光、人孔盖版、叶根盖板...")
|
||||
neirong2.append("内部导雷卡、腹板、透光、人孔盖版、叶根盖板...")
|
||||
typical_picture_description.extend(TEMPLATE_HEADER.JINFENG_HEADER.NEIBU.TYPICAL_LIST)
|
||||
if if_fanglei:
|
||||
baogao_label.append("防雷")
|
||||
image_source_to_find.append(baogao_info['fanglei_enum'])
|
||||
|
@ -202,6 +205,7 @@ async def generate_jf_report(base_info, baogao_info):
|
|||
jiancha.append("叶片导通测试")
|
||||
neirong.append(f"轮毂至塔基导通、内部导线线阻、外部导线线阻...")
|
||||
neirong2.append("轮毂至塔基导通、内部导线线阻、外部导线线阻...")
|
||||
typical_picture_description.extend(TEMPLATE_HEADER.JINFENG_HEADER.FANGLEI.TYPICAL_LIST)
|
||||
|
||||
#获取缺陷图列表和典型图列表
|
||||
filtered_picture_data, total_picture_num = process_picture_data(picture_data, image_source_to_find)
|
||||
|
@ -224,6 +228,7 @@ async def generate_jf_report(base_info, baogao_info):
|
|||
print(f"生成路径{shengcheng_dir}不存在")
|
||||
return
|
||||
|
||||
|
||||
baogao_name = "叶片" + "、".join(baogao_label) + "检查报告"
|
||||
output_dir = os.path.normpath(f"{shengcheng_dir}/{project_name}项目{baogao_name}{jizu_bianhao}{baogao_date.split(' ')[0]}版.docx")
|
||||
|
||||
|
@ -254,6 +259,10 @@ async def generate_jf_report(base_info, baogao_info):
|
|||
"top_margin" : JF_T_MARGIN,
|
||||
"bottom_margin" : JF_B_MARGIN,
|
||||
}))
|
||||
#标题样式
|
||||
change_heading(output_dir, "Heading 1")
|
||||
change_heading(output_dir, "Heading 2", HEADING_2_CONFIG)
|
||||
change_heading(output_dir, "Heading 3", HEADING_3_CONFIG)
|
||||
#加封面
|
||||
merge_documents(output_dir, add_list)
|
||||
#页眉
|
||||
|
@ -299,14 +308,55 @@ async def generate_jf_report(base_info, baogao_info):
|
|||
#缺陷信息表格2
|
||||
|
||||
|
||||
table_list = tree_dict_to_table_data(defect_part_type_list)
|
||||
table_list = defect_list_addtitle(table_list, jizu_bianhao)
|
||||
print(table_list)
|
||||
add_table_title(output_dir, DEFECT_TABLE_TITLE)
|
||||
table_json = list_to_json_with_merges(table_list, style_config=STYLE_CONFIG, merge_columns=2)
|
||||
json_to_docx(table_json, output_dir).save(output_dir)
|
||||
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) # 增加表格标题
|
||||
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
|
||||
|
||||
#使用器具记录表
|
||||
add_table_title(output_dir, USE_TOOL_TABLE_TITLE)
|
||||
print(use_tool_table)
|
||||
json_to_docx(list_to_json_with_merges(use_tool_table, style_config=STYLE_CONFIG, detect_merges=False),output_dir).save(output_dir)
|
||||
|
||||
#添加目录节
|
||||
add_section(output_dir).save(output_dir)
|
||||
|
||||
#添加目录
|
||||
#add_auto_toc_at_end(output_dir)
|
||||
|
||||
#添加横向节(展示图片)
|
||||
add_landscape_section(output_dir).save(output_dir)
|
||||
|
||||
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 = []
|
||||
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 = {}
|
||||
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -116,6 +116,21 @@ def copy_table(source_table, target_doc, ifadjustheight=True, height = 1, if_mer
|
|||
"""
|
||||
# Create a new table with the same dimensions
|
||||
new_table = target_doc.add_table(rows=len(source_table.rows), cols=len(source_table.columns))
|
||||
# 获取表格属性
|
||||
tbl_pr = new_table._tbl.tblPr
|
||||
|
||||
# 设置表格边框
|
||||
tbl_borders = OxmlElement('w:tblBorders')
|
||||
for border_name in ('top', 'left', 'bottom', 'right', 'insideH', 'insideV'):
|
||||
border = OxmlElement(f'w:{border_name}')
|
||||
border.set(qn('w:val'), 'single') # 边框类型
|
||||
border.set(qn('w:sz'), '4') # 边框粗细(1-96,8代表1磅)
|
||||
border.set(qn('w:space'), '0') # 边框间距
|
||||
border.set(qn('w:color'), 'auto') # 边框颜色
|
||||
tbl_borders.append(border)
|
||||
|
||||
tbl_pr.append(tbl_borders)
|
||||
|
||||
# Try to apply the same style
|
||||
try:
|
||||
if source_table.style:
|
||||
|
@ -145,7 +160,7 @@ def copy_table(source_table, target_doc, ifadjustheight=True, height = 1, if_mer
|
|||
#new_table.cell(i,j).width = cell.width
|
||||
if REPORT_ENUM == 'JF':
|
||||
new_table.cell(i,j).paragraphs[0].runs[0]._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体') #设置中文字体
|
||||
new_table.cell(i,j).paragraphs[0].runs[0].font.size = Pt(12) # 字体大小
|
||||
new_table.cell(i,j).paragraphs[0].runs[0].font.size = Pt(8) # 字体大小
|
||||
"""
|
||||
待添加:如何让表格自适应大小(autofit目前不知为何没有作用)
|
||||
"""
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,117 @@
|
|||
from typing import Dict
|
||||
import os
|
||||
from docx import Document
|
||||
from tools.document_tools import add_picture_to_table, add_table_to_document
|
||||
def add_jf_picture_table(
|
||||
typical_picture_dict: Dict[str, str],
|
||||
defect_picture_dict: Dict[str, str],
|
||||
TYPICAL_MUBAN_DIR: str,
|
||||
DEFECT_MUBAN_DIR: str,
|
||||
output_dir: str,
|
||||
):
|
||||
"""添加金风版本的图片展示表格"""
|
||||
# 初始化文档对象
|
||||
doc = Document()
|
||||
target_filename = os.path.join(output_dir, "output.docx")
|
||||
|
||||
# 处理典型图
|
||||
typical_data = []
|
||||
defect_keys = [] # 记录有缺陷的典型图key
|
||||
|
||||
# 准备典型图数据
|
||||
for key, value in typical_picture_dict.items():
|
||||
if "损伤" in key or "损伤" in value:
|
||||
# 情况二:有缺陷
|
||||
defect_count = int(value.split("损伤类型")[1].split("处")[0])
|
||||
typical_data.append([key, "损伤{}处,详见下表".format(defect_count), value])
|
||||
defect_keys.append((key, defect_count))
|
||||
else:
|
||||
# 情况一:正常图片
|
||||
typical_data.append([key, value, ""]) # 第三行留空
|
||||
|
||||
# 添加典型图表格
|
||||
if typical_data:
|
||||
# 将数据转换为适合表格的格式(3行×n列)
|
||||
# 需要将数据从行优先转为列优先
|
||||
cols = len(typical_data)
|
||||
table_data = [[], [], []]
|
||||
for col_data in typical_data:
|
||||
for i in range(3):
|
||||
table_data[i].append(col_data[i] if i < len(col_data) else "")
|
||||
|
||||
# 添加典型图表格
|
||||
add_table_to_document(
|
||||
target_filename=target_filename,
|
||||
source_filename=TYPICAL_MUBAN_DIR,
|
||||
rows=3,
|
||||
cols=cols,
|
||||
table_num=0,
|
||||
data=table_data
|
||||
)
|
||||
|
||||
# 添加典型图中的图片
|
||||
doc = Document(target_filename)
|
||||
for col_idx, (key, value) in enumerate(typical_picture_dict.items()):
|
||||
if "损伤" not in key and "损伤" not in value: # 只有正常图片才添加
|
||||
add_picture_to_table(
|
||||
target_doc=doc,
|
||||
target_filename=target_filename,
|
||||
row=1, # 第二行是图片
|
||||
col=col_idx,
|
||||
image_path=value
|
||||
)
|
||||
doc.save(target_filename)
|
||||
|
||||
# 处理缺陷图
|
||||
if defect_keys:
|
||||
# 遍历所有有缺陷的典型图
|
||||
for typical_key, defect_count in defect_keys:
|
||||
# 计算需要多少个缺陷图表格(每表5列)
|
||||
table_count = (defect_count + 4) // 5 # 向上取整
|
||||
|
||||
for table_idx in range(table_count):
|
||||
# 计算当前表格的列数
|
||||
cols_in_table = min(5, defect_count - table_idx * 5)
|
||||
|
||||
# 准备缺陷图数据
|
||||
defect_data = []
|
||||
for i in range(cols_in_table):
|
||||
defect_idx = table_idx * 5 + i
|
||||
defect_key = list(defect_picture_dict.keys())[defect_idx]
|
||||
defect_value = list(defect_picture_dict.values())[defect_idx]
|
||||
defect_data.append([defect_key, defect_value])
|
||||
|
||||
# 将数据转换为适合表格的格式(2行×n列)
|
||||
table_data = [[], []]
|
||||
for col_data in defect_data:
|
||||
for i in range(2):
|
||||
table_data[i].append(col_data[i] if i < len(col_data) else "")
|
||||
|
||||
# 添加缺陷图表格
|
||||
add_table_to_document(
|
||||
target_filename=target_filename,
|
||||
source_filename=DEFECT_MUBAN_DIR,
|
||||
rows=2,
|
||||
cols=cols_in_table,
|
||||
table_num=0,
|
||||
data=table_data
|
||||
)
|
||||
|
||||
# 添加缺陷图中的图片
|
||||
doc = Document(target_filename)
|
||||
for col_idx in range(cols_in_table):
|
||||
defect_idx = table_idx * 5 + col_idx
|
||||
defect_value = list(defect_picture_dict.values())[defect_idx]
|
||||
add_picture_to_table(
|
||||
target_doc=doc,
|
||||
target_filename=target_filename,
|
||||
row=1, # 第二行是图片
|
||||
col=col_idx,
|
||||
image_path=defect_value
|
||||
)
|
||||
doc.save(target_filename)
|
||||
|
||||
return target_filename
|
||||
|
||||
|
||||
add_jf_picture_table({""})
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -138,7 +138,7 @@ def split_table_by_row_content(
|
|||
return f"处理表格时出错: {str(e)}"
|
||||
|
||||
|
||||
async def add_heading(filename: str, text: str, level: int = 1) -> str:
|
||||
def add_heading(filename: str, text: str, level: int = 1) -> str:
|
||||
"""对文档增加标题
|
||||
|
||||
Args:
|
||||
|
@ -179,10 +179,10 @@ async def add_heading(filename: str, text: str, level: int = 1) -> str:
|
|||
doc.save(filename)
|
||||
return f"Heading '{text}' (level {level}) added to {filename}"
|
||||
except Exception as style_error:
|
||||
print("style-based approach fails, use direct formatting")
|
||||
# If style-based approach fails, use direct formatting
|
||||
paragraph = doc.add_paragraph(text)
|
||||
paragraph.style = doc.styles['Normal']
|
||||
run = paragraph.runs[0]
|
||||
paragraph = doc.add_paragraph()
|
||||
run = paragraph.add_run(text)
|
||||
run.bold = True
|
||||
rPr = run.element.get_or_add_rPr()
|
||||
rFonts = rPr.get_or_add_rFonts()
|
||||
|
@ -657,3 +657,38 @@ def search_and_replace(filename: str, find_text: str, replace_text: str) -> str:
|
|||
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: 缺陷图模板路径
|
||||
"""
|
|
@ -67,6 +67,28 @@ class TEMPLATE_HEADER:
|
|||
QN = qn('w:eastAsia')
|
||||
FONT = 'Arial'
|
||||
PT = Pt(9)
|
||||
class FANGLEI:
|
||||
TYPICAL_LIST = [
|
||||
"防雷导通测试\n叶尖至塔基测试阻值({Resistance} mΩ)",
|
||||
"防雷导通测试\n叶尖与无人吊篮平台接触良好",
|
||||
"防雷导通测试\n叶尖至塔基检测导线线组值"
|
||||
]
|
||||
class WAIBU:
|
||||
TYPICAL_LIST = [
|
||||
"外观检查(迎、背风面是否有漆面脱落、裂纹等)",
|
||||
"外观检查(前、后缘;如前缘漆面脱落、合模缝开裂等)",
|
||||
"叶片防雨环检查",
|
||||
"叶尖接闪器、排水孔检查,如接闪器损伤、雷击熔融;流水孔堵塞",
|
||||
]
|
||||
class NEIBU:
|
||||
TYPICAL_LIST = [
|
||||
"叶片铭牌",
|
||||
"根部检查(挡板、盖板检查是否损坏、金属件是否丢失等)",
|
||||
"避雷系统检查(避雷线是否断裂、雷电记录卡是否缺失等)",
|
||||
"前后缘检查(前缘粘接及补强是否有开裂、裂纹)",
|
||||
"上下蒙皮检查(蒙皮是否有褶皱、发白、折痕、分层、裂纹等)",
|
||||
"腹板检查(腹板是否变形、偏移,腹板粘接是否开裂、裂纹等)",
|
||||
]
|
||||
|
||||
class DT_HEADER:
|
||||
ENUM = 'DT'
|
||||
|
@ -92,7 +114,7 @@ STYLE_CONFIG = {
|
|||
"alignment": "center",
|
||||
"font": {
|
||||
"name": "宋体",
|
||||
"size": 12,
|
||||
"size": 8,
|
||||
"bold": False,
|
||||
},
|
||||
"border": {
|
||||
|
@ -109,7 +131,7 @@ TITLE_STYLE_CONFIG = {
|
|||
"alignment": "center",
|
||||
"font": {
|
||||
"name": "宋体",
|
||||
"size": 12,
|
||||
"size": 9,
|
||||
"bold": False,
|
||||
},
|
||||
"border": {
|
||||
|
@ -122,6 +144,8 @@ TITLE_STYLE_CONFIG = {
|
|||
"color": "FFFFFF"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEFECT_TABLE_TITLE = '叶片故障信息表'
|
||||
DEFECT_TABLE = ['机组号', '叶片编号', '损伤名称', '损坏描述', '面积/S', '备注']
|
||||
|
||||
|
@ -148,3 +172,64 @@ class USE_TOOL_ENUM:
|
|||
["手机", "/", "2", "拍照记录"],
|
||||
["叶片内部爬壁机器人", "DT02", "1", "拍照记录"]
|
||||
]
|
||||
|
||||
from enum import Enum
|
||||
from docx.shared import RGBColor
|
||||
class DocxColors(Enum):
|
||||
"""常用颜色枚举"""
|
||||
BLACK = RGBColor(0, 0, 0)
|
||||
WHITE = RGBColor(255, 255, 255)
|
||||
RED = RGBColor(255, 0, 0)
|
||||
GREEN = RGBColor(0, 255, 0)
|
||||
BLUE = RGBColor(0, 0, 255)
|
||||
YELLOW = RGBColor(255, 255, 0)
|
||||
PURPLE = RGBColor(128, 0, 128)
|
||||
ORANGE = RGBColor(255, 165, 0)
|
||||
GRAY = RGBColor(128, 128, 128)
|
||||
DARK_RED = RGBColor(139, 0, 0)
|
||||
DARK_GREEN = RGBColor(0, 100, 0)
|
||||
DARK_BLUE = RGBColor(0, 0, 139)
|
||||
LIGHT_BLUE = RGBColor(173, 216, 230)
|
||||
PINK = RGBColor(255, 192, 203)
|
||||
BROWN = RGBColor(165, 42, 42)
|
||||
|
||||
# 微软Office常用颜色
|
||||
MS_BLUE = RGBColor(46, 116, 181)
|
||||
MS_ORANGE = RGBColor(247, 150, 70)
|
||||
MS_GREEN = RGBColor(80, 175, 74)
|
||||
MS_RED = RGBColor(217, 83, 79)
|
||||
MS_GRAY = RGBColor(166, 166, 166)
|
||||
|
||||
# 获取颜色值
|
||||
@property
|
||||
def rgb(self):
|
||||
return self.value
|
||||
|
||||
HEADING_1_CONFIG = {
|
||||
"alignment": "left",
|
||||
"font" : {
|
||||
"name" : "宋体",
|
||||
"size" : Pt(11),
|
||||
"bold" : True,
|
||||
"color" : DocxColors.BLACK.rgb
|
||||
},
|
||||
}
|
||||
|
||||
HEADING_2_CONFIG = {
|
||||
"alignment": "left",
|
||||
"font" : {
|
||||
"name" : "宋体",
|
||||
"size" : Pt(10),
|
||||
"bold" : True,
|
||||
"color" : DocxColors.BLACK.rgb
|
||||
},
|
||||
}
|
||||
HEADING_3_CONFIG = {
|
||||
"alignment": "left",
|
||||
"font" : {
|
||||
"name" : "宋体",
|
||||
"size" : Pt(9),
|
||||
"bold" : True,
|
||||
"color" : DocxColors.BLACK.rgb
|
||||
},
|
||||
}
|
||||
|
|
|
@ -219,6 +219,7 @@ def write_table(target_filename: str, rows: int, cols: int, table_num: int, data
|
|||
data: 表格数据,二维列表,每个单元格为字符串
|
||||
ifadjustheight: bool,为真则表格行高自动调整
|
||||
"""
|
||||
table_num = -1
|
||||
target_filename = ensure_docx_extension(target_filename)
|
||||
# Check if target file is writeable
|
||||
is_writeable, error_message = check_file_writeable(target_filename)
|
||||
|
@ -289,7 +290,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') -> 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] = 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:
|
||||
"""复制源文件中的文字与表格(先文字后表格格式)到目标文档
|
||||
Args:
|
||||
target_filename: 目标文档路径
|
||||
|
@ -305,62 +306,59 @@ def add_table_to_document(target_filename: str, source_filename: str, rows: int,
|
|||
source_filename = ensure_docx_extension(source_filename)
|
||||
source_doc = Document(source_filename)
|
||||
target_doc = Document(target_filename)
|
||||
target_doc.add_paragraph()
|
||||
try:
|
||||
# Copy all paragraphs
|
||||
for paragraph in source_doc.paragraphs:
|
||||
# Create a new paragraph with the same text and style
|
||||
new_paragraph = target_doc.add_paragraph(paragraph.text)
|
||||
if if_para:
|
||||
try:
|
||||
# Copy all paragraphs
|
||||
for paragraph in source_doc.paragraphs:
|
||||
# Create a new paragraph with the same text and style
|
||||
new_paragraph = target_doc.add_paragraph(paragraph.text)
|
||||
|
||||
new_paragraph.style = target_doc.styles['Normal'] # Default style
|
||||
#获取合并等样式2025427
|
||||
new_paragraph.alignment = paragraph.alignment
|
||||
new_paragraph.style = target_doc.styles['Normal'] # Default style
|
||||
#获取合并等样式2025427
|
||||
new_paragraph.alignment = paragraph.alignment
|
||||
|
||||
# 复制段落分页属性
|
||||
new_paragraph.paragraph_format.page_break_before = paragraph.paragraph_format.page_break_before
|
||||
# Try to match the style if possible
|
||||
try:
|
||||
if paragraph.style and paragraph.style.name in target_doc.styles:
|
||||
new_paragraph.style = target_doc.styles[paragraph.style.name]
|
||||
except:
|
||||
pass
|
||||
# 复制段落分页属性
|
||||
new_paragraph.paragraph_format.page_break_before = paragraph.paragraph_format.page_break_before
|
||||
# Try to match the style if possible
|
||||
try:
|
||||
if paragraph.style and paragraph.style.name in target_doc.styles:
|
||||
new_paragraph.style = target_doc.styles[paragraph.style.name]
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# Copy run formatting
|
||||
for i, run in enumerate(paragraph.runs):
|
||||
if i < len(new_paragraph.runs):
|
||||
new_run = new_paragraph.runs[i]
|
||||
# Copy basic formatting
|
||||
new_run.bold = run.bold
|
||||
new_run.italic = run.italic
|
||||
new_run.underline = run.underline
|
||||
#添加同时合并字体2025427
|
||||
new_run.font.name = run.font.name
|
||||
rPr = new_run.element.get_or_add_rPr()
|
||||
rFonts = rPr.get_or_add_rFonts()
|
||||
# 检查 run.font.name 是否为 None
|
||||
if run.font.name is None:
|
||||
# 设置默认的中文字体名称
|
||||
run.font.name = '宋体(中文正文)' # 或者使用其他你喜欢的中文字体
|
||||
rFonts.set(qn('w:eastAsia'), run.font.name)
|
||||
new_run.font.color.rgb = run.font.color.rgb
|
||||
# Copy run formatting
|
||||
for i, run in enumerate(paragraph.runs):
|
||||
if i < len(new_paragraph.runs):
|
||||
new_run = new_paragraph.runs[i]
|
||||
# Copy basic formatting
|
||||
new_run.bold = run.bold
|
||||
new_run.italic = run.italic
|
||||
new_run.underline = run.underline
|
||||
#添加同时合并字体2025427
|
||||
new_run.font.name = run.font.name
|
||||
rPr = new_run.element.get_or_add_rPr()
|
||||
rFonts = rPr.get_or_add_rFonts()
|
||||
# 检查 run.font.name 是否为 None
|
||||
if run.font.name is None:
|
||||
# 设置默认的中文字体名称
|
||||
run.font.name = '宋体(中文正文)' # 或者使用其他你喜欢的中文字体
|
||||
rFonts.set(qn('w:eastAsia'), run.font.name)
|
||||
new_run.font.color.rgb = run.font.color.rgb
|
||||
|
||||
|
||||
# Font size if specified
|
||||
if run.font.size:
|
||||
new_run.font.size = run.font.size
|
||||
# Font size if specified
|
||||
if run.font.size:
|
||||
new_run.font.size = run.font.size
|
||||
|
||||
except Exception as e:
|
||||
print(f"添加表格前文章失败:{str(e)}")
|
||||
except Exception as e:
|
||||
print(f"添加表格前文章失败:{str(e)}")
|
||||
|
||||
try:# Copy all tables
|
||||
copy_table(source_doc.tables[0], target_doc, ifadjustheight, height)
|
||||
copy_table(source_doc.tables[0], target_doc, ifadjustheight, height, if_merge, REPORT_ENUM=Report_Enum)
|
||||
except Exception as e:
|
||||
print(f"添加表格失败:{str(e)}")
|
||||
print(f"{target_doc}写入表格{source_doc.tables[0]}成功")
|
||||
target_doc = set_document_para(target_doc)
|
||||
target_doc.save(target_filename)
|
||||
target_doc = Document(target_filename)
|
||||
if data:
|
||||
try:
|
||||
target_doc = write_table(target_filename, rows, cols, table_num, data, ifadjustheight, height, key_words, ALIGMENT)
|
||||
|
@ -755,7 +753,7 @@ async def process_server_images_table(data_list, image_source_list, output_dir,
|
|||
print(message)
|
||||
return i # 返回最后使用的表格序号
|
||||
|
||||
def add_header(target_dir : str, report_enum : str, if_clear_header : Optional[bool] = True):
|
||||
def add_header(target_dir : str, report_enum : str, if_clear_header : Optional[bool] = True, if_section : Optional[bool] = True, text : str = None):
|
||||
"""添加页眉,添加封面后调用此函数,会分离页面和后续页面的节。
|
||||
|
||||
Args:
|
||||
|
@ -770,35 +768,43 @@ def add_header(target_dir : str, report_enum : str, if_clear_header : Optional[b
|
|||
for section in document.sections: # 遍历所有节的页眉
|
||||
clear_header(section) # 清除页眉的段落
|
||||
|
||||
print(f"文档节数:{len(document.sections)},开始往当前节后添加页眉")
|
||||
document.sections[0].header.is_linked_to_previous = False # 取消页眉与上一页关联
|
||||
if if_section:
|
||||
print(f"文档节数:{len(document.sections)},开始往当前节后添加页眉")
|
||||
document.sections[0].header.is_linked_to_previous = False # 取消页眉与上一页关联
|
||||
|
||||
document.add_section(WD_SECTION.NEW_PAGE)
|
||||
header = document.sections[1].header
|
||||
document.add_section(WD_SECTION.NEW_PAGE)
|
||||
header = document.sections[1].header
|
||||
|
||||
header.is_linked_to_previous = False # 取消页眉与上一页关联
|
||||
header.is_linked_to_previous = False # 取消页眉与上一页关联
|
||||
else:
|
||||
header = document.sections[-1].header
|
||||
header.is_linked_to_previous = False # 取消页眉与上一页关联
|
||||
paragraph = header.paragraphs[0] # 获取页眉的第一个段落
|
||||
run = paragraph.add_run()
|
||||
|
||||
if report_enum == 'JF':
|
||||
print("添加金风模板的页眉")
|
||||
pic = run.add_picture(get_template_pic(TEMPLATE_HEADER.JINFENG_HEADER.PIC_DIR))
|
||||
run = paragraph.add_run(TEMPLATE_HEADER.JINFENG_HEADER.PARA)
|
||||
if text:
|
||||
run = paragraph.add_run(text)
|
||||
else:
|
||||
run = paragraph.add_run(TEMPLATE_HEADER.JINFENG_HEADER.PARA)
|
||||
run.font.name = TEMPLATE_HEADER.JINFENG_HEADER.FONT
|
||||
run.font.size = TEMPLATE_HEADER.JINFENG_HEADER.PT
|
||||
document.save(target_dir) # 保存文档
|
||||
|
||||
elif report_enum == 'DT':
|
||||
print("添加迪特模板的页眉")
|
||||
pic = run.add_picture(get_template_pic(TEMPLATE_HEADER.DT_HEADER.PIC_DIR))
|
||||
run = paragraph.add_run(TEMPLATE_HEADER.DT_HEADER.PARA)
|
||||
if text:
|
||||
run = paragraph.add_run(text)
|
||||
else:
|
||||
run = paragraph.add_run(TEMPLATE_HEADER.DT_HEADER.PARA)
|
||||
run.font.name = TEMPLATE_HEADER.DT_HEADER.FONT
|
||||
run.font.size = TEMPLATE_HEADER.DT_HEADER.PT
|
||||
document.save(target_dir) # 保存文档
|
||||
|
||||
else:
|
||||
print("未知模板,不添加页眉")
|
||||
# 定义边框的 XML 字符串
|
||||
# 定义边框的 XML 字符串
|
||||
border_xml = """
|
||||
<w:pBdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
|
||||
<w:bottom w:val="single" w:sz="8" w:space="1" w:color="000000"/>
|
||||
|
@ -811,17 +817,37 @@ def add_header(target_dir : str, report_enum : str, if_clear_header : Optional[b
|
|||
pPr.append(pBdr)
|
||||
|
||||
print(f"文档节数:{len(document.sections)}")
|
||||
document.save(target_dir) # 保存文档
|
||||
|
||||
from docx.enum.section import WD_ORIENT
|
||||
from docx.enum.text import WD_BREAK
|
||||
|
||||
from docx.document import Document as Document_
|
||||
def add_landscape_section(target_dir : str):
|
||||
# 添加横向节
|
||||
doc = Document(target_dir)
|
||||
section = doc.add_section()
|
||||
section.orientation = WD_ORIENT.LANDSCAPE
|
||||
section.page_width, section.page_height = section.page_height, section.page_width
|
||||
print(f"文档:{target_dir},添加了新横向节,页宽:{section.page_width}, 页高:{section.page_height}")
|
||||
return doc
|
||||
|
||||
def add_section(target_dir : str) -> Document_:
|
||||
doc = Document(target_dir)
|
||||
section = doc.add_section()
|
||||
return doc
|
||||
|
||||
def add_title(target_dir : str, title : str, style_config : dict = {}):
|
||||
doc = Document(target_dir)
|
||||
para = doc.add_paragraph()
|
||||
run = para.add_run(title)
|
||||
font_config = style_config.get('font', {})
|
||||
run.font.name = font_config.get('name', "宋体")
|
||||
run.element.get_or_add_rPr().get_or_add_rFonts().set(qn('w:eastAsia'), font_config.get('name', "宋体"))
|
||||
run.font.size = font_config.get('size', Pt(14))
|
||||
run.bold = font_config.get('bold', False)
|
||||
para.alignment = style_config.get('alignment', WD_ALIGN_PARAGRAPH.CENTER)
|
||||
print(f"添加新标题:{title},字体:{run.font.name},大小:{run.font.size},是否加粗:{run.bold}")
|
||||
return doc
|
||||
|
||||
def merge_documents(target_dir : str, source_dirs : List[str]):
|
||||
"""合并多个文档、图片
|
||||
|
@ -924,11 +950,42 @@ def add_defect_info_table(output_dir, defect_info, MUBAN_DIR, total_table_num, R
|
|||
return total_table_num
|
||||
|
||||
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
||||
from docx.shared import RGBColor
|
||||
def add_table_title(output_dir, TITLE):
|
||||
doc = Document(output_dir)
|
||||
table = doc.add_table(rows=1, cols=6, style='Table Grid')
|
||||
table.cell(0,0).merge(table.cell(0,5))
|
||||
para = table.cell(0,0).paragraphs[0]
|
||||
para.text = TITLE
|
||||
run = para.add_run(TITLE)
|
||||
run.font.name = "宋体"
|
||||
run.font.size = Pt(9)
|
||||
para.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
print(f"添加了标题表格:{TITLE}")
|
||||
doc.save(output_dir)
|
||||
|
||||
def change_heading(output_dir, style_name, style_config = {}):
|
||||
doc = Document(output_dir)
|
||||
heading_style = doc.styles[style_name]
|
||||
font_config = style_config.get('font', {})
|
||||
heading_style.font.name = font_config.get('name', "宋体")
|
||||
heading_style.element.get_or_add_rPr().get_or_add_rFonts().set(qn('w:eastAsia'), font_config.get('name', "宋体"))
|
||||
heading_style.font.size = font_config.get('size', Pt(11))
|
||||
heading_style.bold = font_config.get('bold', True)
|
||||
heading_style.font.color.rgb = font_config.get('color', DocxColors.BLACK.rgb)
|
||||
print(f"修改了标题样式:{style_name},字体:{heading_style.font.name},大小:{heading_style.font.size},是否加粗:{heading_style.bold}")
|
||||
doc.save(output_dir)
|
||||
|
||||
from docxtpl import DocxTemplate
|
||||
|
||||
def add_auto_toc_at_end(doc_path):
|
||||
"""使用 python-docx-template 在末尾自动生成目录"""
|
||||
doc = DocxTemplate(doc_path)
|
||||
|
||||
# 渲染模板(r.toc=True 会触发目录生成)
|
||||
context = {
|
||||
'r': {
|
||||
'toc': True # 自动生成目录
|
||||
}
|
||||
}
|
||||
doc.render(context)
|
||||
doc.save(doc_path)
|
Loading…
Reference in New Issue