excelTemplate
Merges Salesforce data into an Excel template file and sends the result to the Excel taskpane. This is the component that produces the downloadable workbook.
Package: Keelstone-Samples
Component name: c:excelTemplate
Flow target: lightning__FlowScreen
Flow input properties
| Property | Type | Required | Description |
|---|---|---|---|
templateId | String | Yes | ContentDocumentId of the Excel template file in Salesforce Files |
mergeData | String | Yes | JSON string of data to merge into the template (see Template Variables) |
linkedEntityId | String | Yes | Record ID to attach the output file to (e.g., an Account Id) |
filename | String | Yes | Output filename, e.g. "Acme Corp - Report.xlsx" |
What it does
When the screen renders, the component runs automatically — no user action required:
1. Fetch template bytes → ExcelTemplateController.getTemplate(templateId)
2. Merge data → POST /api/docs/generate { templateBase64, data }
3. Signal Excel → fires KEELSTONE_INSERT event (see Events Reference)
4. Save to SF Files → ExcelTemplateController.saveDocument(base64, filename, linkedEntityId)
After step 3, the Excel taskpane receives the merged workbook and inserts it. After step 4, the file is saved to Salesforce Files and linked to the record you specified.
Status display
The component shows inline status as it works:
| State | Display |
|---|---|
| Processing | Spinner + current step label |
| Done | Checkmark + "Document ready" |
| Error | Error message with detail |
Events fired
See KEELSTONE_INSERT for the full event reference.
The component fires three signals for maximum compatibility with how Lightning Out renders the component:
// 1. postMessage — works when Lightning Out renders in an iframe
window.parent.postMessage(payload, '*');
// 2. Custom event on component — works for event listeners on the component itself
this.dispatchEvent(new CustomEvent('keelstoneinsert', {
detail: payload,
bubbles: true,
composed: true
}));
// 3. Custom event on document — works when Lightning Out renders inline
document.dispatchEvent(new CustomEvent('keelstoneinsert', {
detail: payload,
bubbles: true
}));
All three carry the same payload:
{
type: 'KEELSTONE_INSERT',
base64: '<base64-encoded xlsx>',
filename: 'Acme Corp - Report.xlsx'
}
Using in a flow
Place this component on the screen after accountSearch (or any component that produces mergeData):
<screen>
<name>Doc_Gen_Screen</name>
<fields>
<componentType>c:excelTemplate</componentType>
<inputParameters>
<name>templateId</name>
<value>
<elementReference>myTemplateIdVariable</elementReference>
</value>
</inputParameters>
<inputParameters>
<name>mergeData</name>
<value>
<elementReference>mergeData</elementReference>
</value>
</inputParameters>
<inputParameters>
<name>linkedEntityId</name>
<value>
<elementReference>selectedAccountId</elementReference>
</value>
</inputParameters>
<inputParameters>
<name>filename</name>
<value>
<elementReference>outputFilename</elementReference>
</value>
</inputParameters>
</fields>
</screen>
Finding the templateId
The templateId is the ContentDocumentId of an .xlsx file in Salesforce Files. The Keelstone Samples post-install handler creates a starter template in the "Keelstone Templates" content library automatically.
To find the ID:
ContentDocument doc = [
SELECT Id FROM ContentDocument
WHERE Title = 'Account Report Template'
LIMIT 1
];
String templateId = doc.Id;
For production flows, store the ContentDocumentId in a Custom Metadata record or Flow variable so it can be configured without code changes.
Error handling
| Scenario | Behavior |
|---|---|
templateId not set or is placeholder | Error state: "Template not configured." |
| Template file not found in SF Files | Apex exception → error state |
| Server merge fails (5xx) | Error state with server message |
saveDocument fails | Error state (Excel insert still succeeded) |