PROBLEM: I have a csv file in an Azure blob storage container. I am try to use Angular to download it and save it to the users computer. I am able to download it, but it is saved as an .xls file instead of .csv, even though the source is csv. If I try to convert it to csv before saving it, the saved excel sheet is empty.
GOAL: I would like to either download it as the original csv or convert it from xls to csv before saving it locally.
I have tried a few methods... This is my service.ts
private containerClient(): ContainerClient {
return new BlobServiceClient(`https://${this.accountName}.blob.core.windows.net?${this.sas}`).getContainerClient(this.containerName);
}
downloadCSV(handler: (blob: Blob) => void){
const blobClient = this.containerClient().getBlockBlobClient("AGENCIES.csv");
blobClient.download().then(res => {
res.blobBody?.then(blob => {
handler(blob);
});
});
}
async downloadCSVwithConnectionString(handler: (blob: Blob) => void){
const containerClient = this.blobServiceConnectionString.getContainerClient(this.containerName);
await containerClient.getBlockBlobClient("AGENCIES.csv").download().then(res => {
res.blobBody?.then(blob => {
handler(blob);
});
});
}
downloadCSVwithConnectionString2(){
const containerClient = this.blobServiceConnectionString.getContainerClient(this.containerName);
return containerClient.getBlockBlobClient("AGENCIES.csv").download();
}
And this is my component.ts
import { AzureBlobStorageService } from 'src/app/services/azure-storage/azure-blob-storage.service';
import * as XLSX from 'xlsx';
import * as FileSaver from 'file-saver';
tryDownload1(){
tryDownload1(){
this.azure.downloadCSV(blob => {
let url = window.URL.createObjectURL(blob);
window.open(url);
});
}
tryDownload2(){
this.azure.downloadCSVwithConnectionString(blob => {
let csvData = XLSX.utils.sheet_to_csv(blob);
const data: Blob = new Blob([csvData], { type: 'application/vnd.ms-excel' });
FileSaver.saveAs(data, "CSVFile" + new Date().getTime() + '.csv');
});
}
tryDownload3(){
this.azure.downloadCSVwithConnectionString2().then(res => {
console.log(res);
let csvData = XLSX.utils.sheet_to_csv(res);
console.log(csvData);
const data: Blob = new Blob([csvData], { type: 'text/plain' });
console.log(data);
FileSaver.saveAs(data, "CSVFile" + new Date().getTime() + '.csv');
});
}
NOTE: I used XLSX because I couldn't find a working package for just xls
I added some console logs in one of them to try and figure out if the data was transferring to the csv correctly, and it does not seem to.
For anyone who comes across this question, here is how I resolved it...
On Microsoft Azure in the storage container, I opened the properties for the file I was downloading. I changed the "CONTENT-TYPE" from "application/vnd.ms-excel" to "text/csv".
I used the same "downloadCSV" function in my service.ts and used the following function in my component.ts. The changes are so that the filename is changed to "AGENCIES.csv" instead of the random url key.
constructor(
private azure: AzureBlobStorageService,
@Inject(DOCUMENT) private document: Document,
private elementref: ElementRef,
private render: Renderer2
) { }
tryDownload1(){
this.azure.downloadCSV(blob => {
let url = window.URL.createObjectURL(blob);
let downloadLink = this.document.createElement("a");
downloadLink.href = url;
downloadLink.download = "AGENCIES.csv";
this.render.appendChild(this.elementref.nativeElement, downloadLink);
downloadLink.click();
this.render.removeChild(this.elementref.nativeElement, downloadLink);
});
}