如何在Flutter中从网络加载和呈现PDF文件 [英] How to load and present a PDF file from the web in Flutter
问题描述
我正试图从URL提取PDF文件,并将其显示在Flutter应用程序中(适用于Android和iOS)。
我已经在Web和SO上搜索了有关如何在Flutter中呈现获取的PDF文件的答案,但是我所能找到的就是如何呈现本地预添加的PDF文件。
我也搜索了相同的软件包,但找不到有效的软件包。
示例:
我正在尝试获取此 PDF文件,然后将其显示在我的应用程序的Flutter小部件屏幕内。
有人知道我该怎么做到吗?
谢谢!
使用flutter_pdfview包。
- 在Android清单中添加权限
< Uses-permission android:name =" android.permission.INTERNET" />
< uses-permission android:name = android.permission.WRITE_EXTERNAL_STORAGE />
- 在pubspec.yaml中添加依赖项
依赖性:
$ p $的许可p>
颤动:
sdk:颤动
flutter_pdfview:^ 1.0.1
http:^ 0.12.0 + 4
path_provider:任何
Permission_handler:4.4.0 //用于请求加载pdf
- 然后使用PDFView
完整代码:
import'package:flutter / material.dart';
import‘package:flutter_pdfview / flutter_pdfview.dart’;
导入 dart:io;
导入 package:http / http.dart为http;
import‘package:path_provider / path_provider.dart’;
import‘package:permission_handler / permission_handler.dart’;
void main(){
runApp(MyApp());
}
类MyApp扩展了StatelessWidget {
@override
Widget build(BuildContext context){
return MaterialApp(
title:'Flutter演示'',
主题:ThemeData(
primarySwatch:Colors.blue,
visualDensity:VisualDensity.adaptivePlatformDensity,
),
主页:MyHomePage(title:'Flutter Demo主页'),
);
}
}
类MyHomePage扩展了StatefulWidget {
MyHomePage({Key key,this.title}):super(key:key);
最终字符串标题;
@override
_MyHomePageState createState()=> _MyHomePageState();
}
类_MyHomePageState扩展State< MyHomePage> {
字符串urlPDFPath =;
bool存在= true;
int _totalPages = 0;
int _currentPage = 0;
bool pdfReady = false;
PDFViewController _pdfViewController;
bool loading = false;
Future< File> getFileFromUrl(String url,{name})异步{
var fileName =‘testonline’;
if(name!= null){
fileName =名称;
}
try {
var data = await http.get(url);
var bytes = data.bodyBytes;
var dir =等待getApplicationDocumentsDirectory();
文件file = File( $ {dir.path} / + fileName + .pdf);
print(dir.path);
文件urlFile =等待file.writeAsBytes(bytes);
返回urlFile;
} catch(e){
throw Exception(打开网址文件时出错);
}
}
void requestPersmission()async {
await PermissionHandler()。requestPermissions([PermissionGroup.storage]);
}
@override
void initState(){
requestPersmission();
getFileFromUrl( http://www.africau.edu/images/default/sample.pdf)。然后(
(值)=> {
setState((){
if(value!= null){
urlPDFPath = value.path;
loading = true;
存在= true;
} else {
存在= false;
}
})
},
);
super.initState();
}
@override
小部件构建(BuildContext上下文){
print(urlPDFPath);
if(loaded){
return Scaffold(
body:PDFView(
filePath:urlPDFPath,
autoSpacing:true,
enableSwipe:true,
pageSnap:true,
swipeHorizontal:true,
nightMode:false,
onError:(e){
//显示一些错误消息或UI
},
onRender:(_pages){
setState((){
_totalPages = _pages;
pdfReady = true;
});
},
onViewCreated:(PDFViewController vc){
setState((){
_pdfViewController = vc;
});
},
onPageChanged:(int page,int总计){
setState((){
_currentPage = page;
});
},
onPageError:(page,e){},
),
floatActionButton:行(
mainAxisAlignment:MainAxisAlignment.end,
儿童:< Widget> [
IconButton(
icon:Icon(Icons.chevron_left),
iconSize:50,
color :Colors.black,$ Presse:
:(){
setState((){
if(_currentPage> 0){
_currentPage--;
_pdfViewController.setPage(_currentPage);
}
});
},
),
Text(
" $ {_ currentPage + 1} / $ _ totalPages" ;,
样式: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){
//用您的加载UI替换
return Scaffold(
appBar:AppBar(
title:Text( 演示),
),
正文:Text(
loading ..,
样式:TextStyle(fontSize:20),
) ,
);
} else {
//替换错误UI
返回Scaffold(
appBar:AppBar(
title:Text( Demo)),
) ,
正文:Text(
" PDF Not Available),
样式:TextStyle(fontSize:20),
),
);
}
}
}
}
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.
- Add Permission in android manifest
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Add the dependencies in pubspec.yaml
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
- Then use the PDFView
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), ), ); } } } }
这篇关于如何在Flutter中从网络加载和呈现PDF文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!