【问题标题】:How can I get all text from a PDF in Swift?如何在 Swift 中从 PDF 中获取所有文本?
【发布时间】:2016-05-15 16:27:37
【问题描述】:

我有一个 PDF 文档,想提取其中的所有文本。 我尝试了以下方法:

import Quartz

let url = NSBundle.mainBundle().URLForResource("test", withExtension: "pdf")
let pdf = PDFDocument(URL: url)
print(pdf.string())

它确实得到了文本,但是与在 Adob​​e 中打开 PDF、编辑全选、复制、粘贴相比,提取的行的顺序完全混淆了!

如何在 Swift 中获得与打开 PDF、全选、复制/粘贴相同的结果!?

【问题讨论】:

  • 我找不到string()pdf 实例吗?没了?
  • @Hemang 它是一个计算属性string (Swift)

标签: swift parsing pdf quartz-core


【解决方案1】:

如果你只想要文本内容:

  extension String
{
    func readPDF() -> String
    {
        let path = "\(self)"
        let url = URL(fileURLWithPath: path)
        let pdf = PDFDocument(url: url)
        return pdf!.string!
    }
}

【讨论】:

    【解决方案2】:

    我做到了。用这个:

    if let pdf = PDFDocument(url: url) {
        let pageCount = pdf.pageCount
        let documentContent = NSMutableAttributedString()
    
        for i in 1 ..< pageCount {
            guard let page = pdf.page(at: i) else { continue }
            guard let pageContent = page.attributedString else { continue }
            documentContent.append(pageContent)
        }
    }
    

    希望对你有帮助。

    【讨论】:

    • 我知道 PDF 计数从 1 开始,但在快速帮助中说“索引从零开始”,所以我将 1 更改为 0,它工作得非常好。
    【解决方案3】:

    很遗憾,这是不可能的。
    至少不是没有你的一些主要工作。对于所有 pdf,这肯定是不可能的。

    PDF(通常)是一条单行道。
    创建它们是为了在每个系统上以相同的方式显示文本而没有任何区别,并且打印机可以打印文档而无需打印机知道所有字体和内容。

    提取文本并非易事,并且仅适用于基本图像 PDF 附带文本(并非必须)的某些 PDF。 PDF 中存在的所有文本信息都与位置信息相结合,以确定将在何处显示。

    如果您在 PDF 中显示了一个表格,其中左列包含条目的名称,右行包含其内容,则这两列都可以表示为完全不同的文本块,仅 出现 彼此之间有一些联系,因为它们彼此相邻。

    框架/您的代码必须做的是确定视觉链接的文本部分在逻辑上也链接并属于一起。这(还)不可能。你和我能阅读、理解和分组 PDF 的原因是,在某些领域,我们的大脑仍然比计算机好得多。

    最后一点,因为它可能会引起混淆:Adobe 和 Apple 也有可能已经做了一些这样的分组并取得了很好的结果,但它仍然不是完美的。我刚刚测试的 PDF 在通过 Mac 预览提取文本后被严重破坏。

    【讨论】:

    • 真不幸!你知道我怎么能剪掉PDF的一部分吗?它确实有列。然后我可以分成几部分并再次尝试使用'pdf.string'。
    • @CenTinel 我不知道,不。但我知道你可以剪掉两边,只从那里拿绳子。 PDFDocument 的文档中有很多功能,您可能需要阅读该网站并在 Google 上搜索您遇到的有趣关键字。
    • 好的,我设法使用 pdf.pageAtIndex(x).selectionForRect(somerect) 在 PDF 上制作选择矩形,但这也完全混乱:(
    • @luk2302,我在pdf 类型为CGPDFDocument 的任何地方都找不到string() 函数?它实际上在哪里?
    • @Hemang 不知道,CGPDFDocumentPDFDocument 不一样。
    【解决方案4】:

    这是一个使用 PDFKit 的选项:

    import Cocoa
    import Quartz
    
    func pdfToText(fromPDF: String) -> String {
        let urlPath = Bundle.main.url(forResource: fromPDF, withExtension: "pdf")
        let docContent = NSMutableAttributedString()
        if let pdf = PDFDocument(url: urlPath!) {
            let pageCount = pdf.pageCount
    
            for i in 1 ..< pageCount {
                guard let page = pdf.page(at: i) else { continue }
                guard let pageContent = page.attributedString else { continue }
                docContent.append(pageContent)
            }
        }
    
        return docContent.string
    }
    
    let pdfString = pdfToText(fromPDF: "documentName")
    

    这使您可以选择将 PDF 内容作为属性字符串获取。如果您只是在纯文本之后,您可以通过将.string 附加到结果中来获取它,就像我在上面的示例中所做的那样。

    参见。 Paul Hudson's snippet

    【讨论】:

    • 我知道 PDF 计数从 1 开始,但在快速帮助中说“索引从零开始”,所以我将 1 更改为 0,它工作得非常好。
    【解决方案5】:

    Apple 的 PDFDocument 类文档说 string 是 “一种方便的方法,相当于为整个文档创建一个选择对象,然后调用 PDFSelection 类的 string 方法。”

    所以你应该得到与在预览中复制和粘贴相同的结果。

    Adobe 的 Acrobat 可能会使用其他一些例程来创建逻辑上更有用的流程,但您无法在 MacOS 中以编程方式访问它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      相关资源
      最近更新 更多