pdf-to-docx

pdf-to-docx

熱門

使用 pdf2docx 將 PDF 檔案轉換為可編輯的 Word 文件

310星標
68分支
更新於 2026/1/31
SKILL.md
唯讀
名稱
pdf-to-docx
描述

使用 pdf2docx 將 PDF 檔案轉換為可編輯的 Word 文件

版本
1.0

PDF 轉 Word 技能

概述

此技能可使用 pdf2docx(一個 Python 函式庫)將 PDF 轉換為可編輯的 Word 文件,保留版面、表格、圖片與文字格式。與 OCR 方案不同,pdf2docx 直接提取 PDF 原生內容,達到精準轉換。

使用方式

  1. 提供您要轉換的 PDF 檔案
  2. 可選擇指定頁面或轉換選項
  3. 我將為您轉換為可編輯的 Word 文件

範例提示:

  • "將這份 PDF 報告轉換為可編輯的 Word 文件"
  • "將這份 PDF 的第 1 到 5 頁轉成 Word 格式"
  • "將這份掃描文件提取為可編輯文字"
  • "將這份 PDF 合約轉成 Word 以便編輯"

領域知識

pdf2docx 基礎

from pdf2docx import Converter

# 基本轉換
cv = Converter('input.pdf')
cv.convert('output.docx')
cv.close()

# 或使用 context manager
with Converter('input.pdf') as cv:
    cv.convert('output.docx')

轉換選項

from pdf2docx import Converter

cv = Converter('input.pdf')

# 整份文件
cv.convert('output.docx')

# 指定頁面(0 為起始)
cv.convert('output.docx', start=0, end=5)

# 單頁
cv.convert('output.docx', pages=[0])

# 多個指定頁面
cv.convert('output.docx', pages=[0, 2, 4])

cv.close()

進階選項

from pdf2docx import Converter

cv = Converter('input.pdf')

cv.convert(
    'output.docx',
    start=0,                    # 起始頁(0 為起始)
    end=None,                   # 結束頁(None = 最後一頁)
    pages=None,                 # 指定頁面列表
    password=None,              # PDF 密碼(若加密)
    min_section_height=20.0,    # 區段最小高度
    connected_border_tolerance=0.5,  # 邊框偵測容差
    line_overlap_threshold=0.9, # 線條合併閾值
    line_break_width_ratio=0.5, # 換行偵測
    line_break_free_space_ratio=0.1,
    line_separate_threshold=5,  # 垂直線條分離
    new_paragraph_free_space_ratio=0.85,
    float_image_ignorable_gap=5,
    page_margin_factor_top=0.5,
    page_margin_factor_bottom=0.5,
)

cv.close()

處理不同類型的 PDF

原生 PDF(文字型)
# 原生 PDF 效果最佳
cv = Converter('native_pdf.pdf')
cv.convert('output.docx')
cv.close()
掃描 PDF(圖片型)
# 掃描 PDF 需先使用 OCR
# pdf2docx 對原生文字 PDF 效果最好
# 建議先使用 pytesseract 或 PaddleOCR

import pytesseract
from pdf2image import convert_from_path

# 將 PDF 頁面轉為圖片
images = convert_from_path('scanned.pdf')

# 對每頁進行 OCR
text = ''
for img in images:
    text += pytesseract.image_to_string(img)

# 再從文字建立 Word 文件

Python 整合

from pdf2docx import Converter
import os

def pdf_to_word(pdf_path, output_path=None, pages=None):
    """將 PDF 轉換為 Word 文件。"""
    if output_path is None:
        output_path = pdf_path.replace('.pdf', '.docx')
    
    cv = Converter(pdf_path)
    
    if pages:
        cv.convert(output_path, pages=pages)
    else:
        cv.convert(output_path)
    
    cv.close()
    
    return output_path

# 使用範例
result = pdf_to_word('document.pdf')
print(f"已建立:{result}")

批次轉換

from pdf2docx import Converter
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor

def convert_single(pdf_path, output_dir):
    """將單一 PDF 轉換為 Word。"""
    output_path = output_dir / pdf_path.with_suffix('.docx').name
    
    try:
        cv = Converter(str(pdf_path))
        cv.convert(str(output_path))
        cv.close()
        return f"成功:{pdf_path.name}"
    except Exception as e:
        return f"錯誤:{pdf_path.name} - {e}"

def batch_convert(input_dir, output_dir, max_workers=4):
    """轉換目錄中所有 PDF。"""
    input_path = Path(input_dir)
    output_path = Path(output_dir)
    output_path.mkdir(exist_ok=True)
    
    pdf_files = list(input_path.glob('*.pdf'))
    
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = [
            executor.submit(convert_single, pdf, output_path)
            for pdf in pdf_files
        ]
        
        for future in futures:
            print(future.result())

batch_convert('./pdfs', './word_docs')

解析 PDF 結構

from pdf2docx import Converter

def analyze_pdf(pdf_path):
    """在轉換前分析 PDF 結構。"""
    cv = Converter(pdf_path)
    
    for i, page in enumerate(cv.pages):
        print(f"第 {i+1} 頁:")
        print(f"  尺寸:{page.width} x {page.height}")
        print(f"  區塊數:{len(page.blocks)}")
        
        for block in page.blocks:
            if hasattr(block, 'text'):
                print(f"    文字區塊:{block.text[:50]}...")
            elif hasattr(block, 'image'):
                print(f"    圖片區塊")
    
    cv.close()

analyze_pdf('document.pdf')

最佳實務

  1. 檢查 PDF 類型:原生 PDF 轉換效果優於掃描版
  2. 先預覽:先測試幾頁再進行完整轉換
  3. 處理表格:複雜表格可能需要手動調整
  4. 圖片品質:圖片以原始解析度提取
  5. 字型處理:部分字型可能被系統預設字型取代

常見模式

含進度條的轉換

from pdf2docx import Converter

def convert_with_progress(pdf_path, output_path):
    """轉換 PDF 並顯示進度。"""
    cv = Converter(pdf_path)
    
    total_pages = len(cv.pages)
    print(f"正在轉換 {total_pages} 頁...")
    
    for i in range(total_pages):
        cv.convert(output_path, start=i, end=i+1)
        progress = (i + 1) / total_pages * 100
        print(f"進度:{progress:.1f}%")
    
    cv.close()
    print("轉換完成!")

僅提取表格

from pdf2docx import Converter
from docx import Document

def extract_tables_to_word(pdf_path, output_path):
    """僅從 PDF 提取表格至 Word。"""
    cv = Converter(pdf_path)
    
    # 先進行完整轉換
    temp_path = 'temp_full.docx'
    cv.convert(temp_path)
    cv.close()
    
    # 開啟並提取表格
    doc = Document(temp_path)
    new_doc = Document()
    
    for table in doc.tables:
        # 複製表格至新文件
        new_table = new_doc.add_table(rows=0, cols=len(table.columns))
        
        for row in table.rows:
            new_row = new_table.add_row()
            for i, cell in enumerate(row.cells):
                new_row.cells[i].text = cell.text
        
        new_doc.add_paragraph()  # 加入間距
    
    new_doc.save(output_path)
    os.remove(temp_path)

範例

範例 1:合約轉換

from pdf2docx import Converter
import os

def convert_contract(pdf_path):
    """將合約 PDF 轉換為可編輯的 Word 並附帶中繼資料。"""
    
    # 定義輸出路徑
    base_name = os.path.splitext(pdf_path)[0]
    output_path = f"{base_name}_editable.docx"
    
    # 轉換
    cv = Converter(pdf_path)
    
    # 檢查頁數
    page_count = len(cv.pages)
    print(f"正在處理 {page_count} 頁...")
    
    # 轉換所有頁面
    cv.convert(output_path)
    cv.close()
    
    print(f"已建立:{output_path}")
    print(f"檔案大小:{os.path.getsize(output_path) / 1024:.1f} KB")
    
    return output_path

# 使用範例
result = convert_contract('contract.pdf')

範例 2:選擇性頁面轉換

from pdf2docx import Converter

def convert_selected_pages(pdf_path, page_ranges, output_path):
    """將指定頁面範圍轉換為 Word。
    
    page_ranges: 元組列表,如 [(1, 3), (5, 7)] 代表第 1-3 頁與第 5-7 頁
    """
    cv = Converter(pdf_path)
    
    # 轉換頁面(內部以 0 為起始)
    all_pages = []
    for start, end in page_ranges:
        all_pages.extend(range(start - 1, end))  # 轉換為 0 起始
    
    cv.convert(output_path, pages=all_pages)
    cv.close()
    
    print(f"已轉換頁面:{page_ranges}")
    return output_path

# 轉換第 1-5 頁與第 10-15 頁
convert_selected_pages(
    'long_document.pdf',
    [(1, 5), (10, 15)],
    'selected_pages.docx'
)

範例 3:PDF 報告轉為可編輯範本

from pdf2docx import Converter
from docx import Document

def pdf_to_template(pdf_path, output_path):
    """將 PDF 報告轉換為 Word 範本,並加入佔位符。"""
    
    # 將 PDF 轉為 Word
    cv = Converter(pdf_path)
    cv.convert(output_path)
    cv.close()
    
    # 開啟並加入佔位符欄位
    doc = Document(output_path)
    
    # 將常見欄位替換為佔位符
    replacements = {
        'Company Name': '[COMPANY_NAME]',
        'Date:': 'Date: [DATE]',
        'Prepared by:': 'Prepared by: [AUTHOR]',
    }
    
    for para in doc.paragraphs:
        for old, new in replacements.items():
            if old in para.text:
                para.text = para.text.replace(old, new)
    
    # 也檢查表格
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for old, new in replacements.items():
                    if old in cell.text:
                        cell.text = cell.text.replace(old, new)
    
    doc.save(output_path)
    print(f"範本已建立:{output_path}")

pdf_to_template('annual_report.pdf', 'report_template.docx')

範例 4:大量發票處理

from pdf2docx import Converter
from pathlib import Path
import json

def process_invoices(input_folder, output_folder):
    """將 PDF 發票轉換為可編輯的 Word 文件。"""
    
    input_path = Path(input_folder)
    output_path = Path(output_folder)
    output_path.mkdir(exist_ok=True)
    
    results = []
    
    for pdf_file in input_path.glob('*.pdf'):
        output_file = output_path / pdf_file.with_suffix('.docx').name
        
        try:
            cv = Converter(str(pdf_file))
            cv.convert(str(output_file))
            cv.close()
            
            results.append({
                'file': pdf_file.name,
                'status': 'success',
                'output': str(output_file)
            })
            
        except Exception as e:
            results.append({
                'file': pdf_file.name,
                'status': 'error',
                'error': str(e)
            })
    
    # 儲存結果記錄
    with open(output_path / 'conversion_log.json', 'w') as f:
        json.dump(results, f, indent=2)
    
    # 摘要
    success = sum(1 for r in results if r['status'] == 'success')
    print(f"已轉換 {success}/{len(results)} 個檔案")
    
    return results

results = process_invoices('./invoices_pdf', './invoices_word')

限制

  • 掃描 PDF 需要 OCR 前處理
  • 複雜版面可能無法完美轉換
  • 部分字型可能無法使用
  • 浮水印會包含在轉換結果中
  • 受保護/加密的 PDF 需要密碼

安裝

pip install pdf2docx

# 圖片處理
pip install Pillow

資源