如何从我的iPhone应用程序打印?

3

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


基本上,您需要将滚动视图转换为图像文件,然后打印出来。我也做了同样的事情,只是将图像作为电子邮件附件发送。 - Hot Licks
3个回答

2
你需要将所有的数据转换为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)在viewDidLoad方法中使用以下代码:

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

1

您可以将所有数据转换为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打印API指南


谢谢,但是你能提供一个将信息转换为PDF并打印的示例代码或项目吗,就像你上面提到的那样? - Nazik
@NAZIK,我也有同样的情况。我想要打印我的滚动视图上的内容。请问你能给我提供一份示例代码吗? - Himanshu Mahajan

0

可以通过编程程序化地截屏,然后打印出来。在这种情况下,您只需打印截屏即可。


2
抱歉,我之前提到的不是关于截屏的问题,而是关于直接打印的问题。 - Nazik
1
这就是我说的。打印屏幕截图。 - Mundi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接