TS + Nodejs:处理 excel 文件下载

客户端

为【导出按钮】添加下载事件

/*
 ** src/components/employee/index.tsx
 */
class Employee extends Component<Props, State> {
  ...
  handleDownload = () => {
    // DOWNLOAD_EMPLOYEE_URL: "/api/employee/downloadEmployee"
    window.open(DOWNLOAD_EMPLOYEE_URL);
  };
  ...
  render() {
    ...
    <Button
      type="primary"
      icon={<DownloadOutlined />}
      onClick={this.handleDownload}
      className="right"
    >
      导出
    </Button>;
    ...
  }
}
复制代码

服务端

excel-export

我们选择 excel-exportnode 端处理 excel 的下载。

因为这个 excel-export,暂时还没有声明文件,所以我们要先添加一个 excel-export.d.ts

/*
 * routes/excel-export.d.ts
 */
declare module "excel-export" {
  export function execute(config: Config): void;
  export interface Config {
    cols: { caption: string; type: string }[];
    rows: any[];
  }
}
复制代码

具体实现

/*
 ** routes/employee.ts
 */
import excelExport from "excel-export";

let conf: excelExport.Config = {
  cols: [
    { caption: "员工ID", type: "number" },
    { caption: "姓名", type: "string" },
    { caption: "部门", type: "string" },
    { caption: "入职时间", type: "string" },
    { caption: "职级", type: "string" },
  ],
  rows: [],
};

router.get("/downloadEmployee", async (req, res) => {
  try {
    let result = await query(queryAllSQL); // 连接数据库,查询所有员工信息
    conf.rows = result.map((i: any) => [
      i.id,
      i.name,
      i.department,
      i.hiredate,
      i.level,
    ]);
    let excel = excelExport.execute(conf);

    // 设置返回头
    res.setHeader(
      "Content-Type",
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    );
    res.setHeader("Content-Disposition", "attachment; filename=employee.xlsx");

    // 最后写入一个二进制文件
    res.end(excel, "binary");
  } catch (error) {
    res.send(e.toString());
  }
});
复制代码

Content-Type

Content-Type:用于指示资源的 MIME 类型(媒体类型),告诉客户端实际返回的内容的内容类型。

拓展名 文档类型 MIME 类型
.xlsx Microsoft Excel (OpenXML) application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Content-Disposition

Content-Disposition:指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

attachment:意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,搭配 filename 的话,用作”保存为”对话框中呈现给用户的默认文件名。

结果

ts-excel.png

TS + Nodejs 系列

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享