nrb 4.1.0
nrb: ^4.1.0 copied to clipboard
A responsive Flutter table and report builder with local Excel, PDF, Word exports, JSON-to-Excel, nested headers, and editable data grids.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:nrb/nrb.dart';
void main() {
runApp(const NrbExampleApp());
}
/// Complete NRB showcase used by pub.dev's Example tab.
///
/// The example intentionally uses local export mode so it runs without secrets
/// or a subscription. Tap the floating NRB menu inside the report to access the
/// same Share Report / Download Report experience used by server mode.
class NrbExampleApp extends StatelessWidget {
const NrbExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'NRB Showcase',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF0F766E)),
scaffoldBackgroundColor: const Color(0xFFF4F7FA),
useMaterial3: true,
),
home: const NrbShowcasePage(),
);
}
}
/// Demonstrates charts, complex headers, frozen columns, a large data set, and
/// free local Excel/PDF/Word export without changing NRB's existing table UI.
class NrbShowcasePage extends StatefulWidget {
const NrbShowcasePage({super.key});
@override
State<NrbShowcasePage> createState() => _NrbShowcasePageState();
}
class _NrbShowcasePageState extends State<NrbShowcasePage> {
static const _brand = Color(0xFF0F766E);
late final List<List<ReportCell>> _tableData;
@override
void initState() {
super.initState();
_tableData = List.generate(150, (index) {
final employeeNo = 1001 + index;
final department = switch (index % 4) {
0 => 'Engineering',
1 => 'Sales',
2 => 'Operations',
_ => 'Finance',
};
final jan = 18000 + (index % 17) * 1250;
final feb = 19500 + (index % 13) * 1375;
final mar = 22000 + (index % 11) * 1450;
final apr = 20500 + (index % 19) * 1175;
final may = 24000 + (index % 9) * 1600;
final jun = 25500 + (index % 15) * 1325;
final ytd = jan + feb + mar + apr + may + jun;
final ratingIndex = index % 5;
final rating = ratingIndex == 0
? 'Excellent'
: (ratingIndex == 1 || ratingIndex == 2 ? 'Very Good' : 'Good');
final ratingColor = rating == 'Excellent'
? const Color(0xFFE7F7ED)
: rating == 'Very Good'
? const Color(0xFFEAF2FF)
: const Color(0xFFFFF8E1);
return <ReportCell>[
TextCell(
itemContent: 'EMP-$employeeNo',
textAlignment: Alignment.centerLeft,
isBold: index % 25 == 0,
),
TextCell(
itemContent: index % 10 == 0
? 'কর্মী ${index + 1}'
: 'Employee ${index + 1}',
textAlignment: Alignment.centerLeft,
),
TextCell(itemContent: department, textAlignment: Alignment.centerLeft),
_amountCell(jan),
_amountCell(feb),
_amountCell(mar),
_amountCell(apr),
_amountCell(may),
_amountCell(jun),
TextCell(
itemContent: ytd,
isAmount: true,
textAlignment: Alignment.centerRight,
isBold: true,
backgroundColor: const Color(0xFFF0FDF9),
),
TextCell(
itemContent: rating,
backgroundColor: ratingColor,
isBold: rating == 'Excellent',
),
];
});
}
static TextCell<int> _amountCell(int value) {
return TextCell<int>(
itemContent: value,
isAmount: true,
textAlignment: Alignment.centerRight,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'Nexora Report Builder',
style: TextStyle(fontWeight: FontWeight.w700),
),
backgroundColor: const Color(0xFF102A43),
foregroundColor: Colors.white,
),
body: Padding(
padding: const EdgeInsets.all(12),
child: Column(
children: [
_buildOverview(),
const SizedBox(height: 12),
Expanded(
child: Card(
clipBehavior: Clip.antiAlias,
elevation: 1,
margin: EdgeInsets.zero,
child: Padding(
padding: const EdgeInsets.all(8),
child: NrbTableEngine(
reportName: 'NRB_Employee_Performance',
frozenColumnsCount: 2,
isSortingEnable: true,
primaryUiColor: _brand,
primaryUiTextColor: Colors.white,
headerRowHeight: 36,
bodyCellHeight: 34,
indexWiseColumnWidths: const {
0: 105,
1: 150,
2: 125,
9: 120,
10: 105,
},
headers: _headers,
tableData: _tableData,
// ---------------------------------------------------------
// FREE LOCAL EXPORT MODE
// ---------------------------------------------------------
// No packageName is required when apiKey is null/blank.
// The existing NRB draggable FAB remains available and its
// Download/Share actions show Excel, PDF, and Word choices.
enableDownload: true,
showDownloadFloatingButton: true,
apiKey: '',
companyName: 'Innovate Nest Labs',
companyAddress: 'Uttar Mawna, Sreepur, Gazipur, Bangladesh',
companyLogoAsset: 'assets/logo.png',
// ---------------------------------------------------------
// OPTIONAL SERVER / SUBSCRIPTION MODE
// ---------------------------------------------------------
// packageName: 'com.your.app',
// apiKey: 'YOUR_API_KEY',
),
),
),
),
],
),
),
);
}
Widget _buildOverview() {
return Card(
elevation: 1,
margin: EdgeInsets.zero,
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Revenue Performance',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 2),
Text(
'${_tableData.length} rows • frozen columns • nested headers • local export',
style: const TextStyle(color: Colors.black54),
),
],
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 6,
),
decoration: BoxDecoration(
color: const Color(0xFFE7F7F4),
borderRadius: BorderRadius.circular(20),
),
child: const Text(
'LOCAL MODE',
style: TextStyle(
color: _brand,
fontWeight: FontWeight.w700,
fontSize: 11,
),
),
),
],
),
const SizedBox(height: 12),
const SizedBox(
height: 110,
child: NrbBarChart(
data: [210, 242, 270, 255, 302, 330],
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
barColor: _brand,
),
),
],
),
),
);
}
static final List<List<NrbHeaderCell>> _headers = [
[
const NrbHeaderCell(
text: 'Employee Information',
colSpan: 2,
backgroundColor: Color(0xFF174A7E),
),
const NrbHeaderCell(
text: 'Department',
rowSpan: 2,
backgroundColor: Color(0xFF174A7E),
),
const NrbHeaderCell(
text: 'Q1 Performance',
colSpan: 3,
backgroundColor: Color(0xFFB45309),
),
const NrbHeaderCell(
text: 'Q2 Performance',
colSpan: 3,
backgroundColor: Color(0xFF6D28D9),
),
const NrbHeaderCell(text: 'Summary', colSpan: 2, backgroundColor: _brand),
],
[
const NrbHeaderCell(text: 'ID', backgroundColor: Color(0xFF2563A6)),
const NrbHeaderCell(text: 'Name', backgroundColor: Color(0xFF2563A6)),
const NrbHeaderCell(text: 'Jan', backgroundColor: Color(0xFFD97706)),
const NrbHeaderCell(text: 'Feb', backgroundColor: Color(0xFFD97706)),
const NrbHeaderCell(text: 'Mar', backgroundColor: Color(0xFFD97706)),
const NrbHeaderCell(text: 'Apr', backgroundColor: Color(0xFF7C3AED)),
const NrbHeaderCell(text: 'May', backgroundColor: Color(0xFF7C3AED)),
const NrbHeaderCell(text: 'Jun', backgroundColor: Color(0xFF7C3AED)),
const NrbHeaderCell(text: 'YTD Sales', backgroundColor: _brand),
const NrbHeaderCell(text: 'Rating', backgroundColor: _brand),
],
];
}