美文网首页
MacOS Object-c Print 打印相关

MacOS Object-c Print 打印相关

作者: 枋_ | 来源:发表于2022-12-05 21:23 被阅读0次

---

title: MacOS Print

date: 11/29/2022, 4:51:31 PM

tags:

- macos

- print

- object-c

---

[TOC]

# MacOS Print

> 主要参考 [https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Printing/osxp_printingapi/osxp_printingapi.html#//apple_ref/doc/uid/10000083i-CH2-SW10](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Printing/osxp_printingapi/osxp_printingapi.html#//apple_ref/doc/uid/10000083i-CH2-SW10)

> 但是这已经是2012年的内容了,有点太陈旧,不完全符合现在的要求

基于这次的打印需求整理下用到的东西

## 基础打印

- `NSView`的打印 

- `WKWebview`的打印

- `PDFDocument`的打印

### NSView 的打印

``` object-c

//NSView * view;

[view.window.contentView print:nil];

```

官方文档中推荐在此基础上可以通过`NSView`自身的重写能力, 为打印的时候添加上*页头和页尾*等,

### WKWebview 的打印

``` object-c

[self.webview printOperationWithPrintInfo:info];

```

这种方式的打印**不能够**依靠`NSView`的方式来给打印的文件添加*页眉页脚*

### PDFDocument的打印

``` object-c

NSPrintOperation* operation = [self.pdf printOperationForPrintInfo:info scalingMode:kPDFPrintPageScaleNone autoRotate:NO];

```

这种方式是对一个pdf文档进行打印操作, 在此基础上可以为这个文档添加水印。 水印图片自然也就可以是图片或者其他文案。 当前的方案就是依靠这个能力来实现打印的

## 打印框的自定义插件View

![image](lowh:///Users/chenxiaofang/Documents/denkui/insert_image_from_clipboard_1670242842982.png)

### 自定义插件View

``` object-c

  [operation.printPanel addAccessoryController: self.vc];

```

打印框PrintPanel内可以传入一个ViewController, 由系统控制如何展示该ViewController的view 达到类似图中 **打印背景**和**打印页眉和页脚** 这两个checkbox的功能。

``` object-c

@interface PrintSettingVC : NSViewController<NSPrintPanelAccessorizing>

- (id) init;

@end

```

``` object-c

@implementation PrintSettingVC

- (id) init {

    self = [super initWithNibName:@"nibname" bundle:nil];

    return self;

}

@end

```

传入的ViewController必须要继承`NSPrintPanelAccessorizing` ,用于提供系统控制这个插件view的其他信息。

#### NSPrintPanelAccessorizing 函数解释

``` object-c

- (nonnull NSArray<NSDictionary<NSPrintPanelAccessorySummaryKey,NSString *> *> *)localizedSummaryItems {

      return @[];

}

- (NSSet<NSString *> *)keyPathsForValuesAffectingPreview {

    return [NSSet setWithObjects:@"wxmailPreview", nil];

}

- (BOOL)commitEditingAndReturnError:(NSError *__autoreleasing  _Nullable * _Nullable)error {

    return false;

}

- (void)encodeWithCoder:(nonnull NSCoder *)coder {

}

```

##### localizedSummaryItems

![image](lowh:///Users/chenxiaofang/Documents/denkui/insert_image_from_clipboard_1670245590337.png)

插件收拢的时候部分版本的操作系统可以以缩略形式看到当前的选择项的状态的, 当然这里具体希望展示什么就自主选择了。

##### keyPathsForValuesAffectingPreview

影响预览页面刷新,在后面具体展开[@更新预览窗口内容](#更新预览窗口内容)

##### commitEditingAndReturnError &amp;  encodeWithCoder

这次需求没有用上

### 更新预览窗口内容

> 仅仅是记录下来这样能生效

``` object-c

/* Return the key paths for properties whose values affect what is drawn in the print panel's built-in preview. NSPrintPanel observes these key paths and redraws the preview when the values for any of them change. For example, if you write an accessory view that lets the user change document margins in the print panel you might provide an implementation of this method that returns a set that includes strings like @"representedObject.leftMargin", @"representedObject.rightMargin", etc. (because the representedObject would be an NSPrintInfo, which is KVO-compliant for "leftMargin," "rightMargin," etc.). This protocol method is optional because it's not necessary if you're not using NSPrintPanel's built-in preview, but if you use preview you almost certainly have to implement this method properly too.

*/

- (NSSet<NSString *> *)keyPathsForValuesAffectingPreview NS_SWIFT_UI_ACTOR;

```

在上文中`wkwebview` 和 `pdfdocument`的打印方式中有传入`NSPrintInfo` 对象, 对该对象进行修改时可以触发预览更新

``` object-c

@implementation PrintSettingVC

- (id) init {

    self = [super initWithNibName:@"nibname" bundle:nil];

    return self;

}

- (void)setWxmailPreview:(BOOL)flag {

    NSPrintInfo *printInfo = [self representedObject];

    // 不改变

    [[printInfo dictionary] setObject:[NSNumber numberWithBool:[[[printInfo dictionary] objectForKey:NSPrintHeaderAndFooter] boolValue]] forKey:NSPrintHeaderAndFooter];

}

- (void) refreshPreview {

    qInfo() << "refreshPreview";

    // NOTE: 刷新

    [self setWxmailPreview:NO];

}

- (NSSet<NSString *> *)keyPathsForValuesAffectingPreview {

    return [NSSet setWithObjects:@"wxmailPreview", nil];

}

```

`setWxmailPreview` 中传入的参数不重要, 实际上即使没有改变printinfo的内容,也能触发刷新。

## 页眉页脚

当前的方案是针对`PDFDocument`打印的,在打印的基础上对整个pdf对象的每一页添加**“水印”**,就能满足在某个区域添加页眉页脚的需求。[@adding_widgets_to_a_pdf_document](https://developer.apple.com/documentation/pdfkit/adding_widgets_to_a_pdf_document?language=objc)

## 如何借用打印能力静默保存网站为pdf

> 需要用到wkwebview在打印时对网页的分页能力,但是又不能直接对wkwebview进行打印

``` object-c

    NSURL *tempURL = [NSURL fileURLWithPath:[self pathForTemporaryFileWithPrefix:@"pdf"]];

    self.pdfpath = tempURL;

    [info.dictionary addEntriesFromDictionary:@{

                                                    NSPrintJobDisposition: NSPrintSaveJob,

                                                    NSPrintJobSavingURL: tempURL

                                                    }];

```

在此基础上进行静默打印操作, 就会时直接保存

``` object-c

/**

  * 网上抄的 不知道为什么打印机打印到临时目录就可以默认保存, 沙盒目录有权限问题

**/

- (NSString *)pathForTemporaryFileWithPrefix:(NSString *)prefix

{

    NSString *  result;

    CFUUIDRef  uuid;

    CFStringRef uuidStr;

    uuid = CFUUIDCreate(NULL);

    assert(uuid != NULL);

    uuidStr = CFUUIDCreateString(NULL, uuid);

    assert(uuidStr != NULL);

    result = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@", prefix, uuidStr]];

    assert(result != nil);

    CFRelease(uuidStr);

    CFRelease(uuid);

    return result;

}

```

相关文章

网友评论

      本文标题:MacOS Object-c Print 打印相关

      本文链接:https://www.haomeiwen.com/subject/vciifdtx.html