I need to read a excel file of .xls format from external storage. Using file picker i have got its path. But now the problem is i have to read the excel file row wise and save it in an array.
I could not find any library like poi similar to java.
The expected result should be like Workbook=>sheet1=>row(i)
OutlinedButton(
onPressed: () async {
ByteData data = await rootBundle.load("assets/mydata.xlsx");
_upload(data);
}
)
static Future<void> _upload(var data) async {
var bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
var excel = Excel.decodeBytes(bytes);
List<dynamic> excelList = [];
for (var table in excel.tables.keys)
{
for(int rowIndex= 1 ;rowIndex <=excel.tables[table].maxRows; rowIndex++)
{
Sheet sheetObject = excel['Sheet1'];
var excelfileDetails = new MyExcelTable();
excelfileDetails.name = sheetObject.cell(CellIndex.indexByColumnRow(columnIndex:0,rowIndex: rowIndex)).value.toString();
excelfileDetails.age = sheetObject.cell(CellIndex.indexByColumnRow(columnIndex:1,rowIndex: rowIndex)).value;
excelfileDetails.state = sheetObject.cell(CellIndex.indexByColumnRow(columnIndex:2,rowIndex: rowIndex)).value.toString();
excelfileDetails.country = sheetObject.cell(CellIndex.indexByColumnRow(columnIndex:3,rowIndex: rowIndex)).value.toString();
excelfileDetails.occupation = sheetObject.cell(CellIndex.indexByColumnRow(columnIndex:4,rowIndex: rowIndex)).value.toString();
excelList.add(excelfileDetails);
}
}
}
class MyExcelTable
{
var name;
var age;
var state;
var country;
var occupation;
MyExcelTable({this.name, this.age, this.state, this.country, this.occupation});
}
Does it have to be an Excel file or could you also save it as .csv data? If you can save it as .csv, you can simply read it as a normal Text.
have a try : https://pub.dev/packages/spreadsheet_decoder
import 'dart:io';
import 'package:spreadsheet_decoder/spreadsheet_decoder.dart';
main() {
var bytes = new File.fromUri(fullUri).readAsBytesSync();
var decoder = new SpreadsheetDecoder.decodeBytes(bytes);
var table = decoder.tables['Sheet1'];
var values = table.rows[0];
...
decoder.updateCell('Sheet1', 0, 0, 1337);
new File(join(fullUri).writeAsBytesSync(decoder.encode());
...
}
Related
The list _data contain data from the csv file.
List<List<dynamic>> _data = [];
String key = "39";
List<List<dynamic>> _tempdata = [];
void _loadCSV() async {
final _rawData = await rootBundle.loadString("assets/mycsv.csv");
List<List<dynamic>> _listData =
const CsvToListConverter().convert(_rawData);
setState(() {
_data = _listData;
});
}
mycsv.csv data
id,Name,Num,Batch
15,JERRY,PH123,G9
27,Tom,PH129,G8
39,Oggy,PH124,G9
45,Jack,PH125,G10
I need to
Get the data where id == key(search element) from the list "_data" and store it in new list named "_tempdata"
You can use where function in List
List searchByKey(key) {
return _data.where((row) => key == row[0]).toList();
}
How to create the contact in locally with Name and phone number and share the created contact to other apps like whatsapp, social media's etc...
By using vcard_maintained library https://pub.dev/packages/vcard_maintained, we are able to create the contact, But not able to share through the apps.
I tried this,
import 'package:share_plus/share_plus.dart';
import 'package:vcard_maintained/vcard_maintained.dart';
var vCard = VCard();
vCard.firstName = 'FirstName';
vCard.middleName = 'MiddleName';
vCard.workPhone = '312-555-1212';
final path = await _localPath;
vCard.saveToFile('$path/contact.vcf');
Share.shareFiles(['$path/contact.vcf'], text: 'Great picture');
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
But getting format of this vcard is not support error.
This is the working example.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:vcard_maintained/vcard_maintained.dart';
void shareAllVCFCard(BuildContext context, {required List<VCard> vCard}) async {
try {
List<String> vcsCardPath = <String>[];
int index = 0;
for (final card in vCard) {
index++;
var vCardAsString = card.getFormattedString();
final directory = await getApplicationDocumentsDirectory();
final path = directory.path;
var pathAsText = "$path/$index.txt";
var contactAsFile = File(await getFilePath(index.toString()));
contactAsFile.writeAsString(vCardAsString);
var vcf = contactAsFile
.renameSync(contactAsFile.path.replaceAll(".txt", ".vcf"));
vcsCardPath.add(vcf.path);
}
Share.shareFiles(vcsCardPath, text: 'Great picture');
} catch (e) {
print("Error Creating VCF File $e");
return null;
}
}
Future<String> getFilePath(String fileName) async {
Directory appDocumentsDirectory =
await getApplicationDocumentsDirectory(); // 1
String appDocumentsPath = appDocumentsDirectory.path; // 2
String filePath = '$appDocumentsPath/$fileName.txt'; // 3
return filePath;
}
I am using xlsx library to convert input excel file into JSON and it works fine but when I test on android it won't trigger reader.onload function. Please suggest to me what's the correct library to use for android or what to need to change
const reader: FileReader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = (e: any) => {
console.log(e)
const binarystr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(binarystr, { type: 'binary' });
const wsname: string = wb.SheetNames[0];
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
const data = XLSX.utils.sheet_to_json(ws);
console.log(data);
this.fileData = data;
};
It doesn't print console.log(e), I've tried try-catch to catch the error but it didn't catch the error as well. Please let me know what's the issue and which library is best for Android as well as IOS
I solved it. Please see the code below, hope it will help someone
incomingfile(event){
this.file= event.target.files[0];
this.readXLSX(this.file);
}
readXLSX(file){
let fileReader = this.getFileReader(file);
fileReader.onload = (e: any) => {
/* create workbook */
const binarystr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(binarystr, { type: 'binary' });
/* selected the first sheet */
const wsname: string = wb.SheetNames[0];
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
/* save data */
const data = XLSX.utils.sheet_to_json(ws); // to get 2d array pass 2nd parameter as object {header: 1}
console.log(data); // Data will be logged in array format containing objects
this.zone.run(() => {
this.fileData = data;
});
};
}
getFileReader(file): FileReader {
const fileReader = new FileReader();
fileReader.readAsBinaryString(file);
const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"];
return zoneOriginalInstance || fileReader;
}
I'm printing the data to a file but this data is overwritten. How can I collect all data in one file
Future<String?> get _localPathBLE async {
final directory = await getExternalStorageDirectory();
return directory?.path;
}
Future<File> get _localFile async {
final path = await _localPathBLE;
var date =
DateUtil.instance.dateParseToString(DateEnum.FULL, DateTime.now());
return File('$path/DATA.csv');
}
Future<void> writeBLE(List<List<double>> acc3d) async {
final file = await _localFile;
String csv = const ListToCsvConverter().convert(acc3d);
// Write the file
return file.writeAsStringSync(csv);
}
In order to append the bytes to an existing file, pass FileMode.append as the optional mode parameter.
See writeAsStringSync for details.
Future<void> writeBLE(List<List<double>> acc3d) async {
final file = await _localFile;
String csv = const ListToCsvConverter().convert(acc3d);
// Write the file
return file.writeAsStringSync(csv + '\n',
mode: FileMode.append, flush: true);
}
I have shopping cart in my android App. I am using Firebase as database. I want to mail cart items as CSV / Excel file as attachment.
First you have to fetch all data from firebase.
Read Data From Firebase database
Then you have to generate csv file from the data.
How to create a .csv on android
After that you can send csv file from its path as an attachment to mail
How to send an email with a file attachment in Android
first install excel4node package in your firebase project, then import this in your index.js
const xl = require('excel4node');
also import these for file handling
const os = require('os');
const path = require('path');
const fs = require('fs');
const tempFilePath = path.join(os.tmpdir(), 'Excel.xlsx');
const storage = admin.storage();
const bucket = storage.bucket();
This is how you return the function should look
exports.writeFireToExcel = functions.https.onCall(async(data, context) => {
// Create a new instance of a Workbook class
const workbook = new xl.Workbook();
// Add Worksheets to the workbook
const worksheet = workbook.addWorksheet('Visa Work List');
const ref = firebaseDb.ref('path');
//firebase functions that return stuff must be done in a transactional way
//start by getting snap
return await ref.once('value').then(snapshot =>{
var style = workbook.createStyle({
font: {
bold : true,
},
});
//write workbook
worksheet.cell(1, 1).string('input').style(style);
//....write the rest of your excel
return
//
}).then(function (){
console.log('workbook filled');
//second part of transation - write the excel file to the temp storage in firebase
//workbook.write doesnt return a promise so ive turned it into a promise function
return new Promise((resolve,reject) =>{
workbook.write(tempFilePath, function (err, stats) {
if (err) {
console.error(err);
reject(err)
}else{
resolve()
}
});
})
}).then(function(){
console.log("File written to: " + tempFilePath);
//read the file and check it exists
return new Promise((resolve,reject) =>{
fs.readFile(tempFilePath, function (err, data) {
if (err) {
reject(err)
}else{
resolve()
}
})
})
}).then(function(){
console.log("writing to bucket");
//write the file to path in firebase storage
var fileName = 'VisaSummaryList.xlsx';
var folderPath = uid + "/excelFile/";
var filePathString = folderPath + fileName;
return bucket.upload(tempFilePath,
{ destination: filePathString}).then(function(){
return filePathString;
})
}).catch(err => {
throw err;
});
});
the function returns a filepath in the firebase storage. In your android app just:
//firebase storage reference, result being whats returned from the firebase function
val fbstore = FirebaseStorage.getInstance().reference.child(result)
fbstore.getFile(myFile)