Flutter

Création d’une application de visualisation et de téléchargement de document PDF dans Flutter

31 mai 2022

Dans ce tutoriel, nous allons créer une application pour visualiser et télécharger un document PDF dans Flutter. Il s'agira d'une jolie petite application que vous pourrez réaliser facilement. Nous allons permettre aux utilisateurs de télécharger, stocker et plus tard visualiser leurs fichiers PDF en ligne et en locale. S'ils le souhaitent, ils pourront également les télécharger.

Préparation de l’environnement de travail

Pour commencer, vous aurez besoin de :

Pour commencer, ajoutez les dépendances suivantes dans votre fichier pubspec.yaml :

cupertino_icons: ^1.0.2
  dio: ^4.0.6
  file_picker: ^4.5.1
  flutter_pdfview: ^1.2.2
  http: ^0.13.4
  path_provider: ^2.0.10
  path: ^1.8.0
  permission_handler: ^9.2.0

Puis importez les dépendances suivantes :

import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:path_provider/path_provider.dart';
import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';

Pour mettre à jour, importez les paquets Flutter get dans le répertoire racine.

Implanter notre code dans un fichier Dart

Pour ce faire, nous allons créer un fichier pdf_viewer_page.dart dans le dossier lib. Cette page nous permettra de visualiser le PDF.

Widget build(BuildContext context) {
  final name = basename(widget.file.path);
  return Scaffold(
    appBar: AppBar(
      title: Text(name),
      actions: [
        IconButton(
          onPressed: () async {
            await saveFile(widget.url, "sample.pdf");
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                content: Text(
                  'success',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            );
          },
          icon: const Icon(Icons.download_rounded),
        ),
      ],
    ),
    body: PDFView(
      filePath: widget.file.path,
    ),
  );
}

Pour rendre les choses plus intéressantes, nous allons créer une fonction saveFile() pour sauvegarder notre fichier en locale.

Future<bool> saveFile(String url, String fileName) async {
  try {
    if (await _requestPermission(Permission.storage)) {
      Directory? directory;
      directory = await getExternalStorageDirectory();
      String newPath = "";
      List<String> paths = directory!.path.split("/");
      for (int x = 1; x < paths.length; x++) {
        String folder = paths[x];
        if (folder != "Android") {
          newPath += "/" + folder;
        } else {
          break;
        }
      }
      newPath = newPath + "/PDF_Download";
      directory = Directory(newPath);

      File saveFile = File(directory.path + "/$fileName");
      if (kDebugMode) {
        print(saveFile.path);
      }
      if (!await directory.exists()) {
        await directory.create(recursive: true);
      }
      if (await directory.exists()) {
        await Dio().download(
          url,
          saveFile.path,
        );
      }
    }
    return true;
  } catch (e) {
    return false;
  }
}

Dans le fichier main.dart à l'intérieur du dossier lib, nous allons permettre à l'utilisateur de choisir entre deux boutons : l'un pour choisir un fichier en locale et l'autre pour l'ouvrir directement en ligne. Ces deux boutons sont liés aux deux fonctions pickFile() et loadFromNetwork().

Pour l'accès au fichier local, le code sera :

Future<File?> pickFile() async {
  final result = await FilePicker.platform.pickFiles(
    type: FileType.custom,
    allowedExtensions: ['pdf'],
  );
  if (result == null) return null;
  return File(result.paths.first ?? '');
}

Et pour visionner un fichier en ligne, le code sera :

Future<File> loadPdfFromNetwork(String url) async {
  final response = await http.get(Uri.parse(url));
  final bytes = response.bodyBytes;
  return _storeFile(url, bytes);
}

Future<File> _storeFile(String url, List<int> bytes) async {
  final filename = basename(url);

Maintenant, nous allons implémenter une fonction qui vous redirigera vers la page pdf_viewer_page.dart. Cela nous permettra de charger les fichiers localement directement en ligne.

void openPdf(BuildContext context, File file, String url) =>
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => PdfViewerPage(
          file: file,
          url: url,
        ),
      ),
    );

Le fichier maint.dart doit ressembler à ça :

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:io';

import 'package:file_picker/file_picker.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf_viewer_and_downloader_example/pdf_viewer_page.dart';
import 'package:http/http.dart' as http;
import 'package:pdf_viewer_and_downloader_example/splash_screen.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.orange,
      ),
      home: const Splash(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    Key? key,
  }) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: const Center(
          child: Text('Voir  & Teléchargez votre fichier PDF'),
        ),
      ),
      backgroundColor: Colors.deepOrange,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: ElevatedButton(
                style: ButtonStyle(
                  backgroundColor:
                      MaterialStateProperty.all<Color>(Colors.amber),
                ),
                onPressed: () async {
                  String url = '';
                  final file = await pickFile();
                  if (file == null) return;
                  openPdf(context, file, url);
                },
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text(
                    'Teléchargez le fichier en local',
                    style: TextStyle(color: Colors.black),
                  ),
                ),
              ),
            ),
            const SizedBox(height: 10),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: ElevatedButton(
                style: ButtonStyle(
                  backgroundColor:
                      MaterialStateProperty.all<Color>(Colors.amber),
                ),
                onPressed: () async {
                  const url =
                      "http://www.africau.edu/images/default/sample.pdf";
                  final file = await loadPdfFromNetwork(url);
                  openPdf(context, file, url);
                },
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text(
                    'Téléchargez le fichier en ligne',
                    style: TextStyle(color: Colors.black),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<File?> pickFile() async {
    final result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['pdf'],
    );
    if (result == null) return null;
    return File(result.paths.first ?? '');
  }

  Future<File> loadPdfFromNetwork(String url) async {
    final response = await http.get(Uri.parse(url));
    final bytes = response.bodyBytes;
    return _storeFile(url, bytes);
  }

  Future<File> _storeFile(String url, List<int> bytes) async {
    final filename = basename(url);
    final dir = await getApplicationDocumentsDirectory();
    final file = File('${dir.path}/$filename');
    await file.writeAsBytes(bytes, flush: true);
    if (kDebugMode) {
      print('$file');
    }
    return file;
  }

  //final file = File('example.pdf');
  //await file.writeAsBytes(await pdf.save());

  void openPdf(BuildContext context, File file, String url) =>
      Navigator.of(context).push(
        MaterialPageRoute(
          builder: (context) => PdfViewerPage(
            file: file,
            url: url,
          ),
        ),
      );
}


Nous avons fini. Lorsque vous exécutez l'application, vous devrez avoir un rendu qui ressemble à la capture d’écran ci-dessous.

Félicitations pour avoir terminé ce tutoriel. Vous savez à présent comment créer une application de visualisation et de téléchargement de documents PDF dans Flutter.

Si vous cherchez à devenir un mentor, un formateur ou même un étudiant en Flutter, Xarala vous ouvre ces portes. Vous pouvez vous inscrire via ce lien : www.xarala.co.

Xarala Academy

Xarala Academy est une solution d’E-Learning qui offre des formations de qualités répondant à la demande du marché.

Super ! Vous vous êtes inscrit avec succès.
Super ! Effectuez le paiement pour obtenir l'accès complet.
Bon retour parmi nous ! Vous vous êtes connecté avec succès.
Parfait ! Votre compte est entièrement activé, vous avez désormais accès à tout le contenu.