从UIScrollView + iphone生成PDF

时间:2011-03-11 04:26:23

标签: iphone pdf scrollview cgcontext

我想生成一个UIScrollView的pdf,其内容大小接近320 * 2000。如果我使用当前图形图像上下文来捕获滚动视图图层,那么它只捕获滚动视图的可见部分而不是该滚动视图的整个图层。

我使用以下代码:

-(void)CreatePdf:(id)sender
{

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *saveDirectory = [paths objectAtIndex:0];
    NSString *saveFileName = @"myPDF.pdf";
    [self writePDFAma];
    CGRect arect=CGRectMake(0, 0, 768, 1024);

    CreatePDFFileAma(arect, nil);
}



-(void) writePDFAma
{
    UIImage *image;
    NSData *data;
    UIAlertView *successAlert;
    UIAlertView *failureAlert;
    //  
    NSArray *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //  // This should be our documents directory
    NSString *saveDiirectory = [documentPath objectAtIndex:0];
    //  // Our PDF is named 'Example.pdf'
    NSString *saveFileName = @"FormImage2.JPG";
    //  // Create the full path using our saveDirectory and saveFileName
    NSString *finalPath = [saveDiirectory stringByAppendingPathComponent:saveFileName];
    //NSLog(@"%@",finalPath);
    CGSize asize=CGSizeMake(_scrollview.frame.size.width, _scrollview.frame.size.height);
    //NSLog(@"%d..%d",mainViewAma.frame.size.width, mainViewAma.frame.size.height);
    UIGraphicsBeginImageContext(asize);
        [[_scrollview layer] renderInContext:UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    data = UIImageJPEGRepresentation(image, 1.0);

    BOOL catch;
    if(!catch){
        if ([[NSFileManager defaultManager] createFileAtPath:finalPath contents:data attributes:nil])
        {
            successAlert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"Doodle was successfully saved to the Photo Library." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
            //[successAlert show];
            [successAlert release];
        } else {
            failureAlert = [[UIAlertView alloc] initWithTitle:@"Failure" message:@"Failed to save doodle to the Photo Library." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
            //[failureAlert show];
            [failureAlert release];
        }

    }

}


void CreatePDFFileAma (CGRect pageRect, const char *filename)
{
    // This code block sets up our PDF Context so that we can draw to it
    //some code here
    CGContextRef pdfContext;
    CFURLRef url;
    CFMutableDictionaryRef myDictionary = NULL;
    NSArray *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //  // This should be our documents directory
    NSString *saveDirectory = [documentPath objectAtIndex:0];
    //  // Our PDF is named 'Example.pdf'



    //NSString *saveFileName = @"PDFForm2.pdf";



    //  // Create the full path using our saveDirectory and saveFileName
    NSString *finalPath = [saveDirectory stringByAppendingPathComponent:saveFileName];
    NSURL * aurl=[[NSURL alloc]initFileURLWithPath:finalPath];
    url=(CFURLRef)aurl;
    // This dictionary contains extra options mostly for 'signing' the PDF
    myDictionary = CFDictionaryCreateMutable(NULL, 0,
                                             &kCFTypeDictionaryKeyCallBacks,
                                             &kCFTypeDictionaryValueCallBacks);
    CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("AMA FORM PDF"));
    CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name2"));
    // Create our PDF Context with the CFURL, the CGRect we provide, and the above defined dictionary
    pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary);
    // Cleanup our mess
    CFRelease(myDictionary);
    CFRelease(url);
    // Starts our first page
    CGContextBeginPage (pdfContext, &pageRect);

    // Draws a black rectangle around the page inset by 50 on all sides
    CGContextStrokeRect(pdfContext, CGRectMake(50, 50, 768, 1024));

    // This code block will create an image that we then draw to the page
    CGImageRef image;
    CGDataProviderRef provider;
    CFURLRef pictureURL;
    documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //  // This should be our documents directory
    saveDirectory = [documentPath objectAtIndex:0];
    NSString *saveFileName2 = @"FormImage2.JPG";
    //  // Create the full path using our saveDirectory and saveFileName
    NSString *finalPath2 = [saveDirectory stringByAppendingPathComponent:saveFileName2];
    NSURL * aurl2=[[NSURL alloc]initFileURLWithPath:finalPath2];
    pictureURL=(CFURLRef)aurl2;
    provider = CGDataProviderCreateWithURL (pictureURL);
    CFRelease (pictureURL);
    image = CGImageCreateWithJPEGDataProvider(provider, NULL, TRUE, kCGRenderingIntentDefault); //DataProvider (, NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease (provider);
    CGContextDrawImage (pdfContext, CGRectMake(0, 0,768, 1024),image);
    CGImageRelease (image);
    CGContextEndPage (pdfContext);
    // We are done with our context now, so we release it
    CGContextRelease (pdfContext);
}

3 个答案:

答案 0 :(得分:7)

嘿伙计们,我使用net上提供的示例准备了一些代码库,以便从UIScrollView创建PDF 我们应该清楚两件事

  

1)页数2)内容   滚动视图

我创建了内容大小(10 * 910)的滚动视图。所以它有10页。。这适用于iPad。

这是代码库

- (void) createPDF
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *directroyPath = nil;
    directroyPath = [documentsDirectory stringByAppendingPathComponent:@"PDF"];
    NSString *filePath = [directroyPath stringByAppendingPathComponent:@"test.pdf"];
    // check for the "PDF" directory
    NSError *error;
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {

    } else {
        [[NSFileManager defaultManager] createDirectoryAtPath:directroyPath
                                  withIntermediateDirectories:NO
                                                   attributes:nil
                                                        error:&error];
    }   

     CGContextRef pdfContext = [self createPDFContext:myScrollView.bounds path:(CFStringRef)filePath];
    NSLog(@"PDF Context created");

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

        // page 1
        CGContextBeginPage (pdfContext,nil); 

        //turn PDF upsidedown   
        CGAffineTransform transform = CGAffineTransformIdentity;    
        transform = CGAffineTransformMakeTranslation(0, (i+1) * 910);   
        transform = CGAffineTransformScale(transform, 1.0, -1.0);   
        CGContextConcatCTM(pdfContext, transform);  

        //Draw view into PDF
        [myScrollView.layer renderInContext:pdfContext];    
        CGContextEndPage (pdfContext);          
        [myScrollView setContentOffset:CGPointMake(0, (i+1) * 910) animated:NO];

    }
    CGContextRelease (pdfContext);
}

- (CGContextRef) createPDFContext:(CGRect)inMediaBox path:(CFStringRef) path    
{   
    CGContextRef myOutContext = NULL;   
    CFURLRef url;   
    url = CFURLCreateWithFileSystemPath (NULL, path,                                         
                                         kCFURLPOSIXPathStyle,                                       
                                         false);

    if (url != NULL) {      
        myOutContext = CGPDFContextCreateWithURL (url, 
                                                  &inMediaBox,                                                
                                                  NULL);        
        CFRelease(url);     
    }   
    return myOutContext;
}

答案 1 :(得分:5)

我想出了一个不同的解决方案:

-(NSData*)pdfDataFromTableViewContent{
   NSMutableData *pdfData = [NSMutableData data];
   //The real size, not only the visible part
   CGSize contentSize = self.tableView.contentSize;
   CGRect tableViewRealFrame = self.tableView.frame;
   //Size tableView to show the whole content
   self.tableView.frame = CGRectMake(0, 0, contentSize.width, contentSize.height);
   //Generate PDF (one page)
   UIGraphicsBeginPDFContextToData(pdfData,self.tableView.frame, nil);
   UIGraphicsBeginPDFPage();
   [self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
   UIGraphicsEndPDFContext();
   //Resize frame
   self.tableView.frame = tableViewRealFrame;
   return  pdfData;}

调整框架的大小以适应scrollView的整个内容,在graphicsContext中捕获它,调整框架的大小。

上层代码生成一页。
对于更多页面,我基本上使用这个:

//MultiPage
CGRect mediaBox = self.tableView.frame;
CGSize pageSize = CGSizeMake(self.view.frame.size.width, 800);
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
NSInteger currentPage = 0;
BOOL done = NO;
do {
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0.0, pageSize.width, pageSize.height), nil);
    CGContextTranslateCTM(pdfContext, 0, -(pageSize.height*currentPage));
    [self.view.layer renderInContext:pdfContext];
    if ((pageSize.height*(currentPage+1)) > mediaBox.size.height) done = YES;
    else currentPage++;
} while (!done);
UIGraphicsEndPDFContext();

答案 2 :(得分:0)

是否可以看到您的示例代码,我正在努力做同样的事情。

你可以在这里发送源代码,谢谢你会非常慷慨 dott.marco@mac.com

无论如何,对于你的问题,这可能会有所帮助:

您正在捕获可见内容,因为您的滚动视图的大小仅与可见内容相匹配,应该是这样。在使用以下内容开始绘图代码之前,您需要调整滚动视图的大小以匹配您需要捕获的内容:

代码: self.scrollView.frame = CGRectMake(0,0,“你的内容宽度在这里”,“你的内容高度在这里”); 完成绘制后,请确保将滚动视图的大小调整为后面,在本例中为容器视图:

代码: self.scrollView.frame = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height);