从文本内容创建多页PDF

时间:2014-09-03 07:57:24

标签: ios objective-c core-text

我有很长的文字内容,希望将其转换为多页PDF文件。

我已按照本教程http://www.raywenderlich.com/6581/how-to-create-a-pdf-with-quartz-2d-in-ios-5-tutorial-part-1中提供的说明进行操作。

但我正在努力制作pdf多页面。

我使用的代码可以创建单页PDF。

+(void)drawText
{
NSString* textToDraw = @"The sample text";

CFStringRef stringRef = (__bridge CFStringRef)textToDraw;
// Prepare the text using a Core Text Framesetter
CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, NULL);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);

CGRect frameRect = CGRectMake(50, 50, 512, 1000);
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, frameRect);

// Get the frame that will do the rendering.
CFRange currentRange = CFRangeMake(0, 0);
CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
CGPathRelease(framePath);

// Get the graphics context.
CGContextRef currentContext = UIGraphicsGetCurrentContext();

// Put the text matrix into a known state. This ensures
// that no old scaling factors are left in place.
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

// Core Text draws from the bottom-left corner up, so flip
// the current transform prior to drawing.
CGContextTranslateCTM(currentContext, 0, 100);
CGContextScaleCTM(currentContext, 1.0, -1.0);

// Draw the frame.
CTFrameDraw(frameRef, currentContext);

CFRelease(frameRef);
CFRelease(stringRef);
CFRelease(framesetter);
}


+(void)drawPDF:(NSString*)fileName
{
// Create the PDF context using the default page size of 612 x 792.
UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
// Mark the beginning of a new page.
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);

[self drawText];

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

1 个答案:

答案 0 :(得分:1)

您可以使用以下代码绘制pdf:

// Use Core Text to draw the text in a frame on the page.

- (CFRange)renderPage:(NSInteger)pageNum withTextRange:(CFRange)currentRange
       andFramesetter:(CTFramesetterRef)framesetter
{
    // Get the graphics context.
    CGContextRef    currentContext = UIGraphicsGetCurrentContext();

    // Put the text matrix into a known state. This ensures
    // that no old scaling factors are left in place.
    CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

    // Create a path object to enclose the text. Use 72 point
    // margins all around the text.
    CGRect    frameRect = CGRectMake(72, 72, 468, 648);
    CGMutablePathRef framePath = CGPathCreateMutable();
    CGPathAddRect(framePath, NULL, frameRect);

    // Get the frame that will do the rendering.
    // The currentRange variable specifies only the starting point. The framesetter
    // lays out as much text as will fit into the frame.
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
    CGPathRelease(framePath);

    // Core Text draws from the bottom-left corner up, so flip
    // the current transform prior to drawing.
    CGContextTranslateCTM(currentContext, 0, kDefaultPageHeight);
    CGContextScaleCTM(currentContext, 1.0, -1.0);

    // Draw the frame.
    CTFrameDraw(frameRef, currentContext);

    // Update the current range based on what was drawn.
    currentRange = CTFrameGetVisibleStringRange(frameRef);
    currentRange.location += currentRange.length;
    currentRange.length = 0;
    CFRelease(frameRef);

    return currentRange;
}


- (void)drawPageNumber:(NSInteger)pageNum
{
    NSString* pageString = [NSString stringWithFormat:@"Page %ld", (long)pageNum];
    UIFont* theFont = [UIFont systemFontOfSize:12];
   // CGSize maxSize = CGSizeMake(kDefaultPageWidth, 72);


    CGSize pageStringSize = [pageString sizeWithAttributes:
                   @{NSFontAttributeName:
                         theFont}];

  //  CGSize pageStringSize = [pageString sizeWithFont:theFont
                                //   constrainedToSize:maxSize
                                //       lineBreakMode:NSLineBreakByClipping];
    CGRect stringRect = CGRectMake(((kDefaultPageWidth - pageStringSize.width) / 2.0),
                                   720.0 + ((72.0 - pageStringSize.height) / 2.0) ,
                                   pageStringSize.width,
                                   pageStringSize.height);


    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;

    NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:15], NSParagraphStyleAttributeName: paragraphStyle};

    [pageString drawInRect:stringRect withAttributes:attributes];



   // [pageString drawInRect:stringRect withFont:theFont];
}

保存pdf:

- (IBAction)savePDFFile:(id)sender
{
    NSString* path = [[NSBundle mainBundle] pathForResource:@"sampleData" ofType:@"plist"];

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

    // Prepare the text using a Core Text Framesetter
    CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, 
                                                                 (CFStringRef)textView.text, NULL);
    if (currentText) {
        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
        if (framesetter) {

            NSString* pdfFileName = self.pdfFilePath; //[NSString stringWithString:@"test.pdf"];

            // Create the PDF context using the default page: currently constants at the size 
            // of 612 x 792.
            UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);

            CFRange currentRange = CFRangeMake(0, 0);
            NSInteger currentPage = 0;
            BOOL done = NO;

            do {
                // Mark the beginning of a new page.
                UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, 
                                                          kDefaultPageHeight), nil);

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

                // Render the current page and update the current range to
                // point to the beginning of the next page.
                currentRange = [self renderPage:currentPage withTextRange:
                                currentRange andFramesetter:framesetter];

                // If we're at the end of the text, exit the loop.
                if (currentRange.location == CFAttributedStringGetLength
                    ((CFAttributedStringRef)currentText))
                    done = YES;
            } while (!done);

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

            // Release the framewetter.
            CFRelease(framesetter);

        } else {
            NSLog(@"Could not create the framesetter needed to lay out the atrributed string.");
        }
        // Release the attributed string.
        CFRelease(currentText);
    } else {
        NSLog(@"Could not create the attributed string for the framesetter");
    }
    // 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];

}

这里是完整的演示,请检查:http://ge.tt/1eW8iJt1/v/0