Flutter Excel sheet in the assets folder - dart

I am creating an app in which i will be sending an email with an attached excel sheet.
I already have the excel sheet and my app will be adding some data to the excel sheet before it will be sent.
However after trying to add the excel sheet to my assets folder, adding the path to the pubspec.yaml the File class could not find the file.
pubspec.yaml:
assets:
- logo.png
- Declaratieformulier.xlsx
function:
openFile() {
var bytes = new File("assets/Declaratieformulier.xlsx").readAsBytesSync();
var decoder = new SpreadsheetDecoder.decodeBytes(bytes);
var table = decoder.tables['Blad1'];
I did a little digging and found out assets aren't put on the device as files but are contained within the APK.
So my question is: How do i include an Excel sheet with my app so i can read it and save it as a new Excel file on the phone?

You have to insert the full path in pubspec.yaml so instead of Declaratieformulier.xlsx you have to add assets/Declaratieformulier.xlsx.
assets:
- logo.png
- assets/Declaratieformulier.xlsx
Also you should read the file for the root bundle
import 'package:flutter/services.dart' show ByteData, rootBundle;
...
ByteData data = await rootBundle.load("assets/Declaratieformulier.xlsx");
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
var decoder = SpreadsheetDecoder.decodeBytes(bytes);

You need to read your file with the Flutter rootBundle.
As #LorenzOliveto said, you also need to fix your pubspec.yaml declaration.
ByteData data = await rootBundle.load("assets/Declaratieformulier.xlsx");
// This would be your equivalent bytes variable
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// You can also copy it to the device when the app starts
final directory = await getApplicationDocumentsDirectory();
String filePath = join(directory, "Declaratieformulier.xlsx");
await File(filePath).writeAsBytes(bytes);

Related

How to read and write a text file in Flutter

How do you read text from a file and write text to a file?
I've been learning about how to read and write text to and from a file. I found another question about reading from assets, but that is not the same. I will add my answer below from what I learned from the documentation.
Setup
Add the following plugin in pubspec.yaml:
dependencies:
path_provider: ^1.6.27
Update the version number to whatever is current.
And import it in your code.
import 'package:path_provider/path_provider.dart';
You also have to import dart:io to use the File class.
import 'dart:io';
Writing to a text file
_write(String text) async {
final Directory directory = await getApplicationDocumentsDirectory();
final File file = File('${directory.path}/my_file.txt');
await file.writeAsString(text);
}
Reading from a text file
Future<String> _read() async {
String text;
try {
final Directory directory = await getApplicationDocumentsDirectory();
final File file = File('${directory.path}/my_file.txt');
text = await file.readAsString();
} catch (e) {
print("Couldn't read file");
}
return text;
}
Notes
You can also get the path string with join(directory.path, 'my_file.txt') but you need to import 'package:path/path.dart'.
Flutter's Official Documentation of Reading and Writing Files
This works for iOS, Android, Linux and MacOS but not for web.
As additional info to #Suragch's answer, if you want to find the file you created, you can do as the images show:
And then inside that data folder, go again to a folder named data and search for your package, and then go to:
If you happen to create new files, in order to be able to see them, just right click and click Synchronize.
An another way to pull the file from the device is by using adb pull command. You can find the file path by debugging the code and then use adb pull command. adb is located in Android SDK -> platform-tools directory.
./adb pull /storage/emulated/0/Android/data/com.innovate.storage.storage_sample/files/sample.txt ~/Downloads
#Suragch 's answer is right. Except the version of path_provider that you want to use now is:
path_provider: ^2.0.9

How to add a File Picker plugin in Flutter?

I am creating a Flutter project in which, I have a piece of data (JSON) that I want to Import from and Export to a location the user wants to. In order to achieve this, I require a File Picker plugin in Flutter. Now, I searched the Dart Packages repository for "file picker" but didn't find one.
Is there a way to get a File Picker that looks like this:
or even this...
The first screenshot is preferable for me as it allows file selection from different sources (like Drive).
Also, since I want to Export the data, I might want a Folder Picker too. ;)
But, if there is any other alternative to Folder Picker. I'd be happy to know...
I've created a file_picker plugin some time ago in order to make it possible to pick (both on iOS and Android) absolute paths and then loaded it with Flutter.
You can check it here: https://pub.dev/packages/file_picker
I used file_picker library to pick files. you can use this for pick images as well.
Future getPdfAndUpload(int position) async {
File file = await FilePicker.getFile(
type: FileType.custom,
allowedExtensions: ['pdf','docx'], //here you can add any of extention what you need to pick
);
if(file != null) {
setState(() {
file1 = file; //file1 is a global variable which i created
});
}
}
here file_picker flutter library.
I'm in the exact same boat as you, haha!
I noticed documents_picker 0.0.2. It allows the user to pick multiple files, and it seems to fit the need!
check it out: https://pub.dartlang.org/packages/documents_picker#-readme-tab-
Here's a better document picker. It looks like the native document picker from the Storage Access Framework, which is what you have in your picture.
flutter_document_picker
Just found the FileSelector plugin from flutter.dev. Compatible with MacOS, Windows and Web.
From its pub.dev page:
Open a single file
final typeGroup = XTypeGroup(label: 'images', extensions: ['jpg', 'png']);
final file = await openFile(acceptedTypeGroups: [typeGroup]);
Open multiple files at once
final typeGroup = XTypeGroup(label: 'images', extensions: ['jpg', 'png']);
final files = await openFiles(acceptedTypeGroups: [typeGroup]);
Saving a file
final path = await getSavePath();
final name = "hello_file_selector.txt";
final data = Uint8List.fromList("Hello World!".codeUnits);
final mimeType = "text/plain";
final file = XFile.fromData(data, name: name, mimeType: mimeType);
await file.saveTo(path);
MacOS: Provide file read or/and write privileges
On target MacOS please provide sufficient rights using Xcode:
In case you don't provide file read or/and write permissions, the call to
final XFile? file =
await openFile(acceptedTypeGroups: <XTypeGroup>[typeGroup]);
neither shows anything not returns.

How to provide path in flutter - path combine

I am creating a quiz app in the Flutter for which I have collected some questions in CSV file. I want to store the CSV file in firebase and display questions into the app by reading from the CSV file. But just to check if the reading file is as simple as it should be, I tried to read a dummy file in this way:
new File('file.txt').readAsString().then((String contents) {
print(contents);
});
from main.dart before returning the Widget.
But i get this error:
`FileSystemException: Cannot open file, path = 'file.txt' (OS Error: No such file or directory, errno = 2)`
even though I have made a dummy 'file.txt' file in the same directory as 'main.dart'.
I tried doing './file.txt' and even the absolute path from windows explorer but none seem to work.
How to fix this?
The path_provider package allows you to access the temp and appDir directory
https://pub.dartlang.org/packages/path_provider
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
You can use the join() method of https://pub.dartlang.org/packages/path to concatenate paths in a platform dependent way, or just use string concatenation like
String filePath = '${appDocDir.path}/file.txt';
new File(filePath).readAsString().then((String contents) {
print(contents);
});
You can use join to safely join files or folders:
Example:
import 'package:path/path.dart' as Path;
String fileName = Path.join('/storage/emulated/0/', 'MyFolder', 'file.txt');
Result:
fileName = '/storage/emulated/0/MyFolder/file.txt'

How to zip PDF and XML files which are in memorystreams

I'm working with VS2015 and ASP.Net on a webservice application which is installed in the AWS cloud.
In one of my methods i got two files, a PDF and a XML.
These files just exist as instances of type MemoryStream.
Now i have to compress these two "files" in a ZIP file before adding the zip as attachment to an E-mail (class MailMessage).
It seems that i have to save the memorystreams to files before adding them as entries to the zip.
Is ist true or do i have another possibility to add the streams as entries to the zip?
Thanks in advance!
The answer is no.
It is not necessary to save the files before adding them to the stream for the ZIP file.
I have found a solution with the Nuget package DotNetZip.
Here is a code example how to use it.
In that example there two files which only exist in MemoryStream objects, not on a local disc.
It is important to reset the Position property of the streams to zero before adding them to the ZIP stream.
At last i save the ZIP stream as a file in my local folder to control the results.
//DotNetZip from Nuget
//http://shahvaibhav.com/create-zip-file-in-memory-using-dotnetzip/
string zipFileName = System.IO.Path.GetFileNameWithoutExtension(xmlFileName) + ".zip";
var zipMemStream = new MemoryStream();
zipMemStream.Position = 0;
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
textFileStream.Position = 0;
zip.AddEntry(System.IO.Path.GetFileNameWithoutExtension(xmlFileName) + ".txt", textFileStream);
xmlFileStream.Position = 0;
zip.AddEntry(xmlFileName, xmlFileStream);
zip.Save(zipMemStream);
// Try to save the ZIP-Stream as a ZIP file. And suddenly: It works!
var zipFs = new FileStream(zipFileName, FileMode.Create);
zipMemStream.Position = 0;
zipMemStream.CopyTo(zipFs);
zipMemStream.WriteTo(zipFs);
}

Launch Excel from MVC with actual file, not download copy

I need to be able to launch Excel and open and eiut a specific file from an MVC application.
The application is for internal use only and users will have access to the folder containing the excel file.
I have looked at the File method below
var dir = location + "Filename.xlsx";
var cd = new ContentDisposition
{
FileName = "Excel Spreadsheet",
Inline = true
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(dir, "application/vnd.ms-excel");
However, this opens Excel with a copy of the file downloaded to the users's download directory. So if they make any changes, these do not update to the original.
Is what I'm trying to do possible? If so, how?
Many thanks,
Chris.

Resources