Hi !
I have an issue with saving a file (.docx) on an android application using cordova and fileSave.js. Everything works fine in a browser but when I'm using the application i'm not getting any error but the file is not saving.
If someone already had an issue like this or know the way to do such a thing like this, thank you to help.
Here is some line of my code :
console.log(doc);
var out=doc.getZip().generate({
type:"blob",
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
})
//Output the document using Data-URI
console.log("the file is "+out);
saveAs(out,"output.docx");
I am getting "Download error" on android. Nor sure how can I see more details on mobile :/
While it does not fix your problem, I used the $cordovaFile plugin for the Android Webview environment. I did not manage to make FileSaver work but at least with $cordovaFile.writeFile I was able to save the generated documents directly to the target folder.
You won't be able to do this with JS only because Android can only download files how have a http link. So local generated files won't work that you have created in Js.
What you need to do is something else. I have an example. I wanted to create a CSV file in JS. What I have done is I made a array in JS like this:
var ArrayOfDataToExport = [];
for (var f = 0; f < localStorage.length; f++) {
var keyName = (localStorage.key(f));
var data = JSON.parse(localStorage.getItem(localStorage.key(f)));
ArrayOfDataToExport.push([keyName, data]);
}
var String = '[';
for (var i = 0; i < ArrayOfDataToExport.length; i++) {
if (typeof ArrayOfDataToExport[i][1] === "object") {
String += '["' + ArrayOfDataToExport[i][0] + '",';
if (ArrayOfDataToExport[i][1] === null) {
String += '[]],';
}
else {
if (ArrayOfDataToExport[i][1].length > 1 || ArrayOfDataToExport[i][1].length === 0) {
if (ArrayOfDataToExport[i][1].length === 0) {
String += '[]],';
}
else {
for (var k = 0; k < ArrayOfDataToExport[i][1].length; k++) {
String += '["';
for (var l = 0; l < ArrayOfDataToExport[i][1][k].length - 1; l++) {
String += ArrayOfDataToExport[i][1][k][l] + '","';
}
String += ArrayOfDataToExport[i][1][k][ArrayOfDataToExport[i][1][k].length - 1] + '"],';
}
String = String.slice(0, -1);
String += '],';
}
}
else {
String += '["';
for (var j = 0; j < ArrayOfDataToExport[i][1][0].length - 1; j++) {
String += ArrayOfDataToExport[i][1][0][j] + '","';
}
String += ArrayOfDataToExport[i][1][0][ArrayOfDataToExport[i][1][0].length - 1] + '"]],';
}
}
}
else {
String += '["' + ArrayOfDataToExport[i][0] + '","';
String += ArrayOfDataToExport[i][1] + '"],';
}
}
String = String.slice(0, -1);
String += "]";
console.log(String);
Like you can see I add [ Why you don't do JSON.stringify ?
Because let me explain. Like you see I do nothing more I just log the string.
I catch that in android that log. How?
Like this:
public void onConsoleMessage(String message, int lineNumber, String sourceID) {
if (sourceID.equals("SOURCE_FILE_OF_YOUR_JS_WHERE_LOG") && lineNumber == 55 ){
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
String currentDate = currentDateTimeString.replace(".", "").replace(" ", "");
String fileName = "FILE_NAME" + currentDate + ".csv";
generateNoteOnSD(getBaseContext(),fileName, message);
}
}
If catch that? The JSON.stringify won't work because he doesn't show the [ so you that is the reason why I have created that JS function that does that.
The only thing you can do know is to create the file in native android and save it. That will work!
If you have any more questions just ask.
+1. saveAs not work and there are no error message.
Only curious why ppl still use cordova 馃檮
If this 'issue' is a limitation in Android and not a bug in FileSaver.js, then this should be closed. Perhaps a note about this limitaion of Android in the README would be nice?
Is this confirmed as being an Android issue? I ran into this limitation as well.
Yes I don't works on Android's webview
Actually no, it's working but you need to do it "by hand", here is the code i've done to make it works. I'm think it's possible to improve it but it's already a good way to start.
i was using DocxTemplater to generate only Docs, I don't know how to do with other formats.
``
function loadFile(url,callback){
JSZipUtils.getBinaryContent(url,callback);
}
$scope.save = function () {
document.addEventListener("deviceready", function() {
console.log("entre fonction");
loadFile("./doc/fiche de poste appli.docx",function(error,content){
if (error) { throw error };
var zip = new JSZip(content);
var doc=new Docxtemplater().loadZip(zip)
var opts = {}
var fileName = $scope.fileName+".docx";
$scope.$storage.currentFileName = fileName;
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, function (directoryEntry) {
directoryEntry.getFile(fileName, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function (e) {
// for real-world usage, you might consider passing a success callback
console.log('Write of file "' + fileName + '"" completed.');
function alertDismissed() {}
navigator.notification.alert(
'Fichier sauvegard茅', // message
alertDismissed, // callback
'Sauvegarde', // title
'ok' // buttonName
);
};
fileWriter.onerror = function (e) {
// you could hook this up with our global error handler, or pass in an error callback
console.log('Write failed: ' + e.toString());
};
var out=doc.getZip().generate({
type:"blob",
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
})
fileWriter.write(out);
}, errorHandler.bind(null, fileName));
}, errorHandler.bind(null, fileName));
}, errorHandler.bind(null, fileName));
})
}
``
@quentin2k29 are you using this in a browser like Google Chrome or did you tried this in Android Webview?
i'm using it with Cordova, so it's using the webwiew if i'm right
I will give it a try, but I don't think it will work for me because I don't use Cordova.
if you can load some JS in your webwiew, it might work i think, good luck
Most helpful comment
Only curious why ppl still use cordova 馃檮