How do you bring a spreadsheet into an app safely?
Match the spreadsheet columns to your app's fields and decide how to handle invalid rows and existing records before you save anything. Check which records the app actually saved after the import.
Do you need an import, a migration or ongoing sync?
For an occasional upload, focus on showing the customer which columns and rows need attention. If many customers send different files for the same job, define a reusable template with field types, required values and duplicate rules. If a team is moving records between systems once, plan who will review and approve the prepared data before switching over.
For an ongoing sync, decide which system controls each field and what happens when both systems change it. Write down how to detect a failed transfer and resume without repeating saved changes.
What should count as a successful import?
Track the rows you received, the rows that passed validation and the records your app saved. Decide in advance whether one bad row holds the whole file or whether valid rows can go through. If the app accepts part of a file, give the uploader a way to find and correct what remains. A delivery can repeat after the app saved data, so decide how your app will recognize that delivery on the next attempt.
Compare tools
Scroll the table sideways to read every column.
| Tool | When it fitsWhat your customer or migration team needs to do. | What you take outHow you get the prepared records or configuration. | Usage to checkThe limits or units to compare with your expected volume. |
|---|---|---|---|
| CSVBox | Customers occasionally upload a CSV or Excel file and need help matching columns and fixing row errors. | Send validated rows to your app to save, write directly to a supported database, or download a file without automatic delivery. | Imports per month and rows per import. |
| OneSchema | With Embedded Importer, reuse the same required fields and validation rules across different incoming spreadsheets. | Send validated rows by webhook or download them. Template configuration has a separate JSON export. | Successfully imported files per year for Embedded Importer. |
| Flatfile | Use Projects when someone needs to map and review records before a migration. Reviewers can correct invalid values in the review table. | Download selected reviewed rows and keep a separate copy of the original files for comparison. | Project volume for Flatfile Projects. |
| Baserow | Move a file into an editable team table. Append or match by a stable ID when updating an existing table. | Export the whole table or a filtered view. Plan linked records, files and settings separately. | Cloud Free lists 3,000 rows and 2 GB per workspace. Check plan-specific export formats. |
| NocoDB | Import a file into a new table or append CSV and Excel rows to an existing one. | Download from a view as CSV, JSON or Excel. Check filters and what needs to move separately. | Cloud Free lists up to 1,000 records per workspace. Self-hosting has separate costs and license boundaries. |
| Airbyte | Copy data repeatedly between a supported source and destination. | Keep the copied data in the destination and record the connection settings separately. | Standard and Plus use data volume. Core needs your own infrastructure and operations. |
| Fivetran | Refresh a managed reporting copy on a schedule. | Copied tables land in your destination. Check connector-specific handling of deleted rows. | Free lists 500,000 monthly active rows for connections. Check separate feature allowances. |
| dlt | Write a Python copy job when you need control over source and destination behavior. | Keep the Python job, output and progress state. Choose append, replace or keyed merge. | The library is Apache 2.0. Runtime, destination and separate dltHub services have their own costs. |
| Estuary | Capture changes when a destination needs to stay fresh. Check the source connector first. | Send a collection to your destination. Confirm the connector’s deletion and table behavior. | Developer lists 10 GB/month and two connector instances. Captures and deliveries both count. |
| Coefficient | Refresh a report in Google Sheets or Excel. | Keep the sheet values and notes separately from the import connection. Refresh rewrites its output. | Check row size, refresh limits and schedule cadence. Export has separate limits. |
How can you rehearse a spreadsheet import on paper?
Use a fictional stock list with the headings Product Code and Quantity. Shop A and Shop B both already have an item with code 0012. The sample file belongs to Shop A. Keep the example on paper and use no account or upload.
- Match the fieldsWrite down that Product Code goes to Item Code and Quantity goes to Units in Stock. Keep item codes as text so 0012 keeps its leading zeros. Match an existing item within the shop that owns the file.
- Decide which rows to holdSketch four rows. Give 0012 quantities of 3 and 4 on two rows, leave one code blank, and give a new item 0031 a quantity of 2. In a plan that allows partial imports, hold the two conflicting rows and the row with no code. Expect one new item in Shop A and no change in Shop B.
- Repeat the same deliveryMark the planned delivery with a reference so the app could recognize it a second time. Write down the expected result after each attempt. The first would save one item and hold three rows. Repeating it would add zero items, with Shop B still unchanged.
What should you be able to export later?
List what your app needs to carry into the next system. Check the original files, cleaned records, attachments and the information that tells you which shop owns each record. Record whether users, permissions and links between records come out with the export or need separate work.
A recovery backup serves a separate job. Check how to restore the previous state if a migration fails. For a portable export, check whether the next app can read the files and reconstruct the relationships you need.
Before sharing customer data, check which service will hold originals and rejected rows, where it stores them, and how long it keeps them. Use the profile and service documentation for those details.