使用Objective-C创建多页PDF

7
我正在尝试创建一个多页的PDF。我遵循了这个教程。这个教程使用XIB文件添加静态文本,接着通过代码添加表格。但是我现在遇到的问题是当表格跨越一页时出现了错误,如果表格有超过9行,则应该继续在下一页上显示。
以下是我的相关代码。
+(void)drawPDF:(NSString*)fileName
{
    NSMutableDictionary *mutDictValues = [[[NSUserDefaults standardUserDefaults] objectForKey:@"dicValues"] mutableCopy];
    NSMutableArray *arrSelectedCities = [[mutDictValues objectForKey:@"cities"]mutableCopy ];

    if(arrSelectedCities.count <= 8){
        // If there are only 8 rows --> we can fit everyting on one page !

        // 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 drawLabels];
        [self drawLogo];

        int xOrigin = 50;
        int yOrigin = 350;

        int rowHeight = 50;
        int columnWidth = 240;

        int numberOfRows = 9;
        int numberOfColumns = 2;

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

        [self drawTableDataAt:CGPointMake(xOrigin, yOrigin) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows andColumnCount:numberOfColumns withArray:arrSelectedCities];

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

    }else{
        // When we have more then 8 rows we should have 2 pages.
        NSLog(@"Create 2 pages");
        // 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 drawLabels];
        [self drawLogo];

        int xOrigin = 50;
        int yOrigin = 350;

        int rowHeight = 50;
        int columnWidth = 240;

        int numberOfRows = 9;
        int numberOfColumns = 2;

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

        [self drawTableDataAt:CGPointMake(xOrigin, yOrigin) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows andColumnCount:numberOfColumns withArray:arrSelectedCities];


        // 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);


        int xOrigin2 = 50;
        int yOrigin2 = 60;
        int numberOfRows2 = ((arrSelectedCities.count+1)-9);

        [self drawTableAt:CGPointMake(xOrigin2, yOrigin2) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows2 andColumnCount:numberOfColumns];

        [self drawTableDataAt:CGPointMake(xOrigin2, yOrigin2) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows2 andColumnCount:numberOfColumns withArray:arrSelectedCities];


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

让我解释一下我的做法。我有一个数组,应该填充我的表格视图。如果数组大于8,则应使用2页。否则,一切都可以在一页上完成。
这样做的结果是,只创建了第二页...
有人能帮帮我吗?

它可以帮助 - https://dev59.com/m1MH5IYBdhLWcg3wvyA4 - Pratik Sodha
4个回答

17
当创建第二页时,不应再调用UIGraphicsBeginPDFContextToFile(),只需要调用UIGraphicsBeginPDFPageWithInfo()
UIGraphicsBeginPDFContextToFile(...); 
UIGraphicsBeginPDFPageWithInfo(...); // start first page
// ...
UIGraphicsBeginPDFPageWithInfo(...); // start second page
// ...
UIGraphicsEndPDFContext();

有一些更改后,这个程序非常完美地生成了多页PDF。谢谢你,伙计 :) - Usman Javed

1
NSArray *imageArray = [NSArray arrayWithObjects:[UIImage imageNamed:@"3.png"], [UIImage imageNamed:@"4.png"], [UIImage imageNamed:@"5.png"], [UIImage imageNamed:@"3.png"], nil];



NSMutableData *pdfFile = [[NSMutableData alloc] init];
double pageWidth = 0.0;
double pageHeight = 0.0;
UIImage *image;
for (int i = 0; i < [imageArray count]; i++)
{
    image =[UIImage imageWithCGImage:[imageArray[i] CGImage]];
    pageWidth = pageWidth + image.size.width ;
    pageHeight = pageHeight + image.size.height;
}
image =[UIImage imageWithCGImage:[imageArray[0] CGImage]];
CGRect rect;
rect = CGRectMake(0, 0,image.size.width ,image.size.height);
UIGraphicsBeginPDFContextToData(pdfFile, CGRectZero, nil);
for (int i = 0; i < [imageArray count] ; i++)
{
    UIGraphicsBeginPDFPageWithInfo(rect, nil);
    UIImage *contextImage = imageArray[i];
    [contextImage drawInRect:rect];
}
UIGraphicsEndPDFContext();

// save PDF file
NSString *saveFileName = [NSString stringWithFormat:@"%@%fx%f.pdf", @"test", pageWidth, pageHeight];

NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* savePath = [documentDirectory stringByAppendingPathComponent:saveFileName];

if([[NSFileManager defaultManager] fileExistsAtPath:savePath])
{
    [[NSFileManager defaultManager] removeItemAtPath:savePath error:nil];
}
[pdfFile writeToFile: savePath atomically: YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"PDF File created and saved successfully." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];

1
虽然这可能是对问题的一个好答案,但请解释一下为什么它能解决问题。 - Glorfindel

0

在第二页(UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil))中,您不需要创建上下文,只需创建此页面即可。 您还应该记住使用CGPDFContextEndPage()关闭已打开的页面。


你如何创建第二个页面呢? - Steaphann
@Tomasz:UIGraphicsBeginPDFPageWithInfo()和UIGraphicsEndPDFContext()都会关闭当前页面。据我所知,CGPDFContextEndPage()是CGPDFContextBeginPage()的对应函数,但在此处未被使用。 - Martin R

0
- (void)viewDidLoad {
[super viewDidLoad];
[self createPDF];
}

- (void)createPDF {
[self setupPDFDocumentNamed:@"myPdf" Width:850 Height:1100];
[self beginPDFPage];
    }

    - (void)beginPDFPage {
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);

// kPadding will make 20 points margin on both sides of pdf
CGRect textRect = [self addText:@"Line Text Testing" withFrame:CGRectMake(PdfPadding, PdfPadding, 400, 200) fontSize:48.0f];

textRect = [self addLineWithFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height +PdfPadding, pageSize.width - PdfPadding*2, 4) withColor:[UIColor blueColor]];

UIImage *anImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://www.phantompeer.com/sitefiles/osx.png"]]];
textRect = [self addImage:anImage atPoint:CGPointMake((pageSize.width/2)-(anImage.size.width/2),textRect.origin.y + textRect.size.height + PdfPadding)];
textRect = [self addLineWithFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height + PdfPadding, pageSize.width - PdfPadding*2, 4) withColor:[UIColor redColor]];

textRect = [self addText:@"Line Text Testing" withFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height + PdfPadding, 400, 200) fontSize:48.0f];

textRect = [self addLineWithFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height +PdfPadding, pageSize.width - PdfPadding*2, 4) withColor:[UIColor blueColor]];

anImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://www.w3schools.com/css/img_fjords.jpg"]]];
    textRect = [self addImage:anImage atPoint:CGPointMake((pageSize.width/2)-(anImage.size.width/2),textRect.origin.y + textRect.size.height + PdfPadding)];

textRect = [self addLineWithFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height + PdfPadding, pageSize.width - PdfPadding*2, 4) withColor:[UIColor redColor]];


UIGraphicsEndPDFContext();
[self loadRemotePdf];
    }
-(CGRect)addText:(NSString*)text withFrame:(CGRect)frame fontSize:(float)fontSize {



UIFont *font = [UIFont systemFontOfSize:fontSize];
CGSize stringSize = [text sizeWithFont:font constrainedToSize:CGSizeMake(pageSize.width - 2*20-2*20, pageSize.height - 2*20 - 2*20) lineBreakMode:UILineBreakModeWordWrap];



if((frame.origin.y + stringSize.height + PdfPadding) > pageSize.height) {
    frame = CGRectMake(frame.origin.x, PdfPadding, frame.size.width, frame.size.height);
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
}

float textWidth = frame.size.width;

if (textWidth < stringSize.width)
    textWidth = stringSize.width;
if (textWidth > pageSize.width)
    textWidth = pageSize.width - frame.origin.x;


CGRect renderingRect = CGRectMake(frame.origin.x, frame.origin.y, textWidth, stringSize.height);

[text drawInRect:renderingRect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentLeft];

frame = CGRectMake(frame.origin.x, frame.origin.y, textWidth, stringSize.height);

return frame;
}

-(CGRect)addLineWithFrame:(CGRect)frame withColor:(UIColor*)color {


if((frame.origin.y + frame.size.height+PdfPadding) > pageSize.height) {
    frame = CGRectMake(frame.origin.x, PdfPadding, frame.size.width, frame.size.height);
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
}

CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(currentContext, color.CGColor);

// this is the thickness of the line
CGContextSetLineWidth(currentContext, frame.size.height);
CGPoint startPoint = frame.origin;
CGPoint endPoint = CGPointMake(frame.origin.x + frame.size.width, frame.origin.y);

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

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



return frame;
        }


-(CGRect)addImage:(UIImage*)image atPoint:(CGPoint)point {
CGRect imageFrame = CGRectMake(point.x, point.y, image.size.width, image.size.height);

if((imageFrame.origin.y + imageFrame.size.height + PdfPadding) > pageSize.height) {
    imageFrame = CGRectMake(imageFrame.origin.x, PdfPadding, imageFrame.size.width, imageFrame.size.height);
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
}
[image drawInRect:imageFrame];
return imageFrame;
}

- (void) loadRemotePdf
{
CGRect rect = [[UIScreen mainScreen] bounds];
CGSize screenSize = rect.size;


NSString *newPDFName = [NSString stringWithFormat:@"myPdf.pdf"];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:newPDFName];

UIWebView *myWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,screenSize.width,screenSize.height)];
myWebView.autoresizesSubviews = YES;
myWebView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);

NSURL *myUrl = [NSURL fileURLWithPath:pdfPath];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myUrl];

[myWebView loadRequest:myRequest];

[self.view addSubview: myWebView];
}

要在PDF中创建新页面,请使用

UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接