Javascript 如何在一系列谷歌电子表格中循环

Javascript 如何在一系列谷歌电子表格中循环,javascript,node.js,express,Javascript,Node.js,Express,我试图用Express呈现Google电子表格中的数据,在放置要呈现的单元格范围并循环到其中后,出现了一个错误:“error[ERR_HTTP_HEADERS\u SENT]:发送到客户端后无法设置标题。” 电子表格有3行6列,我不确定我做错了什么,因为错误是持续的,我无论如何也无法摆脱它 我的代码: const express = require('express'); const router = express.Router(); const {google} = require('

我试图用Express呈现Google电子表格中的数据,在放置要呈现的单元格范围并循环到其中后,出现了一个错误:“error[ERR_HTTP_HEADERS\u SENT]:发送到客户端后无法设置标题。”

电子表格有3行6列,我不确定我做错了什么,因为错误是持续的,我无论如何也无法摆脱它

我的代码:

 const express = require('express');
 const router = express.Router();
 const {google} = require('googleapis');
 const keys = require('../credentials.json');

 const {
   google
  } = require('googleapis');
  const keys = require('../credentials.json');

  /* GET portfolio page. */
  router.get('/', function (req, res, next) {

  const client = new google.auth.JWT(
  keys.client_email,
  null,
  keys.private_key,
   ['https://www.googleapis.com/auth/spreadsheets.readonly']
  );

  client.authorize(function (err) {
   if (err) {
     console.log(err);
     return;
     } else {
       console.log('Connected');
       gsrun(client);
     }
    });

     async function gsrun(cl) {
     const gsapi = google.sheets({
     version: 'v4',
     auth: cl
    });

     const optPort1 = {
     spreadsheetId: '1W1OKGmGU6Io-1FhWjZLyPkGZz9Ky829zurAzcwmXiHg',
     range: ['Portfolio Page!A4:F6']
   };


   let spreadvals1 = await gsapi.spreadsheets.values.get(optPort1);


   console.log(spreadvals1.data.values);


    const cols1 = spreadvals1.data.values || [];

    const colsdata = cols1.map((element) => {
    res.set('Content-Type', 'text/html');

    res.render('portfolio', {
       headlinePortfolio: element[0],
       subheadlinePortfolio: element[1],
       image1: element[3],
       client: element[4],
       campaign: element[5]
     })
   });
 }
 });

  module.exports = router;
我的HTML如下所示:

   <div class="page-header">
   <div class="text-headline">
       <div class="salutation">{{headlinePortfolio}}</div>
   </div>
   <div class="text-subheadline">
       <div class="descr">{{subheadlinePortfolio}}</div>
   </div>
   <div class="port-row">         
       <ul class="flex-container-port">
           <li class="flex-item-img-mob">
              <img src="{{image1}}" alt="header-image" />
           </li>
           <li class="flex-item-img-desktop">
             <img class="img-port" src="{{image2}}" alt="header-image" />
           </li>
           <li class="flex-item-descr">
              <p class="bg-text">{{client1}}</p>
              <p class="descr-text">{{campaign1}}</p>
           </li>
       </ul>
   </div>
   </div>

这方面的问题是:

const colsdata = cols1.map((element) => {
res.set('Content-Type', 'text/html');

res.render('portfolio', {
   headlinePortfolio: element[0],
   subheadlinePortfolio: element[1],
   image1: element[3],
   client: element[4],
   campaign: element[5]
 })
})

不能多次渲染。Render调用将数据发送到前端的方法res.send()。因此发生的情况是:您多次发送(res.send())(因为res.render在贴图内部),因此会出现错误

为了防止渲染发送数据,必须提供如下回调:

res.render('portfolio', {
   headlinePortfolio: element[0],
   subheadlinePortfolio: element[1],
   image1: element[3],
   client: element[4],
   campaign: element[5]
 }, ()=>console.log(`template created do something`))
当您准备好发送所有内容时,只需尝试一次发送所有内容:
res.send(data)

此外,您的
路由器.get
必须是异步的,以便等待关键字工作

更多更新:

你已经更新了你的答案,所以这是一个更愚蠢的方法,我分享了以上所有的东西

您试图创建一个模板,但问题是您正在创建多个模板,因为您在循环中使用了函数。您应该做的是从循环中删除该函数

不幸的是,我不能确切地教你如何实现你想要实现的目标。我将复制最小输出,以便您可以从那里开始工作:

注意:为了简化,这里没有的东西应该保持不变

使用上面的示例,您将不会有错误,它将只获取第一行。如果需要下一行,则必须增加第[1]行、第[2]行和第[3]行等的值。。。
如果你想从不同的行中获得多个(分离的)模板,你必须深入挖掘,理解我所说的回调,并用map实现它。

嗨,iwaduarte,我是个新手,不知道如何才能完成你所说的。如果你能给我举个例子,那就太好了。我现在正为这件事绞尽脑汁,呵呵。费尔南多。你到底想达到什么目的?为什么你要循环几次?我想在页面中显示谷歌电子表格的内容,我在整个范围内循环。所以,我使用的是handlebar,我昨天刚刚学会了如何使用它,每个正在渲染的元素都将是handlebar短代码的内容。元素[0],元素[1]等将电子表格的单元格引用为数组。谢谢你,这真的很有用。
res.render('portfolio', {
   headlinePortfolio: element[0],
   subheadlinePortfolio: element[1],
   image1: element[3],
   client: element[4],
   campaign: element[5]
 }, ()=>console.log(`template created do something`))
 /* GET portfolio page. */
  router.get('/', async function (req, res, next) {

     ...
    const cols1 = spreadvals1.data.values || [];


  // I have removed the .map fn. You should do the same

    res.set('Content-Type', 'text/html');
    res.render('portfolio', {
       headlinePortfolio: cols[0][0], //row 1 - elem (col) 1
       subheadlinePortfolio:cols[0][1], //row 1 - elem  (col) 2
       image1: cols[0][3], //row 1 - elem (col) 4
       client: cols[0][4],//row 1 - elem (col) 5
       campaign: cols[0][5], // row 1 - elem (col) 6
     })

 }
 });

  module.exports = router;