syncfusion / flutter-examples

This repository contains the Syncfusion Flutter UI widgets examples and the guide to use them.
Other
1.98k stars 775 forks source link

SfDataGrid PDF export is not displaying the StackedHeader and Footer in Flutter Web #705

Closed ChipM0nk closed 1 year ago

ChipM0nk commented 2 years ago

SfDataGrid PDF export is not displaying the StackedHeader and Footer in Flutter Web.

Below is the sample code I wrote with Print Button.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:syncfusion_flutter_pdf/pdf.dart' as sf_pdf;
import 'package:syncfusion_flutter_datagrid_export/export.dart';
import 'package:printing/printing.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    List<Employee> employees = [
      Employee(10001, 'James', 'Project Lead', 20000),
      Employee(10002, 'Kathryn', 'Manager', 30000),
      Employee(10003, 'Lara', 'Developer', 15000),
      Employee(10004, 'Michael', 'Designer', 15000),
      Employee(10005, 'Martin', 'Developer', 15000),
      Employee(10006, 'Newberry', 'Developer', 15000),
      Employee(10007, 'Balnc', 'Developer', 15000),
      Employee(10008, 'Perry', 'Developer', 15000),
      Employee(10009, 'Gable', 'Developer', 15000),
      Employee(10010, 'Grimes', 'Developer', 15000)
    ];

    GlobalKey<SfDataGridState> key = GlobalKey<SfDataGridState>();
    EmployeeDataSource employeeDataSource =
        EmployeeDataSource(employees: employees);
    void exportDataGridToPDF() async {
      sf_pdf.PdfDocument document = key.currentState!.exportToPdfDocument();
      final List<int> bytes = document.saveSync();

      await Printing.layoutPdf(onLayout: (_) => Uint8List.fromList(bytes));
      document.dispose();
    }

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Column(
          children: [
            SfDataGrid(
              key: key,
              source: employeeDataSource,
              stackedHeaderRows: [
                StackedHeaderRow(
                  cells: [
                    StackedHeaderCell(
                      columnNames: ['id', 'name', 'designation', 'salary'],
                      child: const Text("Stacked Header"),
                    ),
                  ],
                ),
              ],
              footer: const Text("FOOTER"),
              columns: [
                GridColumn(
                    columnName: 'id',
                    label: Container(
                        padding: const EdgeInsets.symmetric(horizontal: 16.0),
                        alignment: Alignment.centerRight,
                        child: const Text(
                          'ID',
                          overflow: TextOverflow.ellipsis,
                        ))),
                GridColumn(
                    columnName: 'name',
                    label: Container(
                        padding: const EdgeInsets.symmetric(horizontal: 16.0),
                        alignment: Alignment.centerLeft,
                        child: const Text(
                          'Name',
                          overflow: TextOverflow.ellipsis,
                        ))),
                GridColumn(
                    columnName: 'designation',
                    label: Container(
                        padding: const EdgeInsets.symmetric(horizontal: 16.0),
                        alignment: Alignment.centerLeft,
                        child: const Text(
                          'Designation',
                          overflow: TextOverflow.ellipsis,
                        ))),
                GridColumn(
                    columnName: 'salary',
                    label: Container(
                        padding: const EdgeInsets.symmetric(horizontal: 16.0),
                        alignment: Alignment.centerRight,
                        child: const Text(
                          'Salary',
                          overflow: TextOverflow.ellipsis,
                        ))),
              ],
            ),
            ElevatedButton(
                onPressed: () => exportDataGridToPDF(),
                child: const Text("Export to PDF"))
          ],
        ),
      ),
    );
  }
}

class Employee {
  Employee(this.id, this.name, this.designation, this.salary);
  final int id;
  final String name;
  final String designation;
  final int salary;
}

class EmployeeDataSource extends DataGridSource {
  EmployeeDataSource({required List<Employee> employees}) {
    dataGridRows = employees
        .map<DataGridRow>((dataGridRow) => DataGridRow(cells: [
              DataGridCell<int>(columnName: 'id', value: dataGridRow.id),
              DataGridCell<String>(columnName: 'name', value: dataGridRow.name),
              DataGridCell<String>(
                  columnName: 'designation', value: dataGridRow.designation),
              DataGridCell<int>(
                  columnName: 'salary', value: dataGridRow.salary),
            ]))
        .toList();
  }

  List<DataGridRow> dataGridRows = [];

  @override
  List<DataGridRow> get rows => dataGridRows;

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      return Container(
          alignment: (dataGridCell.columnName == 'id' ||
                  dataGridCell.columnName == 'salary')
              ? Alignment.centerRight
              : Alignment.centerLeft,
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          child: Text(
            dataGridCell.value.toString(),
            overflow: TextOverflow.ellipsis,
          ));
    }).toList());
  }
}
image
Tamilarasan-Paranthaman commented 2 years ago

Hi @ChipM0nk,

Regarding the Stacked Header: You need to set the corresponding text in the StackedHeaderCell.text property. As widgets can’t be exported to PDF, set this property to give the corresponding text while exporting the SfDataGrid to PDF. Please refer to the following code snippet and sample.

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Column(
          children: [
            ElevatedButton(
                onPressed: () => exportDataGridToPDF(),
                child: const Text("Export to PDF")),
            Expanded(
              child: SfDataGrid(
                key: key,
                source: employeeDataSource,
                stackedHeaderRows: [
                  StackedHeaderRow(
                    cells: [
                      StackedHeaderCell(
                        text: 'Stacked Header',
                        columnNames: ['id', 'name', 'designation', 'salary'],
                        child: const Text("Stacked Header"),
                      ),
                    ],
                  ),
                ],
                columns: getColumns,
              ),
            ),
          ],
        ),
      ),
    );
  }

Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Sample-1234621677

Regarding the Footer: Currently, the SfDataGrid only provides support for exporting the cell content to a PDF document. Also, DataGrid doesn’t have support for exporting the footer to a PDF document. You can add the footer using the PDF document footer. Refer to the following UG document for the PDF footer

UG Document: https://help.syncfusion.com/flutter/pdf/working-with-headers-and-footers

ChipM0nk commented 1 year ago

Thanks for the response and sample