Every automation eventually needs to create a file.
Whether you’re generating reports for stakeholders, exporting data to spreadsheets, or preparing files for email attachments, the Convert to File node transforms your JSON data into actual files.
The challenge? File conversion in n8n has quirks that trip up even experienced users:
- Data ends up on a single row instead of multiple rows
- Excel formulas appear as plain text
- File names don’t work as expected
These problems have straightforward solutions once you understand how the node works.
The Export Problem
Most APIs and n8n nodes output JSON data.
But business users need spreadsheets they can open in Excel. Customers expect downloadable reports. External systems require specific file formats.
The Convert to File node bridges this gap by transforming structured JSON into binary file data that subsequent nodes can upload, email, or store.
What You’ll Learn
- How to convert JSON data to 10+ file formats including CSV, Excel, and JSON files
- The critical difference between output modes and when to use each
- Step-by-step troubleshooting for the most common conversion errors
- Real workflow patterns for reports, exports, and automated file delivery
When to Use Convert to File
Before diving into configuration, understand when this node is the right choice:
| Scenario | Best Approach | Why |
|---|---|---|
| Export workflow data to Excel/CSV | Convert to File | Creates downloadable spreadsheet files |
| Generate reports for email attachment | Convert to File | Produces binary data for attachment nodes |
| Create JSON file from API response | Convert to File | Converts JSON object to actual .json file |
| Save data to Google Drive/S3 | Convert to File + Upload node | File must be binary before upload |
| Transform JSON between nodes | Edit Fields node | No file conversion needed |
| Read existing file content | Extract from File | Inverse operation of Convert to File |
Rule of thumb: Use Convert to File whenever you need to transform JSON data into a downloadable or uploadable file. If you’re just reshaping data between nodes, use Edit Fields instead.
Understanding File Conversion in n8n
Before converting anything, you need to understand how n8n handles the transition from JSON to file data.
JSON vs Binary Data
In n8n, data exists in two forms:
- JSON data - Structured key-value pairs that nodes can read and manipulate directly
- Binary data - Raw file contents stored separately from JSON, representing actual files
When you run a workflow, data flows as JSON between nodes. The Convert to File node takes that JSON and creates binary data representing a file. This binary data can then be uploaded to cloud storage, attached to emails, or downloaded.
The Binary Property Convention
After conversion, the file lives in a binary property. By default, this property is named data, but you can customize it:
// Item structure after Convert to File
{
"json": {
"originalField": "still available"
},
"binary": {
"data": {
"mimeType": "text/csv",
"fileName": "export.csv",
"fileExtension": "csv",
"data": "bmFtZSxlbWFpbApKb2huLC..." // Base64 encoded content
}
}
}
Subsequent nodes that handle files (Google Drive, S3, Email) look for this binary property. If you change the output field name in Convert to File, make sure downstream nodes reference the correct property name.
How Files Flow Through Workflows
Understanding this flow prevents the “where did my file go?” confusion:
- Source node outputs JSON data (HTTP Request, database query, form submission)
- Convert to File transforms JSON to binary file data
- Binary data travels alongside JSON through connections
- Destination node uploads/sends the binary data (Google Drive, Email, S3)
Critical insight: Some transform nodes can discard binary data. If you add an Edit Fields node after Convert to File using “Set” mode instead of “Append” mode, your file disappears. Always verify binary data exists after intermediate nodes.
For more details on how n8n handles files, see the official n8n binary data documentation.
Supported File Formats
The Convert to File node handles 10 different formats, each optimized for specific use cases:
| Format | Operation | Best For | MIME Type |
|---|---|---|---|
| CSV | Convert to CSV | Spreadsheets, data imports | text/csv |
| XLSX | Convert to XLSX | Modern Excel files | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| XLS | Convert to XLS | Legacy Excel (97-2003) | application/vnd.ms-excel |
| ODS | Convert to ODS | LibreOffice spreadsheets | application/vnd.oasis.opendocument.spreadsheet |
| JSON | Convert to JSON | API payloads, data exchange | application/json |
| HTML | Convert to HTML | Web-viewable reports | text/html |
| RTF | Convert to RTF | Rich text documents | application/rtf |
| Text | Convert to Text | Plain text files | text/plain |
| ICS | Convert to ICS | Calendar events | text/calendar |
| Base64 | Move Base64 to File | Decode existing Base64 strings | varies |
For detailed information on MIME types, refer to MDN’s documentation.
Format Selection Guidelines
For spreadsheet data: Use CSV for maximum compatibility, XLSX for Excel features like multiple sheets, ODS for LibreOffice users.
For structured data: Use JSON when the recipient needs to parse the data programmatically.
For human-readable output: Use HTML for web viewing, RTF for word processors, Text for simple content.
For calendar integration: Use ICS when creating events for calendar applications.
Your First File Conversion
Let’s walk through a complete example: converting JSON data to a downloadable CSV file.
Step 1: Prepare Your Data
Start with a node that outputs JSON data. For testing, use a Manual Trigger with a Code node:
return [
{ json: { name: "Alice", email: "[email protected]", amount: 150 } },
{ json: { name: "Bob", email: "[email protected]", amount: 275 } },
{ json: { name: "Carol", email: "[email protected]", amount: 320 } }
];
Each item represents one row in your output file.
Step 2: Add Convert to File
- Add a Convert to File node after your data source
- Set Operation to “Convert to CSV”
- Leave Put Output File in Field as “data” (default)
- Optionally set Options > File Name to “export.csv”
Step 3: Test and Verify
Click Test step. The output shows:
- Binary tab appears with your file
- Click Download to save and verify the CSV opens correctly in Excel
Your CSV should contain:
name,email,amount
Alice,[email protected],150
Bob,[email protected],275
Carol,[email protected],320
Common First-Time Mistakes
Mistake 1: Single item input creates single row
If you pass one item containing an array, you get one row. Each row needs to be a separate n8n item.
// Wrong - creates one row with array data
return [{ json: { data: [{name: "Alice"}, {name: "Bob"}] } }];
// Correct - creates multiple rows
return [
{ json: { name: "Alice" } },
{ json: { name: "Bob" } }
];
Mistake 2: Forgetting to split items
If your data comes as an array in a single item, use the Split Out node before Convert to File.
Mistake 3: Not testing before connecting upload nodes
Always verify your file content with the Download button before connecting to Google Drive, S3, or email nodes.
Converting to Spreadsheets
Spreadsheet formats (CSV, XLSX, XLS, ODS) are the most common conversion targets. Each has specific configuration options.
CSV Configuration
CSV is the universal spreadsheet format. Configuration options include:
| Option | Default | Purpose |
|---|---|---|
| File Name | - | Sets output filename (include .csv extension) |
| Header Row | true | Include column headers from JSON keys |
| Delimiter | Comma | Field separator (, or ; or tab) |
Handling European formats:
Many European systems expect semicolons instead of commas:
- Set Options > Delimiter to “Semicolon”
- Some systems also expect different decimal separators
For detailed CSV format specifications, see RFC 4180.
Excel (XLSX) Configuration
XLSX provides more features than CSV:
| Option | Purpose |
|---|---|
| File Name | Output filename (include .xlsx extension) |
| Sheet Name | Name of the worksheet (default: “Sheet1”) |
| Header Row | Include column headers from JSON keys |
| Compression | Reduce file size (XLSX is already compressed) |
Multiple sheets: The Convert to File node creates one sheet per conversion. For multiple sheets, you need multiple Convert to File nodes and a Code node to combine them.
Excel Formula Limitation
Important: The Convert to File node outputs values, not formulas. If your JSON contains formula strings like =SUM(A1:A10), they appear as literal text in Excel, not calculated formulas.
Workaround: Calculate values in n8n before conversion using expressions or the Code node:
// Calculate in n8n, not in Excel
const items = $input.all();
let total = 0;
for (const item of items) {
total += item.json.amount;
}
return items.map(item => ({
json: {
...item.json,
percentOfTotal: ((item.json.amount / total) * 100).toFixed(2)
}
}));
Troubleshooting Spreadsheet Issues
Problem: All data appears in one row
This happens when your input is a single item containing an array instead of multiple items.
Solution: Use the Split Out node to convert the array to individual items before Convert to File.
Problem: Missing columns or wrong column order
Column order comes from JSON key order, which can vary.
Solution: Use Edit Fields before Convert to File to explicitly define which fields to include and their order.
Problem: Numbers formatted as text in Excel
CSV files don’t preserve data types. Excel guesses based on content.
Solution: Use XLSX format instead, which better preserves numeric types. Or format the column in Excel after opening.
Converting to JSON Files
Converting to JSON creates a downloadable .json file from your workflow data.
When to Use JSON Format
- Creating configuration files for other systems
- Generating API payloads to store or send later
- Backing up workflow data in a portable format
- Producing machine-readable exports
Configuration Options
| Option | Purpose |
|---|---|
| File Name | Output filename (include .json extension) |
| Format | Pretty print with indentation vs minified |
Output Modes for JSON
All Items to One File: Creates a JSON array containing all items:
[
{"name": "Alice", "amount": 150},
{"name": "Bob", "amount": 275}
]
Each Item to Separate File: Creates individual JSON files for each item:
// File 1
{"name": "Alice", "amount": 150}
// File 2
{"name": "Bob", "amount": 275}
Avoiding Field Name Pollution
A common issue: your JSON file contains an extra wrapper from the n8n item structure.
// Unwanted output
{"json": {"name": "Alice"}}
// Expected output
{"name": "Alice"}
Solution: The node should output clean JSON by default. If you see wrapper objects, check that you’re referencing $json properties correctly in previous nodes.
Converting to Other Formats
HTML Files
HTML conversion creates web-viewable documents. The node generates a basic HTML table from your data:
<table>
<tr><th>name</th><th>email</th></tr>
<tr><td>Alice</td><td>[email protected]</td></tr>
</table>
Use cases:
- Email body content (some email nodes accept HTML)
- Simple web reports
- Data preview pages
Limitation: The default HTML output is basic. For styled reports, generate HTML in a Code node first, then convert to Text file format.
ICS Calendar Files
ICS files create calendar events compatible with Google Calendar, Outlook, and Apple Calendar.
Required fields for ICS:
- Event title
- Start date/time
- End date/time
Example workflow:
- Fetch event data from your source
- Format dates to ISO 8601 format
- Convert to ICS
RTF Documents
RTF (Rich Text Format) creates documents openable in word processors. Useful for:
- Simple formatted documents
- Cross-platform text with basic styling
- Documents that need to be editable
Plain Text Files
Text format creates simple .txt files. Best for:
- Log files
- Simple exports
- Content that doesn’t need structure
Move Base64 String to File
This special operation converts an existing Base64-encoded string into binary file data:
- Set Operation to “Move Base64 String to File”
- Specify the Source Property containing the Base64 string
- Set the MIME Type of the resulting file
Use case: APIs that return file content as Base64 strings in JSON responses.
Output Modes Explained
The Convert to File node offers two output modes that fundamentally change how your data becomes files.
All Items to One File
All input items combine into a single file. For spreadsheets, each item becomes one row.
Input: 3 items with {name, email}
Output: 1 file with 3 rows (plus header)
When to use:
- Exporting reports with multiple records
- Creating single spreadsheet from query results
- Most standard export scenarios
Each Item to Separate File
Each input item creates its own file. You get multiple binary outputs.
Input: 3 items with {name, email}
Output: 3 files, each with 1 row
When to use:
- Individual invoices per customer
- Separate configuration files per record
- Processing that requires file-per-record
Important: When using “Each Item to Separate File,” use expressions in the filename to create unique names:
invoice_{{ $json.customerId }}.pdf
report_{{ $now.format('yyyy-MM-dd') }}_{{ $itemIndex }}.csv
Common Workflow Patterns
Pattern 1: API Data to Email Spreadsheet
Export API data and email it as an attachment:
Schedule Trigger → HTTP Request → Convert to CSV → Gmail (send with attachment)
Gmail configuration:
- Attachments: Use the binary data from Convert to File
- Set the binary property name to match your Convert to File output field
Pattern 2: Database Export to Cloud Storage
Daily export of database records to Google Drive:
Schedule Trigger → Postgres → Convert to XLSX → Google Drive (upload)
Key settings:
- Convert to File: Set descriptive filename with date:
export_{{ $now.format('yyyy-MM-dd') }}.xlsx - Google Drive: Binary Property must match your output field name
Pattern 3: Form Submission to Downloadable Report
Generate downloadable file when user submits form:
Webhook → Process Data → Convert to JSON → Respond to Webhook (with file)
Respond to Webhook configuration:
- Response Type: Binary
- Response Data Property: “data” (or your custom field name)
Pattern 4: Batch Invoice Generation
Create individual PDF-like documents for each customer:
Trigger → Get Customers → Loop → Generate Invoice Data → Convert to HTML → Upload
Use “Each Item to Separate File” mode with dynamic filenames.
Troubleshooting Common Errors
All Data on Single Row
Symptom: Your spreadsheet has one row with all data spread across hundreds of columns.
Cause: Input is a single item containing an array, not multiple items.
Solution: Add a Split Out node before Convert to File to convert the array into separate items.
Debug approach:
- Check the input to Convert to File
- Count the items (should match expected row count)
- Each item should be a flat object, not nested arrays
File Name Not Applied
Symptom: Downloaded file has generic name or wrong extension.
Cause: Filename option not set, or expression error in filename.
Solution:
- Set Options > File Name explicitly
- Include the extension:
report.csvnot justreport - Test expressions:
{{ $json.name }}.csv
If using expressions, validate them with our expression validator tool.
MIME Type Mismatch
Symptom: Upload nodes reject the file or change its type.
Cause: Some upload services are strict about MIME types. The Convert to File node sets appropriate types, but subsequent nodes might override them.
Solution:
- Check what MIME type the destination expects
- Verify the binary data has the correct mimeType property
- Some nodes let you override MIME type explicitly
Empty or Corrupted File
Symptom: File downloads but won’t open, or opens empty.
Causes:
- No input data to Convert to File
- Binary data lost in intermediate nodes
- Encoding mismatch
Debug steps:
- Verify Convert to File receives items (check execution log)
- Click Download immediately after Convert to File to test
- Check intermediate nodes preserve binary data
Use our workflow debugger to diagnose execution issues.
JSON Syntax Errors in Output
Symptom: JSON file contains invalid syntax or unexpected characters.
Cause: Special characters in data not properly escaped.
Solution: The node handles escaping automatically. If you’re building JSON manually in a Code node before conversion, ensure proper escaping:
// Let n8n handle it
return items.map(item => ({
json: item.json
}));
// Don't manually stringify unless necessary
If you’re debugging malformed JSON, try our JSON fixer tool.
Pro Tips and Best Practices
1. Use Dynamic Filenames
Never hardcode filenames in production workflows. Include identifiers and dates:
report_{{ $('Get Customer').item.json.customerId }}_{{ $now.format('yyyyMMdd') }}.xlsx
This prevents file overwrites and makes debugging easier.
2. Enable Compression for Large Files
For files over 1MB, enable compression in node options. This reduces:
- Storage costs in cloud destinations
- Email attachment size
- Transfer time
3. Validate Data Before Conversion
Add a filter or validation step before Convert to File:
Data Source → IF (has required fields) → Convert to File
↓
Error Handler
This prevents empty or malformed exports.
4. Handle Binary Data Carefully
When adding nodes between Convert to File and your upload destination:
- Use “Append” mode in Edit Fields, not “Set” mode
- Verify binary data exists after each node
- Don’t use nodes that reset item structure
5. Test with Sample Data First
Before connecting production data sources:
- Use a Code node with sample data
- Verify file format and content
- Test with the actual destination (email, Drive, S3)
- Then connect the real data source
6. Consider File Size Limits
Different destinations have size limits:
- Gmail: 25MB per attachment
- Most email services: 10-25MB
- API endpoints: Often 5-10MB
For large exports, consider:
- Compression
- Splitting into multiple files
- Direct upload to storage instead of email
For the complete list of options and parameters, refer to the official n8n Convert to File documentation.
For complex file processing workflows, our workflow development services can help you build robust, production-ready solutions. If you need guidance on architecture or best practices, explore our n8n consulting services.
Frequently Asked Questions
Why does my CSV have all data in one row instead of multiple rows?
Cause: Your input is a single n8n item containing an array, rather than multiple separate items.
The Convert to File node creates one row per input item.
Solution:
- Add a Split Out node before Convert to File
- Configure it to split your array field
- Each array element becomes a separate item (and thus a separate row)
Verify by checking that Convert to File shows multiple input items matching your expected row count.
How do I create an Excel file with multiple sheets?
The Convert to File node creates one sheet per execution. For multiple sheets, you have several options:
Option 1: Create separate XLSX files for each sheet, then combine them using a Code node with a library like xlsx-js.
Option 2: Use an external API service that supports multi-sheet Excel generation via the HTTP Request node.
Option 3: Consider whether multiple CSV files might work instead. They’re easier to generate, and many systems can import multiple CSVs.
Can I include Excel formulas in my converted spreadsheet?
Short answer: No. The Convert to File node outputs values only.
If you include formula strings like =SUM(A1:A10), they appear as literal text in Excel, not calculated formulas.
Workaround: Perform all calculations in n8n before conversion:
- Use expressions in Edit Fields nodes
- Use Code nodes for complex calculations
- This is actually more reliable since n8n calculates with your actual data at runtime
For complex reporting needs, consider specialized report generation services or HTML reports with calculated values.
Why does my file upload with the wrong MIME type?
Some upload destinations are strict about MIME types. The Convert to File node sets appropriate types automatically, but subsequent nodes or APIs might override them.
Debugging steps:
- Verify the binary data shows correct mimeType in n8n’s output panel
- Check if your upload node has a MIME type override option
- For Google Drive, explicitly set the MIME type in the upload operation
- Ensure your filename includes the correct extension (some destinations determine type from extension)
How do I generate separate files for each record with unique names?
Use “Each Item to Separate File” mode combined with expression-based filenames.
In the File Name option, use expressions like:
invoice_{{ $json.customerId }}_{{ $now.format('yyyyMMdd') }}.csvreport_{{ $itemIndex }}.xlsx
The $itemIndex variable gives you a sequential number for each item.
Important: Verify your destination node (Google Drive, S3, etc.) handles multiple binary outputs correctly. Some nodes process each item separately, while others might need a Loop.