在PDF文件中嵌入文档



我们想在我们创建的PDF文档中存储一些特定于应用程序的元数据(一个JSON对象)。

我们尝试使用画布。setKeyword and PdfFileReader.documentInfo["/Keywords"]

这适用于一个100 KB的文件,但挂起一个1 MB的文件(documentInfo实际上返回,但需要很长时间> 1min)

是否有另一种方法将文件嵌入到reportlab的PDF文档中?是否有另一种方法读取它与PyPDF2?

(这可能是也可能不是一个足够好的答案,但我还没有足够的声誉来评论…)

长延迟的一个可能原因可能是字符串的编码过程。如果您不介意将PDF读入,添加数据并将其写出来,您可以尝试pdfrw。(声明:我是pdfrw的作者。)这样做的代码看起来像这样:

<>之前从pdfrw导入PdfReader, PdfWritertrailer = PdfReader('source.pdf')trailer.Info.Keywords = my_json_stringPdfWriter () .write("dest.pdf",预告片)之前

如果因为字符串编码而不够快,实际上可以将数据存储在文件的其他位置的流中(如果需要,甚至可以压缩它)。

有点晚了,但我也需要在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)

最新更新