簡體   English   中英

在Objective-C中合並PDF?

[英]Concatenate PDFs in objective-c?

我在連接PDF時遇到問題。 我必須連接2個pdf文件。 讓我們將第一個pdf文件稱為“ pdf1”,第二個稱為“ pdf2”。它將始終有一頁。 為了連接它們,我使用了波紋管功能,但是為了連接pdf1和pdf2,波紋管功能創建了一個新的pdf文件(我們稱其為pdf3),並繼續在pdf3上添加了pdf1和pdf2的所有頁面。 我想知道的是,有一種方法可以將pdf2連接到pdf1而不創建pdf3。

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

我認為您將無法在不首先完全關閉並釋放原始輸入副本的情況下生成PDF1的新實例,以便操作系統可以用同名的新輸出文件覆蓋舊的PDF1。 將新合並的輸出寫為PDF3更直接,因為PDF1和PDF2的合並對象必須相對於彼此進行索引和重新編號。

也就是說,僅將PDF2的內容移動到PDF1中是行不通的,因為您將有兩個對象1,兩個對象2,依此類推。 因此,該過程將創建新的PDF3作為新的目的地,並將包括新編號下的第一個輸入對象(或組合其字典或其他內容),以及每個輸入的第二個對象,第三個,依此類推。 。

(我在這里過分簡化了,因為PDF1和PDF2中的對象順序將不匹配,但是本質上合並需要合並兩者的內容,然后對它們進行重新排序和重新索引;這不是只需將第二個附加到第一個,然后將其關閉。)

如果您的問題是您希望輸出繼承第一個輸入文件的名稱,那么建議您先使用新的PDF3完成該過程,然后在驗證成功完成之后,刪除舊的PDF1,然后再刪除重命名PDF3。

請注意,如果您確實希望使過程的輸出帶有原始輸入文件之一的名稱,則需要確保過程成功,否則可能會得到錯誤的輸出文件並且沒有存活的實例您的輸入文件,然后重試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM