# Export Data to Excel in OutSystems (RecordListToExcel Guide)

- Tool: OutSystems
- Difficulty: Beginner
- Time required: 15-20 min
- Compatibility: OutSystems 11 and ODC
- Last updated: March 2026

## TL;DR

Call RecordListToExcel (Logic tab → System → ExcelUtils) with your record list to get a Binary Data Excel file, then pass it to the Download action with filename and MimeType 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'. Both actions are built into OutSystems — no Forge component required for basic Excel export.

## Excel Export with RecordListToExcel

Exporting data to Excel is one of the most common requests in business applications. OutSystems includes RecordListToExcel as a built-in system action that converts any record list to an .xlsx file in one call. This tutorial covers the complete pattern from clicking Export to downloading the file, including column customization and large dataset considerations.

## Before you start

- A Reactive Web App with at least one entity (e.g., Employee with FullName, Email, Department)
- Service Studio open with the Logic tab visible
- Basic familiarity with Server Actions and calling them from Client Actions

## Step-by-step guide

### 1. Create the Export Server Action

Logic tab → Server Actions → right-click → 'Add Server Action'. Name it 'ExportEmployeesToExcel'.

The action needs no input parameters for a full export, or add filter inputs (e.g., DepartmentId, DateFrom) if you want a filtered export.

Action flow:
Start
  → GetAllEmployees (Aggregate — fetch the data to export)
  → RecordListToExcel
  → Download
  → End

First, set up the Aggregate: drag Aggregate from the Toolbox into the flow. Double-click to configure → drag Employee entity into Sources. Set Max Records to 10000 (or your expected max — see performance notes below). Close the Aggregate editor.

Note: RecordListToExcel is in Logic tab → System → ExcelUtils. Drag it into the flow after the Aggregate.

**Expected result:** ExportEmployeesToExcel Server Action is created with Aggregate and RecordListToExcel nodes.

### 2. Configure the RecordListToExcel action

Select the RecordListToExcel node in the action flow. In the Properties Panel, set the input parameters:

- RecordList: GetAllEmployees.List (your aggregate's output list)

That is the only required input. RecordListToExcel automatically:
- Uses attribute names as column headers
- Includes all attributes in the record list
- Generates an .xlsx format file

Output parameter:
- File: Binary Data (the generated Excel file content)

To customize column headers, you need a Structure. Create a Structure in Data tab → Structures → Add Structure with only the attributes you want exported, then fetch into that structure in the Aggregate. Column headers in the Excel file will match the Structure attribute names.

```
/* RecordListToExcel parameters */
RecordList: GetAllEmployees.List

/* Output */
File: Binary Data (access as RecordListToExcel.File)

/* For custom columns, create a Structure */
/* Data tab → Structures → Add Structure 'EmployeeExportRow' */
/* Add attributes: FullName (Text), Email (Text), Department (Text) */
/* Fetch into this structure in the aggregate using calculated attributes */
```

**Expected result:** RecordListToExcel.File contains the Excel binary data after this node executes.

### 3. Add the Download action to serve the file

After RecordListToExcel in the action flow, drag the Download action from Logic tab → System into the flow.

Set the Download action parameters:
- FileContent: RecordListToExcel.File
- FileName: 'Employees_' + FormatDate(CurrDate(), 'yyyyMMdd') + '.xlsx'
- MimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

The complete action flow:
Start → GetAllEmployees (Aggregate) → RecordListToExcel (RecordList=GetAllEmployees.List) → Download (FileContent=RecordListToExcel.File, FileName='Employees.xlsx', MimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') → End

```
/* Download action parameters */
FileContent: RecordListToExcel.File
FileName:    "Employees_" + FormatDate(CurrDate(), "yyyyMMdd") + ".xlsx"
MimeType:    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

/* Full flow summary */
Start
  --> Aggregate: GetAllEmployees (Max Records: 10000)
  --> RecordListToExcel: RecordList = GetAllEmployees.List
  --> Download: FileContent = RecordListToExcel.File
                FileName    = "Employees_" + FormatDate(CurrDate(), "yyyyMMdd") + ".xlsx"
                MimeType    = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  --> End
```

**Expected result:** The Download action terminates the server response with the Excel file. The browser receives the file and shows a download dialog.

### 4. Add an Export button to the screen

In the Screen Editor, add a Button widget to the screen. Set its Label to 'Export to Excel'. Right-click → 'Add OnClick Client Action'.

In the Client Action flow:
Start → ExportEmployeesToExcel (Server Action) → End

The Download action inside ExportEmployeesToExcel terminates the response — no additional navigation is needed in the Client Action after the call.

For filtered exports, add input parameters to ExportEmployeesToExcel (e.g., DepartmentId) and map the currently selected filter values from the screen when calling the Server Action:
Start → ExportEmployeesToExcel (DepartmentId = SelectedDepartmentId) → End

**Expected result:** Clicking the 'Export to Excel' button downloads an Excel file with all employee records. The file opens in Excel showing rows with attribute names as headers.

### 5. Customize columns with a Structure

By default RecordListToExcel exports all attributes from the aggregate. To control which columns appear (and in what order), define a Structure with only the desired attributes.

Data tab → Structures → right-click → Add Structure. Name it 'EmployeeExportRow'. Add attributes:
- FullName: Text
- Department: Text
- Email: Text
- HireDate: Date

In the GetAllEmployees Aggregate, add calculated attributes matching the Structure:
- Click 'New Attribute' in the Aggregate editor
- Name: FullName, Value: Employee.FirstName + ' ' + Employee.LastName
- Name: Department, Value: Department.Name (requires joining the Department entity)
- etc.

Then map the aggregate list to the Structure list before passing to RecordListToExcel. Use a For Each + Assign pattern or use a List Append approach to build the export list.

```
/* Structure: EmployeeExportRow
   Attributes: FullName (Text), Department (Text), Email (Text), HireDate (Date) */

/* In Server Action - build export list */
Assign: ExportList = GetAllEmployeesWithDept.List
  /* GetAllEmployeesWithDept aggregate joins Employee + Department */
  /* and has calculated attributes matching EmployeeExportRow */

/* RecordListToExcel reads the structure attribute names as column headers */
RecordListToExcel: RecordList = ExportList
```

**Expected result:** The exported Excel file shows only the four specified columns in the order defined by the Structure, with clean attribute names as headers.

## Complete code example

File: `ExportToExcel_ServerAction.txt`

```outsystems-pseudocode
/* ============================================================
   SERVER ACTION: ExportEmployeesToExcel
   Input:  DepartmentId (Department Identifier) - optional filter
   Output: none (Download action terminates response)
   ============================================================ */
Start
  --> Aggregate: GetEmployeesForExport
        Source: Employee join Department (Only With)
        Filter: If(DepartmentId = NullIdentifier(), True,
                   Employee.DepartmentId = DepartmentId)
        Calculated Attributes:
          FullName   = Employee.FirstName + " " + Employee.LastName
          Department = Department.Name
          Email      = Employee.Email
          HireDate   = Employee.HireDate
        Sort: Employee.LastName Ascending
        Max Records: 50000

  --> If: GetEmployeesForExport.List.Empty
       [True] --> Raise UserException: "NoData"
                    Message = "No employees match the selected filter."

  --> RecordListToExcel:
        RecordList: GetEmployeesForExport.List

  --> Download:
        FileContent: RecordListToExcel.File
        FileName:    "Employees_" + FormatDate(CurrDate(), "yyyyMMdd") + ".xlsx"
        MimeType:    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

  --> End

Exception Handler (User Exception: NoData)
  --> (bubble up to Client Action for user message)
  --> End

/* ============================================================
   CLIENT ACTION: ButtonExportOnClick
   ============================================================ */
Start
  --> ExportEmployeesToExcel: DepartmentId = SelectedDepartmentId
  --> End

Exception Handler (User Exception: NoData)
  --> Message: ExceptionMessage (Warning)
  --> End
```

## Common mistakes

- **Calling the Export Server Action directly from another Server Action and expecting the download to reach the browser** — undefined Fix: The Download action must be triggered from a Client Action → Server Action chain that originated from a user interaction. Server-to-server calls that include Download do not reach the browser. Always wire Export to a button OnClick Client Action.
- **Not setting Max Records on the source Aggregate, causing a full table scan** — undefined Fix: RecordListToExcel loads the entire list into memory. Without Max Records, exporting a 500,000-row table crashes the server with an out-of-memory error. Set a practical Max Records limit (e.g., 50000) and document it. For larger exports, use a scheduled export to file pattern.
- **Using 'application/xls' as the MimeType for .xlsx files** — undefined Fix: The correct MIME type for modern Excel (.xlsx) files is 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'. Using 'application/xls' causes Excel to show 'The file format does not match the extension' warning on open.
- **Expecting column headers to be human-readable when attribute names are camelCase database identifiers** — undefined Fix: RecordListToExcel uses attribute names directly as headers. Create a Structure with readable names (FullName not 'empfullnm', HireDate not 'dtehire') to control the header row content.

## Best practices

- Always set Max Records on the Aggregate feeding RecordListToExcel — exporting without a limit on a large table can cause out-of-memory errors on the server.
- Raise a User Exception and show a message when the filtered result is empty, rather than downloading a blank Excel file.
- Use a dynamic filename with FormatDate(CurrDate(), 'yyyyMMdd') so users can distinguish multiple exports by date.
- For exports over 50,000 rows, consider generating the file asynchronously with a Timer and providing a download link instead of blocking the HTTP request.
- Join related entities in the Aggregate (Employee + Department) rather than running multiple queries — keep the export logic in a single well-structured Aggregate.
- Always use the correct MIME type for .xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'. Using 'application/xls' or 'application/excel' may cause Excel to show format warnings.

## Frequently asked questions

### Can I format cells in the exported Excel file (bold headers, colors)?

RecordListToExcel generates a plain .xlsx file with no cell formatting — just data in rows. For styled exports (bold headers, colored rows, merged cells), use the OutSystems Excel Utilities or OfficeUtils Forge components, or generate the file via a third-party library exposed through an Integration Studio extension (O11) or External Library (ODC).

### How do I export multiple sheets in one Excel file?

RecordListToExcel only creates single-sheet files. For multi-sheet exports, use the OfficeUtils Forge component or the XlsxUtils component from the OutSystems Forge marketplace, which provides AddSheet and AddRow actions for building complex workbooks.

### Does RecordListToExcel work in ODC?

Yes. RecordListToExcel and the Download action are built-in system actions available in both O11 and ODC. The action signature and MIME type are identical. Access it in ODC Studio via Logic tab → System → ExcelUtils.

### How do I export dates in a specific format in the Excel file?

RecordListToExcel exports Date values as Excel date serial numbers, which Excel displays using its own date formatting. To control the format, convert the Date to Text using FormatDate() in a calculated attribute of your Aggregate (e.g., HireDateFormatted = FormatDate(Employee.HireDate, 'dd/MM/yyyy')). The column then exports as Text with your format, which prevents Excel from auto-reformatting it.

---

Source: https://www.rapidevelopers.com/outsystems-tutorial/outsystems-export-excel
© RapidDev — https://www.rapidevelopers.com/outsystems-tutorial/outsystems-export-excel
