在 Swift 中为 iOS 和 macOS 使用 PDFKit 和 Core Graphics 生成 PDF 报告

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

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

开始课程

在 Swift 中为 iOS 和 macOS 生成 PDF 报告



创建 PDF 文档是移动和桌面应用程序中的常见任务之一。在 Apple 平台(iOS、macOS)上,有强大的内置工具可供使用:PDFKit 和 Core Graphics。在本文中,我们将探讨如何使用原生 Swift 生成包含表格、文本和图形的多页报告。



为什么要使用内置工具?

  • 无需第三方依赖 — 所有功能都已包含在 SDK 中。
  • 完全控制渲染 — 可处理坐标、字体和颜色。
  • 跨平台 — 代码在 iOS 和 macOS 上均可运行。
  • 高性能 — Core Graphics 利用硬件加速。


主要方法

在 Swift 中生成 PDF 有两种主要方法:

  1. PDFKit — 用于处理 PDF(读取、编辑、创建)的高级 API。
  2. Core Graphics — 通过 PDF 上下文进行低级渲染。

我们将介绍第二种方法,因为它在“从零开始”创建报告时提供了最大的灵活性。



创建 PDF 上下文

第一步是创建一个 PDF 上下文,我们将在其中绘制元素。这需要使用 UIGraphicsBeginPDFContextToFile 函数(iOS)或其 macOS 对应函数。



import UIKit

func generatePDF() -> URL? { let fileName = "Report.pdf" let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) guard let documentsURL = paths.first else { return nil } let pdfURL = documentsURL.appendingPathComponent(fileName) let pageSize = CGRect(x: 0, y: 0, width: 612, height: 792) // A4 UIGraphicsBeginPDFContextToFile(pdfURL.path, pageSize, nil) // 在此处绘制页面 UIGraphicsEndPDFContext() return pdfURL}


添加页面和内容

每个页面都以调用 UIGraphicsBeginPDFPage() 开始。之后,您可以使用标准的 UIKit 方法进行绘制。



func drawReport() {    guard let pdfURL = generatePDF() else { return }        UIGraphicsBeginPDFContextToFile(pdfURL.path, CGRect(x: 0, y: 0, width: 612, height: 792), nil)        // 第一页    UIGraphicsBeginPDFPage()    drawHeader(title: "月度报告")    drawTable(data: sampleData)        // 第二页(如果需要)    UIGraphicsBeginPDFPage()    drawChart()        UIGraphicsEndPDFContext()}


绘制文本和标题

使用带属性的 NSString 来绘制文本。



func drawHeader(title: String) {    let titleAttributes: [NSAttributedString.Key: Any] = [        .font: UIFont.boldSystemFont(ofSize: 24),        .foregroundColor: UIColor.darkGray    ]    title.draw(at: CGPoint(x: 50, y: 40), withAttributes: titleAttributes)}


创建简单表格

可以使用线条和文本绘制表格。以下是一个生成两列表格的示例。



func drawTable(data: [(String, String)]) {    let startX: CGFloat = 50    var startY: CGFloat = 100    let colWidth: CGFloat = 250    let rowHeight: CGFloat = 30        // 绘制标题    let headerAttributes: [NSAttributedString.Key: Any] = [        .font: UIFont.boldSystemFont(ofSize: 14),        .foregroundColor: UIColor.black    ]    "名称".draw(at: CGPoint(x: startX, y: startY), withAttributes: headerAttributes)    "值".draw(at: CGPoint(x: startX + colWidth, y: startY), withAttributes: headerAttributes)        startY += rowHeight        // 绘制行    for (key, value) in data {        let rowAtt                    

推荐