I have an MVC controller to export excel file :
public ActionResult exportExcelBankData(BankDataViewModel viewModel) {
List<BankDataViewModel> bankDatas = (List<BankDataViewModel>)Session["bankDatas"];
bankDatas = bankDatas.OrderBy(x => x.completeLoading).ToList();
using (var package = new ExcelPackage()) {
var stream = new MemoryStream();
string fileName = "bankData.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//fill rows and columns
package.SaveAs(stream);
stream.Position = 0;
return File(stream, contentType, fileName);
}
}
and here my angularjs function to hit the controller
labAnalysisService.exportExcel = function (val, obj) {
return $http.get( val, //url to controller
{ params: obj, //parameter
headers: { 'Accept': 'application/json' }
});
}
and I'am still unable to export the excel.
any suggestion?
A File returned with ajax call will not be downloaded, you have to make following changes.
Make request of the excel download by opening a new window of browser through java script like this
window.open(
"Controller/Action?args=" + encodeURIComponent(val),
"_blank");
Related
I try to display images from s3 bucket in asp.net mvc I get the base64 encoded response. but is not display image in the view
first image is in binary encoding, rather than Base64.
so I convert into base64 with this
function _arrayBufferToBase64()
This is my view
<img data-ng-src="data:image/jpeg;charset=utf-8;base64,{{str}}"
alt="MyImage">
This is my MVC controller
[HttpGet]
public ActionResult GetReadObject()
{
string responseBody = "";
try
{
using (IAmazonS3 s3client = new AmazonS3Client(_awsAccessKey, _awsSecretKey, RegionEndpoint.USEast1))
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = _bucketName,
Key = keyName
};
using (GetObjectResponse response = s3client.GetObject(request))
using (Stream responseStream = response.ResponseStream)
using (StreamReader reader = new StreamReader(responseStream))
{
string title = response.Metadata["x-amz-meta-title"];
Console.WriteLine("The object's title is {0}", title);
responseBody = reader.ReadToEnd();
}
}
}
catch (Exception ex)
{
}
return Json(responseBody, JsonRequestBehavior.AllowGet);
}
This is my controller
app.controller('myCtrl', function ($scope, $http) {
$http({
method: 'GET',
url: '/User/Dashboard/GetReadObject',
responseType: 'arraybuffer'
}).then(function (response) {
alert("1");
console.log(response);
var str = _arrayBufferToBase64(response.data);
$scope.getImage = str;
alert(str);
console.log(str);
// str is base64 encoded.
},
function (response) {
console.error('error in getting static img.');
});
function _arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
})
You should try
<img data-ng-src="data:image/jpeg;charset=utf-8;base64,{{getImage}}"
alt="MyImage">
As you mentioned in your controller, str is simple javascript variable that you could not use with View. As you assign str value to $scope.getImage ($scope.getImage = str) You can use {{getImage}} with angular expression in your View.
download any file using ResponseEntity with angular does not work
I need to download a file using angular in client side,
this file can have any format it could be a pdf or excel or image or txt ...
my method works just for txt files and gives me a fail format for excel and image and for the pdf it gives an empty pdf.
so in my controller here is the function that calles the service method:
vm.downloadFile = downloadFile;
function downloadFile(file){
var urlDir = "C://STCI//"+idpeticion;
return VerDocServices.downloadFile(file,urlDir)
.then(function(response) {
var data = response.data;
var filename = file;
var contentType = 'application/octet-stream';//octet-stream
var linkElement = document.createElement('a');
try {
var blob = new Blob([ data ], {
type : contentType
});
var url = window.URL.createObjectURL(blob);
linkElement.setAttribute('href', url);
linkElement.setAttribute("download", filename);
var clickEvent = new MouseEvent("click", {
"view" : window,
"bubbles" : true,
"cancelable" : false
});
linkElement.dispatchEvent(clickEvent);
} catch (ex) {
console.log(ex);
throw ex;
}
}).catch(function(response) {
alert('Se ha producido un error al exportar del documento');
console.log(response.status);
throw response;
});
}
and my service.js has:
angular.module('mecenzApp').service('VerDocServices',['$http',function($http) {
this.downloadFile = function(file,urlDir) {
return $http.get('api/downloadFile', {
params : {
file : file,
urlDir : urlDir
}
}); }} ]);
And my service method is this:
#GetMapping("/downloadFile")
#Timed
public ResponseEntity<byte[]> downloadFile(#RequestParam(value = "file") String file, #RequestParam(value = "urlDir") String urlDir) {
log.debug("GET ---------------- DOWNLOAD FILE : {}", file);
log.debug("GET ---------------- From the DIRECTORY: {}",urlDir);
InputStream fileStream;
String filepath = urlDir+File.separator+file;
try {
File f = new File(filepath);
log.debug("GET ---------------- FILE: {}",f.getPath());
fileStream = new FileInputStream(f);
byte[] contents = IOUtils.toByteArray(fileStream);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/octet-stream"));
String filename = file;
headers.setContentDispositionFormData(filename, filename);
ResponseEntity<byte[]> response2 = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
fileStream.close();
return response2;
} catch (FileNotFoundException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
return null;
}
could you plz take a look and tell me what did I have missed??
Thank youuu :)
How to Download Binary Files with AngularJS
When downloading binary files, it is important to set the responseType:
app.service('VerDocServices',['$http',function($http) {
this.downloadFile = function(url, file, urlDir) {
var config = {
//SET responseType
responseType: 'blob',
params : {
file : file,
urlDir : urlDir
}
};
return $http.get(url, config)
.then(function(response) {
return response.data;
}).catch(function(response) {
console.log("ERROR: ", response.status);
throw response;
});
};
}]);
If the responseType is omitted the XHR API defaults to converting UTF-8 encoded text to DOMString (UTF-16) which will corrupt PDF, image, and other binary files.
For more information, see MDN Web API Reference - XHR ResponseType
I don't know much about the backend, but I'll provide what i have used may be it will help, so On the Java Script File:
//your $http(request...)
.success(function (data, status, headers, config) {
//Recieves base64 String data
var fileName = 'My Awesome File Name'+'.'+'pdf';
//Parsing base64 String...
var binaryString = window.atob(data);
var binaryLen = binaryString.length;
var fileContent = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
fileContent[i] = ascii;
}
var blob = new Blob([fileContent], { type: 'application/octet-stream' }); //octet-stream
var fileURL = window.URL.createObjectURL(blob);
$sce.trustAsResourceUrl(fileURL); //allow angular to trust this url
//Creating the anchor download link
var anchor = angular.element('<a/>');
anchor.css({display: 'none'}); // Make sure it's not visible
angular.element(document.body).append(anchor); // Attach it to the document
anchor.attr({
href: fileURL,
target: '_blank',
download: fileName
})[0].click();
anchor.remove(); // Clean it up afterwards
})
//.error(function(...
And On your backend, make sure that your webservice produces octet-stream and returning the file in base64 data format, i did this using Java JAX-RS like this:
#POST
#Path("/downloadfile")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadFile(...){
String base64String = Base64.getEncoder().encodeToString(/*here you pass your file in byte[] format*/);
return Response.ok(base64String).build();
}
i want to create a file in client side using Angular or Javascript and send it to server.
Using MVC controller my server function is
public void SavePivotFile(HttpPostedFileBase file)
{
try
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~"), System.Configuration.ConfigurationManager.AppSettings["reportsFolder"].ToString(), fileName);
file.SaveAs(path);
}
}
catch(Exception e)
{
throw;
}
}
Now, in my client side, i have a object that i want to send in SavePivotFile like a file. I tried this but doesnt work. The object 'options' is JSON.
$http({
method: 'GET',
url: '/FileManager/SavePivotFile',
params: {
file: options,
}
}).then(function successCallback(response) {
showNotification('The changes have been saved.', 'info');
}, function errorCallback(response) {
showNotification('Failed to save the file.', 'error');
});
Also i tried to create new FormData() before send but also doesn't work. How cat take options JSON object and pass it to server like file?
//C# Code
[HttpPost]
[Route('FileManager/SavePivotFile')]
// you can use [Allow(Role)] to allow particular role. Google it!
public void SavePivotFile(HttpPostedFileBase file)
{
try
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~"), System.Configuration.ConfigurationManager.AppSettings["reportsFolder"].ToString(), fileName);
file.SaveAs(path);
}
}
catch(Exception e)
{
throw;
}
}
//Angular Code
$http.post('FileManager/SavePivotFile',options)//Optionsistheobjectuwanttosend
.success(function(res){
//your code. since the c# method isvoid you will not get any response
})
.error(function(e){
//your error handling
})
The HttpPostedFileBase model should be similar to options. That way you can access the JSON in c#.
Let me know if this works.
I have a database with a varbinary(max) column for storing an image. I'd like to save the image in the database using Ajax (with controller actions and Entity Framework). Further, I'd like to retrieve the saved image and display it on the view (but that's another problem).
After looking around, I saw this https://stackoverflow.com/a/25768212/7885071
From that answer I have the following Ajax function :
function SaveImageViaAjax() {
var id = 123;
var formData = new FormData();
var totalFiles = document.getElementById("imageUploadForm").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("imageUploadForm").files[i];
formData.append("imageUploadForm", file);
}
$.ajax({
type: "POST",
data: {
"id":id
"image": formData
},
url: '/MyController/MyAction/',
success: function (response){
// alert(success);
},
error: function (xhr, status, error) {
alert("error");
}
});
}
If that function is correct, my problem is I don't know how to use an Action to populate/read the database.
Using https://stackoverflow.com/a/25400976/7885071 , I have properly set my model with byte[] for the image but how to deal with the action?
Here is what I propose :
Action to save the image in database:
[HttpPost]
public string SaveImageFromAjax(int id, byte[] image) //same as Ajax data section...
{
using(var db = myDbContext())
{
var MyObject object1 = new MyObject();
object1.id = id;
obecjt1.photo = image;
db.MyObject.Add(object1);
db.SaveChanges();
}
return "my message";
}
I know I must be far from the right code. Hopefully you'll kindly guide me to it...
I am trying to use ng-file-upload to upload files using Angular. I need the byte array to store in our database (I cannot store the uploaded file on the server), but I also need the FormData as well. My problem is that I can only seem to get one or the other (either the byte array or the formdata) but not both.
Here is my Angular code:
$scope.uploadPic = function (file) {
$scope.emrDetailID = 7;
file.upload = Upload.upload({
url: '/SSQV4/SSQV5/api/Document/UploadEMRDocument',
method: 'POST',
data: { file: file, 'emrdetail': $scope.emrDetailID}
});
file.upload.then(function (response) {
$timeout(function () {
file.result = response.data;
$scope.imageID = file.result;
});
});
};
Using the code below, I can get the byte array and store it in my database:
public async Task<IHttpActionResult> UploadDocument()
{
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var f = provider.Contents.First(); // assumes that the file is the only data
if (f != null)
{
string ClientIP = IPNetworking.GetIP4Address();
var filename = f.Headers.ContentDisposition.FileName.Trim('\"');
filename = Path.GetFileName(filename);
var extension = Path.GetExtension(filename).TrimStart('.');
var buffer = await f.ReadAsByteArrayAsync();
FileImageParameterModel pm = new FileImageParameterModel();
pm.binFileImage = buffer;
//pm.CompanyID = UserInfo.intMajorID;
pm.CompanyID = 10707;
pm.dteDocumentDate = Convert.ToDateTime("4/4/2016");
pm.dteExpiration = Convert.ToDateTime("4/4/2017");
pm.vchUserIP = ClientIP;
pm.vchUploadedbyUserName = UserInfo.Username;
pm.vchFileExtension = extension;
CommonClient = new CommonWebApiClient();
CommonClient.AuthorizationToken = UserInfo.AccessToken;
int imageID = await CommonClient.InsertNewFileImage(pm);
return Json(imageID);
}
else
{
return BadRequest("Attachment failed to upload");
}
}
Using the code below I can get the FormData
var provider = new MultipartFormDataStreamProvider(workingFolder);
await Request.Content.ReadAsMultipartAsync(provider);
var emr = provider.FormData["emrdetail"];
but then I can't get the byte array as using MultipartFormDataStreamProvider wants a folder to store the file.
There's got to be a way to get both. I have been searching the internet for 2 days and all I can find are the two solutions above neither of which solves my issue.
Any assistance is greatly appreciated!
You are thinking way to complicated. Here is some of my code which I used for file upload in AngularJS with .NET
Angular:
function uploadFileToUrl(file) {
var formData = new FormData(); // Notice the FormData!!!
formData.append('uploadedFile', file);
return $http({
url: uploadUrl,
method: 'POST',
data: formData,
headers: {
'Content-Type': undefined
}
}).then(resolve, reject);
function resolve(data) {
$log.debug('data : ', data);
return data;
}
function reject(e) {
$log.warn('error in uploadFileToUrl : ', e);
return $q.reject(e);
}
}
Server:
public Task HandleAsync([NotNull] UploadFilesCommand command)
{
return wrapper.InvokeOnChannel(async client =>
{
// init command
command.Output = new Dictionary<string, int>();
try
{
foreach (var file in command.Files)
{
var request = new UploadFileRequest
{
FileName = file.Name,
FileStream = file.Stream
};
UploadFileResponse response = await client.UploadFileAsync(request);
command.Output.Add(file.Name, response.Id);
}
}
finally
{
// dispose streams
foreach (var file in command.Files)
{
if (file.Stream != null)
{
file.Stream.Dispose();
}
}
}
});
}