Добавление оглавления в PDFDocument в Swift/Cocoa с использованием PDFOutline
Я работаю над небольшой программой, которая берет несколько одностраничных PDF-файлов и объединяет их в один многостраничный PDF-файл. Я работаю в Swift4/MacOS/Cocoa и не могу найти в Swift какого-либо примера для создания контура / только пересечения существующего (с которым я хорошо знаком).
Используя лучшее предположение о документации, я придумал следующее, что я немного вертел, но совсем не повезло. PDF выходит отлично, но в нем никогда нет набросков / оглавления. Это может быть так же просто, как пропущенное задание или что-то в этом роде... любые предложения будут с благодарностью
Кстати, причина в том, что это в двух циклах, а не в одном, потому что я подумал, что, возможно, мне нужно сначала добавить все страницы - но попытка не принесла изменений. В конечном итоге будет только один цикл, если это возможно.
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 ответ
Оказывается, я был намного ближе, чем думал. Основная проблема заключалась в том, что мне нужно было создать корневой узел для PDFOutline. Я также добавил немного, чтобы сделать NSPoint немного умнее, поскольку вы не можете реально предположить в PDF, что взлом "1,1 " является допустимой координатой (обычно это... но не может предположить). И, конечно, теперь можно удалить двойной цикл, но для ясности я оставил его в:
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!)
}