如何设置从 Google 张到 <datalist> 的值范围

How to set a range of values from Google Sheets to <datalist>

我有一些 Google Sheet 有一个 editable 位置列表 ('Items'!A1:A)。我还有另一个 table 使用该方法从在 Google Web 应用程序中创建的页面写入数据。我需要它包含第一张纸范围内的值。

在其中一个主题中我发现了以下脚本:

<script>
  var datalist = document.getElementById('wrkList');
  var fragment = document.createDocumentFragment();

  var myList = ['Item1', 'Item2', 'Item3'];

  // Prepare the option elements to be rendered.
  myList.forEach(function(wrk) {
    var option = document.createElement('option');
    var text = document.createTextNode(wrk);

    option.value = wrk;
    option.appendChild(text);
    fragment.appendChild(option);
  });

  // Append all of them to DOM.
  datalist.appendChild(fragment);
</script>

如何将前 Google 个工作表 ('Items'!A1:A) 范围内的值传递给 myList 变量?

更新。我会尽量详细解释我需要什么。

Web 应用页面有一个输入字段:

<input type="text" list="wrkList" />
  <datalist id="wrkList"></datalist>

并在 .gs 中运行:

function itemsList() {
  var sheet = SpreadsheetApp.openById('1WeO8SyHj259jashQKXZ0WT_saSZHgk31yAQ1kZqiWpc').getSheetByName("Items");
  var lastrow = sheet.getLastRow();
  var myList = sheet.getRange(1, 1, lastrow).getValues();
  return myList;
}

我需要将 itemsList() 函数获得的值作为值传递给数据列表

您可以尝试使用 SpreadsheetApp.openById()

您可以找到 SpreadsheetApp here 的文档。

请参阅下面的改编代码:

  var datalist = document.getElementById('wrkList');
  var fragment = document.createDocumentFragment();

  var myList = SpreadsheetApp.openById('THE_ID_OF_YOUR_SPREADSHEET').getSheetByName('THE_SHEET_NAME').getRange('THE_RANGE').getValue();

  // Prepare the option elements to be rendered.
  myList.forEach(function(wrk) {
    var option = document.createElement('option');
    var text = document.createTextNode(wrk);

    option.value = wrk;
    option.appendChild(text);
    fragment.appendChild(option);
  });

  // Append all of them to DOM.
  datalist.appendChild(fragment);

我修改了代码:

<script>
  var sheet = SpreadsheetApp.openById('1WeO8SyHj259jashQKXZ0WT_saSZHgk31yAQ1kZqiWpc').getSheetByName("Items");
  var lastrow = sheet.getLastRow();
  
  var datalist = document.getElementById('wrkList');
  var fragment = document.createDocumentFragment();

  var myList = sheet.getRange(1, 1, lastrow).getValues();

  // Prepare the option elements to be rendered.
  myList.forEach(function(wrk) {
    var option = document.createElement('option');
    var text = document.createTextNode(wrk);

    option.value = wrk;
    option.appendChild(text);
    fragment.appendChild(option);
  });

  // Append all of them to DOM.
  datalist.appendChild(fragment);
</script>

但在控制台中出现此错误:

Uncaught ReferenceError: SpreadsheetApp is not defined at userCodeAppPanel:2

示例“服务器客户端”或“客户端服务器”与 Apps 脚本的通信

这是一个最小的示例,展示了如何将数据作为数组导入前端。

Code.gs

function doGet(){
  return HtmlService.createHtmlOutputFromFile("index")
}

function getInfo() {
  let file = SpreadsheetApp.getActive();
  let sheet = file.getSheetByName("Items");
  let range = sheet.getRange("A1:A");
  let values = range.getValues();

  return JSON.stringify(values);
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>

    <h1>Hello</h1>
    <button id=main>Run</button>

<script>   
function main(){
  google.script.run.withSuccessHandler(handleInfo).getInfo()
}

function handleInfo(info){
  console.log(JSON.parse(info))
}

const mainButton = document.getElementById("main")
mainButton.addEventListener('click', () => main())
</script>

  </body>
</html>

如果你运行这个,那么你应该将范围记录到控制台。

您可能不需要 JSON.stringify JSON.parse - 如果您的数据只是数字和字符串。如果它是约会之类的东西,那么你将需要它。

到目前为止你的代码

您似乎在尝试从普通 JavaScript 上下文中调用 Apps 脚本特定内容。 SpreadsheetApp 之类的东西在 JavaScript 中不存在,只存在于 Apps 脚本中。因此,网络应用程序中的 <script> 标签不能包含任何直接引用电子表格的内容。您需要使用

的结构
google.script.run.withSuccessHandler(handleInfo).itemsList()

这会将对 Apps 脚本的请求发送到 .gs 文件中的 运行 itemsList()。无论那个函数 returns 将用作本地 handleInfo 函数的参数。也就是说,当 Apps Script 函数成功时,它会这样做:

handleInfo([with whatever itemsList returns])

理想情况下,您可以使 itemsList return 成为一个简单的字符串数组,这样您就可以轻松地创建 <option> 个元素以插入到您的数据列表中。

工作示例

我不知道你的数据是什么样的,所以我自己发明了一些:

我也不知道你的脚本的其余部分是什么样的,也不知道你的 html 文件的名称,所以我已经尽可能多地填补了空白。

我还必须使用我自己的电子表格 ID 进行测试,尽管在下面的示例中我使用了您提供的那个。

Code.gs

function doGet(){
  return HtmlService.createHtmlOutputFromFile("index")
}

function itemsList() {
  var sheet = SpreadsheetApp.openById('1WeO8SyHj259jashQKXZ0WT_saSZHgk31yAQ1kZqiWpc').getSheetByName("Items");
  var lastrow = sheet.getLastRow();
  var myList = sheet.getRange(1,1,lastrow).getValues();
  // This line is to transform the array from [[1], [2], [3]] to [1,2,3]
  myList = myList.map(item => item[0])
  return JSON.stringify(myList); // JSON.stringify may not be neccesary
}

index.html

<!DOCTYPE html>
<html>
<body>
  <input type="text" list="wrkList"/>
  <datalist id="wrkList"></datalist>
</body>

<script>
function handleInfo(info){
  const list = JSON.parse(info) // JSON.parse needed if you used JSON.stringify in Code.gs
  
  // select datalist element
  const datalist = document.getElementById('wrkList')

  // forEach loop to create and append an option element for each item in list
  list.forEach(item => {
    const option = document.createElement('option')
    option.setAttribute('value', item)
    datalist.appendChild(option)
  })
}

// execute the itemsList function in code.gs and with the response
// execute the handleInfo function.
google.script.run.withSuccessHandler(handleInfo).itemsList()
</script>

</html>

一旦删除,这将加载一个 HTML 页面:

参考资料