如何提升pdf2docx的PDF转DOCX转换速度?
PDF转DOCX大文件提速方案
问题说明
我用一段代码将PDF转成同路径同名的DOCX文件,但转换100页以上的大文件时耗时超1分钟,需要把时间控制在1分钟内。代码本身运行耗时不足1秒,我优先想用pdf2docx(它能保留格式、表格、颜色等内容),也接受其他可行方案。
最小可复现代码:
def pdf_to_word(pdf_path, docx_path): """用pdf2docx将PDF转成Word,方便后续解析成XML""" cv = Converter(pdf_path) cv.convert(docx_path, start=0, end=None) cv.close() pdf_to_word("example.pdf", "example.docx")
优化方案
基于pdf2docx的提速方法
- 多页并行处理:pdf2docx支持分页转换,可通过多进程拆分PDF页面同时转换,最后合并DOCX文件,能大幅缩短大文件转换时间。示例代码:
from pdf2docx import Converter from concurrent.futures import ProcessPoolExecutor import os from docx import Document from docxcompose.composer import Composer def convert_page_range(pdf_path, start, end, temp_docx): cv = Converter(pdf_path) cv.convert(temp_docx, start=start, end=end) cv.close() def merge_docxs(docx_list, output_path): if not docx_list: return master_doc = Document(docx_list[0]) composer = Composer(master_doc) for docx in docx_list[1:]: composer.append(Document(docx)) composer.save(output_path) # 清理临时文件 for docx in docx_list: os.remove(docx) def pdf_to_word_parallel(pdf_path, docx_path, page_chunk=20): # 获取总页数 cv = Converter(pdf_path) total_pages = len(cv.pages) cv.close() temp_files = [] with ProcessPoolExecutor() as executor: futures = [] # 按分片批量转换 for i in range(0, total_pages, page_chunk): start = i end = min(i + page_chunk, total_pages) temp_docx = f"temp_{start}_{end}.docx" temp_files.append(temp_docx) futures.append(executor.submit(convert_page_range, pdf_path, start, end, temp_docx)) # 等待所有转换任务完成 for future in futures: future.result() # 合并所有临时DOCX文件 merge_docxs(temp_files, docx_path) # 使用示例 pdf_to_word_parallel("example.pdf", "example.docx")
- 降低解析精度:如果对非核心格式要求不高,可关闭pdf2docx的复杂布局分析,在初始化Converter时传入
layout_analysis=False参数(需测试是否满足格式需求):
cv = Converter(pdf_path, layout_analysis=False)
替代解决方案
- PyMuPDF + python-docx组合:PyMuPDF解析PDF速度极快,虽然格式还原度略低于pdf2docx,但能覆盖基础格式、表格需求,适合对速度要求高的场景。示例代码:
import fitz from docx import Document from docx.shared import Pt def pdf_to_word_fitz(pdf_path, docx_path): doc = Document() # 设置默认字体和字号 doc.styles['Normal'].font.size = Pt(10) doc.styles['Normal'].font.name = 'Arial' with fitz.open(pdf_path) as pdf: for page in pdf: # 添加页面文本 text = page.get_text() doc.add_paragraph(text) # 提取并添加表格(简单示例,复杂表格需额外处理) tables = page.find_tables() for table in tables: table_obj = doc.add_table(rows=len(table.rows), cols=len(table.cols)) for i, row in enumerate(table.rows): for j, cell in enumerate(row.cells): table_obj.cell(i,j).text = cell.text doc.save(docx_path) # 使用示例 pdf_to_word_fitz("example.pdf", "example.docx")
- 调用外部工具:使用LibreOffice命令行工具,速度比纯Python库快,支持批量转换。可以用Python的
subprocess模块集成,命令示例:
libreoffice --headless --convert-to docx example.pdf
内容的提问来源于stack exchange,提问作者user30589464




