# pdf2docx-origin-test **Repository Path**: aylerh/pdf2docx-origin-test ## Basic Information - **Project Name**: pdf2docx-origin-test - **Description**: 介绍:(1)pdf2docx优化;(2)fastapi化;解决问题:(1)图片上字体丢失问题;(2)下标乱码问题;(3)图注、图片等无样式,全是正文;(4)连字问题;(5)内容缺失问题;优点:(1)效果好;速度快;缺点:(1)gpl; - **Primary Language**: Unknown - **License**: AGPL-3.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-01 - **Last Updated**: 2026-06-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PDF to DOCX 高精度高保真转换服务 > 基于 **FastAPI + pdf2docx** 的 PDF 转 Word(.docx)REST API 服务,集成了自主研发的**高精度版面修复与排版适配补丁体系**,通过 Docker Compose 一键部署。 --- ## 页面样式 ### 拖拽/上传即解析主页 (玻璃拟态统计面板) ![1](./images/1.png) ### 效果 - 优化后 (双栏独立、英文字体无乱码、行高段距完美适配) ![1-1](./images/1-1.png) ### 效果 - 优化前 (乱码严重、连字错乱、双栏布局断裂混淆) ![1-2](./images/1-2.png) --- ## 解决的排版痛点与核心技术补丁 本项目在原生 `pdf2docx`(0.5.8 内核)之上,开发了一套**零外部依赖、高精度的版面补丁重构体系**,彻底解决了学术论文、复杂报表等混合排版文档在转换时的核心硬伤: | 转换硬伤 / 痛点 | 本项目的修复机制 | 对应补丁文件 | | :--- | :--- | :--- | | **物理页码遗漏 & 边缘多余列干扰** | 识别并过滤页面边缘的物理页码文本块,防止其破坏双栏切分逻辑;在 DOCX 生成末尾,自动遍历 Section 动态注入 Word 原生 `PAGE` 域代码(指定起始页码),实现页码的原生显示与连续递增。 | [RawPageFitz.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/page/RawPageFitz.py)
[converter.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/converter.py) | | **折线图坐标轴文字截断 / 年份丢失** | 在折线图等 SVG 矢量图检测时,对 bbox 执行四周像素外扩(`x0-=30, y0-=12, x1+=15, y1+=25`),确保刻度、年份和 Y 轴标题完整截入生成的图片中。 | [Paths.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/shape/Paths.py) | | **图表文字在正文中二次重复显现** | 自动比对文字块与已识别的 SVG 折线图 bbox。若重合度超过 60% 则认定为图表标签(如年份、数值),在正文中进行物理过滤,避免在图片下方出现游离的多余字符。 | [RawPageFitz.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/page/RawPageFitz.py) | | **第一栏内容跑到第二栏 / Word页数超限** | Word 的默认行距与段距比 PDF 占用更多垂直空间,导致左栏底部段落被 Word 平衡列算法挤到右栏并撑出第二页。补丁通过引入段距微调系数(`0.45`)与行高压缩系数(`0.85`)精准压缩垂直空间,使 Word 与 PDF 页数 100% 同步(均为 1 页)。 | [TextBlock.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/text/TextBlock.py) | | **无边框表格误识别导致段落物理断裂** | 过滤无背景填充且无画线边框的虚假流式表格检测,释放困在虚假 Cell 内的文本并还原为正常的外部连续段落,解决如 `Just three` 处段落断裂问题。 | [TablesConstructor.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/table/TablesConstructor.py)
[TableBlock.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/table/TableBlock.py)
[Blocks.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/layout/Blocks.py) | | **行内序号与标题分离 / 列数错分** | 学术论文中的段落序号(如 `2.1`)与标题文本存在一定距离,极易被识别为两列,加之右栏从而被错判为 3 列导致 fallback 到单栏布局。补丁对小于 15.0pt 距离的水平 Line 元素进行强制列聚合,完美保留双栏排版。 | [RawPage.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/page/RawPage.py) | | **公式拉丁斜体/粗体字符乱码 (汉字溢出)** | PDF 提取时发生高位截断,致使公式中的 `e`、`B`、`A` 沦为 `푒`、`퐵`、`퐴` 等罕见字。补丁在 Run 生成级别将 `0xd400` 到 `0xd467` 范围汉字反向还原回英文字母。 | [TextSpan.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/text/TextSpan.py) | | **Unicode 下标乱码 & 化学式样式丢失** | 拦截并提取 Unicode 的 `₀` - `₉` 等原生下标字符,以及 `CO2` 等物理偏移的字形。在 Word 对应的 `run` 级别强制注入原生下标属性 `run.font.subscript = True` 并还原基准字符。 | [TextSpan.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/text/TextSpan.py)
[Line.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/text/Line.py) | | **英文排版右侧参差不齐 (对齐缺陷)** | 重构段落对齐方式,将原生的 `LEFT` 对齐全部自动映射为 Word 的 `JUSTIFY`(两端对齐),实现整齐划一的排版效果。 | [TextBlock.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/text/TextBlock.py) | | **图注与图片排版样式缺失** | 自动识别以 `Figure`, `Table`, `图`, `表` 开头的图注段落,自动应用内置的 `Caption` 样式并消除首行缩进;对图片段落应用 `CENTER`(居中对齐)并消除缩进。 | [TextBlock.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/patches/text/TextBlock.py) | | **浏览器下载中文文件名出现乱码** | 采用 RFC 5987 编码格式(`filename*=utf-8''`)输出响应头,原生支持现代浏览器下载非 ASCII (如中文) 文件名。 | [convert.py](file:///d:/ProjectWorkspace/docker-compose-projects/pdf2docx-origin-test/app/routers/convert.py) | --- ## 项目结构 ``` pdf2docx-origin-test/ ├── app/ │ ├── main.py # FastAPI 应用入口与静态模板挂载 │ ├── routers/ │ │ └── convert.py # PDF 转换路由 & 清理路由 │ └── templates/ │ └── index.html # Web UI 界面 (含玻璃拟态面板与文件清理触发) ├── patches/ # 针对 pdf2docx 内核的各个功能重构补丁 │ ├── text/ # 字符、字形与段落对齐补丁 │ ├── layout/ # 布局与块分配补丁 │ ├── table/ # 虚假表格过滤补丁 │ ├── page/ # 分栏切分与页码过滤补丁 │ ├── image/ # OpenCV 图像提取与文字包含限制补丁 │ ├── shape/ # SVG 图表提取与 Bbox 外扩补丁 │ └── converter.py # 转换控制器 (注入页码) ├── .env # 端口配置 ├── docker-compose.yml # 容器编排配置文件 ├── Dockerfile # 包含补丁覆盖逻辑的多阶段镜像构建文件 ├── readme.md └── requirements.txt ``` --- ## 快速开始 ### 前置条件 - Docker Desktop(已开启 WSL2 或 Hyper-V 后端) - PowerShell 5.1+ ### 1. 克隆并进入项目目录 ```powershell cd D:\ProjectWorkspace\docker-compose-projects\pdf2docx-origin-test ``` ### 2. 创建持久化数据目录 ```powershell New-Item -ItemType Directory -Force -Path "H:\docker-data\pdf2docx-origin-test-data\data" ``` ### 3. 构建镜像并启动服务 ```powershell docker compose up --build -d ``` ### 4. 访问 | 服务地址 | 功能说明 | | :--- | :--- | | `http://localhost:8123/` | Web 交互转换界面 (上传即解析、清空临时文件、解析指标动态统计) | | `http://localhost:8123/docs` | Swagger UI 接口文档,可直接测试各个 Endpoint | | `http://localhost:8123/redoc` | ReDoc 接口规格说明书 | --- ## REST API 接口说明 ### 1. `POST /api/v1/convert` - **说明**:上传 PDF 文件,后端解析完成后**直接返回**生成的 DOCX 文件流以供下载。 - **自定义响应头**(用于前端渲染玻璃拟态统计面板): - `X-Total-Pages`:PDF 总页数 - `X-Total-Time`:解析总耗时 (秒) - `X-Page-Time`:平均单页解析耗时 (秒/页) - **PowerShell 示例**: ```powershell $response = Invoke-WebRequest -Uri "http://localhost:8123/api/v1/convert" -Method Post -Form @{ file = Get-Item ".\example.pdf" } [System.IO.File]::WriteAllBytes("D:\output.docx", $response.Content) ``` ### 2. `POST /api/v1/convert/save` - **说明**:上传 PDF 文件,将 PDF 和生成的 DOCX 保存至 `/app/data` 持久化卷中,返回包含路径的 JSON 格式结果。 ### 3. `POST /api/v1/convert/clear` - **说明**:自动清理 `DATA_DIR` 中历史遗留的以 32 位 hex UUID 开头的转换临时 PDF 与 DOCX 文件,保持磁盘健康。 - 前端交互中,每次**页面刷新(Onload)**及**用户拖入或选择新文件上传**时,都会自动静默触发该接口清理临时碎片。 ### 4. `GET /api/v1/convert/list` - **说明**:以 JSON 格式列出数据目录中的所有现有文件。 --- ## 宿主机数据持久化 转换文件(PDF + DOCX)保存在宿主机路径: ``` H:\docker-data\pdf2docx-origin-test-data\data\ ``` 对应容器内路径:`/app/data`。 --- ## 致谢 - [pdf2docx](https://github.com/ArtifexSoftware/pdf2docx) — PDF 高保真转 DOCX 核心引擎 - [python-docx](https://github.com/python-openxml/python-docx) — Word 文档对象创建与底层 XML 控制 - [PyMuPDF (fitz)](https://github.com/pymupdf/PyMuPDF) — 高性能 PDF 文档解析器 - [FastAPI](https://github.com/tiangolo/fastapi) — 现代高性能 Python Web 框架 - [清华大学开源软件镜像站](https://mirrors.tuna.tsinghua.edu.cn) — 加速国内容器依赖构建