2013-07-24 69 views
1

我已经创建了一个PDF格式的表格。表格不会延续到下一页,而是在下一页中创建一个新表格,其y位置与第一页面的位置相同。我如何继续在下一页上绘制表格?在Pdf中绘制表格?

- (IBAction)pdfPressed:(id)sender { 
    // create some sample data. In a real application, this would come from the database or an API. 
    NSString* path = [[NSBundle mainBundle] pathForResource:@"sampleData" ofType:@"plist"]; 
    NSDictionary* data = [NSDictionary dictionaryWithContentsOfFile:path]; 
    NSArray* students = [data objectForKey:@"Students"]; 

    // get a temprorary filename for this PDF 
    path = NSTemporaryDirectory(); 
    self.pdfFilePath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.pdf", [[NSDate date] timeIntervalSince1970] ]]; 

    // Create the PDF context using the default page size of 612 x 792. 
    // This default is spelled out in the iOS documentation for UIGraphicsBeginPDFContextToFile 
    UIGraphicsBeginPDFContextToFile(self.pdfFilePath, CGRectZero, nil); 

    // get the context reference so we can render to it. 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    int currentPage = 0; 

    // maximum height and width of the content on the page, byt taking margins into account. 
    CGFloat maxWidth = kDefaultPageWidth - kMargin * 2; 
    CGFloat maxHeight = kDefaultPageHeight - kMargin * 2; 

    // we're going to cap the name of the class to using half of the horizontal page, which is why we're dividing by 2 
    CGFloat classNameMaxWidth = maxWidth/2; 

    // the max width of the grade is also half, minus the margin 
    CGFloat gradeMaxWidth = (maxWidth/2) - kColumnMargin; 

    // only create the fonts once since it is a somewhat expensive operation 
    UIFont* studentNameFont = [UIFont boldSystemFontOfSize:17]; 
    UIFont* classFont = [UIFont systemFontOfSize:15]; 

    CGFloat currentPageY = 0; 

    // iterate through out students, adding to the pdf each time. 
    for (NSDictionary* student in students) 
    { 
    // every student gets their own page 
    // Mark the beginning of a new page. 
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil); 
    currentPageY = kMargin; 

    // draw the student's name at the top of the page. 
    NSString* name = [NSString stringWithFormat:@"%@ %@", 
          [student objectForKey:@"FirstName"], 
          [student objectForKey:@"LastName"]]; 

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

    // draw a one pixel line under the student's name 
    CGContextSetStrokeColorWithColor(context, [[UIColor blueColor] CGColor]); 
    CGContextMoveToPoint(context, kMargin, currentPageY); 
    CGContextAddLineToPoint(context, kDefaultPageWidth - kMargin, currentPageY); 
    CGContextStrokePath(context); 
    int xOrigin = 50; 
    int yOrigin = 300; 

    int rowHeight = 50; 
    int columnWidth = 120; 

    int numberOfRows = 3; 
    int numberOfColumns = 4; 


    // iterate through the list of classes and add these to the PDF. 
    NSArray* classes = [student objectForKey:@"Classes"]; 
    for (NSDictionary* class in classes) 
    { 
     NSString* className = [class objectForKey:@"Name"]; 
     NSString* grade = [class objectForKey:@"Grade"]; 

     // before we render any text to the PDF, we need to measure it, so we'll know where to render the 
     // next line. 
     size = [className sizeWithFont:classFont constrainedToSize:CGSizeMake(classNameMaxWidth, MAXFLOAT) lineBreakMode:UILineBreakModeWordWrap]; 

     // if the current text would render beyond the bounds of the page, 
     // start a new page and render it there instead 
     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; 
     } 

     // render the text 
     [className drawInRect:CGRectMake(kMargin, currentPageY, classNameMaxWidth, maxHeight) withFont:classFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft]; 

     // print the grade to the right of the class name 
     [grade drawInRect:CGRectMake(kMargin + classNameMaxWidth + kColumnMargin, currentPageY, gradeMaxWidth, maxHeight) withFont:classFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft]; 

     currentPageY += size.height; 

     [self drawTableAt:CGPointMake(xOrigin, yOrigin) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows andColumnCount:numberOfColumns]; 
    } 

    // increment the page number. 
    currentPage++; 
    } 

    // end and save the PDF. 
    UIGraphicsEndPDFContext(); 

    // Ask the user if they'd like to see the file or email it. 
    UIActionSheet* actionSheet = [[[UIActionSheet alloc] initWithTitle:@"Would you like to preview or email this PDF?" 
                  delegate:self 
                cancelButtonTitle:@"Cancel" 
               destructiveButtonTitle:nil 
                otherButtonTitles:@"Preview", @"Email", nil] autorelease]; 
    [actionSheet showInView:self.view]; 
} 

-(void)drawTableAt:(CGPoint)origin 
    withRowHeight:(int)rowHeight 
    andColumnWidth:(int)columnWidth 
     andRowCount:(int)numberOfRows 
    andColumnCount:(int)numberOfColumns 
{ 
    for (int i = 0; i <= numberOfRows; i++) { 
    int newOrigin = origin.y + (rowHeight*i); 
    CGPoint from = CGPointMake(origin.x, newOrigin); 
    CGPoint to = CGPointMake(origin.x + (numberOfColumns*columnWidth), newOrigin); 
    [self drawLineFromPoint:from toPoint:to]; 
    } 

    for (int i = 0; i <= numberOfColumns; i++) { 
    int newOrigin = origin.x + (columnWidth*i); 
    CGPoint from = CGPointMake(newOrigin, origin.y); 
    CGPoint to = CGPointMake(newOrigin, origin.y +(numberOfRows*rowHeight)); 
    [self drawLineFromPoint:from toPoint:to]; 
    } 
} 

-(void)drawLineFromPoint:(CGPoint)from toPoint:(CGPoint)to 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetLineWidth(context, 2.0); 
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 
    CGFloat components[] = {0.2, 0.2, 0.2, 0.3}; 
    CGColorRef color = CGColorCreate(colorspace, components); 

    CGContextSetStrokeColorWithColor(context, color); 
    CGContextMoveToPoint(context, from.x, from.y); 
    CGContextAddLineToPoint(context, to.x, to.y); 

    CGContextStrokePath(context); 
    CGColorSpaceRelease(colorspace); 
    CGColorRelease(color); 
} 

回答

0

PDF图纸是“以页面为中心的”。当你开始绘制第二页时,你已经有效地获得了一个全新的上下文等等。除非你专门编写代码,否则不会有任何从一个页面到另一个页面绘制流血的概念。

我看到你已经通过检查className的尺寸是否会覆盖maxHeight来解决“类”循环中的这个分页问题。你需要为表格做同样的事情。

在高层次上,您一次只能渲染一行,每行以同样的方式进行检查,看下一行是否会将表格放在maxHeight之上,然后如果是,则执行同样的事情,你已经在类循环中做 - 开始一个新的页面,重置currentPageY,并继续绘制行,直到表完成,等等。

总之:没有办法让这个“免费“。