【问题标题】:How do I make a multiple page PDF from a textView?如何从 textView 制作多页 PDF?
【发布时间】:2012-03-01 07:01:01
【问题描述】:

我从我的 iPhone 应用程序生成了一个 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

【问题讨论】:

  • 据我所知,您必须跟踪您当前的 Y 坐标并更新您添加的每个项目。当您处于或接近边缘时,您将开始一个新页面。如果使用云服务是一种选择,您可以尝试使用 Docmosis 之类的东西来管理页面布局。如果您致力于以这样的代码布置文档,则对您没有帮助。
  • 你能告诉我怎么做吗?
  • 我会将其添加为答案,因为它太大而无法发表评论。

标签: ios pdf


【解决方案1】:

概念可以看这里

[来自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;
}

希望对你有帮助。

【讨论】:

  • 太棒了。非常感谢!
  • 这个答案不能说明字符串是否太长。如何把它分成几部分。
【解决方案2】:

我是 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;
    }
}

【讨论】:

  • 对不起,如果我的代码不够精确。时间太长了。
  • 当心以“\n”结尾的页面,它需要更多编码。
  • 我并不真正寻求“积分声誉”,但由于我是 Stackoverflow 的新手,因此不胜感激。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 2012-02-08
  • 2017-02-12
  • 2012-01-23
  • 1970-01-01
相关资源
最近更新 更多