关于|关于 iOS 输出 PDF 文档

关于 iOS 输出 PDF 文档
iOS 开发中难免会遇到生成文件的需求,生成文件还是很简单的,直接将字符串写入文件不就好了吗? 但是又难免会遇到刁钻的用户,不禁要生成文件,还要生成好看的文件。这样的需求说实话,有点过分了,但是项目经理却同意了这样无理的要求,来压榨我们这些开发人员,非要给生成个带各种样式的文件。
既然要生成文件,那首先便是想要生成什么格式的文件了,最简单的txt,集简单、粗暴、好用等优点于一身,可惜不带样式。 Word ? word格式太复杂了,又没有能用的第三方库,考虑了半天决定还是用 PDF.
先看下这个刁钻的需求:
关于|关于 iOS 输出 PDF 文档
文章图片
这样的一个东西,输出成 PDF 真的是报了警了,网上找了一堆资料,大多都是自己画简直就是开玩笑吧,这个东西要画出来直接爆炸,终于在上看到了一篇文章,大概思路将数据先转成网页再由网页转成 PDF 觉得此思路可行,终于能用现成的了,进去一看,是 swift 的,网上搜了半天居然没有个 OC 的,只好自己弄了。
想必对于直接在 PDF 上画,这种先转网页的方式还是要舒服很多的。首先你需要一个网页模版,并且把格式都设置好。将需要填写字段的位置都用标示字符串替换掉,这样大概可以得到一个这样的模版,并将它丢到工程目录中:
关于|关于 iOS 输出 PDF 文档
文章图片
再看下数据段的模版:

#TIME# #DEVICE# #TEMP# #SHIDU#

关于html的模版,还是有点坑的,特别是 table 的边线问题。table 有边框 tb 也有边框,从好友那里搞了个 CSS. 拉进来才解决。
有了模版,首先要从文件中得到模版内容:
NSString *resourcePath = [[NSBundle mainBundle] resourcePath]; NSString *filePath =[resourcePath stringByAppendingPathComponent:@"PDFtemplet.html"]; NSString *HTMLContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];

得到内容后,将标记字符替换掉:
temp = [temp stringByReplacingOccurrencesOfString:@"#DEVICE_DESC#" withString:model.stringDevice]; temp = [temp stringByReplacingOccurrencesOfString:@"#START_TIME#" withString:model.stringStartTime]; ... ...

标记全部替换完成后,剩下的就是把这个网页的源码转成 PDF 了,这里会用到 UIPrintPageRenderer 类,自定义一个 CustomPrintPageRenderer 类继承于 UIPrintPageRenderer 并添加初始化函数:
- (instancetype)init { self = [super init]; if (self) {CGRect page; page.origin.x=0; page.origin.y=0; page.size.width=595.2; page.size.height=612; CGRect printable=CGRectInset(page, 40, 60 ); [self setValue:[NSValue valueWithCGRect:page] forKey:@"paperRect"]; [self setValue:[NSValue valueWithCGRect:printable] forKey:@"printableRect"]; } return self; }

在这里可以调整页边距什么的。
【关于|关于 iOS 输出 PDF 文档】接下来将 HTML 转成 PDF :
CustomPrintPageRenderer *printPageRenderer = [[CustomPrintPageRenderer alloc] init]; UIMarkupTextPrintFormatter *printFormatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:HTMLContent]; [printPageRenderer addPrintFormatter:printFormatter startingAtPageAtIndex:0]; NSMutableData *PDFData = https://www.it610.com/article/[NSMutableData data]; UIGraphicsBeginPDFContextToData(PDFData, CGRectZero, nil ); for (NSInteger i=0; i < [printPageRenderer numberOfPages]; i++) {UIGraphicsBeginPDFPage(); CGRect bounds = UIGraphicsGetPDFContextBounds(); [printPageRenderer drawPageAtIndex:i inRect:bounds]; }UIGraphicsEndPDFContext(); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString * pdfFile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"info.pdf"]]; [PDFData writeToFile:pdfFile atomically:YES]; [SVProgressHUD showSuccessWithStatus:@"生成文件成功"];

文件生成成功,看看转成的 PDF 效果:
关于|关于 iOS 输出 PDF 文档
文章图片
没毛病!这样的话不管生成什么样子的 PDF 都把它先转成网页,让前端把模版做好,数据填上去,要多炫酷有多炫酷,要什么样式有什么样式!

    推荐阅读