Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Complete Examples

This document provides complete, working examples of GXL templates with sample data and expected output.


Example 1: Simple Invoice

Template (invoice.gxl)

<Book>
  <Sheet name="Invoice">
    <Grid>
    | Invoice #{{invoiceNumber}} |
    | Date: {{date}} |
    | Customer: {{customer.name}} |
    </Grid>
    
    <Grid>
    | | | |
    </Grid>
    
    <Grid>
    | Item | Quantity | Price | Total |
    </Grid>
    
    <For src="items">
      <Grid>
      | {{name}} | {{quantity}} | ${{price}} | =B{{_startRow}}*C{{_startRow}} |
      </Grid>
    </For>
    
    <Grid>
    | | | **Grand Total:** | =SUM(D7:D{{_endRow}}) |
    </Grid>
  </Sheet>
</Book>

Data Context

{
  "invoiceNumber": "INV-2024-001",
  "date": "2024-01-15",
  "customer": {
    "name": "Acme Corp"
  },
  "items": [
    {"name": "Consulting", "quantity": 10, "price": 150.00},
    {"name": "Development", "quantity": 40, "price": 200.00}
  ]
}

Expected Output

Sheet: Invoice

ABCD
1Invoice #INV-2024-001
2Date: 2024-01-15
3Customer: Acme Corp
4
5ItemQuantityPriceTotal
6Consulting10$150.00=B6*C6 → 1500
7Development40$200.00=B7*C7 → 8000
8Grand Total:=SUM(D6:D7) → 9500

Example 2: Sales Report with Multiple Sheets

Template (sales-report.gxl)

<Book>
  <Sheet name="Summary">
    <Grid>
    | **Sales Report** |
    | Period: {{period}} |
    </Grid>
    
    <Grid>
    | | |
    </Grid>
    
    <Grid>
    | Region | Total Sales |
    </Grid>
    
    <For src="regions">
      <Grid>
      | {{name}} | ${{totalSales}} |
      </Grid>
    </For>
  </Sheet>
  
  <Sheet name="Details">
    <For src="regions">
      <Grid>
      | **Region: {{name}}** |
      </Grid>
      
      <Grid>
      | Product | Units | Revenue |
      </Grid>
      
      <For src="products">
        <Grid>
        | {{name}} | {{units}} | ${{revenue}} |
        </Grid>
      </For>
      
      <Grid>
      | | |
      </Grid>
    </For>
  </Sheet>
</Book>

Data Context

{
  "period": "Q1 2024",
  "regions": [
    {
      "name": "North",
      "totalSales": 150000,
      "products": [
        {"name": "Widget A", "units": 1000, "revenue": 50000},
        {"name": "Widget B", "units": 2000, "revenue": 100000}
      ]
    },
    {
      "name": "South",
      "totalSales": 200000,
      "products": [
        {"name": "Widget A", "units": 1500, "revenue": 75000},
        {"name": "Widget C", "units": 2500, "revenue": 125000}
      ]
    }
  ]
}

Expected Output

Sheet: Summary

AB
1Sales Report
2Period: Q1 2024
3
4RegionTotal Sales
5North$150000
6South$200000

Sheet: Details

ABC
1Region: North
2ProductUnitsRevenue
3Widget A1000$50000
4Widget B2000$100000
5
6Region: South
7ProductUnitsRevenue
8Widget A1500$75000
9Widget C2500$125000
10

Template (directory.gxl)

<Book>
  <Sheet name="Employees">
    <Anchor cell="E1">
      <Image src="company-logo.png" width="100" height="50" />
    </Anchor>
    
    <Grid>
    | **Employee Directory** |
    | As of {{date}} |
    </Grid>
    
    <Grid>
    | | |
    </Grid>
    
    <Grid>
    | ID | Name | Department | Email |
    </Grid>
    
    <For src="employees">
      <Grid>
      | {{id}} | {{firstName}} {{lastName}} | {{department}} | {{email}} |
      </Grid>
    </For>
  </Sheet>
</Book>

Data Context

{
  "date": "2024-01-20",
  "employees": [
    {
      "id": "E001",
      "firstName": "Alice",
      "lastName": "Johnson",
      "department": "Engineering",
      "email": "alice@example.com"
    },
    {
      "id": "E002",
      "firstName": "Bob",
      "lastName": "Smith",
      "department": "Sales",
      "email": "bob@example.com"
    },
    {
      "id": "E003",
      "firstName": "Carol",
      "lastName": "Williams",
      "department": "Marketing",
      "email": "carol@example.com"
    }
  ]
}

Expected Output

Sheet: Employees

ABCDE
1Employee Directory[Logo]
2As of 2024-01-20
3
4IDNameDepartmentEmail
5E001Alice JohnsonEngineeringalice@example.com
6E002Bob SmithSalesbob@example.com
7E003Carol WilliamsMarketingcarol@example.com

Example 4: Nested Categories

Template (catalog.gxl)

<Book>
  <Sheet name="Catalog">
    <Grid>
    | **Product Catalog** |
    </Grid>
    
    <Grid>
    | | |
    </Grid>
    
    <For src="categories">
      <Grid>
      | **{{name}}** |
      </Grid>
      
      <Grid>
      | SKU | Product | Price |
      </Grid>
      
      <For src="products">
        <Grid>
        | {{sku}} | {{name}} | ${{price}} |
        </Grid>
      </For>
      
      <Grid>
      | | |
      </Grid>
    </For>
  </Sheet>
</Book>

Data Context

{
  "categories": [
    {
      "name": "Electronics",
      "products": [
        {"sku": "E001", "name": "Laptop", "price": 999.99},
        {"sku": "E002", "name": "Mouse", "price": 29.99}
      ]
    },
    {
      "name": "Books",
      "products": [
        {"sku": "B001", "name": "Programming Book", "price": 49.99},
        {"sku": "B002", "name": "Novel", "price": 19.99}
      ]
    }
  ]
}

Expected Output

Sheet: Catalog

ABC
1Product Catalog
2
3Electronics
4SKUProductPrice
5E001Laptop$999.99
6E002Mouse$29.99
7
8Books
9SKUProductPrice
10B001Programming Book$49.99
11B002Novel$19.99
12

Example 5: Loop Variables and Formulas

Template (inventory.gxl)

<Book>
  <Sheet name="Inventory">
    <Grid>
    | # | Product | Quantity | Unit Price | Value |
    </Grid>
    
    <For src="items">
      <Grid>
      | {{_number}} | {{product}} | {{quantity}} | ${{unitPrice}} | =C{{_startRow}}*D{{_startRow}} |
      </Grid>
    </For>
    
    <Grid>
    | | | | **Total:** | =SUM(E2:E{{_endRow}}) |
    </Grid>
  </Sheet>
</Book>

Data Context

{
  "items": [
    {"product": "Widget A", "quantity": 100, "unitPrice": 10.00},
    {"product": "Widget B", "quantity": 50, "unitPrice": 25.00},
    {"product": "Widget C", "quantity": 200, "unitPrice": 5.00}
  ]
}

Expected Output

Sheet: Inventory

ABCDE
1#ProductQuantityUnit PriceValue
21Widget A100$10.00=C2*D2 → 1000
32Widget B50$25.00=C3*D3 → 1250
43Widget C200$5.00=C4*D4 → 1000
5Total:=SUM(E2:E4) → 3250

Example 6: Cell Merging

Template (banner.gxl)

<Book>
  <Sheet name="Report">
    <Grid>
    | Annual Report 2024 | | | |
    </Grid>
    <Merge range="A1:D1" />
    
    <Grid>
    | | | | |
    </Grid>
    
    <Grid>
    | Quarter | Revenue | Expenses | Profit |
    </Grid>
    
    <For src="quarters">
      <Grid>
      | {{name}} | ${{revenue}} | ${{expenses}} | =B{{_startRow}}-C{{_startRow}} |
      </Grid>
    </For>
  </Sheet>
</Book>

Data Context

{
  "quarters": [
    {"name": "Q1", "revenue": 100000, "expenses": 70000},
    {"name": "Q2", "revenue": 120000, "expenses": 80000},
    {"name": "Q3", "revenue": 110000, "expenses": 75000},
    {"name": "Q4", "revenue": 130000, "expenses": 85000}
  ]
}

Expected Output

Sheet: Report

ABCD
1Annual Report 2024 (merged across A1:D1)
2
3QuarterRevenueExpensesProfit
4Q1$100000$70000=B4-C4 → 30000
5Q2$120000$80000=B5-C5 → 40000
6Q3$110000$75000=B6-C6 → 35000
7Q4$130000$85000=B7-C7 → 45000

Example 7: Multi-Sheet Workbook

Template (company-report.gxl)

<Book>
  <Sheet name="Overview">
    <Grid>
    | **{{companyName}}** |
    | {{year}} Annual Report |
    </Grid>
    
    <Grid>
    | | |
    </Grid>
    
    <Grid>
    | Total Revenue: | ${{totalRevenue}} |
    | Total Expenses: | ${{totalExpenses}} |
    | Net Profit: | ${{netProfit}} |
    </Grid>
  </Sheet>
  
  <Sheet name="Revenue">
    <Grid>
    | Month | Amount |
    </Grid>
    
    <For src="revenueByMonth">
      <Grid>
      | {{month}} | ${{amount}} |
      </Grid>
    </For>
  </Sheet>
  
  <Sheet name="Expenses">
    <Grid>
    | Category | Amount |
    </Grid>
    
    <For src="expensesByCategory">
      <Grid>
      | {{category}} | ${{amount}} |
      </Grid>
    </For>
  </Sheet>
</Book>

Data Context

{
  "companyName": "TechCorp Inc.",
  "year": 2024,
  "totalRevenue": 500000,
  "totalExpenses": 350000,
  "netProfit": 150000,
  "revenueByMonth": [
    {"month": "Jan", "amount": 40000},
    {"month": "Feb", "amount": 45000},
    {"month": "Mar", "amount": 50000}
  ],
  "expensesByCategory": [
    {"category": "Salaries", "amount": 200000},
    {"category": "Marketing", "amount": 80000},
    {"category": "Operations", "amount": 70000}
  ]
}

Expected Output

Sheet: Overview

AB
1TechCorp Inc.
22024 Annual Report
3
4Total Revenue:$500000
5Total Expenses:$350000
6Net Profit:$150000

Sheet: Revenue

AB
1MonthAmount
2Jan$40000
3Feb$45000
4Mar$50000

Sheet: Expenses

AB
1CategoryAmount
2Salaries$200000
3Marketing$80000
4Operations$70000

Best Practices Demonstrated

1. Clear Structure

  • Use blank rows (<Grid>| | |</Grid>) for spacing
  • Separate sections visually

2. Nested Data

  • Use nested loops for hierarchical data (Example 4)
  • Access nested properties with dot notation

3. Loop Variables

  • Use {{_number}} for row numbering (Example 5)
  • Use {{_startRow}} in formulas for dynamic references

4. Formulas

  • Reference cells with row variables: =B{{_startRow}}
  • Use SUM with {{_endRow}} for dynamic ranges

5. Anchoring

  • Position logos/images independently (Example 3)
  • Keep content flow unaffected

6. Multi-Sheet Reports

  • Organize related data across sheets (Examples 2, 7)
  • Summary sheet + detail sheets

Common Patterns

Pattern 1: Header + Table

<Grid>
| **{{title}}** |
</Grid>

<Grid>
| | |
</Grid>

<Grid>
| Column1 | Column2 |
</Grid>

<For src="data">
  <Grid>
  | {{field1}} | {{field2}} |
  </Grid>
</For>

Pattern 2: Grouped Data

<For src="groups">
  <Grid>
  | **{{groupName}}** |
  </Grid>
  
  <For src="items">
    <Grid>
    | - {{itemName}} |
    </Grid>
  </For>
  
  <Grid>
  | | |
  </Grid>
</For>

Pattern 3: Summary + Detail

<!-- Summary Sheet -->
<Sheet name="Summary">
  <Grid>
  | Category | Total |
  </Grid>
  <For src="categories">
    <Grid>
    | {{name}} | {{total}} |
    </Grid>
  </For>
</Sheet>

<!-- Detail Sheet -->
<Sheet name="Details">
  <For src="categories">
    <Grid>
    | **{{name}}** |
    </Grid>
    <For src="items">
      <Grid>
      | {{item}} | {{value}} |
      </Grid>
    </For>
  </For>
</Sheet>

Example 9: Cell Types and Type Hints

Template (cell-types.gxl)

<Book>
  <Sheet name="TypeDemo">
    <Grid>
    | Data Type | Auto-detected | With Type Hint | Description |
    </Grid>
    
    <Grid>
    | String | Hello World | {{ "Text" }} | Default text |
    | Number | {{ .price }} | {{ .quantity:int }} | Numeric values |
    | Float | {{ .discount }} | {{ .price:float }} | Decimal numbers |
    | Boolean | {{ .active }} | {{ .enabled:bool }} | TRUE/FALSE |
    | Formula | =SUM(B2:B5) | =AVERAGE(C2:C5) | Excel formulas |
    | Date | {{ .timestamp }} | {{ .created:date }} | Date values |
    </Grid>
    
    <Grid>
    | | | | |
    </Grid>
    
    <Grid>
    | **Mixed Content** | Price: {{ .price }} yen | Total: {{ .quantity }} items | Always string |
    </Grid>
    
    <Grid>
    | | | | |
    </Grid>
    
    <Grid>
    | **Force String Type** | {{ .zipCode:string }} | {{ .id:string }} | Preserve leading zeros |
    </Grid>
  </Sheet>
</Book>

Data Context

{
  "price": 1500.50,
  "quantity": 42,
  "discount": 0.15,
  "active": true,
  "enabled": false,
  "timestamp": "2025-11-03T15:30:00",
  "created": "2025-11-03",
  "zipCode": "00123",
  "id": "00456"
}

Expected Output

Sheet: TypeDemo

ABCD
Data TypeAuto-detectedWith Type HintDescription
StringHello WorldTextDefault text
Number1500.5 (number)42 (number)Numeric values
Float0.15 (number)1500.5 (number)Decimal numbers
BooleanTRUE (boolean)FALSE (boolean)TRUE/FALSE
Formula(calculated)(calculated)Excel formulas
Date2025-11-03T15:30:002025-11-03Date values
Mixed ContentPrice: 1500.5 yenTotal: 42 itemsAlways string
Force String Type00123 (text)00456 (text)Preserve leading zeros

Type Inference:

  • Numbers are stored as Excel numeric cells (can be used in formulas)
  • Formulas are evaluated by Excel
  • Booleans become TRUE/FALSE
  • Dates can be formatted with Excel date formats
  • Type hints override automatic detection

Available Type Hints:

  • :int, :float, :number - Numeric types
  • :bool, :boolean - Boolean types
  • :date - Date types
  • :string - Force text (preserves leading zeros)

Running Examples

Using goxcel CLI

# Render a template
goxcel generate -t invoice.gxl -d data.json -o output.xlsx

# With YAML data
goxcel generate -t invoice.gxl -d data.yaml -o output.xlsx

# Dry run (preview structure)
goxcel generate -t invoice.gxl -d data.json --dry-run

Using goxcel as Library (Go)

package main

import (
    "github.com/ryo-arima/goxcel/pkg/config"
    "github.com/ryo-arima/goxcel/pkg/controller"
)

func main() {
    cfg := config.NewBaseConfig()
    ctrl := controller.NewCommonController(cfg)
    
    err := ctrl.Generate(
        "invoice.gxl",
        "data.json",
        "output.xlsx",
        false, // dry-run
    )
    if err != nil {
        panic(err)
    }
}