Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/118.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从iOS中的UIWebView/UIView生成PDF的最佳方法_Ios_Objective C_Iphone_Pdf_Uiwebview - Fatal编程技术网

从iOS中的UIWebView/UIView生成PDF的最佳方法

从iOS中的UIWebView/UIView生成PDF的最佳方法,ios,objective-c,iphone,pdf,uiwebview,Ios,Objective C,Iphone,Pdf,Uiwebview,在iOS应用程序中,我想从UIWebView/UIView(包括子视图)创建PDF。在我的应用程序中,我将首先在UIWebView中加载原始传入的PDF,然后在UIWebView上添加一个图像作为子视图。我想从UIWebview中创建一个PDF,其中包含此图像(子视图),具有原始清晰度,并且没有数据丢失 PS:渲染PDF中的图像应与UIWebView中的图像位于同一位置 我可以从UIWebView创建PDF,但它缺乏PDF的清晰度,并且会产生边界问题 任何人都可以从UIWebView(包括子视图

在iOS应用程序中,我想从UIWebView/UIView(包括子视图)创建PDF。在我的应用程序中,我将首先在UIWebView中加载原始传入的PDF,然后在UIWebView上添加一个图像作为子视图。我想从UIWebview中创建一个PDF,其中包含此图像(子视图),具有原始清晰度,并且没有数据丢失

PS:渲染PDF中的图像应与UIWebView中的图像位于同一位置

我可以从UIWebView创建PDF,但它缺乏PDF的清晰度,并且会产生边界问题

任何人都可以从UIWebView(包括子视图)提供清晰的PDF呈现解决方案吗

编辑内容

以上是UIWebView的屏幕截图。签名(测试)是子视图中的图像。我想呈现为一个清晰的PDF格式,没有任何数据丢失

在下面的回答中,UIPrintPageRenderer从UIWebView呈现PDF,但它忽略UIWebView上方的子视图。这是该选项的主要问题

使用createPDFfromUIView方法的另一个答案缺乏原始的清晰性:

   -(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename;
此方法也会出现边界问题

我也试着直接在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];
}
-(无效)drawCustomPDFContent
{
//把你的画放在这里
//画一个红色的盒子
[[UIColor redColor]集];
UIRectFill(CGRectMake(20,20,100,100));
//在将视图绘制为PDF的示例中,请注意这将是一个光栅化位图,包括文本。
//要获得更平滑的文本,需要使用NSString绘制方法
CGContextRef ctx=UIGraphicsGetCurrentContext();
[view.layer renderInContext:ctx];
}
-(作废)createCustomPDF
{
NSURL*pdfURL=…/*指向pdf文件的URL*/;
CGPDFDocumentRef pdf=CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
const size\u t numberOfPages=CGPDFDocumentGetNumberOfPages(pdf);
NSMutableData*数据=[NSMutableData];
UIGraphicsBeginPDFContextToData(数据,CGRectZero,nil);
对于(size_t page=1;page
-(void)createPDFfromUIView:(UIView*)查看保存到文档的文件名:(NSString*)文件名
{
//创建一个可变数据对象,以便使用二进制数据(如字节数组)进行更新
UIWebView*webView=(UIWebView*)视图;
NSString*heightStr=[webView stringByEvaluatingJavaScriptFromString:@“document.body.scrollHeight;”;
int height=[heightStr intValue];
//CGRect screenRect=[[UIScreen mainScreen]边界];
//CGFloat screenHeight=(self.contentWebView.hidden)?screenRect.size.width:screenRect.size.height;
CGFloat screenHeight=webView.bounds.size.height;
int pages=ceil(高度/屏幕高度);
NSMutableData*pdfData=[NSMutableData];
UIGraphicsBeginPDFContextToData(pdfData,webView.bounds,nil);
CGRect帧=[webView帧];
对于(int i=0;i高度){
CGRect f=[webView框架];
f、 尺寸.高度-=((i+1)*屏幕高度)-高度);
[webView设置框架:f];
}
UIGraphicsBeginPDFPage();
CGContextRef currentContext=UIGraphicsGetCurrentContext();
//CgContextTranslateCm(currentContext,72,72);//翻译为1“边距
[[[webView子视图]lastObject]setContentOffset:CGPointMake(0,屏幕高度*i)动画:否];
[webView.layer renderInContext:currentContext];
}
UIGraphicsSendPdfContext();
//从iOS设备检索文档目录
NSArray*documentDirectories=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,是);
NSString*documentDirectory=[documentDirectories objectAtIndex:0];
NSString*documentDirectoryFilename=[documentDirectory stringByAppendingPathComponent:aFilename];
//指示可变数据对象将其上下文写入磁盘上的文件
[pdfData WriteFile:documentDirectoryFilename原子性:是];
[webView设置框架:框架];
}

使用
UIPrintPageRenderer
UIWebView
执行以下步骤:

添加
UIPrintPageRenderer
类别
,以获取PDF数据 现在在
UIWebView的
webViewDidFinishLoad
delegate
中,使用
UIWebView
UIPrintPageRenderer
属性。

谢谢。已经尝试过这种方法。此呈现代码会出现数据丢失和边框问题。是的。我以前尝试过你的代码。它从UIWebView呈现PDF。但是我没有包含UIWebView上面的子视图。我在上面的代码中遇到了这个问题。只需在awebView.Scrollview中添加一个子视图。然后使用上面的代码呈现PDF。它将我将只渲染UIWebView(不包括子视图)@prince UIPrintPageRenderer将接受和处理子视图?只渲染UIWebView,而不是其子视图…太棒了!非常感谢!这将以横向方式渲染,不管是纵向还是纵向?有任何建议,请发布您的答案。@Daij Djan在UIWebView上方手动添加子视图。您应该解释您的意思”边界问题”
-(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
// Creates a mutable data object for updating with binary data, like a byte array
UIWebView *webView = (UIWebView*)aView;
NSString *heightStr = [webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"];

int height = [heightStr intValue];
//  CGRect screenRect = [[UIScreen mainScreen] bounds];
//  CGFloat screenHeight = (self.contentWebView.hidden)?screenRect.size.width:screenRect.size.height;
CGFloat screenHeight = webView.bounds.size.height;
int pages = ceil(height / screenHeight);

NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData(pdfData, webView.bounds, nil);
CGRect frame = [webView frame];
for (int i = 0; i < pages; i++) {
  // Check to screenHeight if page draws more than the height of the UIWebView
    if ((i+1) * screenHeight  > height) {
        CGRect f = [webView frame];
        f.size.height -= (((i+1) * screenHeight) - height);
        [webView setFrame: f];
    }

    UIGraphicsBeginPDFPage();
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
//  CGContextTranslateCTM(currentContext, 72, 72); // Translate for 1" margins

    [[[webView subviews] lastObject] setContentOffset:CGPointMake(0, screenHeight * i) animated:NO];
    [webView.layer renderInContext:currentContext];
}

UIGraphicsEndPDFContext();
// Retrieves the document directories from the iOS device
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];

  // instructs the mutable data object to write its context to a file on disk
   [pdfData writeToFile:documentDirectoryFilename atomically:YES];
[webView setFrame:frame];
 }
@interface UIPrintPageRenderer (PDF)
- (NSData*) printToPDF;
@end

@implementation UIPrintPageRenderer (PDF)
- (NSData*) printToPDF
{
  NSMutableData *pdfData = [NSMutableData data];
  UIGraphicsBeginPDFContextToData( pdfData, self.paperRect, nil );
  [self prepareForDrawingPages: NSMakeRange(0, self.numberOfPages)];
  CGRect bounds = UIGraphicsGetPDFContextBounds();
  for ( int i = 0 ; i < self.numberOfPages ; i++ )
  {
    UIGraphicsBeginPDFPage();
    [self drawPageAtIndex: i inRect: bounds];
  }
  UIGraphicsEndPDFContext();
  return pdfData;
}
@end
#define kPaperSizeA4 CGSizeMake(595.2,841.8)
- (void)webViewDidFinishLoad:(UIWebView *)awebView
{
  if (awebView.isLoading)
    return;

  UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];
  [render addPrintFormatter:awebView.viewPrintFormatter startingAtPageAtIndex:0];
  //increase these values according to your requirement
  float topPadding = 10.0f;
  float bottomPadding = 10.0f;
  float leftPadding = 10.0f;
  float rightPadding = 10.0f;
  CGRect printableRect = CGRectMake(leftPadding,
                                  topPadding,
                                  kPaperSizeA4.width-leftPadding-rightPadding,
                                  kPaperSizeA4.height-topPadding-bottomPadding);
  CGRect paperRect = CGRectMake(0, 0, kPaperSizeA4.width, kPaperSizeA4.height);
  [render setValue:[NSValue valueWithCGRect:paperRect] forKey:@"paperRect"];
  [render setValue:[NSValue valueWithCGRect:printableRect] forKey:@"printableRect"];
  NSData *pdfData = [render printToPDF];
  if (pdfData) {
    [pdfData writeToFile:[NSString stringWithFormat:@"%@/tmp.pdf",NSTemporaryDirectory()] atomically: YES];
  }
  else
  {
    NSLog(@"PDF couldnot be created");
  }
}