# 项目总览 PDF 中文字体配置化修复实施记录 ## 保存路径确认 - 文档类型:实施记录 - 保存路径:`docs/reports/implementation/` ## 问题说明 - 异常信息:`com.ruoyi.common.exception.ServiceException: 未找到可用中文字体,无法导出PDF报告` - 触发链路:结果总览导出 PDF 时,`CcdiProjectOverviewReportPdfExporter` 需要通过 PDFBox 加载中文字体;原实现依赖代码内置候选路径,部署环境字体路径不可控时会导致导出失败。 ## 修改内容 - 修改 `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewReportPdfExporter.java` - 删除 Java 代码内置多路径候选列表。 - 通过 `ccdi.report.pdf-font-path` 读取 profile 配置中的单个字体路径。 - 配置为空时提示 `未配置PDF中文字体路径,无法导出PDF报告`。 - 配置文件不存在、格式不支持或字体不可导出时,错误信息包含配置路径。 - `.ttc` 字体集合优先选择支持 TrueType 子集化的简体中文字体名,未命中时再使用集合内首个支持子集化的字体。 - 字体集合源在 `document.save()` 完成后再关闭,避免 PDFBox 保存阶段继续读取字体时源文件已关闭。 - 增加 `.otf` 字体文件加载支持。 - 修改 `ruoyi-admin/src/main/resources/application-dev.yml` - 增加本地 macOS 字体路径:`/System/Library/Fonts/STHeiti Medium.ttc`。 - 修改 `ruoyi-admin/src/main/resources/application-nas.yml` - 修改 `ruoyi-admin/src/main/resources/application-uat.yml` - 修改 `ruoyi-admin/src/main/resources/application-pro.yml` - 增加 Linux 字体路径:`/usr/share/fonts/truetype/wqy/wqy-microhei.ttc`。 - 未修改 `application.yml`,不提供全局默认值。 - 修改 `docker/backend/Dockerfile` - 后端镜像安装 `fontconfig` 与 `fonts-wqy-microhei`,确保 NAS Docker 部署环境具备可用中文字体。 - 修改 `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewReportPdfExporterTest.java` - 正常导出用例显式传入测试环境字体路径。 - 新增空配置与不存在路径的异常覆盖。 ## 影响范围 - 影响结果总览 PDF 导出功能。 - 不改变报告数据组装、表格内容、前端下载接口和文件名规则。 - 不在 `application.yml` 增加默认配置,缺少 profile 配置时导出时报错。 - Docker 镜像构建会新增中文字体包安装步骤。 ## 验证记录 - 已执行:`mvn -pl ccdi-project -Dtest=CcdiProjectOverviewReportPdfExporterTest -Dsurefire.failIfNoSpecifiedTests=false test` - 结果:失败,失败原因是当前工作区已有其他源码编译错误,未进入 PDF 导出测试。 - 主要错误包括:`getDataTable` 调用参数不匹配、流水接口字段和方法签名不匹配。 - 已执行:手工编译 PDF 导出器及其依赖 VO 到 `ccdi-project/target/classes` 后,运行 `mvn -pl ccdi-project -Dtest=CcdiProjectOverviewReportPdfExporterTest -Dsurefire.failIfNoSpecifiedTests=false -Dmaven.main.skip=true test` - 结果:失败,失败原因是 Maven 仍尝试编译 `ccdi-project` 下全量测试类,而当前 `target/classes` 缺少其他测试依赖的业务类。 - 已执行:手工编译 `CcdiProjectOverviewReportPdfExporterTest` 后,通过 JUnit Platform Launcher 指定运行该测试类 - 结果:通过,`Tests found: 3`,`Tests succeeded: 3`,`Tests failed: 0`。