# file-convert **Repository Path**: zfworkspace/file-convert ## Basic Information - **Project Name**: file-convert - **Description**: No description available - **Primary Language**: Unknown - **License**: GPL-3.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-14 - **Last Updated**: 2026-08-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # file-convert `file-convert` 是面向 Java 系统的常见文档格式转换 SDK。调用方只依赖稳定 API,具体转换能力由可插拔引擎提供。 ## 当前阶段 项目已经完成 API、核心执行链、内容格式检测,以及 Office、PDFBox、图片和 OFD 预览引擎的第一轮实现,当前模块包括: - `file-convert-api`:调用方使用的请求、结果、格式和异常模型。 - `file-convert-spi`:转换引擎与格式检测器的扩展契约。 - `file-convert-core`:输入快照、任务生命周期、确定性路由、统一截止时间、产物校验快照、独占发布、摘要和资源限制。 - `file-convert-format-tika`:基于 Apache Tika 的内容格式检测,并按实际解压流校验 OOXML/ODF 的 ZIP 结构、解压大小和压缩比。 - `file-convert-engine-office`:基于 JODConverter 和 LibreOffice 进程池的 Office 转 PDF 引擎。 - `file-convert-engine-pdf`:基于 Apache PDFBox 的图片转 PDF 和 PDF 全页渲染引擎。 - `file-convert-engine-image`:基于 ImageIO 和 TwelveMonkeys 的常见图片格式转换引擎。 - `file-convert-engine-ofd-runtime`:隔离 OFDRW 2.4.0 与 PDFBox 2 的内部 shaded 运行时,不作为业务 API 使用。 - `file-convert-engine-ofd`:将 OFD 页面光栅化并写入预览 PDF 的视觉转换引擎。 - `file-convert-test-support`:视觉黄金样本的像素比较和跨引擎测试辅助能力。 - `file-convert-spring-boot-starter`:Spring Boot 4.1 自动配置、属性绑定、LibreOffice 生命周期和可选健康检查。 - `file-convert-spring-boot-host-smoke`:使用独立 Spring Boot 父项目执行启动、真实图片转换、Office 生命周期和 Actuator 健康检查的门禁夹具,不随 SDK 发布。 项目状态、设计、测试、风险、合规和历史证据的统一入口见[项目材料索引](docs/README.md)。当前代码可用性结论见[项目自检报告](docs/project-self-check-2026-08-18.md),当前源码的 JDK 25 Linux 与外部资源防护证据见[安全验证报告](docs/server-validation-2026-08-18-security.md),OFD 真实样本证据见[OFD 功能验证报告](docs/server-validation-2026-08-14-ofd.md),图片与 PDF 的有限并发数据见[性能验证报告](docs/server-validation-2026-08-17-performance.md)。 ## 当前可用能力 - DOC、DOCX、RTF、ODT 转 PDF。 - XLS、XLSX、ODS 转 PDF。 - PPT、PPTX、ODP 转 PDF。 - PNG、JPEG、TIFF 转 PDF;多页 TIFF 会生成多页 PDF。 - PDF 全部页面转 PNG 或 JPEG,使用目录承载有序产物集合。 - PNG、JPEG、BMP、静态 WebP 转 PNG、JPEG 或 TIFF 中不同于源格式的目标格式。 - 多页 TIFF 转 PNG 或 JPEG,使用目录按页发布;JPEG/TIFF 方向元数据归一化。 - OFD 转 PDF,用于浏览器预览;保留正文、图片、字体和印章外观,不验证数字签名或法律效力。 - PNG/TIFF 产物保留透明通道;转 JPEG 时使用可配置的不透明背景色;像素统一转换到 sRGB。 - 文件路径、目录和流产物目标,源格式自动检测;进入转换执行后的失败使用稳定错误码。 - `FileConverter` 可由多个线程并发调用;SDK 核心不设置统一并发上限,Office 容量由 LibreOffice 工作进程数决定。 Office 转换需要调用方所在环境安装 LibreOffice。SDK 不捆绑 LibreOffice 二进制文件,也不会在运行时下载软件。 Office 进程池仅使用动态分配的 IPv4 本机回环套接字,不依赖平台原生 `jpipe` 库,也不监听外部网络。端口在 LibreOffice 绑定前被其他进程抢占时启动失败,SDK 不会终止或接管其他 LibreOffice 进程。 Office 运行时显式使用 `UpdateDocMode.NO_UPDATE` 禁止文档链接更新,并默认把 `BlockUntrustedRefererLinks=true` 写入一次性模板用户配置,由 JODConverter 复制到每个工作进程。后者用于阻止不可信文档的导入过滤器绕过链接更新模式加载外部网络或本地文件资源。可通过 `blockExternalResources(false)` 或 Starter 属性 `file-convert.office.block-external-resources=false` 显式关闭;关闭后宿主必须自行承担外链内容访问、SSRF 和本地文件读取风险。该配置不改写输入文档,普通超链接文本仍可保留。 `ConversionRequest` 默认超时为 180 秒。Office 任务进入运行时前,剩余请求预算必须严格大于 `task-queue-timeout + task-execution-timeout`;默认配置对应 60 秒排队加 60 秒执行。不满足时返回 `CONVERSION_TIMEOUT`,且不会提交外部任务。该约束保证已提交任务的 JODConverter 排队与执行超时上界处于请求预算内,但不表示超时发生时 LibreOffice 进程会被即时终止。 2026-08-18 的当前源码已在 Linux/JDK 25/LibreOffice 24.2.7.2 断网隔离容器通过 13/13 Reactor 和 168 个测试(167 个 Surefire、1 个 OFD Failsafe),0 失败、0 错误、0 跳过;外部 HTTP 图片正向对照在关闭安全模板时产生请求,默认开启后请求数为 0。全部 28 条公开转换路径继续通过。2026-08-14 的真实 OFD 发票样本已完成 PDF 回读和人工外观复核;2026-08-17 的 Maven SBOM 高危漏洞扫描和图片/PDF 有限并发基线也已通过。Office 输入仍是同版本 LibreOffice 生成的最小合法样本;HTTP 黑盒也不等同于所有 `file://`、OOXML、ODF、RTF 外链语法均已覆盖。 Spring Boot 4.1 宿主可以只引入 `file-convert-spring-boot-starter` 并直接注入 `FileConverter`。PDF、图片、OFD 和 Tika 默认启用;Office 默认关闭,通过 `file-convert.office.enabled=true` 显式启用。OFD 的预览语义和字体要求见 [OFD 预览转换](docs/ofd-preview.md),完整配置见 [Starter 接入说明](docs/spring-boot-starter.md)。 ## Maven 接入 当前采用轻量的 Gitee Git Maven 仓库:发布构件存放在本仓库的 `maven` 分支,不依赖 Gitee 企业版制品库。业务项目先配置仓库: ```xml file-convert-gitee https://gitee.com/zfworkspace/file-convert/raw/maven/ false true always ``` Spring Boot 4.1 项目只需引入 Starter: ```xml io.github.fileconvert file-convert-spring-boot-starter 0.1.0-SNAPSHOT ``` 当前快照要求宿主使用 JDK 25。公开仓库读取不需要 Gitee 凭据;发布使用本机现有 Git 登录状态,不得把密码或 Token 写入 POM、脚本或仓库。完整门禁通过后,可在干净工作区执行: ```powershell .\scripts\publish-gitee-maven.ps1 -SkipTests ``` 不传 `-SkipTests` 时,发布命令会重新执行全部 Maven 测试。该方案用于当前业务项目接入和迭代;如果后续访问量、制品体积或权限管理需求明显增长,再迁移到 Nexus、Gitee 企业制品库或其他正式 Maven 私服。 ## 基本用法 ```java Path runtimeDirectory = Path.of("./work/libreoffice"); Path taskDirectory = Path.of("./work/tasks"); LibreOfficeEngineConfig officeConfig = LibreOfficeEngineConfig.builder() .workingDirectory(runtimeDirectory) .workerCount(2) .build(); try (JodConverterLibreOfficeRuntime runtime = new JodConverterLibreOfficeRuntime(officeConfig)) { runtime.start(); PdfBoxConversionEngine pdfEngine = new PdfBoxConversionEngine( PdfBoxEngineConfig.builder().build()); TwelveMonkeysImageConversionEngine imageEngine = new TwelveMonkeysImageConversionEngine( ImageEngineConfig.builder().build()); OfdVisualConversionEngine ofdEngine = new OfdVisualConversionEngine( OfdEngineConfig.builder().build()); FileConverter converter = new DefaultFileConverter( List.of(new LibreOfficeConversionEngine(runtime), pdfEngine, imageEngine, ofdEngine), new TikaFileFormatDetector(), taskDirectory, DefaultFileConverter.DEFAULT_MAX_INPUT_BYTES); ConversionResult result = converter.convert( Path.of("input.docx"), FileFormats.PDF, Path.of("output.pdf")); ConversionResult pages = converter.convertToDirectory( Path.of("input.pdf"), FileFormats.PNG, Path.of("rendered-pages")); for (ConversionArtifact page : pages.artifacts()) { LOGGER.info("转换产物生成完成,文件名:{},摘要:{}", page.fileName(), page.sha256()); } if (!pages.temporaryResourcesCleaned()) { // 转换成功但临时资源清理不完整,宿主应触发告警并安排清理。 LOGGER.warn("任务临时资源清理不完整,任务编号:{}", pages.taskId()); } } ``` 示例中的 `LOGGER` 由宿主使用的 SLF4J 日志实现提供;生产日志不得记录文件正文、敏感路径或凭据。 实际宿主应在应用启动时创建并启动一个长期复用的 LibreOffice 运行时,在应用停止时关闭它。不要为每次转换重复启动进程池。 路径输入会先复制为受大小和截止时间约束的任务快照,格式检测与引擎不会继续读取调用方原文件;符号链接输入被拒绝。引擎返回后,Core 会把候选产物复制为自己的校验快照,后续格式、大小、摘要和发布均以该快照为准。`convertToDirectory` 要求目标目录尚不存在。多页 PDF 和多页 TIFF 会按顺序生成 `page-0001.png`、`page-0002.png` 等文件;所有页面生成并校验成功后,才从目标文件系统的同父目录暂存路径整体移动到目标。目录移动禁止替换并发创建的目标,但 Java API 不对所有文件系统承诺移动的原子可见性。非覆盖单文件目标使用同目录硬链接执行独占创建,目标已被其他线程或进程创建时返回 `INVALID_REQUEST`,不会覆盖既有文件。单文件路径和输出流不接受多产物转换,输出流发布无法回滚已经写出的字节。 `ConversionRequest`、输入、输出和格式值对象的构造参数错误属于调用方编程错误,直接抛出 `NullPointerException` 或 `IllegalArgumentException`;请求成功构造并进入 `FileConverter.convert()` 后,转换失败统一抛出带稳定 `ConversionErrorCode` 的 `ConversionException`。 动画 WebP 需要处理画布位置、帧混合和处置方式,首版返回 `UNSUPPORTED_FILE_FEATURE`,不会把局部帧错误地当作完整图片输出。图片解码和编码在调用线程执行,超时与中断在帧边界及读写前后检查,底层单次 ImageIO 调用不提供硬中断保证。 ## 环境要求 - JDK 25 - Maven 3.9 或更高版本 - 源码、注释、日志和文档统一使用 UTF-8;注释与日志使用简体中文。根目录 `.mvn/jvm.config` 同时固定 Maven JVM 的文件与标准流编码,避免 Windows 默认 GBK 与独立工具 JVM 的 UTF-8 输出混合后产生乱码。 项目当前以 JDK 25 为发布基线,正式构建和运行需要 JDK 25。当前 Windows 开发机使用 Eclipse Temurin 25.0.4 完成了 OFD 增量构建和真实发票预览验证;Linux 隔离容器使用 Eclipse Temurin 25.0.1 完成了当前源码的全 Reactor 复验和同一 OFD 样本外观复核。 Office 集成测试会自动查找常见安装目录,也可以通过 `LIBREOFFICE_HOME` 指定安装目录。未安装 LibreOffice 时,12 个 Office 矩阵/配置复制用例和 1 个外部 HTTP 资源黑盒用例共 13 个测试会逐项明确标记为跳过。 ## 构建 ```bash mvn clean verify ``` 当前机器临时使用 JDK 17 验证时执行: ```bash mvn -Dmaven.compiler.release=17 clean verify ``` `verify` 同时执行依赖收敛、30% 模块级行覆盖率、SpotBugs Max/Low 和许可证允许列表校验,并在 `target/compliance` 生成 CycloneDX JSON/XML SBOM 与 `THIRD-PARTY.txt`。GitHub Actions 当前以 JDK 25 在 Linux 执行门禁,安装 LibreOffice 并对最终 SBOM 执行高危漏洞扫描;Windows JDK 25 验证作为后续交叉门禁。宿主安装的 LibreOffice 和字体不属于 Maven 依赖,必须在部署镜像级 SBOM 中另行记录。 ## 开源许可证 本项目采用 [GNU General Public License v3.0 only](LICENSE),SPDX 标识为 `GPL-3.0-only`。复制、修改或分发本项目及其衍生作品时必须遵守许可证中的源代码提供、许可证保留和相同许可证分发等要求。第三方依赖仍分别适用其自身许可证,构建生成的 `THIRD-PARTY.txt` 用于辅助审计;本说明不构成法律意见。