我们希望在我们创建的PDF文档中存储一些特定于应用程序的元数据(JSON对象)。
我们尝试使用canvas.setKeyword和PdfFileReader.documentInfo [“/ Keywords”]
这适用于100 KB文件,但挂起1 MB文件(documentInfo实际返回但需要很长时间> 1分钟)
是否有另一种方法可以使用reportlab将文件嵌入到PDF文档中? 还有另一种方法可以用PyPDF2读回来吗?
答案 0 :(得分:0)
(这可能是也可能不是一个足够好的答案,但我还没有能够发表评论的声誉......)
长延迟的一个可能原因可能是字符串的编码过程。如果您不介意重新阅读PDF,添加数据并将其写回,您可以尝试pdfrw。 (免责声明:我是pdfrw作者。)执行此操作的代码如下所示:
from pdfrw import PdfReader, PdfWriter trailer = PdfReader('source.pdf') trailer.Info.Keywords = my_json_string PdfWriter().write('dest.pdf', trailer)
如果由于字符串编码而不够快,您实际上可以将数据存储在文件中其他位置的流中(如果需要,甚至可以压缩它)。
答案 1 :(得分:0)
有点晚了,但我需要将数据嵌入到reportlab创建的PDF中,并最终提出以下内容。它将数据存储为 PDF中的EmbeddedFile流。为了以后查找数据,它存储了 PDF对象引用作为关键字(这不是"标准",PDF规范定义了定位/命名EmbeddedFile流的其他方法,但它有效)。使用PyPDF2提取数据。
# embeds data in the given reportlab.pdfgen.canvas, addressed by key.
# returns a string that must be added to canvas as a keyword
#
def canvas_embed(canvas, key, data):
from reportlab.pdfbase import pdfdoc
# create a stream object to hold the embedded data
s = pdfdoc.PDFStream(
content=data,
filters=[pdfdoc.PDFBase85Encode, pdfdoc.PDFZCompress])
s.dictionary['Type'] = '/EmbeddedFile'
# add it to the pdf
r = canvas._doc.Reference(s)
# return a string representing the object reference.
# we just use the two reference components concatenated with
# the given key name:
return '{}:{:d}:{:d}'.format(key,
*canvas._doc.idToObjectNumberAndVersion[r.name])
# extract the embedded file identified by key from
# the given PyPDF2.pdf.PdfFileReader
#
def reader_extract(pdfreader, key):
from PyPDF2.generic import IndirectObject
# find the key in the pdf's keywords (reportlab canvas
# separates keywords with ', '), and split it to get
# the object reference
for k in pdfreader.documentInfo['/Keywords'].split(', '):
if k.startswith(key + ':'):
refn, refv = [int(x) for x in k.split(':')[1:]]
break
# fetch the stream data
return IndirectObject(refn, refv, pdfreader).getObject().getData()
# a quick test
#
if __name__ == '__main__':
import StringIO
from reportlab.pdfgen import canvas
from PyPDF2.pdf import PdfFileReader
pdfbuf = StringIO.StringIO()
# create pdf with embedded data
c = canvas.Canvas(pdfbuf)
c.drawString(72.0, 72.0, 'embedded file test')
embedkey = canvas_embed(
canvas=c,
key='myembeddeddata',
data='some embedded data.')
c.setKeywords(['SomeOtherKeyword', embedkey])
c.showPage()
c.save()
pdfbuf.seek(0)
# read embedded data from the pdf
r = PdfFileReader(stream=pdfbuf)
data = reader_extract(pdfreader=r, key='myembeddeddata')
print 'Found: {}'.format(data)