Showing
3 changed files
with
625 additions
and
0 deletions
ReportEngine/docs/PDF_EXPORT_GUIDE.md
0 → 100644
| 1 | +# PDF导出优化系统使用指南 | ||
| 2 | + | ||
| 3 | +## 概述 | ||
| 4 | + | ||
| 5 | +全新的PDF导出系统现已集成到ReportEngine中,提供了智能布局优化功能,确保PDF文档美观且无溢出问题。 | ||
| 6 | + | ||
| 7 | +## 核心特性 | ||
| 8 | + | ||
| 9 | +### 1. 智能布局优化 | ||
| 10 | + | ||
| 11 | +系统会自动分析文档内容并优化布局参数: | ||
| 12 | + | ||
| 13 | +- **KPI卡片优化** | ||
| 14 | + - 自动调整每行列数(1-3列) | ||
| 15 | + - 根据数值长度动态调整字号 | ||
| 16 | + - 防止数值溢出 | ||
| 17 | + | ||
| 18 | +- **表格优化** | ||
| 19 | + - 根据列数自动缩小字号 | ||
| 20 | + - 智能调整单元格内边距 | ||
| 21 | + - 支持长内容自动换行 | ||
| 22 | + | ||
| 23 | +- **文本优化** | ||
| 24 | + - 检测长文本自动增加行高 | ||
| 25 | + - 防止标题孤行 | ||
| 26 | + - 优化段落间距 | ||
| 27 | + | ||
| 28 | +### 2. 配置持久化 | ||
| 29 | + | ||
| 30 | +所有优化决策都会保存到日志文件中: | ||
| 31 | +- 位置:`logs/pdf_layouts/layout_YYYYMMDD_HHMMSS.json` | ||
| 32 | +- 内容:文档统计信息、优化策略、最终配置 | ||
| 33 | + | ||
| 34 | +### 3. 前端集成 | ||
| 35 | + | ||
| 36 | +用户只需点击"下载PDF"按钮,系统将: | ||
| 37 | +1. 自动分析报告内容 | ||
| 38 | +2. 应用最佳布局优化 | ||
| 39 | +3. 生成高质量PDF | ||
| 40 | +4. 自动下载到本地 | ||
| 41 | + | ||
| 42 | +## 使用方法 | ||
| 43 | + | ||
| 44 | +### 方式一:通过Web界面(推荐) | ||
| 45 | + | ||
| 46 | +1. 启动系统:`python app.py` | ||
| 47 | +2. 生成报告:在Report Engine中生成最终报告 | ||
| 48 | +3. 点击"下载PDF"按钮 | ||
| 49 | +4. 系统自动优化并下载PDF | ||
| 50 | + | ||
| 51 | +### 方式二:通过API | ||
| 52 | + | ||
| 53 | +#### 根据任务ID导出 | ||
| 54 | + | ||
| 55 | +```bash | ||
| 56 | +curl -X GET \ | ||
| 57 | + "http://localhost:5000/api/report/export/pdf/YOUR_TASK_ID?optimize=true" \ | ||
| 58 | + -o report.pdf | ||
| 59 | +``` | ||
| 60 | + | ||
| 61 | +#### 从IR JSON直接导出 | ||
| 62 | + | ||
| 63 | +```bash | ||
| 64 | +curl -X POST \ | ||
| 65 | + "http://localhost:5000/api/report/export/pdf-from-ir" \ | ||
| 66 | + -H "Content-Type: application/json" \ | ||
| 67 | + -d '{ | ||
| 68 | + "document_ir": {...}, | ||
| 69 | + "optimize": true | ||
| 70 | + }' \ | ||
| 71 | + -o report.pdf | ||
| 72 | +``` | ||
| 73 | + | ||
| 74 | +### 方式三:通过Python脚本 | ||
| 75 | + | ||
| 76 | +```python | ||
| 77 | +from pathlib import Path | ||
| 78 | +import json | ||
| 79 | +from ReportEngine.renderers import PDFRenderer | ||
| 80 | + | ||
| 81 | +# 读取IR数据 | ||
| 82 | +with open('report_ir.json', 'r', encoding='utf-8') as f: | ||
| 83 | + document_ir = json.load(f) | ||
| 84 | + | ||
| 85 | +# 创建渲染器并导出PDF | ||
| 86 | +renderer = PDFRenderer() | ||
| 87 | +renderer.render_to_pdf( | ||
| 88 | + document_ir, | ||
| 89 | + 'output.pdf', | ||
| 90 | + optimize_layout=True # 启用布局优化 | ||
| 91 | +) | ||
| 92 | +``` | ||
| 93 | + | ||
| 94 | +## 配置选项 | ||
| 95 | + | ||
| 96 | +### 全局配置 | ||
| 97 | + | ||
| 98 | +```python | ||
| 99 | +from ReportEngine.renderers import PDFLayoutOptimizer, PDFLayoutConfig | ||
| 100 | + | ||
| 101 | +# 自定义配置 | ||
| 102 | +config = PDFLayoutConfig( | ||
| 103 | + page=PageLayout( | ||
| 104 | + font_size_base=14, | ||
| 105 | + line_height=1.6 | ||
| 106 | + ), | ||
| 107 | + kpi_card=KPICardLayout( | ||
| 108 | + font_size_value=32, | ||
| 109 | + min_height=120 | ||
| 110 | + ), | ||
| 111 | + # ... 更多配置 | ||
| 112 | +) | ||
| 113 | + | ||
| 114 | +# 使用自定义配置 | ||
| 115 | +optimizer = PDFLayoutOptimizer(config) | ||
| 116 | +renderer = PDFRenderer(layout_optimizer=optimizer) | ||
| 117 | +``` | ||
| 118 | + | ||
| 119 | +### 优化策略 | ||
| 120 | + | ||
| 121 | +| 场景 | 触发条件 | 优化措施 | | ||
| 122 | +|------|---------|---------| | ||
| 123 | +| KPI数量多 | > 6个 | 调整为3列布局 | | ||
| 124 | +| KPI数量少 | ≤ 2个 | 调整为1列布局 | | ||
| 125 | +| KPI数值长 | > 10字符 | 字号从32px调整为28px | | ||
| 126 | +| KPI数值很长 | > 15字符 | 字号从32px调整为24px | | ||
| 127 | +| 表格列多 | > 6列 | 字号从13/12px调整为11/10px | | ||
| 128 | +| 文本很长 | > 200字符 | 行高从1.6增加到1.8 | | ||
| 129 | + | ||
| 130 | +## 测试 | ||
| 131 | + | ||
| 132 | +运行测试脚本验证所有功能: | ||
| 133 | + | ||
| 134 | +```bash | ||
| 135 | +# 设置环境变量 | ||
| 136 | +export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH | ||
| 137 | + | ||
| 138 | +# 运行测试 | ||
| 139 | +python test_pdf_optimized.py | ||
| 140 | +``` | ||
| 141 | + | ||
| 142 | +测试将生成: | ||
| 143 | +- `test_pdf_optimized.pdf` - 启用优化的PDF | ||
| 144 | +- `test_pdf_default.pdf` - 默认设置的PDF(对比) | ||
| 145 | +- `test_layout_config.json` - 布局配置 | ||
| 146 | +- `logs/pdf_layouts/` - 优化日志 | ||
| 147 | + | ||
| 148 | +## 优化日志格式 | ||
| 149 | + | ||
| 150 | +```json | ||
| 151 | +{ | ||
| 152 | + "timestamp": "2024-11-18T19:41:10.983000", | ||
| 153 | + "document_stats": { | ||
| 154 | + "kpi_count": 10, | ||
| 155 | + "table_count": 2, | ||
| 156 | + "chart_count": 2, | ||
| 157 | + "max_kpi_value_length": 14, | ||
| 158 | + "max_table_columns": 8 | ||
| 159 | + }, | ||
| 160 | + "optimizations": [ | ||
| 161 | + "KPI数值过长(14字符),字号从32调整为28", | ||
| 162 | + "KPI卡片较多(10个),每行列数从2调整为3", | ||
| 163 | + "表格列数较多(8列),缩小字号和内边距" | ||
| 164 | + ], | ||
| 165 | + "final_config": { | ||
| 166 | + "page": {...}, | ||
| 167 | + "kpi_card": {...}, | ||
| 168 | + "table": {...} | ||
| 169 | + } | ||
| 170 | +} | ||
| 171 | +``` | ||
| 172 | + | ||
| 173 | +## 故障排除 | ||
| 174 | + | ||
| 175 | +### 问题1:WeasyPrint库加载失败 | ||
| 176 | + | ||
| 177 | +**症状**: | ||
| 178 | +``` | ||
| 179 | +OSError: cannot load library 'libpango-1.0-0' | ||
| 180 | +``` | ||
| 181 | + | ||
| 182 | +**解决方案**: | ||
| 183 | +```bash | ||
| 184 | +# macOS | ||
| 185 | +export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH | ||
| 186 | + | ||
| 187 | +# 或在脚本中设置 | ||
| 188 | +import os | ||
| 189 | +os.environ['DYLD_LIBRARY_PATH'] = '/opt/homebrew/lib' | ||
| 190 | +``` | ||
| 191 | + | ||
| 192 | +### 问题2:字体文件缺失 | ||
| 193 | + | ||
| 194 | +**症状**: | ||
| 195 | +``` | ||
| 196 | +FileNotFoundError: 未找到字体文件 | ||
| 197 | +``` | ||
| 198 | + | ||
| 199 | +**解决方案**: | ||
| 200 | +确保以下字体文件存在: | ||
| 201 | +- `ReportEngine/renderers/assets/fonts/SourceHanSerifSC-Medium.otf` | ||
| 202 | + | ||
| 203 | +### 问题3:PDF布局仍有问题 | ||
| 204 | + | ||
| 205 | +**解决方案**: | ||
| 206 | +1. 检查优化日志:`logs/pdf_layouts/` | ||
| 207 | +2. 查看应用了哪些优化策略 | ||
| 208 | +3. 如需自定义,修改配置参数 | ||
| 209 | +4. 禁用优化对比:`optimize_layout=False` | ||
| 210 | + | ||
| 211 | +## 性能优化建议 | ||
| 212 | + | ||
| 213 | +1. **首次导出**:需要加载字体文件,可能需要几秒钟 | ||
| 214 | +2. **字体子集化**:对于大型报告,考虑使用字体子集以减小文件大小 | ||
| 215 | +3. **图表处理**:图表会自动转换为表格,提高PDF渲染速度 | ||
| 216 | +4. **批量导出**:复用同一个PDFRenderer实例可以提高效率 | ||
| 217 | + | ||
| 218 | +## 架构说明 | ||
| 219 | + | ||
| 220 | +``` | ||
| 221 | +┌─────────────────────────────────────────┐ | ||
| 222 | +│ Web UI / API │ | ||
| 223 | +│ (用户点击"下载PDF"按钮) │ | ||
| 224 | +└──────────────┬──────────────────────────┘ | ||
| 225 | + │ | ||
| 226 | + ▼ | ||
| 227 | +┌─────────────────────────────────────────┐ | ||
| 228 | +│ Flask API Endpoint │ | ||
| 229 | +│ /api/report/export/pdf/:task_id │ | ||
| 230 | +└──────────────┬──────────────────────────┘ | ||
| 231 | + │ | ||
| 232 | + ▼ | ||
| 233 | +┌─────────────────────────────────────────┐ | ||
| 234 | +│ PDFLayoutOptimizer │ | ||
| 235 | +│ • 分析文档结构 │ | ||
| 236 | +│ • 智能调整布局参数 │ | ||
| 237 | +│ • 保存优化日志 │ | ||
| 238 | +└──────────────┬──────────────────────────┘ | ||
| 239 | + │ | ||
| 240 | + ▼ | ||
| 241 | +┌─────────────────────────────────────────┐ | ||
| 242 | +│ HTMLRenderer │ | ||
| 243 | +│ • 将IR转换为HTML │ | ||
| 244 | +└──────────────┬──────────────────────────┘ | ||
| 245 | + │ | ||
| 246 | + ▼ | ||
| 247 | +┌─────────────────────────────────────────┐ | ||
| 248 | +│ PDFRenderer │ | ||
| 249 | +│ • 注入优化的CSS │ | ||
| 250 | +│ • 嵌入字体 │ | ||
| 251 | +│ • 使用WeasyPrint生成PDF │ | ||
| 252 | +└──────────────┬──────────────────────────┘ | ||
| 253 | + │ | ||
| 254 | + ▼ | ||
| 255 | +┌─────────────────────────────────────────┐ | ||
| 256 | +│ 优化的PDF文件 │ | ||
| 257 | +│ • 无溢出 │ | ||
| 258 | +│ • 布局美观 │ | ||
| 259 | +│ • 自动分页 │ | ||
| 260 | +└─────────────────────────────────────────┘ | ||
| 261 | +``` | ||
| 262 | + | ||
| 263 | +## 更新日志 | ||
| 264 | + | ||
| 265 | +### v1.0.0 (2024-11-18) | ||
| 266 | + | ||
| 267 | +**新增功能**: | ||
| 268 | +- ✅ PDF布局智能优化器 | ||
| 269 | +- ✅ 自动调整字号、行间距、网格列数 | ||
| 270 | +- ✅ 配置持久化系统 | ||
| 271 | +- ✅ Flask API集成 | ||
| 272 | +- ✅ 前端一键导出 | ||
| 273 | + | ||
| 274 | +**优化措施**: | ||
| 275 | +- ✅ KPI卡片防溢出 | ||
| 276 | +- ✅ 表格自适应布局 | ||
| 277 | +- ✅ 长文本行高优化 | ||
| 278 | +- ✅ 标题防孤行 | ||
| 279 | +- ✅ 图表转表格渲染 | ||
| 280 | + | ||
| 281 | +**测试覆盖**: | ||
| 282 | +- ✅ 多种KPI场景测试 | ||
| 283 | +- ✅ 复杂表格测试 | ||
| 284 | +- ✅ 图表渲染测试 | ||
| 285 | +- ✅ 长文本测试 | ||
| 286 | + | ||
| 287 | +## 未来计划 | ||
| 288 | + | ||
| 289 | +- [ ] 支持更多纸张尺寸(A3、Letter等) | ||
| 290 | +- [ ] 添加PDF水印功能 | ||
| 291 | +- [ ] 支持页眉页脚自定义 | ||
| 292 | +- [ ] 提供更多布局模板 | ||
| 293 | +- [ ] 优化大型文档渲染性能 | ||
| 294 | + | ||
| 295 | +## 技术栈 | ||
| 296 | + | ||
| 297 | +- **PDF生成**:WeasyPrint | ||
| 298 | +- **布局优化**:自研PDFLayoutOptimizer | ||
| 299 | +- **字体**:思源宋体(SourceHanSerifSC) | ||
| 300 | +- **后端框架**:Flask | ||
| 301 | +- **前端**:原生JavaScript | ||
| 302 | + | ||
| 303 | +## 贡献者 | ||
| 304 | + | ||
| 305 | +欢迎提交Issue和PR来改进PDF导出系统! | ||
| 306 | + | ||
| 307 | +## 许可证 | ||
| 308 | + | ||
| 309 | +本项目遵循项目主仓库的许可证。 |
ReportEngine/docs/PDF_EXPORT_QUICKSTART.md
0 → 100644
| 1 | +# PDF导出功能快速启动 | ||
| 2 | + | ||
| 3 | +## 立即开始 | ||
| 4 | + | ||
| 5 | +### 1. 启动系统 | ||
| 6 | + | ||
| 7 | +```bash | ||
| 8 | +# 设置环境变量(macOS必需) | ||
| 9 | +export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH | ||
| 10 | + | ||
| 11 | +# 启动Flask应用 | ||
| 12 | +python app.py | ||
| 13 | +``` | ||
| 14 | + | ||
| 15 | +### 2. 生成报告 | ||
| 16 | + | ||
| 17 | +1. 在浏览器中打开 `http://localhost:5000` | ||
| 18 | +2. 启动 Insight、Media、Query Engine | ||
| 19 | +3. 输入搜索主题,点击搜索 | ||
| 20 | +4. 切换到 Report Engine 标签 | ||
| 21 | +5. 点击"生成最终报告" | ||
| 22 | + | ||
| 23 | +### 3. 导出PDF | ||
| 24 | + | ||
| 25 | +报告生成完成后: | ||
| 26 | +1. 点击"**下载PDF**"按钮 | ||
| 27 | +2. 系统自动: | ||
| 28 | + - 分析报告内容 | ||
| 29 | + - 优化布局参数 | ||
| 30 | + - 生成高质量PDF | ||
| 31 | + - 自动下载文件 | ||
| 32 | + | ||
| 33 | +## 快速测试 | ||
| 34 | + | ||
| 35 | +想立即看到效果?运行测试脚本: | ||
| 36 | + | ||
| 37 | +```bash | ||
| 38 | +# 设置环境变量 | ||
| 39 | +export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH | ||
| 40 | + | ||
| 41 | +# 运行测试(生成示例PDF) | ||
| 42 | +python test_pdf_optimized.py | ||
| 43 | + | ||
| 44 | +# 查看结果 | ||
| 45 | +open test_pdf_optimized.pdf | ||
| 46 | +``` | ||
| 47 | + | ||
| 48 | +测试会生成: | ||
| 49 | +- ✅ 包含10个KPI卡片的报告 | ||
| 50 | +- ✅ 复杂的8列表格 | ||
| 51 | +- ✅ 多个图表和色块 | ||
| 52 | +- ✅ 自动优化的布局 | ||
| 53 | + | ||
| 54 | +## 优化效果对比 | ||
| 55 | + | ||
| 56 | +系统会自动: | ||
| 57 | + | ||
| 58 | +| 问题 | 优化前 | 优化后 | | ||
| 59 | +|------|--------|--------| | ||
| 60 | +| KPI数值溢出 | ⚠️ 字号固定32px,长数值溢出 | ✅ 自动缩小到28px或24px | | ||
| 61 | +| KPI布局拥挤 | ⚠️ 固定2列,10个卡片显得拥挤 | ✅ 自动调整为3列 | | ||
| 62 | +| 表格字体过大 | ⚠️ 8列表格字体过大 | ✅ 字号从13/12px缩小到11/10px | | ||
| 63 | +| 长文本难读 | ⚠️ 行高固定1.6 | ✅ 自动增加到1.8 | | ||
| 64 | + | ||
| 65 | +## 查看优化日志 | ||
| 66 | + | ||
| 67 | +想了解系统做了哪些优化? | ||
| 68 | + | ||
| 69 | +```bash | ||
| 70 | +# 查看最新的优化日志 | ||
| 71 | +cat logs/pdf_layouts/layout_*.json | ||
| 72 | + | ||
| 73 | +# 或打开保存的配置文件 | ||
| 74 | +cat test_layout_config.json | ||
| 75 | +``` | ||
| 76 | + | ||
| 77 | +日志示例: | ||
| 78 | +```json | ||
| 79 | +{ | ||
| 80 | + "optimizations": [ | ||
| 81 | + "KPI数值过长(14字符),字号从32调整为28", | ||
| 82 | + "KPI卡片较多(10个),每行列数从2调整为3", | ||
| 83 | + "表格列数较多(8列),缩小字号和内边距" | ||
| 84 | + ] | ||
| 85 | +} | ||
| 86 | +``` | ||
| 87 | + | ||
| 88 | +## 常见问题 | ||
| 89 | + | ||
| 90 | +### Q: 为什么PDF生成需要几秒钟? | ||
| 91 | +A: 首次生成需要加载字体文件和分析文档,后续会更快。 | ||
| 92 | + | ||
| 93 | +### Q: 可以禁用自动优化吗? | ||
| 94 | +A: 可以,在API中设置 `optimize=false`: | ||
| 95 | +```bash | ||
| 96 | +curl "http://localhost:5000/api/report/export/pdf/TASK_ID?optimize=false" | ||
| 97 | +``` | ||
| 98 | + | ||
| 99 | +### Q: 如何自定义布局参数? | ||
| 100 | +A: 参考 [PDF_EXPORT_GUIDE.md](PDF_EXPORT_GUIDE.md) 中的"配置选项"章节。 | ||
| 101 | + | ||
| 102 | +## 技术亮点 | ||
| 103 | + | ||
| 104 | +✨ **智能布局分析** | ||
| 105 | +- 自动检测KPI数量、表格复杂度、文本长度 | ||
| 106 | +- 根据内容特征动态调整参数 | ||
| 107 | + | ||
| 108 | +✨ **无损质量** | ||
| 109 | +- 使用WeasyPrint专业PDF引擎 | ||
| 110 | +- 完整保留CSS样式 | ||
| 111 | +- 完美支持中文字体 | ||
| 112 | + | ||
| 113 | +✨ **开箱即用** | ||
| 114 | +- 前端一键导出 | ||
| 115 | +- 无需额外配置 | ||
| 116 | +- 自动应用最佳实践 | ||
| 117 | + | ||
| 118 | +## 下一步 | ||
| 119 | + | ||
| 120 | +- 📖 阅读完整文档:[PDF_EXPORT_GUIDE.md](PDF_EXPORT_GUIDE.md) | ||
| 121 | +- 🧪 运行测试:`python test_pdf_optimized.py` | ||
| 122 | +- 🎨 自定义布局:修改配置参数 | ||
| 123 | +- 🚀 集成到生产:通过API批量导出 | ||
| 124 | + | ||
| 125 | +## 问题反馈 | ||
| 126 | + | ||
| 127 | +遇到问题? | ||
| 128 | +1. 查看 [PDF_EXPORT_GUIDE.md](PDF_EXPORT_GUIDE.md) 的"故障排除"章节 | ||
| 129 | +2. 检查 `logs/pdf_layouts/` 目录的优化日志 | ||
| 130 | +3. 提交Issue到项目仓库 | ||
| 131 | + | ||
| 132 | +--- | ||
| 133 | + | ||
| 134 | +享受全新的PDF导出体验! 🎉 |
ReportEngine/docs/PDF_EXPORT_README.md
0 → 100644
| 1 | +# Python PDF 导出 - 使用指南 | ||
| 2 | + | ||
| 3 | +## ✅ 解决方案说明 | ||
| 4 | + | ||
| 5 | +已将PDF导出从浏览器端(jsPDF)改为**Python直接生成**,使用WeasyPrint库,完美解决中文乱码问题。 | ||
| 6 | + | ||
| 7 | +### 优势 | ||
| 8 | +- ✓ **无乱码**:使用思源宋体(SourceHanSerifSC),完美显示所有中文字符 | ||
| 9 | +- ✓ **样式保留**:100%保留HTML的所有CSS样式 | ||
| 10 | +- ✓ **自动优化**:自动处理分页、布局、图表转表格 | ||
| 11 | +- ✓ **高质量**:生成的PDF可直接用于打印和分发 | ||
| 12 | + | ||
| 13 | +## 📦 依赖安装 | ||
| 14 | + | ||
| 15 | +### 1. 安装系统依赖(已完成) | ||
| 16 | +```bash | ||
| 17 | +brew install pango cairo gdk-pixbuf | ||
| 18 | +``` | ||
| 19 | + | ||
| 20 | +### 2. 安装Python库(已完成) | ||
| 21 | +```bash | ||
| 22 | +pip3 install weasyprint | ||
| 23 | +``` | ||
| 24 | + | ||
| 25 | +## 🚀 使用方法 | ||
| 26 | + | ||
| 27 | +### 方法一:直接使用Python(推荐) | ||
| 28 | + | ||
| 29 | +```bash | ||
| 30 | +# 设置环境变量 | ||
| 31 | +export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH | ||
| 32 | + | ||
| 33 | +# 运行导出 | ||
| 34 | +python3 ReportEngine/scripts/export_to_pdf.py final_reports/ir/report_ir_xxx.json | ||
| 35 | + | ||
| 36 | +# 或从项目根目录运行 | ||
| 37 | +python3 -m ReportEngine.scripts.export_to_pdf final_reports/ir/report_ir_xxx.json | ||
| 38 | +``` | ||
| 39 | + | ||
| 40 | +### 方法二:使用便捷脚本(如果有的话) | ||
| 41 | + | ||
| 42 | +```bash | ||
| 43 | +# 基本用法(自动生成同名PDF) | ||
| 44 | +./pdf_export.sh final_reports/ir/report_ir_xxx.json | ||
| 45 | + | ||
| 46 | +# 指定输出路径 | ||
| 47 | +./pdf_export.sh final_reports/ir/report_ir_xxx.json my_report.pdf | ||
| 48 | +``` | ||
| 49 | + | ||
| 50 | +### 方法三:在代码中使用 | ||
| 51 | + | ||
| 52 | +```python | ||
| 53 | +from ReportEngine.renderers import PDFRenderer | ||
| 54 | +import json | ||
| 55 | + | ||
| 56 | +# 读取报告数据 | ||
| 57 | +with open("report_ir.json", "r") as f: | ||
| 58 | + document_ir = json.load(f) | ||
| 59 | + | ||
| 60 | +# 生成PDF | ||
| 61 | +renderer = PDFRenderer() | ||
| 62 | +renderer.render_to_pdf(document_ir, "output.pdf") | ||
| 63 | +``` | ||
| 64 | + | ||
| 65 | +## 📊 测试样例 | ||
| 66 | + | ||
| 67 | +已生成两个测试PDF: | ||
| 68 | + | ||
| 69 | +1. **综合样式测试** ([test_comprehensive.pdf](test_comprehensive.pdf)) | ||
| 70 | + - 包含所有样式元素 | ||
| 71 | + - 字体、标点、列表、表格、KPI卡片等 | ||
| 72 | + | ||
| 73 | +2. **真实报告** ([report_土木工程_python.pdf](report_土木工程_python.pdf)) | ||
| 74 | + - 使用真实的土木工程报告数据 | ||
| 75 | + - 完整展示实际使用效果 | ||
| 76 | + | ||
| 77 | +## ✨ 特性说明 | ||
| 78 | + | ||
| 79 | +### 1. 字体支持 | ||
| 80 | +- 优先使用:`SourceHanSerifSC-Medium.otf`(24MB完整版) | ||
| 81 | +- 备选方案:`SourceHanSerifSC-Medium-Subset.ttf`(3.7MB子集版) | ||
| 82 | +- 覆盖:所有常用汉字、标点符号、数字、英文 | ||
| 83 | + | ||
| 84 | +### 2. 样式保留 | ||
| 85 | +- 响应式布局 → PDF优化布局 | ||
| 86 | +- 交互按钮 → 自动隐藏 | ||
| 87 | +- Chart.js图表 → 自动显示fallback表格 | ||
| 88 | +- 所有CSS样式完整保留 | ||
| 89 | + | ||
| 90 | +### 3. 分页优化 | ||
| 91 | +- 标题不孤立(避免标题单独在页末) | ||
| 92 | +- 表格和卡片避免跨页断裂 | ||
| 93 | +- 引用块和callout保持完整 | ||
| 94 | + | ||
| 95 | +## 🔧 故障排除 | ||
| 96 | + | ||
| 97 | +### 问题1:找不到libpango库 | ||
| 98 | + | ||
| 99 | +**症状**: | ||
| 100 | +``` | ||
| 101 | +OSError: cannot load library 'libpango-1.0-0' | ||
| 102 | +``` | ||
| 103 | + | ||
| 104 | +**解决**: | ||
| 105 | +```bash | ||
| 106 | +# 使用提供的pdf_export.sh脚本(已自动设置环境变量) | ||
| 107 | +./pdf_export.sh <your_file.json> | ||
| 108 | + | ||
| 109 | +# 或手动设置环境变量 | ||
| 110 | +export DYLD_LIBRARY_PATH=/opt/homebrew/lib:$DYLD_LIBRARY_PATH | ||
| 111 | +``` | ||
| 112 | + | ||
| 113 | +### 问题2:字体文件缺失 | ||
| 114 | + | ||
| 115 | +**症状**: | ||
| 116 | +``` | ||
| 117 | +FileNotFoundError: 未找到字体文件 | ||
| 118 | +``` | ||
| 119 | + | ||
| 120 | +**解决**: | ||
| 121 | +确保以下任一字体文件存在: | ||
| 122 | +- `ReportEngine/renderers/assets/fonts/SourceHanSerifSC-Medium.otf` | ||
| 123 | +- `ReportEngine/renderers/assets/fonts/SourceHanSerifSC-Medium-Subset.ttf` | ||
| 124 | + | ||
| 125 | +### 问题3:PDF仍然有乱码 | ||
| 126 | + | ||
| 127 | +**解决**: | ||
| 128 | +1. 检查字体文件是否完整(应该是24MB或3.7MB) | ||
| 129 | +2. 使用pdftotext验证:`pdftotext output.pdf - | head` | ||
| 130 | +3. 如有问题,重新生成字体子集或使用完整版 | ||
| 131 | + | ||
| 132 | +## 📝 开发说明 | ||
| 133 | + | ||
| 134 | +### 核心文件 | ||
| 135 | + | ||
| 136 | +- [PDFRenderer](../renderers/pdf_renderer.py) - PDF渲染器主类 | ||
| 137 | +- [HTMLRenderer](../renderers/html_renderer.py) - HTML渲染器(被PDF渲染器使用) | ||
| 138 | +- [export_to_pdf.py](../scripts/export_to_pdf.py) - 命令行工具 | ||
| 139 | +- [pdf_export.sh](../../pdf_export.sh) - 便捷启动脚本(如果有的话) | ||
| 140 | + | ||
| 141 | +### 工作流程 | ||
| 142 | + | ||
| 143 | +``` | ||
| 144 | +Document IR (JSON) | ||
| 145 | + ↓ | ||
| 146 | +HTMLRenderer.render() | ||
| 147 | + ↓ | ||
| 148 | +HTML with embedded font (base64) | ||
| 149 | + ↓ | ||
| 150 | +WeasyPrint | ||
| 151 | + ↓ | ||
| 152 | +PDF (with SourceHanSerif font) | ||
| 153 | +``` | ||
| 154 | + | ||
| 155 | +## 🎯 下一步 | ||
| 156 | + | ||
| 157 | +如需集成到Web应用: | ||
| 158 | + | ||
| 159 | +1. **Flask/FastAPI后端** | ||
| 160 | + ```python | ||
| 161 | + from flask import send_file | ||
| 162 | + from ReportEngine.renderers import PDFRenderer | ||
| 163 | + | ||
| 164 | + @app.route('/export_pdf') | ||
| 165 | + def export_pdf(): | ||
| 166 | + renderer = PDFRenderer() | ||
| 167 | + pdf_bytes = renderer.render_to_bytes(document_ir) | ||
| 168 | + return send_file(io.BytesIO(pdf_bytes), mimetype='application/pdf') | ||
| 169 | + ``` | ||
| 170 | + | ||
| 171 | +2. **前端按钮** | ||
| 172 | + ```javascript | ||
| 173 | + document.getElementById('export-btn').addEventListener('click', () => { | ||
| 174 | + window.open('/export_pdf', '_blank'); | ||
| 175 | + }); | ||
| 176 | + ``` | ||
| 177 | + | ||
| 178 | +--- | ||
| 179 | + | ||
| 180 | +**生成时间**: 2025-11-18 | ||
| 181 | +**版本**: 1.0 | ||
| 182 | +**状态**: ✅ 已测试,无乱码 |
-
Please register or login to post a comment