2012-03-01 38 views
3

我从我的iPhone应用程序生成PDF文件,虽然大多数文件只有一个页面,但我希望能够检测文本是否要超出“边距”,如果是,请将其添加到下一个页。我对此很陌生,所以不太确定如何做到这一点。如何从textView制作多页PDF?

以下是代码。有什么建议么?

- (void) drawBorder 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    UIColor *borderColor = [UIColor grayColor]; 

    CGRect rectFrame = CGRectMake(kBorderInset, kBorderInset, pageSize.width-kBorderInset*2, pageSize.height-kBorderInset*2); 

    CGContextSetStrokeColorWithColor(currentContext, borderColor.CGColor); 
    CGContextSetLineWidth(currentContext, kBorderWidth); 
    CGContextStrokeRect(currentContext, rectFrame); 
} 

- (void)drawPageNumber:(NSInteger)pageNumber 
{ 
    NSString* pageNumberString = [NSString stringWithFormat:@"Page %d", pageNumber]; 
    UIFont* theFont = [UIFont systemFontOfSize:12]; 

    CGSize pageNumberStringSize = [pageNumberString sizeWithFont:theFont 
               constrainedToSize:pageSize 
                lineBreakMode:UILineBreakModeWordWrap]; 

    CGRect stringRenderingRect = CGRectMake(kBorderInset, 
              pageSize.height - 40.0, 
              pageSize.width - 2*kBorderInset, 
              pageNumberStringSize.height); 

    [pageNumberString drawInRect:stringRenderingRect withFont:theFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter]; 
} 

- (void) drawHeader:(NSString *)header 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    CGContextSetRGBFillColor(currentContext, 0.0, 0.0, 0.0, 1.0); 

    NSString *textToDraw = header; 

    UIFont *font = [UIFont systemFontOfSize:24.0]; 

    CGSize stringSize = [textToDraw sizeWithFont:font constrainedToSize:CGSizeMake(pageSize.width - 2*kBorderInset-2*kMarginInset, pageSize.height - 2*kBorderInset - 2*kMarginInset) lineBreakMode:UILineBreakModeWordWrap]; 

    CGRect renderingRect = CGRectMake(kBorderInset + kMarginInset, kBorderInset + kMarginInset, pageSize.width - 2*kBorderInset - 2*kMarginInset, stringSize.height); 

    [textToDraw drawInRect:renderingRect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft]; 
} 

- (void) drawText:(NSString *)bodyText 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    CGContextSetRGBFillColor(currentContext, 0.0, 0.0, 0.0, 1.0); 

    NSString *textToDraw = bodyText; 

    UIFont *font = [UIFont systemFontOfSize:14.0]; 

    CGSize stringSize = [textToDraw sizeWithFont:font 
           constrainedToSize:CGSizeMake(pageSize.width - 2*kBorderInset-2*kMarginInset, pageSize.height - 2*kBorderInset - 2*kMarginInset) 
            lineBreakMode:UILineBreakModeWordWrap]; 

    CGRect renderingRect = CGRectMake(kBorderInset + kMarginInset, kBorderInset + kMarginInset + 50.0, pageSize.width - 2*kBorderInset - 2*kMarginInset, stringSize.height); 

    [textToDraw drawInRect:renderingRect 
        withFont:font 
      lineBreakMode:UILineBreakModeWordWrap 
       alignment:UITextAlignmentLeft]; 

} 

- (void) drawLine 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 

    CGContextSetLineWidth(currentContext, kLineWidth); 

    CGContextSetStrokeColorWithColor(currentContext, [UIColor blackColor].CGColor); 

    CGPoint startPoint = CGPointMake(kMarginInset + kBorderInset, kMarginInset + kBorderInset + 40.0); 
    CGPoint endPoint = CGPointMake(pageSize.width - 2*kMarginInset -2*kBorderInset, kMarginInset + kBorderInset + 40.0); 

    CGContextBeginPath(currentContext); 
    CGContextMoveToPoint(currentContext, startPoint.x, startPoint.y); 
    CGContextAddLineToPoint(currentContext, endPoint.x, endPoint.y); 

    CGContextClosePath(currentContext);  
    CGContextDrawPath(currentContext, kCGPathFillStroke); 
} 

- (void) drawImage:(UIImage *)image 
{ 
    //UIImage * demoImage = [UIImage imageNamed:@"demo.png"]; 
    [image drawInRect:CGRectMake((pageSize.width - image.size.width/2)/2, 350, image.size.width/2, image.size.height/2)]; 
} 


- (void) generatePdf: (NSString *)thefilePath :(NSString *) theHeader :(NSString *) theText :(UIImage *) theImage 
{ 

    pageSize = CGSizeMake(612, 792); 
    UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil); 

    NSInteger currentPage = 0; 
    BOOL done = NO; 
    do 
    { 
     //Start a new page. 
     UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil); 

     //Draw a page number at the bottom of each page. 
     currentPage++; 
     [self drawPageNumber:currentPage]; 

     //Draw a border for each page. 
     [self drawBorder]; 

     //Draw text fo our header. 
     [self drawHeader:theHeader]; 

     //Draw a line below the header. 
     [self drawLine]; 

     //Draw some text for the page. 
     [self drawText:theText]; 

     //Draw an image 
     [self drawImage:theImage]; 
     done = YES; 
    } 
    while (!done); 

    // Close the PDF context and write the contents out. 
    UIGraphicsEndPDFContext(); 
} 

#pragma mark - View lifecycle 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
} 

- (IBAction)generatePdfWithFileName:(id)sender 
{ 
    pageSize = CGSizeMake(612, 792); 
    NSString *fileName = @"test.pdf"; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName]; 

    NSString *header = @"This is the bad ass header section!"; 
    NSString *text = @"There is so much to say here I don't know where to begin...."; 

    [self generatePdf : pdfFileName : header:text:nil]; 
} 

@end 
+2

就我所知,您必须跟踪您当前的Y坐标并更新每个添加的项目。当您处于或接近保证金时,您将开始一个新页面。如果使用云服务是一种选择,您可以尝试像管理页面布局本身的Docmosis。如果你承诺用这样的代码来编排文档,这对你没有任何帮助。 – 2012-03-01 08:07:03

+0

你可以给我一个想法如何去做这件事? – jroyce 2012-03-01 17:52:29

+0

我会将它添加为答案,因为它太大而不能发表评论。 – 2012-03-02 04:20:45

回答

9

的概念在这里可以看到

[从http://spitzkoff.com/craig/?p=160]

当放置物品,让身高:

CGSize size = [name sizeWithFont:studentNameFont forWidth:maxWidth lineBreakMode:UILineBreakModeWordWrap]; 
[name drawAtPoint:CGPointMake(kMargin, currentPageY) forWidth:maxWidth withFont:studentNameFont lineBreakMode:UILineBreakModeWordWrap]; 
currentPageY += size.height; 

在适当的点,检查currentY,如果你决定需要移动到新页面:

if (size.height + currentPageY > maxHeight) { 
// create a new page and reset the current page's Y value 
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil); 
currentPageY = kMargin; 
} 

我希望有帮助。

+0

太棒了。非常感谢你! – jroyce 2012-03-02 04:40:38

+0

如何保持这种中频条件? – maniclorn 2012-08-18 13:40:50

+0

这个答案不会告诉一个字符串是否太长。如何将其分解成部分。 – Saad 2015-04-12 00:42:25

1

我是新来的stackoverflow,但我想建议一个简短的答案“闯入部分长文本视图”的问题。

我使用的方法肯定不是将文本分解为多个部分的最有效方式,但它是我找到并且工作的唯一方式。 取文本的一部分,我只是检查一个循环,然后逐字绘制,如果子文本适合我的页面,这意味着高度允许。如果整个文本不合适,那么我的代码将只绘制找到的部分。例如,我可以将一个长文本分成四页......至少。 对不起,我缺乏经验,如果我的答案只是一瞥,“如何”的想法还不够清楚。

澄清我的答案。我添加了我用来检查“子文本”所需高度(找到)的方法(每次用添加到“子文本”的单词检查)。因为“sizeWithFont:”自IOS 7以来已被弃用,所以我使用“boundingRectWithSize:”方法。

// Process, that can take long though, to find the next start of the part of a text that hasn't been drawned yet. 

float widthRect; 
widthRect = pageWidth - 2 * leftMargin; 

    - (unsigned int) findNextStartingPos:(NSString *)text withHeight:(float) height 
    { 
     NSString *character; 
     unsigned int pos = 0; 
     unsigned int posFound = 0; 
     unsigned int lastPosFound = 0; 
     BOOL found = NO; 
     NSString *textTest; 
     float heightFound; 

     while (pos <= [text length]-1) 
     { 
      character = [text substringWithRange:NSMakeRange(pos, 1)]; 
      if ([character isEqualToString:@" "] || [character isEqualToString:@"\n"]) 
      { 
       posFound = pos; 
       found = YES; 
      } 

      if (found) 
      { 
       textTest = [text substringWithRange:NSMakeRange(0, posFound)]; 
       heightFound = lroundf([self heightFound:textTest withWidth:widthRect fontSize:fontSizeBody center:NO]); 

       if (heightFound > height) 
       { 
        if (lastPosFound == 0) 
        { 
         posFound = lastPosFound; 
        } else 
        { 
         posFound = lastPosFound + 1; 
        } 
        if (posFound > [text length]-1) posFound = lastPosFound; 
        break; 
       } 
       lastPosFound = posFound; 
      } 
      pos++; 
     } 

     return posFound; 

    } return posFound; 

    } 


// Returns the height needed to draw a text (and to check for space in a page) 
-(float) heightFound:(NSString *)text withWidth:(float)width fontSize:(CGFloat)fontSize center:(BOOL)center 
{ 
    if ([text length] != 0) 
    { 
     UIFont *font = [UIFont fontWithName:@"Helvetica" size:fontSize]; 

     NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 
     paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; 
     if (center) 
     { 
      paragraphStyle.alignment = NSTextAlignmentCenter; 
     } else { 
      paragraphStyle.alignment = NSTextAlignmentLeft; 
     } 
     NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: paragraphStyle}; 

     NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:attributes]; 

     CGRect newRect = [attributedString boundingRectWithSize:(CGSize){width, CGFLOAT_MAX} options:NSStringDrawingUsesLineFragmentOrigin context:nil]; 

     return newRect.size.height; 

    } else { 
     return 0; 
    } 
} 
+0

对不起,如果我的代码不是精确enoungh。它本来就太长了。 – 2016-03-10 06:50:09

+0

要小心一个以“\ n”结尾的页面,它需要更多的编码。 – 2016-03-10 07:07:19

+0

我并不真正寻求“积分声望”,但由于我是新手,因此有些鼓励将会受到赞赏。 – 2016-03-10 07:41:44