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;
}
Related
I am using the react-native-share extension for the share and print Pdf document. I am trying to add The 'Print' attribute but it is not working or I couldn't get it right
I follow this document https://react-native-community.github.io/react-native-share/docs/share-open#activitytype
and i used the example here https://react-native-community.github.io/react-native-share/docs/share-open#activityitemsources-ios-only
According to this document, I created an object like
const url = this.props.navigation.state.params.document.url
{
item:{
print : url
}
},
https://react-native-community.github.io/react-native-share/docs/share-remote-file
The code below solves my problem for IOS. I think there was a problem because the document came from the url.Its still not working for android
static sharePDFWithAndroid(fileUrl, type) {
let filePath = null;
let file_url_length = fileUrl.length;
const configOptions = { fileCache: true };
RNFetchBlob.config(configOptions)
.fetch('GET', fileUrl)
.then(resp => {
filePath = resp.path();
return resp.readFile('base64');
})
.then(async base64Data => {
base64Data = `data:${type};base64,` + base64Data;
await Share.open({ url: base64Data });
// remove the image or pdf from device's storage
await RNFS.unlink(filePath);
});
}
I'm wondering how to upload file onto Firebase's storage via URL instead of input (for example). I'm scrapping images from a website and retrieving their URLS. I want to pass those URLS through a foreach statement and upload them to Firebase's storage. Right now, I have the firebase upload-via-input working with this code:
var auth = firebase.auth();
var storageRef = firebase.storage().ref();
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var file = evt.target.files[0];
var metadata = {
'contentType': file.type
};
// Push to child path.
var uploadTask = storageRef.child('images/' + file.name).put(file, metadata);
// Listen for errors and completion of the upload.
// [START oncomplete]
uploadTask.on('state_changed', null, function(error) {
// [START onfailure]
console.error('Upload failed:', error);
// [END onfailure]
}, function() {
console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
console.log(uploadTask.snapshot.metadata);
var url = uploadTask.snapshot.metadata.downloadURLs[0];
console.log('File available at', url);
// [START_EXCLUDE]
document.getElementById('linkbox').innerHTML = 'Click For File';}
Question what do I replace
var file = evt.target.files[0];
with to make it work with external URL instead of a manual upload process?
var file = "http://i.imgur.com/eECefMJ.jpg"; doesn't work!
There's no need to use Firebase Storage if all you're doing is saving a url path. Firebase Storage is for physical files, while the Firebase Realtime Database could be used for structured data.
Example . once you get the image url from the external site this is all you will need :
var externalImageUrl = 'https://foo.com/images/image.png';
then you would store this in your json structured database:
databaseReference.child('whatever').set(externalImageUrl);
OR
If you want to actually download the physical images straight from external site to storage then this will require making an http request and receiving a blob response or probably may require a server side language ..
Javascript Solution : How to save a file from a url with javascript
PHP Solution : Saving image from PHP URL
This answer is similar to #HalesEnchanted's answer but with less code. In this case it's done with a Cloud Function but I assume the same can be done from the front end. Notice too how createWriteStream() has an options parameter similar to bucket.upload().
const fetch = require("node-fetch");
const bucket = admin.storage().bucket('my-bucket');
const file = bucket.file('path/to/image.jpg');
fetch('https://example.com/image.jpg').then((res: any) => {
const contentType = res.headers.get('content-type');
const writeStream = file.createWriteStream({
metadata: {
contentType,
metadata: {
myValue: 123
}
}
});
res.body.pipe(writeStream);
});
Javascript solution to this using fetch command.
var remoteimageurl = "https://example.com/images/photo.jpg"
var filename = "images/photo.jpg"
fetch(remoteimageurl).then(res => {
return res.blob();
}).then(blob => {
//uploading blob to firebase storage
firebase.storage().ref().child(filename).put(blob).then(function(snapshot) {
return snapshot.ref.getDownloadURL()
}).then(url => {
console.log("Firebase storage image uploaded : ", url);
})
}).catch(error => {
console.error(error);
});
Hopefully this helps somebody else :)
// Download a file form a url.
function saveFile(url) {
// Get file name from url.
var filename = url.substring(url.lastIndexOf("/") + 1).split("?")[0];
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", transferComplete);
xhr.addEventListener("error", transferFailed);
xhr.addEventListener("abort", transferCanceled);
xhr.responseType = 'blob';
xhr.onload = function() {
var a = document.createElement('a');
a.href = window.URL.createObjectURL(xhr.response); // xhr.response is a blob
a.download = filename; // Set the file name.
a.style.display = 'none';
document.body.appendChild(a);
a.click();
delete a;
if (this.status === 200) {
// `blob` response
console.log(this.response);
var reader = new FileReader();
reader.onload = function(e) {
var auth = firebase.auth();
var storageRef = firebase.storage().ref();
var metadata = {
'contentType': 'image/jpeg'
};
var file = e.target.result;
var base64result = reader.result.split(',')[1];
var blob = b64toBlob(base64result);
console.log(blob);
var uploadTask = storageRef.child('images/' + filename).put(blob, metadata);
uploadTask.on('state_changed', null, function(error) {
// [START onfailure]
console.error('Upload failed:', error);
// [END onfailure]
}, function() {
console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
console.log(uploadTask.snapshot.metadata);
var download = uploadTask.snapshot.metadata.downloadURLs[0];
console.log('File available at', download);
// [START_EXCLUDE]
document.getElementById('linkbox').innerHTML = 'Click For File';
// [END_EXCLUDE]
});
// `data-uri`
};
reader.readAsDataURL(this.response);
};
};
xhr.open('GET', url);
xhr.send();
}
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function transferComplete(evt) {
window.onload = function() {
// Sign the user in anonymously since accessing Storage requires the user to be authorized.
auth.signInAnonymously().then(function(user) {
console.log('Anonymous Sign In Success', user);
document.getElementById('file').disabled = false;
}).catch(function(error) {
console.error('Anonymous Sign In Error', error);
});
}
}
function transferFailed(evt) {
console.log("An error occurred while transferring the file.");
}
function transferCanceled(evt) {
console.log("The transfer has been canceled by the user.");
}
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)
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());
...
}
Hi I'm newbie in android!
I want to upload image file from android client to server(Server makes thumbnail, and return thumbnail's url).
However I stucked in this error message.
{"errorMessage":"RequestId: 8e2a21b8-e62e-11e8-8585-d9b6fdfec9b9 Process exited before completing request"}!
I tried to find this error code in stackoverflow, but i cannot found answer for android.
Please help or give me link where I can solve this problem...
Here is server code.
const AWS = require('aws-sdk');
const multipart = require("parse-multipart");
const s3 = new AWS.S3();
const bluebird = require('bluebird');
exports.handler = function(event, context) {
let result = [];
const bodyBuffer = new Buffer(event['body-json'].toString(), 'base64');
const boundary = multipart.getBoundary(event.params.header['Content-Type']);
const parts = multipart.Parse(bodyBuffer, boundary);
const files = getFiles(parts);
return bluebird.map(files, file => {
console.log('UploadCall');
return upload(file)
.then(
data => {
result.push({
'bucket': data.Bucket,
'key': data.key,
'fileUrl': file.uploadFile.fullPath })
console.log( `DATA => ${JSON.stringify(data, null, 2 )}`);
},
err => {
console.log(`S3 UPLOAD ERR => ${err}`);
}
)
})
.then(_=> {
return context.succeed(result);
});
}
let upload = function(file) {
console.log('PutObject Call')
return s3.upload(file.params).promise();
};
let getFiles = function(parts) {
let files = [];
parts.forEach(part => {
const buffer = part.data
const fileName = part.filename;
const fileFullName = fileName;
const originBucket = 'dna-edge/images';
const filefullPath = `https://s3.ap-northeast-2.amazonaws.com/${originBucket}/${fileFullName}`;
const params = {
Bucket: originBucket,
Key: fileFullName,
Body: buffer
};
const uploadFile = {
size: buffer.toString('ascii').length,
type: part.type,
name: fileName,
fullPath: filefullPath
};
files.push({ params, uploadFile })
});
return files;
};
And this is client code.(imgURL looks like /storage/emulated/0/DCIM/img/1493742568136.jpg)
public static String requestHttpPostLambda(String url, String imgURL){
/*
await axios.post(`${AWS_LAMBDA_API_URL}?type=${type}`, formData,
{ headers: { 'Content-Type': 'multipart/form-data' }})
.then((response) => {result = response});
*/
String result=null;
try {
HttpClient client = new DefaultHttpClient();
String postURL = url;
HttpPost post = new HttpPost(postURL);
post.setHeader("Content-Type", "multipart/form-data");
File file = new File(imgURL);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("image", new FileBody(file));
post.setEntity(builder.build());
HttpResponse responsePOST = client.execute(post);
Log.e("HttpResponse", responsePOST.getStatusLine()+"");
HttpEntity resEntity = responsePOST.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
Welcome to stackoverflow.
So for some reason AWS aren't too good an updating the docs, don't use context.succeed, use the callback thats passed as a third param.
Also I'd move to Node 8.10 runtime because then rather than using promises/then pattern you can use async/await.
export default(event, context, callback) => {
try {
// do some stuff
callback(null, SOME_VALID_HTTP_RESPONSE)
} catch(e){
callback(e, null)
}
}
There's a few reason your Lambda could be failing, if the process exited before completing it's either crashing OR you're not returning a valid HTTP response(if your lambda is behind API gateway)
Two solutions - first place to look is in cloudwatch, find your lambda function name and check the latest log to look for error messages.
Second - check out my answer here so when your function succeeds you need to return a valid HTTP response to API Gateway so in essence if you use my code from there you can do:
callback(null, responder.success({someJson: someValue}))
Any questions let me know :-)
EDIT: I'm updating this question I'm just working on an example for a multiple file upload to S3!