{"id":48844219,"url":"https://github.com/swiftly-developed/swiftly-pdfkit","last_synced_at":"2026-04-15T04:02:28.112Z","repository":{"id":339692051,"uuid":"1161306358","full_name":"Swiftly-Developed/Swiftly-PDFKit","owner":"Swiftly-Developed","description":"A convenience PDFKit to create documents.","archived":false,"fork":false,"pushed_at":"2026-02-21T01:01:57.000Z","size":1133,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-21T07:02:58.639Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Swiftly-Developed.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-19T00:41:27.000Z","updated_at":"2026-02-21T01:02:01.000Z","dependencies_parsed_at":"2026-02-21T07:03:09.675Z","dependency_job_id":null,"html_url":"https://github.com/Swiftly-Developed/Swiftly-PDFKit","commit_stats":null,"previous_names":["swiftly-developed/swiftly-pdfkit"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Swiftly-Developed/Swiftly-PDFKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swiftly-Developed%2FSwiftly-PDFKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swiftly-Developed%2FSwiftly-PDFKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swiftly-Developed%2FSwiftly-PDFKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swiftly-Developed%2FSwiftly-PDFKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Swiftly-Developed","download_url":"https://codeload.github.com/Swiftly-Developed/Swiftly-PDFKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swiftly-Developed%2FSwiftly-PDFKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31825515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T18:05:02.291Z","status":"online","status_checked_at":"2026-04-15T02:00:06.175Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-15T04:02:25.562Z","updated_at":"2026-04-15T04:02:28.098Z","avatar_url":"https://github.com/Swiftly-Developed.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SwiftlyPDFKit\n\n[![](https://img.shields.io/badge/Swift-6.0+-F05138?logo=swift\u0026logoColor=white)](https://swift.org)\n[![](https://img.shields.io/badge/Platforms-macOS_12+_|_iOS_15+_|_Linux-blue)](#requirements)\n[![](https://img.shields.io/badge/SPM-compatible-4FC08D)](#installation)\n[![](https://img.shields.io/badge/version-0.2.0-orange)](https://github.com/Swiftly-Developed/Swiftly-PDFKit/releases/tag/v0.2.0)\n[![](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n\nA pure-Swift PDF generation library with a declarative DSL. Build pixel-perfect PDFs using a SwiftUI-inspired syntax — from simple one-page documents to multi-page invoices with automatic pagination.\n\n---\n\n## Features\n\n- **Declarative DSL** \u0026mdash; Result-builder syntax for pages, text, tables, columns, and more\n- **Cross-platform** \u0026mdash; CoreGraphics on Apple platforms, HTML-to-PDF on Linux; no AppKit or UIKit dependency\n- **Invoice engine** \u0026mdash; 5 built-in layouts with automatic multi-page pagination\n- **Business documents** \u0026mdash; Quotes, sales orders, delivery notes, and shipment documents\n- **Themeable** \u0026mdash; 3 built-in themes + fully customizable colors, fonts, and spacing\n- **QR codes** \u0026mdash; SEPA/EPC QR and arbitrary payloads via pure-Swift generation\n- **SwiftUI previews** \u0026mdash; Live Xcode canvas previews with `PDFPreviewView`\n\n---\n\n## Installation\n\nAdd SwiftlyPDFKit to your `Package.swift`:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/Swiftly-Developed/Swiftly-PDFKit.git\", from: \"0.2.0\"),\n]\n```\n\nThen add the target dependency:\n\n```swift\n.target(\n    name: \"YourTarget\",\n    dependencies: [\"SwiftlyPDFKit\"]\n),\n```\n\nFor SwiftUI preview support, also add `SwiftlyPDFKitUI`:\n\n```swift\n.target(\n    name: \"YourTarget\",\n    dependencies: [\"SwiftlyPDFKit\", \"SwiftlyPDFKitUI\"]\n),\n```\n\n---\n\n## Quick start\n\n### Simple PDF with the DSL\n\n```swift\nimport SwiftlyPDFKit\n\nlet pdf = PDF {\n    Page(size: .a4) {\n        Text(\"Hello, world!\")\n            .font(.helvetica, size: 24)\n            .bold()\n\n        Spacer(height: 20)\n\n        Text(\"Generated with SwiftlyPDFKit\")\n            .fontSize(12)\n            .foregroundColor(PDFColor.gray)\n    }\n}\n\nlet data = try pdf.render()\ntry pdf.write(to: URL(fileURLWithPath: \"/tmp/hello.pdf\"))\n```\n\n### Invoice in 3 lines\n\n```swift\nimport SwiftlyPDFKit\n\nlet invoice = InvoiceDocument(\n    header: InvoiceHeader(\n        invoiceNumber: \"INV-2026-001\",\n        issueDate: \"2026-03-01\",\n        dueDate: \"2026-03-15\",\n        currency: \"EUR\"\n    ),\n    supplier: InvoiceSupplier(name: \"Acme Corp\"),\n    client: InvoiceClient(name: \"Client BV\"),\n    lines: [\n        InvoiceLine(description: \"Consulting\", quantity: 8, unit: \"hrs\",\n                    unitPrice: 150, vatRate: 21),\n        InvoiceLine(description: \"Design review\", quantity: 3, unit: \"hrs\",\n                    unitPrice: 120, vatRate: 21, discountPercent: 10),\n    ]\n)\n\nlet pdf = PDF(layout: .classic, invoice: invoice, theme: .standard)\ntry pdf.write(to: URL(fileURLWithPath: \"/tmp/invoice.pdf\"))\n```\n\n---\n\n## Core primitives\n\nSwiftlyPDFKit provides 12 building blocks that compose via result builders:\n\n### PDF \u0026 Page\n\n```swift\n// DSL builder\nlet pdf = PDF {\n    Page(size: .a4, margins: 40) {\n        // ... content ...\n    }\n    Page(size: .letter) {\n        // ... more content ...\n    }\n}\n\n// Render to Data or write to disk\nlet data = try pdf.render()\ntry pdf.write(to: url)\n```\n\n**Page sizes**: `.a4` (595 x 842), `.letter` (612 x 792), `.legal` (612 x 1008), or custom `PageSize(width:height:)`.\n\n### Text\n\n```swift\nText(\"Title\")\n    .font(.times, size: 24)\n    .bold()\n    .italic()\n    .foregroundColor(PDFColor.blue)\n    .alignment(.center)\n```\n\n**Modifier chain**: `.font(_:size:)`, `.bold()`, `.italic()`, `.fontSize(_:)`, `.foregroundColor(_:)`, `.alignment(_:)`\n\n### Table\n\n```swift\nTable(data: rows, style: .default, showHeader: true) {\n    Column(\"Description\", width: .flex)\n    Column(\"Qty\", width: .fixed(60), alignment: .trailing)\n    Column(\"Price\", width: .fixed(80), alignment: .trailing)\n}\n```\n\nColumn widths are `.flex` (fills remaining space proportionally) or `.fixed(points)`. Each column supports independent text alignment and a separate header alignment.\n\n**TableStyle** controls header colors, font sizes, row height, alternating row tint, border width, cell padding, and more.\n\n### Columns (horizontal layout)\n\n```swift\nColumns(spacing: 10) {\n    ColumnItem(width: .flex) {\n        Text(\"Left column\")\n    }\n    ColumnItem(width: .fixed(200)) {\n        Text(\"Right column (200pt)\")\n    }\n}\n```\n\nEach column renders independently with its own cursor. The overall cursor advances by the height of the tallest column.\n\n### Other elements\n\n| Element | Description |\n|---------|-------------|\n| `Spacer(height:)` | Vertical whitespace (default 12pt) |\n| `HRule(thickness:color:)` | Horizontal divider line |\n| `FilledBox(color:height:padding:) { ... }` | Colored background behind nested content |\n| `ImageContent(path:maxWidth:maxHeight:alignment:)` | PNG/JPEG with aspect-ratio preservation |\n| `QRCodeContent(\"payload\", size: 80)` | QR code rendered as a crisp vector image |\n| `Footer(height:) { ... }` | Content pinned to the bottom of every page |\n\n### Colors and fonts\n\n```swift\n// Named colors\nPDFColor.black, .white, .gray, .lightGray, .darkGray, .red, .green, .blue\n\n// Custom colors\nPDFColor(red: 0.2, green: 0.4, blue: 0.8)\nPDFColor(white: 0.9)\n\n// Built-in fonts\nPDFFont.helvetica, .helveticaBold, .helveticaOblique, .helveticaBoldOblique\nPDFFont.times, .timesBold, .timesItalic\nPDFFont.courier, .courierBold\n\n// Custom PostScript font name\nPDFFont(name: \"Menlo-Regular\")\n```\n\n---\n\n## Invoice engine\n\nThe invoice system uses a single data model (`InvoiceDocument`) that feeds into different visual layouts.\n\n### Data model\n\n```\nInvoiceDocument\n +-- header: InvoiceHeader        // number, dates, currency, payment terms, QR, notes\n +-- supplier: InvoiceSupplier    // name, address, VAT, IBAN, logo path\n +-- client: InvoiceClient        // name, address, VAT, PO number\n +-- lines: [InvoiceLine]         // description, qty, unit, price, VAT rate, discount\n +-- totals: InvoiceTotals        // auto-computed from lines, or override manually\n +-- footer: InvoiceFooter?       // text lines pinned to page bottom\n```\n\n`InvoiceTotals` is derived automatically from lines. Override it for edge cases like global discounts or partial payments:\n\n```swift\nlet totals = InvoiceTotals(\n    subtotalExcl: 1200,\n    totalVat: 252,\n    totalIncl: 1452,\n    amountPaid: 500   // deposit already paid\n)\nlet invoice = InvoiceDocument(header: ..., supplier: ..., client: ...,\n                              lines: lines, totals: totals)\n```\n\n### Layouts\n\n| Layout | Description |\n|--------|-------------|\n| `.classic` | Two-column header, metadata grid, line-items table, totals, QR + payment banner |\n| `.classicWithSidebar` | Classic layout with a full-height accent-colored bar on the left edge |\n| `.minimal` | Borderless tables, generous whitespace, plain-text totals |\n| `.stacked` | Full-width title banner, vertically stacked supplier and client blocks |\n| `.summaryFirst` | Page 1 shows totals and payment only; line items start on page 2 |\n\n```swift\nlet pdf = PDF(layout: .minimal, invoice: invoice, theme: .corporate, pageSize: .a4)\n```\n\nAll layouts handle **automatic multi-page pagination**: line items overflow gracefully across pages, and totals/payment sections are guaranteed their own space (bumping to a new page if needed).\n\n### Themes\n\nThree built-in presets:\n\n| Theme | Style |\n|-------|-------|\n| `.standard` | Clean black-and-white with subtle gray accents |\n| `.gold` | Warm gold-tinted accent color |\n| `.corporate` | Bold blue headers with light-blue alternating rows |\n\nCustomize any theme property:\n\n```swift\nvar theme = InvoiceTheme.standard\ntheme.accentColor = PDFColor(red: 0.2, green: 0.6, blue: 0.4)\ntheme.bodyFont = .times\ntheme.logoPosition = .right\ntheme.lineItemRowHeight = 24\n```\n\n**Theme properties**: `accentColor`, `tableHeaderBackground`, `tableHeaderTextColor`, `tableAlternateRowColor`, `ruleColor`, `paymentBannerColor`, `paymentBannerTextColor`, `tableBorderColor`, `bodyFont`, `titleFont`, `bodyFontSize`, `titleFontSize`, `tableHeaderFontSize`, `tableCellFontSize`, `pageMargins`, `logoPosition` (`.left` / `.right` / `.topCenter`), `logoMaxWidth`, `logoMaxHeight`, `lineItemRowHeight`, `totalsRowHeight`.\n\n---\n\n## Business documents\n\nBeyond invoices, SwiftlyPDFKit supports four additional document types. All share the `InvoiceDocument` data model and add a type-specific supplement for extra fields.\n\n### Quotation\n\n```swift\nlet supplement = QuoteSupplement(\n    expiryDate: \"2026-04-01\",\n    acceptanceNote: \"Please sign and return to confirm.\"\n)\nlet pdf = PDF(quoteLayout: .classic, invoice: invoice, supplement: supplement,\n              theme: .standard, pageSize: .a4)\n```\n\nLayouts: `.classic`, `.minimal`\n\n### Sales order\n\n```swift\nlet supplement = SalesOrderSupplement(\n    poConfirmedDate: \"2026-03-01\",\n    requestedDeliveryDate: \"2026-03-15\"\n)\nlet pdf = PDF(salesOrderLayout: .classic, invoice: invoice, supplement: supplement,\n              theme: .corporate, pageSize: .a4)\n```\n\nLayouts: `.classic`, `.stacked`\n\n### Delivery note\n\n```swift\nlet supplement = DeliverySupplement(\n    shipToAddress: \"Warehouse 3\\nIndustrial Park\\n2000 Antwerp\",\n    signatureRequired: true,\n    signatureLabel: \"Received in good order by:\"\n)\nlet pdf = PDF(deliveryLayout: .standard, invoice: invoice, supplement: supplement,\n              theme: .standard, pageSize: .a4)\n```\n\nLayouts: `.standard`\n\n### Shipment document\n\n```swift\nlet supplement = ShipmentSupplement(\n    carrier: \"DHL Express\",\n    trackingNumber: \"JJD000390007843164734\",\n    shipToAddress: \"Warehouse 3\\nIndustrial Park\\n2000 Antwerp\",\n    estimatedDelivery: \"2026-03-18\",\n    signatureRequired: true\n)\nlet pdf = PDF(shipmentLayout: .standard, invoice: invoice, supplement: supplement,\n              theme: .corporate, pageSize: .a4)\n```\n\nLayouts: `.standard`, `.compact`\n\n\u003e **Tip**: Set `header.documentTitle` to customize the title shown on the document (e.g. \"Quotation\", \"Sales Order Confirmation\", \"Delivery Note\", \"Packing Slip\").\n\n---\n\n## SwiftUI previews\n\n`SwiftlyPDFKitUI` provides `PDFPreviewView` for live Xcode canvas previews:\n\n```swift\nimport SwiftUI\nimport SwiftlyPDFKit\nimport SwiftlyPDFKitUI\n\n#Preview(\"Invoice\", traits: .fixedLayout(width: 595, height: 842)) {\n    PDFPreviewView {\n        Page(size: .a4) {\n            Text(\"Preview content\").font(.helvetica, size: 16)\n        }\n    }\n}\n```\n\nOr preview a pre-built PDF:\n\n```swift\nlet pdf = PDF(layout: .classic, invoice: invoice, theme: .standard)\n\n#Preview(\"Classic Invoice\", traits: .fixedLayout(width: 595, height: 842)) {\n    PDFPreviewView(pdf)\n}\n```\n\n---\n\n## Demos\n\nThe project includes 15 demo configurations covering every layout, theme, and document type. Each demo has a SwiftUI `#Preview` for the Xcode canvas and a corresponding CLI generator.\n\n| # | Name | Type | Layout | Theme |\n|---|------|------|--------|-------|\n| 01 | Standard | Invoice | classic | standard |\n| 02 | Gold | Invoice | classic | gold |\n| 03 | Corporate | Invoice | classic | corporate |\n| 04 | Purple | Invoice | classic | custom (Times, logo right) |\n| 05 | Green | Invoice | classic | custom (logo top-center) |\n| 06 | Partial Payment | Invoice | classic | standard |\n| 07 | Mono | Invoice | classic | custom (Courier, Letter) |\n| 08 | Sidebar | Invoice | classicWithSidebar | corporate |\n| 09 | Minimal | Invoice | minimal | standard |\n| 10 | Stacked | Invoice | stacked | custom (teal) |\n| 11 | Summary First | Invoice | summaryFirst | gold |\n| 12 | Quote | Quote | classic | standard |\n| 13 | Sales Order | Sales Order | classic | corporate |\n| 14 | Delivery | Delivery | standard | standard |\n| 15 | Shipment | Shipment | standard | corporate |\n\n### Generate demo PDFs\n\n```bash\nswift run GenerateDemos\n```\n\nOutputs 15 PDF files to `DemoPDFs/` at the package root.\n\n---\n\n## Project structure\n\n```\nSources/\n  SwiftlyPDFKit/\n    Core/\n      PDF.swift               # Entry point, rendering\n      Page.swift              # Page, PageSize\n      PDFContent.swift        # PDFContent protocol, Text, Spacer, HRule\n      ContentBuilder.swift    # @ContentBuilder result builder\n      Color.swift             # PDFColor\n      Font.swift              # PDFFont\n      Table.swift             # Table, Column, TableStyle\n      Columns.swift           # Columns, ColumnItem\n      FilledBox.swift         # Colored background container\n      ImageContent.swift      # Image rendering\n      QRCodeContent.swift     # QR code generation\n      Footer.swift            # Page footer\n      HTMLToPDFConverter.swift # Linux HTML-to-PDF via wkhtmltopdf\n      HTMLUtilities.swift      # HTML escaping helpers\n    Documents/\n      Invoice/\n        Invoice.swift         # Data model (Supplier, Client, Header, Line, etc.)\n        InvoiceTheme.swift    # Theme presets and customization\n        InvoiceLayout.swift   # 5 layout implementations\n      Shared/\n        DocumentSupplement.swift    # Quote/SalesOrder/Delivery/Shipment supplements\n        DocumentLayoutHelpers.swift # Shared drawing helpers\n      Quote/                  # Quote layout + builder\n      SalesOrder/             # Sales order layout + builder\n      Delivery/               # Delivery note layout + builder\n      Shipment/               # Shipment document layout + builder\n  SwiftlyPDFKitUI/\n    PDFPreviewView.swift      # SwiftUI wrapper (iOS + macOS)\n  DemoPDFKit/                 # 15 demo files + shared fixtures\n  GenerateDemos/\n    main.swift                # CLI tool for batch PDF generation\n```\n\n---\n\n## Dependencies\n\n| Dependency | Version | Purpose |\n|------------|---------|---------|\n| [swift-qrcode-generator](https://github.com/fwcd/swift-qrcode-generator) | ~\u003e 1.0 | Pure-Swift QR code encoder (cross-platform) |\n\n**Apple platforms**: CoreGraphics, CoreText (macOS/iOS), PDFKit (SwiftUI previews only).\n**Linux**: `wkhtmltopdf` system binary for HTML-to-PDF conversion (install with `apt-get install wkhtmltopdf`).\n\n---\n\n## Requirements\n\n- **Swift 6.0+**\n- **macOS 12+** or **iOS 15+** for Apple platforms\n- **Linux**: Swift 6.0+ toolchain and `wkhtmltopdf` (`apt-get install wkhtmltopdf`)\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswiftly-developed%2Fswiftly-pdfkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswiftly-developed%2Fswiftly-pdfkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswiftly-developed%2Fswiftly-pdfkit/lists"}