{"id":42807752,"url":"https://github.com/coregx/gxpdf","last_synced_at":"2026-04-02T11:59:25.338Z","repository":{"id":335400341,"uuid":"1129377321","full_name":"coregx/gxpdf","owner":"coregx","description":"GxPDF - Enterprise-grade PDF library for Go. Table extraction, text parsing, encryption, document creation.","archived":false,"fork":false,"pushed_at":"2026-03-24T13:49:41.000Z","size":16030,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-25T10:34:37.684Z","etag":null,"topics":["go","golang","open-source","pdf","pdf-encryption","pdf-generation","pdf-library","pdf-parser","table-extraction","text-extraction"],"latest_commit_sha":null,"homepage":"https://github.com/coregx/gxpdf","language":"Go","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/coregx.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","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-01-07T02:24:52.000Z","updated_at":"2026-03-24T23:01:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/coregx/gxpdf","commit_stats":null,"previous_names":["coregx/gxpdf"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/coregx/gxpdf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coregx%2Fgxpdf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coregx%2Fgxpdf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coregx%2Fgxpdf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coregx%2Fgxpdf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coregx","download_url":"https://codeload.github.com/coregx/gxpdf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coregx%2Fgxpdf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31305971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T09:48:21.550Z","status":"ssl_error","status_checked_at":"2026-04-02T09:48:19.196Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["go","golang","open-source","pdf","pdf-encryption","pdf-generation","pdf-library","pdf-parser","table-extraction","text-extraction"],"created_at":"2026-01-30T04:22:51.498Z","updated_at":"2026-04-02T11:59:25.332Z","avatar_url":"https://github.com/coregx.png","language":"Go","readme":"# GxPDF - Enterprise-Grade PDF Library for Go\n\n![GxPDF Cover](assets/gh_cover.png)\n\n[![GitHub Release](https://img.shields.io/github/v/release/coregx/gxpdf)](https://github.com/coregx/gxpdf/releases/latest)\n[![Go Version](https://img.shields.io/badge/Go-1.25+-00ADD8?style=flat\u0026logo=go)](https://go.dev/)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![CI](https://github.com/coregx/gxpdf/actions/workflows/test.yml/badge.svg)](https://github.com/coregx/gxpdf/actions/workflows/test.yml)\n[![codecov](https://codecov.io/gh/coregx/gxpdf/branch/main/graph/badge.svg)](https://codecov.io/gh/coregx/gxpdf)\n[![GoDoc](https://pkg.go.dev/badge/github.com/coregx/gxpdf)](https://pkg.go.dev/github.com/coregx/gxpdf)\n[![Go Report Card](https://goreportcard.com/badge/github.com/coregx/gxpdf)](https://goreportcard.com/report/github.com/coregx/gxpdf)\n[![GitHub Stars](https://img.shields.io/github/stars/coregx/gxpdf)](https://github.com/coregx/gxpdf/stargazers)\n\n**GxPDF** is a modern, high-performance PDF library for Go, built with clean architecture and Go 1.25+ best practices.\n\n**[View Example PDF](assets/gxpdf_enterprise_brochure.pdf)** - See what GxPDF can create!\n\n## Key Features\n\n### Declarative Builder API (NEW)\n\nQuestPDF-inspired declarative API with 12-column grid, automatic pagination, and composable components. Define documents as nested closures — the engine handles page breaks, header/footer repetition, and two-pass page number resolution automatically.\n\n```go\nimport \"github.com/coregx/gxpdf/builder\"\n\ndoc := builder.NewBuilder(\n    builder.WithPageSize(builder.A4),\n    builder.WithMargins(builder.Mm(20), builder.Mm(15), builder.Mm(20), builder.Mm(15)),\n    builder.WithTitle(\"Invoice\"),\n    builder.WithDefaultFontSize(11),\n)\n\ndoc.Page(func(page *builder.PageBuilder) {\n    page.Header(func(h *builder.Container) {\n        h.Row(func(r *builder.RowBuilder) {\n            r.Col(8, func(c *builder.ColBuilder) {\n                c.Text(\"ACME Corporation\", builder.Bold(), builder.FontSize(16))\n            })\n            r.Col(4, func(c *builder.ColBuilder) {\n                c.Text(\"INVOICE\", builder.Bold(), builder.FontSize(20),\n                    builder.AlignRight(), builder.TextColor(builder.Navy))\n            })\n        })\n        h.Line()\n    })\n\n    page.Content(func(content *builder.Container) {\n        content.Spacer(builder.Mm(10))\n        content.Row(func(r *builder.RowBuilder) {\n            r.Col(6, func(c *builder.ColBuilder) {\n                c.Text(\"Bill To:\", builder.Bold())\n                c.Text(\"John Doe\")\n                c.Text(\"123 Main Street\")\n            })\n            r.Col(6, func(c *builder.ColBuilder) {\n                c.Text(\"Invoice #: INV-2026-001\", builder.AlignRight())\n                c.Text(\"Date: March 23, 2026\", builder.AlignRight())\n            })\n        })\n    })\n\n    page.Footer(func(f *builder.Container) {\n        f.PageNumber(builder.PageNum+\" of \"+builder.TotalPages,\n            builder.AlignCenter(), builder.FontSize(8), builder.TextColor(builder.Gray))\n    })\n})\n\npdfBytes, err := doc.Build()\n```\n\n### Digital Signatures (NEW)\n\nSign and verify PDF documents with zero external dependencies:\n\n```go\nimport \"github.com/coregx/gxpdf/signature\"\n\n// Generate or load your certificate\nkey, cert, _ := signature.GenerateTestCertificate()\nsigner, _ := signature.NewLocalSigner(key, []*x509.Certificate{cert})\n\n// Sign a PDF\nsigned, err := signature.SignDocument(pdfBytes, signer,\n    signature.WithReason(\"Approved\"),\n    signature.WithLocation(\"Moscow\"),\n)\n\n// Verify signatures\ninfos, err := signature.Verify(signed)\nfmt.Println(infos[0].SignedBy, infos[0].Valid) // \"CN=Test\" true\n```\n\n- **PAdES B-B** — CMS/PKCS#7 with ESS signing-certificate-v2\n- **PAdES B-T** — RFC 3161 timestamping via `WithTimestamp(tsaURL)`\n- **RSA + ECDSA** — SHA-256 by default, SHA-384/512 configurable\n- **Verification** — ByteRange hash + CMS cryptographic verification\n- **Incremental update** — preserves existing content and prior signatures\n\n### PDF Creation (Creator API)\n- **Text \u0026 Typography** - Rich text with multiple fonts, styles, and colors\n- **Graphics** - Lines, rectangles, circles, polygons, ellipses, arcs (wedge/chord), cubic and quadratic Bezier curves\n- **Gradients** - Linear and radial gradient fills with full PDF Shading (multi-stop support)\n- **Color Spaces** - RGB and CMYK support\n- **Tables** - Complex tables with merged cells, borders, backgrounds\n- **Images** - JPEG and PNG with transparency support\n- **Fonts** - Standard 14 PDF fonts + TTF/OTF embedding with full Unicode support (Cyrillic, CJK, symbols)\n- **Document Structure** - Chapters, auto-generated Table of Contents\n- **Annotations** - Sticky notes, highlights, underlines, stamps\n- **Interactive Forms** - Text fields, checkboxes, radio buttons, dropdowns\n- **Security** - RC4 (40/128-bit) and AES (128/256-bit) encryption\n- **Watermarks** - Text watermarks with rotation and opacity\n- **Page Sizes** - 35+ built-in sizes (ISO A/B/C, ANSI, photo, book, JIS, envelopes, slides)\n- **Custom Dimensions** - Arbitrary page sizes with unit conversion helpers (inches, mm, cm)\n- **Landscape/Portrait** - True landscape via `NewPageWithSize(A4, Landscape)` — industry-standard swapped-MediaBox\n- **Text Rotation** - Rotated text at any angle via `Tm` operator (standard 14 + custom TTF fonts)\n- **Opacity/Transparency** - Text and shape opacity via ExtGState (`AddTextColorAlpha`, shape `Opacity` option)\n- **Page Operations** - Merge, split, rotate, append\n\n### PDF Reading \u0026 Extraction\n- **Encrypted PDF Reading** - Open password-protected PDFs (RC4-40/128, AES-128)\n- **Table Extraction** - Industry-leading accuracy (100% on bank statements)\n- **Text Extraction** - Full text with positions and Unicode support\n- **Image Extraction** - Extract embedded images\n- **Export Formats** - CSV, JSON, Excel\n\n## Installation\n\n```bash\ngo get github.com/coregx/gxpdf\n```\n\n**Requirements**: Go 1.25 or later\n\n## Quick Start\n\n### Creating a PDF with the Builder API\n\n```go\npackage main\n\nimport (\n    \"log\"\n    \"github.com/coregx/gxpdf/builder\"\n)\n\nfunc main() {\n    doc := builder.NewBuilder(\n        builder.WithPageSize(builder.A4),\n        builder.WithTitle(\"Hello World\"),\n    )\n\n    doc.Page(func(page *builder.PageBuilder) {\n        page.Content(func(c *builder.Container) {\n            c.Text(\"Hello, GxPDF!\", builder.Bold(), builder.FontSize(24))\n            c.Spacer(builder.Mm(5))\n            c.Text(\"Professional PDF creation in Go.\")\n        })\n    })\n\n    if err := doc.BuildToFile(\"output.pdf\"); err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n### Creating a PDF Document (Creator API)\n\n```go\npackage main\n\nimport (\n    \"log\"\n    \"github.com/coregx/gxpdf/creator\"\n)\n\nfunc main() {\n    c := creator.New()\n    c.SetTitle(\"My Document\")\n    c.SetAuthor(\"GxPDF\")\n\n    page, _ := c.NewPage()\n\n    // Add text\n    page.AddText(\"Hello, GxPDF!\", 100, 750, creator.HelveticaBold, 24)\n    page.AddText(\"Professional PDF creation in Go\", 100, 720, creator.Helvetica, 12)\n\n    // Draw shapes\n    page.DrawRectangle(100, 600, 200, 100, \u0026creator.RectangleOptions{\n        FillColor:   \u0026creator.Blue,\n        StrokeColor: \u0026creator.Black,\n        StrokeWidth: 2,\n    })\n\n    if err := c.WriteToFile(\"output.pdf\"); err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n### Unicode Text with Custom Fonts\n\n```go\nc := creator.New()\npage, _ := c.NewPage()\n\n// Load custom font with Unicode support\nfont, _ := c.LoadFont(\"/path/to/arial.ttf\")\n\n// Cyrillic text\npage.AddTextCustomFont(\"Привет, мир!\", 100, 700, font, 18)\n\n// CJK text (requires appropriate font like Malgun Gothic)\ncjkFont, _ := c.LoadFont(\"/path/to/malgun.ttf\")\npage.AddTextCustomFont(\"你好世界 • 안녕하세요\", 100, 670, cjkFont, 16)\n\nc.WriteToFile(\"unicode.pdf\")\n```\n\n### Creating Encrypted PDFs\n\n```go\nc := creator.New()\n\nc.SetEncryption(creator.EncryptionOptions{\n    UserPassword:  \"user123\",\n    OwnerPassword: \"owner456\",\n    Permissions:   creator.PermissionPrint | creator.PermissionCopy,\n    Algorithm:     creator.EncryptionAES256,\n})\n\npage, _ := c.NewPage()\npage.AddText(\"This document is encrypted!\", 100, 750, creator.Helvetica, 14)\nc.WriteToFile(\"encrypted.pdf\")\n```\n\n### Creating Documents with Chapters and TOC\n\n```go\nc := creator.New()\nc.EnableTOC()\n\nch1 := creator.NewChapter(\"Introduction\")\nch1.Add(creator.NewParagraph(\"Introduction content...\"))\n\nch1_1 := ch1.NewSubChapter(\"Background\")\nch1_1.Add(creator.NewParagraph(\"Background information...\"))\n\nch2 := creator.NewChapter(\"Methods\")\nch2.Add(creator.NewParagraph(\"Methods description...\"))\n\nc.AddChapter(ch1)\nc.AddChapter(ch2)\n\nc.WriteToFile(\"document_with_toc.pdf\")\n```\n\n### Interactive Forms (AcroForm)\n\n```go\nimport \"github.com/coregx/gxpdf/creator/forms\"\n\nc := creator.New()\npage, _ := c.NewPage()\n\n// Text field\nnameField := forms.NewTextField(\"name\", 100, 700, 200, 20)\nnameField.SetLabel(\"Full Name:\")\nnameField.SetRequired(true)\npage.AddField(nameField)\n\n// Checkbox\nagreeBox := forms.NewCheckbox(\"agree\", 100, 660, 15, 15)\nagreeBox.SetLabel(\"I agree to the terms\")\npage.AddField(agreeBox)\n\n// Dropdown\ncountryDropdown := forms.NewDropdown(\"country\", 100, 620, 150, 20)\ncountryDropdown.AddOption(\"us\", \"United States\")\ncountryDropdown.AddOption(\"uk\", \"United Kingdom\")\npage.AddField(countryDropdown)\n\nc.WriteToFile(\"form.pdf\")\n```\n\n### Reading and Filling Forms\n\n```go\n// Read form fields from existing PDF\ndoc, _ := gxpdf.Open(\"form.pdf\")\ndefer doc.Close()\n\n// Check if document has a form\nif doc.HasForm() {\n    fields, _ := doc.GetFormFields()\n    for _, f := range fields {\n        fmt.Printf(\"%s (%s): %v\\n\", f.Name(), f.Type(), f.Value())\n    }\n}\n\n// Fill form fields\napp, _ := creator.NewAppender(\"form.pdf\")\ndefer app.Close()\n\napp.SetFieldValue(\"name\", \"John Doe\")\napp.SetFieldValue(\"email\", \"john@example.com\")\napp.SetFieldValue(\"agree\", true)  // Checkbox\napp.SetFieldValue(\"country\", \"USA\")  // Dropdown\n\napp.WriteToFile(\"filled_form.pdf\")\n```\n\n### Flattening Forms\n\n```go\n// Convert form fields to static content (non-editable)\napp, _ := creator.NewAppender(\"filled_form.pdf\")\ndefer app.Close()\n\napp.FlattenForm()  // Flatten all fields\n// Or: app.FlattenFields(\"signature\", \"date\")  // Specific fields\n\napp.WriteToFile(\"flattened.pdf\")\n```\n\n### Extracting Text from PDFs\n\n```go\ndoc, _ := gxpdf.Open(\"document.pdf\")\ndefer doc.Close()\n\n// Extract text from a specific page (1-based)\ntext, err := doc.ExtractTextFromPage(1)\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Println(text)\n\n// Or iterate all pages\nfor _, page := range doc.Pages() {\n    fmt.Println(page.ExtractText())\n}\n```\n\n### Extracting Tables from PDFs\n\n```go\ndoc, _ := gxpdf.Open(\"bank_statement.pdf\")\ndefer doc.Close()\n\ntables := doc.ExtractTables()\nfor _, table := range tables {\n    fmt.Printf(\"Table: %d rows x %d cols\\n\", table.RowCount(), table.ColumnCount())\n\n    // Export to CSV\n    csv, _ := table.ToCSV()\n    fmt.Println(csv)\n}\n```\n\n### Reading Encrypted PDFs\n\n```go\n// PDFs with empty user password (permissions-only) open transparently\ndoc, _ := gxpdf.Open(\"bank_statement_encrypted.pdf\")\ndefer doc.Close()\n\n// PDFs requiring a password\ndoc, err := gxpdf.OpenWithPassword(\"protected.pdf\", \"secret\")\nif errors.Is(err, gxpdf.ErrPasswordRequired) {\n    log.Fatal(\"Wrong password\")\n}\ndefer doc.Close()\n\nfmt.Printf(\"Pages: %d\\n\", doc.PageCount())\n```\n\n## Package Structure\n\n```\ngithub.com/coregx/gxpdf\n├── gxpdf.go          # Main entry point (Open, OpenWithPassword)\n├── builder/          # Declarative Builder API (12-col grid, tables, rich text)\n├── layout/           # Pure computation layout engine (zero PDF deps)\n├── signature/        # Digital signatures (PAdES B-B/B-T, verify)\n├── export/           # Export formats (CSV, JSON, Excel)\n├── creator/          # Low-level PDF creation API\n│   └── forms/        # Interactive form fields\n├── logging/          # Configurable debug logging\n└── internal/         # Private implementation\n    ├── application/  # Use cases (extraction, reading)\n    └── infrastructure/ # PDF parsing, encoding, writing\n```\n\n## Documentation\n\n- **[API Reference](https://pkg.go.dev/github.com/coregx/gxpdf)** - Full API documentation\n- **[Examples](examples/)** - Code examples for all features\n- **[Enterprise Brochure (PDF)](assets/gxpdf_enterprise_brochure.pdf)** - Sample PDF created with GxPDF\n- **[Architecture](docs/ARCHITECTURE.md)** - DDD architecture overview\n- **[Contributing](CONTRIBUTING.md)** - Contribution guidelines\n- **[Security](SECURITY.md)** - Security policy\n\n## Testing\n\n```bash\n# Run all tests\ngo test ./...\n\n# Run with race detector\ngo test -race ./...\n\n# Run with coverage\ngo test -cover ./...\n```\n\n### Debug Logging\n\nDebug output is disabled by default. To enable it, configure a logger via the `logging` package:\n\n```go\nimport (\n    \"log/slog\"\n    \"os\"\n    \"github.com/coregx/gxpdf/logging\"\n)\n\nlogging.SetLogger(slog.New(slog.NewTextHandler(os.Stderr, \u0026slog.HandlerOptions{\n    Level: slog.LevelWarn,\n})))\n```\n\nConvenience methods like `ExtractText()`, `ExtractTables()`, and `GetImages()` log errors via slog instead of returning them. Enable logging to see why these methods return empty results.\n\n## Roadmap\n\nSee [ROADMAP.md](ROADMAP.md) for the full development plan and version history.\n\n## License\n\nGxPDF is released under the **MIT License**. See [LICENSE](LICENSE) for details.\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/coregx/gxpdf/issues)\n- **Discussions**: [GitHub Discussions](https://github.com/coregx/gxpdf/discussions)\n\n---\n\n**Built with Go 1.25+ and Domain-Driven Design**\n","funding_links":[],"categories":["File Handling"],"sub_categories":["Search and Analytic Databases"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoregx%2Fgxpdf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoregx%2Fgxpdf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoregx%2Fgxpdf/lists"}