You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:40:43