在iPhone应用程序中打印html页面

时间:2011-07-23 04:44:54

标签: iphone ios printing

我在iPhone应用程序中以html格式获取文本。我需要打印页面,但我不希望标签也以简单文本显示在打印输出中。

如何在我的iPhone应用程序中完成打印功能,直接打印html文档但不打印html标签?

2 个答案:

答案 0 :(得分:4)

在这里,您可以使用以下功能在iPhone应用程序中打开html页面。

(1)此方法在控制器中打印html。

- (IBAction) btnPrint_Clicked:(id)sender
{
    NSString *htmlData = @"Your HTML Text";        
    [appDelegate.myWebView loadHTMLString:htmlData baseURL:nil];

    [appDelegate printWebPage:[NSString stringWithFormat:@"Employee - %@ %@",[dicEmployeeData valueForKey:@"firstname"],[dicEmployeeData valueForKey:@"lastname"]]];
}

(2)此方法在appDelegate类中也导入MyPrintPageRenderer.h

#import "MyPrintPageRenderer.h".

- (void) printWebPage:(NSString *)title
{
    printController = [UIPrintInteractionController sharedPrintController];
    if(!printController){
        NSLog(@"Couldn't get shared UIPrintInteractionController!");
        return;
    }

    UIPrintInteractionCompletionHandler completionHandler = 
    ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
        if(!completed && error){
            NSLog(@"FAILED! due to error in domain %@ with error code %u", error.domain, error.code);   
        }
    };


    // Obtain a printInfo so that we can set our printing defaults.
    UIPrintInfo *printInfo = [UIPrintInfo printInfo];
    // This application produces General content that contains color.
    printInfo.outputType = UIPrintInfoOutputGeneral;
    // We'll use the URL as the job name
    printInfo.jobName = title;
    // Set duplex so that it is available if the printer supports it. We
    // are performing portrait printing so we want to duplex along the long edge.
    printInfo.duplex = UIPrintInfoDuplexLongEdge;
    // Use this printInfo for this print job.
    printController.printInfo = printInfo;

    // Be sure the page range controls are present for documents of > 1 page.
    printController.showsPageRange = YES;

    // This code uses a custom UIPrintPageRenderer so that it can draw a header and footer.
    MyPrintPageRenderer *myRenderer = [[MyPrintPageRenderer alloc] init];
    // The MyPrintPageRenderer class provides a jobtitle that it will label each page with.
    myRenderer.jobTitle = printInfo.jobName;
    // To draw the content of each page, a UIViewPrintFormatter is used.
    UIViewPrintFormatter *viewFormatter = [myWebView viewPrintFormatter];

#if SIMPLE_LAYOUT
    /*
     For the simple layout we simply set the header and footer height to the height of the
     text box containing the text content, plus some padding.

     To do a layout that takes into account the paper size, we need to do that 
     at a point where we know that size. The numberOfPages method of the UIPrintPageRenderer 
     gets the paper size and can perform any calculations related to deciding header and
     footer size based on the paper size. We'll do that when we aren't doing the simple 
     layout.
     */
    UIFont *font = [UIFont fontWithName:@"Helvetica" size:HEADER_FOOTER_TEXT_HEIGHT]; 
    CGSize titleSize = [myRenderer.jobTitle sizeWithFont:font];
    myRenderer.headerHeight = myRenderer.footerHeight = titleSize.height + HEADER_FOOTER_MARGIN_PADDING;
#endif
    [myRenderer addPrintFormatter:viewFormatter startingAtPageAtIndex:0];
    // Set our custom renderer as the printPageRenderer for the print job.
    printController.printPageRenderer = myRenderer;
    [myRenderer release];

    // The method we use presenting the printing UI depends on the type of 
    // UI idiom that is currently executing. Once we invoke one of these methods
    // to present the printing UI, our application's direct involvement in printing
    // is complete. Our custom printPageRenderer will have its methods invoked at the
    // appropriate time by UIKit.

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        if(orientationStyle == 1)
            [printController presentFromRect:CGRectMake(510, 150, 0, 0) inView:self.window animated:YES completionHandler:completionHandler];
        else
            [printController presentFromRect:CGRectMake(770, 165, 0, 0) inView:self.window animated:YES completionHandler:completionHandler];
    }
    else
        [printController presentAnimated:YES completionHandler:completionHandler];  // iPhone
}

(3)在这里,您还需要为打印功能添加一个类文件:

MyPrintPageRenderer.h文件

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

/*
  Setting SIMPLE_LAYOUT to 1 uses a layout that involves less application code and
  produces a layout where the web view content has margins that are relative to
  the imageable area of the paper.

  Setting SIMPLE_LAYOUT to 0 uses a layout that involves more computation and setup
  and produces a layout where the webview content is inset 1/2 from the edge of the 
  paper (assuming it can be without being clipped). See the comments in 
  MyPrintPageRenderer.m immediately after #if !SIMPLE_LAYOUT.
*/
#define SIMPLE_LAYOUT 1

// The point size to use for the height of the text in the
// header and footer.
#define HEADER_FOOTER_TEXT_HEIGHT     10

// The left edge of text in the header will be offset from the left 
// edge of the imageable area of the paper by HEADER_LEFT_TEXT_INSET.
#define HEADER_LEFT_TEXT_INSET        20

// The header and footer will be inset this much from the edge of the
// imageable area just to avoid butting up right against the edge that
// will be clipped.
#define HEADER_FOOTER_MARGIN_PADDING  5

// The right edge of text in the footer will be offset from the right 
// edge of the imageable area of the paper by FOOTER_RIGHT_TEXT_INSET.
#define FOOTER_RIGHT_TEXT_INSET       20

#if !SIMPLE_LAYOUT

// The header and footer content will be no closer than this distance
// from the web page content on the printed page.
#define MIN_HEADER_FOOTER_DISTANCE_FROM_CONTENT 10

// Enforce a minimum 1/2 inch margin on all sides.
#define MIN_MARGIN 36

#endif

@interface MyPrintPageRenderer : UIPrintPageRenderer {
  NSRange pageRange;
  NSString *jobTitle;
}

@property (readwrite, retain) NSString *jobTitle;

@end

MyPrintPageRenderer.m文件

#import "MyPrintPageRenderer.h"
#import <CoreGraphics/CoreGraphics.h>

@implementation MyPrintPageRenderer

@synthesize jobTitle;

#if !SIMPLE_LAYOUT
/*
 For the case where we are not doing SIMPLE_LAYOUT, this code does the following:
 1) Makes the minimum margin for the content of the content portion of the printout (i.e.
    the webpage) at least 1/4" away from the edge of the paper. If the hardware margins
    of the paper are greater than that, then the hardware margins will force the content
    margins to be as large as they allow.
 2) Because this format is relative to the edge of the sheet rather than the imageable area, we
    need to compute these values once we know the paper size and printableRect. This is known
    in the numberOfPages method and that is the reason this code overrides that method.
 3) Since the header and footer heights of a UIPrintFormatter plays a part in determining height of
    of the content area, this code computes those heights, taking into account that we want
    the minimum 1/4" margin on the content.
 4) This code also enforces a minimum distance (MIN_HEADER_FOOTER_DISTANCE_FROM_CONTENT)
    between the header and footer and the content area.
 5) Note that the insets used for the contentInsets property of a UIPrintFormatter are relative
    to the imageable area of the paper being printed upon. The header and footer height are also
    imposed relative to the edge of the top and bottom hardware margin. 
*/


// Compute an edge inset to produce the minimum margin
// based on the imageable area margin of the edge.
static inline CGFloat EdgeInset(CGFloat imageableAreaMargin)
{
  /*
    Since the offsets specified to a print formatter are relative 
    to printRect and we want our edges to be at least MIN_MARGIN
    from the edge of the sheet of paper, here we compute the necessary
    offset to achieve our margin. If the imageable area margin is
    larger than our MIN_MARGIN, we return an offset of zero which means
    that the imageable area margin will be used.
  */
  CGFloat val = MIN_MARGIN - imageableAreaMargin;
  return val > 0 ? val : 0;
}

// Compute a height for the header or footer, based on the margin for the edge
// in question and the height of the text being drawn.
static CGFloat HeaderFooterHeight(CGFloat imageableAreaMargin, CGFloat textHeight)
{
  /*
    Make the header and footer height provide for a minimum margin of MIN_MARGIN. We
    want the content to appear at least MIN_HEADER_FOOTER_DISTANCE_FROM_CONTENT from
    the header/footer text. If that requires a margin > MIN_MARGIN then we'll use that.
    Remember, the header/footer height returned needs to be relative to the edge of 
    the imageable area.
  */
  CGFloat headerFooterHeight = imageableAreaMargin + textHeight + 
        MIN_HEADER_FOOTER_DISTANCE_FROM_CONTENT + HEADER_FOOTER_MARGIN_PADDING;
  if(headerFooterHeight < MIN_MARGIN)
    headerFooterHeight = MIN_MARGIN - imageableAreaMargin;
  else {
    headerFooterHeight -= imageableAreaMargin;
  }

  return headerFooterHeight;
}

/*  Override numberOfPages so we can compute the values for our UIPrintFormatter based on the
    paper used for the print job. When this is called, self.paperRect and self.printableRect
    reflect the paper size and imageable area of the destination paper.
*/
- (NSInteger)numberOfPages
{
  // We only have one formatter so obtain it so we can set its paramters.
  UIPrintFormatter *myFormatter = (UIPrintFormatter *)[self.printFormatters objectAtIndex:0];

  // Compute insets so that margins are 1/2 inch from edge of sheet, or at
  // the edge of the imageable area if it is larger than that. The EdgeInset
  // function takes a margin for the edge being calculated.
  CGFloat leftInset = EdgeInset(self.printableRect.origin.x);
  CGFloat rightInset = EdgeInset(self.paperRect.size.width - CGRectGetMaxX(self.printableRect));

  // Top inset is only used if we want a different inset for the first page and we don't.
  // The bottom inset is never used by a viewFormatter.
  myFormatter.contentInsets = UIEdgeInsetsMake(0, leftInset, 0, rightInset);

  // Now compute what we want for the header size and footer size. These determine the
  // size and placement of the content height.

  // First compute the 
  UIFont *font = [UIFont fontWithName:@"Helvetica" size:HEADER_FOOTER_TEXT_HEIGHT]; 
  // We'll use the same title height for the header and footer. This is the minimum height 
  // the footer can be. 
  CGFloat titleHeight = [self.jobTitle sizeWithFont:font].height;

  /*
    We want to calculate these heights so that the content top and bottom
    edges are a minimum distance from the edge of the sheet and are inset at least
    MIN_HEADER_FOOTER_DISTANCE_FROM_CONTENT from the header and footer.
  */
  self.headerHeight = HeaderFooterHeight(CGRectGetMinY(self.printableRect), titleHeight); 
  self.footerHeight = HeaderFooterHeight(self.paperRect.size.height - CGRectGetMaxY(self.printableRect), titleHeight); 

  // Just to be sure, never allow the content to go past our minimum margins for the content area.
  myFormatter.maximumContentWidth = self.paperRect.size.width - 2*MIN_MARGIN;
  myFormatter.maximumContentHeight = self.paperRect.size.height - 2*MIN_MARGIN;


  /*
      Let the superclass calculate the total number of pages. Since this UIPrintPageRenderer only uses a UIPrintFormatter,
      the superclass knows the number of pages based on the formatter metrics and the paper/printable rects. 

      Note that since this code only uses a single print formatter we could just as easily use myFormatter.pageCount 
      to obtain the total number of pages. But it would be more complex than that if we had multiple printformatters 
      for our job so we're using a more general approach here for illustration and it is correct for 1 or more formatters.
   */
  return [super numberOfPages];
}

#endif

/*
 Our pages don't have any intrinsic notion of page
 number; our footer will number the pages so that users
 know the order. So for us, we will always render the first
 page printed as page 1, even if the range is n-m.
 So we track which page in the range is the first index
 as well as the total length of our range.
*/
- (void)prepareForDrawingPages:(NSRange)range
{
  pageRange = range;
  [super prepareForDrawingPages:range];
}

- (void)drawHeaderForPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)headerRect
{
  if(self.jobTitle){
    UIFont *font = [UIFont fontWithName:@"Helvetica" size:HEADER_FOOTER_TEXT_HEIGHT]; 
    // Position the title starting from the left and inset slightly from the left edge of the imageable area.
    CGFloat startX = CGRectGetMinX(headerRect) + HEADER_LEFT_TEXT_INSET;
    // The header will always be a fixed amount inset from edge of the the imageable area of the paper.
    // The point passed to drawAtPoint is at the top-left of the text that will be drawn, hence
    // the starting point is the y coordinate of the top of the imageable area rect plus any padding.
    CGFloat startY = self.printableRect.origin.y + HEADER_FOOTER_MARGIN_PADDING; 
    CGPoint startPoint = CGPointMake(startX, startY);
    [self.jobTitle drawAtPoint:startPoint withFont: font];
  }
}


- (void)drawFooterForPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)footerRect 
{
  NSString *localizedPageNumberString = NSLocalizedString(@"Page %d of %d", @"Localized Page Count String");
  // Compute the page numbers so that the first page in the range being 
  // printed is always page 1 of N, where N is the total number of pages.
  NSString *pageNumberString = [NSString stringWithFormat:localizedPageNumberString,
                  pageIndex+1 - pageRange.location, pageRange.length]; 
  UIFont *font = [UIFont fontWithName:@"Helvetica" size:HEADER_FOOTER_TEXT_HEIGHT];
  CGSize pageNumSize = [pageNumberString sizeWithFont:font]; 
  // Position the page number string so that it ends inset by FOOTER_RIGHT_TEXT_INSET from the right edge
  // of the imageable area.
  CGFloat startX = CGRectGetMaxX(footerRect) - pageNumSize.width - FOOTER_RIGHT_TEXT_INSET; 
  // The footer will always be a fixed amount inset from the bottom edge of the imageable area of the paper.
  // The point passed to drawAtPoint is the top-left of the text that will be drawn, hence
  // the height needs to be subtracted from the starting point.
  CGFloat startY = CGRectGetMaxY(self.printableRect) - pageNumSize.height - HEADER_FOOTER_MARGIN_PADDING; 
  CGPoint startPoint = CGPointMake(startX, startY); 

  [pageNumberString drawAtPoint:startPoint withFont: font];
}

@end

如果您需要更多帮助,请告诉我。它会根据您的要求为html文档提供支持。

答案 1 :(得分:0)

我会做一些假设,因为你的问题不是很清楚。您正在尝试打印HTML文档,但文档的某些部分您不想打印。这是对的吗?

如果是这样,一个选项是使用ElementParser之类的东西来解析文档并删除你不想要的部分。