iOS创建PDF文件

参考了官方文档:《PDF Document Creation, Viewing, and Transforming》

pdf文档在iOS中是通过Quartz 2D库提供的api来操作的。iOS有两个图形库:

  • Quartz 2D,是iOS原生的,简单易用,缺点是只有2D,仅限于iOS
  • OpenGL ES,是开放标准的,2D和3D均有

使用Quartz 2D绘图到任意图形上下文(graphics context)创建pdf文件是很容易的事情。这需要:

  • 指定pdf文件的位置
  • 设置pdf的图形上下文(graphics context)

写了个特别简单的示例,效果如下:

image

完整的代码如下:

-(void)createPdf{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *saveDirectory = [paths objectAtIndex:0]; 
    NSString *saveFileName = @"myPDF.pdf"; 
    NSString *newFilePath = [saveDirectory stringByAppendingPathComponent:saveFileName]; 
    const char *filename = [newFilePath UTF8String]; 
    CGRect pageRect=CGRectMake(0, 0, 612, 792); 
    // This code block sets up our PDF Context so that we can draw to it 
    CGContextRef pdfContext; 
    CFStringRef path; 
    CFURLRef url; 
    CFMutableDictionaryRef myDictionary = NULL; 
    // Create a CFString from the filename we provide to this method when we call it 
    path = CFStringCreateWithCString (NULL, filename, 
                                      kCFStringEncodingUTF8); 
    // Create a CFURL using the CFString we just defined 
    url = CFURLCreateWithFileSystemPath (NULL, path, 
                                         kCFURLPOSIXPathStyle, 0); 
    CFRelease (path); 
    // This dictionary contains extra options mostly for ’signing’ the PDF 
    myDictionary = CFDictionaryCreateMutable(NULL, 0, 
                                             &kCFTypeDictionaryKeyCallBacks, 
                                             &kCFTypeDictionaryValueCallBacks); 
    CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("My PDF File")); 
    CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name")); 
    // Create our PDF Context with the CFURL, the CGRect we provide, and the above defined dictionary 
    pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary); 
    // Cleanup our mess 
    CFRelease(myDictionary); 
    CFRelease(url); 
    // Done creating our PDF Context, now it’s time to draw to it 
    // Starts our first page 
    CGContextBeginPage (pdfContext, &pageRect); 
    // Draws a black rectangle around the page inset by 50 on all sides 
    CGContextStrokeRect(pdfContext, CGRectMake(50, 50, pageRect.size.width – 100, pageRect.size.height – 100)); 
    // Adding some text on top of the image we just added 
    CGContextSelectFont (pdfContext, "Helvetica", 30, kCGEncodingMacRoman); 
    CGContextSetTextDrawingMode (pdfContext, kCGTextFill); 
    CGContextSetRGBFillColor (pdfContext, 0, 0, 0, 1); 
    const char *text =  (char *)[@"Hello world" UTF8String]; 
    CGContextShowTextAtPoint (pdfContext, 260, 390, text, strlen(text)); 
    // End text 
    // We are done drawing to this page, let’s end it 
    // We could add as many pages as we wanted using CGContextBeginPage/CGContextEndPage 
    CGContextEndPage (pdfContext); 
    // We are done with our context now, so we release it 
    CGContextRelease (pdfContext); 
}

 

会在当前应用的Documents目录下创建一个myPDF.pdf文件,文件中只有一行字,Hello world。

以下这段:

// This dictionary contains extra options mostly for ’signing’ the PDF 
    myDictionary = CFDictionaryCreateMutable(NULL, 0, 
                                             &kCFTypeDictionaryKeyCallBacks, 
                                             &kCFTypeDictionaryValueCallBacks); 
    CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("My PDF File")); 
    CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name"));

可以不用,是设置pdf文件的一些属性的,比如作者等,那么可以:

pdfContext = CGPDFContextCreateWithURL (url, &pageRect, nil);

写入pdf是从CGContextBeginPage 函数开始,到CGContextEndPage函数截至。然后需要释放context:CGContextRelease。

目前不完美的是有两条:

  1. 汉字乱码
  2. 有报错

对第一个,据说需要使用其他方法,需要用NSString,可以参考这个帖子:

http://www.cocoachina.com/bbs/read.php?tid-2111.html

有报错,如这样:

Thu Oct 14 13:28:43 Henzil-mato-iPad pdfDemo[2200] <Error>: FT_Load_Glyph failed: error 6.

大量的这样的error,虽然我只是写了一行文本。引发错误的是:

CGContextShowTextAtPoint (pdfContext, 260, 390, text, strlen(text));

屏蔽这行就不抱错了。

搜到这个帖子:

http://discussions.apple.com/thread.jspa?messageID=7820664

但是将字体调大也无法解决问题,我调大30问题依旧。

所幸目前写的项目是老外用的,中文不是问题,另外,日志虽然报错,但是能正常生成文档。等有时间再解决这两个问题。

你可能感兴趣的:(iOS创建PDF文件)