【问题标题】:How to take printout from my iPhone app?如何从我的 iPhone 应用程序打印输出?
【发布时间】:2011-08-16 09:23:28
【问题描述】:

我的应用中有一个打印按钮。如果我单击按钮,它应该打印屏幕。 我的问题是屏幕是否有滚动视图并且它的内容大于屏幕大小。它应该打印屏幕的全部内容。打印输出可能需要 2 或 3 页。是否有任何示例代码或项目用于打印屏幕而不是通过拍照或屏幕截图。

【问题讨论】:

  • 基本上你将滚动视图转换为图像文件,然后打印出来。我也做过同样的事情,只是将图片作为电子邮件附件发送。

标签: iphone objective-c ipad printing uiscrollview


【解决方案1】:

您需要将整个数据转换为 HTML 格式并使用 WebView 来显示数据。要从 iPhone 应用程序打印输出,您需要从您的 webview 内容创建一个 Pdf 文件,然后从该 pdf 文件中打印出来。这里我给你示例代码,它在我的应用程序中正常工作。

1) 包含 QuartzCore 框架并在 ViewController.h 文件中导入“QuartzCore/QuartzCore.h”。

2) 在 ViewController.h 文件中使用以下代码

@interface ViewController : UIViewController<UIScrollViewDelegate, UIPrintInteractionControllerDelegate>
 {
       UIWebView *theWebView;
       int imageName;
       double webViewHeight;
 }

 -(void) takeSnapshot;
 - (void) drawPdf;
 -(void) printContent:(NSData *) data;

3) 在 vi​​ewDidLoad 方法中使用以下代码:

 - (void)viewDidLoad
 {
    [super viewDidLoad];

     NSString *htmlString=@"<html><body><img src=\"blue.png\" alt=\"Blue Image\" />  <h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p><h1>Hi, himanshu mahajan</h1><p> I am from Vinove Software service</p></body></html>";

     UIBarButtonItem *generate=[[UIBarButtonItem alloc] initWithTitle:@"Print" style:UIBarButtonItemStylePlain target:self action:@selector(printBtnPressed)];
     [self.navigationItem setRightBarButtonItem:generate];

      theWebView=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 416)];
      [theWebView loadHTMLString:htmlString baseURL:nil];
      theWebView.scrollView.bounces=NO;
      [self.view addSubview:theWebView];

      imageName=0;
      webViewHeight=0.0;
 }

4) 方法定义

-(void) printBtnPressed
{
   [self takeSnapshot];

    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDir=[paths objectAtIndex:0];
    NSString *filePath=[documentDir stringByAppendingPathComponent:@"Demo.pdf"];

    NSData *data=[[NSData alloc] initWithContentsOfFile:filePath];

    [self printContent:data];
}

-(void) takeSnapshot
{

   webViewHeight=[[theWebView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"] integerValue];

   CGRect screenRect=theWebView.frame;
   double currentWebViewHeight = webViewHeight;

   while (currentWebViewHeight > 0)
   {
     imageName ++;

     UIGraphicsBeginImageContext(screenRect.size);
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     [[UIColor blackColor] set];
     CGContextFillRect(ctx, screenRect);

     [theWebView.layer renderInContext:ctx];

     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();

     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *documentsDirectory = [paths objectAtIndex:0];
     NSString *pngPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",imageName]];

     if(currentWebViewHeight < 416)
     {
         CGRect lastImageRect = CGRectMake(0, 416 - currentWebViewHeight, theWebView.frame.size.width, currentWebViewHeight);
          CGImageRef imageRef = CGImageCreateWithImageInRect([newImage CGImage], lastImageRect);    

          newImage = [UIImage imageWithCGImage:imageRef];
          CGImageRelease(imageRef);
      }
      [UIImagePNGRepresentation(newImage) writeToFile:pngPath atomically:YES];

      [theWebView stringByEvaluatingJavaScriptFromString:@"window.scrollBy(0,416);"];
      currentWebViewHeight -= 416;
    }

   [self drawPdf];
  }


  - (void) drawPdf
  {
    CGSize pageSize = CGSizeMake(612, webViewHeight);
    NSString *fileName = @"Demo.pdf";
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName];

    UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);

    // Mark the beginning of a new page.
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);

    double currentHeight = 0.0;
   for (int index = 1; index  <= imageName ; index++)
   {
      NSString *pngPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png", index]];
      UIImage *pngImage = [UIImage imageWithContentsOfFile:pngPath];

      [pngImage drawInRect:CGRectMake(0, currentHeight, pageSize.width, pngImage.size.height)];
      currentHeight += pngImage.size.height;
     }
     UIGraphicsEndPDFContext();
  }

   -(void) printContent:(NSData *) data
   {
      UIPrintInteractionController *print = [UIPrintInteractionController sharedPrintController];

       print.delegate = self;
       UIPrintInfo *printInfo = [UIPrintInfo printInfo];
       printInfo.outputType = UIPrintInfoOutputGeneral;
      //printInfo.jobName = @"Information";
       printInfo.duplex = UIPrintInfoDuplexLongEdge;
       print.printInfo = printInfo;
       print.showsPageRange = YES;
       print.printingItem = data;
       UIViewPrintFormatter *viewFormatter = [self.view viewPrintFormatter];
       viewFormatter.startPage = 0;
       print.printFormatter = viewFormatter;

       UIPrintInteractionCompletionHandler completionHandler = ^(UIPrintInteractionController *printInteractionController, BOOL completed, NSError *error) {};

       [print presentAnimated:YES completionHandler:completionHandler];
 }

【讨论】:

    【解决方案2】:

    您可以将所有数据转换成HTML并打印出来,

    - (void) didPressPrintExpenseButton {
       UIPrintInteractionController *printController = [UIPrintInteractionController sharedPrintController];    
       printController.delegate = self;
    
       void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
            ^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
                if (!completed && error) NSLog(@"Print error: %@", error);
            };
    
       UIPrintInfo *printInfo = [UIPrintInfo printInfo];    
       printInfo.outputType = UIPrintInfoOutputGeneral; 
       printInfo.jobName = @"Expense";  
       printController.printInfo = printInfo;
    
       UIMarkupTextPrintFormatter *htmlFormatter = [[UIMarkupTextPrintFormatter alloc]
                                                         initWithMarkupText:[self getHtmlInvoiceDescription]];  
       htmlFormatter.startPage = 0;
       htmlFormatter.contentInsets = UIEdgeInsetsMake(72.0, 72.0, 72.0, 72.0); // 1 inch margins    
       htmlFormatter.maximumContentWidth = 6 * 72.0;    
       printController.printFormatter = htmlFormatter;  
       [htmlFormatter release]; 
       printController.showsPageRange = YES;
       [printController presentAnimated:YES completionHandler:completionHandler];   
    }
    
    - (NSString *) getHtmlInvoiceDescription {
        NSMutableString *htmlString = [[NSMutableString alloc]init];
        [htmlString appendString:@"<html> \n"];
        [htmlString appendString:@"<body> \n"];
        [htmlString appendString:@"<table border='0' cellpadding='5' width='100%' >\n"];
        [htmlString appendString:@"<tr>\n"];
        [htmlString appendFormat:@"<td style=\"width='50%%'\"> %@ </td>", [self.addressString stringByReplacingOccurrencesOfString:@"\n" withString:@"<br>"]];
        //TODO change the image url here
        UIImage * image = [UIImage imageNamed:@"iTunesArtwork.png"];
        NSData *data = UIImagePNGRepresentation(image);
        NSString * dataString = [data base64EncodedString]; // Your own base 64 converter
        [htmlString appendFormat:@"<td style=\"width='50%%'\" align=\"right\"> <img src=\"data:image/png;base64,%@\" width='%.0f' height='%.0f' > </td>", dataString,
         verifyHeader.frame.size.height * image.size.width/image.size.height, verifyHeader.frame.size.height];
        [htmlString appendString:@"\n</tr> \n </table>"];
    
        [htmlString appendFormat:@"\n<h2> %@ </h2>", NSLocalizedString(@"Expense", @"")];
    
        [htmlString appendString:@"\n<table border='1' cellpadding='5' width='100%'>"];
    
        [htmlString appendString:@"\n<tr>"];
        [htmlString appendFormat:@"<td style=\"width='50%%' \"> %@ </td>", NSLocalizedString(@"Date: ", @"")];
        [htmlString appendFormat:@"<td width='50%%'> %@ </td>", [self getFormattedDateString:self.expense.date]];
        [htmlString appendString:@"</tr>"];
    
        [htmlString appendString:@"\n<tr>"];
        [htmlString appendFormat:@"<td> %@ </td>", NSLocalizedString(@"Reference no: ", @"")];
        [htmlString appendFormat:@"<td> %@ </td>", self.expense.referenceNo];
        [htmlString appendString:@"</tr>"];
    
        [htmlString appendString:@"\n<tr>"];
        [htmlString appendFormat:@"<td> %@ </td>", NSLocalizedString(@"Customer name: ", @"")];
        [htmlString appendFormat:@"<td> %@ </td>", self.expense.customerName];
        [htmlString appendString:@"</tr>"];
    
        [htmlString appendString:@"\n<tr>"];
        [htmlString appendFormat:@"<td> %@ </td>", NSLocalizedString(@"Product description: ", @"")];
        [htmlString appendFormat:@"<td> %@ </td>", self.expense.productDescription];
        [htmlString appendString:@"</tr>"];
    
        [htmlString appendString:@"\n</table>"];
        [htmlString appendString:@"\n</body> \n</html>"];
    
        NSString * tempString = [NSString stringWithString:htmlString];
        [htmlString release];   
        return tempString;
    }
    

    此外,还有一种方法可以将您的信息转换为 PDF,然后您可以打印出来。 查找苹果文档iPhone print API guidelines

    【讨论】:

    • 谢谢,但您能否提供示例代码或项目以将信息转换为 pdf,然后按照您上面提到的方式打印出来
    • @NAZIK,我也有同样的情况。我想从滚动视图上的内容中打印出来。请问能给我示例代码吗??
    【解决方案3】:

    可以take a screenshot programmatically,然后打印出来。在这种情况下,您只需打印屏幕截图即可。

    【讨论】:

    • 对不起,我上面提到的不是截屏,而是直接打印
    • 我就是这么说的。打印屏幕截图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    相关资源
    最近更新 更多