iOS中NSString转PDF文件失败求助(Objective-C/Xcode9)
解决Objective-C中将字符串保存为PDF的问题
嘿,我明白你现在卡在哪了——你直接把字符串转成NSData就想存成PDF,这可不太行哦!PDF是有专门的文件格式规范的,不是纯文本改个后缀就能搞定的。另外你代码里的路径也可能有问题,咱们一步步来修正:
先排查原代码的核心问题
你的代码没进入if分支,大概率是两个原因:
- 路径错误:你用的
@"documents/"是相对路径,iOS沙盒环境下必须使用绝对路径来访问Documents目录,相对路径会导致找不到目标位置 - 文件格式错误:直接把UTF8编码的字符串存成
.pdf后缀,本质还是纯文本文件,完全不符合PDF的格式规范,就算写入成功也无法被PDF阅读器识别
修改后的正确实现方案
下面给你两种常用的实现方式,选适合你的就行:
方式一:用UIKit直接绘制文本生成PDF
这种方式适合简单的纯文本内容,排版要求不高的场景:
// 1. 获取正确的Documents目录绝对路径 NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *formattedName = [NSString stringWithFormat:@"%@.pdf", name]; NSString *pdfPath = [documentsDir stringByAppendingPathComponent:formattedName]; // 2. 开始创建PDF上下文 UIGraphicsBeginPDFContextToFile(pdfPath, CGRectZero, nil); // 设置PDF页面尺寸为标准A4(72dpi下的尺寸:612x792) UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil); // 3. 设置文本样式(字体、颜色等) NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:14.0], NSForegroundColorAttributeName: [UIColor blackColor] }; // 4. 准备要写入的字符串 NSString *documentString = @"这里替换成你的Web服务获取到的字符串"; // 5. 计算文本需要的绘制区域(自动换行) CGRect textRect = [documentString boundingRectWithSize:CGSizeMake(572, CGFLOAT_MAX) // 左右留20pt边距 options:NSStringDrawingUsesLineFragmentOrigin attributes:textAttributes context:nil]; // 6. 在PDF页面上绘制文本 [documentString drawInRect:CGRectMake(20, 20, textRect.size.width, textRect.size.height) withAttributes:textAttributes]; // 7. 结束PDF上下文,完成文件写入 UIGraphicsEndPDFContext(); NSLog(@"PDF已生成,路径:%@", pdfPath);
方式二:通过HTML转PDF(适合复杂排版)
如果你的字符串包含富文本格式,或者需要更灵活的排版,可以把字符串包装成HTML,再通过WKWebView生成PDF:
// 1. 获取正确的Documents目录绝对路径 NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *formattedName = [NSString stringWithFormat:@"%@.pdf", name]; NSString *pdfPath = [documentsDir stringByAppendingPathComponent:formattedName]; // 2. 把原始字符串包装成HTML(可以添加CSS来控制排版) NSString *htmlString = [NSString stringWithFormat:@"<html><head><style>body { font-size:14px; margin:20px; }</style></head><body>%@</body></html>", documentString]; // 3. 创建WKWebView加载HTML WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 612, 1)]; [webView loadHTMLString:htmlString baseURL:nil]; // 4. 等待网页加载完成后生成PDF [webView evaluateJavaScript:@"document.documentElement.scrollHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) { if (error) { NSLog(@"加载HTML失败:%@", error.localizedDescription); return; } CGFloat pageHeight = [result floatValue]; CGRect pdfRect = CGRectMake(0, 0, 612, pageHeight); // 生成PDF UIGraphicsBeginPDFContextToFile(pdfPath, CGRectZero, nil); UIGraphicsBeginPDFPageWithInfo(pdfRect, nil); [webView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIGraphicsEndPDFContext(); NSLog(@"PDF已生成,路径:%@", pdfPath); }];
额外调试技巧
如果还是遇到问题,可以在原代码里加上错误日志,看看具体失败原因:
NSError *error = nil; if([data writeToFile:pdfPath options:NSDataWritingAtomic error:&error]) { NSLog(@"写入成功"); } else { NSLog(@"写入失败原因:%@", error.localizedDescription); }
比如日志提示“文件不存在”,就是路径问题;提示“权限不足”,则需要检查沙盒权限配置。
内容的提问来源于stack exchange,提问作者Jaime Alcántara Arnela
相关产品推荐
相关产品推荐

