参考了官方文档:《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)
写了个特别简单的示例,效果如下:
完整的代码如下:
-(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 �C 100, pageRect.size.height �C 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。
目前不完美的是有两条:
汉字乱码
有报错
对第一个,据说需要使用其他方法,需要用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问题依旧。
所幸目前写的项目是老外用的,中文不是问题,另外,日志虽然报错,但是能正常生成文档。等有时间再解决这两个问题。