PDF Generation From UIScrollView + iphone

本小妞迷上赌 提交于 2019-12-30 05:15:35

问题


I want to generate a pdf of UIScrollView whose content size is near about 320*2000. If I use current graphic image context to capture the scroll view layer, then it only captures the visible part of the scroll view not the whole layer of that scroll view.

I am using the below code:

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

回答1:


Heh guys, i prepared some code base using the examples available on net to create PDF from UIScrollView We should be clear about two things

1) number of pages 2) contentsize of scrollview

i have created a scroll view of content size ( 10 * 910). so it has 10 pages.. This is for iPad.

here is the code base

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



回答2:


I came up with a different solution:

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

Size the frame to fit the entire content of the scrollView, capture it in graphicsContext, size the frame back.

The upper code generates one page.
For more pages I use basically this:

//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();



回答3:


is it possible to see your sample code please, I am trying to do the same exactly thing.

you could send the source code here, thanks for that you would be very generous dott.marco@mac.com

anyway for your problem maybe this can help:

You are capturing the visible content only because your scroll view is sized match the visible content only, which it should be. You need to resize your scrollview to match the content you need to capture before you start the drawing code using something like this:

Code: self.scrollView.frame = CGRectMake(0, 0, "your content width here", "your content height here"); After you are done drawing make sure to resize your scroll view to back, in this case to the container view:

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



来源:https://stackoverflow.com/questions/5268943/pdf-generation-from-uiscrollview-iphone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!