'Retrieving an xlsx file using http.get() and then loading said file into ExcelJs in Angular
I'm using HTTP GET to retrieve an xlsx file that I then want to load into an ExcelJs workbook. After which I want to add an additional sheet to the workbook and save it. This part seems to be working but WITHOUT the xlsx template file being part of the downloaded file.
I think I might not be setting the correct responseType, as when I try and load the file into ExcelJs it is empty. I am still able to add my new sheet (sheet2) to the workbook and download it.
First off I suppose am I using the correct response type? Referring to the ExcelJs documentation, when using xlsx.load(), I need to pass an ArrayBuffer, which does not work so then I tried converting it to Uint8Array and Blob, but neither of those work either. Which is why I'm thinking maybe I'm getting the file from the get() incorrectly.
exportLocalXlsx(): void {
// Retreive the excel template file from the angular app.
// TODO: Replace local file with webapi URL at a later stage.
this.http.get('./assets/Book11.xlsx', { responseType: 'arraybuffer' })
.subscribe((file:ArrayBuffer) => {
// Now prep the excel template file so it can be loaded into Exceljs.
let xlsxArray = new Uint8Array(file);
let xlsxBlob = new Blob([xlsxArray.buffer],
{ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
console.log(file);
console.log(xlsxBlob);
console.log(xlsxArray);
// Load excel template file into a new Exceljs workbook.
let wb : Excel.Workbook = new Excel.Workbook();
///////////////////////////////////
// Read from a file.
//wb.xlsx.readFile('/assets/Book11.xlsx') // Results in corrupt file.
///////////////////////////////////
// Read from a stream.
//wb.xlsx.read(file);
//wb.xlsx.read(xlsxBlob);
//wb.xlsx.read(xlsxArray);
///////////////////////////////////
// Load from buffer.
//wb.xlsx.load(file);
//wb.xlsx.load(xlsxArray.buffer);
wb.xlsx.load(xlsxBlob);
// Output sheets to console.
wb.eachSheet((sheet, id) => {
sheet.eachRow((row, rowIndex) => {
console.log(row.values, rowIndex)
})
});
// Import data into the excel template.
let ws = wb.addWorksheet('Sheet2');
ws.columns = [{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 }];
// Add rows.
ws.addRow({ id: 1, name: 'John' });
ws.addRow({ id: 2, name: 'Jane' });
// Now Download the modified excel template file.
wb.xlsx.writeBuffer().then(data => {
const blob = new Blob([data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' });
FileSaver.saveAs(blob, 'Book11');
});
});
}
Here is the source code for the entire angular app: https://stackblitz.com/edit/verifi-exportuploadtest
Any suggestions would be appreciated.
Solution 1:[1]
Could you trying to return the response with JSON from workbook.model
?
on frontend should work something like that:
const wb = new ExcelJs.Workbook();
wb.model = response.data
Solution 2:[2]
may be very late to the party, i banged my head literally about this, so posting an answer
let workbook = this.excelService.createWorkBook();
this.http.get('./assets/1.xlsx', { responseType: 'blob' })
.subscribe((file:Blob) => {
let fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = async (e) => {
let arrayBuffer = fileReader.result as ArrayBuffer;
if(arrayBuffer)
await workbook.xlsx.load(arrayBuffer);
debugger;
var first_sheet_name = workbook.worksheets.length;
let worksheet = workbook.addWorksheet('Demo Sridhar');
workbook.xlsx.writeBuffer().then((data: any) => {
let blob = new Blob([data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
fs.saveAs(blob, 'Final.xlsx');
});
Await should be the trick and blob
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Pawe? Siemienik |
Solution 2 | user18956253 |