Join drive button and input: file for local files - google-drive-api

So: how can I use the drive button: https://developers.google.com/drive/v3/web/savetodrive and load a selected local file from an input: file so that I can save it in the cloud?
I understand that the button loads a file that is hosted on another host by putting its url in the button, but I need to save a local file, and from "input: file" put it in "data-url" or where it is correct to upload the file (images in my case)
<!DOCTYPE html>
<html>
<head>
<title>Save to Drive Demo: Explicit Render</title>
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<form id="GDrive"
name="GDrive"
enctype="multipart/form-data"
method="post">
<input type="file"
onChange="renderSaveToDrive('savetodrive-div', this.files[0].name,'GDrive');">
<div id="savetodrive-div"></div>
</form>
<script>
function renderSaveToDrive(namediv, namefile, idfrm) {
console.log('namediv: ' + namediv + ' nameFile: ' + namefile);
window.___gcfg = {
lang: 'es-ES',
parsetags: 'explicit'
};
var xhr = new XMLHttpRequest();
var fd = new FormData(document.forms.namedItem(idfrm));
fd.append("file_new_name", namefile);
xhr.open("POST", location.href);
xhr.send(fd);
gapi.savetodrive.render(namediv, {
src: namefile,
filename: namefile,
sitename: 'GDrive Demo: Explicit Render'
});
}
</script>
</body>
</html>

Related

Convert Remote HTML tempalte to PDF in django

I am trying to convert HTML(hosted on a remote server) to pdf and then save in the Django model.
what I tried till now.
def convert_html_to_pdf(template, context, filename):
response = requests.get(template)
template = Template(response.content)
html = template.render(Context(context))
f = NamedTemporaryFile()
f.name = '/' + user + '/' + str(filename)
pdf = pisa.pisaDocument(BytesIO(template.encode('UTF-8')), f)
if not pdf.err:
return File(f)
return False
file = pdf_docs.convert_html_to_pdf(
template='https://www.example.com/sample.html',
context={'name': 'John Smith'},
filename='example.pdf',
)
In response, only the template URL is printed on PDF, not the content.
Javascript has a function called print. You can use the print method to convert the HTML to PDF. Here, is the code snippet to convert HTML to PDF. In addition, you can hide the text elements in JS before converting the HTML to pdf so that you will only get the template printed.
<html>
<head>
<title>Convert HTML to PDF</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$("#btnPrint").live("click", function () {
var divContents = $("#dvContainer").html();
var printWindow = window.open('', '', 'height=400,width=800');
printWindow.document.write('<html><head><title>DIV Contents</title>');
printWindow.document.write('</head><body >');
printWindow.document.write(divContents);
printWindow.document.write('</body></html>');
printWindow.document.close();
printWindow.print();
});
</script>
</head>
<body>
<form id="form1">
<div id="dvContainer">
This content needs to be printed.
</div>
<input type="button" value="Print Div Contents" id="btnPrint" />
</form>
</body>
</html>

Uploading An Image With Google Apps Script To A GSheet - Passing Values To And From HTML Service Modal Dialog

I'm trying to trigger a file upload off of a Google Sheet, taking the uploaded file, add it to a Google Drive folder, and then return the URL of the uploaded file and place it in a cell on the Sheet. I'm currently triggering the file upload by using a checkbox. Once you set the checkbox to TRUE, it'll pop up a dialog box with a file upload input field. This is triggered by an installed onEdit function. Also, info on the row in the sheet will be used to name the newly uploaded file. This info will be input manually on the sheet.
I get to the showModalDialog line, and the dialog box comes up just fine, but I can't figure out how to pass variables from the original function to the HTML service and then back again (with the file) to upload to Drive, set the name, and put the URL back on the sheet.
Here's the first function in Code.gs, receiving values from the onEdit function:
function addFile(ss,ui,row,total) { \\Triggered if edited cell is in column 25 & value is TRUE
Logger.log('add file function');
var name = ss.getRange(row,1).getDisplayValue();
var date = ss.getRange(row,3).getDisplayValue();
var filename = 'Row ' + row + ' - ' + name + ' - ' + date + ' - ' + total;
var htmlTemp = HtmlService.createTemplateFromFile('Index');
htmlTemp.fName = filename;
htmlTemp.position = row;
var html = htmlTemp.evaluate().setHeight(76).setWidth(415);
ui.showModalDialog(html, 'Upload');
Logger.log('end of add file function');
}
And here's what's in Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_center">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<form>
Please upload image below.<br /><br />
<input type="file" name="upload" id="file" accept="image/*,.pdf" />
<input type="button" value="Submit" class="action" onclick="formData(this.parentNode)" />
<input type="button" value="Close" onclick="google.script.host.close()" />
</form>
<script>
function formData(obj){
var newFileName = <? fName ?>;
var rowNum = <? position ?>;
google.script.run.withSuccessHandler(closeIt).upload(obj,newFileName,rowNum);
}
function closeIt(e){
console.log(e);
google.script.host.close();
};
</script>
</body>
</html>
And here's the return function on Code.gs:
function upload(obj,newFileName,rowNum) {
Logger.log('upload function');
var upFile = DriveApp.getFolderById('[folderid]').createFile(obj).setName(newFileName);
var fileUrl = upFile.getUrl();
Logger.log(fileUrl);
var urlCell = SpreadsheetApp.getSheetByName('sheet name').getRange(rowNum,26);
urlCell.setValue('=HYPERLINK("' + fileUrl + '","View image")');
}
Running this code, the dialog box comes up just fine, and I'm able to select a file for upload. However, clicking the Submit button does nothing, and the box stays up until I X it out or hit the Cancel button. The logs only get so far as 'end of add file function' and never gets to the upload function. Should the google.script.run.withSuccessHandler line close the dialog box, or is something else needed to confirm / get the file and close the box?
I've been searching online and have found a number of posts relating to this, but none seem to address this specific issue. This is also pretty much a frankenstein of code I've cobbled together from those posts, so it's possible there's just something that doesn't belong in there and if that is the case I do apologize. Any help would be appreciated; thanks!
[Edit: the submit button wasn't opening a separate tab because I was using <input type="button"> instead of <button>.]
According to the documentation [1] in the “Parameters and return values” part,
if you’re going to send the form object as a parameter “it must be the function’s only parameter”. So you should send the parameters inside the form, using inputs of types “hidden” or “text”, then, from code.gs you can retrieve the input data of the Form object.
Another thing stated in the documentation [1] in the “form” section, is that you need to disable the default submit action with preventFormSubmit function.
Another problem is that the correct way of printing the variables passed to the template are using <?= ?> instead of <? ?> which works to execute code but not to print variables. [2]
Your “addFile” function is all right. Below is the code i've tested on my environment and I was able to upload an image successfully and print the url in the sheet.
Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_center">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
</head>
<body>
<form id="myForm">
Please upload image below.<br /><br />
<input type="hidden" name="fname" id="fname" value="<?= fName ?>"/>
<input type="hidden" name="position" id="position" value="<?= position ?>"/>
<input type="file" name="file" id="file" accept="image/jpeg,.pdf" />
<input type="button" value="Submit" class="action" onclick="formData(this.parentNode)" />
<input type="button" value="Close" onclick="google.script.host.close()" />
</form>
<script>
//Disable the default submit action using “func1”
window.onload=func1;
function func1() {
document.getElementById('myForm').addEventListener('submit', function(event) {
event.preventDefault();
});
}
function formData(obj){
google.script.run.withSuccessHandler(closeIt).upload(obj);
}
function closeIt(e){
console.log(e);
google.script.host.close();
};
</script>
</body>
</html>
Code.gs (upload function):
function upload(obj) {
//Retrieve the input data of the Form object.
var newFileName = obj.fname;
var rowNum = obj.position;
var blob = obj.file;
var upFile = DriveApp.getFolderById('[folderid]').createFile(blob).setName(newFileName);
var fileUrl = upFile.getUrl();
var urlCell = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1').getRange(rowNum,5);
urlCell.setValue('=HYPERLINK("' + fileUrl + '","View image")');
}
[1] https://developers.google.com/apps-script/guides/html/communication
[2] https://developers.google.com/apps-script/guides/html/templates

How to add file upload to spreadsheet as custom menu option?

I want to make a spreadsheet CMS - that is to read/write data from firebase and vice versa. I reached a point where I need to upload files directly from the spreadsheet and not any other page.
I have added a custom menu with a htmlService to output a template where the user may click and upload a file and that file must get handled in google script, but the problem is that I'm getting only the fake path of a file "c:/fakepath/avatar.png" and not a blob.
my files in google script:
upload.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<div>
<div id="progress" ></div>
<input type="file" name="upload" id="file">
<input type="submit" value="Submit" class="action" onclick="form_data()" >
<input type="button" value="Close" onclick="google.script.host.close()" />
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
function form_data(){
var values = [{
"file":$("#upload").val(),
}];
google.script.run.withSuccessHandler(closeIt).upload(values);
};
function closeIt(){
google.script.host.close()
};
</script>
</body>
</html>
test.gs
function upload(values){
//Display the values submitted from the dialog box in the Logger.
Logger.log(values); // here I'm getting file = c/fakepath/avatar.png while I
//need the file to send it as a post request or save it in google drive
};
I believe I should use FileReader but I have tried and failed:
var file,
reader = new FileReader();
// Upload the file to Google Drive
reader.onloadend = function(e) {
google.script.run
.upload(
e.target.result, file.name
);
};
function form_data(){
reader.readAsDataURL(file);
}
You want to upload a file using a dialog box on Google Docs to Google Drive.
If my understanding is correct, how about this modification? Please think of this as just one of several answers.
Modified script:
Google Apps Script:
function upload(obj) {
var file = DriveApp.createFile(obj.upload);
return {
fileId: file.getId(),
mimeType: file.getMimeType(),
fileName: file.getName(),
};
}
HTML:
Please replace <body>...</body> as follows. In this modification, jquery is not used.
<body>
<form> <!-- Modified -->
<div id="progress" ></div>
<input type="file" name="upload" id="file">
<input type="button" value="Submit" class="action" onclick="form_data(this.parentNode)" >
<input type="button" value="Close" onclick="google.script.host.close()" />
</form>
<script>
function form_data(obj){ // Modified
google.script.run.withSuccessHandler(closeIt).upload(obj);
};
function closeIt(e){ // Modified
console.log(e);
google.script.host.close();
};
</script>
</body>
Note:
When you uploaded a file, the file ID, mimeType and filename of the created file are returned. You can see them on the console.
In this method, because blob is used, the maximum file size is 50 MB. Please be careful this.
If I misunderstood your question and this was not the result you want, I apologize.

Uploading csv file with Google Scripts via HTML Service - Illegal Value in property 0 [duplicate]

This question already has answers here:
Google Forms file upload complete example
(2 answers)
Closed 5 years ago.
I'm trying to create an interface to display a csv using Google script. However, whenever I load the file I get this error
`1729820382-mae_html_user_bin_i18n_mae_html_user.js:39 Uncaught TypeError: Failed due to illegal value in property: 0
at Td (1729820382-mae_html_user_bin_i18n_mae_html_user.js:39)
at Pd (1729820382-mae_html_user_bin_i18n_mae_html_user.js:39)
at 1729820382-mae_html_user_bin_i18n_mae_html_user.js:6
at 1729820382-mae_html_user_bin_i18n_mae_html_user.js:21
at Object.fileToCsv (1729820382-mae_html_user_bin_i18n_mae_html_user.js:38)
at loadFile (<anonymous>:10:23)
at HTMLInputElement.onchange (VM1402 userCodeAppPanel:1)`
The console log is showing the file correctly, but it seems to be tripping up when it tries to pass it to the Google script. Do I need a special file reader?
HTML is here
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<input type="text" id="itemHolder" name="itemHolder" style="display:none"/>
<input type="file" id="myFile" name="myFile" onchange="loadFile(event)"/>
<p id="textStuff"></p>
</body>
</html>
<script type="text/javascript">
function loadFile(event) {
var input = event.target.files[0];
console.log(input)
google.script.run.fileToCsv(input);
}
function printout(array){
console.log("Try")
var spot = document.getElementById('textStuff');
spot.innerHTML = array;
}
</script>`
GAS Here
function fileToCsv(myFile){
var strData = myFile.getBlob().getDataAsString();
Logger.log(strData);
return strData;
//return CSVToArray( strData )
}
You need to pass the entire form object to code.gs file. Refer the below code.
HTML
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="testForm">
<input type="text" id="itemHolder" name="itemHolder" style="display:none"/>
<input type="file" id="myFile" name="myFile" onchange="loadFile(event)" accept=".csv"/>
<p id="textStuff"></p>
</form>
</body>
</html>
<script type="text/javascript">
function loadFile(event) {
var inputData = event
google.script.run.withSuccessHandler(printout).fileToCsv(document.getElementById("testForm"));
}
function printout(array){
var spot = document.getElementById('textStuff');
spot.innerHTML = array;
}
</script>
Code.gs
function fileToCsv(form){
var fileData = form.myFile
return fileData.getBlob().getDataAsString()
}

Google drive save to not working (Google drive api)

I am trying to make a website that will save a cat into the account of the user and have tried this:
<script src="https://apis.google.com/js/platform.js"></script>
<div class="g-savetodrive"
data-src="http://example.com/pug-snores.mp3"
data-filename="pug-snores.mp3"
data-sitename="A Snoring Pug">
</div>
The save icon shows up but it does not save to the drive.
Why?
Thanks
try the explicit render: code from the google javascript api
<!DOCTYPE html>
<html>
<head>
<title>Save to Drive Demo: Explicit Render</title>
<link rel="canonical" href="http://www.example.com">
<script src="https://apis.google.com/js/platform.js">
{parsetags: 'explicit'}
</script>
</head>
<body>
Render the Save to Drive button
<div id="savetodrive-div"></div>
<script>
function renderSaveToDrive() {
gapi.savetodrive.render('savetodrive-div', {
src: '//example.com/path/to/myfile.pdf',
filename: 'My Statement.pdf',
sitename: 'My Company Name'
});
}
document.getElementById('render-link').addEventListener('click', renderSaveToDrive);
</script>
</body>
</html>
The data-src URL can be served from another domain but the responses from the HTTP server needs to support HTTP OPTION requests and include the following special HTTP headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Range
Access-Control-Expose-Headers: Cache-Control, Content-Encoding, Content-Range
If you want upload a local file with input file form and/or without php lib would be ...
<!DOCTYPE html>
<html>
<head>
<title>Save to Drive Demo: Explicit Render</title>
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<form id="GDrive" name="GDrive" enctype="multipart/form-data" method = "post">
<input type="file" id="file" name="file" onChange="renderSaveToDrive('savetodrive-div', this.files[0].name,'GDrive');"><div id="savetodrive-div"></div>
</form>
<script>
function renderSaveToDrive(namediv, namefile, idfrm) {
window.___gcfg = {
lang: 'es-ES',
parsetags: 'explicit'
};
var xhr = new XMLHttpRequest();
var fd = new FormData(document.forms.namedItem(idfrm));
fd.append("file_new_name", namefile);
xhr.open("POST", location.href);
xhr.send(fd);
gapi.savetodrive.render(namediv, {
src: namefile,
filename: namefile,
sitename: 'GDrive Demo: Explicit Render'
});
}
</script>
</body>
</html>