使用 Swift 生成 PDF 报告:PDFKit 和 UIPrintPageRenderer

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

使用 PDFKit 在 Swift (iOS/macOS) 中生成 PDF 报告



创建 PDF 文档是移动和桌面应用程序中的常见任务之一。在 Apple 平台(iOS、macOS、watchOS、tvOS)上,使用内置框架 PDFKit 来实现。它允许以编程方式生成、显示和编辑 PDF 文件。在本文中,我们将介绍如何使用 Swift 创建完整的 PDF 报告:包含文本、表格、图像和可自定义的页面。



什么是 PDFKit?

PDFKit 是 Apple 的一个框架,包含在标准 iOS/macOS SDK 中。它提供了用于处理 PDF 的类:

  • PDFDocument — 整个文档的表示。
  • PDFPage — 单个页面。
  • PDFView — 在屏幕上显示 PDF。
  • UIPrintPageRenderer(用于 iOS)— 通过 Core Graphics 绘制生成页面。

生成报告时,最常使用 UIPrintPageRenderer 或直接在 PDF 上下文中通过 Core Graphics 绘制。第二种方法提供了更大的灵活性,但需要更多代码。



项目准备

打开 Xcode,为 iOS 或 macOS 创建一个新项目。确保已导入 PDFKit 模块:

import PDFKitimport UIKit // 用于 iOS


对于 macOS,需要 import Cocoa 以及相应的 NSView 操作。



方法 1:通过 UIPrintPageRenderer 生成 PDF(iOS)

如果您想使用 HTML 标记或复杂布局,这种方法很方便。UIPrintPageRenderer 允许通过 UIPrintFormatter 渲染页面。



func generatePDFUsingRenderer() -> Data? {    let renderer = UIPrintPageRenderer()        // 设置 A4 页面大小    let pageSize = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // 以点为单位    renderer.setValue(pageSize, forKey: "paperRect")    renderer.setValue(pageSize, forKey: "printableRect")        // 创建包含报告的 HTML 字符串    let htmlString = """    <h1>销售报告</h1>    <p>日期:2025-03-17</p>    <table border="1">        <tr><th>商品</th><th>数量</th><th>价格</th></tr>        <tr><td>笔记本电脑</td><td>5</td><td>50000</td></tr>        <tr><td>鼠标</td><td>20</td><td>1500</td></tr>    </table>    """        let formatter = UIMarkupTextPrintFormatter(markupText: htmlString)    renderer.addPrintFormatter(formatter, startingAtPageAt: 0)        // 渲染为 PDF    let pdfData = NSMutableData()    UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)        for pageIndex in 0..<renderer.numberOfPages {        UIGraphicsBeginPDFPage()        renderer.drawPage(at: pageIndex, in: UIGraphicsGetCurrentContext()!)    }        UIGraphicsEndPDFContext()    return pdfData as Data}


调用函数并保存结果:

if let pdfData = generatePDFUsingRenderer() {    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)    let fileURL = paths[0].appendingPathComponent("report.pdf")    try? pdfData.write(to: fileURL)    print("PDF 已保存:\\(fileURL)")}


方法 2:通过 Core Graphics 绘制(iOS/macOS)

这种方法更底层,但可以完全控制每个元素。适用于 macOS,因为 UIPrintPageRenderer 不可用。



func generatePDFWithCoreGraphics() -> Data? {    let pdfData = NSMutableData()    let pageRect = CGRect(x: 0, y: 0, width: 612, height: 792) // US Letter        guard let consumer = CGDataConsumer(data: pdfData),          let pdfContext = CGContext(consumer: consu                    

推荐