nrb 2.0.2 copy "nrb: ^2.0.2" to clipboard
nrb: ^2.0.2 copied to clipboard

A highly responsive Flutter table and report builder for complex nested headers, editable data grids, and premium Excel/PDF exports.

example/lib/main.dart

import 'dart:io' show Directory, File, Platform;

import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode;
import 'package:flutter/material.dart';
import 'package:nrb/nrb.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:device_info_plus/device_info_plus.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      home: InnovateNestReportScreen(),
    ),
  );
}

class InnovateNestReportScreen extends StatelessWidget {
  InnovateNestReportScreen({super.key});

  final _headers = [
    HeaderCell(
      text: "Financials (USD)",
      span: 3,
      backgroundColor: const Color(0xFF0B7A3E), // Brand Accent
    ),
    HeaderCell(
      text: "Operations",
      span: 2,
      backgroundColor: const Color(0xFF0B7A3E),
    ),
  ];

  final _subHeaders = [
    SubHeaderCell(text: "Gross Rev.", backgroundColor: const Color(0xFF0B7A3E), foregroundColor: Colors.white,),
    SubHeaderCell(text: "Op. Expenses", backgroundColor: const Color(0xFF0B7A3E), foregroundColor: Colors.white,),
    SubHeaderCell(text: "Net Profit", backgroundColor: const Color(0xFF0B7A3E), foregroundColor: Colors.white,),
    SubHeaderCell(text: "Active Clients", backgroundColor: const Color(0xFF0B7A3E), foregroundColor: Colors.white,),
    SubHeaderCell(text: "SLA Uptime", backgroundColor: const Color(0xFF0B7A3E), foregroundColor: Colors.white,),
  ];

  final _leftColumns = [
    TextCell(
      itemContent: "Custom Web Applications",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "Mobile App Development",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "Enterprise ERP Solutions",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "Cloud Hosting & DevOps",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "AI & Machine Learning",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "UI/UX Design Services",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "E-Commerce Platforms",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "API Development",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "Cybersecurity Audits",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(
      itemContent: "Data Analytics & BI",
      textAlignment: Alignment.centerLeft,
    ),
    TextCell(itemContent: "IT Consulting", textAlignment: Alignment.centerLeft),
    TextCell(
      itemContent: "Maintenance & Support",
      textAlignment: Alignment.centerLeft,
    ),
  ];

  final _tableData = [
    // Web Apps
    [
      TextCell(itemContent: "450,000", isAmount: true),
      TextCell(itemContent: "180,000", isAmount: true),
      TextCell(itemContent: "270,000", isAmount: true),
      TextCell(itemContent: "42"),
      TextCell(itemContent: "99.9%"),
    ],
    // Mobile Apps
    [
      TextCell(itemContent: "385,500", isAmount: true),
      TextCell(itemContent: "155,000", isAmount: true),
      TextCell(itemContent: "230,500", isAmount: true),
      TextCell(itemContent: "28"),
      TextCell(itemContent: "99.8%"),
    ],
    // ERP
    [
      TextCell(itemContent: "850,000", isAmount: true),
      TextCell(itemContent: "320,000", isAmount: true),
      TextCell(itemContent: "530,000", isAmount: true),
      TextCell(itemContent: "8"),
      TextCell(itemContent: "99.99%"),
    ],
    // Cloud
    [
      TextCell(itemContent: "210,000", isAmount: true),
      TextCell(itemContent: "95,000", isAmount: true),
      TextCell(itemContent: "115,000", isAmount: true),
      TextCell(itemContent: "115"),
      TextCell(itemContent: "99.99%"),
    ],
    // AI & ML
    [
      TextCell(itemContent: "540,200", isAmount: true),
      TextCell(itemContent: "210,000", isAmount: true),
      TextCell(itemContent: "330,200", isAmount: true),
      TextCell(itemContent: "14"),
      TextCell(itemContent: "99.5%"),
    ],
    // UI/UX
    [
      TextCell(itemContent: "125,000", isAmount: true),
      TextCell(itemContent: "45,000", isAmount: true),
      TextCell(itemContent: "80,000", isAmount: true),
      TextCell(itemContent: "55"),
      TextCell(itemContent: "N/A"),
    ],
    // E-Commerce
    [
      TextCell(itemContent: "310,000", isAmount: true),
      TextCell(itemContent: "110,000", isAmount: true),
      TextCell(itemContent: "200,000", isAmount: true),
      TextCell(itemContent: "34"),
      TextCell(itemContent: "99.9%"),
    ],
    // API Dev
    [
      TextCell(itemContent: "195,000", isAmount: true),
      TextCell(itemContent: "65,000", isAmount: true),
      TextCell(itemContent: "130,000", isAmount: true),
      TextCell(itemContent: "22"),
      TextCell(itemContent: "99.95%"),
    ],
    // Cybersec
    [
      TextCell(itemContent: "280,000", isAmount: true),
      TextCell(itemContent: "90,000", isAmount: true),
      TextCell(itemContent: "190,000", isAmount: true),
      TextCell(itemContent: "19"),
      TextCell(itemContent: "100%"),
    ],
    // Data Analytics
    [
      TextCell(itemContent: "415,000", isAmount: true),
      TextCell(itemContent: "140,000", isAmount: true),
      TextCell(itemContent: "275,000", isAmount: true),
      TextCell(itemContent: "26"),
      TextCell(itemContent: "99.8%"),
    ],
    // IT Consulting
    [
      TextCell(itemContent: "150,000", isAmount: true),
      TextCell(itemContent: "30,000", isAmount: true),
      TextCell(itemContent: "120,000", isAmount: true),
      TextCell(itemContent: "45"),
      TextCell(itemContent: "N/A"),
    ],
    // Maintenance
    [
      TextCell(itemContent: "290,000", isAmount: true),
      TextCell(itemContent: "85,000", isAmount: true),
      TextCell(itemContent: "205,000", isAmount: true),
      TextCell(itemContent: "88"),
      TextCell(itemContent: "99.9%"),
    ],
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Innovate Nest Labs - Financial Report Q4'),
        backgroundColor: Colors.white,
        foregroundColor: Colors.black87,
        elevation: 2,
      ),
      body: ReportMaker(
        // --- REPORT STRUCTURE ---
        // --- 1. HEADERS ---
        headers: _headers,

        // --- 2. SUB-HEADERS ---
        subHeaders: _subHeaders,

        // --- 3. LEFT STICKY COLUMNS ---
        leftColumn: _leftColumns,

        // --- 4. TABLE DATA ---
        tableData: _tableData,

        // --- LEFT top ---
        stickyHeaderLabel: "Service / Division",
        stickyHeaderBackgroundColor: const Color(0xFF0B7A3E), // Brand Accent
        // Brand Accent
        stickyHeaderForegroundColor: Colors.white,

        // --- FOR DOWNLOAD FEATURES ---
        packageName: "com.innovatenestlabs.demoapp", // For free demo
        apiKey: "", // Empty for free demo
        enableDownload: true,
        showDownloadFloatingButton: true,
        reportName: "Financial Report Q4",
        // --- 5. PERMISSION HANDLING & DOWNLOAD LOGIC ---
        // Update your onDownloadCompleted logic:
        onDownloadCompleted: (bytes, fileName) async {
          if (!kIsWeb) {
            bool hasPermission = false;

            if (Platform.isAndroid) {
              final deviceInfo = DeviceInfoPlugin();
              final androidInfo = await deviceInfo.androidInfo;

              if (androidInfo.version.sdkInt >= 33) {
                // On Android 13+, we don't need 'storage' permission to write to Downloads
                // We just need to ensure we have 'photos' if we were reading,
                // but for writing, we can often just proceed.
                hasPermission = true;
              } else {
                // For Android 12 and below
                var status = await Permission.storage.status;
                if (!status.isGranted) {
                  status = await Permission.storage.request();
                }
                hasPermission = status.isGranted;
              }
            }

            if (hasPermission) {
              try {
                // Use path_provider for better reliability
                // For now, continuing with your path:
                final directory = Directory('/storage/emulated/0/Download');
                if (!await directory.exists()) {
                  await directory.create(recursive: true);
                }

                final file = File('${directory.path}/$fileName');
                await file.writeAsBytes(bytes);

                if (context.mounted) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Report saved to Downloads'), backgroundColor: Colors.green),
                  );
                }
              } catch (e) {
                if (context.mounted) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Save failed: $e'), backgroundColor: Colors.red),
                  );
                }
              }
            } else {
              // Handle denied state
            }
          }
        },
      ),
    );
  }
}
8
likes
0
points
825
downloads

Publisher

verified publisherinnovatenestlabs.com

Weekly Downloads

A highly responsive Flutter table and report builder for complex nested headers, editable data grids, and premium Excel/PDF exports.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

cross_file, flutter, share_plus, web

More

Packages that depend on nrb