# 新接口快速参考卡片 ## 🎯 核心信息 ### 新增接口 ``` GET /admin/stat/report/fuzzyReportPdfNew ``` ### 功能 将 `fuzzyReport` 返回的 Word 文档转换为 PDF 并下载 ### 参数 - `checkTaskId`: 检查任务ID(必填) - `templateId`: 报告模版ID(必填) --- ## 📊 接口对比 | 特性 | 旧接口 `/fuzzyReportPdf` | 新接口 `/fuzzyReportPdfNew` | |------|--------------------------|----------------------------| | **转换位置** | Service层 | Controller层 | | **Word生成** | Service内部 | 复用 `fuzzyReport()` | | **转换方式** | 内存流 | 内存流 | | **资源管理** | 简单 | 完善(try-finally) | | **错误处理** | 基础 | 详细日志 | | **代码复用** | 低 | 高 | --- ## 🔄 处理流程 ``` ┌─────────────────────────────────────────────────────────┐ │ 新接口流程 │ ├─────────────────────────────────────────────────────────┤ │ 1. 接收请求参数 (checkTaskId, templateId) │ │ 2. 调用 reportService.fuzzyReport() 获取 Word 文档 │ │ 3. 在 Controller 层执行转换: │ │ ├─ Word → ByteArrayOutputStream │ │ ├─ ByteArrayInputStream → XWPFDocument │ │ ├─ 配置 PdfOptions (UTF-8编码) │ │ └─ PdfConverter.convert() → PDF │ │ 4. 设置响应头 (Content-Type: application/pdf) │ │ 5. 输出 PDF 到响应流 │ │ 6. 清理资源 (finally块) │ └─────────────────────────────────────────────────────────┘ ``` --- ## 💻 快速测试 ### 浏览器测试 ``` http://localhost:8080/admin/stat/report/fuzzyReportPdfNew?checkTaskId=1262&templateId=1 ``` ### curl 测试 ```bash curl -o "test.pdf" \ "http://localhost:8080/admin/stat/report/fuzzyReportPdfNew?checkTaskId=1262&templateId=1" ``` ### 运行测试脚本 ```bash # Windows 测试新接口.bat # Linux/Mac chmod +x 测试新接口.sh ./测试新接口.sh ``` --- ## 📝 代码位置 ### 修改的文件 ``` admin-server/src/main/java/com/estate/expert/admin/controller/stat/ReportController.java ``` ### 新增内容 - **接口方法**: `fuzzyReportPdfNew()` (第81-90行) - **转换方法**: `downloadAsPdf()` (第168-233行) - **导入类**: PDF转换相关类 (第9-10行, 第15行, 第26-27行) --- ## ✅ 验证要点 下载PDF后检查: - [ ] 文件能正常打开 - [ ] 文件大小合理(>100KB) - [ ] 包含所有文本内容 - [ ] **图片是否显示**(重点) - [ ] 中文无乱码 - [ ] 表格和图表正常 --- ## 🔧 关键代码片段 ### 接口定义 ```java @ApiOperation("模糊评价报告PDF下载(新接口)") @GetMapping("/fuzzyReportPdfNew") @IgnoreAuth public void fuzzyReportPdfNew( @ApiParam("检查任务ID") @RequestParam Integer checkTaskId, @ApiParam("报告模版ID") @RequestParam Integer templateId, HttpServletResponse response) throws IOException { try (var doc = reportService.fuzzyReport(checkTaskId, templateId)) { downloadAsPdf(doc, response, "模糊评价", checkTaskId, templateId); } } ``` ### 核心转换逻辑 ```java // 1. Word → 字节数组 docOutputStream = new ByteArrayOutputStream(); doc.write(docOutputStream); // 2. 字节数组 → XWPFDocument docInputStream = new ByteArrayInputStream(docOutputStream.toByteArray()); document = new XWPFDocument(docInputStream); // 3. 配置PDF选项 PdfOptions options = PdfOptions.create(); options.fontEncoding("UTF-8"); // 4. 转换为PDF PdfConverter.getInstance().convert(document, bos, options); ``` --- ## ⚠️ 注意事项 ### 1. 图片问题 如果PDF中仍然没有图片,可能是 `fr.opensagres.poi.xwpf.converter.pdf` 库的限制。 **解决方案**: - 使用临时文件代替内存流 - 升级PDF转换库版本 - 考虑使用其他PDF转换方案 ### 2. 性能考虑 - 内存流方式适合小文件(<10MB) - 大文件建议使用临时文件或异步处理 - 考虑添加缓存机制 ### 3. 资源管理 - 使用 try-finally 确保资源释放 - 所有流都需要正确关闭 - 异常情况下也要清理资源 --- ## 🚀 后续优化方向 ### 方案1: 使用临时文件 ```java Path tempFile = Files.createTempFile("report_", ".docx"); try (FileOutputStream out = new FileOutputStream(tempFile.toFile())) { doc.write(out); } // 从文件读取并转换 ``` ### 方案2: 异步处理 ```java @Async public CompletableFuture generatePdfAsync(...) { // 异步生成PDF } ``` ### 方案3: 添加缓存 ```java @Cacheable(value = "pdfReports", key = "#checkTaskId + '_' + #templateId") public byte[] getCachedPdf(...) { // 缓存PDF结果 } ``` --- ## 📞 问题排查 ### 问题1: PDF无法打开 **检查**: 文件大小是否为0或过小 **日志**: `tail -f logs/application.log | grep "Word转PDF"` ### 问题2: 图片不显示 **检查**: Word版本是否有图片 **对比**: 旧接口PDF是否有图片 ### 问题3: 中文乱码 **检查**: `options.fontEncoding("UTF-8")` 是否生效 **系统**: 确认服务器已安装中文字体 --- ## 📚 相关文档 - `新接口使用说明.md` - 详细使用说明 - `测试新接口.bat/.sh` - 自动化测试脚本 --- **创建时间**: 2026-01-24 **接口版本**: v1.0 **状态**: ✅ 已实现