Flutter Web: Show PDF or Any File from Assets on another browser tab or window - flutter

Recently, I was working on the portfolio website where I need to show the user's CV which was in the PDF format on another tab.
Since this was a standalone Web Project, I didn't want to handle PDF viewing for iOS and Android.

First, you need to install this package: universal_html
flutter pub add universal_html
import the package in your file
import 'package:universal_html/html.dart' as html;
And here is the method:
Future<void> showCV() async {
var bytes = await rootBundle.load("assets/files/cv.pdf"); // location of your asset file
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
}
Voila !

var bytes = await rootBundle.load("assets/files/cv.pdf"); // location of your
asset file
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
Does it work in web hosting also ? because in my case this code is working in local host but not in web host.

Related

Flutter Web - Save ui.Image to png File

I need some help with my code, I use the
"FilePicker.platform.saveFile()"
function to get the path on Windows Version (but not works on Web) and then
"final imageFuture = await controller
.renderImage(backgroundImageSize)
.then<Uint8List?>((ui.Image image) => image.pngBytes);
final imgFile = File(path);
imgFile.writeAsBytesSync(imageFuture!);
"
to save my image to disk, this works perfectly on Windows, but not on the web version.I need an alternative to save ui.Image (web Version) to PNG File on disk. 🙏🙏
I was able to solve my problem only, however the solution works only in release mode (after the build process).
import 'dart:html' as html;
import 'dart:js' as js;
final backgroundImageSize = Size(backgroundImage!.width.toDouble(),
backgroundImage!.height.toDouble());
final imageFuture = await controller
.renderImage(backgroundImageSize)
.then<Uint8List?>((ui.Image image) => image.pngBytes);
(imageFuture != null)
? js.context.callMethod(
"saveAs",
[
html.Blob([imageFuture]),
'output-image.png',
],
)
: print('Image is null');
It is necessary to add inside your web/index.html file:
<script src="https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.21.15/plugins/export/libs/FileSaver.js/FileSaver.min.js"></script>

Get file path from system directory using Flutter web (chrome) to read file content Eg: CSV or Text file

Package tried: https://pub.dev/packages/file_picker
Tried the example code implementation shared via GitHub. But the file path is returned as null for
web platform. Where same implementation in mobile platform return the path as expected.
https://github.com/miguelpruivo/flutter_file_picker/blob/master/example/lib/src/file_picker_demo.dart
Things aware of:
Path_Provider - Not supported for web
dart-io-library - Not supported for web
Open issue in Flutter Repo
Goal is to read the file from the path and not to upload. Any workaround to achieve this will be helpful.
Flutter channel: beta
As mentioned in the file_picker FAQ:
Paths aren't inaccessible from browsers since those provide fake paths. If you want to create a File instance to upload it somewhere, like FireStorage, you can do so with the bytes directly.
final result = await FilePicker.platform.pickFiles(type: FileType.any, allowMultiple: false);
if (result.files.first != null){
var fileBytes = result.files.first.bytes;
var fileName = result.files.first.name;
print(String.fromCharCodes(fileBytes));
}
I have a function for picking image from computer. Might work for you.
import 'dart:html';
void uploadImage({#required Function(File file) onSelected}) {
InputElement uploadInput = FileUploadInputElement()..accept = 'image/*';
uploadInput.click();
uploadInput.onChange.listen((event) {
final file = uploadInput.files.first;
final reader = FileReader();
reader.readAsDataUrl(file);
reader.onLoadEnd.listen((event) {
onSelected(file);
});
});
}

Flutter Web download file from url instead of opening it

Is there any way to get files like .pdf downloaded directly on user's device instead of opening this pdf in the browser?
This code works for downloading non browser supported files but it opens pdf, mp3, etc. in the browser.
final anchor = AnchorElement(
href: pickedFile)
..setAttribute("download", fileName)
..click();
If someone is still searching for solution.Here is what I have done.
Anchor tag will directly download file if it has download attribute.
Note: Download attribute is only supported for same-origin request
So instead of assigning external URL link to anchor element. Create Blob object from PDF data and create Object URL from that.
var url = Url.createObjectUrlFromBlob(Blob([data]));
AnchorElement(href: url)
..setAttribute('download', '<downloaded_file_name.pdf>')
..click();
I am using Firebase to store file so here is the complete code.
FirebaseStorage.instance.ref(resumeFileName).getData().then(
(data) {
var url = Url.createObjectUrlFromBlob(Blob([data]));
AnchorElement(href: url)
..setAttribute('download', '<downloaded_file_name.pdf>')
..click();
}
);
by following the steps below, you can download the file automatically by the browser and save it in the download directory.
In this method, http and universal_html packages are used.
The important thing is to manage Multiplatform-Mode and using this code, is better you create 3 separate dart files.
switch_native_web.dart
web.dart
native.dart
/// switch_native_web.dart
import 'native.dart' if (dart.library.html) 'web.dart' as switch_value;
class SwitchNativeWeb {
static void downloadFile({required String url,
required String fileName ,required String dataType}){
switch_value.downloadFile(dataType: dataType,fileName: fileName,url: url);}
}
...
/// web.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:universal_html/html.dart' as universal_html;
Future<void> downloadFile(
{required String url,
required String fileName,
required String dataType}) async {
try {
// first we make a request to the url like you did
// in the android and ios version
final http.Response r = await http.get(
Uri.parse(url),
);
// we get the bytes from the body
final data = r.bodyBytes;
// and encode them to base64
final base64data = base64Encode(data);
// then we create and AnchorElement with the html package
final a =
universal_html.AnchorElement(href: '$dataType;base64,$base64data');
// set the name of the file we want the image to get
// downloaded to
a.download = fileName;
// and we click the AnchorElement which downloads the image
a.click();
// finally we remove the AnchorElement
a.remove();
} catch (e) {
print(e);
}
}
...
/// native.dart
Future<void> downloadFile({required String url, required String fileName,
required String dataType}) async {}
And using the following sample code for calling the downloadFile method wherever you need:
...
GestureDetector(
onTap: () => SwitchNativeWeb.downloadFile(
url: "https://... your url ..../download.jpg",
fileName: "download.jpg",
dataType: "data:image/jpeg"),
child: Text('download')
)
...
I only wrote the code related to web download (according to the question), you can write the code related to ios and android download in the native .dart file.
Use Dio Library.
dependencies:
dio: ^3.0.10
to download file
response = await dio.download("https://www.google.com/", "./xx.html");
this video will help you.

How to Share Image from API(URL) in flutter?

Here I want to share image which I get through API. I tried different method for this functionality but I did not get any solution because every solutions have for only one image.
Exactly, I get multiple image from Url and I open any particular image in next page. So, I want to share that image which I opened in another page.
I tried for sharing image but I could not did this. Whenever I try to share that image, Image url share with sharing option on device but I want share image not URl of image How I can accomplish this?
You have to download the image like this:
http.Response response = await http.get(url);
then create an image on the device using the downloaded image like this (Read and Write Files):
final directory = await getTemporaryDirectory();
final path = directory.path;
final file = File('$path/image.png');
file.writeAsBytes(response.bodyBytes);
The getTemporaryDirectory() is in the plugin path_provider. Now, you have the image you'd like to share stored in the temporarily as "image.png" and you can use the share_plus plugin to share the image like this:
Share.shareFiles(['$path/image.png']);
Thanks to #abdulrazak, At first, you have to download the image in a temporary path & then you can share the image as you want. used Dio to download the image & share_plus for sharing
void _shareNetworkImage(String url) async {
Directory tempDir = await getTemporaryDirectory();
final path = '${tempDir.path}/test.jpeg';
await Dio().download(url, path);
Share.shareFiles([path]);
}
You can use the esys_flutter_share plugin.
Install it, and then get dependencies:
dependencies:
esys_flutter_share: ^1.0.2
Import the plugin to your code:
import 'package:esys_flutter_share/esys_flutter_share.dart';
Use the below code:
var request = await HttpClient().getUrl(Uri.parse('https://yourImageURL.jpg'));
var response = await request.close();
Uint8List bytes = await consolidateHttpClientResponseBytes(response);
await Share.file('ESYS AMLOG', 'amlog.jpg', bytes, 'image/jpg');

Looking for a good sample working code for downloading any file from URL in flutter. If its with native downloader then this will be very good

Looking for a good sample working code for downloading any file from URL in flutter. If its with native downloader then this will be very good. Please help me with sample of code to download any file using native downloader in flutter.
I have used few libraries but didn't turned out well.
For a mobile device, I used the http package to download a file to the applications document directory
First, create a httpClient object
static var httpClient = new HttpClient();
Then you can create a function like this to download the file:
Future<void> _downloadFile({
required String fileName,
}) async {
String url = ...;
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await getApplicationDocumentsDirectory())!.path;
File file = new File('$dir/$fileName'); // Note: Filename must contain the extension of the file too, like pdf, jpg etc.
await file.writeAsBytes(bytes);
}
For a flutter web application, I felt the url_launcher package was the easiest to work with.
_launchURL() async {
String url = ...;
if (await canLaunch(url)) {
await launch(url);
print('URL Launcher success');
} else {
throw Exception('Could not launch $url');
}
}
The url_launcher package code works even for a mobile device but it opens a new browser window to download the required file which is not a good user experience so I have used 2 approaches for the same problem.
Hope I have answered your query.