创建一个分页的PDF-Mac OS X.

时间:2016-08-25 01:12:14

标签: swift macos cocoa pdf swift3

我正在制作Mac应用程序(在Swift 3中使用Xcode 8,Beta 5),用户可以使用该应用程序进行长注并将其导出为PDF。

要创建此PDF,我使用Cocoa的dataWithPDF:方法,并使用以下代码:

do {
   // define bounds of PDF as the note text view
   let rect: NSRect = self.noteTextView.bounds
   // create the file path for the PDF
   if let dir = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true).first {
        // add the note title to path
        let path = NSURL(fileURLWithPath: dir).appendingPathComponent("ExportedNote.pdf")
        // Create a PDF of the noteTextView and write it to the created filepath
        try self.noteTextView.dataWithPDF(inside: rect).write(to: path!)  
   } else {
        print("Path format incorrect.") // never happens to me
   }

} catch _ {
    print("something went wrong.") // never happens to me
}

这完全有效,但有一个问题:PDF仅在一个页面上进行,这意味着当注释中有大量文本时页面会变得非常长。如何在我的应用程序导出PDF或之后立即强制PDF进入所需数量的信纸大小的页面?

1 个答案:

答案 0 :(得分:7)

经过数周的挫折之后,我想出了在Swift应用程序中创建分页PDF的明确方法。而且它并不像看起来那么复杂(以下是基于 Swift 2 ):

注意 :在您阅读更多内容之前,您应该知道我在Github上创建了一个简单的工具,因此您可以在更少的步骤中完成此操作(在Swift 3中,不再需要任何Objective-C)。 Check that out here

第1步:正确设置应用沙盒。每个提交的Mac应用都需要正确使用应用程序沙盒,因此最好只需要30秒即可立即设置它。如果它尚未打开,请转到目标设置,然后转到功能标题。打开App Sandboxing,在顶部。您应该会看到许多子功能,启用您的应用所需的任何一项功能,并确保将User Selected File设置为Read/Write

第2步:将此功能添加到您的代码中,这将创建一个不可见的webview并将文本添加到其中。

func createPDF(fromHTMLString: String) {
            self.webView.mainFrame.loadHTMLString(htmlString, baseURL: nil)
            self.delay(1) {
            MyCreatePDFFile(self.webView)
    }
}

步骤3:创建delay()函数以允许Xcode等待一秒钟,以便将HTML加载到Web视图中。

 func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

(注意:对于此函数的Swift 3版本,go here。)

第4步:在步骤2中添加的功能上方添加WebView的声明。

var webView = WebView()

第5步:您可能会注意到我们尚未创建MyCreatePDFFile()功能。事实证明,没有办法将此WebView转换为使用Swift的PDF,因此我们必须转向Objective-C(呻吟)。是的,您必须在Swift应用程序中运行一些Objective-C。

第6步:转到.m - >创建File文件New - > File(或点击 CMD + N ),然后双击Objective-C File。将其命名为CreatePDF.m并将其保留为空文件。

第7步:在添加.m文件时,您应该会收到添加桥接标头的提示:

enter image description here

点击Yes

如果您没有看到提示或意外删除了桥接标头,请在项目中添加新的.h文件,并将其命名为<#YourProjectName#>-Bridging-Header.h

在某些情况下,特别是在使用ObjC框架时,您不能显式添加Objective-C类,Xcode也无法找到链接器。在这种情况下,请创建如上所述命名的桥接标题.h文件,然后确保在目标公司的项目设置中链接其路径,如下所示:

enter image description here

第8步:转到.h - &gt;创建File文件New - &gt; File(或点击 CMD + N ),然后双击Header File。将其命名为CreatePDF.h

第9步:在CreatePDF.h文件中,添加以下代码,导入Cocoa和WebKit并设置PDF创建功能:

#ifndef CreatePDF_h
#define CreatePDF_h

#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>

@interface Thing : NSObject

void MyCreatePDFFile(WebView *thewebview);

@end


#endif /* CreatePDF_h */

步骤10:设置PDF创建功能的.m文件的时间。首先将其添加到空.m文件中:

#import "CreatePDF.h"
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>

@implementation Thing

void MyCreatePDFFile(WebView *thewebview) {

}
@end

第11步:现在您可以将代码添加到MyCreatePDFFile(..)功能中。这是函数本身(这是在当前空void函数内部):

NSDictionary *printOpts = @{
    NSPrintJobDisposition: NSPrintSaveJob // sets the print job to save the PDF instead of print it.
};
NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printOpts];    
[printInfo setPaperSize:NSMakeSize(595.22, 841.85)]; // sets the paper size to a nice size that works, you can mess around with it
[printInfo setTopMargin:10.0];
[printInfo setLeftMargin:10.0];
[printInfo setRightMargin:10.0];
[printInfo setBottomMargin:10.0];
NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:[[[thewebview mainFrame] frameView] documentView] printInfo:printInfo]; // sets the print operation to printing the WebView as a document with the print info set above
printOp.showsPrintPanel = NO; // skip the print question and go straight to saving pdf
printOp.showsProgressPanel = NO; 
[printOp runOperation];

第12步:现在将此添加到您的桥接标头中,以允许您的Swift文件看到您刚刚制作的Objective-C函数。

#import "CreatePDF.h"

第13步:此代码中不应出现任何错误,但如果有,请在下方发表评论。

步骤14:要从Swift文件的任何位置调用createPDF函数,请执行以下操作:

createPDF("<h1>Title!</h1><p>\(textview.text!)</p>")

您在createPDF中看到的字符串是HTML,可以编辑为HTML。如果您不了解HTML,可以看到一些基础知识right here

应该是它!你现在应该可以在Swift上,在Cocoa / Mac应用程序上创建分页PDF。

积分

注意:此答案经过测试,可与Xcode 7,Swift 2和OS X El Captian配合使用。如果您在使用Xcode 8 / Swift 3 / macOS Sierra时遇到任何问题,请与我们联系。