如何用Python向已有PDF文件追加字节内容?
解决PDF内容追加的问题:别直接拼字节,用专业PDF库!
嘿,我懂你踩的这个坑了——直接用ab或a+b模式往PDF文件里追加字节内容完全行不通!PDF是有严格结构的文档格式,不是随便堆二进制数据就能凑成合法文件的,你现在相当于把两个独立的PDF文件的二进制代码硬粘在一起,系统根本识别不了这种“四不像”的文件。
为什么你的代码不行?
你第一次用wb写入的是一个完整的、结构合法的PDF;第二次用a+b追加的是另一个完整PDF的字节流,这就导致最终文件里有两个独立的PDF头部、交叉引用表等核心结构,阅读器打开时会直接报错或者只显示第一个PDF的内容。
正确的做法:用PDF处理库合并文档
我们需要用专门的PDF处理工具来把两个PDF的页面合并成一个合法的PDF文件,下面给你两种常用的Python方案:
方案1:用PyPDF2合并(入门友好)
首先安装依赖:
pip install PyPDF2
修改你的代码,直接处理请求返回的字节内容,不用先写临时文件:
import requests from PyPDF2 import PdfMerger from io import BytesIO # 第一个PDF请求 get_view_pdf_url = "http://localhost:8000/api/3.0/sites/a18ab9c9-c523-4848-9199-8c50e100ac36/views/e948dd8c-31b1-480a-8123-fecf47b1c682/pdf" reqPDF = requests.get(get_view_pdf_url, data=b'', headers={'x-tableau-auth': token}) reqPDF.raise_for_status() pdf1_bytes = BytesIO(reqPDF.content) # 第二个PDF请求 get_view_pdf1_url = "http://localhost:8000/api/3.0/sites/a18ab9c9-c523-4848-9199-8c50e100ac36/views/910d1215-59cb-4d63-95fd-7a2b224f18bc/pdf" reqPDF1 = requests.get(get_view_pdf1_url, data=b'', headers={'x-tableau-auth': token}) reqPDF1.raise_for_status() pdf2_bytes = BytesIO(reqPDF1.content) # 合并两个PDF merger = PdfMerger() merger.append(pdf1_bytes) merger.append(pdf2_bytes) # 写入最终文件 filename = "C:/Users/pinki.sharma/Desktop/Work/tempmon/pinkiTest.pdf" with open(filename, 'wb') as f: merger.write(f) merger.close()
方案2:用PyMuPDF(fitz)合并(更高效,支持更多PDF特性)
PyMuPDF是性能更好的PDF处理库,合并速度更快,对复杂PDF的兼容性也更强:
先安装依赖:
pip install pymupdf
对应的代码实现:
import requests import fitz # 就是PyMuPDF from io import BytesIO # 获取第一个PDF字节流 get_view_pdf_url = "http://localhost:8000/api/3.0/sites/a18ab9c9-c523-4848-9199-8c50e100ac36/views/e948dd8c-31b1-480a-8123-fecf47b1c682/pdf" reqPDF = requests.get(get_view_pdf_url, data=b'', headers={'x-tableau-auth': token}) reqPDF.raise_for_status() # 获取第二个PDF字节流 get_view_pdf1_url = "http://localhost:8000/api/3.0/sites/a18ab9c9-c523-4848-9199-8c50e100ac36/views/910d1215-59cb-4d63-95fd-7a2b224f18bc/pdf" reqPDF1 = requests.get(get_view_pdf1_url, data=b'', headers={'x-tableau-auth': token}) reqPDF1.raise_for_status() # 创建一个新的PDF文档 output_pdf = fitz.open() # 打开第一个PDF并插入所有页面 with fitz.open("pdf", reqPDF.content) as pdf1: output_pdf.insert_pdf(pdf1) # 打开第二个PDF并插入所有页面 with fitz.open("pdf", reqPDF1.content) as pdf2: output_pdf.insert_pdf(pdf2) # 保存最终文件 filename = "C:/Users/pinki.sharma/Desktop/Work/tempmon/pinkiTest.pdf" output_pdf.save(filename) output_pdf.close()
关键提醒
永远不要尝试直接拼接PDF的二进制内容!PDF的结构包含头部信息、页面树、交叉引用表、尾部标记等多个关键部分,只有专业的PDF处理库才能正确解析并合并这些结构,生成合法的PDF文件。
内容的提问来源于stack exchange,提问作者Pinki Sharma
相关产品推荐
相关产品推荐

