Errors on creating a multipage PDF

后端 未结 4 859
时光取名叫无心
时光取名叫无心 2020-12-09 14:39

Has anyone already created a PDF document in an iPad app? I see that there are new functions in the UIKit to do this, but I can\'t find any code example for it.

<         


        
相关标签:
4条回答
  • 2020-12-09 14:47

    just to let you know that the error message:

    invalid Type1 font: unable to stream font

    and: FT_Load_Glyph failed: error 6.

    disappeared in iOS 4.2

    0 讨论(0)
  • 2020-12-09 15:01

    Here is a method that will create a new PDF document. It does not do text formatting though.

        - (void) createNewPDF: (NSString *) saveFileName withContent: (NSString *) content forSize: (int) fontSize andFont:(NSString *) font andColor: (UIColor *) color
    {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *newFilePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:saveFileName];
    
        CGRect a4Page = CGRectMake(0, 0, 595, 842);
    
        NSDictionary *fileMetaData = [[NSDictionary alloc] init];
    
        if (!UIGraphicsBeginPDFContextToFile(newFilePath, a4Page, fileMetaData )) {
            NSLog(@"error creating PDF context");
            return;
        }
    
        CGContextRef mpdfContext = UIGraphicsGetCurrentContext();
        UIGraphicsBeginPDFPage();
        CGContextSetTextMatrix(mpdfContext, CGAffineTransformMake(1, 0, 0, -1, 0, 0));
        CGContextSetTextDrawingMode (mpdfContext, kCGTextFill);
        CGContextSelectFont (mpdfContext, [font cStringUsingEncoding:NSUTF8StringEncoding], fontSize, kCGEncodingMacRoman);                                                 
        CGContextSetFillColorWithColor(mpdfContext, [color CGColor]);
        CGContextShowTextAtPoint (mpdfContext, 20, 20, [content cStringUsingEncoding:NSUTF8StringEncoding], [content length]);
        UIGraphicsEndPDFContext();
    
    }
    
    0 讨论(0)
  • 2020-12-09 15:02

    This is a better solution as it uses the correct coordinate transform to get the text to print from the top down.

    #define LEFT_MARGIN 25
    #define RIGHT_MARGIN 25
    #define TOP_MARGIN 35
    #define BOTTOM_MARGIN 50
    #define BOTTOM_FOOTER_MARGIN 32
    #define DOC_WIDTH 595
    #define DOC_HEIGHT 842
    
    - (void) createPDF:(NSString *)fileName withContent:(NSString *)content forSize:(int)fontSize andFont:(NSString *)font andColor:(UIColor *)color
    {
    
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *newFilePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:fileName];
    
        CGRect a4Page = CGRectMake(0, 0, DOC_WIDTH, DOC_HEIGHT);
    
        NSDictionary *fileMetaData = [[NSDictionary alloc] init];
    
        if (!UIGraphicsBeginPDFContextToFile(newFilePath, a4Page, fileMetaData )) {
            NSLog(@"error creating PDF context");
            return;
        }
    
        CGContextRef context = UIGraphicsGetCurrentContext();
        UIGraphicsBeginPDFPage();
    
        CGContextSetTextDrawingMode (context, kCGTextFill);
        CGContextSelectFont (context, [font cStringUsingEncoding:NSUTF8StringEncoding], fontSize, kCGEncodingMacRoman);                                                 
        CGContextSetFillColorWithColor(context, [color CGColor]);
    
        CGMutablePathRef path = CGPathCreateMutable();
    
        CGRect bounds = CGRectMake(LEFT_MARGIN, 
                                   TOP_MARGIN, 
                                   DOC_WIDTH - RIGHT_MARGIN - LEFT_MARGIN, 
                                   DOC_HEIGHT - TOP_MARGIN - BOTTOM_MARGIN
                                   );
    
        CGPathAddRect(path, NULL, bounds);
    
        // Initialize an attributed string.
        CFMutableAttributedStringRef attrString =
        CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
        CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), (CFStringRef)content);
    
        // Create the framesetter with the attributed string.
        CTFramesetterRef framesetter =
        CTFramesetterCreateWithAttributedString(attrString);
    
        // Create the frame and draw it into the graphics context
        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
        CFRange visibleRange = CTFrameGetVisibleStringRange(frame);
    
        if (visibleRange.length < [content length] ) {
            NSLog(@"WARNING: Not all displayed on a single page");
        }
    
        CFRelease(attrString);
        CFRelease(framesetter);
    
        if(frame) {
            CGContextSaveGState(context);
            CGContextTranslateCTM(context, 0, bounds.origin.y); 
            CGContextScaleCTM(context, 1, -1); 
            CGContextTranslateCTM(context, 0, -(bounds.origin.y + bounds.size.height)); 
            CTFrameDraw(frame, context);
            CGContextRestoreGState(context); 
            CFRelease(frame);       
        }
    
        UIGraphicsEndPDFContext();
    
        [fileMetaData release];
    }
    
    0 讨论(0)
  • 2020-12-09 15:10

    I actually got multi page PDF creation working by modifying the code above, like:

    - (void) createPDF:(NSString *)fileName withContent:(NSString *)content forSize:(int)fontSize andFont:(NSString *)font andColor:(UIColor *)color {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *newFilePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:fileName];
    
    CGRect a4Page = CGRectMake(0, 0, DOC_WIDTH, DOC_HEIGHT);
    
    NSDictionary *fileMetaData = [[NSDictionary alloc] init];
    
    if (!UIGraphicsBeginPDFContextToFile(newFilePath, a4Page, fileMetaData )) {
        NSLog(@"error creating PDF context");
        return;
    }
    
    BOOL done = NO;
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CFRange currentRange = CFRangeMake(0, 0);
    
    CGContextSetTextDrawingMode (context, kCGTextFill);
    CGContextSelectFont (context, [font cStringUsingEncoding:NSUTF8StringEncoding], fontSize, kCGEncodingMacRoman);                                                 
    CGContextSetFillColorWithColor(context, [color CGColor]);
    // Initialize an attributed string.
    CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
    CFAttributedStringReplaceString (attrString, currentRange, (CFStringRef)content);
    
    // Create the framesetter with the attributed string.
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
    
    do {
        UIGraphicsBeginPDFPage();
    
    
    
        CGMutablePathRef path = CGPathCreateMutable();
    
        CGRect bounds = CGRectMake(LEFT_MARGIN, 
                                   TOP_MARGIN, 
                                   DOC_WIDTH - RIGHT_MARGIN - LEFT_MARGIN, 
                                   DOC_HEIGHT - TOP_MARGIN - BOTTOM_MARGIN);
    
        CGPathAddRect(path, NULL, bounds);
    
    
    
        // Create the frame and draw it into the graphics context
        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, currentRange, path, NULL);
    
        if(frame) {
            CGContextSaveGState(context);
            CGContextTranslateCTM(context, 0, bounds.origin.y); 
            CGContextScaleCTM(context, 1, -1); 
            CGContextTranslateCTM(context, 0, -(bounds.origin.y + bounds.size.height)); 
            CTFrameDraw(frame, context);
            CGContextRestoreGState(context); 
    
            // Update the current range based on what was drawn.
            currentRange = CTFrameGetVisibleStringRange(frame);
            currentRange.location += currentRange.length;
            currentRange.length = 0;
    
            CFRelease(frame);       
        }
    
        // If we're at the end of the text, exit the loop.
        if (currentRange.location == CFAttributedStringGetLength((CFAttributedStringRef)attrString))
            done = YES;
    }
    while(!done);
    
    UIGraphicsEndPDFContext();
    
    [fileMetaData release];
    CFRelease(attrString);
    CFRelease(framesetter);
    }
    

    However, as mentioned above, it ignores the font I try to set. I always get something, looking like "Helvetica".

    So, there is currently no way to create a PDF file on an iPad/iPhone, that embeds the font used on the device? I can hardly believe that. I would have at least hoped for those "usual suspects" fonts , like: Courier, Times New Roman, etc... to be supported.

    If anyone out there has more information or useful tips on workarounds, please feel welcome to share.

    Thanks in advance.

    0 讨论(0)
提交回复
热议问题