将UITableView导出为PDF

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将UITableView导出为PDF相关的知识,希望对你有一定的参考价值。

我正在努力处理一段简单的代码,我花了很多时间搜索这个,检查过论坛并尝试了不同的东西。我几乎在那里,但并不完全。基本上我需要将UITableView的内容转换为PDF。

我下面的代码似乎工作得很好,除非用户必须将表格滑动到其内容的末尾,否则将不会呈现该部分。我以编程方式滚动了UITableView,但这似乎并没有成功。我越来越多地进入Quartz2D以进一步理解这些东西,但客户端需要这个固定的昨天:-)

    -(void) createPDFfromUITable:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
    CGRect priorBounds = self.tableView.bounds;
    CGSize fittedSize = [self.tableView sizeThatFits:CGSizeMake(priorBounds.size.width,3000)];
    self.tableView.bounds = CGRectMake(0, 0, fittedSize.width,1800);

    CGRect pdfPageBounds = CGRectMake(0, 0,self.view.bounds.size.width,792);
    NSMutableData *pdfData = [[NSMutableData alloc] init];

    UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil);
    CGFloat pageOriginY=0;
    for(int i=0;i<2;i++)//for (CGFloat pageOriginY = 0; pageOriginY < fittedSize.height; pageOriginY += pdfPageBounds.size.height)
    {
        UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil);
        CGContextSaveGState(UIGraphicsGetCurrentContext());
        {
            CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -pageOriginY);
            [self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:([_resultados count]-1)] atScrollPosition:UITableViewScrollPositionTop animated:NO];
            CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -pageOriginY);

        } CGContextRestoreGState(UIGraphicsGetCurrentContext());

        pageOriginY += pdfPageBounds.size.height;
    }

    UIGraphicsEndPDFContext();

    self.tableView.bounds = priorBounds; // Reset the tableView

    NSArray     *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString    *documentsPath = [paths objectAtIndex:0];
    NSString    *filePathPDF = [documentsPath stringByAppendingPathComponent:aFilename];
    [pdfData writeToFile:filePathPDF atomically:YES];
    [self showEmail:filePathPDF];
}

如果你有修复我现在使用的代码的建议,你碰巧有一整个片段来完成整个事情,这将非常感激。

答案

我遇到了类似的情况,我想导出用户输入的数据,以生成包含该信息的pdf报告。

经过几天的研究,我发现截图UITableView不是一个好习惯。

我建议使用CoreText来绘制它自己的。以下是执行绘图的辅助方法。

+(void)drawText:(NSString*)textToDraw withFont:(UIFont *)font inFrame:(CGRect)frameRect
{
    if (textToDraw) {
        //    create attributed string
        CFMutableAttributedStringRef attrStr = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
        CFAttributedStringReplaceString (attrStr, CFRangeMake(0, 0), (CFStringRef) textToDraw);

        //    create font
        if (!font) {
            font = [UIFont fontWithName:@"TimesNewRomanPSMT" size:12];
        }
        CFStringRef fontString = (__bridge CFStringRef)font.fontName;

        CTFontRef fontRef = CTFontCreateWithName(fontString, font.pointSize, NULL);

        //    create paragraph style and assign text alignment to it
        CTTextAlignment alignment = kCTTextAlignmentLeft;
        CTParagraphStyleSetting _settings[] = {    {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment} };
        CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(_settings, sizeof(_settings) / sizeof(_settings[0]));

        //    set paragraph style attribute
        CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, CFAttributedStringGetLength(attrStr)), kCTParagraphStyleAttributeName, paragraphStyle);

        //    set font attribute
        CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, CFAttributedStringGetLength(attrStr)), kCTFontAttributeName, fontRef);

        //    release paragraph style and font
        CFRelease(paragraphStyle);
        CFRelease(fontRef);

        // Prepare the text using a Core Text Framesetter

        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrStr);


        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, frameRect.origin.y*2);
        CGContextScaleCTM(currentContext, 1.0, -1.0);

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

        CGContextScaleCTM(currentContext, 1.0, -1.0);
        CGContextTranslateCTM(currentContext, 0, (-1)*frameRect.origin.y*2);



    }
}

+(void)drawLineFromPoint:(CGPoint)from toPoint:(CGPoint)to
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(context, 1.0);

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();



    CGColorRef color = [UIColor colorWithWhite:0.0 alpha:1.0].CGColor;

    CGContextSetStrokeColorWithColor(context, color);


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

    CGContextStrokePath(context);
    CGColorSpaceRelease(colorspace);


}

+(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];


    }
}

所以你的代码将是这样的:

// Draw first page
CGRect pageFrame = CGRectMake(0, 0, 612.0, 792.0);
UIGraphicsBeginPDFPageWithInfo(pageFrame, nil);
CGContextScaleCTM(UIGraphicsGetCurrentContext(),pageFrame.size.width/screenSize.width, pageFrame.size.height/screenSize.height);
[self doTheDrawing];
UIGraphicsEndPDFContext();

以上是关于将UITableView导出为PDF的主要内容,如果未能解决你的问题,请参考以下文章

R:如何将绘图/图形导出为 png 或 pdf 文件

将 OpenOffice Calc 文件导出为 PDF 时如何处理打印区域?

将 Acrobat JavaScript 代码添加到 pdf 导出

以特定顺序将多个页面导出为 PDF

将访问报告导出为 PDF

phpexcel将选定的工作表导出为pdf