2012-02-06 26 views
4

我正在嘗試解決如何執行此操作。使用內存中的UIWebView在PhoneGap中生成PDF

注意:我不是一個有經驗的Objective-C開發者(因此爲什麼我首先使用PhoneGap的)

這樣做的缺點:我的UIWebView(不,不是的PhoneGap一個呈現webapp,第二個UIWebView在內存中創建並且不可見)不會呈現到PDF中。我只是得到一個空白的PDF。我會發布我的一些想法和代碼,希望有人會知道我做錯了什麼。


我的起點是,已經有針對PhoneGap的打印插件在這裏:

https://github.com/phonegap/phonegap-plugins/tree/master/iPhone/PrintPlugin

此插件創建於即時,你通過JavaScript傳遞一些HTML給它一個UIWebView ,然後它調用一些打印控制器來執行打印。

所以我借用了一些想法。然後,我注意到了生成這個真棒博客文章PDF的

http://www.ioslearner.com/convert-html-uiwebview-pdf-iphone-ipad/

所以我試圖將兩者結合到我自己的PhoneGap插件採取了一些HTML(從我的Web應用程序),並生成PDF上the-飛。

部首:

#import <Foundation/Foundation.h> 
#import <QuartzCore/QuartzCore.h> 

#ifdef PHONEGAP_FRAMEWORK 
#import <PhoneGap/PGPlugin.h> 
#else 
#import "PGPlugin.h" 
#endif 


@interface ExportPlugin : PGPlugin <UIWebViewDelegate> { 
    NSString* exportHTML; 
} 

@property (nonatomic, copy) NSString* exportHTML; 

//This gets called from my HTML5 app (Javascript): 
- (void) exportPdf:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; 

@end 

MAIN:

#import "ExportPlugin.h" 

@interface ExportPlugin (Private) 
-(void) doExport; 
-(void) drawPdf; 
@end 

@implementation ExportPlugin 

@synthesize exportHTML; 

- (void) exportPdf:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options{ 
    NSUInteger argc = [arguments count]; 

    if (argc < 1) { 
     return; 
    } 
    self.exportHTML = [arguments objectAtIndex:0]; 

    [self doExport]; 
} 

int imageName = 0; 
double webViewHeight = 0.0; 

- (void) doExport{ 
    //Set the base URL to be the www directory. 
    NSString *dbFilePath = [[NSBundle mainBundle] pathForResource:@"www" ofType:nil ]; 
    NSURL *baseURL = [NSURL fileURLWithPath:dbFilePath]; 

    //Load custom html into a webview 
    UIWebView *webViewExport = [[UIWebView alloc] init]; 
    webViewExport.delegate = self; 
    //[webViewExport loadHTMLString:exportHTML baseURL:baseURL]; 
    [webViewExport loadHTMLString:@"<html><body><h1>testing</h1></body></html>" baseURL:baseURL]; 
} 

- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{ 
    return YES; 
} 

- (void)webViewDidFinishLoad:(UIWebView *)webViewExport 
{   
    webViewHeight = [[webViewExport stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"] integerValue]; 

    CGRect screenRect = webViewExport.frame; 

    //WHY DO I HAVE TO SET THE SIZE? OTHERWISE IT IS 0 
    screenRect.size.width = 768; 
    screenRect.size.height = 1024; 

    double currentWebViewHeight = webViewHeight; 
    while (currentWebViewHeight > 0) 
    { 
     imageName ++; 

     UIGraphicsBeginImageContext(screenRect.size); 
     CGContextRef ctx = UIGraphicsGetCurrentContext(); 

     //[[UIColor blackColor] set]; 
     //CGContextFillRect(ctx, screenRect); 

     [webViewExport.layer renderInContext:ctx]; 

     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 

     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 
     NSString *pngPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",imageName]]; 

     if(currentWebViewHeight < 960) 
     { 
      CGRect lastImageRect = CGRectMake(0, 960 - currentWebViewHeight, webViewExport.frame.size.width, currentWebViewHeight); 
      CGImageRef imageRef = CGImageCreateWithImageInRect([newImage CGImage], lastImageRect);  

      newImage = [UIImage imageWithCGImage:imageRef]; 
      CGImageRelease(imageRef); 
     } 
     [UIImagePNGRepresentation(newImage) writeToFile:pngPath atomically:YES]; 

     [webViewExport stringByEvaluatingJavaScriptFromString:@"window.scrollBy(0,960);"]; 

     currentWebViewHeight -= 960; 
    } 

    [self drawPdf]; 
} 

- (void) drawPdf 
{ 
    CGSize pageSize = CGSizeMake(612, webViewHeight); 
    NSString *fileName = @"Demo.pdf"; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName]; 

    UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil); 

    // Mark the beginning of a new page. 
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil); 

    double currentHeight = 0.0; 
    for (int index = 1; index <= imageName ; index++) 
    { 
     NSString *pngPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png", index]]; 
     UIImage *pngImage = [UIImage imageWithContentsOfFile:pngPath]; 

     [pngImage drawInRect:CGRectMake(0, currentHeight, pageSize.width, pngImage.size.height)]; 
     currentHeight += pngImage.size.height; 
    } 

    UIGraphicsEndPDFContext(); 
} 

@end 

的第一個跡象的東西是不正確的,是上面我必須設置UIWebView.frame大小:

screenRect.size.width = 768; 
screenRect.size.height = 1024; 

但爲什麼? PhoneGap PrintPlugin不必這樣做。如果我沒有設置它,大小爲0,然後我得到很多上下文錯誤。

然後接下來的問題是UIWebView沒有渲染任何東西。第一個問題的症狀可能是什麼?

我該如何解決這個問題並找出問題所在?


UPDATE

我敢肯定,它可能無法在一個UIWebView層呈現的圖像內容,除非一個UIWebView實際上是可見的。

我不確定PhoneGap PrintPlugin是如何工作的。它似乎呈現它的UIWebView相當好,它不可見。

我目前正在嘗試將實際的PhoneGap UIWebView渲染到PDF中(而不是我自己的UIWebView)。但這並不理想。

  • 這意味着我不得不隱藏所有工具欄和諸如此類的東西,然後的UIWebView的周圍,所以我捕捉到視區之外的一切。這並不理想,因爲用戶會直觀地看到發生這種情況!

  • 以上第1點似乎無法正常工作,因爲iPad在動態地擺弄佈局時更新屏幕太慢。在iPad上,如果你非常快速地做視覺事情(例如平移屏幕),iPad太慢而不會顯示它。你最終只看到最終狀態。所以當我截取屏幕截圖時,屏幕在視覺上並沒有平移(儘管DOM說它有)。 (希望是有道理的)。

唉,令人沮喪。

回答

1

我現在有一個工作解決方案,但它不是理想的。

我所做的就是將電話UIWebView渲染到PDF中。

要做到這一點非常棘手。我有幾個Objective-C功能

- (void) takeScreenshot; 

- (void) renderPdf; 

我從Javascript調用。

然後,我必須編寫一個遞歸JS算法,它可以在每個方向上平移屏幕,同時調用takeScreenshot

在對takeScreenshot的調用之間,我使用了setTimeout,它在JS處理中給出了20毫秒的中斷時間 - iPad有足夠的時間更新屏幕,因此可以拍攝下一個屏幕快照。

這是屁股的皇家痛苦。如果有人知道處理這個問題的更好方法,賞金仍然是開放的 - 我會很好奇知道!

-1

這裏是如何呈現在PDF一個UIWebView(網頁是你的UIWebView),您的代理(這裏的「自我」)可以實現UIWebViewDelegate協議:

- (void)loadingPDFwithURL:(NSURL *)anURL { 
    CGRect appFrame = [[UIScreen mainScreen] applicationFrame]; 
    appFrame.origin.y = 0; 
    [self.webPage initWithFrame:appFrame]; 
    [self.webPage setScalesPageToFit:YES]; 
    [self.webPage setDelegate:self]; 
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:anURL]; 
    [self.webPage loadRequest:requestObj]; 
    [self.view addSubview:self.webPage]; 
} 

所以你給的網址PDF(如果它在內存中,只需將該文件寫入應用程序中,因爲該URL可以是文件路徑)。

另一種可能性是潛入CGPdf,但它變得越來越困難。

+0

我實際上需要相反的 - 將UIWebView的內容呈現爲PDF – asgeo1 2012-02-15 19:52:19

0

如果你想呈現一個UIWebView成PDF,我覺得你可以去這樣的:

1 /使用convertRect:你的UIWebView對象實現fromView方法來獲得的CGRect

2 /看到UIPrintPageRenderer Class Reference做出那樣打印預覽

3 /使用UIGraphicsGetCurrentContext得到CGContextRef出它

4 /創建從的CGRect和CGContextRef的PDF(您可以使用所提供的幫助Apple sample code zoomingPDFViewer用於使用CGPdf構建PDF