如何使用Cocoa(Mac)在Swift中创建PDF

时间:2016-08-15 00:16:06

标签: swift macos cocoa pdf

Xcode 7.3.2,Swift 2,Cocoa(Mac)。

我的应用涉及用户输入一些文本,可以导出为PDF。

在我的应用的iOS版本中,我可以使用CoreText框架相对轻松地创建PDF:

let html = "<font face=\'Futura\' color=\"SlateGray\"><h2>\(title)</h2></font><font face=\"Avenir\" color=\"SlateGray\"><h4>\(string)</h4></font>"

    let fmt = UIMarkupTextPrintFormatter(markupText: html)

    // 2. Assign print formatter to UIPrintPageRenderer

    let render = UIPrintPageRenderer()
    render.addPrintFormatter(fmt, startingAtPageAt: 0)

    // 3. Assign paperRect and printableRect

    let page = CGRect(x: 10, y: 10, width: 595.2, height: 841.8) // A4, 72 dpi, margin of 10 from top and left.
    let printable = page.insetBy(dx: 0, dy: 0)

    render.setValue(NSValue(cgRect: page), forKey: "paperRect")
    render.setValue(NSValue(cgRect: printable), forKey: "printableRect")

    // 4. Create PDF context and draw

    let pdfData = NSMutableData()
    UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil)

    for i in 1...render.numberOfPages {

        UIGraphicsBeginPDFPage();
        let bounds = UIGraphicsGetPDFContextBounds()
        render.drawPage(at: i - 1, in: bounds)
    }

    UIGraphicsEndPDFContext();

    // 5. Save PDF file

    path = "\(NSTemporaryDirectory())\(title).pdf"
    pdfData.write(toFile: path, atomically: true)

但是,操作系统X上不存在UIMarkupTextPrintFormatterUIPrintPageRendererUIGraphicsBeginPDFContextToDataUIGraphicsEndPDFContext。我怎样才能完成与我一样的操作使用Mac和Cocoa,这个iOS代码(从某些HTML创建基本PDF并将其作为分页PDF写入某个文件路径)?

编辑:此问题的答案如下:Create a paginated PDF—Mac OS X

1 个答案:

答案 0 :(得分:5)

这是一个将从纯HTML生成PDF的函数。

func makePDF(markup: String) {
    let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
    let printOpts: [NSPrintInfo.AttributeKey: Any] = [NSPrintInfo.AttributeKey.jobDisposition: NSPrintInfo.JobDisposition.save, NSPrintInfo.AttributeKey.jobSavingURL: directoryURL]
    let printInfo = NSPrintInfo(dictionary: printOpts)
    printInfo.horizontalPagination = NSPrintingPaginationMode.AutoPagination
    printInfo.verticalPagination = NSPrintingPaginationMode.AutoPagination
    printInfo.topMargin = 20.0
    printInfo.leftMargin = 20.0
    printInfo.rightMargin = 20.0
    printInfo.bottomMargin = 20.0

    let view = NSView(frame: NSRect(x: 0, y: 0, width: 570, height: 740))

    if let htmlData = markup.dataUsingEncoding(NSUTF8StringEncoding) {
        if let attrStr = NSAttributedString(HTML: htmlData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) {
            let frameRect = NSRect(x: 0, y: 0, width: 570, height: 740)
            let textField = NSTextField(frame: frameRect)
            textField.attributedStringValue = attrStr
            view.addSubview(textField)

            let printOperation = NSPrintOperation(view: view, printInfo: printInfo)
            printOperation.showsPrintPanel = false
            printOperation.showsProgressPanel = false
            printOperation.run()
        }
    }
}

发生了什么:

  1. 将HTML放入NSAttributedString。
  2. 将NSAttributedString呈现给NSTextField。
  3. 将NSTextField呈现为NSView。
  4. 使用该NSView创建NSPrintOperation。
  5. 将打印参数设置为另存为PDF。
  6. 运行打印操作(实际打开一个对话框以保存PDF)
  7. 每个人都很开心。
  8. 这不是一个完美的解决方案。注意硬编码的整数值。