2

I am trying to combine 11 pdf files into a single pdf file.The following code i am using ,but in the final pdf only the first pdf is shown ...i nslogged the pdfurls and CGPDFDocumentRef in the loop and they are not nil all the time(in the loop).What may be the reason why only the first page is displayed in the final document

-(void)mergeDocuments
    {


        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder

        NSString *oldFile=[documentsDirectory stringByAppendingPathComponent:@"finalPdf.pdf"];
        NSMutableData *data=[[NSMutableData alloc] init];
         CGRect paperSize=CGRectMake(0,0,kDefaultPageWidth,kDefaultPageHeight);
        UIGraphicsBeginPDFContextToData(data, paperSize, nil);

        for (int pageNumber = 1; pageNumber <= 11; pageNumber++)
        {

            NSString *pdfPath = [[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"page_%d.pdf",pageNumber]] retain];



            NSURL *pdfUrl = [[NSURL fileURLWithPath:pdfPath] retain];



            UIGraphicsBeginPDFPageWithInfo(paperSize, nil);


            CGContextRef currentContext = UIGraphicsGetCurrentContext();


            CGContextTranslateCTM(currentContext, 0, paperSize.size.height);
            CGContextScaleCTM(currentContext, 1.0, -1.0); 



            CGPDFDocumentRef newDocument = CGPDFDocumentCreateWithURL ((CFURLRef) pdfUrl);

            CGPDFPageRef newPage = CGPDFDocumentGetPage (newDocument, pageNumber);


            CGContextDrawPDFPage (currentContext, newPage);
            newPage = nil;       
            CGPDFDocumentRelease(newDocument);
            newDocument = nil;
            [pdfUrl release];

        }

        NSURL *finalUrl=[NSURL URLWithString:oldFile];



        UIGraphicsEndPDFContext(); 
[data writeToURL:finalUrl atomically:YES];
    }
sujith1406
  • 2,822
  • 6
  • 40
  • 60
  • Try creating pages using CGContextBeginPage instead of UIGraphicsBeginPDFPageWithInfo – Swapnil Luktuke Mar 12 '12 at 13:55
  • @lukya tried that but didnt help – sujith1406 Mar 12 '12 at 14:10
  • What are you using to view the pdf and determine that it only has one page? – lnafziger Mar 12 '12 at 14:27
  • @Inafziger i am doing to the documents folder of my app and opening the pdf document with adobe reader. – sujith1406 Mar 12 '12 at 14:32
  • Okay, I had the same issue with a pdf reader available for iOS that turned out to be a bug with the reader only displaying the first page (even though they were all there). – lnafziger Mar 12 '12 at 14:35
  • Are you specifically wanting to do it this way? I can post code that takes a different approach but that I know works. – lnafziger Mar 12 '12 at 14:39
  • @Inafziger ok post it here.... but ultimately this is the way right? begin a context ,in that for each pdf to add ,begin a new page and ultimately end the context.. – sujith1406 Mar 12 '12 at 15:45
  • @Sujit: Can you share your PDF module with me on nav.memane@yahoo.com. I have put similar Query on following SO http://stackoverflow.com/questions/16646039/how-to-save-created-pdf-in-document-folder-and-merge-in-ios. Could you please help – Navnath Memane May 26 '13 at 13:38

2 Answers2

3

It looks like your code assumes that there is only one page in each document, however it is asking for page pageNumber from each file as it opens it, and is therefore asking for page 1 from page_1.pdf, page 2 from page_2.pdf, page 3 from page_3.pdf, etc...

If you just want the first page from each document change this:

CGPDFPageRef newPage = CGPDFDocumentGetPage (newDocument, pageNumber);

to this:

CGPDFPageRef newPage = CGPDFDocumentGetPage (newDocument, 1);

For what it's worth, I re-wrote your routine before I spotted this based on one that I already have (forgive me but it is in an ARC project so you'll have to re-do your memory management) as follows:

(NOTE: Error checking has been removed to make the code more readable!)

-(void)mergeDocuments {
    NSArray     *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString    *documentsDirectory = [paths objectAtIndex:0];

    NSString    *oldFilePath=[documentsDirectory stringByAppendingPathComponent:@"finalPdf.pdf"];
    NSURL       *oldFileUrl = [NSURL fileURLWithPath:oldFilePath];

    CGContextRef context = CGPDFContextCreateWithURL((__bridge_retained CFURLRef)oldFileUrl, NULL, NULL);

    for (int docNumber = 1; docNumber <= 11; docNumber++)
    {
        // Get the first page from each source document
        NSString            *pdfPath        = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"page_%d.pdf",docNumber]];
        NSURL               *pdfUrl         = [NSURL fileURLWithPath:pdfPath];
        CGPDFDocumentRef    pdfDoc          = CGPDFDocumentCreateWithURL((__bridge_retained CFURLRef)pdfUrl);
        CGPDFPageRef        pdfPage         = CGPDFDocumentGetPage(pdfDoc, 1);
        CGRect              pdfCropBoxRect  = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);

        // Copy the page to the new document
        CGContextBeginPage(context, &pdfCropBoxRect);
        CGContextDrawPDFPage(context, pdfPage);

        // Close the source files
        CGContextEndPage(context);
        CGPDFDocumentRelease(pdfDoc);         
    }

    // Cleanup
    CGContextRelease(context);
}
lnafziger
  • 25,760
  • 8
  • 60
  • 101
  • 1
    There's a `CGContextEndPage(context);` missing after the `CGContextDrawPDFPage(context, pdfPage);` Otherwise you'll generate a log warning that: Don't nest calls to this function -- the results will not be what you expect. – Peter Brockmann Aug 15 '13 at 19:20
1

If what you want is all pages of all the source PDF files, your for loop is wrong.

You loop counter 'pageNumber' runs from 1 to 11. You are using the same variable to open the corresponding file as well as to fetch a page from that pdf. So, your for loop will produce a pdf with

1st page of 1st pdf, 2nd page of 2nd pdf,....,11th page of 11th pdf

If your 2nd - 11th pdf files do not have as many pages, the final output will obviously have only the first page of first pdf.

You need 2 for loops. One to iterate through pdf files and the other to iterate through each page of every pdf file.

    for (int documentNumber = 1; documentNumber <= 11; documentNumber++)
    {

        NSString *pdfPath = [[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"page_%d.pdf",documentNumber]] retain];
        NSURL *pdfUrl = [[NSURL fileURLWithPath:pdfPath] retain];
        UIGraphicsBeginPDFPageWithInfo(paperSize, nil);
        CGContextRef currentContext = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(currentContext, 0, paperSize.size.height);
        CGContextScaleCTM(currentContext, 1.0, -1.0); 

        CGPDFDocumentRef newDocument = CGPDFDocumentCreateWithURL ((CFURLRef) pdfUrl);
        int numberOfPages = CGPDFDocumentGetNumberOfPages(newDocument);

        for (int pageNumber = 1; pageNumber <= numberOfPages; pageNumber++)
        {
            CGPDFPageRef newPage = CGPDFDocumentGetPage (newDocument, pageNumber);
            CGContextDrawPDFPage (currentContext, newPage);
            //any other page rendering
            newPage = nil;       
        }

        CGPDFDocumentRelease(newDocument);
        newDocument = nil;
        [pdfUrl release];            
    }
Swapnil Luktuke
  • 10,385
  • 2
  • 35
  • 58