【问题标题】:Issues in generating PDF from uiwebview in objective c在目标 c 中从 uiwebview 生成 PDF 的问题
【发布时间】:2015-03-06 13:07:56
【问题描述】:

我在 uiwebview 中打开了 pdf 文件,在 uiwebview 子视图中添加了图像和文本。然后我尝试创建了 pdf 文件。下面的示例我用来生成 pdf 文件。单页多页书写。我怎样才能写出样品质量和确切尺寸。 请查看屏幕截图及以下来源

UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, nil );

for (int i = 0; i < 10; i++) {

    CGRect f = [pdfView frame];
    [pdfView setFrame: f];

    UIGraphicsBeginPDFPage();
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(currentContext, 72, 72); // Translate for 1" margins
    [[[pdfView subviews] lastObject] setContentOffset:CGPointMake(0, 648 * i) animated:NO];
    [pdfView.layer renderInContext:currentContext];
}

UIGraphicsEndPDFContext();

我也尝试过以下链接,但我无法添加 uiwebview 子视图来编写 pdf。 http://b2cloud.com.au/tutorial/drawing-over-a-pdf-in-ios-pdf-template/

【问题讨论】:

    标签: ios objective-c uiwebview pdf-generation uigraphicscontext


    【解决方案1】:

    您可以在 UIView 上使用以下类别来创建 PDF 文件:

    #import <QuartzCore/QuartzCore.h>
    
    @implementation UIView(PDFWritingAdditions)
    
    - (void)renderInPDFFile:(NSString*)path
    {
        CGRect mediaBox = self.bounds;
        CGContextRef ctx = CGPDFContextCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path], &mediaBox, NULL);
    
        CGPDFContextBeginPage(ctx, NULL);
        CGContextScaleCTM(ctx, 1, -1);
        CGContextTranslateCTM(ctx, 0, -mediaBox.size.height);
        [self.layer renderInContext:ctx];
        CGPDFContextEndPage(ctx);
        CFRelease(ctx);
    }
    
    @end
    

    坏消息:UIWebView 不会在 PDF 中创建漂亮的形状和文本,而是将自身呈现为 PDF 中的图像。

    How to Convert UIView to PDF within iOS?

    Creating PDF file from UIWebView

    这可能对你有帮助:)

    【讨论】:

    • 感谢您的回答。我会检查它然后让你知道。但是一件事如果我们添加“renderInContext”我们就会失去我们的质量
    • 我尝试从 UIwebview 创建 PDF 文件,但我得到的高度字符串为空。 NSString *heightStr = [webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"];
    • 如果我们使用“renderInContext”页面质量缺失。请指教
    【解决方案2】:

    我也使用了相同的工作正常希望这对你有帮助。

    创建一个块:-
    typedef void (^PdfCompletion)(BOOL 状态,NSString *filePath,NSArray *fbArr);

    -(void)addData
    {
        [MBProgressHUD showHUDAddedTo:self.view animated:YES];
        NSMutableDictionary *contactDict = [[NSMutableDictionary alloc] init];
        [contactDict setObject:contactTextField.text forKey:@"phonenumber"];
        [contactDict setObject:emailTextField.text forKey:@"emailid"];
        [contactDict setObject:userNameLabel.text forKey:@"displayname"];
        [self drawPdf:contactDict completion:^(BOOL status,NSString *filePath,NSArray *fbArr)
         {
             if (status)
             {
                 NSMutableArray *arr;
                 arr = [[NSMutableArray alloc] init];
                 NSData *filedata;
                 filedata = [NSData dataWithContentsOfFile:filePath];
                 double locaTotalFileSize = filedata.length +498;
                 totalFileSize += locaTotalFileSize;
                 NSMutableDictionary *fileDict = [[NSMutableDictionary alloc] init];
                 [fileDict setObject:userPicImageView.image forKey:@"image"];
                 [fileDict setObject:filePath forKey:@"filePath"];
                 [fileDict setObject:@"txt" forKey:@"fileType"];
                 [fileDict setObject:[NSString stringWithFormat:@"%@_%@_%@",@"contact",[self getFbID],[self CurrentSystemTime]] forKey:@"fileName"];
                 [fileDict setObject:@"1" forKey:@"uploadStatus"];
                 [fileDict setObject:@"0 KB/0 KB" forKey:@"fileSizeStatus"];
                 [fileDict setObject:@"0 KB/0 KB" forKey:@"ContentSize"];
                 [arr addObject:fileDict];
                 [self switchToReviewFiles:arr];
                 //////NSLog(@"pdf convrt successfull");
             }
             else
             {
                 //////NSLog(@"Error to convert into pdf");
             }
         }];
    }
    
    
     // Then Call The DrawPDF Method::--
    
     -(void)drawPdf:(NSMutableDictionary *)drawText completion:(PdfCompletion)callback
    {
        NSString* fileName = @"contact_card.txt";
    
        NSArray *arrayPaths =
        NSSearchPathForDirectoriesInDomains(
                                            NSDocumentDirectory,
                                            NSUserDomainMask,
                                            YES);
        NSString *path = [arrayPaths objectAtIndex:0];
        NSString* txtFileName = [path stringByAppendingPathComponent:fileName];
    
        NSData *data = [NSJSONSerialization dataWithJSONObject:drawText options:NSJSONWritingPrettyPrinted error:nil];
        [data writeToFile:txtFileName atomically:YES];
         callback(YES,txtFileName,nil);
    
    }
    

    【讨论】:

    • Vinod Pandey 感谢您的回复。我会测试然后更新你。今天只有我久别重逢来了
    【解决方案3】:

    在我看来,您只是想向现有 PDF 添加内容,对吧?

    - (void) drawCustomPDFContent
    {
        //  Put your drawing calls here
        //  Draw a red box
        [[UIColor redColor] set];
        UIRectFill(CGRectMake(20, 20, 100, 100));
    
        //  Example of drawing your view into PDF, note that this will be a rasterized bitmap, including the text.
        //  To get smoother text you'll need to use the NSString draw methods
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        [view.layer renderInContext:ctx];
    }
    
    - (void) createCustomPDF
    {
        NSURL* pdfURL = ... /* URL to pdf file */;
        CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
    
        const size_t numberOfPages = CGPDFDocumentGetNumberOfPages(pdf);
    
        NSMutableData* data = [NSMutableData data];
        UIGraphicsBeginPDFContextToData(data, CGRectZero, nil);
    
        for(size_t page = 1; page <= numberOfPages; page++)
        {
            //  Get the current page and page frame
            CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdf, page);
            const CGRect pageFrame = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);
    
            UIGraphicsBeginPDFPageWithInfo(pageFrame, nil);
    
            //  Draw the page (flipped)
            CGContextRef ctx = UIGraphicsGetCurrentContext();
            CGContextSaveGState(ctx);
            CGContextScaleCTM(ctx, 1, -1);
            CGContextTranslateCTM(ctx, 0, -pageFrame.size.height);
            CGContextDrawPDFPage(ctx, pdfPage);
            CGContextRestoreGState(ctx);
    
            if(page == 1)
            {
                [self drawCustomPDFContent];
            }
        }
    
        UIGraphicsEndPDFContext();
    
        CGPDFDocumentRelease(pdf);
        pdf = nil;
    
        //  Do something with data here
        [data writeToFile:... atomically:YES];
    }
    

    引用的部分:

    http://b2cloud.com.au/tutorial/drawing-over-a-pdf-in-ios-pdf-template/

    【讨论】:

    • 是的,我只是在现有 PDF 中绘制内容。我在 uiwebview 中查看了 pdf 文件
    • 如果您遇到的问题是在现有 PDF 之上绘图,请试一试我的代码,您需要进行一些更改才能使其适用于您的场景。跨度>
    • 如何添加绘制所有子视图(更多)?请指教
    • Someguy 工作正常。但是我已经在用户触摸的 uiwebview 子视图中写了图像。当我生成 pdf 确切的 GCpoint 时,我不想写? Bz pdf UIWebview 的原始大小差异。请告诉我它将如何解决?
    • @2vision2 你可以使用任何你需要的自定义绘图代码,如果你已经有你想要绘制的视图,你可以尝试其他人也建议的相同的 renderInContext 方法调用
    【解决方案4】:

    你可以试试这个。它对我有用:)

    https://github.com/iclems/iOS-htmltopdf/blob/master/NDHTMLtoPDF.h

    NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"];
    
     self.PDFCreator = [NDHTMLtoPDF createPDFWithHTML:html
                                              pathForPDF:[path  stringByExpandingTildeInPath]
                                                delegate:self
                                                pageSize:CGSizeMake(595,847)
                                                 margins:UIEdgeInsetsMake(105, 0, 0, 0)];
    

    像这样传递 webView

    【讨论】:

    • 谢谢 nikita,我会试试的,然后告诉你。请确认你是否在 uiwebview 中使用了子视图?
    • Nikita 您提供了一个示例代码,该代码是您直接从 PDF url 导出 PDF 的代码。但是在想要 Uiwebview 和 Uiwebview.subview.it 的例子中是可能的吗?
    • Nikita 我试过了,但我得到了“html”的“”空值。它呈现空 PDF。它是如何工作的“document.documentElement.outerHTML'”?
    • 您使用的是本地 HTML 还是 HTML URL?
    • 我正在使用本地 pdf 加载到 uiwebview ...我在 Uiwebview 中只打开 PDF 或 word 文件而不是 html。
    【解决方案5】:

    您实际上非常接近您拥有的代码。我感觉你最大的问题是在每次循环迭代中获取一个新的 CGContextRef ..

    UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, nil );
    CGContextRef currentContext = UIGraphicsGetCurrentContext();//movedByJef
    
      //  default pdf..
      // 8.5 X 11 inch
      // 612 x 792
    
    
    for (int i = 0; i < 10; i++) {
    
        CGContextSaveGstate( currentContext ); //addedByJef
    
        CGRect f = [pdfView frame];
        [pdfView setFrame: f]; // hmm what does this even do??
    
        UIGraphicsBeginPDFPage();
        CGContextTranslateCTM(currentContext, -72, -72); // Translate for 1" margins ///editedByJef, you had it backwards..
    
    //assuming you want a 72pt margin on right and bottom as well..
    //we want to reduce our size (612 x 792) by 72pts on all four sides..
    
    CGSize printPageSize = CGSizeMake( (612.0 - (72.0 * 2.0)), (792.0 -(72.0*2.0)) );
    CGSize layrSize = self.layer.bounds.size;
    
    //so we translate the context so our view fills it nicely..
    CGFloat xScaler = layrSize.width / printPageSize.width;
    CGFloat yScaler = layrSize.height / printPageSize.height;
    
    CGContextConcatCTM(currentContext, CGAffineTransformMakeScale(xScaler, yScaler) );
    
    
        [[[pdfView subviews] lastObject] setContentOffset:CGPointMake(0, 648 * i) animated:NO];
        [pdfView.layer renderInContext:currentContext];
    
    CGContextRestoreGstate(currentContext);//added by jef
    }
    
    UIGraphicsEndPDFContext();
    

    让我知道你是怎么做的,毫无疑问,变换的顺序会有一些混乱,也许缩放的任一侧都需要翻译,但这应该会让你非常接近..

    【讨论】:

    • 杰夫感谢您的回复。我会测试然后更新你。今天才长假才来
    猜你喜欢
    • 2017-09-12
    • 2015-07-23
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    相关资源
    最近更新 更多