Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Xcode 7.3.2, Swift 2, Cocoa (Mac).

My app involves the user entering in some text, which can be exported to a PDF.

In the iOS version of my app, I can create the PDF relatively easily with the CoreText framework:

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)

However, UIMarkupTextPrintFormatter, UIPrintPageRenderer, UIGraphicsBeginPDFContextToData, and UIGraphicsEndPDFContext all do not exist on OS X. How can I do the exact same thing as I am doing with this iOS code (create a basic PDF from some HTML and write it to a certain file path as a paginated PDF) with Mac and Cocoa?

EDIT: The answer to this question is here: Create a paginated PDF—Mac OS X.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
699 views
Welcome To Ask or Share your Answers For Others

1 Answer

Here is a function that will generate a PDF from pure HTML.

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()
        }
    }
}

What is happening:

  1. Put the HTML into a NSAttributedString.
  2. Render the NSAttributedString to a NSTextField.
  3. Render the NSTextField to a NSView.
  4. Create a NSPrintOperation with that NSView.
  5. Set the printing parameters to save as a PDF.
  6. Run the print operation (which actually opens a dialog to save the PDF)
  7. Everyone is happy.

This is not a perfect solution. Note the hard coded integer values.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...