Flutterexperts

Empowering Vision with FlutterExperts' Expertise
Implement Chart Export In Different Formats In Flutter

In this article, we will explore Chart Export in Different Formats. We will also implement a demo program and learn how to implement it in your Flutter applications.

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table Of Contents

Introduction

Implementation

Conclusion

GitHub Link


Introduction:

A Flutter Charts library which includes data visualization widgets such as bar charts, circular charts, and line charts, to create real-time, interactive, high-performance, animated charts.

To render a Flutter chart utilizing JSON data, you can utilize the deserialization idea. This includes changing the JSON data over completely to a Dart list object. You can then utilize the deserialized list object as chart data for a Flutter Cartesian chart.

Here are some ways to export charts in Flutter:
  • > SfCartesianChart: Exports Cartesian charts as PNG images or PDF documents
  • > Syncfusion’s Flutter DataGrid export library: Exports Flutter DataGrids to Excel and PDF formats

Implementation:

Let’s see how to Implement Chart Rendering in Different Formats.

First Add the dependencies in pubsec.yaml file
dependencies:
syncfusion_flutter_charts: ^22.2.8

Alright, now we will work on further implementation for:

> Bar Chart

> Line Chart

> Pie Chart

First Add the dependencies in pubsec.yaml file
path_provider: ^2.1.0
open_file: ^3.3.2
syncfusion_flutter_pdf: ^22.2.12
syncfusion_flutter_xlsio:

Now we will design the Home Screen UI:

Bar Chart:

We will create a new class BarChartView() class. In this class, we will add barChartData is equal to the array bracket. In the body part, we will add a column widget. In this widget, we will add the BarChartViewWidget() method.

import 'package:flutter/material.dart';
import 'package:render_chart_and_chart_data_in_multiple_form/widgets/custom_button.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

import '../constants/app_text_style.dart';
import '../constants/color_constants.dart';
import '../constants/dimension_constants.dart';
import '../helper/app_helper.dart';
import '../helper/size_helper.dart';
import '../model/bar_chart_data_model.dart';
import '../resources/assets.gen.dart';
import '../widgets/bar_chart_view_widget.dart';

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

@override
State<BarChartView> createState() => _BarChartViewState();
}

class _BarChartViewState extends State<BarChartView> {
List<BarChartDataModel> barChartData = [];
bool isLoading = false;
late GlobalKey<SfCartesianChartState> barChartKey;
late TooltipBehavior barChartToolTipBehavior;

_initializeData() async {
setState(() {
isLoading = true;
});

barChartData = [
(BarChartDataModel(x: '1', y1: 5, y2: 11, y3: 15, y4: 8)),
(BarChartDataModel(x: '2', y1: 15, y2: 17, y3: 8, y4: 2)),
(BarChartDataModel(x: '3', y1: 20, y2: 18, y3: 9, y4: 6)),
(BarChartDataModel(x: '4', y1: 8, y2: 9, y3: 2, y4: 10)),
(BarChartDataModel(x: '5', y1: 15, y2: 9, y3: 7, y4: 4))
];
await Future.delayed(const Duration(seconds: 1));
setState(() {
isLoading = false;
});
}

@override
initState() {
barChartKey = GlobalKey();
barChartToolTipBehavior = TooltipBehavior(
enable: true,
tooltipPosition: TooltipPosition.pointer,
);
_initializeData();
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Icon(
Icons.arrow_back_ios_new,
color: ColorConstants.radicalRed,
),
),
title: Text('Bar Chart Demo',
style: AppTextStyles.boldText(
fontSize: Dimensions.px20, color: ColorConstants.radicalRed)),
),
body: isLoading
? const Center(
child: CircularProgressIndicator(
color: ColorConstants.radicalRed,
),
)
: Padding(
padding: const EdgeInsets.symmetric(
horizontal: Dimensions.px10, vertical: Dimensions.px10),
child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
BarChartViewWidget(
maximumPoint: Dimensions.px60,
intervalPoint: Dimensions.px10,
key: barChartKey,
chartData: barChartData,
toolTip: barChartToolTipBehavior,
),
SizeHelper.h2(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Download as',
style: AppTextStyles.boldText(
fontSize: Dimensions.px22,
color: ColorConstants.radicalRed),
),
MyAssets.download.svg(),
],
),
SizeHelper.h2(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderChartAsImage(barChartKey, false);
},
label: 'PNG Image',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.png_file.svg(),
),
),
SizeHelper.w2(),
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderPDF(barChartKey, false);
},
label: 'PDF File',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.pdf_file.svg(),
),
),
],
),
SizeHelper.h1(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderChartAsExcel(
barChartData, false);
},
label: 'Excel (xls)',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.xls_file.svg(),
),
),
],
),
],
),
),
);
}
}

In this method, we will add maximumPoint, intervalPoint, key, chartData, and toolTip. Now we will add three custom buttons PNG Image, PDF File, and Excel (xls) for the download bar chart in these formats.

When we run the application, we ought to get the screen’s output like the underneath screen Capture.
Bar Chart Output

Line Chart:

We will create a new class LineChartView() class. In this class, we will add lineChartData is equal to the array bracket. In the body part, we will add a column widget. In this widget, we will add the LineChartViewWidget() method.

import 'package:flutter/material.dart';
import 'package:render_chart_and_chart_data_in_multiple_form/model/line_chart_data_model.dart';
import 'package:render_chart_and_chart_data_in_multiple_form/widgets/custom_button.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

import '../constants/app_text_style.dart';
import '../constants/color_constants.dart';
import '../constants/dimension_constants.dart';
import '../helper/app_helper.dart';
import '../helper/size_helper.dart';
import '../resources/assets.gen.dart';
import '../widgets/line_chart_view_widget.dart';

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

@override
State<LineChartView> createState() => _LineChartViewState();
}

class _LineChartViewState extends State<LineChartView> {
List<LineChartDataModel> lineChartData = [];
bool isLoading = false;
late GlobalKey<SfCartesianChartState> lineChartKey;
late TooltipBehavior lineChartToolTipBehavior;

_initializeData() async {
setState(() {
isLoading = true;
});

lineChartData = [
(LineChartDataModel(x: 'Jan', y: 10)),
(LineChartDataModel(x: 'Fab', y: 40)),
(LineChartDataModel(x: 'Mar', y: 30)),
(LineChartDataModel(x: 'Apr', y: 50)),
(LineChartDataModel(x: 'May', y: 5)),
];
await Future.delayed(const Duration(seconds: 1));
setState(() {
isLoading = false;
});
}

@override
initState() {
lineChartKey = GlobalKey();
lineChartToolTipBehavior = TooltipBehavior(
enable: true,
);
_initializeData();
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Icon(
Icons.arrow_back_ios_new,
color: ColorConstants.radicalRed,
),
),
title: Text('Line Chart Demo',
style: AppTextStyles.boldText(
fontSize: Dimensions.px20, color: ColorConstants.radicalRed)),
),
body: isLoading
? const Center(
child: CircularProgressIndicator(
color: ColorConstants.radicalRed,
),
)
: Padding(
padding: const EdgeInsets.symmetric(
horizontal: Dimensions.px10, vertical: Dimensions.px10),
child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
LineChartViewWidget(
maximumPoint: Dimensions.px60,
intervalPoint: Dimensions.px10,
key: lineChartKey,
lineChartData: lineChartData,
toolTip: lineChartToolTipBehavior,
),
SizeHelper.h2(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Download as',
style: AppTextStyles.boldText(
fontSize: Dimensions.px22,
color: ColorConstants.radicalRed),
),
MyAssets.download.svg(),
],
),
SizeHelper.h2(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderChartAsImage(
lineChartKey, false);
},
label: 'PNG Image',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.png_file.svg(),
),
),
SizeHelper.w2(),
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderPDF(lineChartKey, false);
},
label: 'PDF File',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.pdf_file.svg(),
),
),
],
),
SizeHelper.h1(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderChartAsExcel(
lineChartData, true);
},
label: 'Excel (xls)',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.xls_file.svg(),
),
),
],
),
],
),
),
);
}
}

In this method, we will add maximumPoint, intervalPoint, key, linechartData, and toolTip. Same as above we will add three custom buttons PNG Image, PDF File, and Excel (xls) for the download line chart in these formats.

When we run the application, we ought to get the screen’s output like the underneath screen Capture.
Line Chart Output

Pie Chart:

We will create a new class PieChartView() class. In this class, we will add pieChartData is equal to the array bracket. In the body part, we will add a column widget. In this widget, we will add the RepaintBoundary() method.

import 'package:flutter/material.dart';
import 'package:render_chart_and_chart_data_in_multiple_form/widgets/custom_button.dart';

import '../constants/app_text_style.dart';
import '../constants/color_constants.dart';
import '../constants/dimension_constants.dart';
import '../helper/app_helper.dart';
import '../helper/size_helper.dart';
import '../model/pie_chart_data_model.dart';
import '../resources/assets.gen.dart';
import '../widgets/pie_chart_view_widget.dart';

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

@override
State<PieChartView> createState() => _PieChartViewState();
}

class _PieChartViewState extends State<PieChartView> {
List<PieChartDataModel> pieChartData = [];
bool isLoading = false;
late GlobalKey pieChartKey;

_initializeData() async {
setState(() {
isLoading = true;
});

pieChartData = [
(PieChartDataModel(
x: 'Jan',
y: 15,
z: ColorConstants.radicalRed,
)),
(PieChartDataModel(
x: 'Fab',
y: 10,
z: ColorConstants.purple,
)),
(PieChartDataModel(
x: 'Mar',
y: 20,
z: ColorConstants.semiGrey,
)),
(PieChartDataModel(
x: 'Apr',
y: 20,
z: ColorConstants.laPalma,
)),
(PieChartDataModel(
x: 'May',
y: 20,
z: ColorConstants.grey,
)),
];
await Future.delayed(const Duration(seconds: 1));
setState(() {
isLoading = false;
});
}

@override
initState() {
pieChartKey = GlobalKey();
_initializeData();
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Icon(
Icons.arrow_back_ios_new,
color: ColorConstants.radicalRed,
),
),
title: Text('Pie Chart Demo',
style: AppTextStyles.boldText(
fontSize: Dimensions.px20, color: ColorConstants.radicalRed)),
),
body: isLoading
? const Center(
child: CircularProgressIndicator(
color: ColorConstants.radicalRed,
),
)
: Padding(
padding: const EdgeInsets.symmetric(
horizontal: Dimensions.px10, vertical: Dimensions.px10),
child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
RepaintBoundary(
key: pieChartKey,
child: PieChartViewWidget(pieChartData: pieChartData),
),
SizeHelper.h2(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Download as',
style: AppTextStyles.boldText(
fontSize: Dimensions.px22,
color: ColorConstants.radicalRed),
),
MyAssets.download.svg(),
],
),
SizeHelper.h2(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderChartAsImage(pieChartKey, true);
},
label: 'PNG Image',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.png_file.svg(),
),
),
SizeHelper.w2(),
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderPDF(pieChartKey, true);
},
label: 'PDF File',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.pdf_file.svg(),
),
),
],
),
SizeHelper.h1(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: CustomButton(
onTap: () {
AppHelper.getRenderChartAsExcel(pieChartData, true);
},
label: 'Excel (xls)',
style: AppTextStyles.semiBoldText(
fontSize: Dimensions.px16,
color: ColorConstants.white),
iconWidget: MyAssets.xls_file.svg(),
),
),
],
),
],
),
),
);
}
}

In this method, we will add a key and a child. In child was PieChartViewWidget(pieChartData: pieChartData) . Same as above we will add three custom buttons PNG Image, PDF File, and Excel (xls) for the download line chart in these formats.

When we run the application, we ought to get the screen’s output like the underneath screen Capture.

Pie Chart Output

Alright, now we will implement the download Functionality part:

> Export in PNG format

> Export in PDF format

> Export in Excel (.xls) format

Export in PNG Format:

We will create getRenderChartAsImage() method:

static Future<void> getRenderChartAsImage(
dynamic cartesianChartKey, bool isPieChart) async {
final Directory directory = await getApplicationSupportDirectory();
final String path = directory.path;
File file = File('$path/ChartImageOutput.png');
if (isPieChart) {
final RenderRepaintBoundary boundary =
cartesianChartKey.currentContext.findRenderObject();

final ui.Image image = await boundary.toImage();

final ByteData? byteData =
await image.toByteData(format: ui.ImageByteFormat.png);

final Uint8List? pngBytes = byteData?.buffer.asUint8List();
final Uint8List imageBytes = pngBytes!.buffer
.asUint8List(pngBytes.offsetInBytes, pngBytes.lengthInBytes);
await file.writeAsBytes(imageBytes, flush: true);
} else {
final ui.Image data =
await cartesianChartKey.currentState!.toImage(pixelRatio: 3.0);
final ByteData? bytes =
await data.toByteData(format: ui.ImageByteFormat.png);
final Uint8List imageBytes =
bytes!.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes);
await file.writeAsBytes(imageBytes, flush: true);
}

OpenFile.open('$path/ChartImageOutput.png');
}

When we run the application, we ought to get the screen’s output like the underneath screen Capture.

Output

Export in PDF Format:

We will create getRenderPDF() method:

static Future<void> getRenderPDF(
dynamic cartesianChartKey, isPieChart) async {
final Directory directory = await getApplicationSupportDirectory();
final String path = directory.path;
File file = File('$path/ChartPdfOutput.pdf');
final List<int> imageBytes =
await _readImageData(cartesianChartKey, isPieChart);
final PdfBitmap bitmap = PdfBitmap(imageBytes);
final PdfDocument document = PdfDocument();
if (isPieChart) {
document.pageSettings.orientation = PdfPageOrientation.landscape;
}

document.pageSettings.size =
Size(bitmap.width.toDouble(), bitmap.height.toDouble());
final PdfPage page = document.pages.add();
final Size pageSize = page.getClientSize();
page.graphics.drawImage(
bitmap, Rect.fromLTWH(0, 0, pageSize.width, pageSize.height));
final List<int> bytes = document.saveSync();
document.dispose();

await file.writeAsBytes(bytes, flush: true);
OpenFile.open('$path/ChartPdfOutput.pdf');
}

We will create _readImageData() method:

static Future<List<int>> _readImageData(cartesianChartKey, isPieChart) async {
if (isPieChart) {
final RenderRepaintBoundary boundary =
cartesianChartKey.currentContext.findRenderObject();

final ui.Image image = await boundary.toImage();

final ByteData? byteData =
await image.toByteData(format: ui.ImageByteFormat.png);

final Uint8List? pngBytes = byteData?.buffer.asUint8List();
return pngBytes!.buffer
.asUint8List(pngBytes.offsetInBytes, pngBytes.lengthInBytes);
} else {
final ui.Image data =
await cartesianChartKey.currentState!.toImage(pixelRatio: 3.0);
final ByteData? bytes =
await data.toByteData(format: ui.ImageByteFormat.png);

return bytes!.buffer
.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes);
}
}

When we run the application, we ought to get the screen’s output like the underneath screen Capture.

Output

Export in Excel (.xls) Format:

We will create getRenderChartAsExcel() method:

static Future<void> getRenderChartAsExcel(
List<dynamic> data, bool isLineChart) async {
final Directory directory = await getApplicationSupportDirectory();
final String path = directory.path;
final xcel.Workbook workbook = xcel.Workbook();
final xcel.Worksheet sheet = workbook.worksheets[0];

if (!isLineChart) {
sheet.getRangeByIndex(1, 1).setText("Sr.");
sheet.getRangeByIndex(1, 2).setText("Pending");
sheet.getRangeByIndex(1, 3).setText("Resolve-Requested");
sheet.getRangeByIndex(1, 4).setText("Resolve");
sheet.getRangeByIndex(1, 5).setText("Closed");
sheet.autoFitColumn(3);

for (var i = 0; i < data.length; i++) {
final item = data[i];
sheet.getRangeByIndex(i + 2, 1).setText(item.x);
sheet.getRangeByIndex(i + 2, 2).setText(item.y1.toString());
sheet.getRangeByIndex(i + 2, 3).setText(item.y2.toString());
sheet.getRangeByIndex(i + 2, 4).setText(item.y3.toString());
sheet.getRangeByIndex(i + 2, 5).setText(item.y4.toString());
}
final List<int> bytes = workbook.saveAsStream();
File file = File('$path/BarChartOutput.xlsx');
await file.writeAsBytes(bytes, flush: true);

await OpenFile.open('$path/BarChartOutput.xlsx');
AppLogger.log('data list :${file.lengthSync()}');
} else {
sheet.getRangeByIndex(1, 1).setText("Month");
sheet.getRangeByIndex(1, 2).setText(" Value ");
sheet.autoFitColumn(2);

for (var i = 0; i < data.length; i++) {
final item = data[i];
sheet.getRangeByIndex(i + 2, 1).setText(item.x);
sheet.getRangeByIndex(i + 2, 2).setText(item.y.toString());
}
final List<int> bytes = workbook.saveAsStream();
File file = File('$path/LineChartOutput.xlsx');
await file.writeAsBytes(bytes, flush: true);

await OpenFile.open('$path/LineChartOutput.xlsx');
}
workbook.dispose();
}

When we run the application, we ought to get the screen’s output like the underneath screen Capture.

Output

Conclusion:

In the article, I have explained the Chart Export in Different Formats In Flutter; you can modify this code according to your choice. This was a small introduction to the Chart Export in Different Formats In Flutter User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on Trying Chart Export in Different Formats in your Flutter projects. We will show you what the Introduction is. Make a demo program for working on chart export in different formats in your Flutter applications. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


GitHub Link:

You can check out Implement Chart Export in Different Formats In Flutter on GitHub. We hope you enjoyed this tutorial

GitHub — rahul-t-aeologic/render_chart_and_chart_data_in_multiple_form: Implement Chart Rendering…
Implement Chart Rendering in Different Formats. Contribute to…github.com


Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a Flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on Facebook, GitHub, Twitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.


Leave comment

Your email address will not be published. Required fields are marked with *.