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.