Skip to content
Demo示例FAQ

PDF 生成模板编辑器

开源可视化 PDF 生成引擎,支持自定义模板,并提供面向开发者的 API,灵活构建文档生成流程。

查看 GitHub

PDF 标准验证 ​

通过 CPDFDocument 的 validateStandardPDFWithType:basePath:,可以按指定标准对已打开的文档执行基础规则检查,并返回 CPDFStandardValidationResult。验证针对的是内存中已打开的文档,如需验证转换结果,请先打开转换输出的文件再进行验证。

支持的验证目标

标准formattypenumpartType状态
PDF/A-1a、1bCPDFStandardFormatPDFA1CPDFPartTypePDF_a、CPDFPartTypePDF_b正式
PDF/A-2a、2u、2b、PDF/A-3a、3u、3bCPDFStandardFormatPDFA2、3CPDFPartTypePDF_a、CPDFPartTypePDF_u、CPDFPartTypePDF_b正式
PDF/E-1、E-2CPDFStandardFormatPDFE1、2CPDFPartTypeNone正式
PDF/X-1a、X-3、X-4CPDFStandardFormatPDFX1、3、4CPDFPartTypeNone实验性
PDF/UACPDFStandardFormatPDFUA忽略CPDFPartTypeNone实验性
PDF/VTCPDFStandardFormatPDFVT忽略(按文档声明的 VT 级别检查)CPDFPartTypeNone实验性

basePath 是用于解析外部引用文件的目录,仅在验证 PDF/X 时使用,可以传 nil。

出现以下情况时,该方法返回 nil:

  • 文档未加载。
  • 目标标准不在上表支持范围内。
  • 许可证不包含 PDF/A 转换权限。

验证结果

CPDFStandardValidationResult 的属性:

属性类型说明
passedBOOL文档是否符合所验证的标准。
detectedTypeCPDFStandardMode文档声明的标准级别;验证 PDF/E、PDF/UA、PDF/VT 时为 nil。
issuesNSArray<CPDFStandardValidationIssue *>检查出的问题列表。

CPDFStandardValidationIssue 的属性:

属性类型说明
codeNSInteger核心库给出的问题编号。
ruleIdNSString违反的规则标识,例如标准中的条款,可能为空。
messageNSString问题描述。
pageIndexNSInteger问题所在页面的索引;为 -1 时表示文档级问题。
standardNameNSString规则所属的标准名称,可能为空。
severityCPDFStandardValidationSeverity问题的严重程度。

CPDFStandardValidationSeverity 的取值:

取值说明
CPDFStandardValidationSeverityError错误,导致文档不符合标准。
CPDFStandardValidationSeverityWarning警告。
CPDFStandardValidationSeverityInfo信息性提示。

“已转换”与“已通过验证”

转换方法返回成功,只表示已生成目标标准的文档(已转换);文档是否符合标准规则,需要再调用验证方法确认(passed 为 YES 表示已通过基础验证)。这是两个不同的状态,建议在界面中分别展示。

以下是将文档转换为 PDF/A-2b 后,验证转换结果并输出问题列表的示例代码:

swift
let document = CPDFDocument(url: URL(fileURLWithPath: pdfPath))

let pdfA2b = CPDFStandardMode()
pdfA2b.format = .PDFA
pdfA2b.typenum = 2
pdfA2b.partType = .pdf_b

do {
    // 1. 转换为 PDF/A-2b
    try document?.writeStandardPDF(toFilePath: savePath, withType: pdfA2b, iccFilePath: nil, with: nil, isSaveFontSubset: false, error: ())
} catch {
    print("Conversion failed: \((error as NSError).localizedFailureReason ?? "")")
    return
}

// 2. 打开转换结果并按 PDF/A-2b 验证
let convertedDocument = CPDFDocument(url: URL(fileURLWithPath: savePath))
guard let result = convertedDocument?.validateStandardPDF(withType: pdfA2b, basePath: nil) else {
    // 文档未加载、目标标准不支持或许可证不包含 PDF/A 转换权限
    return
}

print("Passed: \(result.passed)")
for issue in result.issues {
    let level: String
    switch issue.severity {
    case .error:
        level = "Error"
    case .warning:
        level = "Warning"
    default:
        level = "Info"
    }
    // pageIndex 为 -1 表示文档级问题
    let location = issue.pageIndex == -1 ? "Document" : "Page \(issue.pageIndex + 1)"
    print("[\(level)] \(location) \(issue.ruleId): \(issue.message)")
}
objective-c
CPDFDocument *document = [[CPDFDocument alloc] initWithURL:[NSURL fileURLWithPath:pdfPath]];

CPDFStandardMode *pdfA2b = [[CPDFStandardMode alloc] init];
pdfA2b.format = CPDFStandardFormatPDFA;
pdfA2b.typenum = 2;
pdfA2b.partType = CPDFPartTypePDF_b;

// 1. 转换为 PDF/A-2b
NSError *error = nil;
if (![document writeStandardPDFToFilePath:savePath
                                 withType:pdfA2b
                              iccFilePath:nil
                             withUAConfig:nil
                         isSaveFontSubset:NO
                                    error:&error]) {
    NSLog(@"Conversion failed: %@", error.localizedFailureReason);
    return;
}

// 2. 打开转换结果并按 PDF/A-2b 验证
CPDFDocument *convertedDocument = [[CPDFDocument alloc] initWithURL:[NSURL fileURLWithPath:savePath]];
CPDFStandardValidationResult *result = [convertedDocument validateStandardPDFWithType:pdfA2b basePath:nil];
if (!result) {
    // 文档未加载、目标标准不支持或许可证不包含 PDF/A 转换权限
    return;
}

NSLog(@"Passed: %d", result.passed);
for (CPDFStandardValidationIssue *issue in result.issues) {
    NSString *level = @"Info";
    if (issue.severity == CPDFStandardValidationSeverityError) {
        level = @"Error";
    } else if (issue.severity == CPDFStandardValidationSeverityWarning) {
        level = @"Warning";
    }
    // pageIndex 为 -1 表示文档级问题
    NSString *location = issue.pageIndex == -1 ? @"Document" : [NSString stringWithFormat:@"Page %ld", (long)issue.pageIndex + 1];
    NSLog(@"[%@] %@ %@: %@", level, location, issue.ruleId, issue.message);
}

注: 标准验证为基础规则检查,不等同于第三方专业校验器的完整合规认证。PDF/X、PDF/UA 和 PDF/VT 验证为实验性功能,结果可能不完整。