打印 NSDocument

发布于 2024-08-25 12:07:01 字数 205 浏览 10 评论 0原文

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

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

I'm trying to print a document. The document is an array of NSImageReps, or a single NSPDFImageRep, which has multiple pages. I'm having trouble figuring out how to use the NSPrintOperation class to print this.

The NSPrintOperation seems to need an NSView to print. Do I need to manually add each image into the view at a calculated position and then let it do the pagination? that seems like it isn't in the spirit of Cocoa... is there some technique that I'm missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

手心的海 2024-09-01 12:07:01

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

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

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

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

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

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

Despite this having an accepted answer, it doesn't really answer the basic question, just gives a work-around.

I just had a similar problem (I have an array of objects each rendered by the same NSView subclass, one per page). Here's how I solved it, without the baroque nonsense of creating one giant view that holds all the pages...

1) We have an NSView subclass that has a model associated with it (NSImage in your case, ModelData in my case)

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

2) We have an array var models: [ModelData] in your document controller.

3) Create a new subclass that will be the printer view.

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) Do this in your document controller:

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)
}
∞琼窗梦回ˉ 2024-09-01 12:07:01

你无法打印无法绘制的东西。 NSView 是您绘制想要打印的内容的方式。您可以创建一个仅用于打印的 NSView 子类,通过使用 NSView 的分页方法来决定您希望打印如何工作(例如,您想要一个 NSImageRep 来打印页面 - 任何尺寸的页面吗?)。只需重写knowsPageRange:即可返回YES。

You can't print something that can't be drawn. NSView is how you draw what you want to print. You can make an NSView subclass just for printing that decides how you want the printing to work (e.g. do you want one NSImageRep for page — ANY size page?) by using NSView's pagination methods. Just override knowsPageRange: to return YES.

最偏执的依靠 2024-09-01 12:07:01

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

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

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

请参阅 打印编程主题,或者我在下面引用的书中的完整示例有分页,我没有在此处包含它。看看 自定义分页以获取更多提示。

如果您有基于文档的应用程序和想要转储到打印机的视图,那么在扩展 NSDocumentMyDocument (或您所说的任何名称)中,您将实现

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

:然后 view 使用标准的 drawRect: 进行绘制。

例如,这里 PeopleView 只是绘制一个人员详细信息的 table,它需要一个 NSDictonary 的人员employees

- (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 章“打印”中查找更多详细信息。

You can create view that that displays what you want to print. Then you use it to create print operation.

You would typically created a view that displays your image. You implement an algorithm to figure out what image you want to display on which page. Then you return number of pages available to print and implement method to print specific page.

  • If you have 10 images and you want to
    print one per page that's easy.
  • If you want to print records per page
    and you have 100 records then you
    calculate how many records you can
    fit on a page (using current font
    size and number of lines per record).
  • Then you figure out from records per
    page how many pages you need to
    display all records - this is your
    number of pages (range of pages).
  • When requested to print specific
    range of pages you select the records
    that should be show on given page and
    display them.
  • See references below on how to
    implement these steps. See the
    custom pagination
    info for
    example how to implement these steps, it's not difficult.

See Print Programming Topics, or the full example I reference bellow from the book has pagination which I did not included here. Have a look at the custom pagination for more hints.

If you have Document Based application and a view that you want to dump to printer, then in our MyDocument (or whatever you call it) that extends NSDocument you would implement:

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

The view then uses standard drawRect: for drawing.

Example, here PeopleView just draws a table of people details, it takes a NSDictonary of people employees here:

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

You can look for more details in chapter 27, Printing, in Hillegass' Cocoa Programming For Mac OS X.

舞袖。长 2024-09-01 12:07:01

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

至少理论上,我已经创建了视图,并且出现了打印对话框,但是当我点击“ print" 对话框不会消失......

但这是一个不同的问题。

For Future reference, I believe the answer is PDFViews. you can add a PDFPage all at once to a PDFView (Via a PDFDocument) and then you can print with printWithInfo:autoRotate:

In theory at least, I have gotten the view created, and the print dialog comes up, but when I hit "print" the dialog doesn't disappear...

But that's a different question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文