I'm trying to fetch a PDF file from a URL, and to present it in my Flutter app (for both Android and iOS).
I've searched the web and SO for answers on how to present a fetched PDF file in Flutter, but all I could find was how to present a locally pre-added PDF file.
I've also searched for packages doing the same, but I couldn't find one that worked.
Example:
I'm trying to fetch this PDF file for example, and to present it inside a Flutter widget screen in my app.
Does anyone know how can I achieve that?
Thank you!
Use flutter_pdfview package.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
dependencies:
flutter:
sdk: flutter
flutter_pdfview: ^1.0.1
http: ^0.12.0+4
path_provider: any
permission_handler: 4.4.0 //For asking permission to load the pdf
Full Code:
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String urlPDFPath = "";
bool exists = true;
int _totalPages = 0;
int _currentPage = 0;
bool pdfReady = false;
PDFViewController _pdfViewController;
bool loaded = false;
Future<File> getFileFromUrl(String url, {name}) async {
var fileName = 'testonline';
if (name != null) {
fileName = name;
}
try {
var data = await http.get(url);
var bytes = data.bodyBytes;
var dir = await getApplicationDocumentsDirectory();
File file = File("${dir.path}/" + fileName + ".pdf");
print(dir.path);
File urlFile = await file.writeAsBytes(bytes);
return urlFile;
} catch (e) {
throw Exception("Error opening url file");
}
}
void requestPersmission() async {
await PermissionHandler().requestPermissions([PermissionGroup.storage]);
}
@override
void initState() {
requestPersmission();
getFileFromUrl("http://www.africau.edu/images/default/sample.pdf").then(
(value) => {
setState(() {
if (value != null) {
urlPDFPath = value.path;
loaded = true;
exists = true;
} else {
exists = false;
}
})
},
);
super.initState();
}
@override
Widget build(BuildContext context) {
print(urlPDFPath);
if (loaded) {
return Scaffold(
body: PDFView(
filePath: urlPDFPath,
autoSpacing: true,
enableSwipe: true,
pageSnap: true,
swipeHorizontal: true,
nightMode: false,
onError: (e) {
//Show some error message or UI
},
onRender: (_pages) {
setState(() {
_totalPages = _pages;
pdfReady = true;
});
},
onViewCreated: (PDFViewController vc) {
setState(() {
_pdfViewController = vc;
});
},
onPageChanged: (int page, int total) {
setState(() {
_currentPage = page;
});
},
onPageError: (page, e) {},
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
IconButton(
icon: Icon(Icons.chevron_left),
iconSize: 50,
color: Colors.black,
onPressed: () {
setState(() {
if (_currentPage > 0) {
_currentPage--;
_pdfViewController.setPage(_currentPage);
}
});
},
),
Text(
"${_currentPage + 1}/$_totalPages",
style: TextStyle(color: Colors.black, fontSize: 20),
),
IconButton(
icon: Icon(Icons.chevron_right),
iconSize: 50,
color: Colors.black,
onPressed: () {
setState(() {
if (_currentPage < _totalPages - 1) {
_currentPage++;
_pdfViewController.setPage(_currentPage);
}
});
},
),
],
),
);
} else {
if (exists) {
//Replace with your loading UI
return Scaffold(
appBar: AppBar(
title: Text("Demo"),
),
body: Text(
"Loading..",
style: TextStyle(fontSize: 20),
),
);
} else {
//Replace Error UI
return Scaffold(
appBar: AppBar(
title: Text("Demo"),
),
body: Text(
"PDF Not Available",
style: TextStyle(fontSize: 20),
),
);
}
}
}
}