# Build and Upload an XLSX Template

Use this page when you want workbook-native design in Microsoft Excel and a generated `.xlsx` output from Salesforce data.

An XLSX template is built in Excel, then uploaded to S-Docs for generation.

Use XLSX when spreadsheet structure matters more than HTML layout, Word editing, or slide design.

{% hint style="info" %}
Pick **XLSX** when you need spreadsheet-first output, Excel design tools, and bracket-based S-Docs syntax.

Pick [Microsoft Word (DOCX)](/sdocs/template-architecture/document-formats/docx-s-docs.md) when users need document-style output in Word.
{% endhint %}

### Before you start

Make sure you have:

* a new S-Docs template with format set to **XLSX**
* the correct **Related To Type** for your base record
* an `.xlsx` file you can edit in Microsoft Excel
* the right upload path for your S-Docs version

XLSX templates do not support related lists.

If you need repeating row output, use a format that supports related lists instead.

XLSX upload behavior depends on whether **Enable New Microsoft Template Upload** is checked.

* **Checked** — use the newer Microsoft template upload flow. This applies to Summer 2025 (`v10.0`) and later. These templates generate through **S-Docs LWCs** or the **SDK**.
* **Not checked** — use the legacy upload flow in **Template Editor**. These templates generate through the legacy custom S-Docs button.

{% hint style="warning" %}
The upload path and generation path must match.

A valid XLSX file can still fail if it was uploaded in one mode and generated in the other.
{% endhint %}

### Build and upload an XLSX template

{% stepper %}
{% step %}

### Create the template record

Create a new S-Docs template.

Set **Template Format** to `XLSX`.
{% endstep %}

{% step %}

### Build the workbook in Microsoft Excel

Create the workbook layout in Excel exactly as you want it to appear.

Use normal Excel tools for worksheets, tables, formulas, number formats, and cell styling.
{% endstep %}

{% step %}

### Add S-Docs merge syntax

Insert merge fields, render blocks, and query output using bracketed Microsoft template syntax.

{% code title="xlsx-basic-syntax.txt" %}

```plaintext
[{{!Opportunity.Name}}]

[<!--RENDER='{{!Opportunity.StageName}}' == 'Closed Won' -->]
  Closed-won summary
[<!--ENDRENDER-->]
```

{% endcode %}
{% endstep %}

{% step %}

### Add merge fields, logic, and formulas

Place merge fields where single values should appear.

Add conditional logic where worksheet content should show only for certain records.

Keep workbook formulas and formatting in Excel.
{% endstep %}

{% step %}

### Upload the `.xlsx` file

If **Enable New Microsoft Template Upload** is checked, upload the file through the newer Microsoft template upload flow.

If it is not checked, upload the file in **Template Editor**.
{% endstep %}

{% step %}

### Generate and test with real data

Test the template with real Salesforce records.

Verify merge fields, formulas, row growth, number formatting, and conditional sections before rollout.
{% endstep %}
{% endstepper %}

### Core XLSX syntax patterns

#### Merge fields

Wrap merge fields in square brackets.

{% code title="xlsx-merge-fields.txt" %}

```plaintext
[{{!Account.Name}}]
[{{!Opportunity.Amount #,###.00}}]
```

{% endcode %}

Use this same pattern for standard field paths too.

{% code title="xlsx-merge-field-paths.txt" %}

```plaintext
[{{!Opportunity.Name}}]
[{{!Opportunity.Account.Name}}]
[{{!Contact.Email}}]
```

{% endcode %}

#### Conditional logic

Wrap both `RENDER` tags in square brackets.

{% code title="xlsx-render-block.txt" %}

```plaintext
[<!--RENDER='{{!Contact.Phone}}' != 'NULL' -->]
  Phone: [{{!Contact.Phone}}]
[<!--ENDRENDER-->]
```

{% endcode %}

Keep merge fields inside rendered content in square brackets too.

Use the same operators you use in standard conditional logic.

{% code title="xlsx-render-operators.txt" %}

```plaintext
[<!--RENDER=( ('{{!Account.BillingState}}' == 'CA' || '{{!Account.BillingState}}' == 'NV')
             && '{{!Account.Active_Contract__c}}' == 'True' ) -->]
  Regional account with active contract
[<!--ENDRENDER-->]
```

{% endcode %}

Nested render blocks work too.

{% code title="xlsx-render-nested.txt" %}

```plaintext
[<!--RENDER='{{!Opportunity.StageName}}' == 'Closed Won' -->]
  Congratulations on your purchase.
  [<!--RENDER1='{{!Opportunity.Install_Date__c}}' != 'NULL' -->]
    Installation is scheduled for [{{!Opportunity.Install_Date__c}}].
  [<!--ENDRENDER1-->]
[<!--ENDRENDER-->]
```

{% endcode %}

#### Named queries

Wrap both the query block and output fields in square brackets.

{% code title="xlsx-named-query.txt" %}

```plaintext
[{{!<lineitemsSOQL>
  <class>none</class>
  <queryname>TopItem</queryname>
  <soql>
    SELECT Name, TotalPrice
    FROM OpportunityLineItem
    WHERE OpportunityId = '{{!Opportunity.Id}}'
    ORDER BY TotalPrice DESC
    LIMIT 1
  </soql>
</lineitemsSOQL>}}]

[{{!TopItem.Name}}]
[{{!TopItem.TotalPrice #,###.00}}]
```

{% endcode %}

If you need a filtered or offset result, keep the same square-bracket wrapping.

{% code title="xlsx-named-query-filter-offset.txt" %}

```plaintext
[{{!<lineitemsSOQL>
  <class>none</class>
  <queryname>FilteredItems</queryname>
  <soql>
    SELECT Name, TotalPrice
    FROM OpportunityLineItem
    WHERE OpportunityId = '{{!Opportunity.Id}}'
    ORDER BY TotalPrice DESC
  </soql>
  <filter id="1">TotalPrice >= 1000</filter>
</lineitemsSOQL>}}]

[{{!FilteredItems.Name filter="1" offset="1"}}]
[{{!FilteredItems.TotalPrice filter="1" offset="1" #,###.00}}]
```

{% endcode %}

{% hint style="info" %}
For XLSX syntax, three rules matter most:

* merge fields use square brackets
* named query output fields use square brackets
* `RENDER` blocks use square brackets
  {% endhint %}

### Common syntax mistakes

* **Field prints as text:** add square brackets around the merge field
* **Conditional block does not run:** wrap both opening and closing `RENDER` tags in square brackets
* **Named query returns nothing:** confirm the output field is wrapped in square brackets and included in `SELECT`
* **Related list output is expected:** XLSX does not support related lists
* **Formatting shifts after edits:** re-upload the workbook and retest with real data

### What XLSX supports

XLSX templates support these common S-Docs capabilities:

* merge fields
* conditional logic
* named queries
* Excel-native formatting and formulas
* generation through **S-Docs LWCs** and the **SDK** when uploaded through the newer Microsoft template upload flow

### Important XLSX limitations

Keep these XLSX-specific rules in mind:

* Live Edit is not supported.
* Template headers and footers are not supported.
* Component templates are not supported.
* S-Sign is not supported.
* Related lists are not supported.
* Leading zeros and strict number formats may need explicit Excel formatting.

{% hint style="warning" %}
If you need repeating row output, choose a format that supports related lists instead of XLSX.
{% endhint %}

### Next reads by goal

* Need an XLSX overview? Read [Excel (XLSX)](/sdocs/template-architecture/document-formats/xlsx-format.md).
* Need XLSX setup considerations? Read [XLSX Rendering Considerations](/sdocs/template-architecture/document-formats/xlsx-format/xlsx-rendering-considerations.md).
* Need merge field syntax? Read [Merge Fields With Microsoft Templates (DOCX, PPTX, XLSX)](/sdocs/template-architecture/inserting-merge-fields/merge-fields-with-microsoft-templates-docx-pptx-xlsx.md).
* Need conditional syntax? Read [Quick Setup: Conditional Logic With Microsoft Templates (DOCX, PPTX, XLSX)](/sdocs/advanced-template-logic/conditional-logic/quick-setup-conditional-logic-with-microsoft-templates-docx-pptx-xlsx.md).
* Need named query patterns? Read [How To: Advanced Data Retrieval with Named Queries](/sdocs/advanced-template-logic/named-query/how-to-advanced-data-retrieval-with-named-queries.md).
* Need formatting help for leading zeros? Read [Preserve leading zeros in Excel output](/sdocs/template-architecture/document-formats/other-formats/leading-zeroes-for-xls-templates.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.sdocs.com/sdocs/template-architecture/document-formats/xlsx-format/build-and-upload-an-xlsx-template.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
