【问题标题】:How to create an Excel File with Nodejs?如何使用 Nodejs 创建 Excel 文件?
【发布时间】:2013-07-01 06:51:49
【问题描述】:

我是一个 nodejs 程序员。现在我有一个要以 Excel 文件格式保存的数据表。我该怎么做呢?

我找到了一些 Node 库。但其中大多数是 Excel 解析器而不是 Excel 编写器。我使用的是 Linux 服务器。因此需要可以在 Linux 上运行的东西。如果您知道任何有用的库,请告诉我。

或者有没有办法可以将 CSV 文件转换为 xls 文件(以编程方式)?

【问题讨论】:

    标签: excel node.js file-io export-to-excel npm


    【解决方案1】:

    excel4node 是一个维护的原生 Excel 文件创建器根据官方规范构建。它与另一个答案中提到的mxexcel-builder 相似,但维护得更多。

    // Require library
    var excel = require('excel4node');
    
    // Create a new instance of a Workbook class
    var workbook = new excel.Workbook();
    
    // Add Worksheets to the workbook
    var worksheet = workbook.addWorksheet('Sheet 1');
    var worksheet2 = workbook.addWorksheet('Sheet 2');
    
    // Create a reusable style
    var style = workbook.createStyle({
      font: {
        color: '#FF0800',
        size: 12
      },
      numberFormat: '$#,##0.00; ($#,##0.00); -'
    });
    
    // Set value of cell A1 to 100 as a number type styled with paramaters of style
    worksheet.cell(1,1).number(100).style(style);
    
    // Set value of cell B1 to 300 as a number type styled with paramaters of style
    worksheet.cell(1,2).number(200).style(style);
    
    // Set value of cell C1 to a formula styled with paramaters of style
    worksheet.cell(1,3).formula('A1 + B1').style(style);
    
    // Set value of cell A2 to 'string' styled with paramaters of style
    worksheet.cell(2,1).string('string').style(style);
    
    // Set value of cell A3 to true as a boolean type styled with paramaters of style but with an adjustment to the font size.
    worksheet.cell(3,1).bool(true).style(style).style({font: {size: 14}});
    
    workbook.write('Excel.xlsx');
    

    【讨论】:

    • 嗨 mikemaccana ,我应该在哪里使用此代码。我是否必须在控制器或任何架构代码中使用此代码。你能回答这个问题吗:stackoverflow.com/questions/44369082/…
    • 我收到一个错误错误:找不到模块'excel4node',并在使用前用npm install安装了它
    • @raz 你应该问这个问题。
    • @mikemaccana 是否有任何可能的方式来导出数组列表。
    • @tamilselvans 使用array.forEach(value, index)worksheet.cell(column, row).string(value)。贝蒂还没有阅读文档!
    【解决方案2】:

    我只是想出了一个简单的方法。这行得通 -

    只需创建一个以 Tabs 作为分隔符的文件(类似于 CSV,但用 Tab 替换逗号)。使用扩展名 .XLS 保存它。该文件可以在 Excel 中打开。

    一些帮助的代码--

    var fs = require('fs');
    var writeStream = fs.createWriteStream("file.xls");
    
    var header="Sl No"+"\t"+" Age"+"\t"+"Name"+"\n";
    var row1 = "0"+"\t"+" 21"+"\t"+"Rob"+"\n";
    var row2 = "1"+"\t"+" 22"+"\t"+"bob"+"\n";
    
    writeStream.write(header);
    writeStream.write(row1);
    writeStream.write(row2);
    
    writeStream.close();
    

    这将创建 XLS 文件格式的文件。如果您尝试使用 XLSX 而不是 XLS,它将不起作用。

    【讨论】:

    • 为什么不用逗号,用node创建一个CSV文件,然后导入Excel呢?这样 Excel 就可以完成它的工作并正确创建 xls/xlsx 文件。
    • 啊,明白了。但是,您找到了很好的解决方案。
    • 为了也支持特殊字符,我用 oh-csv github.com/SimpliField/oh-csv#excel-compatible-csv 做了一个简单的包装器见stackoverflow.com/questions/6588068/…
    • "这将创建 XLS 文件格式的文件。"不,它没有。它仍然是一个 CSV 文件,不能做 excel 的事情,例如,多个工作表。
    • 这根本不能回答问题,因为它不是一个 excel 文件。
    【解决方案3】:

    使用msexcel-builder。安装它:

    npm install msexcel-builder
    

    然后:

    // Create a new workbook file in current working-path 
    var workbook = excelbuilder.createWorkbook('./', 'sample.xlsx')
    
    // Create a new worksheet with 10 columns and 12 rows 
    var sheet1 = workbook.createSheet('sheet1', 10, 12);
    
    // Fill some data 
    sheet1.set(1, 1, 'I am title');
    for (var i = 2; i < 5; i++)
      sheet1.set(i, 1, 'test'+i);
    
    // Save it 
    workbook.save(function(ok){
      if (!ok) 
        workbook.cancel();
      else
        console.log('congratulations, your workbook created');
    });
    

    【讨论】:

    • 我可以将结果文件通过管道传输到响应对象而不是保存到磁盘吗?
    • 当然,试试 npm 请求。
    • 这是一个很好的答案(与当前标记的答案不同,它根本不创建 Excel 文件)但 mxexcel-builder 四年来没有任何更新。我在下面使用excel4node 添加了答案。
    • 嗨,Hesham Yassin,你能回答这个问题吗:stackoverflow.com/questions/44369082/…
    • 从 npm 运行他们的示例代码时,我在控制台中收到此警告:(node:11702) [DEP0013] DeprecationWarning: Calling an asynchronous function without callback is deprecated.
    【解决方案4】:

    虽然这个问题有几个答案,但现在可能有点过时了。

    新读者可能更愿意考虑 xlsx 或“sheetsJS”package,现在看来,它现在似乎是该用例中最流行的节点包。

    当前的最佳答案推荐 excel4node ,它看起来确实不错 - 但后一个包似乎比前者维护得更少(并且远没有那么受欢迎)。

    直接回答问题,使用 xlsx:

    const XLSX = require('xlsx');
    
    /* create a new blank workbook */
    const wb = XLSX.utils.book_new();
    
    // Do stuff, write data
    //
    //
    
    // write the workbook object to a file
    XLSX.writeFile(workbook, 'out.xlsx');
    

    【讨论】:

    • 对于某些人来说,excel4node 会更容易掌握,特别是如果你来自 JQuery 世界,你会链接东西。但 JQuery 的消亡是有充分理由的,而 XLSX 是一种更简洁的做事方式,并且提供了更多的控制权。
    【解决方案5】:

    你应该检查ExcelJS

    适用于 CSV 和 XLSX 格式。

    非常适合读取/写入 XLSX 流。我用它来将 XLSX 下载流式传输到 Express 响应对象,基本上是这样的:

    app.get('/some/route', function(req, res) {
      res.writeHead(200, {
        'Content-Disposition': 'attachment; filename="file.xlsx"',
        'Transfer-Encoding': 'chunked',
        'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      })
      var workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res })
      var worksheet = workbook.addWorksheet('some-worksheet')
      worksheet.addRow(['foo', 'bar']).commit()
      worksheet.commit()
      workbook.commit()
    }
    

    非常适合大文件,性能比 excel4node 好得多(对于包含 20 张纸中的 400 万个单元格的文件,近 5 分钟后内存使用量很大,节点进程“内存不足”崩溃)因为它的流媒体功能受到更多限制(不允许“提交()”数据在生成块时立即检索)

    另见this SO answer

    【讨论】:

      【解决方案6】:

      新 Office 中的 XLSx 只是 XML 和其他文件的压缩集合。所以你可以生成它并相应地压缩它。

      奖励:您可以创建一个非常漂亮的带有样式等的模板:

      1. 在“您最喜欢的电子表格程序”中创建模板
      2. 将其保存为 ODS 或 XLSx
      3. 解压内容
      4. 将其用作基础并用您的数据填充content.xml(或xl/worksheets/sheet1.xml
      5. 上菜前将其全部压缩

      但我发现 ODS (openoffice) 更容易上手(excel 仍然可以打开它),这是我在 content.xml 中找到的内容

      <table:table-row table:style-name="ro1">
          <table:table-cell office:value-type="string" table:style-name="ce1">
              <text:p>here be a1</text:p>
          </table:table-cell>
          <table:table-cell office:value-type="string" table:style-name="ce1">
              <text:p>here is b1</text:p>
          </table:table-cell>
          <table:table-cell table:number-columns-repeated="16382"/>
      </table:table-row>
      

      【讨论】:

      • 学习 OOXML 并非易事。使用不同的文件格式也不是问题的答案 - 作为评论会更好。
      【解决方案7】:

      使用 fs 包,我们可以从 JSON 数据创建 excel/CSV 文件。

      第 1 步: 将 JSON 数据存储在一个变量中(这里是 jsn 变量)。

      第二步:创建空字符串变量(这里是data)。

      第 3 步:jsn 的每个属性附加到字符串变量数据中,同时在完成行后附加 put '\t' in-between 2 个单元格和 '\n' .

      代码

      var fs = require('fs');
      
      var jsn = [{
          "name": "Nilesh",
          "school": "RDTC",
          "marks": "77"
         },{
          "name": "Sagar",
          "school": "RC",
          "marks": "99.99"
         },{
          "name": "Prashant",
          "school": "Solapur",
          "marks": "100"
       }];
      
      var data='';
      for (var i = 0; i < jsn.length; i++) {
          data=data+jsn[i].name+'\t'+jsn[i].school+'\t'+jsn[i].marks+'\n';
       }
      fs.appendFile('Filename.xls', data, (err) => {
          if (err) throw err;
          console.log('File created');
       });
      

      【讨论】:

      • 这不只是其中一个答案的副本吗?
      • 可能我已经扩展了之前的答案。
      【解决方案8】:

      或者 - 以@Jamaica Geek 的回答为基础,使用 Express - 避免保存和读取文件:

        res.attachment('file.xls');
      
        var header="Sl No"+"\t"+" Age"+"\t"+"Name"+"\n";
        var row1 = [0,21,'BOB'].join('\t')
        var row2 = [0,22,'bob'].join('\t');
      
        var c = header + row1 + row2;
        return res.send(c);
      

      【讨论】:

      • 很遗憾,这不是一个好主意。您的数据可能会破坏这种幼稚的代码:使用上述方法您会遇到的问题: 1. 当您的单元格包含引号字符或换行时,列被破坏;和 2. 在 Mac 上导入 Excel 时的编码问题(您必须包含正确的 BOM decodeURIComponent("%EF%BB%BF") 并使用 UTF16LE 进行编码。我建议改用适当的库
      【解决方案9】:

      安装 exceljs

      npm i exceljs --save
      

      导入 exceljs

      var Excel = require('exceljs');
      var workbook = new Excel.Workbook();
      

      创建工作簿

      var options = {
                      filename: __dirname+'/Reports/'+reportName,
                      useStyles: true,
                      useSharedStrings: true
                  };
      
                  var workbook = new Excel.stream.xlsx.WorkbookWriter(options);
      

      创建工作表后

      var worksheet = workbook.addWorksheet('Rate Sheet',{properties:{tabColor:{argb:'FFC0000'}}});
      

      在 worksheet.column 数组中,您在标题和数组键中传递列名 传入密钥

      worksheet.columns = [
                  { header: 'column name', key: 'array key', width: 35},
                  { header: 'column name', key: 'array key', width: 35},
                  { header: 'column name', key: 'array key', width: 20},
      
                  ];
      

      使用forEach循环后在exel文件中逐行追加

      array.forEach(function(row){ worksheet.addRow(row); })
      

      您还可以在每个 exel 行和单元格上执行循环

      worksheet.eachRow(function(row, rowNumber) {
          console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values));
      });
      row.eachCell(function(cell, colNumber) {
          console.log('Cell ' + colNumber + ' = ' + cell.value);
      });
      

      【讨论】:

        【解决方案10】:

        使用 exceljs 库创建和写入现有的 excel 工作表。

        您可以查看本教程以获得详细说明。

        link

        【讨论】:

          【解决方案11】:

          第一个参数是源文件

          第二个参数是分隔符

          第三个参数是生成的文件(*.xlsx)

          注意:增加节点堆使用:node --max-old-space-size=4096 index.js

          const fs = require('fs');
          var xl = require('excel4node');
          const data = fs.readFileSync(process.argv[2], 'utf-8');
          const lines = data.split(/\r?\n/);
          const linesFromOne = [null].concat(lines);
          var wb = new xl.Workbook();
          var ws = wb.addWorksheet('Planilha 1');
          for (let j=1;j<=linesFromOne.length-1;j++){             
            // Create a reusable style
            var style = wb.createStyle({
              font: {
                color: '#050000',
                size: 12,
              },
          
            });
          
              pieces = linesFromOne[j].split(process.argv[3])
              pieces.forEach((element, index) =>{
              ws.cell(j, index+1).string(element)
              .style(style);
              });
          
          } 
          
          wb.write(process.argv[4]);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-01-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-03-08
            相关资源
            最近更新 更多