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()