BCCL Documentation
Index

Importing Excel Files

BCCL supports importing data directly from Excel spreadsheets. This is convenient when your data originates from business users who work in Excel, or when you need to import data that includes formatted dates, numbers, and mixed data types. This page covers the Excel-specific parameters, mapping by column letter, data type handling, and common pitfalls.

Supported Excel Format

BCCL only supports the .xlsx format (Excel 2007 and later, also known as Open XML). The legacy .xls format (Excel 97-2003) is not supported. If you have an .xls file, open it in Excel and save it as .xlsx before importing.

Required Parameters

Excel imports require two additional parameters beyond the standard PUTDATA parameters:

Parameter Flag Description
Sheet name -x The name of the worksheet containing your data
Data range -y The cell range where your data begins and ends

Both parameters are mandatory for Excel imports. BCCL will report an error if either is missing.

Basic Excel Import Command

bccl -t putdata -s table=18 -i customers.xlsx -x Customers -y A2..C50

This reads data from the sheet named "Customers", starting at cell A2 and ending at cell C50.

Range Syntax

BCCL uses two dots (..) to separate the start and end cells in a range. This differs from Excel's colon notation:

Notation System Example
Two dots BCCL A2..C50
Colon Excel A2:C50

Important: Using Excel's colon notation (like A2:C50) will cause an error. Always use two dots: A2..C50.

Range Examples

Range Meaning
A2..C50 Columns A through C, rows 2 through 50
A1..H1000 Columns A through H, rows 1 through 1000
B5..F200 Columns B through F, rows 5 through 200
A2..Z9999 All 26 columns, rows 2 through 9999

The start cell defines where BCCL begins reading data. Typically you set the start row to 2 (or wherever your data begins) to skip a header row. The end cell defines the last possible data cell -- BCCL stops reading when it reaches the end row, even if some rows are empty.

Importing Without a Mapping File

When you import Excel data without a mapping file, BCCL matches columns to table fields by position. The first column in the range maps to the first field in the table, the second column to the second field, and so on.

bccl -t putdata -s table=18 -i customers.xlsx -x Customers -y A2..C50

For this to work correctly, the number of columns in your range must match the number of fields in the target table (excluding blob, media, and mediaset fields unless -b true is specified). If the counts do not match, BCCL reports an error:

There's 3 columns in the uploaded file, but 68 fields in the Customer table, consider using a mapping file?

In practice, you almost always want to use a mapping file with Excel imports.

Importing With a Mapping File

When using a mapping file with Excel data, the MappedName property uses Excel column letters (A, B, C, etc.) instead of column header names. This is because BCCL reads Excel cell values by position, not by header names.

Example Mapping File for Excel

Suppose your Excel sheet has this layout:

A B C
1 Customer Name City Post Code
2 Adatum Corporation Redmond 98052
3 Trey Research Atlanta 30329

Your mapping file would use column letters as MappedName:

{
  "Customer": [
    {
      "FieldNo": 2,
      "FieldName": "Name",
      "MappedName": "A",
      "Validate": true
    },
    {
      "FieldNo": 7,
      "FieldName": "City",
      "MappedName": "B",
      "Validate": true
    },
    {
      "FieldNo": 91,
      "FieldName": "Post Code",
      "MappedName": "C",
      "Validate": true
    }
  ],
  "ValidateOnInsert": true,
  "ValidateOnModify": true
}

And the import command:

bccl -t putdata -s table=18 -i customers.xlsx -x Customers -y A2..C50 -m mapping.json

Key Differences from CSV Mapping

Aspect CSV Mapping Excel Mapping
MappedName CSV column header text Excel column letter (A, B, C...)
Header row Used for matching Not used for matching
Column identification By name By position

Important: The header row in your Excel sheet is not used for matching. Even if row 1 contains column names, BCCL identifies columns purely by their letter position. The header row exists only for human readability. Set your range to start at the first data row (typically row 2) to skip it.

Data Type Handling

One advantage of Excel imports is that BCCL can read native Excel data types, preserving more precision than text-based formats like CSV. BCCL handles the following Excel cell types:

Numbers

Numeric cells are read as decimal values. BCCL uses the invariant culture when parsing numbers from Excel, so there are no locale-related issues with decimal separators.

Cell value: 1234.56
BCCL reads: 1234.56

Dates

Excel stores dates internally as OLE Automation dates (a floating-point number representing days since December 30, 1899). BCCL detects date-formatted cells and converts them to the standard yyyy-MM-dd format for Business Central:

Cell value: March 15, 2026 (displayed)
Excel internal: 46097 (OLE date)
BCCL reads: "2026-03-15"

If a date cell also contains a time component, BCCL preserves the full datetime value.

Times

Time-formatted cells are converted to HH:mm:ss.fff format:

Cell value: 2:30 PM (displayed)
BCCL reads: "14:30:00.000"

Strings

Text cells are read as-is. Shared strings (Excel's internal string deduplication) are resolved automatically.

Booleans

Boolean cells are converted to their logical values (true or false).

Empty Cells

Empty cells within the data range are skipped. BCCL tracks column positions and handles gaps in data gracefully.

Complete Excel Import Example

Here is a full end-to-end example of importing item data from Excel.

The Excel File (items.xlsx)

Sheet name: ItemData

A B C D
1 Item No. Description Unit Price Base Unit
2 ITEM-001 Widget 25.50 PCS
3 ITEM-002 Gadget 42.00 PCS
4 ITEM-003 Component 8.75 BOX

The Mapping File (item_mapping.json)

{
  "Item": [
    {
      "FieldNo": 1,
      "FieldName": "No.",
      "MappedName": "A",
      "Validate": true
    },
    {
      "FieldNo": 3,
      "FieldName": "Description",
      "MappedName": "B",
      "Validate": false
    },
    {
      "FieldNo": 18,
      "FieldName": "Unit Price",
      "MappedName": "C",
      "Validate": false
    },
    {
      "FieldNo": 8,
      "FieldName": "Base Unit of Measure",
      "MappedName": "D",
      "Validate": true
    }
  ],
  "ValidateOnInsert": true,
  "ValidateOnModify": true
}

The Import Command

bccl -t putdata -s table=27 -i items.xlsx -x ItemData -y A2..D4 -m item_mapping.json

The Result

{"Table":27,"Inserted":3,"Modified":0}

Working With Multiple Columns

For sheets with many columns, column letters extend beyond Z into two-letter combinations (AA, AB, AC, etc.), following standard Excel conventions. Use the same letters in your mapping file:

{
  "FieldNo": 50,
  "FieldName": "Some Field",
  "MappedName": "AA",
  "Validate": false
}

Paging With Excel Files

For large Excel files, BCCL sends data in batches. The default page size is 1000 records. Each batch is committed as a separate transaction.

You can adjust the page size:

bccl -t putdata -s table=18 -i big_data.xlsx -x Sheet1 -y A2..Z50000 -m mapping.json -z 500

When a page boundary is reached during Excel reading, BCCL sends the current batch to Business Central, receives the response, and then continues reading the next batch from the Excel file.

File Locking

Excel files are locked while open in Microsoft Excel. If you attempt to import a file that is currently open, BCCL reports an error:

Cannot open Excel file, is the file already opened in Excel?

Close the file in Excel before running the import, or save a copy to a different location.

Automatic Number Series With Excel

Just as with CSV imports, you can let Business Central generate primary key values by omitting the key field from the mapping. Your Excel data would contain only the non-key fields, and the range should cover just those columns:

{
  "Customer": [
    {"FieldNo":2,"FieldName":"Name","MappedName":"A","Validate":true},
    {"FieldNo":7,"FieldName":"City","MappedName":"B","Validate":true}
  ],
  "ValidateOnInsert": true,
  "ValidateOnModify": true
}
bccl -t putdata -s table=18 -i new_customers.xlsx -x Sheet1 -y A2..B100 -m mapping.json

Tips and Best Practices

  • Always close the Excel file before running an import to avoid file lock errors.
  • Set the range end row generously. BCCL handles empty rows at the end gracefully, and it is better to set the range too large than too small.
  • Remember that MappedName in Excel mapping uses column letters, not header text. Double-check your column letters.
  • Use the two-dot range syntax (A2..C50), not Excel's colon syntax.
  • For date fields, ensure cells are formatted as dates in Excel. If dates are stored as text, BCCL may not parse them correctly.
  • Use verbose mode (-v) to see exactly what data BCCL reads from each cell when troubleshooting.
  • If your sheet name contains spaces, wrap it in quotes: -x "My Sheet Name".