SKILL.md
唯讀
名稱
pdf-to-docx
描述
使用 pdf2docx 將 PDF 檔案轉換為可編輯的 Word 文件
版本
1.0
PDF 轉 Word 技能
概述
此技能可使用 pdf2docx(一個 Python 函式庫)將 PDF 轉換為可編輯的 Word 文件,保留版面、表格、圖片與文字格式。與 OCR 方案不同,pdf2docx 直接提取 PDF 原生內容,達到精準轉換。
使用方式
- 提供您要轉換的 PDF 檔案
- 可選擇指定頁面或轉換選項
- 我將為您轉換為可編輯的 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')
最佳實務
- 檢查 PDF 類型:原生 PDF 轉換效果優於掃描版
- 先預覽:先測試幾頁再進行完整轉換
- 處理表格:複雜表格可能需要手動調整
- 圖片品質:圖片以原始解析度提取
- 字型處理:部分字型可能被系統預設字型取代
常見模式
含進度條的轉換
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






