【问题标题】:read, highlight, save PDF programmatically以编程方式阅读、突出显示、保存 PDF
【发布时间】:2011-11-28 04:00:51
【问题描述】:

我想编写一个小脚本(将在无头 Linux 服务器上运行)读取 PDF,突出显示与我传递的字符串数组中的任何内容匹配的文本,然后保存修改后的 PDF。我想我最终会使用python bindings to poppler 之类的东西,但不幸的是,文档几乎为零,而我在 python 方面的经验也几乎为零。

如果有人可以向我指出一个教程、示例或一些有用的文档来帮助我入门,我将不胜感激!

【问题讨论】:

  • 这通常不是 100% 万无一失的,因为任何 PDF 编译器 - 即使是像 pdftex 这样古老而可靠的编译器也可能会在每个地方绘制 pdf 内联...您确定可以阅读您的 PDF以这种方式?
  • 在我看来,Evince(或大多数其他 PDF 阅读器,就此而言)中的“查找”功能基本上可以满足我的要求 - 它突出显示基本上任何 PDF 中的匹配文本。如果它可以将这样的高亮渲染到屏幕上,为什么不将其渲染到文件中呢?
  • 这只是有点棘手,因为 PDF 通常不提供文本流。它更像是一张图片——文字可以出现在任何地方。通常它对读者来说看起来不错,但内部却是一团糟。也就是说,通常文本对齐是通过分解文本并仅放置内联以使其显得合理来实现的。无论如何,当 Evince 突出显示某些内容时,它要么很聪明,要么你的 PDF 表现良好,要么你很幸运,因为那个特定的字符串作为一个连续的实体存在于 PDF 中。不管怎样,看看itextpdf.com 这是最好的免费图书馆。
  • 你找到这个问题的答案了吗?如果是这样,我想听听:)
  • 对于通过 Google 来到这里的人:How to extract Highlighted Parts from PDF files

标签: python linux pdf poppler


【解决方案1】:

是的,可以结合使用 pdfminer (pip install pdfminer.six) 和 PyPDF2

首先,找到坐标(例如this)。然后突出显示它:

#!/usr/bin/env python

"""Create sample highlight in a PDF file."""

from PyPDF2 import PdfFileWriter, PdfFileReader

from PyPDF2.generic import (
    DictionaryObject,
    NumberObject,
    FloatObject,
    NameObject,
    TextStringObject,
    ArrayObject
)


def create_highlight(x1, y1, x2, y2, meta, color=[0, 1, 0]):
    """
    Create a highlight for a PDF.

    Parameters
    ----------
    x1, y1 : float
        bottom left corner
    x2, y2 : float
        top right corner
    meta : dict
        keys are "author" and "contents"
    color : iterable
        Three elements, (r,g,b)
    """
    new_highlight = DictionaryObject()

    new_highlight.update({
        NameObject("/F"): NumberObject(4),
        NameObject("/Type"): NameObject("/Annot"),
        NameObject("/Subtype"): NameObject("/Highlight"),

        NameObject("/T"): TextStringObject(meta["author"]),
        NameObject("/Contents"): TextStringObject(meta["contents"]),

        NameObject("/C"): ArrayObject([FloatObject(c) for c in color]),
        NameObject("/Rect"): ArrayObject([
            FloatObject(x1),
            FloatObject(y1),
            FloatObject(x2),
            FloatObject(y2)
        ]),
        NameObject("/QuadPoints"): ArrayObject([
            FloatObject(x1),
            FloatObject(y2),
            FloatObject(x2),
            FloatObject(y2),
            FloatObject(x1),
            FloatObject(y1),
            FloatObject(x2),
            FloatObject(y1)
        ]),
    })

    return new_highlight


def add_highlight_to_page(highlight, page, output):
    """
    Add a highlight to a PDF page.

    Parameters
    ----------
    highlight : Highlight object
    page : PDF page object
    output : PdfFileWriter object
    """
    highlight_ref = output._addObject(highlight)

    if "/Annots" in page:
        page[NameObject("/Annots")].append(highlight_ref)
    else:
        page[NameObject("/Annots")] = ArrayObject([highlight_ref])


def main():
    pdf_input = PdfFileReader(open("samples/test3.pdf", "rb"))
    pdf_output = PdfFileWriter()

    page1 = pdf_input.getPage(0)

    highlight = create_highlight(89.9206, 573.1283, 376.849, 591.3563, {
        "author": "John Doe",
        "contents": "Lorem ipsum"
    })

    add_highlight_to_page(highlight, page1, pdf_output)

    pdf_output.addPage(page1)

    output_stream = open("output.pdf", "wb")
    pdf_output.write(output_stream)


if __name__ == '__main__':
    main()

【讨论】:

  • 嗨,我们能否仅使用一个 Y 坐标来突出显示所有行?例如只有 y1 并从左到右标记所有内容?谢谢!
  • 不知道为什么这个答案没有得到更多的支持 :) .. 救命的东西 .. 非常感谢作者
【解决方案2】:

PDFlib 具有 Python 绑定并支持这些操作。如果您想打开 PDF,您将需要 PDI。 http://www.pdflib.com/products/pdflib-family/pdflib-pdi/ 和 TET。

不幸的是,它是一种商业产品。我过去在生产中使用过这个库,效果很好。绑定非常实用,而不是 Python。我已经看到一些尝试使它们更加 Pythonic:https://github.com/alexhayes/pythonic-pdflib 你会想要使用:open_pdi_document()。

听起来你会想要做某种搜索突出显示:

http://www.pdflib.com/tet-cookbook/tet-and-pdflib/highlight-search-terms/

【讨论】:

    【解决方案3】:

    您是否尝试过查看PDFMiner?听起来它可以满足您的需求。

    【讨论】:

    • 据我所知,PDFMiner 的目标是 PDF-> 文本提取端;它看起来不能突出显示更改后的 PDF 并将其呈现到文件中。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多