Flutter WEB download option

17,217

Solution 1

Simple Code for redirecting to download URL

import 'dart:html' as html;
void downloadFile(String url) {
   html.AnchorElement anchorElement =  new html.AnchorElement(href: url);
   anchorElement.download = url;
   anchorElement.click();
}

Solution 2

One way to trigger download is the adapt a common pattern used in "native" javascript, create an anchor element with the download attribute and trigger a click.

import 'dart:convert';
import 'dart:html';

main() {
  File file = // generated somewhere
  final rawData = file.readAsBytesSync();
  final content = base64Encode(rawData);
  final anchor = AnchorElement(
      href: "data:application/octet-stream;charset=utf-16le;base64,$content")
    ..setAttribute("download", "file.txt")
    ..click();
}

Solution 3

you can use package url_launcher with url_launcher_web

then you can do:

launch("data:application/octet-stream;base64,${base64Encode(yourFileBytes)}")

EDIT: you don't need a plugin if you do this

download.dart:

import 'dart:convert';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html';

void download(
  List<int> bytes, {
  String downloadName,
}) {
  // Encode our file in base64
  final _base64 = base64Encode(bytes);
  // Create the link with the file
  final anchor =
      AnchorElement(href: 'data:application/octet-stream;base64,$_base64')
        ..target = 'blank';
  // add the name
  if (downloadName != null) {
    anchor.download = downloadName;
  }
  // trigger download
  document.body.append(anchor);
  anchor.click();
  anchor.remove();
  return;
}

empty_download.dart:

void download(
  List<int> bytes, {
  String downloadName,
}) {
  print('I do nothing');
}

import and use:

import 'empty_download.dart'
if (dart.library.html) 'download.dart';

void main () {
  download('I am a test file'.codeUnits, // takes bytes
      downloadName: 'test.txt');
}

Solution 4

A good workaround is to open the hosted file in a new tab using

import 'dart:html' as html;

openInANewTab(url){
  html.window.open(url, 'PlaceholderName');
}

Fits well for my use case.

Solution 5

I've found a solution that let me make an authorized request to get a file (with package http.dart) and then download the file using flutter web (with package dart:html). I don't know if someone other could need this, but I wasn't able to find a solution, so here is the code.

import 'package:http/http.dart';
import 'dart:html' as html;

...

var headers = {
   'Content-Type': 'application/octet-stream',
   'Accept': 'application/octet-stream',
   'Authorization' : 'Bearer [TOKEN HERE]'
};

Response res =
      await get(url, headers: headers); 

if (res.statusCode == 200) {
    final blob = html.Blob([res.bodyBytes]);
    final url = html.Url.createObjectUrlFromBlob(blob);
    final anchor = html.document.createElement('a') as html.AnchorElement
      ..href = url
      ..style.display = 'none'
      ..download = filename;
    html.document.body.children.add(anchor);

    anchor.click();

    html.document.body.children.remove(anchor);
    html.Url.revokeObjectUrl(url);
}
Share:
17,217
Admin
Author by

Admin

Updated on June 07, 2022

Comments

  • Admin
    Admin almost 2 years

    I am making flutter web app that should generate a file from user data. And have the option to download the output file.

    But I can not find any options/packages which works for flutter web :(

    Can someone please help me out?

  • Suragch
    Suragch about 4 years
    What if the audio file is url is http://www.example.com/my_audio.mp3?
  • Suragch
    Suragch about 4 years
    This works for downloading an APK file. It doesn't work for downloading an audio file because the audio file starts playing automatically.
  • Suragch
    Suragch about 4 years
    Since this answer came late in the bounty period I don't have time to try it before the bounty expires. However, I'll assume that it works (but can you confirm that it would download an audio file without just playing it automatically?). I'm choosing this answer because it is easy to understand.
  • Eradicatore
    Eradicatore about 4 years
    Yes, I'm also trying to download a .json file and it too get's opened by the chrome tab. Trying to see if there is some way to use "download" tag in html5.
  • Razi Kallayi
    Razi Kallayi about 4 years
    This is specifically for flutter web. Is there any alternative for mobile app?
  • vishwajit76
    vishwajit76 about 4 years
    In Android you can download file from url and save it to your phone storage using IO library.
  • nipunasudha
    nipunasudha about 4 years
    Wow this one saved me BIG TIME! Thank you so much. This code could instantly download a pdf file I generated in Flutter.
  • Aidan Marshall
    Aidan Marshall almost 4 years
    @Eradicatore any luck?
  • Eradicatore
    Eradicatore almost 4 years
    @AidanMarshall Yea I did get this working. I'll share some information here when I get a chance. I don't have the code handy right now
  • Stack Underflow
    Stack Underflow almost 4 years
    This does not work. The browser opens the file rather than downloading it.
  • Vae
    Vae over 3 years
    @Eradicatore don't forget to share your treasure as soon as you can haha
  • GnRSlashSP
    GnRSlashSP over 3 years
    I am surprised that this answer has no votes. It is perfect, this guy show two methods to acomplish what we need and no votes? Thank you very much!
  • Wesley Barnes
    Wesley Barnes about 3 years
    This is the only answer that has worked for me, so many articles, but this one worked.
  • Sha-agi
    Sha-agi about 3 years
    This worked but it only saves with the filename the url gave ... - on mac, chrome browser
  • Sha-agi
    Sha-agi about 3 years
    is a.download the desired custom file name?
  • Dmytro Rostopira
    Dmytro Rostopira about 3 years
    @Sha-agi yes, it is
  • EzPizza
    EzPizza over 2 years
    I think you can set the anchorElement.download = fileName to set a name unlike the url.
  • Fellow7000
    Fellow7000 over 2 years
    for me it worked, thanks a lot! the only point: I had to modify URL for running in release - like if (!isInDebug) {url = "assets/$url} just look on the file structure of the release build and you will get the point
  • Björn W
    Björn W over 2 years
    Love it! Thanks so much for sharing.
  • David L
    David L over 2 years
    Thanks @vishwajit76... it works perfect for Web, but an error appears if you have a cross-platform code because dart:html doesn't support Mobile. What do you recommend in this case?
  • vishwajit76
    vishwajit76 over 2 years
    For cross-platform, you can use conditional import.see this post - medium.com/globant/support-flutter-cross-platform-b55ea3cccf‌​41
  • Chris
    Chris over 2 years
    thanks for your answer! Could you explain me the purpose of the 'empty_download.dart' ?
  • Roberto Juárez
    Roberto Juárez over 2 years
    There is just an issue with downloading in the mobile chrome version, the file is not stored. Working like a charm on mobile safari.
  • AzureIP
    AzureIP over 2 years
    This article is about flutter web. I don't think this works on web. Please correct my if I'm wrong.
  • Pranav Manoj
    Pranav Manoj over 2 years
    What makes you say it isn't ?
  • AzureIP
    AzureIP over 2 years
    In the documentation they say "Download the file and save it in local". So I think it requires local file acces to write the file and that is not possible in web.
  • Kin Pu
    Kin Pu about 2 years
    In my case, I need to download images either jpeg or png. In mobile chrome, the file is not recognized as an image. Is there a way to indicate this on htref?