gpt4 book ai didi

objective-c - 使用内存中的 UIWebView 在 PhoneGap 中生成 PDF

转载 作者:搜寻专家 更新时间:2023-10-30 19:49:49 25 4
gpt4 key购买 nike

我正在研究如何做到这一点。

注意:我不是经验丰富的 Objective-C 开发人员(因此我首先使用 PhoneGap)

缺点:我的 UIWebView(不,不是呈现 web 应用程序的 PhoneGap,是在内存中创建的第二个 UIWebView,不可见)没有呈现到 PDF 中。我刚得到一个空白的 PDF。我会发布一些我的想法和代码,希望有人会知道我做错了什么。


我的起点是这里已经有一个 PhoneGap 的打印插件:

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

此插件即时创建一个 UIWebView,您通过 JavaScript 将一些 HTML 传递给它,然后它调用一些打印 Controller 来进行打印。

所以我从中借鉴了一些想法。然后我注意到这篇关于生成 PDF 的很棒的博客文章

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

所以我试图将两者结合到我自己的 PhoneGap 插件中,以获取一些 HTML(来 self 的网络应用程序)并即时生成 PDF。

标题:

#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

主要内容:

#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 没有渲染任何东西。也许是第一个问题的症状?

我该如何调试并找出问题所在?


更新

我很确定将 UIWebView 层渲染到图像上下文中可能是不可能的,除非 UIWebView 实际上是可见的。

我不确定 PhoneGap PrintPlugin 是如何工作的。它似乎渲染它的 UIWebView 非常好,因为它不可见。

我目前正在尝试将实际的 PhoneGap UIWebView 呈现为 PDF(与我自己的 UIWebView 相对)。但这并不理想。

  • 这意味着我必须隐藏所有工具栏和诸如此类的东西,然后平移 UIWebView,这样我才能捕获视口(viewport)之外的所有内容。这并不理想,因为用户会在视觉上看到这种情况的发生!

  • 上面的第 1 点似乎无论如何都行不通,因为 iPad 在动态摆弄布局时更新屏幕的速度太慢。在 iPad 上,如果您非常快速地进行视觉操作(例如左右摇动屏幕),iPad 会太慢并且不会显示它。您最终只能看到最终状态。所以当我截取屏幕截图时,屏幕在视觉上没有平移(即使 DOM 说它有)。 (希望这是有道理的)。

啊,令人沮丧。

最佳答案

我现在有了一个可行的解决方案,但它并不理想。

我所做的是将 phonegap UIWebView 渲染到 PDF 中。

要做到这一点是相当棘手的。我有几个 objective-c 函数

- (void) takeScreenshot;

- (void) renderPdf;

我从 Javascript 调用。

然后我必须编写一个递归 JS 算法,在调用 takeScreenshot 时向各个方向平移屏幕。

在对 takeScreenshot 的调用之间,我使用了 setTimeout,它在 JS 处理中提供了 20 毫秒的中断 - iPad 有足够的时间更新屏幕,以便下一个屏幕截图可以被带走。

这是一种皇家的痛苦。赏金仍然开放,以防有人知道更好的处理方法 - 我很想知道!

关于objective-c - 使用内存中的 UIWebView 在 PhoneGap 中生成 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9167598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com