How to upload and download file in Angular 5+ and .net core
2 min readNov 11, 2021
When you develop a web application in Angular for the front-end and C# or Java in the back-end, it’s frequently that you need to upload and download files.
Here is an example that may inspire you in your development.
HTML buttons to download and upload file.
<!-- Upload file -->
<input hidden #feeFile type="file" #uploader (change)="uploadFees($event)" accept=".xlsx, .xls" />
<button mat-button color="primary" (click)="uploader.click()">
<mat-icon matTooltip="Upload fees" class="import-export-button">cloud_upload</mat-icon>
</button>
<!-- Download file -->
<button mat-button color="primary" (click)="downloadFees()">
<mat-icon matTooltip="Download fees" class="import-export-button">cloud_download</mat-icon>
</button>
Define a file object to use in file download and upload.
export class DocumentDTO {
fileName!: string;
fileData!: string;
contentType!: string;
}
Define a HHTML input event to pass the file.
interface HTMLInputEvent extends Event {
target: HTMLInputElement & EventTarget;
}
Define a file service to treat the file.
import { Injectable } from '@angular/core';
import { DocumentDTO } from '@app/models/document.model';
import * as FileSaver from 'file-saver';
import { Subject } from 'rxjs';@Injectable({
providedIn: 'root'
})
export class FileService { constructor() { } saveFile(document: DocumentDTO) {
//Convert file content to blob
let blob = this.convertBase64StringToBlob(document.fileData, document.contentType);
//Save file
FileSaver.saveAs(blob, document.fileName);
} readFile(file: File): Promise<string> {
//Convert file to string
const sub = new Subject<string>();
const reader = new FileReader();
reader.onloadend = function () {
const content: string = reader.result as string;
sub.next(content);
sub.complete();
};
reader.readAsDataURL(file);
return sub.asObservable().toPromise();
} private convertBase64StringToBlob(base64: string, contentType: string): Blob {
const byteCharacters = atob(base64);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
return new Blob([byteArray], { type: contentType });
}
}
Typescript code to upload and download Excel file.
async uploadFee(e: any) {
let target = e.target as HTMLInputElement;
const file = (target.files as FileList)[0];
var fileContent = await this.fileService.readFile(file);
let document = this.createDocumentDto(file, fileContent); //Upload file by calling web api upload file endpoint
await this.http.post<boolean>(`${this.apiUrl}/document`, document).toPromise(); //reset feeFile value to be able to reload the same file
this.feeFile.nativeElement.value = null;
}private createDocumentDto(file: File, content: string): DocumentDTO {
let doc = new DocumentDTO();
doc.fileName = file.name;
doc.contentType = file.type;
doc.fileData = content;
return doc;
}async downloadFees() {
let queryParams = this.createFilterParams(this.filter);
let document = await this.http.get<DocumentDTO>(`${this.apiUrl}/document`, { params: queryParams }).toPromise();
this.fileService.saveFile(document);
}private createFilterParams(filter: CodeDDGFilterDTO) {
let queryParams = new HttpParams();
if (filter.Name !== undefined) queryParams = queryParams.set("Name", filter.Name);
if (filter.Code !== undefined) queryParams = queryParams.set("Code", filter.Code);
return queryParams;
}
Back-end code in .net core web api.
[HttpPost]
[Route("document")]
public async Task<bool> UploadFeesExcelAsync(DocumentDTO document)
{
return await _feesImporter.ImportDocument(document);
}[HttpGet]
[Route("document")]
public async Task<DocumentDTO> DownloadFeesExcelAsync([FromQuery] FilterDTO filter)
{
return await _feesExporter.GenerateDocument(filter);
}
Ok, you have seen the sample code. You can make your hands dirty now. :)