【问题标题】:Using Google AppScript, Is it possible to programmatically publish to the web a _single sheet_ within a Google Sheets document?使用 Google AppScript,是否可以以编程方式将 Google 表格文档中的_单张表格_发布到网络上?
【发布时间】:2018-04-05 15:19:47
【问题描述】:

我想通过 Google Appscript (a) 以编程方式将 Google 表格文档中选定的 表格 发布到网络,(b) 以编程方式获取每张表格发布的 URL,以及 ( c)每当相应的工作表更新时,每个工作表的已发布版本都会自动更新(这应该会自动发生,对吗?)。现在,我只能通过文件/发布到 Web 来完成此操作...

以下问答与本题高度相关:

Google Sheets API: How to "publish to web" for embeddable sheet?

但是,它似乎仅适用于发布整个 Google 表格文档,而不适用于发布 Google 表格文档中的单个表格。任何解决方案的想法将不胜感激。

【问题讨论】:

    标签: google-apps-script google-sheets google-drive-api google-sheets-api web-publishing


    【解决方案1】:

    我对这个问题有了一些了解。只需修改用于访问该工作表的 URL,即可获得指向 Google 表格文档中单个工作表的已发布 HTML 版本的 URL。

    例如,这是我在 Google 表格中处理的工作表的网址,直接从浏览器的网址栏中复制:

    https://docs.google.com/spreadsheets/d/1fTx3dUsvdbVKgP2nXs1LcyG_7oBp-MoFZTXn7MtdEZg/edit#gid=1711661074

    然后我可以如下修改 URL 以获得该单张工作表的已发布 HTML 版本:

    https://docs.google.com/spreadsheets/u/0/d/1fTx3dUsvdbVKgP2nXs1LcyG_7oBp-MoFZTXn7MtdEZg/htmlembed/sheet?gid=1711661074

    我所做的 URL 修改总结:

    1. 将“电子表格”后的“/d”替换为“/u/0/d”
    2. 将“edit#”替换为“htmlembed/sheet?”

    可以做出的其他推论:

    1. “/u/0/d”后面的长字符串是 Google 表格文档的 ID。
    2. “sheet?”之后的较短字符串?是该文档中单张工作表的 ID。

    这些新见解将我的问题转变为一个新问题:即,我如何以编程方式(通过 Google Appscript)获取我正在处理的 Google 表格文档的 ID,以及我使用的电子表格的 ID正在工作吗?

    答案如下:

    1. 要在 Appscript 中获取当前 Google 表格文档的 ID:
      var ss = SpreadsheetApp.getActiveSpreadsheet().getId();
    2. 要获取当前 Google 表格文档中当前表格的 ID:
      var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getSheetId();
    3. 我现在可以通过以下字符串连接为 Google 表格文档中任何单个表格的已发布 html 版本构建 URL:
      var publishedURL = "https://docs.google.com/spreadsheets/u/0/d/" + ss + "/htmlembed/sheet?gid=" + sheet;

    不过,还有一个挥之不去的问题:这个已发布 URL 的用户似乎必须手动刷新浏览器才能将 HTML 与电子表格同步。 目前,我没有除了要求 URL 的用户安装自动 URL 刷新器或定期手动刷新页面之外,此问题的解决方案。我欢迎对此提出任何想法。

    【讨论】:

    • 能否通过在 html 源代码中嵌入元刷新标签来解决手动刷新问题?见link。问题是我不知道如何更改已发布的 html 版本的 Google 表格的内容。
    • 查看我的答案。您还可以添加一个 javascript 超时函数来启动刷新。
    • 感谢这对我意味着什么,帮我解决我的问题!!!
    【解决方案2】:

    您似乎可以根据这些对话框发布单个工作表:

    它确实会更新已发布的表格,尽管我偶尔会注意到该过程有相当多的延迟。

    由于 Publish to the Web 仅显示包含工作表值的 html 表格的只读版本,因此您可以使用一个 web 应用程序来完成。下面是一个以表格形式显示所有工作表的示例。

    一个显示所有工作表的 Web 应用程序:

    function publishAllSheets() 
    {
      var ss=SpreadsheetApp.getActive();
      var allShts=ss.getSheets();
      var s='All my Sheets';
      for(var i=0;i<allShts.length;i++)
      {
        var sh=allShts[i];
        var rg=sh.getDataRange();
        var vA=rg.getValues();
        s+=Utilities.formatString('Sheet: %s <br /><table border="1">',allShts[i].getName());
        for(var j=1;j<vA.length;j++)
        {
          s+='<tr>';
          for(var k=0;k<vA[j].length;k++)
          {
            s+=Utilities.formatString('<td>%s</td>', vA[j][k]);
          }
          s+='</tr>';
        }
        s+='</table>';
      }
      return s;
    }
    
    function showAllMySheets()
    {
      var ui=HtmlService.createHtmlOutputFromFile('allsheets').setWidth(1000);
      SpreadsheetApp.getUi().showModelessDialog(ui, 'All My Sheets')
    }  
    
    function doGet()
    {
      var ui=HtmlService.createHtmlOutputFromFile('allsheets');
      return ui.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
    }
    

    allsheets.html

    <!DOCTYPE html>
    <html>
      <head>
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
      <script>
       $(function(){
         google.script.run
            .withSuccessHandler(updateDiv)
            .publishAllSheets();
       });
    
       function updateDiv(hl)
       {
         document.getElementById('c1').innerHTML=hl;
       }
      </script>
      </head>
      <body>
       <div id="c1"></div>  
      </body>
    </html>
    

    以下是获取任何一张工作表的代码:

    function getSheetNames()
    {
      var ss=SpreadsheetApp.getActive();
      var allShts=ss.getSheets();
      var shts=[];
      for(var i=0;i<allShts.length;i++)
      {
        shts.push(allShts[i].getName());
      }
      return shts;
    }
    
    function getOneSheet(name)
    {
      var ss=SpreadsheetApp.getActive();
      var sh=ss.getSheetByName(name);
      var rg=sh.getDataRange();
      var vA=rg.getValues();
      var s='';
      s+=Utilities.formatString('Sheet: %s <br /><table border="1">',sh.getName());
      for(var j=1;j<vA.length;j++)
      {
        s+='<tr>';
        for(var k=0;k<vA[j].length;k++)
        {
          s+=Utilities.formatString('<td>%s</td>', vA[j][k]);
        }
        s+='</tr>';
      }
      s+='</table>';
      return s;
    }
    

    onesheet.html

    <!DOCTYPE html>
    <html>
      <head>
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
       <script>
       $(function(){
         google.script.run
            .withSuccessHandler(updateSelect)
            .getSheetNames();
       });
    
       function updateDiv(hl)
       {
         document.getElementById('c1').innerHTML=hl;
       }
    
       function updateSelect(vA)
        {
          var select = document.getElementById("sel1");
          select.options.length = 0; 
          for(var i=0;i<vA.length;i++)
          {
            select.options[i] = new Option(vA[i],vA[i]);
          }
        }
    
        function getSelectedSheet()
        {
          var name=$('#sel1').val();
          google.script.run
             .withSuccessHandler(updateDiv)
             .getOneSheet(name);
        }
       console.log('MyCode');
      </script>
      </head>
      <body>
        <select id="sel1">
          <option value="" selected></option>
       </select>
       <input type="button" value="Select" onClick="getSelectedSheet();" />
       <div id="c1"></div>
      </body>
    </html>
    

    【讨论】:

    • 谢谢,@Cooper。我正在寻找一种解决方案,允许我通过 Google Appscript以编程方式执行此操作。
    • 好吧,如果您想要的只是他们在发布到网络时所做的事情,那么我会选择一个具有工作表名称下拉列表的 web 应用程序。用户选择工作表名称,webapp 将其发送回服务器,服务器将 webapp 的工作表的 html 发送到 html 表中,webapp 将其放入带有document.getElementById().innerHTML= 的 div
    • 请看我的新答案。我认为它解决了问题。
    • 如果您在电子表格中构建包含的 Web 应用程序,则无需了解所有这些。看我的回答。
    • 这是一个有趣的方法,@Cooper!谢谢分享!唉,它不适用于我的应用程序,因为我将电子表格的 webapp 功能 (doGet()) 用于完全不同的目的,并且不能利用该功能来提供电子表格内容的 html 版本。相反,我需要能够向用户提供指向 Google 托管的电子表格内容的链接。为此,我认为我提出的解决方案的一些变化将是最好的路线。如果我决定构建一个能够提供电子表格内容的扩展 web 应用程序,我会考虑您的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多