Skip to main content

Workbook (multi-sheet)

final wb = BCellWorkbook(sheets: [
BCellSheet(name: 'People', columns: cols, rows: rows, tabColor: Color(0xFF2196F3)),
BCellSheet(name: 'Budget', columns: cols2, rows: rows2),
]);

Column(children: [
Expanded(child: BCellWorkbookView(workbook: wb)),
BCellSheetTabBar(workbook: wb),
]);

wb.setProtected(i, true); wb.setHidden(i, true);
final json = jsonEncode(wb.toJson());
final restored = BCellWorkbook.fromJson(jsonDecode(json));

// Encrypt (AES-256-GCM, password-derived key):
final blob = wb.toEncryptedBytes('pw'); wb.loadEncryptedBytes(blob, 'pw');

// Version history:
wb.saveVersion(); wb.versions; wb.restoreVersion(0);

// Shared 3-way merge:
final conflicts = wb.mergeChanges(base: baseJson, theirs: theirJson);

Encryption notes: the blob is AES-256-GCM with a PBKDF2-derived key and a random per-file salt + nonce, so the same workbook never encrypts to the same bytes. A wrong password or a tampered byte throws BCellDecryptException (authenticated — never silent garbage); a non-encrypted file throws FormatException. decryptWorkbook(bytes, pw) returns a new workbook; loadEncryptedBytes loads in place.

Merge notes: mergeChanges is cell-level three-way against the shared base snapshot — a cell only the other copy changed lands here; a cell both copies changed differently keeps the local value and comes back as a BCellMergeConflict(sheet, rowIdx, field, base/mine/theirs) so you can offer "take theirs". Rows/sheets the other copy added come along; rows align by index, deletions don't propagate.


See every feature live with its calling code: cd widgetbook && flutter run -d chrome.