如何利用Node写入CSV文件

657 阅读2分钟

背景:我们在进行后台相关的页面开发过程,常常会涉及到数据量较大的相关开发,比如将浏览的页面数据导出到excell中浏览或操作。这时候常常会有下面两种情况:

一. 页面数据分页展示

此时可以通过服务器直接返回xlsx文件的url,然后通过创建超链标签元素a,然后利用a.href=url直接在浏览器下载文件

//关键实现函数代码
const exportCsv=(url)=>{
   let a=document.creatElement('a')  //创建标签a
   a.href=url   //将服务器返回的文件url赋值给a
   a.download=url.split('/').pop()  //下载文件
   a.click() 
}
二. 页面一次展示所有数据

此时服务器不会返回url,需要前端结合Node库和中间件实现对数据的处理和写入csv文件中,从而提供下载,主要利用nodejs组件库exceljs

前端代码:

    //下载csv文件
    const downloadCsv = () => {
    //headKeys为列表每列写入的内容
       const headKeys = getBaseTableColumnsOption().map((item:any) => item.prop);  //getBaseTableColumnsOption为表格的表头内容
       //headNames为表头的内容
      const headNames = getBaseTableColumnsOption().map((item:any) => item.label);
      exportCsv(headKeys, headNames,tableData, 'test.csv');  //tableData为需要写入csv的数据
    };

Node代码

import * as ExcelJS from 'exceljs';

export const exportCsv = async (headKeys: string[], headNames:string[], tableData: any[], filename: string) => {
  const workbook = new ExcelJS.Workbook();
  const worksheet = workbook.addWorksheet('sheet1', {
    properties: { tabColor: { argb: 'FFC0000' } }
  });
  const columns = headKeys.map((item: string) => ({ name: item, style: {} }));
  const columnsName = headNames.map((item: string) => ({ name: item, style: {} }));
  const rows = tableData.map((item) => {
    const row: any[] = [];

    const columnKeys = columns.map((item) => item.name);
    columnKeys.forEach((prop: string) => {
      row.push(item[prop]);
    });
    return row;
  });
  worksheet.addTable({
    name: 'MyTable',
    ref: 'A1',
    headerRow: true,
    // totalsRow: true,
    style: {
      theme: 'TableStyleLight',
      showRowStripes: true
    },
    columns: columnsName,
    rows: rows
  });

  const buffer = await workbook.csv.writeBuffer();   //对需要写入的数据进行转换
  // const blob = new Blob([buffer], { type: 'text/csv' });
  // const blob = new Blob([buffer], { type: 'text/csv' }); //blob对象前添加unicode标识符可以解决乱码问题
  const blob = new Blob(['\ufeff' + buffer], { type: 'text/csv, charset = UTF - 8' });  //注意unicode'\ufeff'不能缺少,缺少会产生中文乱码现象
  const a = document.createElement('a');
  a.download = filename
  const url = URL.createObjectURL(blob);  
  a.href = url;
  document.body.appendChild(a);
  a.click();
  URL.revokeObjectURL(url);
  document.body.removeChild(a);
};