SKILL.md
readonly只读
name
pdf-to-docx
description
使用 pdf2docx 将 PDF 文件转换为可编辑的 Word 文档
version
1.0
PDF 转 Word 技能
概述
本技能支持使用 pdf2docx 将 PDF 转换为可编辑的 Word 文档。pdf2docx 是一个 Python 库,能够保留布局、表格、图像和文本格式。与基于 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()
# 或使用上下文管理器
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))
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






