Có cách nào trong iOS để hợp nhất các tệp PDF, có nghĩa là, nối các trang của một tệp vào cuối tệp khác và lưu nó vào đĩa không?Hợp nhất các tệp PDF trên iOS
Trả lời
tôi bước ra với giải pháp này:
// Documents dir
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// File paths
NSString *pdfPath1 = [documentsDirectory stringByAppendingPathComponent:@"1.pdf"];
NSString *pdfPath2 = [documentsDirectory stringByAppendingPathComponent:@"2.pdf"];
NSString *pdfPathOutput = [documentsDirectory stringByAppendingPathComponent:@"out.pdf"];
// File URLs
CFURLRef pdfURL1 = (CFURLRef)[[NSURL alloc] initFileURLWithPath:pdfPath1];
CFURLRef pdfURL2 = (CFURLRef)[[NSURL alloc] initFileURLWithPath:pdfPath2];
CFURLRef pdfURLOutput = (CFURLRef)[[NSURL alloc] initFileURLWithPath:pdfPathOutput];
// File references
CGPDFDocumentRef pdfRef1 = CGPDFDocumentCreateWithURL((CFURLRef) pdfURL1);
CGPDFDocumentRef pdfRef2 = CGPDFDocumentCreateWithURL((CFURLRef) pdfURL2);
// Number of pages
NSInteger numberOfPages1 = CGPDFDocumentGetNumberOfPages(pdfRef1);
NSInteger numberOfPages2 = CGPDFDocumentGetNumberOfPages(pdfRef2);
// 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 (%i)...", 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 (%i)...", 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
CFRelease(pdfURL1);
CFRelease(pdfURL2);
CFRelease(pdfURLOutput);
CGPDFDocumentRelease(pdfRef1);
CGPDFDocumentRelease(pdfRef2);
CGContextRelease(writeContext);
Vấn đề lớn nhất ở đây là cấp phát bộ nhớ. Như bạn có thể thấy, trong phương pháp này, bạn phải đọc cả hai tệp PDF mà bạn muốn hợp nhất và, đồng thời, tạo đầu ra. Các bản phát hành chỉ xảy ra ở cuối. Tôi đã thử kết hợp một tập tin PDF với 500 trang (~ 15MB) với một trang khác có chứa 100 trang (~ 3MB) và nó tạo ra một trang mới với 600 trang (tất nhiên!) Chỉ có kích thước ~ 5MB (ma thuật?). Việc thực hiện mất khoảng 30 giây (không quá tệ, xem xét iPad 1) và phân bổ 17MB (ouch!). Các ứng dụng may mắn đã không sụp đổ, nhưng tôi nghĩ rằng iOS sẽ thích giết một ứng dụng tiêu thụ 17MB như thế này. ; P
Không nên khó sửa đổi mã để nó phát hành từng tài liệu (hoặc thậm chí mỗi x trang), nếu bạn đang viết mỗi trang vào đĩa cùng một lúc ... heck, bạn có thể đọc và phát hành một trang tại một thời điểm! Đó là một sự cân bằng giữa tốc độ và trí nhớ… – FeifanZ
Điều đó sẽ hiệu quả! Mặc dù tôi không thể tìm được cách để thực hiện điều đó. Sau khi bạn đóng một bối cảnh (lưu tệp vào đĩa) bằng cách sử dụng 'CGPDFContextClose', bạn không thể mở lại và tiếp tục chỉnh sửa từ nơi bạn đã dừng, như di chuyển con trỏ đến cuối tệp và thêm nội dung mới. – Jonatan
Hmmm ... Tôi không quá quen thuộc với các hàm và phương thức ở dưới đó, nhưng có thể có một số loại tệp luồng I/O cho phép bạn nâng cao con trỏ. Hoặc chỉ cần rút ra một cái gì đó giống như một megabyte bit tại một thời điểm và ghi nó vào đĩa (không chắc chắn như thế nào mà sẽ làm việc mặc dù) – FeifanZ
Tôi tin rằng FastPdfKit chính xác là những gì bạn đang tìm kiếm và miễn phí!
Đó là một thư viện tốt đẹp o hiển thị pdf, nhưng nó không hỗ trợ sáp nhập AFAICT. – lkraider
Tôi đã thực hiện một chút cấu trúc lại trên mã của Jonathan tham gia bất kỳ tập tin PDF của bất kỳ kích thước:
+ (NSString *)joinPDF:(NSArray *)listOfPaths {
// File paths
NSString *fileName = @"ALL.pdf";
NSString *pdfPathOutput = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:fileName];
CFURLRef pdfURLOutput = ( CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:pdfPathOutput]);
NSInteger numberOfPages = 0;
// Create the output context
CGContextRef writeContext = CGPDFContextCreateWithURL(pdfURLOutput, NULL, NULL);
for (NSString *source in listOfPaths) {
CFURLRef pdfURL = ( CFURLRef)CFBridgingRetain([[NSURL alloc] initFileURLWithPath:source]);
//file ref
CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithURL((CFURLRef) pdfURL);
numberOfPages = CGPDFDocumentGetNumberOfPages(pdfRef);
// Loop variables
CGPDFPageRef page;
CGRect mediaBox;
// Read the first PDF and generate the output pages
DLog(@"GENERATING PAGES FROM PDF 1 (%@)...", source);
for (int i=1; i<=numberOfPages; i++) {
page = CGPDFDocumentGetPage(pdfRef, i);
mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
CGContextBeginPage(writeContext, &mediaBox);
CGContextDrawPDFPage(writeContext, page);
CGContextEndPage(writeContext);
}
CGPDFDocumentRelease(pdfRef);
CFRelease(pdfURL);
}
CFRelease(pdfURLOutput);
// Finalize the output file
CGPDFContextClose(writeContext);
CGContextRelease(writeContext);
return pdfPathOutput;
}
Hy vọng rằng sẽ giúp
chỉ là bản cập nhật cho ARC: Có vẻ như điều này sẽ ném ngoại lệ trừ khi bạn sử dụng phương thức tự động phát lại fileURLWithPath: -> (__bridge CFURLRef) [NSURL fileURLWithPath: pdfPathOutput] thay vì phương thức init. – Bek
Bản gốc pdf khác biệt về kích thước và phiên bản tương thích, chỉ xem xét một tệp pdf để hợp nhất, bản gốc nằm trong phiên bản 1.4 nhưng bản gốc được tạo trong 1.3. Làm thế nào tôi có thể thiết lập phiên bản? – Cam
tôi đang đẩy mạnh thư viện riêng của tôi ở đây ... nhưng Tôi có một thư viện đọc/ghi PDF miễn phí, mà gần đây tôi đã giới thiệu cách sử dụng trong ngữ cảnh iOS. nó hoàn hảo cho việc sáp nhập các tệp PDF và thao tác chúng, và làm điều đó với một chữ ký bộ nhớ tương đối nhỏ. Hãy xem xét sử dụng nó, xem ở đây một ví dụ - ios with PDFHummus. Một lần nữa, đó là tôi thúc đẩy thư viện của riêng tôi, vì vậy hãy thực hiện lời khuyên này trong bối cảnh phù hợp.
Tôi dựa trên giải pháp của mình về giải pháp được tạo bởi @matsoftware.
Tôi tạo ra một đoạn mã cho giải pháp của tôi: https://gist.github.com/jefferythomas/7265536
+ (void)combinePDFURLs:(NSArray *)PDFURLs writeToURL:(NSURL *)URL
{
CGContextRef context = CGPDFContextCreateWithURL((__bridge CFURLRef)URL, NULL, NULL);
for (NSURL *PDFURL in PDFURLs) {
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((__bridge CFURLRef)PDFURL);
size_t numberOfPages = CGPDFDocumentGetNumberOfPages(document);
for (size_t pageNumber = 1; pageNumber <= numberOfPages; ++pageNumber) {
CGPDFPageRef page = CGPDFDocumentGetPage(document, pageNumber);
CGRect mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
CGContextBeginPage(context, &mediaBox);
CGContextDrawPDFPage(context, page);
CGContextEndPage(context);
}
CGPDFDocumentRelease(document);
}
CGPDFContextClose(context);
CGContextRelease(context);
}
tôi nghĩ rằng tôi muốn chia sẻ câu trả lời bằng Swift kể từ khi tôi đang tìm kiếm nó trong Swift và không thể tìm thấy nó và phải dịch nó. Ngoài ra, câu trả lời của tôi sử dụng một mảng của từng tệp pdf riêng lẻ pdfPagesURLArray
và lặp lại để tạo bản pdf hoàn chỉnh. Tôi khá mới ở đây vì vậy bất kỳ đề xuất được chào đón.
let file = "fileName.pdf"
guard var documentPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first else {
NSLog("Doh - can't find that path")
return
}
documentPaths = documentPaths.stringByAppendingString(file)
print(documentPaths)
let fullPDFOutput: CFURLRef = NSURL(fileURLWithPath: documentPaths)
let writeContext = CGPDFContextCreateWithURL(fullPDFOutput, nil, nil)
for pdfURL in pdfPagesURLArray {
let pdfPath: CFURLRef = NSURL(fileURLWithPath: pdfURL)
let pdfReference = CGPDFDocumentCreateWithURL(pdfPath)
let numberOfPages = CGPDFDocumentGetNumberOfPages(pdfReference)
var page: CGPDFPageRef
var mediaBox: CGRect
for index in 1...numberOfPages {
có thể làm lực lượng unwrapping đây như thế này: page = CGPDFDocumentGetPage(pdfReference, index)!
Nhưng để tiếp tục thực hành tốt nhất:
guard let getCGPDFPage = CGPDFDocumentGetPage(pdfReference, index) else {
NSLog("Error occurred in creating page")
return
}
page = getCGPDFPage
mediaBox = CGPDFPageGetBoxRect(page, .MediaBox)
CGContextBeginPage(writeContext, &mediaBox)
CGContextDrawPDFPage(writeContext, page)
CGContextEndPage(writeContext)
}
}
NSLog("DONE!")
CGPDFContextClose(writeContext);
NSLog(documentPaths)
Cảm ơn một bó, tôi đang tạo pdf từ html và tôi cần ngắt trang, Vì tôi không thể tìm thấy bất kỳ, Vì vậy, tôi đã tạo nhiều pdf với nhiều html và sau đó sử dụng mã ur để kết hợp tất cả, cảm ơn rất nhiều :) – vinbhai4u
@ vinbhai4u Tôi không thể tìm thấy bất kỳ giải pháp trong swift vì vậy tôi đã hy vọng những gì tôi đã đưa ra sẽ là hữu ích cho người khác. Vui mừng nó đã giúp bạn :) – FromTheStix
chức năng của tôi trong nhanh chóng 3:
// sourcePdfFiles is array of source file full paths, destPdfFile is dest file full path
func mergePdfFiles(sourcePdfFiles:[String], destPdfFile:String) {
guard UIGraphicsBeginPDFContextToFile(destPdfFile, CGRect.zero, nil) else {
return
}
guard let destContext = UIGraphicsGetCurrentContext() else {
return
}
for index in 0 ..< sourcePdfFiles.count {
let pdfFile = sourcePdfFiles[index]
let pdfUrl = NSURL(fileURLWithPath: pdfFile)
guard let pdfRef = CGPDFDocument(pdfUrl) else {
continue
}
for i in 1 ... pdfRef.numberOfPages {
if let page = pdfRef.page(at: i) {
var mediaBox = page.getBoxRect(.mediaBox)
destContext.beginPage(mediaBox: &mediaBox)
destContext.drawPDFPage(page)
destContext.endPage()
}
}
}
destContext.closePDF()
UIGraphicsEndPDFContext()
}
Điều này cực kỳ hữu ích. Cảm ơn bạn! :) –
- 1. Hợp nhất các tệp PDF
- 2. FPDI hợp nhất các tệp PDF, dòng lạ xuất hiện
- 3. Kết hợp các tệp PDF C#
- 4. Kết hợp các tệp pdf với các dấu trang
- 5. Chuyển đổi HTML sang PDF trên iOS?
- 6. Hợp nhất PDF hiện tại vào tệp ReportLab PDF mới qua lưu lượng
- 7. Làm cách nào để hợp nhất nhiều tệp PDF thành một tệp duy nhất?
- 8. Hợp nhất các tệp ttf
- 9. Hợp nhất các tệp CSS
- 10. Làm cách nào để hợp nhất các tệp PDF với Perl?
- 11. Đọc các tệp Midi trên IOS
- 12. Cách tiếp cận tốt nhất để sửa đổi các trường biểu mẫu tương tác PDF trên iOS là gì?
- 13. Nhận siêu liên kết PDF trên iOS với Quartz
- 14. Hợp nhất FDF và PDF mà không cần PDFTK
- 15. Hợp nhất các tệp dự án Xcode
- 16. Làm cách nào để tạo tệp PDF có nội dung văn bản "thực" trên iOS?
- 17. Sự cố khi tải PDF trên Chrome IOS
- 18. hợp nhất hai tệp
- 19. Làm phẳng các tệp PDF trong PHP?
- 20. Kết hợp hình ảnh png vào một tệp pdf
- 21. Cách tạo tệp pdf trên android
- 22. Có thể kết hợp nhiều tệp pdf thành một tệp pdf có lập trình trong iphone không?
- 23. Kiểm tra xem Tệp PDF có hợp lệ không (Python)
- 24. Phông chữ nhúng của iOS trong PDF
- 25. Kết hợp các tệp PDF và giữ lại các tính năng mở rộng trong Acrobat Reader
- 26. Tạo tệp PDF từ tệp html trên iPhone
- 27. Tìm kiếm tất cả các tệp phù hợp với một mẫu nhất định
- 28. Ngày Javascript không hợp lệ trên iOS
- 29. Hợp nhất các tệp di chuyển db/di chuyển
- 30. Hợp nhất nhiều khung dữ liệu từ các tệp csv
Đây không phải là một câu trả lời cho điều này, nhưng nếu ai đó muốn [nối thêm một tập tin pdf hiện có] (http://stackoverflow.com/a/15355168/1603234) – Hemang