File Download using Asp.net Web Api and Angular 8 - asp.net-web-api

Hi I recently started working on angular and I have a requirement to create and download excel file using asp.net web api and angular 8
I created excel file using Asp.net Web API and returning file as
return File(excelPackage.GetAsByteArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "test.xlsx");
I have to read this excel file using angular and download
GetExportExcel(editQuoteFilters: EditQuoteModel):Observable<any>{
let postHeaders = new HttpHeaders();
postHeaders.append('Content-Type', 'application/json');
postHeaders.append('responseType', 'blob');
return this.http.post<any>(this.ExcelExportLevel0ApiUrl, editQuoteFilters,{ headers: postHeaders,
responseType : 'arraybuffer' as 'json'})
.pipe(map((res) =>{
var blob = new Blob([res.blob()], {type: "application/vnd.ms-excel"})
return blob
})
);
}

You can use file-saver
import { saveAs } from 'file-saver';
this.http.post(this.ExcelExportLevel0ApiUrl, editQuoteFilters, { responseType: 'blob' }).subscribe((resp: any) => {
let fileName = "test";
FileSaver.saveAs(resp, `${fileName}.xlsx`);
});
Stackbiltz code

Related

How to parse image form data from FilePond

I'm attempting to upload image files to my nextjs app where I'll eventually store in GCS but I'm having some trouble with the image form data. I'm using FilePond on the client to handle uploading the file and sending a req to a simple API that I have on the server.
// Component
import { FilePond, File, registerPlugin } from "react-filepond";
import FilePondPluginImageExifOrientation from 'filepond-plugin-image-exif-orientation';
import FilePondPluginImagePreview from "filepond-plugin-image-preview";
registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginImagePreview);
const Page = () => {
const [productImages, setProductImages] = useState<File[]>([]);
return (
<FilePond
allowMultiple={true}
maxFiles={2}
files={productImages}
onupdateFiles={setProductImages}
server={{
process: {
url: "/api/upload",
method: "POST",
headers: {
"Content-Type": "mutlipart/form-data"
},
ondata: formData => {
formData.append('image', "test-image");
return formData;
}
}
}}
/>
);
};
export default Page;
// ./pages/api/upload
import { NextApiRequest, NextApiResponse } from "next";
const Index = (_req: NextApiRequest, res: NextApiResponse) => {
const reqBody = _req.body ?? null;
console.log(_req);
if (!reqBody) res.status(200).json({ message: "No request body found" });
res.status(200).json({ data: "OK" });
};
export default Index;
The issue I'm seeing is the files are being sent as a giant blob string and I've seen other people be able to access the files property from the incoming request (shown here). This is my first time building a file uploading feature into any of my projects so I'm not entirely sure what's best practice for handling files from incoming requests and parsing them to be stored in some file storage service like GCP or S3.
You might need to chunk the image file. set the configuration chunkUploads to true.
Then your backend should process the chunked file like this.

Laravel vue donwloaded PDF file not loading

I am trying to download pdf file from Laravel api with vue front end. Here is my vue code
methods: {
downloadAttachment(file) {
axios({
url: 'http://localhost:8000/storage/app/public/files/owwhz8JkFjyTuE4SNMytTKjXbVWLLIkaPnaSUF9b.pdf',
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf');
document.body.appendChild(link);
link.click();
});
}
}
Now when i execute the method, it downloads a pdf file but says "Failed to load pdf document"
what's the error here ? Do I need to change anything in Laravel Api ?
Assuming you already created the symlink in Laravel, I think you are missing the type when creating your Blob instance.
So change your code from
const url = window.URL.createObjectURL(new Blob([response.data]));
to
const url = window.URL.createObjectURL(new Blob([response.data], { type: 'application/pdf' }));
Also check your URL. If it's a public file, strip off the /app/public/ part, so that your URL becomes http://localhost:8000/storage/files/...

Expo React Native upload an image to Laravel in backend

I am fairly new to coding and I'm in the learning phase for both React Native and Laravel. I was working on some practice project and I needed to upload an image from my React Native app to the Laravel server and from the server I could save it on a cloud or something. I can upload and display the image on the app using expo-image-picker but I just can't seem to get it to post it to the server using formData.
Also, why is that when I console.log formData why is it showing an empty object?
My code to loading the image and uploading it:
pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if(!result.cancelled)
{
this.setState({
image : result.uri
})
}
// ImagePicker saves the taken photo to disk and returns a local URI to it
let localUri = result.uri;
//console.log("localUri:", localUri)
let filename = localUri.split('/').pop();
console.log("filename:", filename)
// extract the filetype
//let fileType = localUri.substring(localUri.lastIndexOf(".") + 1);
//console.log(fileType)
let fileType = localUri.substring(localUri.lastIndexOf(":") + 1,localUri.lastIndexOf(";")).split("/").pop();
console.log("type:", fileType)
let formData = new FormData();
formData.append("photo", {
uri : localUri,
name: `photo.${fileType}`,
type: `image/${fileType}`
});
console.log("formdata", formData)
let options = {
method: "POST",
body: formData,
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data"
}
};
let response = await fetch(`${this.props.url}imagetest`, options)
result = await response.json()
console.log(result)
My simple code for api.php in Laravel is:
Route::post("/imagetest", function (Request $request) {
return ["uploaded" => $request->hasFile("photo")];
});
Found the solution at
send image using Expo
The problem I was having, I was testing it by running the code on web, when I ran it on the device I could see the formdata as well as the image was been uploaded too

react can't get restController response

I have tried to use restController generate file byte array but when i return it to react , react didn't get the byte array. front-end is using react , back-end is using spring restController and i use Http to communication both front and back. is it any wrong in my code? Thank you for your helping.
restController:
String fileName = DateUtility.dateToStr(new Date(), DateUtility.YYYYMMDD_HHMMSS) + " - "
+ reportNmaeByType.get(exportParam.getReportType()) + ".xls";
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<>(excelByte, HttpStatus.OK);
react:
createExcelFile(){
var params = {
reportResultList: this.state.reportResult,
reportType: getReportSelector().state.selectedReportType,
selectColumnMap: this.state.selectColumn,
selectCusColumnMap: this.state.selectCusColumn
}
fetch("http://localhost:8080/mark-web/file/createExcel", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params)
}).then(res => {
if (res.ok) {
console.log(res)
console.log(this)
console.log('create excel success!!')
} else {
console.log('create excel Fail!!')
}
})
}
response:
enter image description here
Update 2018/09/16:
I have added some code in react function and it finally could download excel file but the file is broken. i have checked the blob object in response. it shows blob is json object. is it because i didn't decode to the blob object?
React:
}).then(res => {
if(!res.ok){
console.log("Failed To Download File")
}else{
return res.blob()
}
}).then(blob => {
console.log(blob)
let url = URL.createObjectURL(blob)
console.log(url)
var downloadAnchorNode = document.createElement('a')
downloadAnchorNode.setAttribute("href", url)
downloadAnchorNode.setAttribute("download", "excel" + ".xls")
downloadAnchorNode.click()
downloadAnchorNode.remove()
})
response:
enter image description here
So, from your network graph, it looks like your request is completing as expected, but you are just unable to derive the ByteArray from the response.
With normal requests which return a JSON or XML for e.x. you can read them in one go, as they are part of the body. In your case however, your body contains a Stream. You will thus have to handle reading that stream on your own.
You can do that with response.blob() :
The blob() method reads the stream to completion and returns a Blob object. You can then use this blob object to embed an image or download the file. For all intent and purposes, I would recommend using this. Unless you are dealing with huge files (>500 MB), it should suffice your needs.
For example:
fetch("http://localhost:8080/mark-web/file/createExcel", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params)
}).then(res => {
if (!res.ok) {
throw new Error(res.statusText);
} else {
return res.blob()
}
}).then(blob => {// do your thing})
.catch(err => console.log(error))
Or
You can use the experimental ReadableStream interface for a more granular control over what you want to do with it.

Parse Server - How to delete image file from the server using cloud code

How can I delete an image's file from the server using Parse Cloud Code. I am using back4app.com
After Deleting Image Row
I am getting the images urls, then calling a function to delete the image using its url
Parse.Cloud.afterDelete("Image", function(request) {
// get urls
var imageUrl = request.object.get("image").url();
var thumbUrl = request.object.get("thumb").url();
if(imageUrl!=null){
//delete
deleteFile(imageUrl);
}
if(thumbUrl!=null){
//delete
deleteFile(thumbUrl);
}
});
Delete the image file from the server
function deleteFile(url){
Parse.Cloud.httpRequest({
url: url.substring(url.lastIndexOf("/")+1),
method: 'DELETE',
headers: {
'X-Parse-Application-Id': 'xxx',
'X-Parse-Master-Key': 'xxx'
}
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
});
}
for security reasons, not is posible to delete directly the image from Back4App, using DELETE from SDK or REST API. I believe that you can follow the guide below:
https://help.back4app.com/hc/en-us/articles/360002327652-How-to-delete-files-completely-
After struggling with this for a while it seems to be possible through cloud function as mentioned here. One need to use MasterKey in the cloud code:
Parse.Cloud.define('deleteGalleryPicture', async (request) => {
const {image_id} = request.params;
const Gallery = Parse.Object.extend('Gallery');
const query = new Parse.Query(Gallery);
try {
const Image = await query.get(image_id);
const picture = Image.get('picture');
await picture.destroy({useMasterKey: true});
await Image.destroy();
return 'Image removed.';
} catch (error) {
console.log(error);
throw new Error('Error deleting image');
}
});
For me it was first confusing since I could open the link to that file even after I deleted the reference object in the dashboard, but then I found out that the dashboard is not calling Parse.Cloud.beforeDelete() trigger for some reason.
Trying to download the data from the url after deleting the file through the cloud code function returns 0kB data and therefore confirms that they were deleted.

Resources