简体   繁体   English

如何以编程方式在iOS中创建PDF?

[英]How to create a PDF in iOS programmatically?

I want to create a PDF file in iOS ,there should be one table in the PDF, which is filled from one array. 我想在iOS中创建一个PDF文件,PDF中应该有一个表,它从一个数组中填充。 I already searched on Google, but didn't succeed. 我已经在Google上搜索过,但没有成功。 Any help is appreciated 任何帮助表示赞赏

Something like this routine to render the text: 像这个例程来渲染文本:

- (CFRange)renderTextRange:(CFRange)currentRange andFrameSetter:(CTFramesetterRef)frameSetter intoRect:(CGRect)frameRect {
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, frameRect);
CTFrameRef frameRef = CTFramesetterCreateFrame(frameSetter, currentRange, framePath, NULL);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);  
CGContextTranslateCTM(currentContext, 0, 792); 
CGContextScaleCTM(currentContext, 1.0, -1.0);
CTFrameDraw(frameRef, currentContext);
CGContextRestoreGState(currentContext);
CGPathRelease(framePath);
currentRange = CTFrameGetVisibleStringRange(frameRef);
currentRange.location += currentRange.length;
currentRange.length = 0;
CFRelease(frameRef);
return currentRange;
}

And the following code snippet which calls it, assuming you have the context and any fonts etc created and in the appropriate variables. 以下代码片段调用它,假设您已创建上下文和任何字体等,并在适当的变量中。 The following loop simply builds up the text line by line into an NSMutableAttributedString which you can then render: 以下循环只是将文本逐行构建到NSMutableAttributedString ,然后可以呈现:

CTFontRef splainFont = CTFontCreateWithName(CFSTR("Helvetica"), 10.0f, NULL);
CGFloat margin = 32.0f;
CGFloat sink = 8.0f;

NSMutableAttributedString *mainAttributedString = [[NSMutableAttributedString alloc] init];
NSMutableString *mainString = [[NSMutableString alloc] init];

// Ingredients is an NSArray of NSDictionaries
// But yours could be anything, or just an array of text.
for (Ingredient *ingredient in ingredients) {
    NSString *ingredientText = [NSString stringWithFormat:@"%@\t%@
        \n",ingredient.amount,ingredient.name];
    [mainString appendString:ingredientText];
    NSMutableAttributedString *ingredientAttributedText =
        [[NSMutableAttributedString alloc] initWithString:ingredientText];
    [ingredientAttributedText addAttribute:(NSString *)(kCTFontAttributeName)
        value:(id)splainFont
        range:NSMakeRange(0, [ingredientText length])];
    [mainAttributedString appendAttributedString:ingredientAttributedText];
    [ingredientAttributedText release];
}

Now you have your array written out with newlines to one NSMutableAttributedString you can render it, depending on your text you might want to render it out in a loop until the rendered location matches your text length. 现在,您可以使用换行符将您的数组写入一个NSMutableAttributedString您可以根据文本将其渲染出来,直到呈现的位置与文本长度匹配为止。 Something like: 就像是:

// Render Main text.
CTFramesetterRef mainSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)mainAttributedString);
currentRange = [KookaDIS renderTextRange:currentRange 
    andFrameSetter:mainSetter 
    intoRect:pageRect];

// If not finished create new page and loop until we are.
while (!done) {
    UIGraphicsBeginPDFPageWithInfo(pageRect, nil);

    currentRange = [self renderTextRange:currentRange 
        andFrameSetter:mainSetter 
        intoRect:pageRect];

    if (currentRange.location >= [mainString length]) {
        done = TRUE;
    }
}

The above code will need quite a bit of adapting I'm sure as it's hacked out of a project of my own so some variables (like the frame setter) won't exist and you need to close off the PDF context and release variables etc. Note how mainString is used to determine when the text has been rendered out. 上面的代码需要相当多的调整我确定,因为它被我自己的项目破解,所以一些变量(如框架设置器)将不存在,你需要关闭PDF上下文和释放变量等请注意mainString如何用于确定文本何时被渲染出来。

It should give a clear enough indication of how to loop around an array or any other group to render an arbitrary length of text into a document. 它应该清楚地表明如何循环数组或任何其他组以将任意长度的文本呈现到文档中。

Slight modifications to the while loop and the one render before entering it will let you render text out in multiple columns too. 稍微修改while循环和输入之前的渲染将允许您在多个列中渲染文本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM