使用 PDFOutline 在 Swift/Cocoa 中将 TOC 添加到 PDFDocument [英] Adding TOC to PDFDocument in Swift/Cocoa using PDFOutline

查看:108
本文介绍了使用 PDFOutline 在 Swift/Cocoa 中将 TOC 添加到 PDFDocument的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个小型例程,它将多个单页 PDF 合并到一个多页 PDF 中.我在 Swift4/MacOS/Cocoa 中工作,我一生都无法在 Swift 中找到任何用于创建大纲/仅遍历现有大纲(我很熟悉)的示例.

I'm working on a small routine that takes a number of single page PDFs and merges them together into one multi-page PDF. I'm working in Swift4/MacOS/Cocoa and can not for the life of me find any kind of example in Swift for creating an outline / only traversing an existing one (which I'm well familiar with).

使用对文档的最佳猜测,我想出了以下内容,我一直在玩弄一些,但根本没有运气.PDF 出来的很好,但里面从来没有大纲/目录.它可能像丢失任务或其他东西一样简单......任何线索将不胜感激.

Using best guess on the documentation I came up with the following which I've been twiddling w/a bit but no luck at all. The PDF comes out fine but there is never an outline/TOC in it. It might be as simple as a missing assignment or something... any leads would be greatly appreciated.

顺便说一句,它在两个循环中而不是一个循环中的原因是因为我想也许我需要先添加所有页面 - 但尝试这样做并没有什么不同.如果可能,最终将只有一个循环.

BTW, the reason it's in two loops rather than one was because I thought maybe I needed to add all pages first - but trying that didn't make a difference. Ultimately will just have one loop if possible.

static func mergePagesIntoSinglePDF(streamId: String, numPages: Int)
    {
        let newPDF = PDFDocument()
        var directoryURLStr = ""

        for pageNum in 1...numPages {

            let directoryUrl = getFileURL(streamId: streamId, recNum: pageNum)
            directoryURLStr = directoryUrl!.absoluteString

            if let pdfDocument = PDFDocument(url: directoryUrl!),
                let pdfPage = pdfDocument.page(at: 0)
            {
                newPDF.insert(pdfPage, at: newPDF.pageCount)    
            }
        }

        for pageNum in 1...numPages {

            let newDest:PDFDestination = PDFDestination.init(page: newPDF.page(at: pageNum-1)!, at:NSPoint(x:1,y:1))
            let newTOCEntry:PDFOutline = PDFOutline.init()

            newTOCEntry.destination = newDest
            newTOCEntry.label = "This is page: \(pageNum)"
            newPDF.outlineRoot?.insertChild(newTOCEntry, at: pageNum-1)
        }

        directoryURLStr = (getFileURL(streamId: streamId)?.absoluteString)!
        let fileURL = URL(string: directoryURLStr)

        newPDF.write(to: fileURL!)
    }

推荐答案

看来我比我想象的要近得多.主要问题是我需要为 PDFOutline 创建一个根节点.我还添加了一点让 NSPoint 更智能一点,因为你不能在 PDF 中真正假设1,1"黑客是一个有效的坐标(通常是......但不能假设).当然,现在可以删除双循环,但为了清楚起见,我把它留在了:

Appears that I was much closer than I thought. The main problem was that I needed to create a root node for the PDFOutline. I also added a little to make the NSPoint a little smarter, since you can't really assume in PDF that the "1,1 " hack is a valid coordinate (generally is... but can't assume). And of course the double loop can now be removed, but for clarity's sake I left it in:

static func mergePagesIntoSinglePDF(streamId: String, numPages: Int)
{
    let newPDF = PDFDocument()

    newPDF.outlineRoot = PDFOutline();  // CREATE PDF OUTLINE ROOT NODE!

    var directoryURLStr = ""

    for pageNum in 1...numPages {

        let directoryUrl = getFileURL(streamId: streamId, recNum: pageNum)
        directoryURLStr = directoryUrl!.absoluteString

        if let pdfDocument = PDFDocument(url: directoryUrl!),
            let pdfPage = pdfDocument.page(at: 0)
        {
            newPDF.insert(pdfPage, at: newPDF.pageCount)    
        }
    }

    for pageNum in 1...numPages {

        let pdfPage = newPDF.page(at: pageNum-1)!

        // ADD A LITTLE CODE TO MAKE THE NSPoint IN THE DESTINATION MORE SOUND

        let pdfPageRect = pdfPage.bounds(for: PDFDisplayBox.mediaBox)
        let topLeft = NSMakePoint(pdfPageRect.minX, pdfPageRect.height + 20)
        let destination = PDFDestination(page: pdfPage, at: topLeft)

        let newDest = PDFDestination(page: pdfPage, at:topLeft)
        let newTOCEntry = PDFOutline()

        newTOCEntry.destination = newDest
        newTOCEntry.label = "\(streamId) page \(pageNum)"
        newPDF.outlineRoot!.insertChild(newTOCEntry, at: pageNum-1)
    }

    directoryURLStr = (getFileURL(streamId: streamId)?.absoluteString)!
    let fileURL = URL(string: directoryURLStr)

    newPDF.write(to: fileURL!)
}

这篇关于使用 PDFOutline 在 Swift/Cocoa 中将 TOC 添加到 PDFDocument的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆