问题
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).
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!)
}
回答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!)
}
来源:https://stackoverflow.com/questions/51689514/adding-toc-to-pdfdocument-in-swift-cocoa-using-pdfoutline