4

我想用 API Gateway + Lambda 做一个 csv 下载链接。但是有一个问题是 lambda 总是返回 JSON.stringify。有没有办法解决这个问题?

s-function.json

"responses": {
    "default": {
      "statusCode": "200",
      "responseParameters": {
        "method.response.header.Content-disposition": "'attachment; filename=testing.csv'"
      },
      "responseTemplates": {
        "text/csv": ""
      }
    }
  }

handler.js

var json2csv = require('json2csv');
module.exports.handler = function(event, context, cb) {
   var fields = ['car', 'price', 'color'];
   var myCars = [
    {
      "car": "Audi",
      "price": 40000,
      "color": "blue"
    }, {
      "car": "BMW",
      "price": 35000,
      "color": "black"
    }, {
      "car": "Porsche",
      "price": 60000,
      "color": "green"
    }
   ]; 
    var csv = json2csv({ data: myCars, fields: fields });
    return cb(null, csv);
};

在下载的 csv 文件中。

"\"汽车\",\"价格\",\"颜色\"\n\"奥迪\",40000,\"蓝色\"\n\"宝马\",35000,\"黑色\"\n \"保时捷\",60000,\"绿色\""

更新:

我还在努力,但谢谢你,至少我有方向。顺便说一句,我找不到关于 $input.body.replaceAll 的 API Gateway 文档。replaceAll 是 Java 函数吗?

最后,我通过 Api Gateway 模板中的以下代码解决了这个问题。

$input.body.replaceAll("\\""","").replaceAll("""","").replaceAll("\\n","
")

s-function 转义了双引号。

"responseTemplates": {
    "text/csv": "$input.body.replaceAll(\"\\\\\"\"\",\"\").replaceAll(\"\"\"\",\"\").replaceAll(\"\\\\n\",\"\n\")"
}

返回数据:

car,price,color
Audi,40000,blue
BMW,35000,black
Porsche,60000,green

模板最终 replaceAll 很奇怪。CSV 无法识别 \n 或 \r\n,但我尝试在 IDE 中复制新行并传递给代码。它有效,而且很神奇。

4

2 回答 2

8

自从您提出这个问题以来,Serverless 发生了一些变化,但如果您使用的lambda_proxy是集成方法,您可以使用如下处理程序:

module.exports.handler = (event, context, callback) => {
  const csvRows = [
    '1,"blah",123',
    '2,"qwe",456'
  ]
  const result = csvRows.reduce((prev, curr) => {
    return prev + '\n' + curr
  })
  callback(null, {
    headers: {
      'Content-Type': 'text/csv',
      'Content-disposition': 'attachment; filename=testing.csv'
    },
    body: result,
    statusCode: 200
  })
}

注意:我使用了 ES6 功能,因此您需要使用 Node 6 或更高版本来直接复制粘贴此示例。

于 2017-05-26T00:43:56.797 回答
1

如果您无法在 Lambda 函数上修复它,您可以在 API Gateway 映射模板中执行 replaceAll()。我认为这可以用来替换转义的双引号:

$input.body.replaceAll("\\""","")

编辑:所以大摇大摆的是(如果我得到正确的转义):

"responses": {
    "default": {
      "statusCode": "200",
      "responseParameters": {
        "method.response.header.Content-disposition": "'attachment; filename=testing.csv'"
      },
      "responseTemplates": {
        "text/csv": "$input.body.replaceAll(\"\\\"\"\",\"\")"
      }
    }
  }
于 2016-08-02T19:46:15.433 回答