Загрузка файла сценария Google Apps, сохранение в Google Sheets, отправка формы без файла - PullRequest
1 голос
/ 17 апреля 2020

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

Что работает? 1. Следующий код принимает данные пользователя и сохраняет их в листе Google. Однако загрузка файла не работает 2. Если я удаляю «function iteratorFileUpload ()» и запускаю «function UploadFile ()» при событии «onclick» кнопки ввода типа ввода, то загрузка отдельного файла работает, однако в этом сценарии форма отправки без загрузки файла не работает. 3. Я также пытался загрузить несколько файлов, но он тоже не работает.

code.gs

var emailTo= "******@gmail.com"
var REDIRECT_URL = "https://script.google.com/macros/s/*******/dev";


function doGet() {
  var ssheet_url = "https://docs.google.com/spreadsheets/d/1NNW0cx-9niPDwkNmQXWdY0KjXnP0Ihjo0ZoIM6ckkDM/edit#gid=0";
  var ss = SpreadsheetApp.openByUrl(ssheet_url);
  var ws = ss.getSheetByName("Inputs")
  var mylistTransactionType = ws.getRange(2,1,ws.getRange("A2").getDataRegion().getLastRow(),1).getValues();
  var mylistWhoRecieved = ws.getRange(2,2,ws.getRange("B2").getDataRegion().getLastRow(),1).getValues();
  var mylistTransactionProfile = ws.getRange(2,3,ws.getRange("B2").getDataRegion().getLastRow(),1).getValues();
  var mylistSourceOfFund = ws.getRange(2,4,ws.getRange("B2").getDataRegion().getLastRow(),1).getValues();


  var htmlmylistTransactionTypeArray = mylistTransactionType.map(function(r){ return '<option>' + r[0] + '</option>'; }).join('');
  var htmlmylistWhoRecievedArray = mylistWhoRecieved.map(function(r){ return '<option>' + r[0] + '</option>'; }).join('');
  var htmlmylistTransactionProfileArray = mylistTransactionProfile.map(function(r){ return '<option>' + r[0] + '</option>'; }).join('');
  var htmlmylistmylistSourceOfFundArray = mylistSourceOfFund.map(function(r){ return '<option>' + r[0] + '</option>'; }).join('');


  //return HtmlService.createHtmlOutputFromFile('InputForm.html');
  var tmp = HtmlService.createTemplateFromFile("index");
  tmp.title = "Transaction Record Web APP";
  //tmp.mylist1 = mylist1.map(function(r){ return r[0]; });
  tmp.mylistTransactionType = htmlmylistTransactionTypeArray;
  tmp.mylistWhoRecieved = htmlmylistWhoRecievedArray;
  tmp.mylistTransactionProfile = htmlmylistTransactionProfileArray;
  tmp.mylistSourceOfFund = htmlmylistmylistSourceOfFundArray;


  return tmp.evaluate().addMetaTag('viewport', 'width=device-width, initial-scale=1');


}


function include(filename){
  return HtmlService.createHtmlOutputFromFile(filename).getContent();

}

function doPost(e) {

 try {
    var data = e.parameter.fileContent;
    var filename = e.parameter.filename;
    var email = e.parameter.Transcation_Profile;
    var name = e.parameter.Who_Recieved_Paid;
    var result=uploadFileToGoogleDrive(data,filename,name,email,e);
    return redirect();

   // ContentService    // return json success results
         // .createTextOutput(
           // JSON.stringify({"result":"success",
                          //  "data": JSON.stringify(result) }))
          //.setMimeType(ContentService.MimeType.JSON);
  } catch(error) { return redirect(); // if error return this
   // Logger.log(error);
    //return ContentService
          //.createTextOutput(JSON.stringify({"result":"error", "error": error}))
          //.setMimeType(ContentService.MimeType.JSON);
  } return redirect();

}

function redirect() {
  return HtmlService.createHtmlOutput(
    "<script>window.top.location.href=\"" + REDIRECT_URL + "\";</script>"
  ); 
}

// new property service GLOBAL
var SCRIPT_PROP = PropertiesService.getScriptProperties();
// see: https://developers.google.com/apps-script/reference/properties/

/**
 * select the sheet
 */
//function setup() {
//    var doc = SpreadsheetApp.getActiveSpreadsheet();
//    SCRIPT_PROP.setProperty("key", doc.getId());
//}

/**
 * record_data inserts the data received from the html form submission
 * e is the data received from the POST
 */

function record_data(e,fileUrl) {
  try {
//    var doc     = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var doc     = SpreadsheetApp.openById("1NNW0cx-9niPDwkNmQXWdY0KjXnP0Ihjo0ZoIM6ckkDM");


    var sheet   = doc.getSheetByName('responses'); // select the responses sheet

    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row     = [ new Date() ]; // first element in the row should always be a timestamp
    // loop through the header columns
    for (var i = 1; i < headers.length; i++) { // start at 1 to avoid Timestamp column

      if(headers[i].length > 0 && headers[i] == "Invoice") {
        row.push(fileUrl); // add data to row
      }
      else if(headers[i].length > 0) {
        row.push(e.parameter[headers[i]]); // add data to row
      }
    }
    // more efficient to set values as [][] array than individually
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
  }
  catch(error) {
    Logger.log(e);
  }
  finally {
    return;
  }

}

function uploadFileToGoogleDrive(data, file, name, email,e) {
  try {
    var dropbox = "Demo";
    var folder, folders = DriveApp.getFoldersByName(dropbox);

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

    var contentType = data.substring(5,data.indexOf(';')),
        bytes = Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)),
        blob = Utilities.newBlob(bytes, contentType, file);
        var file = folder.createFolder([name, email].join("-")).createFile(blob);

        var fileUrl=file.getUrl();

        //Generating Email Body
        var html =  
    '<body>' + 
      '<h2> New Job Application </h2>' +
        '<p>Name : '+e.parameters.name+'</p>' +
        '<p>Email : '+e.parameters.email+'</p>' +
        '<p>Contact : '+e.parameters.contact+'</p>' +
        '<p>Skill Sets : '+e.parameters.skillsets+'</p>' +
        '<p>LinkedIn Url : '+e.parameters.linkedinUrl+'</p>' +
        '<p>File Name  : '+e.parameters.filename+'</p>' +
        '<p><a href='+file.getUrl()+'>Resume Link</a></p><br />' +
    '</body>';

    record_data(e,fileUrl);

    MailApp.sendEmail(emailTo, "New Job Application Recieved","New Job Application Request Recieved",{htmlBody:html});
        return file.getUrl();
  } catch (f) {
    return ContentService    // return json success results
          .createTextOutput(
            JSON.stringify({"result":"file upload failed",
                            "data": JSON.stringify(f) }))
          .setMimeType(ContentService.MimeType.JSON);
  }
}

index. html

<html>
  <head>
    <base target="_top">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">

     <?!= include("page-css"); ?>   

  </head>

  <!--<body onload="addList()">  Modified -->
  <body>

<div class="container">

    <blockquote>
     <h5><?= title; ?></h5>
    </blockquote>



        <form id="uploadForm" action="https://script.google.com/macros/s/AKfycbxZeCebav4lkFNiMrOFa9PYaWTMkT4LA7-xHqMOc_k74BDWlyEB/exec" method="POST">
        <input type="hidden" value="" name="fileContent" id="fileContent">
        <input type="hidden" value="" name="filename" id="filename">
   <div class="row">
      <div class="input-field col s6">
        <i class="material-icons prefix">face</i>

        <input list="dropdownList1" name="Who_Recieved_Paid" placeholder="Who Recieved or Paid" required> <!-- Modified -->
            <datalist id="dropdownList1"> 
             <?!= mylistWhoRecieved; ?>

          </datalist>        


        <!--<input required type="text" value="" name="Who_Recieved_Paid" id="Who_Recieved_Paid" class="validate">        

        <label class="active" for="Who_Recieved_Paid"> Who Recieved or Paid : </label> -->
      </div>


      <div class="input-field col s6">   
        <i class="material-icons prefix">business</i> 
        <input list="dropdownList2" name="Transaction_Type" placeholder="Transaction Type" required> <!-- Modified -->
            <datalist id="dropdownList2"> 
             <?!= mylistTransactionType; ?>

          </datalist>

      </div>      

   </div><!-- First Row Form -->

   <div class="row">
      <div class="input-field col s6"> 
        <i class="material-icons prefix">account_balance</i>

        <input list="dropdownList3" name="Source_of_Fund" placeholder="Source of Fund" required> <!-- Modified -->
            <datalist id="dropdownList3"> 
             <?!= mylistSourceOfFund; ?>

          </datalist>        

        <!-- <input required type="text" value="" name="Source_of_Fund" id="Source_of_Fund" class="validate">
        <label class="active" for="Source_of_Fund"> Source of Fund : </label> -->
      </div>  

      <div class="input-field col s6">                   
        <i class="material-icons prefix">attach_money</i>
        <input required type="text" value="" name="Amount" id="Amount" class="validate">
        <label class="active" for="Amount"> Amount :</label> 
      </div>
   </div><!-- 2nd Row Form -->

   <div class="row">
      <div class="input-field col s6">            
        <i class="material-icons prefix">menu</i>

        <input list="dropdownList4" name="Transcation_Profile" placeholder="Transcation Profile" required> <!-- Modified -->
            <datalist id="dropdownList4"> 
             <?!= mylistTransactionProfile; ?>

          </datalist>                

        <!--<input required type="text" value="" name="Transcation_Profile" id="Transcation_Profile" class="validate">
        <label class="active" for="Transcation_Profile"> Transcation Profile :</label>  -->
      </div>




        <div class="input-field col s6">      
          <input id="prefDate" type="text" class="datepicker">
          <label for="prefDate" >Transaction Date</label>
        </div><!-- Close Date -->


   </div><!-- 3rd Row Form -->   


     <div class="row">


      <div class="input-field col s12">         
        <i class="material-icons prefix">chat_bubble</i>
        <input type="text" value="" name="Remarks" id="Remarks" class="validate"> 
        <label class="active" for="Remarks"> Remarks :</label>
      </div>


      </div><!-- 4th Row Form -->   

</form>


   <div class="row">
      <div class="input-field col s6"> 
        <script type="text/javascript" src="//code.jquery.com/jquery-1.10.2.min.js"></script>
        <div class="file-upload">
          <div class="file-select">
            <div class="file-select-button" id="fileName">Choose File</div>
            <div class="file-select-name" id="noFile">No file chosen...</div> 
            <input type="file" name="attach" id="attach">

          </div>
        </div>
      </div>

   </div><!-- 5th Row Form -->  


   <div class="row">
<!--<input required id="attach" name="attach" type="file"/> -->

      <div class="input-field col s6"> 
        <input value="Submit" type="button" class="btn orange darken-2" onclick="iteratorFileUpload()" />
      </div>

   </div><!-- 6th Row Form -->   

</div><!-- Close Container -->


  <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>  
  <?!= include("page-js"); ?>  
  </body>
</html>

page- js. html

На этой странице у меня есть все сценарии java. Вышеупомянутые функции здесь.

<script>


          //Date Picker Initialization
          var datePicker = document.getElementById('prefDate');
          M.Datepicker.init(datePicker,{
          showClearBtn:true,          
          });


    function iteratorFileUpload() {
        var allFiles = document.getElementById('attach').files;

    if (allFiles.length == 0) {
        document.getElementById('uploadForm').submit();
            } else {

    // Send each file one at a time
    var i=0;
    for (i=0; i < allFiles.total; i+=1) {
      console.log('This iteration: ' + i);
      UploadFile(allFiles[i]);
          };
        };
      };



function UploadFile(file) {
  var reader = new FileReader();
  //var file = document.getElementById('attach').files[0];


  reader.onload = function(){


    document.getElementById('fileContent').value=reader.result;
    document.getElementById('filename').value=file.name;
    document.getElementById('uploadForm').submit();
  }
  reader.readAsDataURL(file);



}



$('#attach').bind('change', function () {
  var filename = $("#attach").val();
  if (/^\s*$/.test(filename)) {
    $(".file-upload").removeClass('active');
    $("#noFile").text("No file chosen..."); 
  }
  else {
    $(".file-upload").addClass('active');
    $("#noFile").text(filename.replace("C:\\fakepath\\", "")); 
  }
});


</script>

ps - я новичок во всем этом, и это мое первое приложение. Я собрал образцы кодов с SO, YouTube и других сайтов и сделал некоторые модификации. У меня есть некоторый предыдущий опыт работы с VBA, но только основы. Так что, пожалуйста, ожидайте глупых ошибок.

...