go-docx

Go-DOCX - Microsoft Word Document Library for Go

Go-DOCX is a comprehensive Go library for creating and manipulating Microsoft Word (.docx) documents. It is inspired by and provides feature parity (~75%) with the popular python-docx library, offering a type-safe, high-performance alternative for Go developers.

๐Ÿ†• Whatโ€™s New

Quick examples:

// 1) Insert a row after a template row
table := doc.AddTable(2, 3)
// ... fill header in row 0 and example/template row in row 1
newRow := table.InsertRowAt(2) // insert right after template row (index 1)
_ = newRow // fill cells as needed

// 2) Preserve landscape orientation
sec := doc.AddSection(docx.WDSectionNewPage)
// Set page size with width > height; ToXML will emit w:orient="landscape"
sec.SetPageSize(16838, 11906)

โœจ Features

Core Document Features

Text and Paragraphs

Headings and Styles

Tables

Images ๐Ÿ“ท

Lists ๐Ÿ“

Headers and Footers

Page Layout

Advanced Features

๐Ÿ“ฆ Installation

go get github.com/SanjarbekSaminjonov/go-docx

๐Ÿš€ Quick Start

package main

import (
    "log"
    "github.com/SanjarbekSaminjonov/go-docx"
)

func main() {
    // Create a new document
    doc := docx.NewDocument()
    defer doc.Close()
    
    // Set document properties
    props := doc.CoreProperties()
    props.SetTitle("My Document")
    props.SetCreator("John Doe")
    
    // Add a title
    title, _ := doc.AddHeading("Welcome to Go-DOCX", 0)
    title.SetAlignment(docx.WDAlignParagraphCenter)
    
    // Add a paragraph with formatted text
    p := doc.AddParagraph()
    p.AddRun("This is ").SetBold(false)
    p.AddRun("bold text").SetBold(true)
    p.AddRun(" and this is ").SetBold(false)
    p.AddRun("italic text").SetItalic(true)
    
    // Add a hyperlink
    p2 := doc.AddParagraph("Visit our website: ")
    p2.AddHyperlink("Go-DOCX on GitHub", "https://github.com/SanjarbekSaminjonov/go-docx")
    
    // Add an image
    doc.AddPicture("logo.png", 0, 0) // Auto aspect ratio
    
    // Add a numbered list
    doc.AddNumberedParagraph("First item", 0)
    doc.AddNumberedParagraph("Second item", 0)
    doc.AddNumberedParagraph("Sub-item", 1)
    
    // Add a table
    table := doc.AddTable(3, 3)
    table.Row(0).Cell(0).SetText("Header 1")
    table.Row(0).Cell(1).SetText("Header 2")
    table.Row(0).Cell(2).SetText("Header 3")
    
    // Save the document
    if err := doc.SaveAs("my_document.docx"); err != nil {
        log.Fatal(err)
    }
}

API Reference

Document

Creating Documents

// Create a new document
doc := docx.NewDocument()

// Open an existing document
doc, err := docx.OpenDocument("existing.docx")

Adding Content

// Add a paragraph
paragraph := doc.AddParagraph("Text content")

// Add a heading (levels 0-9)
heading, err := doc.AddHeading("Chapter Title", 1)

// Add a table
table := doc.AddTable(3, 4) // 3 rows, 4 columns

// Add a page break
doc.AddPageBreak()

Document Properties

props := doc.CoreProperties()
props.SetTitle("Document Title")
props.SetCreator("Author Name")
props.SetSubject("Document Subject")

Saving Documents

// Save to a new file
err := doc.SaveAs("output.docx")

// Save to original location (if opened from file)
err := doc.Save()

// Close the document
err := doc.Close()

Getting Document XML

You can retrieve the raw XML content of the document for debugging, analysis, or custom processing:

// Get the XML content of the document
xmlContent, err := doc.GetXML()
if err != nil {
    log.Printf("Error getting XML: %v", err)
    return
}

fmt.Println("Document XML content:")
fmt.Println(xmlContent)

Use cases for GetXML():

The returned XML will be in OpenXML WordprocessingML format, containing elements like <w:document>, <w:body>, <w:p> (paragraphs), <w:r> (runs), and <w:t> (text).

Paragraphs

paragraph := doc.AddParagraph("Initial text")

// Set alignment
paragraph.SetAlignment(docx.WDAlignParagraphCenter)
paragraph.SetAlignment(docx.WDAlignParagraphRight)
paragraph.SetAlignment(docx.WDAlignParagraphJustify)

// Set style
paragraph.SetStyle("Heading 1")

// Paragraph spacing (in twips)
paragraph.SetSpacingBefore(240) // 240 twips = 1/6 inch
paragraph.SetSpacingAfter(240)
paragraph.SetLineSpacing(360, docx.LineSpacingAuto) // 1.5 line spacing

// Paragraph indentation (in twips)
paragraph.SetIndentation(720, 0, 0) // left, right, firstLine

// Paragraph borders
paragraph.SetBorder(docx.ParagraphBorderTop, docx.ParagraphBorder{
    Style: "single",
    Color: "000000",
    Size:  4,
})

// Paragraph shading
paragraph.SetShading("clear", "D9D9D9", "auto")

// Keep with next paragraph
paragraph.SetKeepWithNext(true)

// Keep lines together
paragraph.SetKeepTogether(true)

// Add runs with different formatting
run1 := paragraph.AddRun("Normal text ")
run2 := paragraph.AddRun("Bold text")
run2.SetBold(true)

Text Formatting (Runs)

run := paragraph.AddRun("Formatted text")

// Basic formatting
run.SetBold(true)
run.SetItalic(true)
run.SetUnderline(docx.WDUnderlineSingle)

// Font and size
run.SetFont("Arial")
run.SetSize(14) // Font size in points

// Color and highlighting
run.SetColor("FF0000") // Red color
run.SetHighlight(docx.WDColorIndexYellow)

// Add breaks
run.AddBreak(docx.BreakTypePage)
run.AddBreak(docx.BreakTypeColumn)

Tables

// Create a table
table := doc.AddTable(3, 4) // 3 rows, 4 columns

// Access cells
cell := table.Row(0).Cell(0)
cell.SetText("Header 1")

// Add content to cells
cell.AddParagraph("Additional content")

// Add new rows
newRow := table.AddRow()

// Table borders
table.SetBorder(docx.TableBorderTop, docx.TableBorder{
    Style: "single",
    Color: "000000",
    Size:  4,
})

// Cell shading
cell.SetShading("clear", "4472C4", "auto") // pattern, fill, color

// Cell margins (in twips - 1/1440 inch)
table.SetCellMargins(100, 100, 100, 100) // top, left, bottom, right

// Merge cells horizontally
table.MergeCellsHorizontally(0, 0, 2) // row, startCol, endCol

// Merge cells vertically
table.MergeCellsVertically(0, 0, 2) // col, startRow, endRow

// Insert table after a specific paragraph
paragraph := doc.AddParagraph("This paragraph will be followed by a table")
newTable, err := doc.InsertTableAfterParagraph(paragraph, 2, 3)
if err != nil {
    log.Fatal(err)
}

Document Manipulation

// Remove a paragraph
paragraph := doc.AddParagraph("Temporary text")
err := doc.RemoveParagraph(paragraph)
if err != nil {
    log.Fatal(err)
}

// Remove a table
table := doc.AddTable(2, 2)
err := doc.RemoveTable(table)
if err != nil {
    log.Fatal(err)
}

// Remove a section
section := doc.AddSection(docx.SectionStartNewPage)
err := doc.RemoveSection(section)
if err != nil {
    log.Fatal(err)
}

// Get all document elements
paragraphs := doc.Paragraphs()
tables := doc.Tables()
sections := doc.Sections()

Images ๐Ÿ“ท

// Add image to document (creates new paragraph)
paragraph, picture, err := doc.AddPicture("photo.png", 0, 0)
if err != nil {
    log.Fatal(err)
}
// 0, 0 means auto aspect ratio based on image dimensions

// Add image with specific size (in EMUs)
// 914400 EMUs = 1 inch
doc.AddPicture("photo.jpg", 914400, 914400) // 1" x 1"

// Add image to a run
run := paragraph.AddRun()
pic, err := run.AddPicture("logo.png", 0, 0)

// Get image data
imageBytes, err := picture.ImageData()

// Supported formats: PNG, JPEG, GIF, BMP, TIFF
// Simple hyperlink using paragraph method
p := doc.AddParagraph("Visit ")
p.AddHyperlink("Google", "https://www.google.com")

// URL hyperlink using run
run := p.AddRun("GitHub")
run.SetHyperlink("https://github.com")
run.SetColor("0563C1") // Blue color
run.SetUnderline(docx.WDUnderlineSingle)

// Internal anchor/bookmark
run.SetHyperlinkAnchor("section1")

// Check if run has hyperlink
if run.HasHyperlink() {
    // Handle hyperlink
}

Lists (Numbered and Bulleted) ๐Ÿ“

// Numbered list
doc.AddNumberedParagraph("First item", 0)
doc.AddNumberedParagraph("Second item", 0)
doc.AddNumberedParagraph("Third item", 0)

// Multi-level numbered list
doc.AddNumberedParagraph("Level 0 - Item 1", 0)
doc.AddNumberedParagraph("Level 1 - Sub-item 1.1", 1)
doc.AddNumberedParagraph("Level 1 - Sub-item 1.2", 1)
doc.AddNumberedParagraph("Level 2 - Sub-sub-item", 2)
doc.AddNumberedParagraph("Level 0 - Item 2", 0)

// Bulleted list
doc.AddBulletedParagraph("First bullet", 0)
doc.AddBulletedParagraph("Second bullet", 0)
doc.AddBulletedParagraph("Sub-bullet", 1)

// Custom numbering
paragraph := doc.AddParagraph("Custom numbered item")
paragraph.SetNumbering(1, 0) // numID, level

Headers and Footers

// Get or create default section
section := doc.Sections()[0]

// Add default header
header, err := section.Header()
if err != nil {
    log.Fatal(err)
}
headerP := header.AddParagraph("Company Name")
headerP.SetAlignment(docx.WDAlignParagraphCenter)

// Add default footer
footer, err := section.Footer()
if err != nil {
    log.Fatal(err)
}
footerP := footer.AddParagraph("Page ")
footerP.SetAlignment(docx.WDAlignParagraphCenter)

// First page header (different from others)
firstHeader, err := section.HeaderOfType(docx.HeaderTypeFirst)
firstHeader.AddParagraph("First Page Header")

// Even page header
evenHeader, err := section.HeaderOfType(docx.HeaderTypeEven)
evenHeader.AddParagraph("Even Page Header")

// Document-level convenience methods
header, err := doc.Header() // Default header of first section
footer, err := doc.Footer() // Default footer of first section

Sections and Page Layout

// Add a new section
section := doc.AddSection(docx.WDSectionNewPage)

// Set page size (in twips - 1/1440 inch)
section.SetPageSize(12240, 15840) // Letter size: 8.5" x 11"

// Set orientation
section.SetOrientation(docx.WDOrientLandscape)

// Set margins (in twips)
section.SetMargins(1440, 1440, 1440, 1440) // 1 inch margins

Constants

Alignment

Underline Types

Break Types

Color Indices (for highlighting)

Section Start Types

Orientation Types

Header/Footer Types

Table Border Sides

Units

EMUs (English Metric Units):

Twips (Twentieth of a point):

๐Ÿ“š Examples

Complete Example

package main

import (
    "log"
    "github.com/SanjarbekSaminjonov/go-docx"
)

func main() {
    // Create document
    doc := docx.NewDocument()
    defer doc.Close()
    
    // Document properties
    props := doc.CoreProperties()
    props.SetTitle("Comprehensive Example")
    props.SetCreator("Go-DOCX")
    props.SetSubject("Feature Demonstration")
    
    // Title
    title, _ := doc.AddHeading("Go-DOCX Feature Showcase", 0)
    title.SetAlignment(docx.WDAlignParagraphCenter)
    
    // Section 1: Text Formatting
    doc.AddHeading("1. Text Formatting", 1)
    p := doc.AddParagraph()
    p.AddRun("Normal text, ")
    p.AddRun("bold text, ").SetBold(true)
    p.AddRun("italic text, ").SetItalic(true)
    p.AddRun("colored text").SetColor("FF0000")
    
    // Section 2: Hyperlinks
    doc.AddHeading("2. Hyperlinks", 1)
    p2 := doc.AddParagraph("Visit ")
    p2.AddHyperlink("our website", "https://example.com")
    
    // Section 3: Lists
    doc.AddHeading("3. Lists", 1)
    doc.AddNumberedParagraph("First item", 0)
    doc.AddNumberedParagraph("Second item", 0)
    doc.AddBulletedParagraph("Bullet point", 0)
    
    // Section 4: Tables
    doc.AddHeading("4. Tables", 1)
    table := doc.AddTable(3, 3)
    table.Row(0).Cell(0).SetText("Name")
    table.Row(0).Cell(1).SetText("Age")
    table.Row(0).Cell(2).SetText("City")
    
    // Set all table borders
    border := docx.TableBorder{Style: "single", Color: "000000", Size: 4}
    table.SetBorder(docx.TableBorderTop, border)
    table.SetBorder(docx.TableBorderBottom, border)
    table.SetBorder(docx.TableBorderLeft, border)
    table.SetBorder(docx.TableBorderRight, border)
    table.SetBorder(docx.TableBorderInsideH, border)
    table.SetBorder(docx.TableBorderInsideV, border)
    
    // Section 5: Images
    doc.AddHeading("5. Images", 1)
    doc.AddPicture("logo.png", 0, 0) // Add your image
    
    // Headers and Footers
    section := doc.Sections()[0]
    header, _ := section.Header()
    header.AddParagraph("Document Header").SetAlignment(docx.WDAlignParagraphCenter)
    
    footer, _ := section.Footer()
    footer.AddParagraph("Page Footer").SetAlignment(docx.WDAlignParagraphCenter)
    
    // Save
    if err := doc.SaveAs("comprehensive_example.docx"); err != nil {
        log.Fatal(err)
    }
}

๐Ÿ“Š Feature Comparison with python-docx

Feature python-docx go-docx Status
Core Document ย  ย  ย 
Create document Document() NewDocument() โœ… Full
Open document Document('file.docx') OpenDocument('file.docx') โœ… Full
Save document doc.save() doc.SaveAs() โœ… Full
Document properties doc.core_properties doc.CoreProperties() โœ… Full
Paragraphs & Text ย  ย  ย 
Add paragraph doc.add_paragraph() doc.AddParagraph() โœ… Full
Add heading doc.add_heading() doc.AddHeading() โœ… Full
Text formatting run.bold = True run.SetBold(true) โœ… Full
Paragraph alignment p.alignment = WD_ALIGN_* p.SetAlignment() โœ… Full
Paragraph spacing p.paragraph_format p.SetSpacing*() โœ… Full
Paragraph indentation p.paragraph_format p.SetIndentation() โœ… Full
Paragraph borders XML manipulation p.SetBorder() โœ… Full
Tables ย  ย  ย 
Add table doc.add_table() doc.AddTable() โœ… Full
Table borders Limited table.SetBorder() โœ… Enhanced
Cell shading XML manipulation cell.SetShading() โœ… Full
Cell margins XML manipulation table.SetCellMargins() โœ… Full
Merge cells XML manipulation table.MergeCells*() โœ… Full
Images ย  ย  ย 
Add picture run.add_picture() run.AddPicture() โœ… Full
Document picture doc.add_picture() doc.AddPicture() โœ… Full
Image formats PNG, JPEG, GIF, BMP PNG, JPEG, GIF, BMP, TIFF โœ… Full
Auto aspect ratio width=None or height=None widthEMU=0 or heightEMU=0 โœ… Full
Hyperlinks ย  ย  ย 
Add hyperlink Paragraph method p.AddHyperlink() โœ… Full
Run hyperlink XML manipulation run.SetHyperlink() โœ… Full
Internal anchor Limited run.SetHyperlinkAnchor() โœ… Full
Lists ย  ย  ย 
Numbered list Style-based doc.AddNumberedParagraph() โœ… Full
Bulleted list Style-based doc.AddBulletedParagraph() โœ… Full
Multi-level paragraph.style Level parameter โœ… Full
Custom numbering numbering_part paragraph.SetNumbering() โœ… Full
Headers & Footers ย  ย  ย 
Add header section.header section.Header() โœ… Full
Add footer section.footer section.Footer() โœ… Full
First page header section.first_page_header section.HeaderOfType() โœ… Full
Even page header section.even_page_header section.HeaderOfType() โœ… Full
Sections ย  ย  ย 
Add section doc.add_section() doc.AddSection() โœ… Full
Page size section.page_width section.SetPageSize() โœ… Full
Orientation section.orientation section.SetOrientation() โœ… Full
Margins section.left_margin section.SetMargins() โœ… Full
Styles ย  ย  ย 
Built-in styles doc.styles paragraph.SetStyle() โœ… Full
Custom styles styles.add_style() Limited API โš ๏ธ Partial
Advanced ย  ย  ย 
Comments doc.add_comment() Struct exists โš ๏ธ Partial
Track changes Yes No โŒ Not implemented
Charts Yes No โŒ Not implemented
SmartArt Yes No โŒ Not implemented

Overall Feature Parity: ~75% ๐ŸŽฏ

๐Ÿš€ Performance & Advantages

Why Choose Go-DOCX?

  1. Type Safety - Goโ€™s static typing prevents runtime errors
  2. Performance - Compiled binary, faster than interpreted Python
  3. Deployment - Single binary, no dependencies to install
  4. Concurrency - Native goroutines for parallel processing
  5. Memory Efficient - Better memory management than Python
  6. Production Ready - Tested and stable for production use

When to Use Go-DOCX

โœ… Server-side document generation
โœ… Microservices architecture
โœ… High-performance scenarios
โœ… Production deployments
โœ… Documents with tables, images, and lists
โœ… Automated report generation
โœ… Go ecosystem integration

When to Use python-docx

โœ… Charts and SmartArt required
โœ… Mail merge functionality
โœ… Track changes needed
โœ… Python ecosystem integration
โœ… Rapid prototyping

๐Ÿ“– Documentation

For detailed API documentation, see:

๐Ÿงช Testing

Run the test suite:

go test ./...

Run specific tests:

go test -v -run TestInlinePicture
go test -v -run TestHyperlink
go test -v -run TestNumbered

All tests include round-trip validation (save and reopen).

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development Setup

# Clone the repository
git clone https://github.com/SanjarbekSaminjonov/go-docx.git
cd go-docx

# Run tests
go test ./...

# Run tests with coverage
go test -cover ./...

# Format code
gofmt -w .

Areas for Contribution

We welcome contributions in these areas:

  1. Custom Styles API - Complete the styles creation and management
  2. Comments Integration - Finish the comments API implementation
  3. Charts Support - Add basic chart creation capabilities
  4. Performance Optimization - Improve XML parsing/generation
  5. Documentation - More examples and tutorials
  6. Bug Fixes - Report and fix any issues you find

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments

๐Ÿ“ž Support

๐Ÿ—บ๏ธ Roadmap

Completed Features โœ…

In Progress ๐Ÿšง

Planned Features ๐Ÿ“‹

Future Enhancements ๐Ÿ”ฎ


Made with โค๏ธ for the Go community

Go-DOCX - Production-ready Word document generation for Go