2012-02-06 18 views
4

私はこれを行う方法を工夫しています。メモリ内のUIWebViewを使用してPhoneGapでPDFを生成する

注:私はそれの短い経験豊富なObjective-Cの開発者(したがって、なぜ私は最初の場所でのPhoneGapを使用しています)

ないよ:私のUIWebView(いや、ないのPhoneGapの1 Webアプリケーションをレンダリングします.2番目のUIWebViewはメモリ内に作成され、表示されません)、PDFにレンダリングされません。私はただ空白のPDFを取得します。私は思考とコードのいくつかを投稿し、うまくいけば誰かが私が間違っていることを知っているだろう。


私の出発点は、ここではPhoneGapのための印刷プラグインがすでに存在することである:

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

このプラグインは、オンザフライのUIWebViewを作成し、あなたはJavaScriptを経由して、それにいくつかのHTMLを渡します印刷を行うために何らかの印刷コントローラを呼び出す。

私はそれからいくつかのアイデアを借りました。それから私は、だから私は(私のWebアプリケーションからの)いくつかのHTMLを取り、上・ザPDFを生成するために私自身のPhoneGapプラグインに2を結合しようとしているPDFの

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

を生成する上で、この素晴らしいブログ記事に気づきました飛ぶ。

HEADER:

#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をレンダリングするようです。

私は現在、自分のUIWebViewではなく、実際のP​​honeGap UIWebViewをPDFにレンダリングしようとしています。しかしこれは理想的ではありません。

  • それは私がビューポートの外にすべてを取り込むので、私は周りのUIWebViewをすべてのツールバーやその他もろもろを非表示にする必要があり、その後、パンを意味します。これは理想的ではありません。なぜなら、ユーザーはこれが視覚的に見えるからです!

  • iPadがあまりにも遅すぎてレイアウトを動的に操作しても画面を更新できないため、上記のポイント1はうまく動作していないようです。 iPad上で、ビジュアルをすばやく行うと(画面をパンするように)、iPadは遅すぎて、それを表示しません。あなたは最終状態を見るだけになります。だから私がスクリーンショットを撮ると、画面は視覚的にパンされていない(たとえDOMが持っていると言っても)。 (ホープは意味をなさないと思う)。

大変です。

答えて

1

私は実用的な解決策を得ましたが、それは理想的ではありません。

私がやっていることは、phonegap UIWebViewをPDFにレンダリングすることです。

これを行うには非常に手間がかかります。私はJavascriptから呼び出すいくつかのobjective-c関数を持っています。

- (void) takeScreenshot; 

- (void) renderPdf; 

次に、takeScreenshotを呼び出しながら、すべての方向に画面をパンする再帰的なJSアルゴリズムを記述する必要があります。

への呼び出しの間に、私はを使用します。これは、JS処理で20ミリ秒の休憩を与えます。iPadが画面を更新して次のスクリーンショットを撮るのに十分な時間です。

これはお尻の王様の痛みでした。 Bountyは誰かがこれに対処するより良い方法を知っている場合に備えてまだ開いています - 私は知ることが非常に不思議です!

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

ですからのURLを与えている:ここで

-1

はUIWebViewDelegateプロトコルを実装することができ(ここでは「自己」)、(WebページがあなたのUIWebViewである)のUIWebViewであなたのデリゲートをPDFにレンダリングする方法でありますPDF(メモリに保存されている場合は、URLをファイルパスにすることができるため、アプリケーションにファイルを書き込むだけです)。

もう一つの可能​​性は、CGPdfに飛び込むことですが、難しくなります。あなたはPDFへのUIWebViewをレンダリングしたい場合

+0

実際には逆のことが必要です - UIWebViewの内容をPDFにレンダリングする – asgeo1

0

は、私はあなたがこのために行くことができると思う:

1/convertRect使用しますCGRectを得るためにあなたのUIWebViewオブジェクトによって実装さfromView方法を

2/

4/CGRectとCGContextRefからPDFを作成してそこからCGContextRefを取得するために、印刷プレビュー

3 /使用UIGraphicsGetCurrentContextようにするためにUIPrintPageRenderer Class Referenceを参照してください(あなたはで提供されるヘルプを使用することができますApple sample code zoomingPDFViewer CGPdfを使用してPDFを作成する

関連する問題