Есть ли способ программно скачать заархивированные файлы с G.Drive? - PullRequest
0 голосов
/ 20 июня 2019

Я получил библиотеку из нескольких книг и хочу, чтобы пользователь мог загрузить любую из них с помощью тега select на моей html-странице, используя несколько js. Что бы я ни делал (на стороне сервера и на стороне клиента), это приводило меня к другому URL. заблудиться, поскольку я новичок в этом. Любая помощь высоко ценится. Я просто поставил ниже последнюю попытку, которую я сделал

Это скрипт html & js

<html>
.....
    <div class="input-field col s4 form-text">
        <button id="download" class="waves-effect blue-grey darken-1 btn" > <i class="material-icons left">cloud</i>Download </button> 
   </div>  

<!-- I got an eventListener-->
 <script>
   document.getElementById("download").addEventListener("click",downloadMyBook);
 </script>
....
</html>

на стороне сценария (на стороне клиента)

<script>

  function downloadMyBook() {
     var sel = document.getElementById("selected_book");
     var title= sel.options[sel.selectedIndex].text;
     google.script.run.GetThatBook(title); // send a job to the server
    }
</script>

на стороне сервера

function doGet(e){

}

function GetThatBook(text){
   // reading  the files description from a G.Sheet
   var url = "";
   var ss = SpreadsheetApp.openByUrl(url);
   var ws = ss.getSheetByName("2019");
   var records = ws.getRange(1,1,ws.getRange("A1").getDataRegion().getLastRow()-2,12);
   // All detailed for clarity-Debugging purpose 
   var myBooks = records.map(function(r){return r[0]}); // Book titles
   var myLinks = records.map(function(r){return r[8]}); // the google IDs
   var index = myBooks.indexOf(text); // identify the index in the array of the one of interest
   var fileID = myLinks[index] ; // get it's ID as it's recorded in the G.sheet

   var file = DriveApp.getFileById(fileID); // here is the blocking point

   if(file){
        return true;
   }
  else{
        return false;
       }

}

Хотелось бы, чтобы файл (все они были заархивированы) был загружен, но похоже, что процесс сложнее, чем я ожидал. (Вопрос отредактирован по мере необходимости. Прошу прощения - сделал не так

1 Ответ

0 голосов
/ 27 июня 2019

Для вашего собственного комментария по вашему вопросу я предположил, что вы забыли поместить функцию getValues ​​() в конец строки, где вы получаете переменную records.

Изменения, необходимые в вашем коде:

1) Чтобы использовать HTML в вашем веб-приложении Script, вам необходимо вернуть объект HtmlOutput в функцию doGet () [1]. Кроме того, здесь приведены инструкции по развертыванию веб-приложения в приложении Script, если вы не знаете [2].

2) Как вы сказали, после запуска функции GetThatBook она перенаправляет вас на другой URL-адрес, потому что вы не обрабатываете ответ этой функции. Вам нужно использовать функцию withSuccessHandler для обработки ответа, если он успешен [3]. Я также использую функцию withFailureHandler для печати ошибки и отладки кода.

3) Чтобы получить URL для загрузки полученного файла, вам необходимо использовать функцию getDownloadUrl () для объекта File [4].

4) В настоящее время в Google есть ошибка, связанная с URL, который вы получаете этим методом, вы можете увидеть его здесь [5]. Предложенный обходной путь заключается в удалении последнего параметра URL-адреса, это можно сделать с помощью функции подстроки.

5) Наконец, в функции обработчика успеха (updateUrl) вы можете перенаправить приложение на URL-адрес, который загрузит файл.

Вот ваш код, откорректированный мной, который я протестировал и успешно работал при загрузке файла:

Index.html (на стороне клиента):

<script>
      document.getElementById("download").addEventListener("click",downloadMyBook);

      function downloadMyBook() {
         var sel = document.getElementById("selected_book");
         var title= sel.options[sel.selectedIndex].text;
         google.script.run.withFailureHandler(error).withSuccessHandler(updateUrl).GetThatBook(title); // send a job to the server
      }

    //
      function updateUrl(url) {
       window.location.href = url;
      }

      function error(e) {
        console.log(e);
      }

  </script>

Code.gs (на стороне сервера):

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function GetThatBook(text){
   // reading  the files description from a G.Sheet
   var url = "";
   var ss = SpreadsheetApp.openByUrl(url);
   var ws = ss.getSheetByName("2019");
   var records = ws.getRange(1,1,ws.getRange("A1").getDataRegion().getLastRow()-2,12).getValues();
   // All detailed for clarity-Debugging purpose 
   var myBooks = records.map(function(r){return r[0]}); // Book titles
   var myLinks = records.map(function(r){return r[8]}); // the google IDs
   var index = myBooks.indexOf(text); // identify the index in the array of the one of interest
   var fileID = myLinks[index] ; // get it's ID as it's recorded in the G.sheet

  // From this part, I would suggest to use another way to do this part (using try/catch) because it will throw an error if it doesn’t find the file with that fileID. 

   var file = DriveApp.getFileById(fileID); // here is the blocking point
   //Get Url
   var url = file.getDownloadUrl();


   If (file) {
   //Fix Url and return it to client side
        return url.substring(0, url.length -8);
   } else {
        return "No file";
   }
}

[1] https://developers.google.com/apps-script/guides/html/

[2] https://developers.google.com/apps-script/guides/web

[3] https://developers.google.com/apps-script/guides/html/reference/run#withsuccesshandlerfunction

[4] https://developers.google.com/apps-script/reference/drive/file#getdownloadurl

[5] https://b.corp.google.com/issues/36761174#comment3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...