如何在flutter中通过webview下载/创建pdf
Posted
技术标签:
【中文标题】如何在flutter中通过webview下载/创建pdf【英文标题】:how to download/create pdf through webview in flutter 【发布时间】:2019-10-08 09:27:52 【问题描述】:我创建了一个 webviewscaffold,但在从 webview 浏览时无法从中下载任何内容,我创建了但是当我单击按钮时它什么也不做。我不知道从哪里开始,就像在其他可以下载和预览的浏览器中一样,我正在尝试在这里实现相同的目标。
class AppState extends State<App>
@override
Widget build(BuildContext context)
return Scaffold(
body: Stack(
children: <Widget>[
Align(
alignment: Alignment(1, 1),
child: Container(
child: Web(), // it is a statefulwidget that have WebviewScaffold, i have created it on a new page and imported/used here
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 20.0),
)
],
),
Align(
alignment: Alignment(0.7, -0.93),
child: FloatingActionButton(
tooltip: "Share",
child: Icon(
Icons.share,
color: Colors.amberAccent,
),
onPressed: ()
_onShareTap();
),
),
],
),
);
我希望,当我单击 web 视图中的打印或下载按钮时,它应该像任何其他浏览器一样工作。
【问题讨论】:
@user10182490 你找到解决办法了吗? 【参考方案1】:你可以使用我的插件flutter_inappwebview,这是一个 Flutter 插件,允许你添加内联 WebViews 或打开一个应用内浏览器窗口,并且有很多事件、方法和选项来控制 WebViews。
为了能够识别可下载的文件,您需要设置useOnDownloadStart: true
选项,然后您才能监听onDownloadStart
事件!
另外,例如,在 android 上,您需要在 AndroidManifest.xml
文件中添加写入权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
然后,您需要使用permission_handler 插件请求许可。相反,为了有效地下载您的文件,您可以使用flutter_downloader 插件。
这是一个使用http://ovh.net/files/(特别是http://ovh.net/files/1Mio.dat作为URL)测试下载的完整示例:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
Future main() async
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(
debug: true // optional: set false to disable printing logs to console
);
await Permission.storage.request();
runApp(new MyApp());
class MyApp extends StatefulWidget
@override
_MyAppState createState() => new _MyAppState();
class _MyAppState extends State<MyApp>
InAppWebViewController webView;
@override
void initState()
super.initState();
@override
void dispose()
super.dispose();
@override
Widget build(BuildContext context)
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('InAppWebView Example'),
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: InAppWebView(
initialUrl: "http://ovh.net/files/1Mio.dat",
initialHeaders: ,
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
useOnDownloadStart: true
),
),
onWebViewCreated: (InAppWebViewController controller)
webView = controller;
,
onLoadStart: (InAppWebViewController controller, String url)
,
onLoadStop: (InAppWebViewController controller, String url)
,
onDownloadStart: (controller, url) async
print("onDownloadStart $url");
final taskId = await FlutterDownloader.enqueue(
url: url,
savedDir: (await getExternalStorageDirectory()).path,
showNotification: true, // show download progress in status bar (for Android)
openFileFromNotification: true, // click on notification to open downloaded file (for Android)
);
,
))
])),
),
);
在这里,如您所见,我还使用path_provider 插件来获取我要保存文件的文件夹。
【讨论】:
【参考方案2】:如果您是 html 页面的所有者,您可以查看适合我的解决方法。在您的 html 页面 的源代码中,为特定资源链接添加 onclick 功能:
function downloadpdf()
var currentHref = window.location.href;
window.history.pushState(null, null, '/app/somepdf.pdf');
setTimeout(() => window.location.replace(currentHref), 1000);
在 Flutter 代码中添加监听器:
StreamSubscription<String> _onWebViewUrlChanged;
_onWebViewUrlChanged =
FlutterWebviewPlugin().onUrlChanged.listen((String url)
if (url.contains('.pdf'))
launchURL(url);
);
launchURL 将在外部浏览器窗口中打开预定义的 url。所以你可以从flutter_webview_plugin下载pdf/etc。
您应该添加一些特定于应用的 js/flutter 魔法
【讨论】:
以上是关于如何在flutter中通过webview下载/创建pdf的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中从 NSData 显示 PDF - 如何将 PDF 保存到文档文件夹 Swift - 如何在 Swift 中通过 WebView 从保存的 NSData 显示 PDF