Articles in this section
Category / Section

How to export the cartesian chart as a pdf document (SfCartesianChart) ?

3 mins read

In this article, we explain how to export the cartesian chart as a PDF using the Flutter cartesian chart.

The SfCartesianChart widget provides an option to export the chart in PDF format. The following steps explain how to accomplish this exporting functionality.

Step 1: To access the path from mobile and other platforms, add the path_provider package as a dependency in the application. And add syncfusion_flutter_pdf package as a dependency to create and access PDF files.

  path_provider: ^2.0.9
  syncfusion_flutter_charts: ^20.1.48
  syncfusion_flutter_pdf: ^20.1.48-beta

Step 2: It is necessary to include the platform-specific file generating codes to save the file as a PDF document. So, we have created two dart files (save_file_mobile and save_file_web) to save and launch the file on different platforms. On that two dart files, we have provided the common method called saveAndLaunchFile to save the exported content as a file.

To download the PDF file in the web platform, we should add AnchorElement from dart:html in this save_file_web file.

save_file_web.dart

import 'dart:async';
import 'dart:convert';
import 'dart:html';
 
class FileSaveHelper {
  static Future<void> saveAndLaunchFile(
      List<int> bytes, String fileName) async {
    AnchorElement(
        href:
            'data:application/octet-stream;charset=utf-16le;base64,${base64.encode(bytes)}')
      ..setAttribute('download', fileName)
      ..click();
  }
}

To download the PDF file on the mobile and other platforms, we use this save_file_mobile file.

save_file_mobile.dart

import 'dart:io';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
 
class FileSaveHelper {
  static const MethodChannel _platformCall = MethodChannel('launchFile');
 
  static Future<void> saveAndLaunchFile(
      List<int> bytes, String fileName) async {
    String? path;
    if (Platform.isAndroid ||
        Platform.isIOS ||
        Platform.isLinux ||
        Platform.isWindows) {
      final Directory directory = await getApplicationSupportDirectory();
      path = directory.path;
    } else {
      path = await PathProviderPlatform.instance.getApplicationSupportPath();
    }
    final File file =
        File(Platform.isWindows ? '$path\\$fileName' : '$path/$fileName');
    await file.writeAsBytes(bytes, flush: true);
    if (Platform.isAndroid || Platform.isIOS) {
      final Map<String, String> argument = <String, String> {
        'file_path': '$path/$fileName'
      };
      try {
        final Future<Map<String, String>?> result =
            _platformCall.invokeMethod('viewPdf', argument);
      } catch (e) {
        throw Exception(e);
      }
    } else if (Platform.isWindows) {
      await Process.run('start', <String>['$path\\$fileName'],
          runInShell: true);
    } else if (Platform.isMacOS) {
      await Process.run('open', <String>['$path/$fileName'], runInShell: true);
    } else if (Platform.isLinux) {
      await Process.run('xdg-open', <String>['$path/$fileName'],
          runInShell: true);
    }
  }
}

Step 3: Initialize the variable _chartData which stores the data source and initialize the variable _cartesianChartKey which stores the global key of rendering the cartesian chart. This key is used to convert the chart into an image and we will use that image to create a PDF file.

And create the SfCartesianChart widget with the necessary properties.

//Add the necessary imports
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import '../save_file_mobile.dart'
    if (dart.library.html) '../save_file_web.dart';
import 'dart:async';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:syncfusion_flutter_pdf/pdf.dart';
 
late GlobalKey<SfCartesianChartState> _cartesianChartKey;
late List<ChartSampleData> _chartData;
 
@override
void initState() {
  _cartesianChartKey = GlobalKey();
  _chartData = < ChartSampleData >[
      ChartSampleData ('Jan', 12),
      ChartSampleData ('Feb', 28),
      ChartSampleData ('Mar', 35),
      ChartSampleData ('Apr', 27),
      ChartSampleData ('Jun', 42),
      ChartSampleData ('Jul', 33)
  ];
  super.initState();
}
 
@override
Widget build(BuildContext context) {
  return SfCartesianChart(
    key: _cartesianChartKey,
    primaryXAxis: CategoryAxis(), 
    series: <ColumnSeries< ChartSampleData, String>>[
      ColumnSeries< ChartSampleData, String>(
        dataSource: _chartData,
        xValueMapper: (ChartSampleData data, _) => data.x,
        yValueMapper: (ChartSampleData data, _) => data.y
      )
    ]
  )
}
 
class ChartSampleData {
  ChartSampleData ({this.x, this.y});
  final String? x;
  final num? y;
}

Step 4: Create a separate method called _renderPdf  where we export the chart as a PDF. Added a snack bar to notify the chart is exported as a PDF document.

Future<void> _ renderPdf () async {
  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);
  final PdfBitmap bitmap = PdfBitmap(imageBytes);
  final PdfDocument document = PdfDocument();
  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));
  await FileSaveHelper.saveAndLaunchFile(document.save(), 'cartesian_chart.pdf');
  ScaffoldMessenger.of(context).showSnackBar(
    const SnackBar(
      behavior: SnackBarBehavior.floating,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(5))
      ),
      duration: Duration(milliseconds: 200),
      content: Text('Chart has been exported as PDF document.'),
    )
  );

Step 5: Add the TextButton widget and call the _renderPdf method to convert the rendered chart as PDF.

@override
Widget build(BuildContext context) {
  return Column(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[
      SfCartesianChart(
        key: _ cartesianChartKey,
        primaryXAxis: CategoryAxis(),
        series: <ColumnSeries<ChartSampleData, String>>[
          ColumnSeries<ChartSampleData, String>(
            dataSource: _chartData,
            xValueMapper: (ChartSampleData data, _) => data.x,
            yValueMapper: (ChartSampleData data, _) => data.y,
          )
        ]
      ),
      TextButton(
        child: const Text('Export as PDF),
        onPressed: () {
          _renderPdf();
        },
      )
    ]
  );
}

Now if we tap the TextButton ,the exported PDF of the cartesian chart will be downloaded.

flutter chart - pdf export

View the sample in GitHub.

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments
Please  to leave a comment
Access denied
Access denied