Introduction

Aspose.PDF FOSS for Go provides a set of document-level operations that cover the most common PDF management tasks: opening existing files, creating new documents, splitting a document into per-page outputs, merging multiple PDFs into one, extracting a subset of pages, and reading or writing document metadata. These operations are available without any native C or C++ dependencies.

The library is a Go module at github.com/aspose-pdf-foss/aspose-pdf-foss-for-go, MIT licensed, and requires Go 1.24 or later. Install with go get github.com/aspose-pdf-foss/aspose-pdf-foss-for-go.

This post covers the Document, Page, PageRange, and Metadata types that form the core document management surface.


Core Operations

Opening and Saving Documents

pdf.Open loads a PDF from disk and returns a *Document. OpenWithPassword does the same for password-protected files. Document.Save writes the result back to a file path. Document.WriteTo writes to an io.Writer for in-memory or network scenarios.

import pdf "github.com/aspose-pdf-foss/aspose-pdf-foss-for-go"

// Open a standard PDF
doc, err := pdf.Open("input.pdf")
if err != nil {
    panic(err)
}

// Open an encrypted PDF
protected, err := pdf.OpenWithPassword("locked.pdf", "userpassword")
if err != nil {
    panic(err)
}

// Save to a new path
err = doc.Save("output.pdf")

Creating a New Document

pdf.NewDocument creates an empty *Document. Use AddBlankPageFromFormat to append a blank page with a standard paper size. PageFormat provides named format constants (PageFormatA4, PageFormatLetter, etc.).

doc := pdf.NewDocument()

// Add an A4 page
doc.AddBlankPageFromFormat(pdf.PageFormatA4)

doc.Save("new_document.pdf")

Splitting a Document

Document.Split divides a PDF into individual per-page *Document values. Each returned document contains exactly one page and can be saved independently. This is useful for splitting batch-generated reports or separating invoice pages.

doc, _ := pdf.Open("multi_page.pdf")
pages, err := doc.Split()
if err != nil {
    panic(err)
}

for i, p := range pages {
    filename := fmt.Sprintf("page_%03d.pdf", i+1)
    if err := p.Save(filename); err != nil {
        fmt.Printf("Failed to save page %d: %v\n", i+1, err)
    }
}
fmt.Printf("Split into %d pages\n", len(pages))

Merging Multiple PDFs

Document.Append merges a second *Document into the receiver in-place, appending all pages from the source. Call Append repeatedly to chain multiple documents before a single Save. The source document is not modified.

base, _ := pdf.Open("report_intro.pdf")
section1, _ := pdf.Open("section1.pdf")
section2, _ := pdf.Open("section2.pdf")
appendix, _ := pdf.Open("appendix.pdf")

base.Append(section1)
base.Append(section2)
base.Append(appendix)

base.Save("complete_report.pdf")

Extracting a Page Range

PageRange represents an inclusive range (1-based, using From/To fields). Pass ranges to Document.Extract to produce a new *Document containing only the selected pages. This is useful for building per-chapter exports or redacted copies that omit certain pages.

doc, _ := pdf.Open("long_report.pdf")

// Extract pages 3 through 7
subset, err := doc.Extract(pdf.PageRange{From: 3, To: 7})
if err != nil {
    panic(err)
}
subset.Save("pages_3_to_7.pdf")

Reading and Writing Document Metadata

Document.Metadata returns a Metadata struct exposing both XMP and traditional Info dictionary fields: Title, Author, Subject, Keywords, Creator, Producer, CreationDate, and ModDate. Modify the fields directly, then call Document.SetMetadata to write the updated struct back before calling Save.

doc, _ := pdf.Open("report.pdf")
meta, _ := doc.Metadata()

// Read current values
fmt.Printf("Title: %s\nAuthor: %s\n", meta.Title, meta.Author)

// Update fields
meta.Title = "Annual Report 2026"
meta.Author = "Finance Team"
meta.Keywords = "annual, report, finance, 2026"

doc.SetMetadata(meta)
doc.Save("report_updated.pdf")

Accessing Individual Pages

Document.Page(n) retrieves a *Page by 1-based index. Document.PageCount returns the total number of pages. Pages expose geometry properties for reading page boxes and size.

doc, _ := pdf.Open("document.pdf")
fmt.Printf("Page count: %d\n", doc.PageCount())

page, _ := doc.Page(1)
size := page.PageSize()
fmt.Printf("Page 1 size: %.0f x %.0f pt\n", size.Width, size.Height)

Quick Start

Install the module:

go get github.com/aspose-pdf-foss/aspose-pdf-foss-for-go

A complete example that opens a document, splits it, and merges three of its pages into a new document with updated metadata:

package main

import (
    "fmt"
    pdf "github.com/aspose-pdf-foss/aspose-pdf-foss-for-go"
)

func main() {
    // Open source document
    src, err := pdf.Open("source.pdf")
    if err != nil {
        panic(err)
    }

    // Extract pages 1-3
    subset, err := src.Extract(pdf.PageRange{From: 1, To: 3})
    if err != nil {
        panic(err)
    }

    // Update metadata
    meta, _ := subset.Metadata()
    meta.Title = "Pages 1-3 Extract"
    meta.Author = "Document Pipeline"
    subset.SetMetadata(meta)

    if err := subset.Save("extract_pages_1_3.pdf"); err != nil {
        panic(err)
    }
    fmt.Printf("Saved %d pages\n", subset.PageCount())
}

Open Source and Licensing

Aspose.PDF FOSS for Go is released under the MIT license. There are no usage restrictions, no runtime fees, and no registration requirements. The source code is available at github.com/aspose-pdf-foss/aspose-pdf-foss-for-go.


Getting Started