在Objective-C中打印多页

4

我有一个打印函数,代码如下:

- (void)sendToPrinter:(int)code {
    NSPrintInfo *printInfo;
    NSPrintInfo *sharedInfo;
    NSPrintOperation *printOp;
    NSMutableDictionary *printInfoDict;
    NSMutableDictionary *sharedDict;

    sharedInfo = [NSPrintInfo sharedPrintInfo];
    sharedDict = [sharedInfo dictionary];
    printInfoDict = [NSMutableDictionary dictionaryWithDictionary:
                     sharedDict];
    [printInfoDict setObject:NSPrintSpoolJob 
                      forKey:NSPrintJobDisposition];
    printInfo = [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
    [printInfo setHorizontalPagination: NSAutoPagination];
    [printInfo setVerticalPagination: NSAutoPagination];
    [printInfo setVerticallyCentered:NO];
    [printInfo setLeftMargin:10];
    [printInfo setRightMargin:10];
    [printInfo setTopMargin:10];
    [printInfo setBottomMargin:10];
    [printInfo setScalingFactor:1.1];
    printOp = [NSPrintOperation printOperationWithView:sheet 
                                             printInfo:printInfo];
    [printOp setShowsPrintPanel:YES];
    [printOp runOperation];
}

这会打印一个名为sheet的页面预览表示,它是一个NSBox。这个功能很好。

有时候我有更多的信息,无法放在一页上,所以我有“下一页”按钮,通过重新加载相关数据到sheet中,填充了Page2、Page3等的表示。这个功能很好。

现在,如果我想要打印出适合于2或3页而不是1页的信息,我想要在打印之前手动向NSPrintInfoNSPrintOperation添加额外的页面,而不是分页。像这样:

printOp = [NSPrintOperation printOperationWithView:sheet 
                                             printInfo:printInfo];
[self nextPage];
printOp = [NSPrintOperation printOperationWithView:sheet 
                                             printInfo:printInfo];
[self nextPage];
printOp = [NSPrintOperation printOperationWithView:sheet 
                                             printInfo:printInfo];
// run this in loop until all the pages are accounted for
[printOp setShowsPrintPanel:YES];
[printOp runOperation];

有什么解决方案吗?提前感谢您。

我正在研究使用PDFView或Quartz的建议。这可能是我要走的路线,但考虑到我只需打印NSBox,并且通过一种快速的方法可以将整个NSBox更改为后续每一页,这似乎有点太多了。我只希望打印操作可以接受与第2页、第3页等相同的NSBox,并通过调用方法快速更改NSBox到相关页面。 - biscuitstack
还请查看这个教程:http://cocoadevcentral.com/articles/000074.php 它真的帮助了我解决打印问题。 - siannopollo
1个回答

1

使用Cocoa打印系统时无法避免分页;正如您的评论所提到的,您需要转向更低级别的东西。

但是,我认为将您正在做的事情适应分页不应该太难。请查看提供自定义分页方案自定义视图的绘制以进行打印。只需子类化NSBox,提供每个页面大小的矩形,并在beginPageInRect:atPlacement:中调整您的坐标系,以便框绘制到矩形中。您可以使用[[NSPrintOperation currentOperation] currentPage]获取当前页码,以便知道要绘制什么。

更新:事实证明,如果您的视图已经是正确的大小,则甚至不需要修改坐标系。这是一个非常简单的NSBox子类的示例,它只是为每个页面更改其标题:

@implementation NumberBox

- (BOOL)knowsPageRange:(NSRangePointer)aRange;
{
    *aRange = NSMakeRange(1, 10);
    return YES;
}

- (void)beginPageInRect:(NSRect)aRect atPlacement:(NSPoint)location;
{
    [self setTitle:[NSString stringWithFormat:@"Page %d", [[NSPrintOperation currentOperation] currentPage]]];
    [super beginPageInRect:aRect atPlacement:location];
}

- (NSRect)rectForPage:(NSInteger)page;
{
    return [self bounds];
}

@end

可能不太明显的一点是需要调用超类的 beginPageInRect:atPlacement: 实现。此外,不要在 rectForPage: 中绘制,这样会导致无法正常工作—这是 beginPage…/endPage 方法的作用。


子类化NSBox是否提供了直接访问自定义分页(如教程中所示)的便捷方式,还是仅适用于NSView? - biscuitstack
1
它适用于任何NSView子类,包括NSBox。 - Nicholas Riley
啊..出于某种原因,我决定NSBox不是从NSView派生的。现在有意义了。这引起了我的代码中的一些其他问题,所以我要先解决它们,然后再回来处理这个问题,届时我会报告结果。 - biscuitstack
我应该补充说明,我知道你已经指出如何获取当前打印页面。更重要的是,我需要知道当前打印页面何时更改或结束,以调用我的方法并刷新NSBox以显示下一页的数据。 - biscuitstack
1
不要在那个方法里绘制——它不起作用。我用一些示例代码修改了我的答案。事实证明,beginPageInRect:atPlacement:的默认行为非常好;它将您的视图居中显示在页面顶部,而不是在左下角的页面原点处显示(如果没有它,您将得到这样的结果)。 - Nicholas Riley
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接