【问题标题】:Concatenate PDFs in objective-c?在objective-c中连接PDF?
【发布时间】:2015-10-29 18:37:37
【问题描述】:

我在连接 PDF 时遇到问题。 我必须连接 2 个 pdf 文件。让我们称第一个 pdf 文件为“pdf1”,第二个为“pdf2”,它总是只有一页。 为了连接它们,我使用了下面的函数,但是下面的函数为了连接 pdf1 和 pdf2 创建了一个新的 pdf 文件(让我们称之为 pdf3)并继续在 pdf3 上添加来自 pdf1 和 pdf2 的所有页面。 我想知道的是,有没有一种方法可以在不创建 pdf3 的情况下在 pdf1 上连接 pdf2。

-(void) concatenaPDF:(NSNumber*)paginaSendoBaixada{

    NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

    // File paths
    cacheDir = [cacheDir stringByAppendingPathComponent:@"PDFs"];

    NSString *pdfPathOutput = [cacheDir stringByAppendingPathComponent:@"out.pdf"];

    // File URLs - bridge casting for ARC
    NSURL *pdfURL1 = [[NSURL alloc] initFileURLWithPath:self.filePath];
    NSURL *pdfURL2 = [[NSURL alloc] initFileURLWithPath:self.filePathPagina];
    CFURLRef pdfURLOutput =(__bridge_retained CFURLRef) [[NSURL alloc] initFileURLWithPath:(NSString *)pdfPathOutput];//(CFURLRef)

    // File references
    CGPDFDocumentRef pdfRef1 = CGPDFDocumentCreateWithURL((CFURLRef) pdfURL1);
    CGPDFDocumentRef pdfRef2 = CGPDFDocumentCreateWithURL((CFURLRef) pdfURL2);

    // Number of pages
    NSInteger numberOfPages1 = CGPDFDocumentGetNumberOfPages(pdfRef1);
    NSInteger numberOfPages2 = CGPDFDocumentGetNumberOfPages(pdfRef2);

    //se pagina do pdfbaxado for 0 e pq deu erro na baixa e vou ter que baixar denovo.
    if (numberOfPages2 == 0) {
        self.modeloParaItemSendoBaixado.model.paginaBaixando--;
        //vou apagar o pdf da pagina
        [self deleteFileAtPath:self.filePathPagina];
        return;    
    }

    if (numberOfPages1 > [paginaSendoBaixada integerValue]) {
        [self clearState];
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Erro"
                                                            message:@"Falha na conexão.\nNão foi possível baixar a edição!"
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alertView show];
        });

    }

    // Create the output context
    CGContextRef writeContext = CGPDFContextCreateWithURL(pdfURLOutput, NULL, NULL);

    // Loop variables
    CGPDFPageRef page;
    CGRect mediaBox;

    // Read the first PDF and generate the output pages
    NSLog(@"GENERATING PAGES FROM PDF 1 (%li)...", (long)numberOfPages1);
    for (int i=1; i<=numberOfPages1; i++) {
        page = CGPDFDocumentGetPage(pdfRef1, i);
        mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
        CGContextBeginPage(writeContext, &mediaBox);
        CGContextDrawPDFPage(writeContext, page);
        CGContextEndPage(writeContext);
    }

    // Read the second PDF and generate the output pages
    NSLog(@"GENERATING PAGES FROM PDF 2 (%li)...", (long)numberOfPages2);
    for (int i=1; i<=numberOfPages2; i++) {
        page = CGPDFDocumentGetPage(pdfRef2, i);
        mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
        CGContextBeginPage(writeContext, &mediaBox);
        CGContextDrawPDFPage(writeContext, page);
        CGContextEndPage(writeContext);
    }
    NSLog(@"DONE!");

    // Finalize the output file
    CGPDFContextClose(writeContext);

    // Release from memory
    CGPDFDocumentRelease(pdfRef1);
    CGPDFDocumentRelease(pdfRef2);
    CGContextRelease(writeContext);


    [self deleteFileAtPathWithoutImage:self.filePath];


    NSFileManager *fileMan = [NSFileManager defaultManager];
    NSError *error = nil;
    if (self.filePath != nil) {
        if (![fileMan moveItemAtPath:pdfPathOutput toPath:self.filePath error:&error])
        {
            [self clearState];
            dispatch_async(dispatch_get_main_queue(), ^{
                UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Erro"
                                                                message:@"Falha na conexão.\nNão foi possível baixar a edição!"
                                                               delegate:nil
                                                      cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alertView show];
            });
            NSLog(@"Failed to move '%@' to '%@': %@", pdfPathOutput, self.filePath, [error localizedDescription]);
        }
    }  
}

【问题讨论】:

    标签: ios objective-c pdf


    【解决方案1】:

    如果不先完全关闭并释放原始输入副本,我认为您将无法生成 PDF1 的新实例,以便操作系统可以用相同的新输出文件覆盖旧 PDF1姓名。将新合并的输出写为 PDF3 更直接,因为 PDF1 和 PDF2 的组合对象必须相对于彼此进行索引和重新编号。

    也就是说,简单地将 PDF2 的内容移动到 PDF1 中是行不通的,因为您将拥有两个对象 1、两个对象 2 等等。因此,该过程将创建您的新 PDF3 作为新目标,并且将包括您输入的第一个新数字下的对象(或组合它们的字典,或其他),以及来自每个输入的第二个对象,第三个,依此类推.

    (我在这里过度简化了很多,因为 PDF1 和 PDF2 中的对象序列不会匹配,但本质上合并需要将两者的内容结合起来,然后重新排序和重新索引它们;这不仅仅是将第二个附加到第一个然后将其关闭。)

    如果您的问题特别是您希望输出继承您的第一个输入文件的名称,我建议先使用新的 PDF3 完成该过程,然后在验证成功完成后,您可以删除旧的PDF1,然后在其位置重命名 PDF3。

    请注意,如果您真的想让您的流程的输出带有您的原始输入文件之一的名称,那么您需要确保您的流程是成功的,否则您最终可能会得到一个错误的输出文件并且没有输入文件的幸存实例,可用于重试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      • 2010-09-10
      • 2019-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多