我正在尝试通过从pandas数据框中读取数据并使用pyPDF2和reportlab将其写入现有pdf表单来自动生成pdf。该计划的主要内容是:
def pdfOperations(row, bp):
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
createText(row, can)
packet.seek(0)
new_pdf = PdfFileReader(packet)
textPage = new_pdf.getPage(0)
secondPage = bp.getPage(1)
secondPage.mergePage(textPage)
assemblePDF(frontPage, secondPage, row)
del packet, can, new_pdf, textPage, secondPage
def main():
df = openData()
bp = readPDF()
frontPage = bp.getPage(0)
for ind in df.index:
row = df.loc[ind]
pdfOperations(row, bp)
这适用于第一行数据和第一行pdf,但对于后续的数据,所有文本都会被覆盖。即第二个pdf包含第一次迭代和第二次迭代的文本。我认为垃圾收集会处理所有内存更改,但这似乎并没有发生。谁知道为什么?
我甚至尝试在函数运行之后强制删除对象,但没有运气......
答案 0 :(得分:1)
您只能在循环前阅读bp
一次。然后在循环中,您通过getPage(1)
获取其第二页并将其合并到其中。但由于它始终来自同一个对象(bp
),因此每个迭代将合并到同一页面,因此所有合并在加起来之前完成。
虽然我没有找到任何方法来创建一个" deepcopy"在PyPDF2的文档中,它应该只为每次迭代创建一个新的bp
对象。
readPDF
中的某个位置,您必须完成某些操作,将模板PDF打开为二进制流,然后将其传递给PdfFileReader
。相反,您可以将数据读入变量:
with open(filename, "rb") as f:
bp_bin = f.read()
然后,为每个循环迭代创建一个新的PdfFileReader
实例:
for ind in df.index:
row = df.loc[ind]
bp = PdfFileReader(bp_bin)
pdfOperations(row, bp)
这应该"重置"每次secondPage
没有任何额外的文件I / O开销。每次只进行解析,但根据文件大小和内容,可能花费的时间很少,你可以忍受。