使用 ExcelJS 和节点 js 下载 excel 文件未在任何浏览器中下载

Downloading excel file using ExcelJS and node js not being downloaded in any browser

我尝试使用 exceljsnodejs.xlsx 文件作为可下载文件发送到客户端。到目前为止,我可以创建 employees.xlsx 文件,但它不会在浏览器中触发保存文件对话框。这是我在后端尝试过的 API:

我的控制器:

exports.exportEmployees = async (req, res) => {

  try {
    const employees = await Employee.find();
    let workbook = new Excel.Workbook();
    let worksheet = workbook.addWorksheet("Employees");
    worksheet.columns = [
      { header: "Employee Name", key: "fullName", width: 40 },
      { header: "Department", key: "departmentName", width: 25 },
      { header: "Position", key: "positionName", width: 25 },
    ];

    worksheet.addRows(employees);

    res.setHeader(
      "Content-Type",
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    );
    res.setHeader("Content-Disposition", "attachment; filename=employees.xlsx");

    // This doesn't work either
    // workbook.xlsx.write(res).then(function () {
    //   res.status(200).end();
    // });

    workbook.xlsx.writeFile("./employees.xlsx").then(
      (response) => {
        console.log("File is created"); // I'm able to see this in my console
        console.log(path.join(__dirname, "../employees.xlsx"));
        res.sendFile(path.join(__dirname, "../employees.xlsx"));
      },
      (err) => {
        console.log("ERROR: ", err);
      }
    );
  } catch (err) {
    res.status(500).json({ errors: err });
  }
};

在我的 route.js

router.get("/employee-excel", auth, exportExcelController.exportEmployees);

module.exports = router;

所以,我现在面临的问题是,每当我从 Angular 应用程序调用 api 时,浏览器响应都是二进制代码。

Angular 服务调用 API

generateEmployeeExcel(query: any): Observable<any> {
    return this.http.get(`${this.serverReportAPI}/employee-excel`, {
      params: query,
      headers: this.tokenHelperService.getAuthToken().headers,
    });
  }

我的组件

this.reportService.generateEmployeeExcel(query).subscribe(
  (response) => {
    console.log("Are we getting here?", response); // not able to get here
    this.isLoading = false;
  },
  (err) => {
    console.log("Is there any error?", err); // This is displayed in console

    this.isLoading = false;
  }
);

如有任何帮助,我们将不胜感激。

我浏览器中的响应

将 http 代码更改为:-

generateEmployeeExcel(query: any): Observable<any> {
    return this.http.get(`${this.serverReportAPI}/employee-excel`, {
      params: query,
      headers: this.tokenHelperService.getAuthToken().headers,
      responseType: 'blob'
    });
  }

订阅和下载:-

this.reportService.generateEmployeeExcel(query).subscribe(
  (res) => {
        console.log("Are we getting here?", res); // not able to get here
        this.isLoading = false;
        let url = window.URL.createObjectURL(res.data);
        let a = document.createElement('a');
        document.body.appendChild(a);
        a.setAttribute('style', 'display: none');
        a.href = url;
        a.download = "employee.xlsx";
        a.click();
        window.URL.revokeObjectURL(url);
        a.remove();
  },
  (err) => {
    console.log("Is there any error?", err); // This is displayed in console

    this.isLoading = false;
  }
);

如果需要支持IE :-

this.reportService.generateEmployeeExcel(query).subscribe(
  (res) => {
        console.log("Are we getting here?", res); // not able to get here
     if(window.navigator.msSaveBlob) {
         window.nagigator.msSaveBlob(res, "employee.xlsx");
         return;
     }
        this.isLoading = false;
        let url = window.URL.createObjectURL(res.data);
        let a = document.createElement('a');
        document.body.appendChild(a);
        a.setAttribute('style', 'display: none');
        a.href = url;
        a.download = "employee.xlsx";
        a.click();
        window.URL.revokeObjectURL(url);
        a.remove();
  },
  (err) => {
    console.log("Is there any error?", err); // This is displayed in console

    this.isLoading = false;
  }
);