Как создать PDF в iOS программно? - PullRequest
7 голосов
/ 21 октября 2011

Я хочу создать файл PDF в iOS, должна быть одна таблица в PDF, которая заполнена из одного массива.Я уже искал в Google, но не удалось.Любая помощь приветствуется

1 Ответ

1 голос
/ 27 октября 2011

Что-то вроде этой процедуры для визуализации текста:

- (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;
}

И следующий фрагмент кода, который вызывает его, при условии, что у вас есть контекст, все шрифты и т. Д., Созданные в соответствующих переменных. Следующий цикл просто строит текст построчно в 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];
}

Теперь у вас есть массив, записанный с новыми строками в один NSMutableAttributedString, который вы можете отрендерить, в зависимости от вашего текста вы можете рендерить его в цикле, пока отображаемое местоположение не будет соответствовать длине вашего текста. Что-то вроде:

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

Приведенный выше код потребует некоторой адаптации, я уверен, что он взломан из моего собственного проекта, поэтому некоторые переменные (например, установщик фреймов) не существуют, и вам необходимо закрыть контекст PDF и переменные выпуска и т. д. Обратите внимание, как mainString используется, чтобы определить, когда текст был обработан.

Он должен дать достаточно четкое указание на то, как обвести массив или любую другую группу, чтобы сделать произвольную длину текста в документе.

Небольшие изменения в цикле while и рендеринге перед его вводом позволят вам выводить текст также в несколько столбцов.

...