简体   繁体   English

如何通过 nodejs 在 S3 中创建 Excel 文件?

[英]How do I create an Excel File in S3 though nodejs?

I'm trying to create a script that will take a JSON object and put it into the S3 bucket as an xlsx file我正在尝试创建一个脚本,该脚本将采用 JSON 对象并将其作为 xlsx 文件放入 S3 存储桶中

I am planning on integrating SQL queries to the code but for now limiting it to JSON for easier coding.我计划将 SQL 查询集成到代码中,但现在将其限制为 JSON 以便于编码。 I've tried using alasql and xlsx to try and create the S3.putObject body but the output creates a corrupted excel file我已经尝试使用 alasql 和 xlsx 来尝试创建 S3.putObject 主体,但输出创建了一个损坏的 excel 文件

var data = [{a:1,b:1,c:1},{a:1,b:2,c:1},{a:1,b:3,c:1}, {a:2,b:1,c:1}];
  var a = XLSX.utils.json_to_sheet(data);

  var params = {
  'Body' : Buffer.from(a),
  'Key': event.Key + '.xlsx',
  'Bucket': event.Bucket
};

s3.putObject(params).promise();

I expect that the data will be placed in an xlsx file in the S3 bucket and while the file is created, it is corrupted我希望数据将放置在 S3 存储桶中的 xlsx 文件中,并且在创建文件时,它已损坏

What worked for me is this, using sheetjs import xlsx from 'xlsx';对我sheetjs是,使用sheetjs import xlsx from 'xlsx'; :


        // initiate the workbook
        const wb = xlsx.utils.book_new();

        // add properties to the sheet
        wb.Props = {
          Title: 'Books Borrowed',
          Subject: 'Borrowed Books',
          Author: 'Admin',
          CreatedDate: '2020-04-23',
        };

        // add a sheet
        wb.SheetNames.push('Borrowed');

        // I used aoa_to_sheet because I'm having an issue with json_to_sheet but was able to create a workaround, see: https://github.com/SheetJS/sheetjs/issues/1487#issuecomment-618767784
        // I find the aoa_to_sheet a much cleaner approach
        const ws = xlsx.utils.aoa_to_sheet(sheet);
        wb.Sheets.Borrowed = ws;

        // generate output as buffer
        const wbOut = xlsx.write(wb, {
          bookType: 'xlsx',
          type: 'buffer',
        });

        // upload to S3
        const data = await s3
          .putObject({
            Bucket: config.s3.s3BucketPublic,
            Key: 'filenameHere.xlsx',
            ACL: 'public-read',
            Body: wbOut,
            ContentType:
              'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
          })
          .promise();

Below is what works for me.以下是对我有用的内容。

const Excel = require('exceljs');
const aws = require('aws-sdk');
let workbook = new Excel.Workbook();
workbook.creator = 'System';
workbook.lastModifiedBy = 'System';
workbook.created = new Date();
workbook.modified = new Date();
workbook.lastPrinted = new Date();

let worksheet = workbook.addWorksheet('SOME Data');
worksheet.columns = [{
    header: 'somekey',
    key: 'DeviceID'
}, {
    header: 'Type',
    key: 'Type'
}];

hcpData.forEach(element => {
   worksheet.addRow({
       somekey: element.DEVICEID,
       Type: element.TYPE
   });
});

worksheet.getRow(1).eachCell(cell => {
    cell.font = {
        bold: true
   };
});
//configuring the AWS environment
aws.config.update({
    accessKeyId: 'putyourkye',
    secretAccessKey: 'putyourkye',
});

const s3 = new aws.S3();
const stream = new Stream.PassThrough();

workbook.xlsx.write(stream).then(() => {
    return s3
       .upload({
        Key: Date.now() + '_XYZNAME.xlsx',
        Bucket: 'abc-reports',
        Body: stream,
        ACL: 'public-read',
    })
    .promise()
    .then(data => {
        // do some task after upload
    });
});

This can be achieved by doing the following steps:这可以通过执行以下步骤来实现:

1. Install and import ExcelJS import * as excel from "exceljs"; 1.安装并导入ExcelJS import * as excel from "exceljs";

2. Create a function that will generate the excel file as stream: 2.创建一个函数,将生成 excel 文件作为流:

const createExcel = async (
  headers: Partial<excel.Column>[],
  rows: any[]
): Promise<Buffer> => {
  const workbook: excel.stream.xlsx.WorkbookWriter =
    new excel.stream.xlsx.WorkbookWriter({});
  const sheet: excel.Worksheet = workbook.addWorksheet("My Worksheet");
  sheet.columns = headers;
  for (let i = 0; i < rows.length; i++) {
    sheet.addRow(rows[i]);
  }
  sheet.commit();
  return new Promise((resolve, reject): void => {
    workbook
      .commit()
      .then(() => {
        const stream: any = (workbook as any).stream;
        const result: Buffer = stream.read();
        resolve(result);
      })
      .catch((e) => {
        reject(e);
      });
  });
};

3. Retrieve the data as JSON, in my case from MySQL table: const data = db.query("SELECT * FROM data_table"); 3.以 JSON 形式检索数据,在我的例子中是从 MySQL 表中检索数据: const data = db.query("SELECT * FROM data_table");

4. Generate the excel stream by using above function - createExcel 4.使用上面的函数 - createExcel 生成 excel 流

const stream: Buffer = await createExcel(
      [
        { header: "Column one header", key: "id" },
        { header: "Name column header", key: "name" },
      ],
      data
    );

The first argument will set the excel file column headers.第一个参数将设置 Excel 文件列标题。 make sure the key will match with the key from your JSON file.确保密钥与您的 JSON 文件中的密钥匹配。

The second argument (data) represents the JSON file which will be an array of objects that have the same properties as the values of each of the keys.第二个参数 (data) 表示 JSON 文件,它将是一个对象数组,这些对象与每个键的值具有相同的属性。

5. Now you can do whatever you need with the stream variable which will contain the Buffer. 5.现在您可以对包含缓冲区的流变量执行任何您需要的操作。 To upload to S3:上传到 S3:

  const BUCKET_NAME = "data-bucket";
  const KEY = `xls-file-name.xlsx`;
  const params = {
    Bucket: BUCKET_NAME,
    Key: KEY,
    Body: stream,
  };

  s3.upload(params, function (err: any, data: any) {
    if (err) {
      console.log(err);
      console.log("Error");
    }
    console.log(`File uploaded successfully. ${data.Location}`);
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM