将数据从Google表格中提取到HTML表格中

时间:2019-06-06 10:00:44

标签: javascript html google-apps-script google-sheets

我在Google表格上有一个小型的Web应用程序设置,其中包含近1万行和9列。

当前,我从Google表格中获取了所有数据,并将其放在HTML表格中,然后我很少使用输入来使用事件监听器过滤表格。

您可能已经猜到,由于它位于客户端,并且占用了太多内存,因此加载和筛选速度很慢。

以前,我在每个按键上都有一个带有事件侦听器的交互式筛选器,因为将前两个或三个字符花了太多时间,所以我将其更改为“ Enter”键。

索引脚本。HTML

 <script>
    //global variables
    var rows = []; //rows 
    var currentOrder = 'ascending'; //sorting order
    var inputFilter = document.getElementById('partNum'); //input field for ItemName
    var inputFilterDes = document.getElementById('partDes'); //input field for description
    var nameTable = document.getElementById('table'); //html table

    //load function being used for pulling data from google sheet

    function load() {
    //calling get data function with array and filter array inside
    google.script.run
        .withSuccessHandler(function(response) {
        //response function will be separted into column values
        rows = response.map(function(element) {
            //all the elements converted into columns
            return {
            itemCode: element[0],
            itemName: element[1],
            itemDescription: element[2],
            inStock: element[3],
            committed: element[4],
            onOrder: element[5],
            available: element[6],
            warehouse: element[7]
            };
        });
        //rows mapping finished

        renderTableRows(rows);
        //initial load finished here

        //filter section starts

        //Item name filter

        inputFilter.addEventListener('keyup', function(evt) {
            if (evt.keyCode === 13) {
            // Cancel the default action, if needed
            evt.preventDefault();
            var filter = evt.target.value.toString().toLowerCase();
            }
            var filteredArray = rows.filter(function(row) {
            return row.itemName.toString().toLowerCase().includes(filter);
            });

            renderTableRows(filteredArray);
        });
        //description filter

        inputFilterDes.addEventListener('keyup', function(evt) {
            if (evt.keyCode === 13) {
            // Cancel the default action, if needed
            evt.preventDefault();
            var filterDes = evt.target.value.toString().toLowerCase();
            }
            var filteredArrayDes = rows.filter(function(row) {

            return row.itemDescription.toString().toLowerCase().includes(filterDes);
            });
            renderTableRows(filteredArrayDes);
        });

        })
        .getData("SAP"); //pull data from defined sheet
    }
    //retruing array values in HTML table and placing them in page
    function renderTableRows(arr) {
    nameTable.innerHTML = arr.map(function(row) {
        return '<tr>' + 
        '<td>' + row.itemCode + '</td>' + '<td>' + row.itemName + '</td>' + 
        '<td>' + row.itemDescription + '</td>' + '<td>' + row.inStock + '</td>' + 
        '<td>' + row.committed + '</td>' + '<td>' + row.onOrder + '</td>' + '<td>' + 
        row.available + '</td>' + '<td>' + row.warehouse + '</td>' + '</tr>';
    }).join('');
    };


    load();
  </script>

我的代码。gs

function doGet(e) {

  if (!e.parameter.page) {
    // When no specific page requested, return "home page"
    return HtmlService.createTemplateFromFile('index').evaluate().setTitle("My Web App");
  }
  // else, use page parameter to pick an html file from the script
  return HtmlService.createTemplateFromFile(e.parameter['page']).evaluate();
}

function getData(sheetName) {

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);

  return sheet.getSheetValues(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn());
}

function getScriptUrl() {
  var url = ScriptApp.getService().getUrl();
  return url;
}

我尝试使用以下方法在服务器端移动它,但失败了

编辑:删除了服务器端的emption代码,因为我认为这会造成混乱。

我不是编码员,所以听起来很傻或组织混乱,请原谅。

因此,我正在尝试提高速度,为此,我想在服务器端移动脚本,但是我不确定它是否会帮助我,因此我愿意采用任何其他方法来提高应用程序的速度。

2 个答案:

答案 0 :(得分:1)

构建一个9列,10,000行的html表大约需要112秒。

function dataToHtmlTable() {
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getActiveSheet();
  var rg=sh.getDataRange();
  var vA=rg.getValues();
  var html="<style>th,td{border:1px solid black;}</style><table>";
  for(var i=0;i<vA.length;i++) {
    html+='<tr>';
    for(var j=0;j<vA[i].length;j++) {
      if(i==0) {
        html+=Utilities.formatString('<th>%s</th>',vA[i][j]);
      }else{
        html+=Utilities.formatString('<td>%s</td>',vA[i][j]);
      }
    }
    html+='</tr>';
  }
  html+='</table>';
  var userInterface=HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModelessDialog(userInterface, 'HTML Table')
}

答案 1 :(得分:0)

除了将map()移至异步服务器调用之外,您还可以通过创建在DOM上运行的排序函数来优化客户端代码。当前,每次触发keyup事件时,您渲染整个表(如果我正确理解Spreadsheet的大小,则每次迭代10K)。

首先,访问表的子级(假设它是由<thead><tbody>元素构成的:var collection = nameTable.children.item(1).children(返回所有行的HtmlCollection)。

第二,使用hidden属性(或创建和toggle一个CSS类)来遍历行并隐藏不满足过滤条件的行:

for(var i=0; i<collection.length; i++) {
  var row      = collection.item(i);
  var cells    = row.children;
  var itemName = cells.item(1).textContent; //access item name (0-based);
  var itemDesc = cells.item(2).textContent; //access item description (0-based);

  var complies = itemName==='' && itemDesc===''; //any criteria here;

  if( complies ) {
    row.hidden = false;
  }else {
    row.hidden = true;
  }

}

第三,将renderTableRows()函数也移至服务器异步调用,因为您使用createElement()通过字符串连接(而不是document上的htmlString)来呈现表行

有用的链接

  1. Document Object Model(DOM)参考;
  2. Server-client communication在GAS参考中;
  3. Best practicesHtmlService合作;