首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我试图将一个NSPrintOperation保存为PDF时,为什么WebView要创建一个空的WebView?

当我试图将一个NSPrintOperation保存为PDF时,为什么WebView要创建一个空的WebView?
EN

Stack Overflow用户
提问于 2014-10-07 07:03:48
回答 2查看 807关注 0票数 2

我正在尝试将HTML转换为OS上的PDF文件。经过深入研究,我发现最好的方法是使用NSPrintOperation。下面是我用来将HTML字符串转换为PDF的代码:

代码语言:javascript
复制
WebView *webview = [[WebView alloc] init];
[webview.mainFrame loadHTMLString:htmlString baseURL:nil];

NSDictionary *printOpts = @{
                            NSPrintJobDisposition: NSPrintSaveJob,
                            NSPrintSavePath: outputFilePath
                            };
NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printOpts];
printInfo.horizontalPagination = NSAutoPagination;
printInfo.verticalPagination = NSAutoPagination;
NSPrintOperation *printOp = [NSPrintOperation 
                             printOperationWithView:webview.mainFrame.frameView.documentView
                                          printInfo:printInfo];
printOp.showsPrintPanel = NO;
printOp.showsProgressPanel = NO;

[printOp runOperation];

此代码确实生成PDF文件,但PDF文件为空。是因为WebView没有框架吗?我试过使用dataWithPDFInsideRect:,但这也不起作用。

我是否应该用一个A4工作表大小的框架初始化网页?还是别的地方出了问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-14 11:55:19

我知道这是个老生常谈,但我想贴出我今天想出的解决方案。由于WebViews负载是异步的,关键是设置一个框架加载委托回调,然后在运行循环中运行,直到框架完成加载。

下面的代码创建了一个新的WebView,然后将一个HTML加载到其中:

代码语言:javascript
复制
// Clear the loaded flag
_webViewIsLoaded = NO;

// Fetch the default paper size and init print settings
NSPrintInfo * sharedInfo = [NSPrintInfo sharedPrintInfo];
NSMutableDictionary * sharedDict = [sharedInfo dictionary];
NSMutableDictionary * printInfoDict = [NSMutableDictionary dictionaryWithDictionary:sharedDict];
NSRect printRect = NSZeroRect;
printRect.size = [sharedInfo paperSize];

// Create a new web view
WebView * printView = [[WebView alloc] initWithFrame:printRect];
[printView setFrameLoadDelegate:self];

// Configure the WebView
WebPreferences * preferences = [[WebPreferences alloc] initWithIdentifier:@"com.id.here"];
[preferences setShouldPrintBackgrounds:YES];
[preferences setAllowsAnimatedImageLooping:NO];
[preferences setJavaScriptCanOpenWindowsAutomatically:NO];
[preferences setAutosaves:NO];
[preferences setJavaEnabled:NO];
[preferences setJavaScriptEnabled:NO];
[preferences setCacheModel:WebCacheModelDocumentViewer];        // most memory-efficient setting
[preferences setPlugInsEnabled:NO];                             // disable plugins
[printView setPreferences:preferences];

// Load the HTML file
NSURL * url = [NSURL fileURLWithPath:htmlPath];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
[[printView mainFrame] loadRequest:request];

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

NSPrintInfo * printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];
[printInfo setHorizontalPagination:NSFitPagination];
[printInfo setVerticalPagination:NSAutoPagination];
[printInfo setVerticallyCentered:NO];
[printInfo setHorizontallyCentered:YES];

// Wait for the frame to finish loading
while(!_webViewIsLoaded)
{
    @autoreleasepool
    {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.005]];
    }
}

NSPrintOperation * printOp = [NSPrintOperation printOperationWithView:[[[printView mainFrame] frameView] documentView]
                                                            printInfo:printInfo];
[printOp setShowsProgressPanel:YES];
[printOp setShowsPrintPanel:NO];
[printOp runOperation];

接下来,我的frame委托方法在框架完全加载后设置一个标志,并调整帧的高度大小以与内容的高度匹配:

代码语言:javascript
复制
-(void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)webFrame
{
    _webViewIsLoaded = YES;

    NSRect webFrameRect = [[[webFrame frameView] documentView] frame];
    NSRect webViewRect = [webView frame];

    // Resize the webview so it fits all of its contents
    NSRect newWebViewRect = NSMakeRect(webViewRect.origin.x,
                                   webViewRect.origin.y - (NSHeight(webFrameRect) - NSHeight(webViewRect)),
                                   NSWidth(webViewRect),
                                   NSHeight(webFrameRect));
    [webView setFrame:newWebViewRect];
}

这样可以很好地将HTML文档保存到PDF中。

票数 3
EN

Stack Overflow用户

发布于 2014-10-08 19:14:07

试试这个:

代码语言:javascript
复制
 NSPrintOperation *printOp = [NSPrintOperation
                             printOperationWithView:[[[webview mainFrame] frameView] documentView] printInfo:printInfo];

而不是:

代码语言:javascript
复制
NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:webview.mainFrame.frameView.documentView
                             printInfo:printInfo];

(这应有效:)

编辑:这是我使用的完整代码

代码语言:javascript
复制
NSString *htmlString = @"<html><head></head><body><h1>Hello, World</h1></body></html>";

WebView *webview = [[WebView alloc] init];
[webview.mainFrame loadHTMLString:htmlString baseURL:nil];

NSString* outputFilePath = @"/Users/YOUR-USERNAME/Documents/MyAwesomePDF.pdf";
NSURL *url = [[NSURL alloc] initWithString:outputFilePath];

NSDictionary *printOpts = @{
                            NSPrintJobDisposition: NSPrintSaveJob,
                            NSPrintSaveJob: url
                            };
NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printOpts];
printInfo.horizontalPagination = NSAutoPagination;
printInfo.verticalPagination = NSAutoPagination;



NSPrintOperation *printOp = [NSPrintOperation
                             printOperationWithView:[[[webview mainFrame] frameView] documentView] printInfo:printInfo];
printOp.showsPrintPanel = NO;
printOp.showsProgressPanel = NO;

[printOp runOperation];
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26230344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档