以编程方式从 iOS 中的 UIWebView 生成多页 PDF

Generate multipage PDF from a UIWebView in iOS programmatically

我正在将 www.whosebug.com 加载到我应用程序的 UIWebView 中。我使用以下代码片段生成 pdf:

NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString *pdfFileName = [documentDirectory stringByAppendingPathComponent:@"mypdf.pdf"];
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);

CGRect PDFRect = CGRectMake(0, 0, self.webView.frame.size.width, self.webView.frame.size.height);
UIGraphicsBeginPDFPageWithInfo(PDFRect, nil);

CGContextRef pdfContext = UIGraphicsGetCurrentContext();
CGContextScaleCTM(pdfContext, 1, 1);
[self.webView.layer renderInContext:pdfContext];
UIGraphicsEndPDFContext();

生成pdf时,只会生成网站第一个可见页面的PDF。 Whosebug 站点在屏幕下方有几个页面,它是可滚动的。我需要将网站的整个页面转换为 PDF。 现在,当我生成 PDF 时,它只有一页。我想要多页的PDF,根据加载网站的内容大小高度。

应该怎么做才能达到同样的效果?

我找到了解决办法:

- (IBAction)showWebView:(id)sender {
  self.webView.hidden = NO;
  self.webView.delegate=self;
  [self.webView setScalesPageToFit:YES];
  NSMutableURLRequest * request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.whosebug.com"]];
  [self.webView loadRequest:request];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
   //Check here if still webview is loding the content
    if (webView.isLoading)
    return;
    else //finished loading
    [self performSelector:@selector(createPDF) withObject:nil afterDelay:0];
}


-(void)createPDF
{
 CGRect origframe = self.webView.frame;
 NSString *heightStr = [self.webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"]; // Get the height of our webView
 int height = [heightStr intValue];

// Size of the view in the pdf page
CGFloat maxHeight   = 568;
CGFloat maxWidth    = self.webView.frame.size.width;
int pages = ceil(height / maxHeight);
// gets the total no:of pages needed in PDF

[self.webView setFrame:CGRectMake(0.f, 0.f, maxWidth, maxHeight)];

NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString *pdfFileName = [documentDirectory stringByAppendingPathComponent:@"mypdf.pdf"];
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);

int i = 0;
for ( ; i < pages; i++)
{
    if (maxHeight * (i+1) > height)
    { // Check to see if page draws more than the height of the UIWebView
        CGRect f = [self.webView frame];
        f.size.height -= (((i+1) * maxHeight) - height);
        [self.webView setFrame: f];
    }

    // Specify the size of the pdf page
    CGRect PDFRect = CGRectMake(0, 0, self.webView.frame.size.width, self.webView.frame.size.height);
    UIGraphicsBeginPDFPageWithInfo(PDFRect, nil);

    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    // Move the context for the margins
    CGContextScaleCTM(currentContext, 1, 1);
    // offset the webview content so we're drawing the part of the webview for the current page
    [[[self.webView subviews] lastObject] setContentOffset:CGPointMake(0, maxHeight * i) animated:NO];
    // draw the layer to the pdf, ignore the "renderInContext not found" warning.
    [self.webView.layer renderInContext:currentContext];
}
// all done with making the pdf
UIGraphicsEndPDFContext();
// Restore the webview and move it to the top.
[self.webView setFrame:origframe];
[[[self.webView subviews] lastObject] setContentOffset:CGPointMake(0, 0) animated:NO];

}