Automated Excel Row to Xero Invoice Sync (n8n)

Seamlessly bridge front-office sales tracking in Excel with back-office accounting in Xero using n8n's robust workflow engine.

Tools: ExcelXero

Platform: n8n

Short Answer

A fully automated pipeline that monitors Excel Online tables for new records and instantly generates professional draft invoices in Xero. This ensures 100% data accuracy and provides real-time visibility into company financials without manual intervention.

The Problem

Manual data entry from Excel spreadsheets into Xero is time-consuming and prone to human error, leading to reconciliation discrepancies and delayed billing. Businesses struggle to maintain data integrity when scaling sales operations handled in flexible spreadsheets.

The Outcome

A fully automated pipeline that monitors Excel Online tables for new records and instantly generates professional draft invoices in Xero. This ensures 100% data accuracy and provides real-time visibility into company financials without manual intervention.

Step-by-Step Guide

1. **Establish Credentials**: In n8n, go to 'Credentials' and create 'Microsoft Online' (OAuth2) and 'Xero' (OAuth2) connections. Ensure your Xero app has `acc.transactions` and `contact.read` scopes. 2. **Setup Excel Trigger**: Add the 'Microsoft Excel Online Trigger' node. Set the 'Resource' to 'Row' and 'Event' to 'Created'. Select your Spreadsheet and the specific **Table** name (not just the sheet name). 3. **Search for Contact**: Add a 'Xero' node. Action: 'Get Many' for 'Contact'. Use a filter expression: `{{ $json["Customer Name"] }}` to check if the customer already exists in Xero. 4. **Conditional Logic (IF Node)**: Insert an 'IF' node after the Search. If the Xero search returns an empty array, route to a Xero 'Create Contact' node; otherwise, proceed to invoice creation. 5. **Format Dates with Expressions**: n8n expressions are needed for date compatibility. Use `{{ $today.format('yyyy-MM-dd') }}` for the Invoice Date and `{{ $json["Due Date"].toDate().toISOString() }}` to ensure Xero accepts the Excel date format. 6. **Map Invoice Line Items**: Add a 'Xero' node with Resource: 'Invoice' and Action: 'Create'. Set 'Status' to 'DRAFT'. Map the 'Line Items' using an n8n expression to build the JSON array containing Description, Quantity, and UnitAmount. 7. **Include Account Codes**: Map the 'AccountCode' field. In n8n, use a fixed value like `200` (Sales) or a mapping expression if the code exists in your Excel column. 8. **Implement Error Handling**: Create an 'Error Trigger' workflow or use the 'On Error' setting on the Xero node to 'Route to another node' (e.g., Slack or Email) if the API returns a 400 error due to invalid account codes or missing data.

Data Mapping

| Excel Field | Xero Field | Transformation / n8n Syntax | Req? | | :--- | :--- | :--- | :--- | | Customer Name | Contact Name | `{{ $json["Customer Name"] }}` | Yes | | Row ID | Reference | `Excel_ID_{{ $json["id"] }}` (Prevents Duplicates) | No | | Invoice Date | Date | `{{ $now.format('yyyy-MM-dd') }}` | Yes | | Due Date | DueDate | `{{ $json["Due Date"].format('yyyy-MM-dd') }}` | Yes | | Description | Line Item Description| `{{ $json["Item"] }}` | Yes | | Price | UnitAmount | `{{ parseFloat($json["Price"]) }}` | Yes | | Qty | Quantity | `{{ parseInt($json["Qty"]) }}` | Yes | | Account Code | AccountCode | `{{ $json["Code"] || '200' }}` (Default to 200) | Yes |

Gotchas & Failure Modes

* **The Table Requirement**: Excel nodes only work with data inside a formal 'Format as Table' object. Standard cell ranges will be invisible to the trigger. * **Rate Limiting**: Xero has a limit of 5,000 API calls per day. If processing thousands of rows, use the 'Split In Batches' node to throttle requests. * **Date Serial Numbers**: Excel often sends dates as numbers (e.g., 45123). Use n8n's `DateTime` node or Luxon expressions to convert these to `YYYY-MM-DD` before hitting Xero. * **Duplicate Prevention**: Map the Excel 'Row ID' or a unique 'Order Number' to the Xero 'Reference' field. Before creating, use a Xero node to search for an invoice with that Reference to avoid double-billing.

Verification Checklist

- [ ] **Trigger Test**: Add a row to the Excel Table and use 'Fetch Test Event' in n8n to ensure data is received. - [ ] **Credential Check**: Ensure Xero Organization is correctly selected in the node (especially if you manage multiple companies). - [ ] **Data Type Validation**: Verify in the 'Execution Log' that Quantity is a Number and UnitAmount is a Decimal, not Strings. - [ ] **Draft Creation**: Confirm a 'Draft' invoice appears in Xero > Business > Invoices > Draft. - [ ] **Error Path**: Intentionally leave an Excel 'Customer Name' blank to trigger your error notification node.

Ready to Automate?

Build this automation with n8n in minutes.