PDF 是办公文件里最难处理的格式——看似简单的提取文字、合并拆分用常规方法做起来都很麻烦。这篇讲几个最实用的 PDF 处理场景代码直接复制就能用。一、安装pipinstallpdfplumber PyPDF2# 两个库各有侧重搭配使用库擅长不擅长pdfplumber提取文字、表格精度高合并拆分 PDFPyPDF2合并、拆分、旋转、加密PDF提取表格不太行两个都装上各取所长。二、读取 PDF 文字1. 提取所有文字importpdfplumberwithpdfplumber.open(报告.pdf)aspdf:# 总页数print(f共{len(pdf.pages)}页)full_textfori,pageinenumerate(pdf.pages):textpage.extract_text()iftext:full_texttext\nprint(f第{i1}页:{len(text)}字符)# 保存成 txtwithopen(输出.txt,w,encodingutf-8)asf:f.write(full_text)2. 提取指定页面importpdfplumberwithpdfplumber.open(报告.pdf)aspdf:# 提取第 3-5 页页码从 0 开始foriinrange(2,5):pagepdf.pages[i]textpage.extract_text()print(f 第{i1}页 )print(text)3. 解决中文乱码问题PDF 中文提取乱码很常见试试这些方法importpdfplumberwithpdfplumber.open(报告.pdf)aspdf:forpageinpdf.pages:# 方法1直接提取textpage.extract_text()# 方法2如果乱码试试保留空白textpage.extract_text(x_tolerance3,y_tolerance3)# 方法3按行提取linespage.extract_text_lines()forlineinlines:print(line[text])如果还是乱码那说明 PDF 本身是扫描件图片型 PDF需要 OCR 识别后面会讲。三、提取 PDF 中的表格pdfplumber 提取表格精度很高比手动复制粘贴快 100 倍importpdfplumberimportpandasaspdwithpdfplumber.open(财务报表.pdf)aspdf:all_tables[]forpageinpdf.pages:tablespage.extract_tables()fortableintables:# table 是二维列表第一行通常是表头dfpd.DataFrame(table[1:],columnstable[0])all_tables.append(df)print(f找到 1 个表格{len(table)}行 ×{len(table[0])}列)# 合并所有表格并导出ifall_tables:resultpd.concat(all_tables,ignore_indexTrue)result.to_excel(表格数据.xlsx,indexFalse)print(f共提取{len(result)}行数据已导出到 表格数据.xlsx)实际案例提取每个月的财务报表 PDF → 自动汇总到 Excel → 每月省 30 分钟的重复劳动。四、合并多个 PDFfromPyPDF2importPdfMergerimportosdefmerge_pdfs(input_dir,output_file):合并一个文件夹下的所有 PDFmergerPdfMerger()# 按文件名排序保证顺序filessorted([fforfinos.listdir(input_dir)iff.endswith(.pdf)])forfinfiles:filepathos.path.join(input_dir,f)merger.append(filepath)print(f已添加:{f})merger.write(output_file)merger.close()print(f合并完成共{len(files)}个文件 →{output_file})# 使用merge_pdfs(要合并的PDF,合并结果.pdf)五、拆分 PDFfromPyPDF2importPdfReader,PdfWriterdefsplit_pdf(input_file,output_dir,pages_per_file10):按每N页一组拆分 PDFreaderPdfReader(input_file)total_pageslen(reader.pages)os.makedirs(output_dir,exist_okTrue)file_index1forstartinrange(0,total_pages,pages_per_file):writerPdfWriter()endmin(startpages_per_file,total_pages)forpage_numinrange(start,end):writer.add_page(reader.pages[page_num])output_filef{output_dir}/第{file_index}部分({start1}-{end}页).pdfwithopen(output_file,wb)asf:writer.write(f)print(f已生成:{output_file})file_index1# 使用每 20 页拆一份split_pdf(大文件.pdf,拆分输出,pages_per_file20)六、给 PDF 加密码fromPyPDF2importPdfReader,PdfWriterdefencrypt_pdf(input_file,password,output_fileNone):给 PDF 加上密码保护readerPdfReader(input_file)writerPdfWriter()forpageinreader.pages:writer.add_page(page)writer.encrypt(password)outputoutput_fileorinput_file.replace(.pdf,_加密.pdf)withopen(output,wb)asf:writer.write(f)print(f已加密:{output})returnoutput# 使用encrypt_pdf(合同.pdf,123456,合同_加密.pdf)七、处理扫描件 PDFOCR 识别如果 PDF 是扫描图片pdfplumber 提取不到文字需要用 OCRpipinstallpytesseract pillow# 还需要安装 Tesseract-OCR 引擎百度搜索下载importpytesseractfromPILimportImageimportpdfplumberimportiodefocr_pdf(pdf_path):OCR 识别扫描件 PDFwithpdfplumber.open(pdf_path)aspdf:full_textfori,pageinenumerate(pdf.pages):# 把 PDF 页面转成图片imgpage.to_image(resolution300)img_pathftemp_page_{i}.pngimg.save(img_path)# OCR 识别textpytesseract.image_to_string(Image.open(img_path),langchi_simeng)full_texttext\nprint(f第{i1}页识别完成{len(text)}字符)withopen(ocr_result.txt,w,encodingutf-8)asf:f.write(full_text)returnfull_text# 使用识别中文要下载中文语言包ocr_pdf(扫描件.pdf)注意OCR 识别需要安装 Tesseract-OCR 引擎Windows 用户下载安装包后要配置环境变量。中文识别还需要下载chi_sim语言包。八、常用场景速查表场景代码用哪个库提取文字page.extract_text()pdfplumber提取表格page.extract_tables()pdfplumber合并多个 PDFmerger.append(file)PyPDF2拆分 PDFwriter.add_page(page)PyPDF2加密码writer.encrypt(password)PyPDF2提取图片page.to_image()pdfplumberOCR 识别image_to_string()pytesseract旋转页面page.rotate(90)PyPDF2九、完整案例发票信息批量提取importpdfplumberimportpandasaspdimportosdefextract_invoice_info(pdf_path):从发票 PDF 中提取关键信息info{文件名:os.path.basename(pdf_path)}withpdfplumber.open(pdf_path)aspdf:textforpageinpdf.pages:textpage.extract_text()or# 用正则提取关键信息根据实际发票格式调整importre# 发票号码matchre.search(r发票号码[:]\s*(\d),text)info[发票号码]match.group(1)ifmatchelse# 开票日期matchre.search(r开票日期[:]\s*(\d{4}[-年]\d{1,2}[-月]\d{1,2}),text)info[开票日期]match.group(1)ifmatchelse# 金额matchre.search(r价税合计[:]\s*[¥]?([\d,]\.\d{2}),text)info[金额]match.group(1)ifmatchelse# 销售方名称matchre.search(r销售方[名称]?[:]\s*(.?)(?:\n|$),text)info[销售方]match.group(1).strip()ifmatchelsereturninfo# 批量处理所有 PDFpdf_dir发票文件夹results[]forfinos.listdir(pdf_dir):iff.endswith(.pdf):try:infoextract_invoice_info(os.path.join(pdf_dir,f))results.append(info)print(f已处理:{f})exceptExceptionase:print(f处理失败{f}:{e})# 导出到 Exceldfpd.DataFrame(results)df.to_excel(发票汇总.xlsx,indexFalse)print(f共处理{len(results)}份发票)总结PDF 自动化处理最难的不是技术而是不同的 PDF 格式差异太大有的是文字型、有的是扫描件、有的表格不规范。一篇 80% 的 PDF 用上面的代码能搞定剩下 20% 需要根据具体 PDF 格式微调参数。建议遇到新的 PDF 格式时先用pdfplumber打开看看结构再决定怎么提取。 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。