You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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写入对应位置:

  1. 安装pdfplumber:
pip install pdfplumber
  1. 替换代码中绘制文本的片段:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:45:16