如何在Flutter中通过WebView下载/创建pdf

Sma*_*Dev 5 dart flutter flutter-dependencies flutter-layout

我创建了一个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();
                }),
          ),
        ],
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

我希望,当我单击Web视图中的“打印”或“下载”按钮时,它应该像任何其他浏览器一样工作。

Lor*_*lli 5

您可以使用我的插件flutter_inappwebview,这是一个 Flutter 插件,允许您添加内联 WebView 或打开应用内浏览器窗口,并且有很多事件、方法和选项来控制 WebView。

\n\n

为了能够识别可下载的文件,您需要设置该useOnDownloadStart: true选项,然后您就可以监听onDownloadStart\xc2\xa0事件!

\n\n

另外,例如,在 Android 上,您需要在AndroidManifest.xml文件中添加写入权限:

\n\n
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后,您需要使用permission_handler插件请求许可。相反,要有效下载文件,您可以使用flutter_downloader插件。

\n\n

以下是使用http://ovh.net/files/(特别是http://ovh.net/files/1Mio.dat作为 URL)来测试下载的完整示例:

\n\n
import \'dart:async\';\nimport \'package:flutter/material.dart\';\nimport \'package:flutter_inappwebview/flutter_inappwebview.dart\';\nimport \'package:flutter_downloader/flutter_downloader.dart\';\nimport \'package:path_provider/path_provider.dart\';\nimport \'package:permission_handler/permission_handler.dart\';\n\nFuture main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  await FlutterDownloader.initialize(\n      debug: true // optional: set false to disable printing logs to console\n  );\n  await Permission.storage.request();\n  runApp(new MyApp());\n}\n\nclass MyApp extends StatefulWidget {\n  @override\n  _MyAppState createState() => new _MyAppState();\n}\n\nclass _MyAppState extends State<MyApp> {\n  InAppWebViewController webView;\n\n  @override\n  void initState() {\n    super.initState();\n  }\n\n  @override\n  void dispose() {\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        appBar: AppBar(\n          title: const Text(\'InAppWebView Example\'),\n        ),\n        body: Container(\n            child: Column(children: <Widget>[\n          Expanded(\n              child: InAppWebView(\n            initialUrl: "http://ovh.net/files/1Mio.dat",\n            initialHeaders: {},\n            initialOptions: InAppWebViewGroupOptions(\n              crossPlatform: InAppWebViewOptions(\n                debuggingEnabled: true,\n                useOnDownloadStart: true\n              ),\n            ),\n            onWebViewCreated: (InAppWebViewController controller) {\n              webView = controller;\n            },\n            onLoadStart: (InAppWebViewController controller, String url) {\n\n            },\n            onLoadStop: (InAppWebViewController controller, String url) {\n\n            },\n            onDownloadStart: (controller, url) async {\n              print("onDownloadStart $url");\n              final taskId = await FlutterDownloader.enqueue(\n                url: url,\n                savedDir: (await getExternalStorageDirectory()).path,\n                showNotification: true, // show download progress in status bar (for Android)\n                openFileFromNotification: true, // click on notification to open downloaded file (for Android)\n              );\n            },\n          ))\n        ])),\n      ),\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这里,如您所见,我还使用path_provider插件来获取我想要保存文件的文件夹。

\n


Fri*_*dka 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);
}
Run Code Online (Sandbox Code Playgroud)

在 Flutter 代码中添加监听器:

StreamSubscription<String> _onWebViewUrlChanged;
_onWebViewUrlChanged =
    FlutterWebviewPlugin().onUrlChanged.listen((String url) {
      if (url.contains('.pdf')) {
        launchURL(url);
      }
});
Run Code Online (Sandbox Code Playgroud)

launchURL 将在外部浏览器窗口中打开预定义的 url。所以你可以从 flutter_webview_plugin 下载 pdf/etc。

您应该添加一些特定于应用程序的 js/flutter 魔法