PDF генерация в Swift (iOS/macOS): от простого к сложному
Создание PDF-документов — одна из частых задач в мобильной и десктопной разработке. На платформах Apple (iOS/macOS) встроенные инструменты позволяют генерировать качественные PDF без сторонних библиотек. В этой статье мы разберём три основных подхода: UIGraphicsPDFRenderer (современный и простой), PDFKit (для работы с существующими PDF) и Core Graphics (для полного контроля). Все примеры написаны на Swift и подходят как для iOS, так и для macOS (с минимальными изменениями).
1. UIGraphicsPDFRenderer — современный стандарт
UIGraphicsPDFRenderer появился в iOS 10 и macOS 10.12. Он предоставляет высокоуровневый API для создания многостраничных PDF. Основные преимущества: автоматическая работа с контекстом, поддержка метаданных и простота использования.
Базовый пример: создание PDF с текстом
import UIKit
func generateSimplePDF() -> Data? {
let pageWidth: CGFloat = 612 // A4
let pageHeight: CGFloat = 792
let renderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight))
let data = renderer.pdfData { context in
// Первая страница
context.beginPage()
let text = "Привет, мир PDF!"
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 24),
.foregroundColor: UIColor.black
]
text.draw(at: CGPoint(x: 50, y: 50), withAttributes: attributes)
// Вторая страница
context.beginPage()
let secondText = "Это вторая страница"
secondText.draw(at: CGPoint(x: 50, y: 50), withAttributes: attributes)
}
return data
}
// Сохранение в файл
if let pdfData = generateSimplePDF() {
let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let pdfURL = documentsPath.appendingPathComponent("sample.pdf")
try? pdfData.write(to: pdfURL)
print("PDF сохранён: \(pdfURL)")
}
Продвинутый пример: таблица и изображение
func generateInvoicePDF() -> Data {
let renderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 612, height: 792))
return renderer.pdfData { context in
context.beginPage()
// Рисуем логотип (если есть)
if let logo = UIImage(named: "logo") {
logo.draw(in: CGRect(x: 50, y: 50, width: 100, height: 50))
}
// Заголовок
let titleAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.boldSystemFont(ofSize: 28),
.foregroundColor: UIColor.darkGray
]
"СЧЁТ №123".draw(at: CGPoint(x: 400, y: 50), withAttributes: titleAttributes)
// Таблица
let items = [("Товар", "Цена"), ("Ноутбук", "1200$"), ("Мышь", "25$")]
var yPosition: CGFloat = 200
for (name, price) in items {
let nameAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 14),
.foregroundColor: UIColor.black
]
name.draw(at: CGPoint(x: 100, y: yPosition), withAttributes: nameAttributes)
price.draw(at: CGPoint(x: 400, y: yPosition), withAttributes: nameAttributes)
yPosition += 30
}
// Итого
let totalAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.boldSystemFont(ofSize: 18),
.foregroundColor: UIColor.red
]
"Итого: 1225$".draw(at: CGPoint(x: 350, y: yPosition + 20), withAttributes: totalAttributes)
}
}
2. PDFKit — работа с существующими PDF и аннотации
PDFKit — это более мощный фреймворк, который позволяет не только создавать, но и редактировать PDF, добавлять аннотации, формы и просматривать документы. Он доступен на iOS 11+ и macOS 10.13+.
Пример: объединение двух PDF
import PDFKit
func mergePDFs(urls: [URL]) -> PDFDocument? {
let mergedDocument = PDFDocument()
for url in urls {
guard let document = PDFDocument(url: url) else { continue }
for pageIndex in 0..<document.pageCount {
if let page = document.page(at: pageIndex) {
mergedDocument.insert(page, at: mergedDocument.pageCount)
}
}
}
return mergedDocument
}
// Использование
let pdf1 = Bundle.main.url(forResource: "doc1", withExtension: "pdf")!
let pdf2 = Bundle.main.url(forResource: "doc2", withExtension: "pdf")!
if let merged = mergePDFs(urls: [pdf1, pdf2]) {
let url = FileManager Также в библиотеке
Конфигурация приложений Go (Golang): библиотеки и инструменты
SnapKit для Swift: полное руководство с примерами
Отправка SMS на Go (Golang): интеграция с API библиотеки
Конфигурация приложений C++: библиотеки и инструменты для гибкой настройки
JsonWebToken для JavaScript (Node.js): полное руководство с примерами