Skip to main content
RapidDev - Software Development Agency
outsystems-tutorial

Export Data to Excel in OutSystems (RecordListToExcel Guide)

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.

What you'll learn

  • How to use the built-in RecordListToExcel action to convert a record list to a Binary Data Excel file
  • Calling the Download action with the correct MIME type for Excel files
  • Wiring an Export button on a screen to trigger a Server Action download
  • Controlling which columns are exported and setting custom column headers
  • Handling large datasets with Max Records and streaming patterns
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read15-20 minOutSystems 11 and ODCMarch 2026RapidDev Engineering Team
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.

Prerequisites

  • 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.

typescript
1/* RecordListToExcel parameters */
2RecordList: GetAllEmployees.List
3
4/* Output */
5File: Binary Data (access as RecordListToExcel.File)
6
7/* For custom columns, create a Structure */
8/* Data tab → Structures → Add Structure 'EmployeeExportRow' */
9/* Add attributes: FullName (Text), Email (Text), Department (Text) */
10/* 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

typescript
1/* Download action parameters */
2FileContent: RecordListToExcel.File
3FileName: "Employees_" + FormatDate(CurrDate(), "yyyyMMdd") + ".xlsx"
4MimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
5
6/* Full flow summary */
7Start
8 --> Aggregate: GetAllEmployees (Max Records: 10000)
9 --> RecordListToExcel: RecordList = GetAllEmployees.List
10 --> Download: FileContent = RecordListToExcel.File
11 FileName = "Employees_" + FormatDate(CurrDate(), "yyyyMMdd") + ".xlsx"
12 MimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
13 --> 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.

typescript
1/* Structure: EmployeeExportRow
2 Attributes: FullName (Text), Department (Text), Email (Text), HireDate (Date) */
3
4/* In Server Action - build export list */
5Assign: ExportList = GetAllEmployeesWithDept.List
6 /* GetAllEmployeesWithDept aggregate joins Employee + Department */
7 /* and has calculated attributes matching EmployeeExportRow */
8
9/* RecordListToExcel reads the structure attribute names as column headers */
10RecordListToExcel: 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 working example

ExportToExcel_ServerAction.txt
1/* ============================================================
2 SERVER ACTION: ExportEmployeesToExcel
3 Input: DepartmentId (Department Identifier) - optional filter
4 Output: none (Download action terminates response)
5 ============================================================ */
6Start
7 --> Aggregate: GetEmployeesForExport
8 Source: Employee join Department (Only With)
9 Filter: If(DepartmentId = NullIdentifier(), True,
10 Employee.DepartmentId = DepartmentId)
11 Calculated Attributes:
12 FullName = Employee.FirstName + " " + Employee.LastName
13 Department = Department.Name
14 Email = Employee.Email
15 HireDate = Employee.HireDate
16 Sort: Employee.LastName Ascending
17 Max Records: 50000
18
19 --> If: GetEmployeesForExport.List.Empty
20 [True] --> Raise UserException: "NoData"
21 Message = "No employees match the selected filter."
22
23 --> RecordListToExcel:
24 RecordList: GetEmployeesForExport.List
25
26 --> Download:
27 FileContent: RecordListToExcel.File
28 FileName: "Employees_" + FormatDate(CurrDate(), "yyyyMMdd") + ".xlsx"
29 MimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
30
31 --> End
32
33Exception Handler (User Exception: NoData)
34 --> (bubble up to Client Action for user message)
35 --> End
36
37/* ============================================================
38 CLIENT ACTION: ButtonExportOnClick
39 ============================================================ */
40Start
41 --> ExportEmployeesToExcel: DepartmentId = SelectedDepartmentId
42 --> End
43
44Exception Handler (User Exception: NoData)
45 --> Message: ExceptionMessage (Warning)
46 --> End

Common mistakes

Why it's a problem: Calling the Export Server Action directly from another Server Action and expecting the download to reach the browser

How to avoid: 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.

Why it's a problem: Not setting Max Records on the source Aggregate, causing a full table scan

How to avoid: 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.

Why it's a problem: Using 'application/xls' as the MimeType for .xlsx files

How to avoid: 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.

Why it's a problem: Expecting column headers to be human-readable when attribute names are camelCase database identifiers

How to avoid: 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.

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Show me how to export data to Excel in OutSystems 11 using RecordListToExcel. I have an Employee entity with FirstName, LastName, Email, DepartmentId. Walk through: (1) creating an ExportEmployeesToExcel Server Action with an Aggregate, (2) calling RecordListToExcel with the aggregate list, (3) calling the Download action with the correct MIME type for .xlsx, (4) wiring a button OnClick Client Action. Include the dynamic filename pattern using FormatDate.

OutSystems Prompt

Add an Excel export button to my OutSystems employee list screen. Create ExportEmployeesToExcel Server Action that: fetches employees joined with Department (Max Records: 10000), with optional DepartmentId filter; calls RecordListToExcel with the list; calls Download with FileName = 'Employees_' + FormatDate(CurrDate(), 'yyyyMMdd') + '.xlsx' and the correct xlsx MimeType. Wire a ButtonExport OnClick Client Action to call it.

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.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.