Showing
2 changed files
with
76 additions
and
3 deletions
| @@ -422,8 +422,8 @@ class PDFRenderer: | @@ -422,8 +422,8 @@ class PDFRenderer: | ||
| 422 | # 格式: <canvas id="chart-N" data-config-id="chart-config-N"></canvas> | 422 | # 格式: <canvas id="chart-N" data-config-id="chart-config-N"></canvas> |
| 423 | canvas_pattern = rf'<canvas[^>]+data-config-id="{re.escape(config_id)}"[^>]*></canvas>' | 423 | canvas_pattern = rf'<canvas[^>]+data-config-id="{re.escape(config_id)}"[^>]*></canvas>' |
| 424 | 424 | ||
| 425 | - # 替换canvas为SVG | ||
| 426 | - html = re.sub(canvas_pattern, svg_html, html) | 425 | + # 【修复】替换canvas为SVG,使用lambda避免反斜杠转义问题 |
| 426 | + html = re.sub(canvas_pattern, lambda m: svg_html, html) | ||
| 427 | logger.debug(f"已替换图表 {widget_id} 的canvas为SVG") | 427 | logger.debug(f"已替换图表 {widget_id} 的canvas为SVG") |
| 428 | else: | 428 | else: |
| 429 | logger.warning(f"未找到图表 {widget_id} 对应的配置脚本") | 429 | logger.warning(f"未找到图表 {widget_id} 对应的配置脚本") |
| @@ -468,7 +468,10 @@ class PDFRenderer: | @@ -468,7 +468,10 @@ class PDFRenderer: | ||
| 468 | # 暂时使用简单的替换方案 | 468 | # 暂时使用简单的替换方案 |
| 469 | # 找到第一个math-block div并替换 | 469 | # 找到第一个math-block div并替换 |
| 470 | math_block_pattern = r'<div class="math-block">\$\$[^$]*\$\$</div>' | 470 | math_block_pattern = r'<div class="math-block">\$\$[^$]*\$\$</div>' |
| 471 | - html = re.sub(math_block_pattern, svg_html, html, count=1) | 471 | + # 【修复】转义svg_html中的反斜杠,避免re.sub将其解释为转义序列 |
| 472 | + # 使用re.escape处理替换字符串中的特殊字符 | ||
| 473 | + escaped_svg_html = svg_html.replace('\\', r'\\') | ||
| 474 | + html = re.sub(math_block_pattern, lambda m: svg_html, html, count=1) | ||
| 472 | logger.debug(f"已替换公式 {math_id} 为SVG") | 475 | logger.debug(f"已替换公式 {math_id} 为SVG") |
| 473 | 476 | ||
| 474 | return html | 477 | return html |
export_pdf.py
0 → 100644
| 1 | +#!/usr/bin/env python | ||
| 2 | +""" | ||
| 3 | +PDF导出脚本 | ||
| 4 | +""" | ||
| 5 | +import json | ||
| 6 | +import os | ||
| 7 | +import sys | ||
| 8 | +from datetime import datetime | ||
| 9 | +from pathlib import Path | ||
| 10 | + | ||
| 11 | +# 添加项目路径到sys.path | ||
| 12 | +sys.path.insert(0, '/Users/mayiding/Desktop/GitMy/BettaFish') | ||
| 13 | + | ||
| 14 | +def export_pdf(ir_file_path): | ||
| 15 | + """导出PDF""" | ||
| 16 | + try: | ||
| 17 | + # 读取IR文件 | ||
| 18 | + print(f"正在读取报告文件: {ir_file_path}") | ||
| 19 | + with open(ir_file_path, 'r', encoding='utf-8') as f: | ||
| 20 | + document_ir = json.load(f) | ||
| 21 | + | ||
| 22 | + # 导入PDF渲染器 | ||
| 23 | + from ReportEngine.renderers.pdf_renderer import PDFRenderer | ||
| 24 | + | ||
| 25 | + # 创建PDF渲染器 | ||
| 26 | + print("正在初始化PDF渲染器...") | ||
| 27 | + renderer = PDFRenderer() | ||
| 28 | + | ||
| 29 | + # 生成PDF | ||
| 30 | + print("正在生成PDF...") | ||
| 31 | + pdf_bytes = renderer.render_to_bytes(document_ir, optimize_layout=True) | ||
| 32 | + | ||
| 33 | + # 确定输出文件名 | ||
| 34 | + topic = document_ir.get('metadata', {}).get('topic', 'report') | ||
| 35 | + output_dir = Path('/Users/mayiding/Desktop/GitMy/BettaFish/final_reports/pdf') | ||
| 36 | + output_dir.mkdir(parents=True, exist_ok=True) | ||
| 37 | + | ||
| 38 | + pdf_filename = f"report_{topic}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf" | ||
| 39 | + output_path = output_dir / pdf_filename | ||
| 40 | + | ||
| 41 | + # 保存PDF文件 | ||
| 42 | + print(f"正在保存PDF到: {output_path}") | ||
| 43 | + with open(output_path, 'wb') as f: | ||
| 44 | + f.write(pdf_bytes) | ||
| 45 | + | ||
| 46 | + print(f"✅ PDF导出成功!") | ||
| 47 | + print(f"文件位置: {output_path}") | ||
| 48 | + print(f"文件大小: {len(pdf_bytes) / 1024 / 1024:.2f} MB") | ||
| 49 | + | ||
| 50 | + return str(output_path) | ||
| 51 | + | ||
| 52 | + except Exception as e: | ||
| 53 | + print(f"❌ PDF导出失败: {str(e)}") | ||
| 54 | + import traceback | ||
| 55 | + traceback.print_exc() | ||
| 56 | + return None | ||
| 57 | + | ||
| 58 | +if __name__ == "__main__": | ||
| 59 | + # 使用最新的报告文件 | ||
| 60 | + latest_report = "/Users/mayiding/Desktop/GitMy/BettaFish/final_reports/ir/report_ir_人工智能行情发展走势_20251119_235407.json" | ||
| 61 | + | ||
| 62 | + if os.path.exists(latest_report): | ||
| 63 | + print("="*50) | ||
| 64 | + print("开始导出PDF") | ||
| 65 | + print("="*50) | ||
| 66 | + result = export_pdf(latest_report) | ||
| 67 | + if result: | ||
| 68 | + print(f"\n📄 PDF文件已生成: {result}") | ||
| 69 | + else: | ||
| 70 | + print(f"❌ 报告文件不存在: {latest_report}") |
-
Please register or login to post a comment