文章目录
- 一个真实的PDF文件主要由四大部分构成,分别是文件头(Header)、文件主体(Body)、交叉引用表(Cross-Reference Table)和文件尾(Trailer)。了解这些基本结构有助于我们更好地处理PDF文件。
- pip install pymupdf
- pymupdf库(也称为fitz)可以轻松实现对PDF文件的读写操作。以下是提取PDF文本内容的示例: import fitz # pymupdf的导入名称是fitz def extract_text_from_pdf(pdf_path): “””从PDF文件中提取所有文本内容””” # 打开PDF文件 doc = fitz.open(pdf_path) # 创建一个空字符串用于存储文本内容 text = “” # 遍历每一页 for page_num in range(len(doc)): # 获取当前页面 page = doc[page_num] # 提取文本 page_text = page.get_text() # 添加页码信息和页面文本 text += f”n— 第 {page_num + 1} 页 —n” text += page_text # 关闭文档 doc.close() return text # 使用示例 pdf_path = “example.pdf” # 替换为实际的PDF文件路径 try: extracted_text = extract_text_from_pdf(pdf_path) print(“提取的文本内容:”) print(extracted_text[:500] + “…” if len(extracted_text) > 500 else extracted_text) # 将提取的文本保存到文件 with open(“extracted_text.txt”, “w”, encoding=”utf-8″) as f: f.write(extracted_text) print(“文本已保存到 extracted_text.txt”) except Exception as e: print(f”提取文本时出错: {e}”)
- 一个PDF文件通常会包含图像元素,图像作为PDF文件中的对象也会记录在交叉引用表中。在pymupdf库中,可以通过相应的方法获取交叉引用表中记录的对象ID编号,并将其称为xref整数。 import fitz import os def extract_images_from_pdf(pdf_path, output_folder=”extracted_images”): “””从PDF文件中提取所有图像””” # 确保输出文件夹存在 if not os.path.exists(output_folder): os.makedirs(output_folder) # 打开PDF文件 doc = fitz.open(pdf_path) # 用于记录提取的图像数量 image_count = 0 # 遍历每一页 for page_num in range(len(doc)): # 获取当前页面 page = doc[page_num] # 获取页面上的图像列表 image_list = page.get_images() # 遍历图像列表 for img_index, img in enumerate(image_list): # 获取图像的xref xref = img[0] # 获取图像信息 base_image = doc.extract_image(xref) image_bytes = base_image[“image”] image_ext = base_image[“ext”] # 生成输出文件名 output_filename = f”{output_folder}/page{page_num + 1}_img{img_index + 1}.{image_ext}” # 保存图像 with open(output_filename, “wb”) as f: f.write(image_bytes) image_count += 1 # 关闭文档 doc.close() return image_count # 使用示例 pdf_path = “example.pdf” # 替换为实际的PDF文件路径 try: num_images = extract_images_from_pdf(pdf_path) print(f”成功提取了 {num_images} 张图像到 ‘extracted_images’ 文件夹”) except Exception as e: print(f”提取图像时出错: {e}”)
- import fitz def add_watermark_to_pdf(input_pdf, output_pdf, watermark_text): “””为PDF文件添加文字水印””” # 打开PDF文件 doc = fitz.open(input_pdf) # 遍历每一页 for page_num in range(len(doc)): # 获取当前页面 page = doc[page_num] # 获取页面尺寸 rect = page.rect # 创建一个透明的水印文本 # 设置字体大小、颜色和透明度 text_color = (0.5, 0.5, 0.5) # 灰色 alpha = 0.3 # 透明度 fontsize = 24 # 在页面中心添加水印 tw = fitz.TextWriter(rect) tw.append((rect.width/2, rect.height/2), watermark_text, fontsize=fontsize, color=text_color) tw.write_text(page, opacity=alpha) # 保存修改后的PDF doc.save(output_pdf) doc.close() return output_pdf # 使用示例 input_pdf = “example.pdf” # 替换为实际的PDF文件路径 output_pdf = “watermarked.pdf” watermark_text = “机密文件 – 请勿外传” try: result_pdf = add_watermark_to_pdf(input_pdf, output_pdf, watermark_text) print(f”已成功添加水印并保存为: {result_pdf}”) except Exception as e: print(f”添加水印时出错: {e}”)
- pip install pdfplumber
- pdfplumber库提供的extract_table方法可以轻松提取PDF文件中某页的所有表格,对于缺少边界的表格,pdfplumber库会利用文本位置信息进行猜测,从而定位出不可见边界的位置。 import pdfplumber import pandas as pd def extract_tables_from_pdf(pdf_path): “””从PDF文件中提取所有表格””” # 打开PDF文件 with pdfplumber.open(pdf_path) as pdf: all_tables = [] # 遍历每一页 for page_num, page in enumerate(pdf.pages): # 提取表格 tables = page.extract_tables() if tables: print(f”在第 {page_num + 1} 页找到 {len(tables)} 个表格”) # 处理每个表格 for table_num, table in enumerate(tables): # 创建DataFrame df = pd.DataFrame(table[1:], columns=table[0]) # 添加页码和表格编号信息 df[‘页码’] = page_num + 1 df[‘表格编号’] = table_num + 1 all_tables.append(df) else: print(f”在第 {page_num + 1} 页没有找到表格”) # 如果找到了表格,合并所有表格 if all_tables: combined_df = pd.concat(all_tables, ignore_index=True) return combined_df else: return None # 使用示例 pdf_path = “example_with_tables.pdf” # 替换为包含表格的PDF文件路径 try: tables_df = extract_tables_from_pdf(pdf_path) if tables_df is not None: print(“n提取的表格数据:”) print(tables_df.head()) # 将表格数据保存到Excel文件 excel_path = “extracted_tables.xlsx” tables_df.to_excel(excel_path, index=False) print(f”表格数据已保存到: {excel_path}”) else: print(“未在PDF中找到任何表格”) except Exception as e: print(f”提取表格时出错: {e}”)
- pip install PyPDF2
- from PyPDF2 import PdfMerger def merge_pdfs(pdf_files, output_path): “””合并多个PDF文件””” merger = PdfMerger() # 添加每个PDF文件 for pdf in pdf_files: try: merger.append(pdf) print(f”已添加: {pdf}”) except Exception as e: print(f”添加 {pdf} 时出错: {e}”) # 保存合并后的PDF merger.write(output_path) merger.close() return output_path # 使用示例 pdf_files = [“document1.pdf”, “document2.pdf”, “document3.pdf”] # 替换为实际的PDF文件路径 output_path = “merged_document.pdf” try: result_path = merge_pdfs(pdf_files, output_path) print(f”已成功合并PDF文件并保存为: {result_path}”) except Exception as e: print(f”合并PDF文件时出错: {e}”)
- from PyPDF2 import PdfReader, PdfWriter import os def split_pdf(input_pdf, output_folder=”split_pages”): “””将PDF文件拆分为单页文件””” # 确保输出文件夹存在 if not os.path.exists(output_folder): os.makedirs(output_folder) # 打开PDF文件 reader = PdfReader(input_pdf) total_pages = len(reader.pages) # 获取文件名(不含扩展名) base_name = os.path.splitext(os.path.basename(input_pdf))[0] # 拆分每一页 for page_num in range(total_pages): writer = PdfWriter() writer.add_page(reader.pages[page_num]) # 生成输出文件名 output_filename = f”{output_folder}/{base_name}_page_{page_num + 1}.pdf” # 保存单页PDF with open(output_filename, “wb”) as output_file: writer.write(output_file) print(f”已保存第 {page_num + 1} 页到: {output_filename}”) return total_pages # 使用示例 input_pdf = “example.pdf” # 替换为实际的PDF文件路径 try: num_pages = split_pdf(input_pdf) print(f”已成功将 {input_pdf} 拆分为 {num_pages} 个单页PDF文件”) except Exception as e: print(f”拆分PDF文件时出错: {e}”)
- from PyPDF2 import PdfReader, PdfWriter def encrypt_pdf(input_pdf, output_pdf, password): “””加密PDF文件””” reader = PdfReader(input_pdf) writer = PdfWriter() # 复制所有页面 for page in reader.pages: writer.add_page(page) # 设置密码和加密选项 writer.encrypt(password) # 保存加密后的PDF with open(output_pdf, “wb”) as output_file: writer.write(output_file) return output_pdf def decrypt_pdf(input_pdf, output_pdf, password): “””解密PDF文件””” reader = PdfReader(input_pdf) # 检查PDF是否加密 if reader.is_encrypted: # 尝试使用密码解密 if reader.decrypt(password) != 1: raise ValueError(“密码不正确”) else: print(“警告: 输入的PDF文件未加密”) writer = PdfWriter() # 复制所有页面 for page in reader.pages: writer.add_page(page) # 保存解密后的PDF with open(output_pdf, “wb”) as output_file: writer.write(output_file) return output_pdf # 使用示例 – 加密 input_pdf = “example.pdf” # 替换为实际的PDF文件路径 encrypted_pdf = “encrypted_document.pdf” password = “secure123″ # 设置密码 try: result_path = encrypt_pdf(input_pdf, encrypted_pdf, password) print(f”已成功加密PDF文件并保存为: {result_path}”) except Exception as e: print(f”加密PDF文件时出错: {e}”) # 使用示例 – 解密 decrypted_pdf = “decrypted_document.pdf” try: result_path = decrypt_pdf(encrypted_pdf, decrypted_pdf, password) print(f”已成功解密PDF文件并保存为: {result_path}”) except Exception as e: print(f”解密PDF文件时出错: {e}”)
- 1.首先,需要安装wkhtmltopdf工具: 在macOS上:brew install wkhtmltopdf 在Windows上:从官方网站下载安装程序 在Linux上:sudo apt-get install wkhtmltopdf(Ubuntu/Debian)或 sudo yum install wkhtmltopdf(CentOS/RHEL) 2.然后,安装pdfkit Python库: pip install pdfkit
- import pdfkit def url_to_pdf(url, output_pdf): “””将URL指向的网页转换为PDF””” try: # 配置wkhtmltopdf路径(如果不在系统PATH中) # config = pdfkit.configuration(wkhtmltopdf=’/path/to/wkhtmltopdf’) # pdfkit.from_url(url, output_pdf, configuration=config) # 如果wkhtmltopdf在系统PATH中 pdfkit.from_url(url, output_pdf) print(f”已成功将 {url} 转换为PDF: {output_pdf}”) return output_pdf except Exception as e: print(f”转换网页到PDF时出错: {e}”) return None def html_to_pdf(html_file, output_pdf): “””将HTML文件转换为PDF””” try: pdfkit.from_file(html_file, output_pdf) print(f”已成功将 {html_file} 转换为PDF: {output_pdf}”) return output_pdf except Exception as e: print(f”转换HTML文件到PDF时出错: {e}”) return None def html_string_to_pdf(html_content, output_pdf): “””将HTML字符串转换为PDF””” try: pdfkit.from_string(html_content, output_pdf) print(f”已成功将HTML内容转换为PDF: {output_pdf}”) return output_pdf except Exception as e: print(f”转换HTML字符串到PDF时出错: {e}”) return None # 使用示例 – 从URL创建PDF url = “https://www.example.com” # 替换为实际的URL output_pdf = “webpage.pdf” url_to_pdf(url, output_pdf) # 使用示例 – 从HTML文件创建PDF html_file = “example.html” # 替换为实际的HTML文件路径 output_pdf = “from_html_file.pdf” html_to_pdf(html_file, output_pdf) # 使用示例 – 从HTML字符串创建PDF html_content = “””<!DOCTYPE html> <html> <head> <title>测试页面</title> </head> <body> <h1>Hello, World!</h1> <p>这是一个由HTML字符串生成的PDF文档。</p> </body> </html>””” output_pdf = “from_html_string.pdf” html_string_to_pdf(html_content, output_pdf)
- 除了转换为PDF,wkhtmltoimage工具(wkhtmltopdf的一部分)还可以将网页转换为图片: import subprocess def url_to_image(url, output_image): “””将URL指向的网页转换为图片””” try: # 执行wkhtmltoimage命令 command = [“wkhtmltoimage”, url, output_image] subprocess.run(command, check=True) print(f”已成功将 {url} 转换为图片: {output_image}”) return output_image except subprocess.CalledProcessError as e: print(f”转换网页到图片时出错: {e}”) return None except Exception as e: print(f”发生错误: {e}”) return None # 使用示例 url = “https://www.example.com” # 替换为实际的URL output_image = “webpage.jpg” url_to_image(url, output_image)
- from docx2pdf import convert def word_to_pdf(input_docx, output_pdf=None): “””将Word文档转换为PDF””” try: # 如果未指定输出PDF路径,则使用相同的文件名但扩展名为.pdf if output_pdf is None: output_pdf = input_docx.replace(“.docx”, “.pdf”) # 转换Word文档为PDF convert(input_docx, output_pdf) print(f”已成功将 {input_docx} 转换为PDF: {output_pdf}”) return output_pdf except Exception as e: print(f”转换Word到PDF时出错: {e}”) return None # 使用示例 input_docx = “example.docx” # 替换为实际的Word文档路径 word_to_pdf(input_docx)
- import win32com.client import os def excel_to_pdf(input_excel, output_pdf=None): “””将Excel文件转换为PDF(仅适用于Windows系统)””” try: # 如果未指定输出PDF路径,则使用相同的文件名但扩展名为.pdf if output_pdf is None: output_pdf = input_excel.replace(“.xlsx”, “.pdf”).replace(“.xls”, “.pdf”) # 获取绝对路径 input_excel = os.path.abspath(input_excel) output_pdf = os.path.abspath(output_pdf) # 创建Excel应用程序实例 excel = win32com.client.Dispatch(“Excel.Application”) excel.Visible = False # 打开Excel文件 workbook = excel.Workbooks.Open(input_excel) # 将工作簿导出为PDF workbook.ExportAsFixedFormat(0, output_pdf) # 关闭工作簿和Excel应用程序 workbook.Close() excel.Quit() print(f”已成功将 {input_excel} 转换为PDF: {output_pdf}”) return output_pdf except Exception as e: print(f”转换Excel到PDF时出错: {e}”) return None # 使用示例(仅适用于Windows系统) # input_excel = “example.xlsx” # 替换为实际的Excel文件路径 # excel_to_pdf(input_excel)
- import os import fitz import re from datetime import datetime import pandas as pd def process_invoice_pdfs(invoice_folder, output_excel): “””批量处理发票PDF,提取关键信息并生成汇总表””” # 存储提取的发票信息 invoices_data = [] # 获取文件夹中的所有PDF文件 pdf_files = [f for f in os.listdir(invoice_folder) if f.lower().endswith(‘.pdf’)] for pdf_file in pdf_files: pdf_path = os.path.join(invoice_folder, pdf_file) print(f”处理: {pdf_path}”) try: # 打开PDF文件 doc = fitz.open(pdf_path) # 提取第一页文本(假设发票信息在第一页) text = doc[0].get_text() # 使用正则表达式提取关键信息 # 注意:以下正则表达式需要根据实际发票格式进行调整 invoice_number = re.search(r’发票号码[::](s*d+)’, text) invoice_number = invoice_number.group(1).strip() if invoice_number else “未知” invoice_date = re.search(r’开票日期[::](s*d{4}[年/-]d{1,2}[月/-]d{1,2})’, text) invoice_date = invoice_date.group(1).strip() if invoice_date else “未知” amount = re.search(r’金额[::]s*¥?s*(d+.d{2})’, text) amount = amount.group(1).strip() if amount else “0.00” # 将信息添加到列表 invoices_data.append({ ‘文件名’: pdf_file, ‘发票号码’: invoice_number, ‘开票日期’: invoice_date, ‘金额’: float(amount), }) # 关闭文档 doc.close() except Exception as e: print(f”处理 {pdf_file} 时出错: {e}”) # 创建DataFrame并保存为Excel if invoices_data: df = pd.DataFrame(invoices_data) # 添加总计行 total_amount = df[‘金额’].sum() df.loc[len(df)] = [‘总计’, ”, ”, total_amount] # 保存为Excel df.to_excel(output_excel, index=False) print(f”已成功处理 {len(invoices_data)} 个发票PDF并保存汇总表到: {output_excel}”) return output_excel else: print(“未找到有效的发票PDF文件”) return None # 使用示例 invoice_folder = “invoices” # 替换为实际的发票PDF文件夹路径 output_excel = “invoice_summary.xlsx” # process_invoice_pdfs(invoice_folder, output_excel)
- import pandas as pd import matplotlib.pyplot as plt import fitz import os from datetime import datetime def generate_sales_report_pdf(sales_data_excel, output_pdf): “””根据销售数据生成PDF报告””” # 读取销售数据 df = pd.read_excel(sales_data_excel) # 创建临时HTML文件 html_path = “temp_report.html” # 生成图表 plt.figure(figsize=(10, 6)) df.groupby(‘产品’)[‘销售额’].sum().plot(kind=’bar’) plt.title(‘各产品销售额对比’) plt.ylabel(‘销售额’) plt.tight_layout() chart_path = “sales_chart.png” plt.savefig(chart_path) # 计算汇总数据 total_sales = df[‘销售额’].sum() avg_sales = df[‘销售额’].mean() max_product = df.loc[df[‘销售额’].idxmax()][‘产品’] max_sales = df[‘销售额’].max() # 生成HTML报告 html_content = f””” <!DOCTYPE html> <html> <head> <title>销售数据报告</title> <style> body {{ font-family: Arial, sans-serif; margin: 40px; }} h1 {{ color: #2c3e50; text-align: center; }} .report-date {{ text-align: right; color: #7f8c8d; }} .summary {{ background-color: #f8f9fa; padding: 20px; border-radius: 5px; margin: 20px 0; }} table {{ width: 100%; border-collapse: collapse; margin: 20px 0; }} th, td {{ padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }} th {{ background-color: #3498db; color: white; }} tr:hover {{ background-color: #f5f5f5; }} .chart {{ text-align: center; margin: 30px 0; }} .footer {{ text-align: center; margin-top: 50px; font-size: 12px; color: #7f8c8d; }} </style> </head> <body> <div class=”report-date”>生成日期: {datetime.now().strftime(‘%Y年%m月%d日’)}</div> <h1>销售数据报告</h1> <div class=”summary”> <h2>销售摘要</h2> <p>总销售额: ¥{total_sales:,.2f}</p> <p>平均销售额: ¥{avg_sales:,.2f}</p> <p>最畅销产品: {max_product} (¥{max_sales:,.2f})</p> </div> <h2>销售数据明细</h2> <table> <tr> <th>产品</th> <th>销售量</th> <th>销售额</th> <th>日期</th> </tr> “”” # 添加表格数据 for _, row in df.iterrows(): html_content += f””” <tr> <td>{row[‘产品’]}</td> <td>{row[‘销售量’]}</td> <td>¥{row[‘销售额’]:,.2f}</td> <td>{row[‘日期’]}</td> </tr> “”” # 添加图表和页脚 html_content += f””” </table> <div class=”chart”> <h2>销售图表</h2> <img src=”{chart_path}” alt=”销售数据图表” style=”max-width: 100%;”> </div> <div class=”footer”> <p>此报告由Python自动生成 | 仅供内部使用</p> </div> </body> </html> “”” # 保存HTML文件 with open(html_path, “w”, encoding=”utf-8″) as f: f.write(html_content) # 将HTML转换为PDF import pdfkit try: pdfkit.from_file(html_path, output_pdf) print(f”已成功生成销售报告PDF: {output_pdf}”) # 清理临时文件 os.remove(html_path) os.remove(chart_path) return output_pdf except Exception as e: print(f”生成PDF报告时出错: {e}”) return None # 使用示例 sales_data_excel = “sales_data.xlsx” # 替换为实际的销售数据Excel文件路径 output_pdf = “sales_report.pdf” # generate_sales_report_pdf(sales_data_excel, output_pdf) 通过以上代码示例和应用场景,你可以轻松掌握Python PDF文档自动化的各种技巧,大幅提高工作效率。无论是提取文本和图像、合并拆分PDF、添加水印,还是从网页或Office文档生成PDF报告,Python都能帮你轻松应对。 以上就是Python自动化处理PDF文档的完整指南的详细内容,更多关于Python自动化处理PDF的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Python自动化处理Excel、Word、PDF文档的操作大全 Python自动化办公全攻略之Excel/Word/PDF/邮件批量处理 利用Python实现PDF文档的自动化创建 Python自动化实现将PDF文档高效转换为HTML文件 Python自动化办公之Excel、Word和PDF操作指南 5 种使用Python自动化处理PDF的实用方法介绍
目录
- 使用pymupdf读写PDF文件
- 基本概念
- 安装pymupdf
- 提取文本内容
- 提取图像
- 添加水印
- 使用pdfplumber提取PDF中表格
- 安装pdfplumber
- 提取表格数据
- 使用PyPDF2操控PDF文件
- 安装PyPDF2
- 合并PDF文件
- 拆分PDF文件
- 加密和解密PDF
- 使用wkhtmltopdf将网页转为PDF
- 安装wkhtmltopdf和pdfkit
- 将网页转换为PDF
- 将网页转换为图片
- 从Word/Excel导出PDF报告
- 从Word导出PDF
- 从Excel导出PDF
- 实际应用场景
- 场景一:批量处理发票PDF
- 场景二:自动生成PDF报告
PDF(Portable Document Format,便携式文档格式)是一种广泛使用的文档格式,具有跨平台、稳定性好、安全性高等特点。在办公自动化中,PDF文档处理是一项常见需求。本文将介绍如何使用Python实现PDF文档的自动化处理,包括读写、合并拆分、提取内容、添加水印等操作。
一个真实的PDF文件主要由四大部分构成,分别是文件头(Header)、文件主体(Body)、交叉引用表(Cross-Reference Table)和文件尾(Trailer)。了解这些基本结构有助于我们更好地处理PDF文件。
pip install pymupdf
pymupdf库(也称为fitz)可以轻松实现对PDF文件的读写操作。以下是提取PDF文本内容的示例:
import fitz # pymupdf的导入名称是fitz
def extract_text_from_pdf(pdf_path):
"""从PDF文件中提取所有文本内容"""
# 打开PDF文件
doc = fitz.open(pdf_path)
# 创建一个空字符串用于存储文本内容
text = ""
# 遍历每一页
for page_num in range(len(doc)):
# 获取当前页面
page = doc[page_num]
# 提取文本
page_text = page.get_text()
# 添加页码信息和页面文本
text += f"n--- 第 {page_num + 1} 页 ---n"
text += page_text
# 关闭文档
doc.close()
return text
# 使用示例
pdf_path = "example.pdf" # 替换为实际的PDF文件路径
try:
extracted_text = extract_text_from_pdf(pdf_path)
print("提取的文本内容:")
print(extracted_text[:500] + "..." if len(extracted_text) > 500 else extracted_text)
# 将提取的文本保存到文件
with open("extracted_text.txt", "w", encoding="utf-8") as f:
f.write(extracted_text)
print("文本已保存到 extracted_text.txt")
except Exception as e:
print(f"提取文本时出错: {e}")
一个PDF文件通常会包含图像元素,图像作为PDF文件中的对象也会记录在交叉引用表中。在pymupdf库中,可以通过相应的方法获取交叉引用表中记录的对象ID编号,并将其称为xref整数。
import fitz
import os
def extract_images_from_pdf(pdf_path, output_folder="extracted_images"):
"""从PDF文件中提取所有图像"""
# 确保输出文件夹存在
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 打开PDF文件
doc = fitz.open(pdf_path)
# 用于记录提取的图像数量
image_count = 0
# 遍历每一页
for page_num in range(len(doc)):
# 获取当前页面
page = doc[page_num]
# 获取页面上的图像列表
image_list = page.get_images()
# 遍历图像列表
for img_index, img in enumerate(image_list):
# 获取图像的xref
xref = img[0]
# 获取图像信息
base_image = doc.extract_image(xref)
image_bytes = base_image["image"]
image_ext = base_image["ext"]
# 生成输出文件名
output_filename = f"{output_folder}/page{page_num + 1}_img{img_index + 1}.{image_ext}"
# 保存图像
with open(output_filename, "wb") as f:
f.write(image_bytes)
image_count += 1
# 关闭文档
doc.close()
return image_count
# 使用示例
pdf_path = "example.pdf" # 替换为实际的PDF文件路径
try:
num_images = extract_images_from_pdf(pdf_path)
print(f"成功提取了 {num_images} 张图像到 'extracted_images' 文件夹")
except Exception as e:
print(f"提取图像时出错: {e}")
import fitz
def add_watermark_to_pdf(input_pdf, output_pdf, watermark_text):
"""为PDF文件添加文字水印"""
# 打开PDF文件
doc = fitz.open(input_pdf)
# 遍历每一页
for page_num in range(len(doc)):
# 获取当前页面
page = doc[page_num]
# 获取页面尺寸
rect = page.rect
# 创建一个透明的水印文本
# 设置字体大小、颜色和透明度
text_color = (0.5, 0.5, 0.5) # 灰色
alpha = 0.3 # 透明度
fontsize = 24
# 在页面中心添加水印
tw = fitz.TextWriter(rect)
tw.append((rect.width/2, rect.height/2), watermark_text, fontsize=fontsize, color=text_color)
tw.write_text(page, opacity=alpha)
# 保存修改后的PDF
doc.save(output_pdf)
doc.close()
return output_pdf
# 使用示例
input_pdf = "example.pdf" # 替换为实际的PDF文件路径
output_pdf = "watermarked.pdf"
watermark_text = "机密文件 - 请勿外传"
try:
result_pdf = add_watermark_to_pdf(input_pdf, output_pdf, watermark_text)
print(f"已成功添加水印并保存为: {result_pdf}")
except Exception as e:
print(f"添加水印时出错: {e}")
PDF文件中通常会有表格元素,如果想提取表格元素中的内容,可以使用pdfplumber库。
pip install pdfplumber
pdfplumber库提供的extract_table方法可以轻松提取PDF文件中某页的所有表格,对于缺少边界的表格,pdfplumber库会利用文本位置信息进行猜测,从而定位出不可见边界的位置。
import pdfplumber
import pandas as pd
def extract_tables_from_pdf(pdf_path):
"""从PDF文件中提取所有表格"""
# 打开PDF文件
with pdfplumber.open(pdf_path) as pdf:
all_tables = []
# 遍历每一页
for page_num, page in enumerate(pdf.pages):
# 提取表格
tables = page.extract_tables()
if tables:
print(f"在第 {page_num + 1} 页找到 {len(tables)} 个表格")
# 处理每个表格
for table_num, table in enumerate(tables):
# 创建DataFrame
df = pd.DataFrame(table[1:], columns=table[0])
# 添加页码和表格编号信息
df['页码'] = page_num + 1
df['表格编号'] = table_num + 1
all_tables.append(df)
else:
print(f"在第 {page_num + 1} 页没有找到表格")
# 如果找到了表格,合并所有表格
if all_tables:
combined_df = pd.concat(all_tables, ignore_index=True)
return combined_df
else:
return None
# 使用示例
pdf_path = "example_with_tables.pdf" # 替换为包含表格的PDF文件路径
try:
tables_df = extract_tables_from_pdf(pdf_path)
if tables_df is not None:
print("n提取的表格数据:")
print(tables_df.head())
# 将表格数据保存到Excel文件
excel_path = "extracted_tables.xlsx"
tables_df.to_excel(excel_path, index=False)
print(f"表格数据已保存到: {excel_path}")
else:
print("未在PDF中找到任何表格")
except Exception as e:
print(f"提取表格时出错: {e}")
PyPDF2是一个流行的Python库,用于处理PDF文件。它能完成PDF文件的信息提取、拆分、合并、页面裁剪、加密/解密等多种操作。
pip install PyPDF2
from PyPDF2 import PdfMerger
def merge_pdfs(pdf_files, output_path):
"""合并多个PDF文件"""
merger = PdfMerger()
# 添加每个PDF文件
for pdf in pdf_files:
try:
merger.append(pdf)
print(f"已添加: {pdf}")
except Exception as e:
print(f"添加 {pdf} 时出错: {e}")
# 保存合并后的PDF
merger.write(output_path)
merger.close()
return output_path
# 使用示例
pdf_files = ["document1.pdf", "document2.pdf", "document3.pdf"] # 替换为实际的PDF文件路径
output_path = "merged_document.pdf"
try:
result_path = merge_pdfs(pdf_files, output_path)
print(f"已成功合并PDF文件并保存为: {result_path}")
except Exception as e:
print(f"合并PDF文件时出错: {e}")
from PyPDF2 import PdfReader, PdfWriter
import os
def split_pdf(input_pdf, output_folder="split_pages"):
"""将PDF文件拆分为单页文件"""
# 确保输出文件夹存在
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 打开PDF文件
reader = PdfReader(input_pdf)
total_pages = len(reader.pages)
# 获取文件名(不含扩展名)
base_name = os.path.splitext(os.path.basename(input_pdf))[0]
# 拆分每一页
for page_num in range(total_pages):
writer = PdfWriter()
writer.add_page(reader.pages[page_num])
# 生成输出文件名
output_filename = f"{output_folder}/{base_name}_page_{page_num + 1}.pdf"
# 保存单页PDF
with open(output_filename, "wb") as output_file:
writer.write(output_file)
print(f"已保存第 {page_num + 1} 页到: {output_filename}")
return total_pages
# 使用示例
input_pdf = "example.pdf" # 替换为实际的PDF文件路径
try:
num_pages = split_pdf(input_pdf)
print(f"已成功将 {input_pdf} 拆分为 {num_pages} 个单页PDF文件")
except Exception as e:
print(f"拆分PDF文件时出错: {e}")
from PyPDF2 import PdfReader, PdfWriter
def encrypt_pdf(input_pdf, output_pdf, password):
"""加密PDF文件"""
reader = PdfReader(input_pdf)
writer = PdfWriter()
# 复制所有页面
for page in reader.pages:
writer.add_page(page)
# 设置密码和加密选项
writer.encrypt(password)
# 保存加密后的PDF
with open(output_pdf, "wb") as output_file:
writer.write(output_file)
return output_pdf
def decrypt_pdf(input_pdf, output_pdf, password):
"""解密PDF文件"""
reader = PdfReader(input_pdf)
# 检查PDF是否加密
if reader.is_encrypted:
# 尝试使用密码解密
if reader.decrypt(password) != 1:
raise ValueError("密码不正确")
else:
print("警告: 输入的PDF文件未加密")
writer = PdfWriter()
# 复制所有页面
for page in reader.pages:
writer.add_page(page)
# 保存解密后的PDF
with open(output_pdf, "wb") as output_file:
writer.write(output_file)
return output_pdf
# 使用示例 - 加密
input_pdf = "example.pdf" # 替换为实际的PDF文件路径
encrypted_pdf = "encrypted_document.pdf"
password = "secure123" # 设置密码
try:
result_path = encrypt_pdf(input_pdf, encrypted_pdf, password)
print(f"已成功加密PDF文件并保存为: {result_path}")
except Exception as e:
print(f"加密PDF文件时出错: {e}")
# 使用示例 - 解密
decrypted_pdf = "decrypted_document.pdf"
try:
result_path = decrypt_pdf(encrypted_pdf, decrypted_pdf, password)
print(f"已成功解密PDF文件并保存为: {result_path}")
except Exception as e:
print(f"解密PDF文件时出错: {e}")
wkhtmltopdf是一个开源工具,可以将HTML页面转换为PDF文档。它可以通过命令行直接使用,也可以通过Python的pdfkit库进行调用。
1.首先,需要安装wkhtmltopdf工具:
- 在macOS上:
brew install wkhtmltopdf - 在Windows上:从官方网站下载安装程序
- 在Linux上:
sudo apt-get install wkhtmltopdf(Ubuntu/Debian)或sudo yum install wkhtmltopdf(CentOS/RHEL)
2.然后,安装pdfkit Python库:
pip install pdfkit
import pdfkit
def url_to_pdf(url, output_pdf):
"""将URL指向的网页转换为PDF"""
try:
# 配置wkhtmltopdf路径(如果不在系统PATH中)
# config = pdfkit.configuration(wkhtmltopdf='/path/to/wkhtmltopdf')
# pdfkit.from_url(url, output_pdf, configuration=config)
# 如果wkhtmltopdf在系统PATH中
pdfkit.from_url(url, output_pdf)
print(f"已成功将 {url} 转换为PDF: {output_pdf}")
return output_pdf
except Exception as e:
print(f"转换网页到PDF时出错: {e}")
return None
def html_to_pdf(html_file, output_pdf):
"""将HTML文件转换为PDF"""
try:
pdfkit.from_file(html_file, output_pdf)
print(f"已成功将 {html_file} 转换为PDF: {output_pdf}")
return output_pdf
except Exception as e:
print(f"转换HTML文件到PDF时出错: {e}")
return None
def html_string_to_pdf(html_content, output_pdf):
"""将HTML字符串转换为PDF"""
try:
pdfkit.from_string(html_content, output_pdf)
print(f"已成功将HTML内容转换为PDF: {output_pdf}")
return output_pdf
except Exception as e:
print(f"转换HTML字符串到PDF时出错: {e}")
return None
# 使用示例 - 从URL创建PDF
url = "https://www.example.com" # 替换为实际的URL
output_pdf = "webpage.pdf"
url_to_pdf(url, output_pdf)
# 使用示例 - 从HTML文件创建PDF
html_file = "example.html" # 替换为实际的HTML文件路径
output_pdf = "from_html_file.pdf"
html_to_pdf(html_file, output_pdf)
# 使用示例 - 从HTML字符串创建PDF
html_content = """<!DOCTYPE html>
<html>
<head>
<title>测试页面</title>
</head>
<body>
<h1>Hello, World!</h1>
<p>这是一个由HTML字符串生成的PDF文档。</p>
</body>
</html>"""
output_pdf = "from_html_string.pdf"
html_string_to_pdf(html_content, output_pdf)
除了转换为PDF,wkhtmltoimage工具(wkhtmltopdf的一部分)还可以将网页转换为图片:
import subprocess
def url_to_image(url, output_image):
"""将URL指向的网页转换为图片"""
try:
# 执行wkhtmltoimage命令
command = ["wkhtmltoimage", url, output_image]
subprocess.run(command, check=True)
print(f"已成功将 {url} 转换为图片: {output_image}")
return output_image
except subprocess.CalledProcessError as e:
print(f"转换网页到图片时出错: {e}")
return None
except Exception as e:
print(f"发生错误: {e}")
return None
# 使用示例
url = "https://www.example.com" # 替换为实际的URL
output_image = "webpage.jpg"
url_to_image(url, output_image)
from docx2pdf import convert
def word_to_pdf(input_docx, output_pdf=None):
"""将Word文档转换为PDF"""
try:
# 如果未指定输出PDF路径,则使用相同的文件名但扩展名为.pdf
if output_pdf is None:
output_pdf = input_docx.replace(".docx", ".pdf")
# 转换Word文档为PDF
convert(input_docx, output_pdf)
print(f"已成功将 {input_docx} 转换为PDF: {output_pdf}")
return output_pdf
except Exception as e:
print(f"转换Word到PDF时出错: {e}")
return None
# 使用示例
input_docx = "example.docx" # 替换为实际的Word文档路径
word_to_pdf(input_docx)
import win32com.client
import os
def excel_to_pdf(input_excel, output_pdf=None):
"""将Excel文件转换为PDF(仅适用于Windows系统)"""
try:
# 如果未指定输出PDF路径,则使用相同的文件名但扩展名为.pdf
if output_pdf is None:
output_pdf = input_excel.replace(".xlsx", ".pdf").replace(".xls", ".pdf")
# 获取绝对路径
input_excel = os.path.abspath(input_excel)
output_pdf = os.path.abspath(output_pdf)
# 创建Excel应用程序实例
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = False
# 打开Excel文件
workbook = excel.Workbooks.Open(input_excel)
# 将工作簿导出为PDF
workbook.ExportAsFixedFormat(0, output_pdf)
# 关闭工作簿和Excel应用程序
workbook.Close()
excel.Quit()
print(f"已成功将 {input_excel} 转换为PDF: {output_pdf}")
return output_pdf
except Exception as e:
print(f"转换Excel到PDF时出错: {e}")
return None
# 使用示例(仅适用于Windows系统)
# input_excel = "example.xlsx" # 替换为实际的Excel文件路径
# excel_to_pdf(input_excel)
import os
import fitz
import re
from datetime import datetime
import pandas as pd
def process_invoice_pdfs(invoice_folder, output_excel):
"""批量处理发票PDF,提取关键信息并生成汇总表"""
# 存储提取的发票信息
invoices_data = []
# 获取文件夹中的所有PDF文件
pdf_files = [f for f in os.listdir(invoice_folder) if f.lower().endswith('.pdf')]
for pdf_file in pdf_files:
pdf_path = os.path.join(invoice_folder, pdf_file)
print(f"处理: {pdf_path}")
try:
# 打开PDF文件
doc = fitz.open(pdf_path)
# 提取第一页文本(假设发票信息在第一页)
text = doc[0].get_text()
# 使用正则表达式提取关键信息
# 注意:以下正则表达式需要根据实际发票格式进行调整
invoice_number = re.search(r'发票号码[::](s*d+)', text)
invoice_number = invoice_number.group(1).strip() if invoice_number else "未知"
invoice_date = re.search(r'开票日期[::](s*d{4}[年/-]d{1,2}[月/-]d{1,2})', text)
invoice_date = invoice_date.group(1).strip() if invoice_date else "未知"
amount = re.search(r'金额[::]s*¥?s*(d+.d{2})', text)
amount = amount.group(1).strip() if amount else "0.00"
# 将信息添加到列表
invoices_data.append({
'文件名': pdf_file,
'发票号码': invoice_number,
'开票日期': invoice_date,
'金额': float(amount),
})
# 关闭文档
doc.close()
except Exception as e:
print(f"处理 {pdf_file} 时出错: {e}")
# 创建DataFrame并保存为Excel
if invoices_data:
df = pd.DataFrame(invoices_data)
# 添加总计行
total_amount = df['金额'].sum()
df.loc[len(df)] = ['总计', '', '', total_amount]
# 保存为Excel
df.to_excel(output_excel, index=False)
print(f"已成功处理 {len(invoices_data)} 个发票PDF并保存汇总表到: {output_excel}")
return output_excel
else:
print("未找到有效的发票PDF文件")
return None
# 使用示例
invoice_folder = "invoices" # 替换为实际的发票PDF文件夹路径
output_excel = "invoice_summary.xlsx"
# process_invoice_pdfs(invoice_folder, output_excel)
import pandas as pd
import matplotlib.pyplot as plt
import fitz
import os
from datetime import datetime
def generate_sales_report_pdf(sales_data_excel, output_pdf):
"""根据销售数据生成PDF报告"""
# 读取销售数据
df = pd.read_excel(sales_data_excel)
# 创建临时HTML文件
html_path = "temp_report.html"
# 生成图表
plt.figure(figsize=(10, 6))
df.groupby('产品')['销售额'].sum().plot(kind='bar')
plt.title('各产品销售额对比')
plt.ylabel('销售额')
plt.tight_layout()
chart_path = "sales_chart.png"
plt.savefig(chart_path)
# 计算汇总数据
total_sales = df['销售额'].sum()
avg_sales = df['销售额'].mean()
max_product = df.loc[df['销售额'].idxmax()]['产品']
max_sales = df['销售额'].max()
# 生成HTML报告
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<title>销售数据报告</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; }}
h1 {{ color: #2c3e50; text-align: center; }}
.report-date {{ text-align: right; color: #7f8c8d; }}
.summary {{ background-color: #f8f9fa; padding: 20px; border-radius: 5px; margin: 20px 0; }}
table {{ width: 100%; border-collapse: collapse; margin: 20px 0; }}
th, td {{ padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }}
th {{ background-color: #3498db; color: white; }}
tr:hover {{ background-color: #f5f5f5; }}
.chart {{ text-align: center; margin: 30px 0; }}
.footer {{ text-align: center; margin-top: 50px; font-size: 12px; color: #7f8c8d; }}
</style>
</head>
<body>
<div class="report-date">生成日期: {datetime.now().strftime('%Y年%m月%d日')}</div>
<h1>销售数据报告</h1>
<div class="summary">
<h2>销售摘要</h2>
<p>总销售额: ¥{total_sales:,.2f}</p>
<p>平均销售额: ¥{avg_sales:,.2f}</p>
<p>最畅销产品: {max_product} (¥{max_sales:,.2f})</p>
</div>
<h2>销售数据明细</h2>
<table>
<tr>
<th>产品</th>
<th>销售量</th>
<th>销售额</th>
<th>日期</th>
</tr>
"""
# 添加表格数据
for _, row in df.iterrows():
html_content += f"""
<tr>
<td>{row['产品']}</td>
<td>{row['销售量']}</td>
<td>¥{row['销售额']:,.2f}</td>
<td>{row['日期']}</td>
</tr>
"""
# 添加图表和页脚
html_content += f"""
</table>
<div class="chart">
<h2>销售图表</h2>
<img src="{chart_path}" alt="销售数据图表" style="max-width: 100%;">
</div>
<div class="footer">
<p>此报告由Python自动生成 | 仅供内部使用</p>
</div>
</body>
</html>
"""
# 保存HTML文件
with open(html_path, "w", encoding="utf-8") as f:
f.write(html_content)
# 将HTML转换为PDF
import pdfkit
try:
pdfkit.from_file(html_path, output_pdf)
print(f"已成功生成销售报告PDF: {output_pdf}")
# 清理临时文件
os.remove(html_path)
os.remove(chart_path)
return output_pdf
except Exception as e:
print(f"生成PDF报告时出错: {e}")
return None
# 使用示例
sales_data_excel = "sales_data.xlsx" # 替换为实际的销售数据Excel文件路径
output_pdf = "sales_report.pdf"
# generate_sales_report_pdf(sales_data_excel, output_pdf)
通过以上代码示例和应用场景,你可以轻松掌握Python PDF文档自动化的各种技巧,大幅提高工作效率。无论是提取文本和图像、合并拆分PDF、添加水印,还是从网页或Office文档生成PDF报告,Python都能帮你轻松应对。
以上就是Python自动化处理PDF文档的完整指南的详细内容,更多关于Python自动化处理PDF的资料请关注风君子博客其它相关文章!
您可能感兴趣的文章:
- Python自动化处理Excel、Word、PDF文档的操作大全
- Python自动化办公全攻略之Excel/Word/PDF/邮件批量处理
- 利用Python实现PDF文档的自动化创建
- Python自动化实现将PDF文档高效转换为HTML文件
- Python自动化办公之Excel、Word和PDF操作指南
- 5 种使用Python自动化处理PDF的实用方法介绍