4

我正在尝试打印文档。该文档是一个 NSImageRep 数组,或者是一个 NSPDFImageRep,它有多个页面。我无法弄清楚如何使用 NSPrintOperation 类来打印它。

NSPrintOperation 似乎需要一个 NSView 来打印。我是否需要手动将每个图像添加到视图中的计算位置,然后让它进行分页?这似乎不符合 Cocoa 的精神......我是否缺少一些技术?

4

4 回答 4

3

尽管这有一个公认的答案,但它并没有真正回答基本问题,只是提供了一种解决方法。

我刚刚遇到了类似的问题(我有一组对象,每个对象都由同一NSView个子类呈现,每页一个)。这就是我解决它的方法,没有巴洛克式的废话,即创建一个包含所有页面的巨型视图......

1)我们有一个NSView子类,它有一个与之关联的模型(NSImage在你的情况下,ModelData在我的情况下)

class BaseView: NSView {
    var modelData: ModelData /* Whatever your view needs to draw */
    //...
}

var models: [ModelData]2)我们在您的文档控制器中有一个数组。

3) 创建一个新的子类作为打印机视图。

class PrinterView: BaseView {
    var pageIndex: Int = 1
    var modelArray: [ModelData]

    init(frame: NSRect, models: [ModelData]) {
        self.modelArray = models
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("invalid initializer")
    }

    override func knowsPageRange(_ range: NSRangePointer) -> Bool {
        range.pointee.location = 1
        range.pointee.length = self.modelArray.count
        return true
    }

    override func rectForPage(_ page: Int) -> NSRect {
        self.pageIndex = page
        return self.bounds
    }

    override func draw(_ dirtyRect: NSRect) {
        self.model = self.modelArray[self.page - 1] // Pages are 1, not 0, based
        super.draw(dirtyRect)
    }
} // That's it! That's all...

4)在您的文档控制器中执行此操作:

override func printOperation(withSettings printSettings: [String : Any]) throws -> NSPrintOperation {
    self.printInfo.horizontalPagination = .fitPagination
    self.printInfo.verticalPagination = .clipPagination
    let printView = PrinterView(size: self.printInfo.paperSize, models: self.models)

    return NSPrintOperation(view: printView, printInfo: self.printInfo)
}
于 2017-04-13T14:36:14.557 回答
1

您可以创建显示您要打印的内容的视图。然后你用它来创建打印操作。

您通常会创建一个显示图像的视图。您实现了一种算法来确定要在哪个页面上显示什么图像。然后返回可打印的页数并实现打印特定页面的方法。

  • 如果您有 10 张图像,并且您想每页打印一张,这很容易。
  • 如果要每页打印记录并且有 100 条记录,则计算一页可以容纳多少条记录(使用当前字体大小和每条记录的行数)。
  • 然后你从每页的记录中计算出你需要多少页来显示所有记录——这是你的页数(页面范围)。
  • 当要求打印特定范围的页面时,您选择应该在给定页面上显示的记录并显示它们。
  • 请参阅下面的参考资料,了解如何实施这些步骤。请参阅自定义分页信息,例如如何实现这些步骤,这并不难。

请参阅Print Programming Topics,或者我在本书下面引用的完整示例有分页,我没有在这里包含。查看自定义分页以获取更多提示。

如果您有基于文档的应用程序和要转储到打印机的视图,那么在我们的MyDocument(或您所称的)扩展中,NSDocument您将实现:

- (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps
                                           error:(NSError **)e

然后视图使用标准drawRect:进行绘图。

例如,这里PeopleView只画了一个table人的细节,这里需要一个NSDictonaryemployees

- (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps
                                           error:(NSError **)e
{
    PeopleView * view = [[PeopleView alloc] initWithPeople:employees];
    NSPrintInfo * printInfo = [self printInfo];
    NSPrintOperation * printOp
        = [NSPrintOperation printOperationWithView:view
                                         printInfo:printInfo];
    [view release];
    return printOp;
}

您可以在 Hillegass 的 Cocoa Programming For Mac OS X 中的第 27 章“打印”中查找更多详细信息。

于 2010-03-18T23:38:06.657 回答
1

您无法打印无法绘制的东西。NSView 是您绘制想要打印的内容的方式。您可以使用 NSView 的分页方法创建一个仅用于打印的 NSView 子类,该子类决定您希望打印的工作方式(例如,您是否想要一个 NSImageRep 用于页面 - 任何大小的页面?)。只需覆盖knowsPageRange:以返回 YES。

于 2010-03-18T20:00:33.343 回答
0

对于未来的参考,我相信答案是 PDFViews。您可以一次将 PDFPage 添加到 PDFView(通过 PDFDocument),然后您可以使用 printWithInfo:autoRotate 进行打印:

至少在理论上,我已经创建了视图,并且出现了打印对话框,但是当我点击“打印”时,对话框并没有消失......

但这是一个不同的问题。

于 2010-03-18T21:53:55.937 回答