PyPDF2替换PDF占位符时出现EOF marker not found错误求助
问题根源
你遇到的EOF marker not found错误是因为你把从PDF提取的纯文本当成完整PDF文件解析了。page_text = pdf_reader.pages[0].extract_text()得到的只是页面纯文本内容,没有PDF必需的文件结构(如xref表、trailer、%%EOF标记等),用PdfReader读取这种纯文本流,自然找不到合法PDF的EOF标记。
另外代码还有两处逻辑问题:
- 循环中每次创建新的
PdfWriter,还重复添加原页面和错误生成的"编辑页面",最终输出的PDF会堆积大量重复页面 - 用
chardet检测纯文本编码没有意义,PDF的文本编码与文件二进制编码是两个概念
修复方案
要实现PDF占位符替换,需保留原PDF结构,直接修改页面内容。以下是基于PyPDF2和reportlab的可行方案(reportlab用于生成替换后的文本内容,再覆盖到原PDF页面):
步骤1:安装依赖
确保安装所需库:
pip install PyPDF2 pandas reportlab
步骤2:修正后的代码
import pandas as pd from PyPDF2 import PdfReader, PdfWriter from reportlab.pdfgen import canvas from io import BytesIO # 读取Excel数据 excel_filename = "prozesse-220-238.xlsx" df_excel = pd.read_excel(excel_filename) # 读取原始PDF pdf_filename = "handbook-2-with-placeholder.pdf" pdf_reader = PdfReader(pdf_filename) page = pdf_reader.pages[0] page_width, page_height = page.mediabox.width, page.mediabox.height # 遍历Excel每行数据,生成对应替换后的PDF for idx, row in df_excel.iterrows(): # 创建新的PDF Writer pdf_writer = PdfWriter() # 添加原始页面作为底版 pdf_writer.add_page(page) # 创建临时画布用于写入替换后的文本 packet = BytesIO() can = canvas.Canvas(packet, pagesize=(page_width, page_height)) # 提取原始页面文本,替换占位符 page_text = page.extract_text() for keyword, value in row.items(): placeholder = "{" + keyword + "}" if placeholder in page_text: # 注意:示例使用近似位置,实际需根据你的PDF调整坐标;如需精准定位,参考下方可选方案 can.drawString(100, 700, str(value)) can.save() packet.seek(0) new_pdf = PdfReader(packet) # 将生成的文本页面合并到底版上 pdf_writer.pages[0].merge_page(new_pdf.pages[0]) # 保存单个替换后的PDF edited_pdf_filename = f"edited_handbook_{idx+1}.pdf" with open(edited_pdf_filename, "wb") as f: pdf_writer.write(f) print(f"已保存: {edited_pdf_filename}")
精准定位占位符(可选)
如果需要精准定位占位符位置,可使用pdfplumber库获取文本坐标,再用reportlab写入对应位置:
- 安装
pdfplumber:
pip install pdfplumber
- 替换代码中绘制文本的片段:
import pdfplumber # 获取占位符的坐标 with pdfplumber.open(pdf_filename) as pdf: pdf_page = pdf.pages[0] for keyword, value in row.items(): placeholder = "{" + keyword + "}" for text in pdf_page.extract_words(): if text['text'] == placeholder: # 转换PDF坐标系与reportlab坐标系 x = text['x0'] y = page_height - text['top'] can.drawString(x, y, str(value))
注意事项
- 若你的PDF是扫描件(图片格式),无法直接提取文本替换,需先做OCR识别
- 若原PDF有复杂格式(如特殊字体、复杂排版),建议使用
PyMuPDF(fitz)库,它对PDF文本编辑的支持更友好
内容的提问来源于stack exchange,提问作者SailingHobo
相关产品推荐
相关产品推荐

