# 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 一键部署。
---
## 页面样式
### 拖拽/上传即解析主页 (玻璃拟态统计面板)

### 效果 - 优化后 (双栏独立、英文字体无乱码、行高段距完美适配)

### 效果 - 优化前 (乱码严重、连字错乱、双栏布局断裂混淆)

---
## 解决的排版痛点与核心技术补丁
本项目在原生 `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) — 加速国内容器依赖构建