get multiple files from request on Grails - file

Im using this but it saves only one file. I want to save multiple files.
Here is my code:
<input id="data" type="file" name="data" multiple="multiple"/>
and
def uploadSave() {
def document = request.getFile("data").each { file ->
log.debug(file.originalFilename)
}
What can I use to save all the files uploaded and print their original names? I tried to use MultipartFile but doesnt work. Help me, please.
MultipartFile data = request.getFile("data"){
println "File name: "+ ${data.orignalFileName}"
}

Have you tried using the uploadr plugin for grails?
https://grails.org/plugin/uploadr
no point re-inventing the wheel.

I would Like suggest you this jquery it one best file upload I ever come across as per as customization comes into picture they have solve all the problem ,you can upload the file download file and delete uploaded file
http://hayageek.com/docs/jquery-upload-file.php#doc
Hope this help you Thank's.

try this
def uploadSave() {
// notice "getFiles" instead of "getFile"
def document = request.getFiles("data")
document.each { file ->
println(file.getOriginalFilename()) // try this
//log.debug(file.originalFilename) // tthink this is causing the error
}
}

Related

How to upload a local json file using Blazor

I am trying to select a local json file and load it in my blazor client component.
<input type="file" onchange="LoadFile" accept="application/json;.json" class="btn btn-primary" />
protected async Task LoadFile(UIChangeEventArgs args)
{
string data = args.Value as string;
}
P,S I do not understand , do i need to keep track both the name of the file and the content when retrieving it ?
I guess you're trying to read the contents of a JSON file on the client (Blazor), right? Why not on the server !?
Anyhow, args.Value can only furnish you with the name of the file. In order to read the contents of the file, you can use the FileReader API (See here: https://developer.mozilla.org/en-US/docs/Web/API/FileReader). That means that you should use JSIntrop to communicate with the FileReader API. But before you start, I'd suggest you try to find out if this API have been implemented by the community (something like the localStorage, etc.). You may also need to deserialize the read contents into something meaningful such as a C# object.
Hope this helps...
There is a tool that can help, but it currently doesn't support the 3.0 preview. https://github.com/jburman/W8lessLabs.Blazor.LocalFiles
(no affiliation with the developer)
The input control will give you the location of the file as a full path along with the name of the file. Then you still have to retrieve the file and download it to the server.
Late response but with 3.1 there is an additional AspNetCore.Components module you can download via NuGet to get access to HttpClient extensions. These make it simple:
// fetch mock data for now
var results = await _http.GetJsonAsync<WellDetail[]>("sample-data/well.json");
You could inject the location of the file from your input control in place of the "sample-data/well.json" string.
Something like:
using Microsoft.AspNetCore.Components;
private async Task<List<MyData>> LoadFile(string filePath)
{
HttpClient _http;
// fetch data
// convert file data to MyData object
var results = await _http.GetJsonAsync<MyData[]>(filePath);
return results.ToList();
}

convert cordova files path to File object

I am trying to build a simple photo upload app on Ionic (Cordova). I am using the cordovaImagePicker plugin to have the user select images from the mobile device. This plugin returns an array of paths on the device.
For handling the upload part I am using jquery-file-upload (mostly because that is what I used for the browser version and I am doing all kinds of processing for which I have the code ready). The problem is however that jquery-file-upload expects to work with an input element <input type="file"> which creates a javascript File object containing all kinds of metadata.
So in order to get the cordovaImagePicker to work with jquery-file-upload, I figure I have to convert the filepath to a File object. Below I am using the cordova file plugin to achieve this:
$cordovaImagePicker.getPictures($scope.pickOptions).then(function(filelist) {
$.each(filelist, function (index, filepath) {
$window.resolveLocalFileSystemURL(filepath, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
fileObj = new File([this.result],"filename.jpg",{type: "image/jpeg"});
// send filelist from cordovaImagePicker to jquery-fileupload as if through file input
$('#fileupload').fileupload('send', {files: fileObj});
};
reader.readAsArrayBuffer(file);
}, function(e){$scope.errorHandler(e)});
}, function(e){$scope.errorHandler(e)});
});
}, function(error) {
// error getting photos
console.log('Error selecting images through $cordovaImagePicker');
});
So first of all this is not really working correctly, apparently I am doing doing something wrong, since for example the type attribute ends up being another object that contains the type attribute with the correct values (and other such weird issues). I would be happy if someone could point out what I am doing wrong.
Surely there must be something (cordova plugin?) that I am not aware of that does this conversion for me (including for example adding a thumbnail)? Alternatively, maybe there is something that can easily make jquery-file-upload work with filepaths? I couldn't find anything so far...
However, it feels I am trying too hard here to force connecting two components that were just not built to work together (File objects vs filepath) and I should maybe just rewrite the processing and use the cordova file transfer plugin?
I ended up rewriting the uploader with the cordova-file-transfer which works like a charm. I wasted more time trying to work around it than just rewriting it from scratch.

Google Apps Scripts - How to replace a file?

I'm trying to replace a PDF file in a Google Drive Folder using a script. Since GAS does not provide a method for adding revisions (versions), I'm trying to replace the content of the file, but all I get is a blank PDF.
I can't use the DriveApp.File class since our Admin has disabled the new API, so I have to use DocsList.File instead.
Input:
OldFile.pdf (8 pages)
NewFile.pdf (20 pages)
Output expected:
OldFile.pdf with the same content as NewFile.pdf
Real Output:
OldFile.pdf with 20 empty pages.
Process:
var old = DocsList.getFileById("####");
var new = DocsList.getFileById("####");
old.replace(new.getContentAsString());
Any ideas, please?
Thanks a lot in advance.
PS.: I also tried calling old.clear() first, but I'd say the problem lies on the getContentAsString method.
The Advanced Drive Service can be used to replace the content of an existing PDF file in Google Drive. This answer also includes an example of how to update a PDF file in a shared Drive.
function overwriteFile(blobOfNewContent,currentFileID) {
var currentFile;
currentFile = DriveApp.getFileById(currentFileID);
if (currentFile) {//If there is a truthy value for the current file
Drive.Files.update({
title: currentFile.getName(), mimeType: currentFile.getMimeType()
}, currentFile.getId(), blobOfNewContent);
}
}
References
https://developers.google.com/apps-script/advanced/drive
https://developers.google.com/drive/api/v3/reference/files/update
An example of using with a shared Drive:
Drive.Files.update({ title: currentFile.getName(), mimeType:
currentFile.getMimeType() }, currentFile.getId(), blobOfNewContent,
{supportsTeamDrives: true});
Try to get it as a blob datatype instead.

Grails create downloadable file on the fly

Briefly: I can make a file, save it in the file system and then make a page with a link to that file, but what if I want a page with links to many files which may not all need to be generated?
So my user clicks a link on the list page like:
<g:link action="gimmeAFile" id="${myThingieInstance.id}">${fieldValue(bean: myThingieInstance, field: "id")}</g:link>
Right now I have a controller that looks like this:
def gimmeAFile = {
def lotsaLines = []
//Do a ton of stuff that has lotsaLines.add(resultStrings) all over
def fileName = "blahblah-${dateOrSomething}.csv"
def dumbFile = new File('web-app/tmpfiles/'+fileName).withWriter {out ->
lotsaLines.each{
out.println it
}
}
[fileName:fileName]
}
And then they go to gimmeAFile.gsp which has the link to actually download the file:
Download Report
How do I make a link on the list viewer that will create and download the file without dragging the user to an extra screen. NOTE: I cannot have the files pre-generated, so I need to figure out how to link to a file that isnt there yet. I'm thinking something like render() at the end of the controller. Can I make the gimmeAFile controller just give the file instead of making a page with a link to the file?
OK so to clarify this is what I finally figured out based on Kaleb's answer. Thankyou SO!!
def gimmeAFile = {
def lotsaLines = []
//Do a ton of stuff that has lotsaLines.add(resultStrings) all over
def fileName = "blahblah-${dateOrSomething}.csv"
def dumbFile = new File('web-app/tmpfiles/'+fileName).withWriter {out ->
lotsaLines.each{
out.println it
}
}
def openAgain = new File('web-app/tmpfiles/'+fileName)
response.setContentType("text/csv")
response.setHeader("Content-disposition", "filename=${fileName}")
response.outputStream << openAgain.getBytes()
response.outputStream.flush()
return
}
You can create a view that just gets the bytes of the file and writes out to the response:
response.contentType = 'image/jpeg' // or whatever content type your resources are
response.outputStream << file.getBytes()
response.outputStream.flush()
Is that what you're trying to do?
Another option which is a bit nicer, you can just render the file, straight from your controller's action:
render(file: theFile, contentType: 'your/contentType')
See also: http://grails.org/doc/latest/ref/Controllers/render.html
(I've found that if you add the fileName option, it prompts the user to download the file.)

grails file download

I have sucessfully managed to make a file upload system which basically is copying files to a specific folder and save in the database its location. Now i need help with the download part. Imagine my file location is: Files/1306242602661_file1.exe, and in my view i have this:
<g:link controller="fileManager" action="downloadFile">
Download</g:link><br>
I need help with the downloadFile controller. Could you please give me a hint about how to do this, considering my filename is a string:
String fileName = "Files/1306242602661_file1.exe"
Within your controller create an download action with following content:
def file = new File("path/to/file")
if (file.exists()) {
response.setContentType("application/octet-stream")
response.setHeader("Content-disposition", "filename=${file.name}")
response.outputStream << file.bytes
return
}
// else for err message
You can render a file. see http://grails.org/doc/2.4.x/ref/Controllers/render.html
render file: new File ("path/to/file.pdf"), fileName: 'myPdfFile.pdf'

Resources