123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- //
- // KMConvertURLToPDF.m
- // PDF Reader
- //
- // Created by 丁林圭 on 2019/3/11.
- // Copyright © 2019年 Kdan Mobile. All rights reserved.
- //
- #import "KMConvertURLToPDF.h"
- #import <WebKit/WebKit.h>
- #import <Quartz/Quartz.h>
- @interface KMConvertURLToPDF () <WebFrameLoadDelegate,WebResourceLoadDelegate>{
- BOOL isProgressing;
- }
- @property (nonatomic,retain) NSString *savePath;
- @property (nonatomic,assign) NSInteger pageIndex;
- @property (nonatomic,retain) NSMutableArray * urls;
- @property (nonatomic,retain) NSMutableArray * failArray;
- @property (nonatomic,retain) NSMutableArray * successArray;
- @property (nonatomic,assign) CGSize pageSize;
- @property (nonatomic,assign) CGFloat gap;
- @property (nonatomic,retain) WebView *webView;
- @property (nonatomic,copy) void (^progress)(CGFloat value);
- @property (nonatomic,copy) void (^handler)(NSArray *successArray,NSArray *failArray);
- @end
- @implementation KMConvertURLToPDF
- -(void)dealloc {
- }
- + (KMConvertURLToPDF *)shareInstance
- {
- static KMConvertURLToPDF *sharedConvertUrlToPDF = nil;
- static dispatch_once_t predicate;
- dispatch_once(&predicate, ^{
- sharedConvertUrlToPDF = [[KMConvertURLToPDF alloc] init];
- });
- return sharedConvertUrlToPDF;
- }
- - (void)convertUrlToPDF:(NSArray <NSURL *>*)urls
- toPath:(NSString *)toPath
- pageSize:(CGSize)pageSize
- gap:(CGFloat)gap
- progress:(void (^)(CGFloat value))progress
- completionHandler:(void (^) (NSArray *successArray,NSArray *failArray))handler
- {
- self.urls = [NSMutableArray arrayWithArray:urls];
- self.failArray = [NSMutableArray array];
- self.successArray = [NSMutableArray array];
- self.savePath = toPath;
- self.progress = progress;
- self.pageSize = pageSize;
- self.gap = gap;
- self.handler = handler;
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- self.pageIndex = 0;
- dispatch_async(dispatch_get_main_queue(), ^{
- [self convertFileAtPageIndex:self.pageIndex];
- });
- });
- }
- - (void)convertFileAtPageIndex:(NSInteger)pageIndex
- {
- if (pageIndex >= self.urls.count) {
-
- if (self.handler) {
- self.handler (self.successArray,self.failArray);
- self.handler = nil;
- }
- return;
- }
-
- NSURL *url = self.urls[pageIndex];
-
- if ([url.pathExtension.lowercaseString isEqualToString:@"pdf"]) {
- dispatch_async(dispatch_get_main_queue(), ^{
- NSData *urlData = [NSData dataWithContentsOfURL:url];
- NSString *name = [NSString stringWithFormat:@"webpage%ld",self.pageIndex];
- NSString *savePath = [self.savePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf", self.fileName.length > 0? self.fileName : name]];
- if (![[NSFileManager defaultManager]fileExistsAtPath:self.savePath]) {
- [[NSFileManager defaultManager] createDirectoryAtPath:self.savePath withIntermediateDirectories:YES attributes:nil error:nil];
- }
- if ([urlData writeToFile:savePath atomically:YES]) {
- [self.successArray addObject:savePath];
- if (self.pageIndex + 1 >= self.urls.count) {
- if (self.handler) {
- self.handler (self.successArray,self.failArray);
- self.handler= nil;
- }
- } else {
- [self convertFileAtPageIndex:++self.pageIndex];
-
- }
- } else {
- [self.failArray addObject:self.urls[self.pageIndex]];
- if (self.handler) {
- self.handler (self.successArray,self.failArray);
- self.handler= nil;
- }
- }
- });
- } else {
-
- if (!self.webView) {
- _webView = [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)];
- WebPreferences *webPrefs = [[WebPreferences alloc] init];
- [webPrefs setShouldPrintBackgrounds:YES];
- [self.webView setPreferences:webPrefs];
- [self.webView setFrameLoadDelegate:self];
- [self.webView setResourceLoadDelegate:self];
- }
- [[self.webView mainFrame] loadRequest:[NSURLRequest requestWithURL:url]];
- }
- if (pageIndex != 0 && self.progress) {
- self.progress((float)self.pageIndex/self.urls.count);
- }
- }
- - (void)convertWebViewFrame:(WebFrame *)frame
- {
- // if (isProgressing) {
- // return;
- // }
- // isProgressing = YES;
-
- NSString *name = [NSString stringWithFormat:@"webpage%ld",self.pageIndex];
- if (self.fileName.length != 0) {
- name = self.fileName;
- }
- NSString *savePath = [self.savePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf",name]];
- if (![[NSFileManager defaultManager]fileExistsAtPath:self.savePath]) {
- [[NSFileManager defaultManager] createDirectoryAtPath:self.savePath withIntermediateDirectories:YES attributes:nil error:nil];
- }
- CGFloat margin = self.gap;
- NSSize paperSize = self.pageSize;
- WebFrameView *frameView = [frame frameView];
- NSPrintInfo *sharedInfo = [NSPrintInfo sharedPrintInfo];
- NSMutableDictionary *printInfoDict = [NSMutableDictionary dictionaryWithDictionary:[sharedInfo dictionary]];
- [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
- [printInfoDict setObject:[NSURL fileURLWithPath:savePath] forKey:NSPrintJobSavingURL];
-
- NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];
- [printInfo setHorizontalPagination:NSPrintingPaginationModeAutomatic];
- [printInfo setVerticalPagination:NSPrintingPaginationModeAutomatic];
- [printInfo setVerticallyCentered:NO];
- if (!CGSizeEqualToSize(paperSize, CGSizeZero)) {
- [printInfo setBottomMargin:margin];
- [printInfo setTopMargin:margin];
- [printInfo setLeftMargin:margin];
- [printInfo setRightMargin:margin];
- [printInfo setPaperSize:paperSize];
- }
- [printInfo setOrientation:NSPaperOrientationPortrait];
-
- NSPrintOperation *printOp = [frameView printOperationWithPrintInfo:printInfo];
- [printOp setShowsPrintPanel:NO];
- [printOp setShowsProgressPanel:NO];
-
- if ([printOp runOperation]) {
- [self.successArray addObject:savePath];
-
- if (self.pageIndex + 1 >= self.urls.count) {
- if (self.handler) {
- self.handler (self.successArray,self.failArray);
- self.handler= nil;
- }
- } else {
- [self convertFileAtPageIndex:++self.pageIndex];
- }
- } else {
- [self.failArray addObject:self.urls[self.pageIndex]];
- if (self.handler) {
- self.handler (self.successArray,self.failArray);
- self.handler= nil;
- }
- }
- }
- #pragma mark - WebView Delegate Methods
- - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
- if (frame == [sender mainFrame]) {
- NSString *htmlTitle = @"document.title";
-
- if (!self.fileName) {
- self.fileName = [sender stringByEvaluatingJavaScriptFromString:htmlTitle];
-
- if ([self.fileName length] < 1) {
- self.fileName = sender.mainFrameTitle;
- }
-
- if ([self.fileName length] < 1) {
- self.fileName = @"Untitled";
- }
- }
-
- [self performSelector:@selector(convertWebViewFrame:) withObject:frame afterDelay:0.3];
- }
- }
- - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
- {
- if([error code] == NSURLErrorCancelled) {
- return;
- }
- [self.failArray addObject:self.urls[self.pageIndex]];
- if (self.handler) {
- self.handler (self.successArray,self.failArray);
- self.handler= nil;
- }
- }
- - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
- {
- [self.failArray addObject:self.urls[self.pageIndex]];
- if (self.handler) {
- self.handler (self.successArray,self.failArray);
- self.handler= nil;
- }
- }
- @end
|