关于 iOS 输出 PDF 文档

作者: Vesincc | 来源:发表于2017-03-07 13:35 被阅读261次

    关于 iOS 输出 PDF 文档

    iOS 开发中难免会遇到生成文件的需求,生成文件还是很简单的,直接将字符串写入文件不就好了吗? 但是又难免会遇到刁钻的用户,不禁要生成文件,还要生成好看的文件。这样的需求说实话,有点过分了,但是项目经理却同意了这样无理的要求,来压榨我们这些开发人员,非要给生成个带各种样式的文件。

    既然要生成文件,那首先便是想要生成什么格式的文件了,最简单的txt,集简单、粗暴、好用等优点于一身,可惜不带样式。 Word ? word格式太复杂了,又没有能用的第三方库,考虑了半天决定还是用 PDF.

    先看下这个刁钻的需求:

    这样的一个东西,输出成 PDF 真的是报了警了,网上找了一堆资料,大多都是自己画简直就是开玩笑吧,这个东西要画出来直接爆炸,终于在简书上看到了一篇文章,大概思路将数据先转成网页再由网页转成 PDF 觉得此思路可行,终于能用现成的了,进去一看,是 swift 的,网上搜了半天居然没有个 OC 的,只好自己弄了。

    想必对于直接在 PDF 上画,这种先转网页的方式还是要舒服很多的。首先你需要一个网页模版,并且把格式都设置好。将需要填写字段的位置都用标示字符串替换掉,这样大概可以得到一个这样的模版,并将它丢到工程目录中:

    再看下数据段的模版:

    <tr>
        <td td colspan="2">#TIME#</td>
        <td td colspan="2">#DEVICE#</td>
        <td>#TEMP#</td>
        <td>#SHIDU#</td>
    </tr>
    

    关于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;
    }
    

    在这里可以调整页边距什么的。

    接下来将 HTML 转成 PDF :

    CustomPrintPageRenderer *printPageRenderer = [[CustomPrintPageRenderer alloc] init];
        
        UIMarkupTextPrintFormatter *printFormatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:HTMLContent];
        
        [printPageRenderer addPrintFormatter:printFormatter startingAtPageAtIndex:0];
        
        NSMutableData *PDFData = [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 输出 PDF 文档

      本文链接:https://www.haomeiwen.com/subject/lydmgttx.html