Download file from FileSystem in Google Chrome - javascript

I've created an app for Google Chrome that stores a file into the File System.
I can read this file but every time I try to export it, it doesn't work.
I've tried some methods:
method toUrl,
Download File Using Javascript/jQuery
create a file using javascript in chrome on client side
but they doesn't work.
Replacement for fileEntry.toURL() in Chrome Packaged Apps talks about my problem..
So I changed my code into
function readFileRdf() {
window.requestFileSystem(window.PERSISTENT, 5*1024*1024, function(filesystem) {
fs = filesystem;
fs.root.getFile('rdf.txt', {create: false}, function(fileEntry) {
// Get a File object representing the file,
// then use FileReader to read its contents.
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
fromFileSystemRdf = e.target.result;
arr = fromFileSystemRdf;
exportRdf(arr);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
});
}
and
function exportRdf(arr){
console.log(arr);
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
console.log(arr);
writer.write(new Blob([arr], {type: 'text/plain'}));
}, errorHandler);
});
}
the last problem is that I get an error with createWriter
Error in response to fileSystem.chooseEntry: TypeError: Cannot call method 'createWriter' of undefined
Up.. adding a console.log(chrome.runtime.lastError); it says
Object {message: "Invalid calling page. This function can't be called from a background page."}
Question solved.
Since is not possible to call a method from a background page, I've used this solution:
(Remember, Google Chrome doesn't accept inline javascript)
button for exporting is pressed
`document.getElementById("button2").addEventListener("click",readFileRdf);`
method readFileRdf creates a new page:
function readFileRdf() {
chrome.app.window.create("data.html");
}
data.html calls the data.js file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Data page</title>
</head>
<body>
</body>
<script rel="text/javascript" src="data.js"></script>
</html>
and data.js allows the user to read the file from filesystem and download it
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
function initFs() {
window.requestFileSystem(window.PERSISTENT, 5*1024*1024, function(filesystem) {
fs = filesystem;
readFile(fs);
}, errorHandler);
}
function readFile(fs) {
fs.root.getFile('rdf.txt', {create: false}, function(fileEntry) {
// Get a File object representing the file,
// then use FileReader to read its contents.
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
fromFileSystemRdf = e.target.result;
arr = fromFileSystemRdf;
exportRdf(arr);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}
function exportRdf(arr){
console.log(arr);
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
console.log(chrome.runtime.lastError);
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
writer.write(new Blob([arr], {type: 'text/plain'}));
}, errorHandler);
});
}
initFs();

Related

ASP Net Core Filepond load file from server

I have a project where it uses Filepond to upload files and I need it to load file from server.
I already follow the docs but It doesn't work. The Filepond gives error Error during load 400 and it even doesn't send the request to load the file from server
This is my javascript
let pond = FilePond.create(value, {
files: [
{
// the server file reference
source: 'e958818e-92de-4953-960a-d8157467b766',
// set type to local to indicate an already uploaded file
options: {
type: 'local'
}
}
]
});
FilePond.setOptions({
labelFileProcessingError: (error) => {
return error.body;
},
server: {
headers: {
'#tokenSet.HeaderName' : '#tokenSet.RequestToken'
},
url: window.location.origin,
process: (fieldName, file, metadata, load, error, progress, abort) => {
// We ignore the metadata property and only send the file
fieldName = "File";
const formData = new FormData();
formData.append(fieldName, file, file.name);
const request = new XMLHttpRequest();
request.open('POST', '/UploadFileTemp/Process');
request.setRequestHeader('#tokenSet.HeaderName', '#tokenSet.RequestToken');
request.upload.onprogress = (e) => {
progress(e.lengthComputable, e.loaded, e.total);
};
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
load(request.responseText);
}
else {
let errorMessageFromServer = request.responseText;
error('oh no');
}
};
request.send(formData);
},
revert: "/UploadFileTemp/revert/",
load: "/UploadFileTemp/load"
}
})
This is my controller
public async Task<IActionResult> Load(string p_fileId)
{
//Code to get the files
//Return the file
Response.Headers.Add("Content-Disposition", cd.ToString());
Response.Headers.Add("X-Content-Type-Options", "nosniff");
return PhysicalFile(filePath, "text/plain");
}
NB
I already test my controller via postman and it works. I also check the content-disposition header
I'd advise to first set all the options and then set the files property.
You're setting the files, and then you're telling FilePond where to find them, it's probably already trying to load them but doesn't have an endpoint (yet).
Restructuring the code to look like this should do the trick.
let pond = FilePond.create(value, {
server: {
headers: {
'#tokenSet.HeaderName': '#tokenSet.RequestToken',
},
url: window.location.origin,
process: (fieldName, file, metadata, load, error, progress, abort) => {
// your processing method
},
revert: '/UploadFileTemp/revert',
load: '/UploadFileTemp/load',
},
files: [
{
// the server file reference
source: 'e958818e-92de-4953-960a-d8157467b766',
// set type to local to indicate an already uploaded file
options: {
type: 'local',
},
},
],
});

Where are files stored with cordova-file-plugin

I'm trying to create a excel on a mobile device, I'm testing with android but it should work for iOS too
I used the following code from the documentation
Documentation
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
console.log('file system open: ' + fs.name);
fs.root.getFile("newPersistentFile.txt", { create: true, exclusive: false }, function (fileEntry) {
console.log("fileEntry is file?" + fileEntry.isFile.toString());
fileEntry.name == 'someFile.txt'
fileEntry.fullPath == '/someFile.txt'
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function() {
console.log("Successful file write...");
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log("Successful file read: " + this.result);
//displayFileData(fileEntry.fullPath + ": " + this.result);
};
reader.readAsText(file);
},);
};
fileWriter.onerror = function (e) {
console.log("Failed file write: " + e.toString());
};
let dataObj = new Blob(['some file data'], { type: 'text/plain' });
fileWriter.write(dataObj);
});
});
});
I've tried changing the first three lines for the following ones, with the same result
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (fs) {
console.log('file system open: ' + fs.name);
fs.root.getFile("newPersistentFile.txt", { create: true, exclusive: false }, function (fileEntry) { ...
I get the following console log
file system open: persistent
fileEntry is file?true
Successful file write...
Successful file read: some file data
so, the file is created and I can read it, but I don't get any prompt or something, then I navigate to my file on Android/data/com.myapp.app/files and I don't have any file
Seems the files were saving but I couldn't see them, but I could read them via cordova-file-plugin
I changed the destination folder to
let ruta = cordova.file.externalRootDirectory
let directoryRoute = "myApp";
window.resolveLocalFileSystemURL(ruta, function (fs) {
fs.getDirectory(directoryRoute, { create: true }, function (fs2) {
fs2.getFile(fileName, { create: true, exclusive: false }
, function (fileEntry) { ...
with cordova.file.externalRootDirectory I'm creating if doesn't exist a folder to save my app documents, this works with android, probably there will be changes to iOS
I'm going to update the answer on a few days when I have the answer for iOS in case this can help someone

ExtJs - Save selected file from filefield

I want to upload a file using the extjs6 modern toolkit. Therefor I display a MessageBox with a file chooser. How can I retrieve the selected file into a javascript object after clicking the OK button to upload it (via HTTP POST e.g.)?
this.createUploadMsgBox("File Upload", function (clickedButton) {
if (clickedButton == 'ok') {
console.log("file: " + file);
}
createUploadMsgBox: function (title, callback) {
Ext.Msg.show({
title: title,
width: 300,
buttons: Ext.MessageBox.OKCANCEL,
fn: callback,
items: [
{
xtype: 'filefield',
label: "File:",
name: 'file'
}
]
});
}
You can rum my example here:
https://fiddle.sencha.com/#view/editor&fiddle/1kro
You have two posible solutions.
One is to use a form, and send the file via form.submit() (use form.isValid() before the submit). You can retrieve the file in the server with a MultipartFile.
The other way is to use JS File API. In you createUploadMsgBox function:
this.createUploadMsgBox("File Upload", function (clickedButton) {
if (clickedButton == 'ok') {
//console.log("file: " + file);
var filefield = Ext.ComponentQuery.query('filefield')[0];
var file = filefield.el.down('input[type=file]').dom.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
console.log(e.target.result);
};
})(file);
reader.readAsBinaryString(file);
}
});
In the file object you have the basic info of the file, and then you will see in the console the content of the file.
Hope this helps!

Save this pdf in the cache/local storage on ionic

Ho to everyone. I followed this tutorial to create a modal view with a pdf generated with pdfmake.
http://gonehybrid.com/how-to-create-and-display-a-pdf-file-in-your-ionic-app/
My simply question is how can i save the pdf in my local storage on in cache? I need that to send the pdf by email or open it with openfile2. I'm using Ionic and cordova.
I don't know how you code it, but I know what plugin you should use:
https://github.com/apache/cordova-plugin-file
The git contains a complete documentation of the plugin so everything you could need should be there.
Sample code to write pdf file in device using cordova file and file transfer plugin:
var fileTransfer = new FileTransfer();
if (sessionStorage.platform.toLowerCase() == "android") {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, onFileSystemSuccess, onError);
} else {
// for iOS
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, onError);
}
function onError(e) {
navigator.notification.alert("Error : Downloading Failed");
};
function onFileSystemSuccess(fileSystem) {
var entry = "";
if (sessionStorage.platform.toLowerCase() == "android") {
entry = fileSystem;
} else {
entry = fileSystem.root;
}
entry.getDirectory("Cordova", {
create: true,
exclusive: false
}, onGetDirectorySuccess, onGetDirectoryFail);
};
function onGetDirectorySuccess(dir) {
cdr = dir;
dir.getFile(filename, {
create: true,
exclusive: false
}, gotFileEntry, errorHandler);
};
function gotFileEntry(fileEntry) {
// URL in which the pdf is available
var documentUrl = "http://localhost:8080/testapp/test.pdf";
var uri = encodeURI(documentUrl);
fileTransfer.download(uri, cdr.nativeURL + "test.pdf",
function(entry) {
// Logic to open file using file opener plugin
},
function(error) {
navigator.notification.alert(ajaxErrorMsg);
},
false
);
};

How to add html form user input into a file with JavaScript?

I was wondering how do I put HTML form user input into a file using JavaScript ONLY.
I have struggled to find an answer to such a simple question.
Writing data to files on a local filesystem is only supported in modern browsers with a set of limitations, you can google for HTML FileSystem API.
As for writing to a file, this is a basic example:
function onInitFs(fs) {
fs.root.getFile('log.txt', {create: true}, function(fileEntry) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
console.log('Write completed.');
};
fileWriter.onerror = function(e) {
console.log('Write failed: ' + e.toString());
};
// Create a new Blob and write it to log.txt.
var blob = new Blob(['Lorem Ipsum'], {type: 'text/plain'});
fileWriter.write(blob);
}, errorHandler);
}, errorHandler);
}
window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);

Categories