156 lines
6.3 KiB
Python
156 lines
6.3 KiB
Python
|
||
import json
|
||
import os
|
||
import plotly.graph_objects as go
|
||
from plotly.io import write_image, write_html
|
||
from config import styles
|
||
|
||
class PlotlyTableConverter:
|
||
"""使用Plotly将表格数据转换为交互式表格或图片的类"""
|
||
def __init__(self):
|
||
"""初始化表格样式配置"""
|
||
self.table_config = styles.get('table')
|
||
|
||
def load_table_data(self, file_path):
|
||
"""从JSON文件加载表格数据"""
|
||
with open(file_path, 'r', encoding='utf-8') as file:
|
||
data = json.load(file)
|
||
return data.get('tables', [])
|
||
|
||
def create_table(self, table_data, table_index=0):
|
||
"""使用Plotly创建表格"""
|
||
if not table_data:
|
||
return None
|
||
|
||
# 提取表头和表体
|
||
header = table_data[0]
|
||
cells = table_data[1:] if len(table_data) > 1 else []
|
||
|
||
# 配置表格样式
|
||
header_config = self.table_config['header']
|
||
cells_config = self.table_config['cells']
|
||
layout_config = self.table_config['layout']
|
||
border_config = self.table_config['border']
|
||
|
||
# 创建Plotly表格(优化边框和对齐方式)
|
||
table = go.Table(
|
||
header=dict(
|
||
values=header,
|
||
font=dict(
|
||
size=header_config['font_size'],
|
||
color=header_config['font_color'],
|
||
family=header_config['font_family']
|
||
),
|
||
fill_color=header_config['background_color'],
|
||
height=header_config['height'],
|
||
line=dict(width=border_config['width'], color=border_config['color']),
|
||
align=header_config.get('align', 'center')
|
||
),
|
||
cells=dict(
|
||
values=list(zip(*cells)) if cells else [], # 转置数据以匹配Plotly格式
|
||
font=dict(
|
||
size=cells_config['font_size'],
|
||
color=cells_config['font_color'],
|
||
family=cells_config['font_family']
|
||
),
|
||
fill_color=cells_config['background_color'],
|
||
height=cells_config['height'],
|
||
line=dict(width=border_config['width'], color=border_config['color']),
|
||
align=cells_config.get('align', 'left')
|
||
)
|
||
)
|
||
|
||
# 创建布局(优化标题和边距)
|
||
layout = go.Layout(
|
||
width=layout_config['width'],
|
||
height=layout_config['height'],
|
||
margin=dict(
|
||
t=layout_config['margin']['t'],
|
||
b=layout_config['margin']['b'],
|
||
l=layout_config['margin']['l'],
|
||
r=layout_config['margin']['r']
|
||
),
|
||
title=dict(
|
||
text=f'项目评估表格 {table_index+1}',
|
||
font=dict(
|
||
size=layout_config['title']['font']['size'],
|
||
family=layout_config['title']['font'].get('family', 'LXGWWenKai-Medium, SimHei, Arial')
|
||
)
|
||
),
|
||
showlegend=layout_config.get('showlegend', False)
|
||
)
|
||
|
||
# 创建Figure
|
||
fig = go.Figure(data=[table], layout=layout)
|
||
return fig
|
||
|
||
def save_as_html(self, fig, output_path):
|
||
"""保存为交互式HTML"""
|
||
write_html(fig, output_path, auto_open=False)
|
||
return output_path
|
||
|
||
def save_as_image(self, fig, output_path):
|
||
"""保存为图片"""
|
||
image_config = self.table_config['image']
|
||
write_image(
|
||
fig,
|
||
file=output_path,
|
||
format=image_config['format'],
|
||
width=image_config['width'],
|
||
height=image_config['height'],
|
||
scale=image_config['scale']
|
||
)
|
||
return output_path
|
||
|
||
def convert_tables(self, json_path, output_dir='temp'):
|
||
"""将JSON中的所有表格转换为HTML和图片"""
|
||
os.makedirs(output_dir, exist_ok=True)
|
||
tables = self.load_table_data(json_path)
|
||
output_paths = {'html': [], 'image': []}
|
||
|
||
for i, table in enumerate(tables):
|
||
fig = self.create_table(table, i)
|
||
if fig:
|
||
# 保存HTML
|
||
# html_path = os.path.join(output_dir, f"table_{i+1}.html")
|
||
# html_path = self.save_as_html(fig, html_path)
|
||
# output_paths['html'].append(html_path)
|
||
|
||
# 保存图片
|
||
image_path = os.path.join(output_dir, f"table_{i+1}.png")
|
||
image_path = self.save_as_image(fig, image_path)
|
||
output_paths['image'].append(image_path)
|
||
|
||
return output_paths
|
||
|
||
def generate_table_images():
|
||
converter = PlotlyTableConverter()
|
||
# 示例JSON数据格式应与图片中的表格结构一致
|
||
sample_data = {
|
||
"tables": [
|
||
[
|
||
["维度", "项目A/Project A", "项目B/Project B", "项目C/Project C", "评估标准/Evaluation"],
|
||
["进度 Progress", "按时完成90%的关键里程碑,延期完成10%", "提前两周完成所有阶段", "频繁延期,关键任务延误超过一个月", "按时完成率≥90%为优秀,80%-89%为良好,<80%为需改进"],
|
||
["质量 Quality", "客户满意度调查得分92分", "产品缺陷率低至0.5%", "多次因质量问题返工", "客户满意度≥90%,产品缺陷率≤1%为高质量"],
|
||
["成本 Cost", "超支5%,在可接受范围内", "预算内完成,成本控制出色,节约3%", "成本超支20%", "成本控制在预算+5%内为优秀,+5%-10%为良好,>10%为需改进"],
|
||
["风险 Risk", "无重大损失", "风险识别全面", "风险管理不足", "风险识别率≥90%,有效缓解率≥80%为优秀"],
|
||
["沟通 Communication", "定期召开项目会议,沟通记录详尽,反馈及时", "建立了高效的沟通机制使用管理工具促进协作", "沟通不畅,信息延误导致决策失误", "沟通满意度≥90%,信息传递准确率≥95%为高效沟通"]
|
||
]
|
||
]
|
||
}
|
||
|
||
# 保存示例JSON数据
|
||
os.makedirs("temp", exist_ok=True)
|
||
with open("temp/table.json", "w", encoding="utf-8") as f:
|
||
json.dump(sample_data, f, ensure_ascii=False, indent=4)
|
||
|
||
# 执行转换
|
||
output_paths = converter.convert_tables("temp/table.json")
|
||
|
||
print("表格图片已保存至:")
|
||
for path in output_paths['image']:
|
||
print(f"- {path}")
|
||
|
||
if __name__ == "__main__":
|
||
generate_table_images()
|