从 google apps 脚本启动下载

问题描述 投票:0回答:3

我使用谷歌应用程序脚本向我的电子表格添加了一个新的菜单项。此菜单项创建一个文件,但我希望它在创建文件后启动文件的下载。

这可能吗?

请记住,这不是网络应用程序,而是我的电子表格中的菜单项。

谢谢

编辑:

感谢 Serge insas 的建议,以下简单脚本可以完美运行,并打开一个带有我需要的链接的下载窗口:

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var csvMenuEntries = [ {name: "Zip all CSVs", functionName: "saveAsCSV"} ];
  ss.addMenu("CSV", csvMenuEntries);
};

function saveAsCSV() {
  var folder = createCSVs(); // creates a folder with CSV for each Sheet
  var zipFile = zipCSVs(folder, "DI.zip"); // creates a zip of all CSVs in folder

  var ui = UiApp.createApplication().setTitle("Download");
  var p = ui.createVerticalPanel();
  ui.add(p);
  p.add(ui.createAnchor("Download", zipFile.getDownloadUrl()));
  SpreadsheetApp.getActive().show(ui)
}
google-apps-script google-drive-api
3个回答
10
投票

编辑:阅读下面的评论,Zig Mandel 指出“复杂”版本的局限性时完全正确,这确实是一个简单(且有趣)的展示其他方法的练习。


我认为您必须使用中间 Ui 作为弹出窗口来确认下载。 之后我知道有两种可能的方法,一种很简单,另一种很麻烦,你可以选择,下面的代码展示了这两种方法。

注意:要使用复杂的应用程序,您需要部署应用程序(即保存版本并部署为 web 应用程序),对于简单的应用程序,只需“按原样”使用它。 (我在代码注释中显示了简单的)。

代码:

function onOpen() {
  var menuEntries = [ {name: "test download", functionName: "downloadFile"}
                     ];
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  sheet.addMenu("Utils",menuEntries);
}

function downloadFile(){
  var file = DriveApp.createFile('test file', 'Some content in this file to test it');
  var fileID = file.getId();
  var fileName = file.getName();
  var ui = UiApp.createApplication().setTitle('Download');
  var url = ScriptApp.getService().getUrl()+'?&ID='+fileID+'&name='+fileName;
  var p = ui.createVerticalPanel();
  ui.add(p);
  p.add(ui.createAnchor('click to download', url));
  p.add(ui.createAnchor('or use this link ',file.getDownloadUrl()));// this is the simple one, just get the file you created and use getDownloadUrl()
  SpreadsheetApp.getActive().show(ui)
}

function doGet(e){
  var fileId = e.parameter.ID;
  var fileName = e.parameter.name;
  var fileString = DocsList.getFileById(fileId).getContentAsString();
  return ContentService.createTextOutput(fileString).downloadAsFile(fileName);
}

PS:我写这篇文章很有趣,“复杂版本”真的很有趣:-)


9
投票

OP 的答案已被弃用(2021 年),所以我基于它制作了一个更通用的答案。


Code.gs

// Runs when the spreadsheet starts, adds a tab at the top
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Script Menu')
    .addItem('Download a file!', 'dlFile')
    .addToUi();
}

// Run when you click "Download a file!"
function dlFile() {
  let file = DriveApp.getRootFolder().createFile('Hi.txt', 'Hello, world!');

  // Create little HTML popup with the URL of the download
  let htmlTemplate = HtmlService.createTemplateFromFile('Download.html');
  htmlTemplate.dataFromServerTemplate = { url: file.getDownloadUrl() };

  let html = htmlTemplate
    .evaluate()
    .setWidth(400)
    .setHeight(300);

  SpreadsheetApp.getUi()
    .showModalDialog(html, 'Download');
};


Download.html

<!DOCTYPE html>
<html>
  <head>
    <script>
      let data = <?!= JSON.stringify(dataFromServerTemplate) ?>; // Stores the data directly in the javascript code

      function downloadFile() {
        document.getElementById("dlBtn").innerText = "Downloading..";

        window.open(data.url, '_blank');

        document.getElementById("dlBtn").disabled = true;
      }
    </script>
  </head>
  <body>
    <button id="dlBtn" onclick="downloadFile()">Download</button>
  </body>
</html>

0
投票

只是添加到 @dr-bracket 的答案,我在脚本中做了一些小的添加,试图阻止浏览器导航到新选项卡。

我的想法来自:

从已部署的网络应用程序(Google Apps 脚本)下载创建的 Google 文档

其中 @tanaike 使用 google.script.run.withSuccessHandler 类和方法创建弹出提示,然后在下载时关闭并返回到您的应用程序。 (如果您的浏览器设置设置为不选择下载位置,则可能不会弹出。)

代码.gs:

// Runs when the spreadsheet starts, adds a tab at the top
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Script Menu')
    .addItem('Download a file!', 'dlFile')
    .addToUi();
}

// Run when you click "Download a file!"
function dlFile() {
  let file = DriveApp.getRootFolder().createFile('Hi.txt', 'Hello, world!');

  // Create little HTML popup with the URL of the download. Added filename to object. ~~~~~~~~~~~
  let htmlTemplate = HtmlService.createTemplateFromFile('Download.html');
  htmlTemplate.dataFromServerTemplate = { url: file.getDownloadUrl(), name: file.getName() };

  let html = htmlTemplate
    .evaluate()
    .setWidth(400)
    .setHeight(300);

  SpreadsheetApp.getUi()
    .showModalDialog(html, 'Download');
};

// Added the following to satisfy the withSuccessHandler method: ~~~~~~~~~~~~~
function createDownloadUrl(data) {
  return { 
    url: data.url,
    name: data.name,
  };
}

下载.html:

<!DOCTYPE html>
<html>
  <head>
    <script>
      let data = <?!= JSON.stringify(dataFromServerTemplate) ?>; // Stores the data directly in
      // the javascript code

      function downloadFile() {
        const dlBtn = document.getElementById("dlBtn");
        dlBtn.innerText = "Downloading..";

        // window.open(data.url);
        // Replaced with: 
        // the url and name variables will be returned here from the 
        // code.gs function createDownloadEvent() after it runs successfully.
        google.script.run
          .withSuccessHandler(({ url, name }) => {
              const a = document.createElement("a");
              document.body.appendChild(a);
              a.download = name;
              a.href = url;
              a.target = "_blank";
              a.click();
            })
            .createDownloadEvent(data);

        dlBtn.disabled = true;
      }
    </script>
  </head>
  <body>
    <button id="dlBtn" onclick="downloadFile()">Download</button>
  </body>
</html>

资源:

© www.soinside.com 2019 - 2024. All rights reserved.