Back to skills
SkillHub ClubShip Full StackFull Stack

openakita/skills@translate-pdf

Translate PDF documents while preserving original layout, styling, tables, images, and formatting. Supports Simplified Chinese, Traditional Chinese, English, Japanese, Korean, and more. Page-by-page translation with structure preservation.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
1,319
Hot score
99
Updated
March 20, 2026
Overall rating
C4.6
Composite score
4.6
Best-practice grade
C57.6

Install command

npx @skill-hub/cli install openakita-openakita-translate-pdf

Repository

openakita/openakita

Skill path: skills/translate-pdf

Translate PDF documents while preserving original layout, styling, tables, images, and formatting. Supports Simplified Chinese, Traditional Chinese, English, Japanese, Korean, and more. Page-by-page translation with structure preservation.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: MIT.

Original source

Catalog source: SkillHub Club.

Repository owner: openakita.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install openakita/skills@translate-pdf into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openakita/openakita before adding openakita/skills@translate-pdf to shared team environments
  • Use openakita/skills@translate-pdf for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: openakita/skills@translate-pdf
description: Translate PDF documents while preserving original layout, styling, tables, images, and formatting. Supports Simplified Chinese, Traditional Chinese, English, Japanese, Korean, and more. Page-by-page translation with structure preservation.
license: MIT
metadata:
  author: openakita
  version: "1.0.0"
---

# Translate PDF — PDF 文档翻译

## When to Use

- 用户需要将英文 PDF 翻译为中文(或其他语言)
- 需要保留 PDF 的原始排版、表格、图片和格式
- 需要翻译学术论文、技术文档、商业报告
- 需要双语对照的 PDF 输出
- 需要批量翻译多个 PDF 文件

---

## Prerequisites

### 必需依赖

| 依赖 | 用途 | 安装方式 |
|------|------|---------|
| Python ≥ 3.10 | 运行翻译脚本 | 系统预装 |
| `PyMuPDF` (fitz) | PDF 解析与重建 | `pip install PyMuPDF` |
| `httpx` | HTTP API 调用 | `pip install httpx` |

### 可选依赖

| 依赖 | 用途 | 安装方式 |
|------|------|---------|
| `pdf2image` | PDF 转图片(OCR 场景) | `pip install pdf2image` |
| `pytesseract` | OCR 文字识别 | `pip install pytesseract` |
| `pdfplumber` | 表格提取 | `pip install pdfplumber` |
| `reportlab` | PDF 生成 | `pip install reportlab` |
| `deep-translator` | 多引擎翻译 | `pip install deep-translator` |
| `openai` | GPT 翻译 | `pip install openai` |

### 系统级依赖

| 工具 | 用途 | 说明 |
|------|------|------|
| Poppler | pdf2image 的后端 | Windows: 下载 poppler-utils; macOS: `brew install poppler` |
| Tesseract | OCR 引擎 | Windows: 下载安装包; macOS: `brew install tesseract` |
| 中文字体 | PDF 中文渲染 | 系统需安装中文字体(微软雅黑、思源黑体等) |

### 验证安装

```bash
python -c "import fitz; print('PyMuPDF', fitz.version)"
python -c "import pdfplumber; print('pdfplumber OK')"
```

### LLM API 配置

翻译引擎首选 LLM(GPT-4 / Claude),在 `.env` 中配置:

```
OPENAI_API_KEY=sk-xxxxx
```

如果未配置 LLM API,将回退到 `deep-translator`(Google Translate / DeepL)。

---

## Instructions

### 支持的语言

| 语言代码 | 语言 | 翻译质量 |
|---------|------|---------|
| `zh-CN` | 简体中文 | ★★★★★ |
| `zh-TW` | 繁体中文 | ★★★★★ |
| `en` | 英文 | ★★★★★ |
| `ja` | 日文 | ★★★★ |
| `ko` | 韩文 | ★★★★ |
| `fr` | 法文 | ★★★★ |
| `de` | 德文 | ★★★★ |
| `es` | 西班牙文 | ★★★★ |
| `ru` | 俄文 | ★★★ |
| `ar` | 阿拉伯文 | ★★★ |

### 翻译引擎优先级

| 优先级 | 引擎 | 特点 |
|--------|------|------|
| 1 | LLM (GPT-4/Claude) | 最高质量,理解上下文,术语一致 |
| 2 | DeepL API | 高质量机器翻译 |
| 3 | Google Translate | 免费,覆盖语种广 |

Agent 按照优先级自动选择可用的翻译引擎。用户可以指定使用特定引擎。

### PDF 元素处理策略

| 元素 | 处理方式 |
|------|---------|
| 正文文本 | 翻译并保留字体大小、颜色、粗体/斜体 |
| 标题 | 翻译并保留层级和样式 |
| 表格 | 翻译单元格内容,保留表格结构 |
| 图片 | 保留原图不动 |
| 图片中的文字 | 可选 OCR 识别后翻译 |
| 页眉/页脚 | 翻译并保持位置 |
| 页码 | 保持不变 |
| 脚注/尾注 | 翻译内容,保留编号 |
| 目录 | 翻译条目,页码不变 |
| 书签 | 翻译标题 |
| 链接/URL | 保持不变 |
| 数学公式 | 保持不变 |
| 代码块 | 保持不变(仅翻译注释) |
| 水印 | 保留原样 |

---

## Workflows

### Workflow 1: 标准 PDF 翻译

**步骤 1 — 解析 PDF 结构**

```python
import fitz

doc = fitz.open("input.pdf")
print(f"总页数: {doc.page_count}")
print(f"元数据: {doc.metadata}")

for page_num in range(min(3, doc.page_count)):
    page = doc[page_num]
    text = page.get_text("dict")
    print(f"第 {page_num + 1} 页: {len(text['blocks'])} 个文本块")
```

**步骤 2 — 逐页提取文本块**

```python
def extract_text_blocks(page):
    """提取页面中所有文本块及其位置和样式"""
    blocks = []
    text_dict = page.get_text("dict")

    for block in text_dict["blocks"]:
        if block["type"] == 0:  # text block
            for line in block["lines"]:
                for span in line["spans"]:
                    blocks.append({
                        "text": span["text"],
                        "bbox": span["bbox"],
                        "font": span["font"],
                        "size": span["size"],
                        "color": span["color"],
                        "flags": span["flags"],
                    })
    return blocks
```

**步骤 3 — 批量翻译**

将提取的文本按段落分组,批量发送给翻译引擎:

```python
async def translate_blocks(blocks, target_lang="zh-CN"):
    paragraphs = merge_spans_to_paragraphs(blocks)

    translated = []
    for batch in chunk_list(paragraphs, batch_size=20):
        texts = [p["text"] for p in batch]
        results = await batch_translate(texts, target_lang)
        translated.extend(results)

    return translated
```

**LLM 翻译 Prompt**

```
你是一位专业的文档翻译师。请将以下文本从{source_lang}翻译为{target_lang}。

要求:
1. 保持专业术语的准确性和一致性
2. 保持段落结构不变
3. 对于技术术语,首次出现时附上原文:如"卷积神经网络(CNN)"
4. 不翻译代码、公式、URL、人名(除非有通用中文译名)
5. 保持原文的语气和风格

待翻译文本:
---
{text}
---
```

**步骤 4 — 重建 PDF**

```python
def rebuild_pdf(original_doc, translated_blocks, output_path):
    """用翻译后的文本替换原文,保留排版"""
    new_doc = fitz.open()

    for page_num in range(original_doc.page_count):
        orig_page = original_doc[page_num]
        new_page = new_doc.new_page(
            width=orig_page.rect.width,
            height=orig_page.rect.height
        )

        # 复制图片和非文本元素
        new_page.show_pdf_page(new_page.rect, original_doc, page_num)

        # 覆盖原文区域并写入译文
        for block in translated_blocks[page_num]:
            rect = fitz.Rect(block["bbox"])
            new_page.draw_rect(rect, color=None, fill=(1, 1, 1))
            new_page.insert_textbox(
                rect,
                block["translated_text"],
                fontsize=block["size"] * 0.85,
                fontname="china-ss",
                align=fitz.TEXT_ALIGN_LEFT
            )

    new_doc.save(output_path)
```

**步骤 5 — 质量检查**

翻译完成后执行自动检查:
- 页数与原文一致
- 无空白页面
- 翻译覆盖率(已翻译文本 / 总文本 ≥ 95%)
- 字体渲染正常

---

### Workflow 2: 双语对照 PDF

生成左右/上下对照的双语 PDF:

**布局选项**

| 布局 | 说明 | 适用场景 |
|------|------|---------|
| 左右对照 | 左页原文、右页译文 | 学术论文、对比审阅 |
| 上下对照 | 段落级交替显示 | 学习材料 |
| 注释模式 | 译文作为侧边注释 | 保留原文为主 |

```python
def create_bilingual_pdf(original_doc, translated_blocks, output_path, layout="side-by-side"):
    new_doc = fitz.open()

    for page_num in range(original_doc.page_count):
        orig_page = original_doc[page_num]

        if layout == "side-by-side":
            new_width = orig_page.rect.width * 2
            new_page = new_doc.new_page(
                width=new_width,
                height=orig_page.rect.height
            )
            # 左侧放原文
            new_page.show_pdf_page(
                fitz.Rect(0, 0, orig_page.rect.width, orig_page.rect.height),
                original_doc, page_num
            )
            # 右侧放译文
            insert_translated_page(
                new_page,
                translated_blocks[page_num],
                offset_x=orig_page.rect.width
            )

    new_doc.save(output_path)
```

---

### Workflow 3: 扫描版 PDF 翻译(OCR)

处理扫描件或图片型 PDF:

**步骤 1 — 检测 PDF 类型**

```python
def is_scanned_pdf(doc):
    """检测 PDF 是否为扫描件"""
    for page_num in range(min(3, doc.page_count)):
        page = doc[page_num]
        text = page.get_text().strip()
        images = page.get_images()
        if not text and images:
            return True
    return False
```

**步骤 2 — OCR 识别**

```python
from pdf2image import convert_from_path
import pytesseract

images = convert_from_path("scanned.pdf", dpi=300)
for i, img in enumerate(images):
    text = pytesseract.image_to_string(img, lang='eng')
    # 使用 image_to_data 获取文字位置信息
    data = pytesseract.image_to_data(img, lang='eng', output_type=pytesseract.Output.DICT)
```

**步骤 3** — 对 OCR 结果执行 Workflow 1 的翻译和重建流程

---

### Workflow 4: 批量 PDF 翻译

```python
import glob
import asyncio

async def batch_translate_pdfs(input_dir, output_dir, target_lang="zh-CN"):
    pdf_files = glob.glob(f"{input_dir}/*.pdf")
    print(f"发现 {len(pdf_files)} 个 PDF 文件")

    for pdf_path in pdf_files:
        output_path = os.path.join(
            output_dir,
            os.path.basename(pdf_path).replace('.pdf', f'_{target_lang}.pdf')
        )
        print(f"翻译: {pdf_path} -> {output_path}")
        await translate_single_pdf(pdf_path, output_path, target_lang)
```

---

## Output Format

### 文件命名

```
{原文件名}_{目标语言}.pdf
```

示例:
- `research_paper_zh-CN.pdf`(翻译版)
- `research_paper_bilingual.pdf`(双语版)

### 输出报告

```
📄 PDF 翻译完成
- 原文件:research_paper.pdf (25 页)
- 译文件:research_paper_zh-CN.pdf (25 页)
- 源语言:English → 目标语言:简体中文
- 翻译引擎:GPT-4
- 翻译覆盖率:98.5%
- 表格数量:12 个(已翻译)
- 图片数量:8 张(已保留)
- 耗时:3 分 42 秒
- 费用估算:$0.85
```

---

## Common Pitfalls

### 1. 中文字体缺失导致乱码

**症状**:翻译后的 PDF 中文显示为方框或乱码
**解决**:确保系统安装了中文字体,并在 PyMuPDF 中注册:

```python
import fitz

# PyMuPDF 支持的中文字体
# "china-ss" = 思源宋体 (简体)
# "china-ts" = 思源宋体 (繁体)
# 或使用自定义字体
page.insert_font(fontname="custom-zh", fontfile="/path/to/NotoSansCJK-Regular.ttf")
```

### 2. 表格翻译后错位

**症状**:表格内容溢出单元格
**原因**:中文译文通常比英文短,但某些情况下可能更长
**解决**:
- 动态调整字体大小以适应单元格
- 允许文本自动换行
- 对于复杂表格,使用 pdfplumber 提取后单独翻译

### 3. 数学公式被错误翻译

**症状**:公式被当作文本翻译
**解决**:在翻译前识别并标记数学公式区域,跳过翻译:

```python
import re

def should_skip_translation(text):
    """判断文本是否应跳过翻译"""
    # 数学公式模式
    if re.match(r'^[\s\d\+\-\*\/\=\(\)\[\]\{\}\^\_\\\$]+$', text):
        return True
    # LaTeX 公式
    if text.strip().startswith('\\') and not text.strip().startswith('\\text'):
        return True
    # 代码块
    if re.match(r'^(def |class |import |from |const |let |var |function )', text.strip()):
        return True
    return False
```

### 4. 大文件内存溢出

**症状**:处理超过 100 页的大型 PDF 时内存不足
**解决**:逐页处理而非一次性加载:

```python
for page_num in range(doc.page_count):
    page = doc[page_num]
    # 处理当前页
    process_page(page)
    # 释放内存
    page = None
```

### 5. OCR 识别率低

**症状**:扫描版 PDF 的文字识别错误多
**解决**:
- 提高扫描 DPI(≥ 300)
- 预处理图片(二值化、去噪、倾斜校正)
- 使用语言包:`pytesseract.image_to_string(img, lang='eng+chi_sim')`

### 6. 翻译术语不一致

**症状**:同一术语在不同页面有不同翻译
**解决**:
- 第一遍扫描时建立术语表
- 将术语表作为上下文传递给 LLM
- 翻译后用脚本检查术语一致性

```python
glossary = {
    "machine learning": "机器学习",
    "neural network": "神经网络",
    "gradient descent": "梯度下降",
    "backpropagation": "反向传播",
}
```

### 7. 页眉页脚重复翻译

**症状**:每页的页眉页脚翻译结果微有差异
**解决**:先识别页眉页脚模式,统一翻译一次后应用到所有页面

---

## 高级配置

### 翻译质量等级

| 等级 | 方式 | 速度 | 质量 | 费用 |
|------|------|------|------|------|
| 快速 | Google Translate | ★★★★★ | ★★★ | 免费 |
| 标准 | DeepL | ★★★★ | ★★★★ | $$ |
| 专业 | GPT-4 | ★★★ | ★★★★★ | $$$ |
| 人机协作 | GPT-4 + 人工审校 | ★★ | ★★★★★+ | $$$$ |

### 自定义术语表

用户可提供术语表文件(CSV/JSON)确保特定术语的翻译一致:

```json
{
  "source_lang": "en",
  "target_lang": "zh-CN",
  "terms": {
    "OpenAkita": "OpenAkita",
    "Agent": "智能体",
    "fine-tuning": "微调",
    "prompt engineering": "提示词工程"
  }
}
```

---

## EXTEND.md 扩展

用户可在技能同目录下创建 `EXTEND.md` 添加:
- 行业专用术语表
- 首选翻译引擎和质量等级
- 自定义字体路径
- PDF 模板和样式覆盖规则
- 特定文档类型的预处理规则
openakita/skills@translate-pdf | SkillHub