关于|关于 iOS 输出 PDF 文档
关于 iOS 输出 PDF 文档
iOS 开发中难免会遇到生成文件的需求,生成文件还是很简单的,直接将字符串写入文件不就好了吗? 但是又难免会遇到刁钻的用户,不禁要生成文件,还要生成好看的文件。这样的需求说实话,有点过分了,但是项目经理却同意了这样无理的要求,来压榨我们这些开发人员,非要给生成个带各种样式的文件。
既然要生成文件,那首先便是想要生成什么格式的文件了,最简单的txt,集简单、粗暴、好用等优点于一身,可惜不带样式。 Word ? word格式太复杂了,又没有能用的第三方库,考虑了半天决定还是用 PDF.
先看下这个刁钻的需求:
文章图片
这样的一个东西,输出成 PDF 真的是报了警了,网上找了一堆资料,大多都是自己画简直就是开玩笑吧,这个东西要画出来直接爆炸,终于在上看到了一篇文章,大概思路将数据先转成网页再由网页转成 PDF 觉得此思路可行,终于能用现成的了,进去一看,是 swift 的,网上搜了半天居然没有个 OC 的,只好自己弄了。
想必对于直接在 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 效果:
文章图片
没毛病!这样的话不管生成什么样子的 PDF 都把它先转成网页,让前端把模版做好,数据填上去,要多炫酷有多炫酷,要什么样式有什么样式!
推荐阅读
- iOS常用第三方集合(四)
- iOS|iOS 13 重大 Bug ,你凉了吗()
- Java 并发编程解析 | 关于线程机制的那些事,你究竟了解多少()
- 消息中间件解析 | 如何正确理解软件应用系统中关于系统通信的那些事()
- (转)iOS应用架构谈(一)(架构设计的方法论)
- 十万字与一万天
- std::cout 输出 unsigned char类型数据
- 面试准备系列之计算机网络
- iOS开发自定义页脚和页眉技巧详解
- iOS开发底层探索界面优化示例详解