I am using a POST method to get a byte array of an excel file
c# server side implementation:
downloadExcel() {
....
FileResultDto fileResultDto = new FileResultDto
{
Data = ExcelHelper.CreateExcelFile(excelFile) //Data contains the byte array
};
return new JsonHttpResponseMessage(JsonConvert.SerializeObject(fileResultDto));
}
CreateExcelFile():
public byte[] CreateExcelFile(ExcelFile excelFile)
{
try
{
#region Validation
if (excelFile == null)
{
throw new ArgumentNullException(nameof(excelFile));
}
#endregion
byte[] bytes;
using (ExcelPackage excelPackage = new ExcelPackage())
{
for (int i = 1; i <= excelFile.Worksheets.Count; i++)
{
Worksheet worksheet = excelFile.Worksheets[i - 1];
excelPackage.Workbook.Worksheets.Add(worksheet.Name);
ExcelWorksheet currentExcelWorksheet = excelPackage.Workbook.Worksheets[i];
if (excelFile.HasLogoTemplate)
{
byte[] imageBytes = Convert.FromBase64String(LogoBase64);
Image image;
using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
image = Image.FromStream(ms, true);
}
ExcelPicture picture = currentExcelWorksheet.Drawings.AddPicture("Logo", image);
picture.SetPosition(0, 4, 0, 10);
currentExcelWorksheet.Row(1).Height = 50;
}
SetColumnsWidths(currentExcelWorksheet, worksheet);
WriteHeaderRow(currentExcelWorksheet, worksheet.HeaderRow);
WriteCells(currentExcelWorksheet, worksheet.Cells);
}
#region Set Excel Stream
bytes = excelPackage.GetAsByteArray();
#endregion
}
return bytes;
}
catch (Exception exception)
{
throw new Exception("There was an error on excel export. Exception: ", exception);
}
}
front end implementation:
public downloadExcel(): void {
this.myRepository.downloadExcel(this.postData).then(result => {
var byteArray = new Uint8Array(result.data.data);
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob([byteArray], { type: "application/octet-stream" }));
a.download = "test.xlsx";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}, error => {
console.log(error);
});
}
Apparently the created blob file it seems to be corrupted. Any suggestions where the problem can be?
Finally the problem solved using 'arraybuffer' as the response type of the http request.
let requestConfiguration: ng.IRequestConfig = {
cache: ...,
data: ...,
headers: ...,
method: ...,
url: ...,
responseType: 'arraybuffer'
};
let promise: ng.IPromise<any> = this.$http(requestConfiguration);
The same is done in Angular. This might be help you
downloadExcel(){
this.downloadAttachment(filename).subscribe(res => {
let Res=res;
const downloadedFile = new Blob([Res], { type: Res.type });
const a = document.createElement('a');
a.setAttribute('style', 'display:none;');
document.body.appendChild(a);
a.download = attachment.filename;
a.href = URL.createObjectURL(downloadedFile);
a.target = '_blank';
a.click();
document.body.removeChild(a);
},
err=>{
throw err;
})
}
downloadAttachment(filename){
this.httpOptions = {
reportProgress: true,
responseType: "blob"
};
return this.http.get(API_URL, this.httpOptions).pipe(
map(response => response),
catchError(this.handleError<any>(isShowError)),
finalize(() => {
})
);
}
C# Code
var res=DownloadAttachment(filename);
if (res == null)
return Content("filename not present");
return File(res, Utility.GetContentType(filename), filename);
Related
I try to upload file using Axios but I want to just use string of file path. Using code below it is working:
<input
id="select-files"
style="visibility: hidden"
type="file"
multiple
#change="handleFilesUpload($event)"
/>
But when I tried to use createReadStream it does not work. I wonder how I could convert these path files to event.target.files.
I already try the code above but it does not work:
let data = {
THE_FILE: "",
BRANCH_ID: this.$store.state.starv.localUser.DOCTOR_INFO["BRANCH_ID"],
ACC_NO: this.locationItem["ACC_NO"],
CHART_NO: this.locationItem["CHART_NO"],
EMP_ID: this.$store.state.starv.localUser.DOCTOR_INFO["EMP_ID"],
CO_EMP_ID: this.doctorList.toString(),
ST: "telehealthclient",
NEW_NAME: "",
MAID: LocalData.getComputerId(),
}
/*
Iterate over any file sent over appending the files to the form data.
*/
data["THE_FILE"] = window.fs.createReadStream(filePath)
let bodyFormData = new FormData()
// if (THE_FILE) {
// bodyFormData.append("THE_FILE", THE_FILE)
// }
for (let key in data) {
bodyFormData.append(key, data[key])
}
I already found the solution to this problem, what we would to do are below:
Encode our file to base64
base64_encode(file) {
// read binary data
let bitmap = window.fs.readFileSync(file);
// convert binary data to base64 encoded string
return new Buffer(bitmap).toString("base64");
},
Create a file-url object from our base64
dataURLtoFile(dataurl, filename) {
const arr = dataurl.split(",");
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n) {
u8arr[n - 1] = bstr.charCodeAt(n - 1);
n -= 1; // to make eslint happy
}
return new File([u8arr], filename, { type: mime });
},
Create form data from form-data library Upload using Axios
form-multipart
Full code is below
base64_encode(file) {
// read binary data
let bitmap = window.fs.readFileSync(file);
// convert binary data to base64 encoded string
return new Buffer(bitmap).toString("base64");
},
dataURLtoFile(dataurl, filename) {
const arr = dataurl.split(",");
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n) {
u8arr[n - 1] = bstr.charCodeAt(n - 1);
n -= 1; // to make eslint happy
}
return new File([u8arr], filename, { type: mime });
},
uploadScreenRecord(data) {
return new Promise((resolve, reject) => {
// #1 Convert to base64 first
let base64_video = this.base64_encode(data.file);
// #2 Create file url object from base64
let filename = path.parse(data.file).base;
let fileURLobject = this.dataURLtoFile(
"data:video/mp4;base64," + base64_video,
filename
);
// #3 Create form data from form-data libary
const formData = new formData_();
formData.append("THE_FILE", fileURLobject, filename);
for (let key in data) {
if (key != "file") {
formData.append(key, data[key]);
}
}
// #4 Send to server
let url;
if (SETTING.imedtacDomain.hostname == undefined) {
url = SETTING.webservice.imedtacProtocol + "//" + defaultDomain;
} else {
url =
SETTING.webservice.imedtacProtocol + "//" + SETTING.imedtacDomain.hostname;
}
axios
.post(url + SETTING.imedtacAPI.uploadFile.URL, formData, {
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "multipart/form-data",
},
timeout: 30000,
})
.then(function (response) {
//Return Patient
console.log("[File debug] This is upload file response %o", response);
if (response.data.success) {
resolve(response.data.FILE_URL);
} else {
reject(response.data.message + " screen record upload error");
}
})
.catch(function (error) {
reject(error);
});
});
},
submitFilesTest() {
return new Promise((resolve, reject) => {
//Data
let data = {
file: "/Users/ivanhutomo/Downloads/B0120221214151850_A.mp4",
BRANCH_ID: "xxx",
ACC_NO: "xx",
CHART_NO: "xx",
EMP_ID: "xx",
CO_EMP_ID: "xx",
ST: "xx",
NEW_NAME: "",
MAID: "xx",
};
this.uploadScreenRecord(data)
.then((response) => {
logger.debug("[File debug] File upload URL %o", response);
resolve(response);
})
.catch((error) => {
logger.debug("[File debug] File %o", error);
reject(error);
});
});
},
submitFilesTest()
From a http request, a blob (b) (type application/octet-stream) is downloaded and then needs to be processed, it contains a json object.
I tried the following:
var reader = new FileReader();
reader.readAsText(b);
var readResult = <string> reader.result;
console.log(readResult);
var obj = JSON.parse(readResult);
It doesn´t work, and readResult is null.
How can you process a blob that contains a json into a json object?
When the request has responseType: 'blob' it returns binary, but if an error occurs message is returned as JSON inside Blob.
This is how you can decode JSON messages from blob:
(response) => {
return response;
},
async (error) => {
if (error.response.data instanceof Blob) {
const blob = new Blob([error.response.data]);
const data = await blob.text();
const { message, details } = JSON.parse(data);
//display message and details to the user
}
}
You will need an onload event like so:
var blob = new Blob([JSON.stringify({"test": "Hello from JSON!"})], {type : "application/json"}),
reader = new FileReader();
reader.onload = function() {
document.body.innerText = JSON.parse(this.result).test;
};
reader.readAsText(blob);
Code example :
try{
await this.exampleservice.MygetRequest().then(httpResponse => {
httpResponse.body.text().then(text => {
//console.log(text);
obj = JSON.parse(text);
//console.log('obj after parse:' ,obj);
let data = obj.result.data;
console.log('My data:' ,data);
});
});
}catch (error) {
if (error instanceof HttpErrorResponse) {
Swal({
type: 'error',
title: this.errorsService.getErrorMessage(error.status),
showConfirmButton: false,
timer: 1500
});
this.feedback_errors = error.error.errors;
this.feedback_errors_keys = this.feedback_errors ? Object.keys(this.feedback_errors) : null;
}
}
I am trying to convert an image file to blob but get the error below:
{"code":2, "message":"SECURITY_ERR"}
Any idea why this might be happening? I tried a lot of online resources but really could not find out what is going on.
I have the following code:
choose(){
this.filechooser.open().then((uri)=>{
this.file.resolveLocalFilesystemUrl(uri).then((newurl)=>{
let dirPath = newurl.nativeURL;
alert(dirPath);
let dirPathsegments = dirPath.split('/')
dirPathsegments.pop();
dirPath = dirPathsegments.join('/');
this.file.readAsArrayBuffer(dirPath, newurl.name).then((buffer)=>{
let blob = new Blob([buffer], {type: "image/jpeg"});
alert('blob creation success');
}, Error=>{
alert('Blob Error '+ JSON.stringify(Error));
});
});
},Error=>{
alert('Error Choosing File ' + Error);
});
}
Is there any other way to convert the file into a blob?
The current APIs that I am using only accepts Binary or Multipart attachments
It works. Tested on ionic 2 & 3
uploadFile() {
this.fileChooser.open().then((url) => {
(<any>window).FilePath.resolveNativePath(url, (nativeFilepath) => {
this.readFileFromStorage(nativeFilepath);
}
)
})
}
readFileFromStorage(nativeFilepath) {
let fileName = this.getfilename(nativeFilepath);
let fileExt = fileName.substring(fileName.lastIndexOf('.') + 1);
let blogType = { type: 'image/'+fileExt };
(<any>window).resolveLocalFileSystemURL(nativeFilepath, (res) => {
res.file((resFile) => {
var reader = new FileReader();
reader.readAsArrayBuffer(resFile);
reader.onloadend = (evt: any) => {
var imgBlob = new Blob([evt.target.result], blogType);
//Upload blob to firebase
this.uploadToFirebase(imgBlob,fileName);
}
})
})
}
getfilename(filePath){
let fileName : string;
fileName = filePath.replace(/^.*[\\\/]/, '')
return fileName;
}
uploadToFirebase(fileBlob, name) {
let storage = firebase.storage();
storage.ref('images/' + name).put(fileBlob).then((d) => {
alert("Done");
}).catch((error) => {
alert("Error: " + JSON.stringify(error));
});
}
I am trying to fill an excel file using the JSON below. I am getting the JSON data from HTTP response and I would like to use it for downloading an excel file.
{
"dynaModel":[
{
"map":{
"UNIT/SUBUNIT":"sdasd",
"SUBUNIT/ISU/GEO":"sasd",
"REVENUEINR-RS":"₹87,sdd",
"COSTINR-RS":"₹47,33",
"GMINR-RSUSD-$":46,
"REVENUEINR-RS":"₹87,64,",
"COSTINR-RS":"₹47,33,",
"GMINR-RSUSD-$":46
}
},
{
"map":{
"UNIT/SUBUNIT":"fghf",
"SUBUNIT/ISU/GEO":"CMghhfI",
"REVENUEINR-RS":"₹59,06",
"COSTINR-RS":"₹30,43",
"GMINR-RSUSD-$":48.47,
"REVENUEINR-RS":"₹59",
"COSTINR-RS":"₹30,43",
"GMINR-RSUSD-$":48.47
}
},
{
"map":{
"UNIT/SUBUNIT":"hfgh",
"SUBUNIT/ISU/GEO":"fghh",
"'APR-16'_REVENUEINR-RS":"₹29,72",
"'APR-16'_COSTINR-RS":"₹11,43",
"'APR-16'_GMINR-RSUSD-$":61.53,
"'Total'_REVENUEINR-RS":"₹29,72",
"'Total'_COSTINR-RS":"₹11,43",
"'Total'_GMINR-RSUSD-$":61.53
}
}
]
}
my components code is shown below :
excelDownload(){
this._isuGeoSubunitReportService.excelDownload(this.isugeosubunitTO)
.subscribe(data =>this.responseStatus = data,
err => console.log(err),
() => console.log('Request Completed222')
);
const ws_name = 'SomeSheet';
const wb: WorkBook = { SheetNames: [], Sheets: {} };
const ws: any = utils.json_to_sheet(this.responseStatus.dynamoModel);
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
const wbout = write(wb, { bookType: 'xlsx', bookSST: true, type: 'binary' });
function s2ab(s) {
const buf = new ArrayBuffer(s.length);
const view = new Uint8Array(buf);
for (let i = 0; i !== s.length; ++i) {
view[i] = s.charCodeAt(i) & 0xFF;
};
return buf;
}
saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), 'exported.xlsx');
}
I am trying to download the result in xlxs for which I am using xlxs module of json. its works fine for simple json but my json data is different.
const ws: any = utils.json_to_sheet(this.responseStatus);
if I simply put the this.responseStatus it return only one map value in the xlxs.
There is a typing error in your code. You are using: this.responseStatus.dynamoModel instead of this.responseStatus.dynaModel.
Also, according to the documentation of the module xlsx, your array to parse is expected to have a syntax like this one before using utils.json_to_sheet:
[
{S:1,h:2,e:3,e_1:4,t:5,J:6,S_1:7},
{S:2,h:3,e:4,e_1:5,t:6,J:7,S_1:8}
]
So you can use the function utils.aoa_to_sheet instead of utils.json_to_sheet
Another option, you could create your own function that will parse your data so as to have a form like the one given in the documentation for utils.json_to_sheet. This is how I transformed the code in your component.
excelDownload() {
this.appService.excelDownload()
.subscribe(data => {
this.responseStatus = data;
this.generateExcelFile(data);
},
err => console.log(err),
() => console.log('Request Completed222')
);
}
generateExcelFile(data: any) {
this.responseStatus = data;
const ws_name = 'SomeSheet';
const wb: WorkBook = { SheetNames: [], Sheets: {} };
const ws: any = utils.json_to_sheet(parseArray(this.responseStatus.dynaModel));
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
const wbout = write(wb, { bookType: 'xlsx', bookSST: true, type: 'binary' });
function s2ab(s) {
const buf = new ArrayBuffer(s.length);
const view = new Uint8Array(buf);
for (let i = 0; i !== s.length; ++i) {
view[i] = s.charCodeAt(i) & 0xFF;
}
return buf;
}
// function to parse your array coming from the backend
function parseArray(dataToParse: any) {
const newArray = [];
dataToParse.forEach(item => {
Object.keys(item).forEach(key => {
newArray.push(item[key]);
});
});
console.log('newArray:' + JSON.stringify(newArray));
return newArray;
}
FileSaver.saveAs(new Blob([s2ab(wbout)],
{ type: 'application/octet-stream'}),
'exported.xlsx');
}
Uploading an image (from a dataUrl format) using an XHR request appears to fail on iOS (10.0.2+), other browsers are working: the latest Chrome (54.0.2840.71), Firefox (50.0).
The request seems to be constructed correctly in JS, but there is no actual data attached to the request.
var dataUrl = "data:image/jpeg;base64,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";
// create base64 encoded version of image
let parts = dataUrl.split(',');
let mime = parts[0].match(/:(.*?);/)[1];
let bstr = atob(parts[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
let blob = new window.Blob([u8arr], {type: mime});
file = new window.File([blob], file.name);
// create formdata for uploading
let data = new FormData();
data.append('file', file, file.name);
// send the post request
var xhr = new XMLHttpRequest;
xhr.onload = function (oEvent) {
// Uploaded.
if ( oEvent.target.status == '200') {
console.log('upload with XHR success');
} else {
console.log('upload with XHR error');
}
};
xhr.open("POST", '/upload-endpoint', false);
xhr.send(data);
The main idea of how to upload an image to a RESTful api is using multipart/form-data.
If you use Swift 3.0, you can try these code below, using URLSession:
import Cocoa
fileprivate extension ImageUploader {
static let urlString = "/upload-endpoint"
static let boundary = "---------------------------14737809831460499985746342449"
static let contentType = "multipart/form-data; boundary=\(boundary)"
}
typealias CompletionBlock = (_ data: Data?, _ response: URLResponse?, _ error: Error?) -> Swift.Void
class ImageUploader {
func recognize(with paths: [String], completionBlock: #escaping CompletionBlock) {
guard paths.count > 0 else { return }
let path = paths.first!
guard let image = NSImage(contentsOfFile: paths.first!) else { return }
let imgRep: NSBitmapImageRep = image.representations.first as! NSBitmapImageRep
let data = imgRep.representation(using: .JPEG, properties: [:])
var request = URLRequest(url: URL(string: ImageUploader.urlString)!)
request.httpMethod = "POST"
request.timeoutInterval = 10
request.addValue(ImageUploader.contentType, forHTTPHeaderField: "Content-Type")
var postbody = Data()
postbody.append("\r\n--\(ImageUploader.boundary)\r\n".data(using: .utf8)!)
postbody.append("Content-Disposition: form-data; name=\"file\"; filename=\"file\"\r\n".data(using: .utf8)!)
postbody.append("Content-Type: application/octet-stream\r\n\r\n".data(using: .utf8)!)
postbody.append(data!)
postbody.append("\r\n--\(ImageUploader.boundary)\r\n".data(using: .utf8)!)
request.httpBody = postbody
let task = URLSession.shared.dataTask(with: request) { data, response, error in
completionBlock(data, response, error)
}
task.resume()
}
}
Maybe try using fetch instead of xhr?
let dataUrl = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
let {name} = file
// First convert base64 to blob
fetch(dataUrl)
.then(res => res.blob())
.then(blob => {
// Now upload the blob
let fd = new FormData()
fd.append('file', blob, name)
fetch('/upload-endpoint', {method: 'POST', body: fd})
.then(res => {
console.log('upload with fetch success:', res.ok)
})
})