项目需求APP连接打印机,打印出APP里加载的PDF文件或H5网页。以下mark打印功能的开发。
//点击打印
-(void)printAction:(UIBarButtonItem *)sender
{
if ([_url containsString:@".aspx"] || [_url containsString:@".html"]) { //打印H5网页
/** Safari自带共享按钮,包含打印功能,可跳出APP打印
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"打印网页需前往Safari浏览器,并点击顶部共享按钮,即可选择“打印”" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"立即前往" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:_url]]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:_url]];
}
}];
[alertController addAction:action1];
[alertController addAction:action2];
[self presentViewController:alertController animated:YES completion:nil];
*/
//直接弹出打印控制器打印网页
UIPrintInteractionController *printController = [UIPrintInteractionController sharedPrintController];
//打印完成回调
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if(!completed && error){
NSLog(@"FAILED! due to error in domain %@ with error code %ld",
error.domain, (long)error.code);
}
};
//配置打印信息
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral; //输出类型,可打印文本、图形、图像
printInfo.jobName = @"就医解读报告"; //打印工作标识
printInfo.duplex = UIPrintInfoDuplexLongEdge; //双面打印绕长边翻页,NONE为禁止双面
printController.printInfo = printInfo;
printController.showsPageRange = YES;
//格式化打印UIWebView上显示的内容
UIViewPrintFormatter *viewFormatter = [self.webView viewPrintFormatter];
viewFormatter.startPage = 0;
printController.printFormatter = viewFormatter;
/** 格式化打印HTML文档
UIMarkupTextPrintFormatter *htmlFormatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:self.htmlString];
htmlFormatter.startPage = 0;
htmlFormatter.contentInsets = UIEdgeInsetsMake(72.0, 72.0, 72.0, 72.0);
*/
/** 格式化打印简单文字
UISimpleTextPrintFormatter *textFormatter = [[UISimpleTextPrintFormatter alloc] initWithText:@"嘛哩嘛哩哄发哈砂砾石"];
textFormatter.startPage = 0;//指定从哪一张开始打印0代表第一张
textFormatter.contentInsets = UIEdgeInsetsMake(36, 36, 36, 36);//72相当于1英寸,这样设置上下左右的边距都为0.5英寸
textFormatter.maximumContentWidth = 504;//(72x7.5)相当于打印宽度为7英寸
*/
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[printController presentFromBarButtonItem:sender animated:YES completionHandler:completionHandler];
//或者 presentFromRect:inView:animated:completionHandler:
}else{
[printController presentAnimated:YES completionHandler:completionHandler];
}
}else{ //打印网络加载的PDF文件
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
//首先需要下载下来
[[HDNetworking sharedHDNetworking] downLoadWithURL:_url progress:nil destination:^NSURL * _Nullable(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
//返回目的地路径
NSString *cashPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
return [NSURL fileURLWithPath:[cashPath stringByAppendingPathComponent:response.suggestedFilename]];
} downLoadSuccess:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
DLog(@"response = %@, filePath = %@", response, filePath);
_tempPath = filePath.path; //获取到本地文件路径
//方法一:文件预览控制器打印,其不仅有打印功能,而且有保存、转发等功能
self.previewController = [[QLPreviewController alloc] init];
self.previewController.dataSource = self;
self.previewController.delegate = self;
[self presentViewController:self.previewController animated:YES completion:nil];
//方法二:单纯用打印控制器打印PDF
/*
AirPrint可以直接打印一些内容。 这些内容是 NSData, NSURL, UIImage, and ALAsset 类的实例, 但是这些实例的内容, 或者引用的类型(NSURL)必须是 image 或者pdf.
对于 image来说, NSData, NSURL, UIImage, and ALAsset 类型都可以的。 对于PDF, 只能使用 NSData, NSURL。 然后需要将这些数据实例直接赋值 给 UIPrintInteractionController实例的 printingItem 或者 printingItems 属性。
*/
/*
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
NSData *pdfData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:_tempPath]];
if (pic && [UIPrintInteractionController canPrintData:pdfData]) {
pic.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = @"就医解读报告";
printInfo.duplex = UIPrintInfoDuplexLongEdge;
pic.printInfo = printInfo;
pic.showsPageRange = YES;
pic.printingItem = pdfData;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
if (!completed && error)
NSLog(@"FAILED! due to error in domain %@ with error code %ld",
error.domain, error.code);
};
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[pic presentFromBarButtonItem:sender animated:YES
completionHandler:completionHandler];
} else {
[pic presentAnimated:YES completionHandler:completionHandler];
}
}
*/
} failure:^(NSError * _Nonnull error) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
}];
}
//内置Safari,功能较少
// SFSafariViewController *safariVC = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:_url]];
// [self presentViewController:safariVC animated:YES completion:nil];
}
#pragma QLPreViewDelegate
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return 1;
}
- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
return [NSURL fileURLWithPath:_tempPath];
}
- (void)previewControllerDidDismiss:(QLPreviewController *)controller
{
if(![_tempPath isEqual:@""]){ //文件预览器dismiss,将下载到本地的文件移除
NSFileManager * fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:_tempPath error:nil];
}
}
注意,使用文件预览器需要导入框架<QuickLook/QuickLook.h>和代理QLPreviewControllerDelegate,QLPreviewControllerDataSource
根据项目需要,选择使用打印控制器还是文件预览器O(∩_∩)O~
//另附:UIActivityViewController、UIDocumentInteractionController的使用方法
//一、系统原生分享交互视图
//一、系统原生分享交互视图
/*! 1. 创建要分享的数据内容,加在一个数组 ActivityItems里。 */
NSString *textToShare = @"我是且行且珍惜_iOS,欢迎关注我!";
UIImage *imageToShare = [UIImage imageNamed:@"wang.png"];
NSURL *urlToShare = [NSURL URLWithString:@"https://github.com/wslcmk"];
NSArray *activityItems = @[urlToShare,textToShare,imageToShare];
//自定义 customActivity继承于UIActivity,创建自定义的Activity加在数组Activities中。
// customActivity * custom = [[customActivity alloc] initWithTitie:@"且行且珍惜_iOS" withActivityImage:[UIImage imageNamed:@"wang"] withUrl:urlToShare withType:@"customActivity" withShareContext:activityItems];
// NSArray *activities = @[custom];
/*!
* 2.创建分享视图控制器,初始化UIActivityViewController
* ActivityItems 在执行activity中用到的数据对象数组。数组中的对象类型是可变的,并依赖于应用程序管理的数据。例如,数据可能是由一个或者多个字符串/图像对象,代表了当前选中的内容。
* Activities 是一个UIActivity对象的数组,代表了应用程序支持的自定义服务。这个参数可以是nil。
*/
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@healthCare20160822163627HY2016.pdf",PER_REPORT_PATH]];
UIActivityViewController *activity = [[UIActivityViewController alloc] initWithActivityItems:@[@"分享PDF", url] applicationActivities:nil];
/*! 3、关闭系统的一些Activity类型,不需要的功能关掉。 */
//Activity 类型又分为“操作”和“分享”两大类
/*
UIKIT_EXTERN NSString *const UIActivityTypePostToFacebook NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UIActivityTypePostToTwitter NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UIActivityTypePostToWeibo NS_AVAILABLE_IOS(6_0); //SinaWeibo
UIKIT_EXTERN NSString *const UIActivityTypeMessage NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UIActivityTypeMail NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UIActivityTypePrint NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UIActivityTypeCopyToPasteboard NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UIActivityTypeAssignToContact NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UIActivityTypeSaveToCameraRoll NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UIActivityTypeAddToReadingList NS_AVAILABLE_IOS(7_0);
UIKIT_EXTERN NSString *const UIActivityTypePostToFlickr NS_AVAILABLE_IOS(7_0);
UIKIT_EXTERN NSString *const UIActivityTypePostToVimeo NS_AVAILABLE_IOS(7_0);
UIKIT_EXTERN NSString *const UIActivityTypePostToTencentWeibo NS_AVAILABLE_IOS(7_0);
UIKIT_EXTERN NSString *const UIActivityTypeAirDrop NS_AVAILABLE_IOS(7_0);
*/
activity.excludedActivityTypes = @[UIActivityTypePostToVimeo];
[self presentViewController:activity animated:YES completion:nil];
二、文件交互控制器
@property(nonatomic,strong)UIDocumentInteractionController *docController;
//二、文件交互控制器
_docController = [UIDocumentInteractionController interactionControllerWithURL:[[NSBundle mainBundle] URLForResource:@"meinv" withExtension:@"gif"]];
//功能一:分享文件
// [_docController presentOpenInMenuFromRect:self.view.bounds inView:self.view animated:YES];
//展示更多可选项
// [_docController presentOptionsMenuFromRect:self.view.bounds inView:self.view animated:YES];
//功能二:预览文件
//预览文件需遵循代理UIDocumentInteractionControllerDelegate
// _docController.delegate = self;
// [_docController presentPreviewAnimated:YES];
#pragma mark - UIDocumentInteractionControllerDelegate
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
return self.view.frame;
}
注意:UIDocumentInterRactionController定义的时候一定要是设置一个strong类型的属性,因为必须要对该对象进行持有;
当上述方法确实无法满足你的要求的时候就可以考虑一下用Quick Look了。