ククログ

株式会社クリアコード > ククログ > macOSでCocoaのAPIからPDF印刷を行うには

macOSでCocoaのAPIからPDF印刷を行うには

はじめに

macOSでは印刷をプログラマブルに行うことができます。 また、macOSではAppKit, Core PrintingのAPIを用いて印刷を行うことができます。

通常はAppKitにあるNSPrintInfoやNSPrintOperationを使えばいいのですが、より細部の設定を変更するにはCore PrintingのAPIに触る必要があります。この記事ではAppKitの範囲でmacOSの印刷について見ます。

AppKitを用いた印刷

単純な例

AppKitで印刷するにはまず、NSPrintOperationクラスを作成する必要があります。また、必要に応じてNSPrintInfoクラス を作成する必要があります。

単純にNSViewを持つCocoaアプリケーションからビューを印刷するには以下のように NSPrintOperation クラスを用いて

- (IBAction)print:(id)sender {
      NSPrintOperation *op;
      op = [NSPrintOperation printOperationWithView:self];
      if (op)
           [op setShowPanels:YES]; // If set 'NO', printing modal dialog will not be shown.
           [op runOperation];
      else
          // handle error here
}

のようにします。ここではselfがNSViewのインスタンスであることを要求しています。

NSPrintInfoを用いたより複雑な例

- (IBAction)print:(id)sender {
      NSPrintOperation* op;
      // Get NSPrintInfo
      NSPrintInfo* printInfo = [NSPrintInfo sharedPrintInfo];
      [printInfo setTopMargin:10.0];
      [printInfo setBottomMargin:10.0];

      op = [NSPrintOperation printOperationWithView:self printInfo:printInfo];
      if (op)
           [op setShowPanels:YES]; // If set 'NO', printing modal dialog will not be shown.
           [op runOperation];
      else
          // handle error here
}

のようにすることで、NSPrintOperationクラスにカスタマイズを施したNSPrintInfoクラスのオブジェクトを渡すことができます。

NSPrintInfoへdictionaryを渡しPDFを出力する場合

NSPrintInfoは以下のようにNSDictionary, NSMutableDictionaryのオブジェクトを渡すことにより初期化できます。

NSPrintInfo* printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];

これを利用すると、例えば以下のようなコードを用いてアプリケーションのビューをPDFへ出力できるようになります。

NSPrintInfo* sharedInfo = [NSPrintInfo sharedPrintInfo];
NSMutableDictionary* printInfoDict = [sharedInfo dictionary];

NSURL* jobSavingURL = [NSURL fileURLWithPath:@"日本語ファイル名.pdf"];

[printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
[printInfoDict setObject:jobSavingURL forKey:NSPrintJobSavingURL];

NSPrintInfo* printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];

// Then, set Cocoa application's NSView or its subclass View
NSPrintOperation* op = [NSPrintOperation printOperationWithView:self printInfo:printInfo];
[op setShowPanels:NO];
[op runOperation];

ここで注意する点は

NSURL* jobSavingURL = [NSURL fileURLWithPath:@"日本語ファイル名.pdf"];

は正しく日本語も扱えるコードとなりますが、

NSURL* jobSavingURL = [NSURL fileURLWithString:@"日本語ファイル名.pdf"];

は日本語が正しくエスケープされずにファイル出力に失敗します。

まとめ

macOSでのAppKitのAPIを用いた印刷の仕組み、特にPDFへ出力するようにするにはどうするかをざっと解説しました。 この記事では詳しく取り上げませんが、NSPrintJobDispositionへは通常のプリンターに送ったり、Preview.appに送ったり、PDFとしてファイルに出力したりという印刷ジョブの大まかな行き先を指定するために用いる定数を指定することができます。 macOSの印刷のAPIは扱いに慣れると一貫性のあるAPIとなっていることがわかります。