Загрузка нескольких файлов на Google Диск С помощью Google App Script

Я пытаюсь загрузить несколько файлов одновременно с моим приложением. Он распознает, когда выбраны 2 или более файлов. Однако он будет загружать только 1-й файл, выбранный на мой диск. Кроме того (хотя и довольно незначительный), мне было интересно, как я могу изменить шрифт textarea, чтобы быть Times New Roman, чтобы оставаться в соответствии с остальной частью шрифта.

Код.gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('form')
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);
}

function uploadFiles(form) {

  try {
    var foldertitle = form.zone + ' | Building: ' + form.building + ' | ' + form.propertyAddress + ' | ' + form.attachType;
    var folder, folders = DriveApp.getFolderById("0B7UEz7SKB72HfmNmNnlSM2NDTVVUSlloa1hZeVI0VEJuZUhSTmc4UXYwZjV1eWM5YXJPaGs");
    var createfolder = folders.createFolder(foldertitle);
    folder = createfolder;
    var blob = form.filename;
    var file = folder.createFile(blob);
    file.setDescription(" " + form.fileText);

    return "File(s) uploaded successfully! Here is the link to your file(s):     " + folder.getUrl();

  } catch (error) {
    Logger.log('err: ' + error.toString());
    return error.toString();
  }

}

function uploadArquivoParaDrive(base64Data, nomeArq, idPasta) {
  try{
    var splitBase = base64Data.split(','),
        type = splitBase[0].split(';')[0].replace('data:','');

    var byteCharacters = Utilities.base64Decode(splitBase[1]);
    var ss = Utilities.newBlob(byteCharacters, type);
    ss.setName(nomeArq);

    var file = DriveApp.getFolderById("0B7UEz7SKB72HfmNmNnlSM2NDTVVUSlloa1hZeVI0VEJuZUhSTmc4UXYwZjV1eWM5YXJPaGs").createFile(ss);

    return file.getName();
  }catch(e){
    return 'Erro: ' + e.toString();
  }
}

5 ответов


Я знаю, что этот вопрос старый, но после его поиска и связанных с ним, я никогда не мог заставить несколько файлов загружать работу. Поэтому после того, как я много бился головой о стены, я хотел опубликовать полный пример (.HTML и .ОО) если кто-то в будущем ищу один, чтобы начать. Это работает, когда я разворачиваю его прямо сейчас и, надеюсь, будет работать для других людей. Обратите внимание, что я просто жестко закодировал папку на диске для использования в коде.GS файл, но это может быть легко измененный.


вы должны отправить файл за раз через скрипт.запустите, вот моя реализация с FileReaders / ReadAsURL, которая делает файл строкой Base64, которую можно легко передать:

Примечания:

  1. Не знаю, если это необходимо, но я использую iframe sandbox
  2. Я оставил progressBar в коде, вы можете удалить его
  3. все должно быть вне формы
  4. он принимает любой файл тип

HTML-код:

// Upload de arquivo dentro das pastas Arquivos Auxiliares
function iterarArquivosUpload() {
    var arquivos = document.getElementById('inputUpload').files;

    if (arquivos.length == 0) {
        alert('No file selected!');
    } else {
        //Show Progress Bar
        numUploads.total = arquivos.length;
        $('.progressUpload').progressbar({
            value : false
        });
        $('.labelProgressUpload').html('Preparando arquivos para upload');

        // Send each file at a time
        for (var arqs = 0; arqs < numUploads.total; arqs++) {
            console.log(arqs);
            enviarArquivoParaDrive(arquivos[arqs]);
        }
    }
}

function enviarArquivoParaDrive(arquivo) {
    var reader = new FileReader();
    reader.onload = function (e) {
        var content = reader.result;
        console.log('Sending ' + arquivo.name);
        google.script.run.withSuccessHandler(updateProgressbar).uploadArquivoParaDrive(content, arquivo.name, currFolder);
    }
    reader.readAsDataURL(arquivo);
}

function updateProgressbar( idUpdate ){
   console.log('Received: ' + idUpdate);
   numUploads.done++;
   var porc = Math.ceil((numUploads.done / numUploads.total)*100);
   $('.progressUpload').progressbar({value: porc });
   $('.labelProgressUpload').html(numUploads.done +'/'+ numUploads.total);
   if( numUploads.done == numUploads.total ){
      uploadsFinished();
      numUploads.done = 0;
   };
}

Код.GS

function uploadArquivoParaDrive(base64Data, nomeArq, idPasta) {
  try{
    var splitBase = base64Data.split(','),
        type = splitBase[0].split(';')[0].replace('data:','');

    var byteCharacters = Utilities.base64Decode(splitBase[1]);
    var ss = Utilities.newBlob(byteCharacters, type);
    ss.setName(nomeArq);

    var file = DriveApp.getFolderById(idPasta).createFile(ss);

    return file.getName();
  }catch(e){
    return 'Erro: ' + e.toString();
  }
}

Обновлено Для Мая 2017

я обновил и улучшил ответ Баррагана.

плюсы:

  1. позволяет пользователям создавать имя вложенной папки, чтобы содержать все файлы, загруженные во время этого сеанса
  2. гарантирует, что все эти подпапки существуют в одной указанной папке на вашем Google Диске
  3. страница / форма является мобильным адаптивным

вы можете начать с как раз создать сценарий и узнать основы.

затем вы можете полностью заменить форма.HTML-код С этого:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>
            Send Files
        </title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>        
        <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
        <script>

            $(document).ready(function () {

                function afterSubfolderCreated(subfolderId) {
                    console.log(subfolderId);
                    console.log(allFiles);
                    numUploads.total = allFiles.length;
                    $('#progressbar').progressbar({
                        value: false
                    });
                    $(".progress-label").html('Preparing files for upload');
                    for (var i = 0; i < allFiles.length; i++) {
                        console.log(i);
                        sendFileToDrive(allFiles[i], subfolderId);
                    }
                }

                function sendFileToDrive(file, subfolderId) {
                    var reader = new FileReader();
                    reader.onload = function (e) {
                        var content = reader.result;
                        console.log('Sending ' + file.name);
                        google.script.run.withSuccessHandler(updateProgressbar).uploadFileToDrive(content, file.name, subfolderId);
                    }
                    reader.readAsDataURL(file);
                }

                function updateProgressbar(idUpdate) {
                    console.log('Received: ' + idUpdate);
                    numUploads.done++;
                    var porc = Math.ceil((numUploads.done / numUploads.total) * 100);
                    $("#progressbar").progressbar({value: porc});
                    $(".progress-label").text(numUploads.done + '/' + numUploads.total);
                    if (numUploads.done == numUploads.total) {                        
                        numUploads.done = 0;
                        $(".progress-label").text($(".progress-label").text() + ': FINISHED!');
                        $("#progressbar").after('(Optional) Refresh this page if you remembered other screenshots you want to add.');//<a href="javascript:window.top.location.href=window.top.location.href"> does not work
                    }
                }

                function fileUploaded(status) {
                    document.getElementById('myForm').style.display = 'none';
                    document.getElementById('output').innerHTML = status;
                }
                var numUploads = {};
                numUploads.done = 0;
                numUploads.total = 0;
                var allFiles;
                var frm = $('#myForm');
                frm.submit(function () {
                    allFiles = document.getElementById('myFile').files;
                    if (!frm.checkValidity || frm.checkValidity()) {
                        if (allFiles.length == 0) {
                            alert('Error: Please choose at least 1 file to upload.');
                            return false;
                        } else {
                            frm.hide();
                            var subfolderName = document.getElementById('myName').value;
                            $.ajax({
                                url: '',//URL of webhook endpoint for sending a Slack notification
                                data: {
                                     title: subfolderName + ' is uploading screenshots',
                                     message: ''
                                }
                            });
                            google.script.run.withSuccessHandler(afterSubfolderCreated).createSubfolder(subfolderName);
                            return false;
                        }
                    } else {
                        alert('Invalid form');
                        return false;
                    }
                });
            });//end docReady
        </script>
        <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
        <style>
            body {
                padding: 20px;
                margin: auto;
                font-size: 20px;
            }
            label{
                font-weight: bold;
            }
            input{
                font-size: 20px;
                padding: 5px;
                display: inline-block;
                margin-bottom: 10px;
                -webkit-box-sizing: border-box;
                ‌-moz-box-sizing: border-box;
                box-sizing: border-box;
            }
            .hint{
                font-size: 90%;
                color: #666;
            }
            select {
                margin: 5px 0px 15px 0px;
            }
            input[type="file"] {
                padding: 5px 0px 15px 0px;
            }
            #progressbar{
                width: 100%;
                text-align: center;
                overflow: hidden;
                position: relative;
                vertical-align: middle;
            }
            .progress-label {
                float: left;
                margin-top: 5px;
                font-weight: bold;
                text-shadow: 1px 1px 0 #fff;
                width: 100%;
                height: 100%;
                position: absolute;
                vertical-align: middle;
            }
            li{
               padding: 10px;
            }
            @media only screen and (max-width : 520px) {
                #logo {
                    max-width: 100%;
                }
            }
        </style>
    </head>
    <body>
        <p>
            <img src="" id="logo">
        </p>
        <p>This webpage allows you to send me screenshots of your dating profiles.</p>
        <ol>
            <li>
                In each of your dating apps, take a screenshot <a href="https://www.take-a-screenshot.org/" target="_blank">(how?)</a> of every part of every page of your profile.
            </li>
            <li>
                Do the same for each of your photos (at full resolution).
            </li>
            <li>
                In the form below, type your first name and last initial (without any spaces or special characters), such as SallyT.
            </li>
            <li>
                Then click the first button and select all of your screenshot images (all at once).
            </li>
            <li>
                Finally, press the last button to send them all to me!
            </li>
        </ol>
        <form id="myForm"> 
            <div>
                <label for="myName">Your first name and last initial:</label> 
            </div>
            <div>
                <input type="text" name="myName" id="myName" placeholder="SallyT" required pattern="[a-zA-Z]+" value=""> 
                </div>
                <div>
                    <span class="hint">(No spaces or special characters allowed because this will determine your folder name)</span>
                </div>            
            <div style="margin-top: 20px;">
                <label for="myFile">Screenshot image files:</label>

                <input type="file" name="filename" id="myFile" multiple>
            </div>
            <div style="margin-top: 20px;">
                <input type="submit" value="Send File(s) ➔" >
            </div>
        </form>

        <div id="output"></div>
        <div id="progressbar">
            <div class="progress-label"></div>
        </div>


    </body>
</html>

и полностью заменить сервер.gs с этим:

function doGet() {
  var output = HtmlService.createHtmlOutputFromFile('form');
  output.addMetaTag('viewport', 'width=device-width, initial-scale=1');// See http://stackoverflow.com/a/42681526/470749
  return output.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}

function uploadFileToDrive(base64Data, fileName, subfolderId) {
  Logger.log(subfolderId);
  try{
    var splitBase = base64Data.split(','),
        type = splitBase[0].split(';')[0].replace('data:','');

    var byteCharacters = Utilities.base64Decode(splitBase[1]);
    var ss = Utilities.newBlob(byteCharacters, type);
    ss.setName(fileName);
    var subfolder = DriveApp.getFolderById(subfolderId);
    var file = subfolder.createFile(ss);
    Logger.log(file);
    return file.getName() + ' at ' + file.getUrl();
  } catch(e){
    return 'createFile Error: ' + e.toString();
  }
}

function createSubfolder(subfolderName){
  var dropbox = subfolderName + Utilities.formatDate(new Date(), "US/Eastern", "_yyyy-MM-dd");
    Logger.log(dropbox);
    var parentFolderId = "{ID such as 0B9iQ20nrMNYAaHZxRjd}";
    var parentFolder = DriveApp.getFolderById(parentFolderId);
    var folder;
    try {
      folder = parentFolder.getFoldersByName(dropbox).next();      
    }
    catch(e) {
      folder = parentFolder.createFolder(dropbox);
    }
    Logger.log(folder);
  return folder.getId();
}

во-первых, изменить свой doGet() код для этого:

function doGet() {
  return HtmlService.createHtmlOutputFromFile('form')
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);
}

не используйте расширение файла в конце имени файла формы. У тебя есть,form.html. Изменить это просто:

return HtmlService.createHtmlOutputFromFile('form')

затем добавьте метод setSandboxMode, и если вы не захватываете параметр строки поиска URL, то вам не нужен аргумент e на doGet().

удалить <form> теги из HTML.

если вы собираетесь использовать jQuery, то вы нужно загрузить jQuery.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

в настоящее время, у вас есть google.script.run код внутри атрибута click. У вас есть:

<input type="button" value="Submit" onclick="this.value='Uploading..';
              google.script.run.withSuccessHandler(fileUploaded)
              .uploadFiles(this.parentNode);
              return false;">

я бы поместил весь код в свою собственную функцию:

<input type="submit" value="Submit" onclick="iteratorFileUpload()">

затем в теге скрипт:

<script>
function iteratorFileUpload() {
  var allFiles = document.getElementById('myFile').files;

  if (allFiles.length == 0) {
    alert('No file selected!');
  } else {
    // Send each file one at a time
    var i=0;
    for (i=0; i < allFiles.length; i+=1) {
      console.log('This iteration: ' + i);
      sendFileToDrive(allFiles[i]);
    };
  };
};

function sendFileToDrive(file) {
  var reader = new FileReader();
  reader.onload = function (e) {
    var content = reader.result;
    console.log('Sending ' + file.name);

    google.script.run
      .withSuccessHandler(fileUploaded)
      .uploadFiles(file.name);
  }

  reader.readAsDataURL(file);
};
</script>

как ответ @barragan вот лучший ответ, который я нашел после нескольких часов и часов поиска вопроса, который задавали многие люди, я сделал немного развития, чтобы улучшить дизайн немного для других в качестве благодарности. еще несколько ошибок и chrome, кажется, исчерпали память и отказаться от любого файла более 100MB

вот живая версия

сервер.gs

'function doGet() {
  return HtmlService.createHtmlOutputFromFile('form')
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);
}

function uploadFileToDrive(base64Data, fileName) {
  try{
    var splitBase = base64Data.split(','),
        type = splitBase[0].split(';')[0].replace('data:','');

    var byteCharacters = Utilities.base64Decode(splitBase[1]);
    var ss = Utilities.newBlob(byteCharacters, type);
    ss.setName(fileName);

    var dropbox = "Something"; // Folder Name
    var folder, folders = DriveApp.getFoldersByName(dropbox);

    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = DriveApp.createFolder(dropbox);
    }
    var file = folder.createFile(ss);

    return file.getName();
  }catch(e){
    return 'Error: ' + e.toString();
  }
}
'

форма.HTML-код

<head>
    <base target="_blank">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Focallocal Uploader</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css">
  <div align="center">
    <p><img src="http://news.focallocal.org/wp-content/uploads/2015/03/FOCALLOCAL-Website-Text-Header.png" width="80%"></p> 
  </div> 
</head>

<body>


  <div id="formcontainer" width="50%">

    <label for="myForm">Focallocal Community G.Drive Uploader</label>

  <br>

  <br>
    <form id="myForm" width="50%"> 
      <label for="myForm">Details</label>
      <div>
        <input type="text" name="Name" placeholder="your name">
      </div>
      <div>
        <input type="text" name="gathering" placeholder="which fabulous Positive Action you're sending us">
      </div>
      <div>
        <input type="text" name="location" placeholder="the town/village/city and country month brightend by positivity">
      </div>
      <div>
        <input type="text" name="date" placeholder="date of the beautiful action">
      </div>
      <div  width="100%" height="200px">

      <label for="fileText">would you like to leave a short quote?</label>

          <TEXTAREA name="Quote" 
          placeholder="many people would love to share in your experience. if you have more than a sentence or two to write, why not writing an article the Community News section of our website?"         
          ></TEXTAREA>


      </div> 
      <br>


      <br>

      <label for="myFile">Upload Your Files:</label>
      <br>


      <input type="file" name="filename" id="myFile" multiple>

      <input type="button" value="Submit" onclick="iteratorFileUpload();">



    </form>
  </div>

  <div id="output"></div>
<div id="progressbar">
    <div class="progress-label"></div>   


</div>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script>

var numUploads = {};
numUploads.done = 0;
numUploads.total = 0;

// Upload the files into a folder in drive
// This is set to send them all to one folder (specificed in the .gs file)
function iteratorFileUpload() {
    var allFiles = document.getElementById('myFile').files;

    if (allFiles.length == 0) {
        alert('No file selected!');
    } else {
        //Show Progress Bar

        numUploads.total = allFiles.length;
        $('#progressbar').progressbar({
        value : false
        });//.append("<div class='caption'>37%</div>");
        $(".progress-label").html('Preparing files for upload');
        // Send each file at a time
        for (var i = 0; i < allFiles.length; i++) {
            console.log(i);
            sendFileToDrive(allFiles[i]);
        }
    }
}

function sendFileToDrive(file) {
    var reader = new FileReader();
    reader.onload = function (e) {
        var content = reader.result;
        console.log('Sending ' + file.name);
        var currFolder = 'Something';
        google.script.run.withSuccessHandler(updateProgressbar).uploadFileToDrive(content, file.name, currFolder);
    }
    reader.readAsDataURL(file);
}

function updateProgressbar( idUpdate ){
   console.log('Received: ' + idUpdate);
   numUploads.done++;
   var porc = Math.ceil((numUploads.done / numUploads.total)*100);
   $("#progressbar").progressbar({value: porc });
   $(".progress-label").text(numUploads.done +'/'+ numUploads.total);
   if( numUploads.done == numUploads.total ){
      //uploadsFinished();
      numUploads.done = 0;
   };
}
</script>

  <script>
    function fileUploaded(status) {
      document.getElementById('myForm').style.display = 'none';
      document.getElementById('output').innerHTML = status;
    }

  </script>

  <style>
    body {
      max-width: 60%;
      padding: 20px;
      margin: auto;
    }
    input {
      display: inline-block;
      width: 50%;
      padding: 5px 0px 5px 5px;
      margin-bottom: 10px;
      -webkit-box-sizing: border-box;
      ‌​ -moz-box-sizing: border-box;
      box-sizing: border-box;
    }
    select {
      margin: 5px 0px 15px 0px;
    }
    input[type="submit"] {
      width: auto !important;
      display: block !important;
    }
    input[type="file"] {
      padding: 5px 0px 15px 0px !important;
    }
#progressbar{
    width: 40%;
    text-align: center;
    overflow: hidden;
    position: relative;
    vertical-align: middle;

}
.progress-label {
      float: left;
      margin-top: 5px;
      font-weight: bold;
      text-shadow: 1px 1px 0 #fff;
      width: 100%;
    height: 100%;
    position: absolute;
    vertical-align: middle;
    }
  </style>
</body>

i не удалось получить текстовые поля для отправки электронной почты с подробностями, и закончилось время, прежде чем разработать, как подключить их к электронной таблице Google, поэтому на данный момент они не записывают добавленную информацию

в качестве дополнительного бонуса это выглядело потрясающе с is в форме.HTML-код

      <div class="fixed-action-btn horizontal" style="bottom: 45px; right: 24px;">
      <a class="btn-floating btn-large red">
        <i class="large material-icons">menu</i>
      </a>
      <ul>
        <li><a class="btn-floating red"  href="https://focallocal-a-positive-action-movement.myshopify.com/" target="_blank" title="Pimp your Cool at the Positive Action Shop"><i class="material-icons">monetization_on</i></a></li>
        <li><a class="btn-floating blue"  href="https://www.youtube.com/user/Focallocal" target="_blank" title="Follow the Positive Action Youtube Channel"><i class="material-icons">video_library</i></a></li>
        <li><a class="btn-floating green" href="http://focallocal.org/" target="_blank" title="Read our About Us Page"><i class="material-icons">help</i></a></li>
      </ul>

   </div>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js"></script>
    <script src="https://gumroad.com/js/gumroad.js"></script>

я снова вытащил его, так как некоторые из вызываемых скриптов вызывали проблемы. если кто-то может исправить их, они добавляют много к внешнему виду и функциональности форма

*edit: я играл с ним, и только около половины отправленных файлов, похоже, поступают, поэтому все еще есть некоторые проблемы с обоими кодами здесь atm