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.
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)
doc.AddPicture()
run.AddPicture()
paragraph.AddHyperlink()
run.SetHyperlink()
, run.SetHyperlinkAnchor()
run.HasHyperlink()
doc.AddNumberedParagraph()
, doc.AddBulletedParagraph()
paragraph.SetNumbering(numID, level)
go get github.com/SanjarbekSaminjonov/go-docx
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)
}
}
// Create a new document
doc := docx.NewDocument()
// Open an existing document
doc, err := docx.OpenDocument("existing.docx")
// 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()
props := doc.CoreProperties()
props.SetTitle("Document Title")
props.SetCreator("Author Name")
props.SetSubject("Document Subject")
// 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()
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).
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)
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)
// 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)
}
// 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()
// 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
}
// 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
// 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
// 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
WDAlignParagraphLeft
- Left alignmentWDAlignParagraphCenter
- Center alignmentWDAlignParagraphRight
- Right alignmentWDAlignParagraphJustify
- Justified alignmentWDAlignParagraphDistribute
- Distributed alignmentWDUnderlineNone
- No underlineWDUnderlineSingle
- Single underlineWDUnderlineDouble
- Double underlineWDUnderlineThick
- Thick underlineWDUnderlineDotted
- Dotted underlineWDUnderlineDashed
- Dashed underlineWDUnderlineWave
- Wave underlineBreakTypePage
- Page breakBreakTypeColumn
- Column breakBreakTypeText
- Text wrapping breakWDColorIndexAuto
- Automatic colorWDColorIndexBlack
- BlackWDColorIndexBlue
- BlueWDColorIndexBrightGreen
- Bright greenWDColorIndexDarkBlue
- Dark blueWDColorIndexDarkRed
- Dark redWDColorIndexDarkYellow
- Dark yellowWDColorIndexGray25
- 25% grayWDColorIndexGray50
- 50% grayWDColorIndexGreen
- GreenWDColorIndexPink
- PinkWDColorIndexRed
- RedWDColorIndexTeal
- TealWDColorIndexTurquoise
- TurquoiseWDColorIndexViolet
- VioletWDColorIndexWhite
- WhiteWDColorIndexYellow
- YellowWDSectionContinuous
- Continuous sectionWDSectionNewColumn
- New columnWDSectionNewPage
- New page (default)WDSectionEvenPage
- Even pageWDSectionOddPage
- Odd pageWDOrientPortrait
- Portrait orientation (default)WDOrientLandscape
- Landscape orientationHeaderTypeDefault
- Default header (odd pages)HeaderTypeFirst
- First page headerHeaderTypeEven
- Even page headerFooterTypeDefault
- Default footer (odd pages)FooterTypeFirst
- First page footerFooterTypeEven
- Even page footerTableBorderTop
- Top borderTableBorderLeft
- Left borderTableBorderBottom
- Bottom borderTableBorderRight
- Right borderTableBorderInsideH
- Inside horizontal bordersTableBorderInsideV
- Inside vertical bordersEMUs (English Metric Units):
EMUsPerInch = 914400
- EMUs in one inchEMUsPerCm = 360000
- EMUs in one centimeterEMUsPerPoint = 12700
- EMUs in one pointTwips (Twentieth of a point):
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 | 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% ๐ฏ
โ
Server-side document generation
โ
Microservices architecture
โ
High-performance scenarios
โ
Production deployments
โ
Documents with tables, images, and lists
โ
Automated report generation
โ
Go ecosystem integration
โ
Charts and SmartArt required
โ
Mail merge functionality
โ
Track changes needed
โ
Python ecosystem integration
โ
Rapid prototyping
For detailed API documentation, see:
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).
Contributions are welcome! Please feel free to submit a Pull Request.
# 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 .
We welcome contributions in these areas:
This project is licensed under the MIT License - see the LICENSE file for details.
Made with โค๏ธ for the Go community
Go-DOCX - Production-ready Word document generation for Go