DEV Community

Cover image for Discover OfficeForge: Enhance Microsoft Office with Open-Source Automation
SiliconCatalyst
SiliconCatalyst

Posted on

Discover OfficeForge: Enhance Microsoft Office with Open-Source Automation

For developers automating administrative work inside the Microsoft Office ecosystem, generating contracts from DOCX templates, producing XLSX reports, or assembling PPTX decks, there's usually a messy gap between where the data lives and where the final document needs to be. OfficeForge closes that gap with an open-source, zero-dependency tool that pushes structured data straight into polished Office files while keeping the original formatting without any parameters.

Part I: For Any Developer in Any Language

A Lightweight CLI That Works From Any Language

OfficeForge comes with a CLI tool that lets you automate Microsoft Office documents without touching Go. Whether you code in Python, Node.js, PHP, or Bash, you can generate Word files, fill templates, or batch-process documents, while keeping the formatting intact and without juggling parameters.

Getting started is simple: download the binary for your Windows architecture from the Releases page and you're ready to go.

For example, replace a single keyword in a template:

officeforge docx-single --input template.docx --output output.docx --key "{{NAME}}" --value "John Doe"
Enter fullscreen mode Exit fullscreen mode

Or generate multiple documents from CSV/JSON:

officeforge docx-batch --input template.docx --output ./contracts --data employees.csv
Enter fullscreen mode Exit fullscreen mode

Flexible Naming Patterns

Control how your generated documents are named using patterns:

# Sequential numbering
officeforge docx-batch --input template.docx --output ./output --data employees.csv --pattern "contract_%03d.docx"
# Creates: contract_001.docx, contract_002.docx, contract_003.docx

# Data-based naming (CSV must have NAME column)
officeforge docx-batch --input template.docx --output ./output --data employees.csv --pattern "{NAME}_contract.docx"
# Creates: Alice_contract.docx, Bob_contract.docx

# Multiple fields (CSV has ID and COMPANY columns)
officeforge docx-batch --input template.docx --output ./output --data clients.csv --pattern "{COMPANY}_{ID}_agreement.docx"
# Creates: Acme_001_agreement.docx, TechCorp_002_agreement.docx

# Combine data and index
officeforge docx-batch --input template.docx --output ./output --data employees.csv --pattern "{DEPARTMENT}_report_{INDEX}.docx"
# Creates: Engineering_report_1.docx, Sales_report_2.docx
Enter fullscreen mode Exit fullscreen mode

With zero dependencies, blazing speed, and straightforward commands, this CLI bridges the gap between your data and document automation, letting you focus on logic. It's a portable, language-agnostic way to automate administrative tasks efficiently.

Because OfficeForge is a standalone binary with zero dependencies, you can call it from any language that can run system commands. Here are examples using Node.js, Python, and PHP to run the same docx-batch operation.

Node.js Example (using child_process)
import { exec } from "node:child_process";
import { promisify } from "node:util";

const execAsync = promisify(exec);

(async () => {
  try {
    const { stdout, stderr } = await execAsync(
      `officeforge docx-batch --input template.docx --output ./contracts --data employees.csv --pattern "{EMPLOYEE_NAME} Contract.docx`
    );

    if (stderr) console.error("CLI stderr:", stderr);
    console.log("Success:", stdout);
  } catch (err) {
    console.error("Error:", err);
  }
})();

Enter fullscreen mode Exit fullscreen mode
Python Example (using subprocess)
import subprocess

cmd = [
    "officeforge",
    "docx-batch",
    "--input", "template.docx",
    "--output", "./contracts",
    "--data", "employees.csv",
    "--pattern", "{EMPLOYEE_NAME} Contract.docx"
]

result = subprocess.run(cmd, capture_output=True, text=True)

if result.returncode != 0:
    print("Error:", result.stderr)
else:
    print("Success:", result.stdout)
Enter fullscreen mode Exit fullscreen mode

PHP Example (using exec)

<?php

$cmd = 'officeforge docx-batch --input template.docx --output ./contracts --data employees.csv --pattern "{EMPLOYEE_NAME} Contract.docx"';

exec($cmd . " 2>&1", $output, $returnCode);

if ($returnCode !== 0) {
    echo "Error:\n";
    echo implode("\n", $output);
} else {
    echo "Success:\n";
    echo implode("\n", $output);
}

?>
Enter fullscreen mode Exit fullscreen mode

Whether you're working in Node.js, Python, PHP, Bash, Go, or anything else, OfficeForge’s CLI gives you a language-agnostic way to automate DOCX generation at high speeds.

Part II: For Go Developers Who Want Native Integration

Integrate OfficeForge Directly in Your Go Code

For Go developers, OfficeForge isn't just a CLI, it's a fully programmatic library. You can embed it directly in your apps to fill templates, generate batches, and keep full control over your Microsoft Word documents.

Installation

Grab the latest version:

go get github.com/siliconcatalyst/officeforge@latest
Enter fullscreen mode Exit fullscreen mode

Or install the CLI for mixed usage:

go install github.com/siliconcatalyst/officeforge/cmd/officeforge@latest
Enter fullscreen mode Exit fullscreen mode

Single Keyword Replacement

Quickly replace one keyword:

import "github.com/siliconcatalyst/officeforge/docx"

err := docx.ProcessDocxSingle("template.docx", "output.docx", "{{NAME}}", "John Doe")
if err != nil {
    log.Fatal(err)
}
Enter fullscreen mode Exit fullscreen mode

Perfect for one-off documents or testing replacements.

Multiple Replacements

Fill multiple fields at once:

import "github.com/siliconcatalyst/officeforge/docx"

replacements := map[string]string{
    "{{NAME}}":  "John Doe",
    "{{EMAIL}}": "john@example.com",
    "{{DATE}}":  "2025-12-07",
}

err := docx.ProcessDocxMulti("template.docx", "output.docx", replacements)
if err != nil {
    log.Fatal(err)
}
Enter fullscreen mode Exit fullscreen mode

Ideal for contracts, letters, or forms where several fields need updating.

Batch Document Generation

Generate dozens—or thousands—of documents in one go:

import "github.com/siliconcatalyst/officeforge/docx"

records := []map[string]string{
    {"NAME": "Alice", "EMAIL": "alice@example.com"},
    {"NAME": "Bob", "EMAIL": "bob@example.com"},
}

// Sequential numbering
err := docx.ProcessDocxMultipleRecords("template.docx", "./output", records, "contract_%03d.docx")
// Creates: contract_001.docx, contract_002.docx

// Data-based naming using fields from records
err := docx.ProcessDocxMultipleRecords("template.docx", "./output", records, "{NAME}_contract.docx")
// Creates: Alice_contract.docx, Bob_contract.docx

// Multiple fields
err := docx.ProcessDocxMultipleRecords("template.docx", "./output", records, "{NAME}_{EMAIL}.docx")
// Creates: Alice_alice@example.com.docx, Bob_bob@example.com.docx

// Combine data and index
err := docx.ProcessDocxMultipleRecords("template.docx", "./output", records, "employee_{INDEX}_{NAME}.docx")
// Creates: employee_1_Alice.docx, employee_2_Bob.docx
Enter fullscreen mode Exit fullscreen mode

For advanced naming logic, use ProcessDocxMultipleRecordsWithNames with a custom nameFunc of your own creation:

import "github.com/siliconcatalyst/officeforge/docx"

nameFunc := func(record map[string]string, index int) string {
    // Custom logic based on data
    if record["PRIORITY"] == "high" {
        return fmt.Sprintf("urgent_%s_%d.docx", record["NAME"], index)
    }
    return fmt.Sprintf("standard_%s_%d.docx", record["NAME"], index)
}

err := docx.ProcessDocxMultipleRecordsWithNames("template.docx", "./output", records, nameFunc)
// Creates: urgent_Alice_1.docx, standard_Bob_2.docx (based on PRIORITY field)
Enter fullscreen mode Exit fullscreen mode

Important Note: In your template DOCX file, the placeholders like {{NAME}} or CLIENT_EMAIL should match the map keys exactly: {"{{NAME}}": "Alice"} or use the field names directly {"CLIENT_EMAIL": "alice@acmecorp.com"} depending on your template structure.

Why You Should Consider Using OfficeForge

  • Pure Go, zero external dependencies
  • Fast, even with large batches
  • Full programmatic control
  • Intelligent naming patterns built-in
  • Works seamlessly with existing Go projects

Tips

  • Use clear, unique keywords like {{CLIENT_NAME}} or [[EMAIL]]
  • Test templates with a single record first
  • Keep keywords visible in the document for easy verification
  • Pattern placeholders {FIELD} must match your CSV/JSON column names or record keys
  • Use {INDEX} in patterns to include the record number
  • Invalid filename characters in data are automatically sanitized

OfficeForge makes Microsoft Office automation effortless, whether you’re calling it from a CLI in any language or embedding it directly in a Go application. Fast, reliable, and zero-dependency, it bridges your data with DOCX documents so you can focus on building solutions for your team.

Note: As of December 7, 2025, only DOCX manipulation and generation are fully supported. PowerPoint (PPTX) and Excel (XLSX) support are currently in development.

Get started today and see how OfficeForge can simplify document automation in your projects:

Contributions, feedback, and questions are always welcome!

Top comments (0)