excel_plus v2.14.3
pub.dev GitHub

How to read an Excel file in Dart

Open an .xlsx workbook, walk its sheets and rows, and pull out typed values.

Install#

dart pub add excel_plus
import 'package:excel_plus/excel_plus.dart';

Read every row#

Load the file into bytes and hand them to Excel.decodeBytes. Each sheet is available by name from tables.

import 'dart:io';
import 'package:excel_plus/excel_plus.dart';

void main() {
  final bytes = File('input.xlsx').readAsBytesSync();
  final excel = Excel.decodeBytes(bytes);

  for (final sheetName in excel.tables.keys) {
    for (final row in excel[sheetName].rows) {
      print(row.map((cell) => cell?.value).toList());
    }
  }
}

A cell can be null when the sheet has a gap, so guard the value with ?. as above.

Read one cell#

final cell = excel['Sheet1'].cell(CellIndex.indexByString('B2'));
print(cell.value);

Cell values are typed#

cell.value returns a CellValue, not a raw string, so the original type survives the round trip. Switch on it to get the underlying Dart value:

final value = sheet.cell(CellIndex.indexByString('A1')).value;

switch (value) {
  case TextCellValue(:final value):    print('text: ${value.text}');
  case IntCellValue(:final value):     print('int: $value');
  case DoubleCellValue(:final value):  print('double: $value');
  case BoolCellValue(:final value):    print('bool: $value');
  case DateCellValue():                print('date: ${value.asDateTimeLocal()}');
  case FormulaCellValue(:final formula): print('formula: $formula');
  case null:                           print('empty cell');
  default:                             print(value);
}

Addressing cells#

Two ways to point at a cell. Use whichever fits the code around it.

CellIndex.indexByString('B2');
CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: 1);

Both are zero based when given as numbers, so B2 is column 1, row 1.

Sheet size#

final sheet = excel['Sheet1'];
print(sheet.maxRows);
print(sheet.maxColumns);

Reading from somewhere other than disk#

decodeBytes takes any List<int>, so the same call works for a file, an HTTP response body, or an asset bundled with an app. If the file is large and sits on disk, see reading large files for a streaming alternative that keeps memory flat.