I'm passing information from Google Sheets to a Document via Google Apps Script. All the information transfers with two exceptions...
The link of the picture shows rather than the image. How can I insert the image rather than the link?
In the folder it saves to, I get 2 versions of the document. One with the name I want, and another named 'Copy of Template'. I don't want the copy of the template, how can I either not create it, or delete it in the script?
Any help would be greatly appreciated.
function myFunction(e) {
var timestamp = e.values[0];
var studentName = e.values[1];
var firstName = e.values[2];
var studentNumber = e.values[3];
var dateOfBirth = e.values[4];
var studentImage = e.values[5];
var file = DriveApp.getFileById('fileId');
var folder = DriveApp.getFolderById('folderId')
var copy = file.makeCopy(studentName, folder);
var doc = DocumentApp.openById(copy.getId());
var body = doc.getBody();
body.replaceText('{{Time}}', timestamp);
body.replaceText('{{Name}}', studentName);
body.replaceText('{{Preferred Name}}', firstName);
body.replaceText('{{Student Number}}', studentNumber);
body.replaceText('{{DOB}}', dateOfBirth);
body.replaceText('{{Image}}', studentImage);
doc.saveAndClose();
}
The expected output is a document with relevant information, an image of the student, and only 1 version of the document in the folder.
I am unsure of why your code creates an extra copy of your file. This might be due to something else.
However, to change "{{image}}" to an image from an URL you can do this:
body.findText('{{Image}}').getElement().asParagraph()
.setText("") //Clears text
.appendInlineImage(UrlFetchApp.fetch(studentImage).getBlob()); //Adds image element from URL
Related
Im trying to .makecopy of a single tab or sheet from a spreadsheet with multiple tabs, Im able to make a copy of the entire sheet however this includes information the end user does not need to see.
I've seen some threads about creating a new spreadsheet within apps script then coping over the detail although formatting gets messy, I know there is a way to fix this but i'd like to know if there is a method as simple as the one i use currently to copy an entire sheet.
//Written like a true noob.
function Createcopy() {
//Base
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Review')
var date = sheet.getRange(1,3).getValue(); // Probably wont need.
//Folder detail
var folderid = '1iEILmAp3JiOTiPjFbDhv0bAfgu6AWhtd'
var Folder = "https://drive.google.com/drive/folders/"+folderid
Logger.log(folderid)
//Create copy
var title = sheet.getRange(1,4).getValue();
Logger.log(title)
var filename = title
var destFolder = DriveApp.getFolderById(folderid);
var createdcopy = DriveApp.getFileById(ss.getId()).makeCopy(filename, destFolder);
var url = createdcopy.getUrl()
Logger.log(url)
}
I believe your goal is as follows.
You want to copy the specific sheet in a Google Spreadsheet to a new Google Spreadsheet.
You want to put the new Spreadsheet in the specific folder.
You want to retrieve the URL of the new Spreadsheet.
Modification points:
As you say, your script copies the whole Spreadsheet.
In this case, I would like to propose the following flow.
Retrieve source sheet.
Copy the source sheet to a new Spreadsheet and remove the default empty sheet.
Move a new Spreadsheet to the destination folder.
Retrieve the URL of a new Spreadsheet.
When this flow is reflected in your script, it becomes as follows.
Modified script:
function Createcopy() {
var sheetName = 'Review'; // Please set the source sheet name.
var folderId = '###'; // Please set the destination folder ID.
// 1. Retrieve source sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var title = sheet.getRange(1, 4).getValue(); // New Spreadsheet title. This is from your script.
// 2. Copy source sheet to a new Spreadsheet and remove the default empty sheet.
var newSS = SpreadsheetApp.create(title);
sheet.copyTo(newSS).setName(sheetName);
newSS.deleteSheet(newSS.getSheets()[0]);
// 3. Move a new Spreadsheet to the destination folder.
var dstFolder = DriveApp.getFolderById(folderId);
DriveApp.getFileById(newSS.getId()).moveTo(dstFolder);
// 4. Retrieve URL of a new Spreadsheet.
var url = newSS.getUrl();
Logger.log(url)
}
When this script is run, the source sheet is copied to a new Spreadsheet. And, at a new Spreadsheet, the default empty sheet is removed. By this, a Spreadsheet including the specific sheet is obtained.
Note:
In this case, if the source sheet includes the formulas for loading the values from another sheet, an error occurs. Please be careful about this. And also, for example, when the source sheet includes the custom function, I think that the following script might be able to be used.
function Createcopy() {
var sheetName = 'Review'; // Please set the source sheet name.
var folderId = '###'; // Please set the destination folder ID.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var title = sheet.getRange(1, 4).getValue(); // New Spreadsheet title. This is from your script.
var dstFolder = DriveApp.getFolderById(folderId);
var newSSFile = DriveApp.getFileById(ss.getId()).makeCopy(title, dstFolder);
var newSS = SpreadsheetApp.open(newSSFile);
newSS.getSheets().forEach(s => {
if (s.getSheetName() != sheetName) newSS.deleteSheet(s);
});
var url = newSS.getUrl();
Logger.log(url)
}
References:
create(name)
copyTo(spreadsheet) of Class Sheet of Class SpreadsheetApp
I'm new to google script and I'm going crazy trying to do a simple tool.
I created a simple google form with just an email and a file uploader and I need just to insert an email and a pdf, and this should go to the recipient well HTML formatted and whit the pdf attached.
I'm new to this and I tried litterally every syntax using mailApp and Gmail app and the mail comes smooth but the pdf wont.
I know it's just a newbie stupid thing but I can't figure it out at my 74th attempt.
here's the code, I will be grateful forever with someone who can help me!
function sendPDF (e) {
var html = HtmlService.createTemplateFromFile("emailbolladireso.html");
var htmlText = html.evaluate().getContent();
var emailTo = e.response.getRespondentEmail();
var Subject = "---."
var textbody = "---."
var attach = e.response.getItemResponses();
var options = { htmlBody: htmlText};
if(emailTo !== undefined){
GmailApp.sendEmail(emailTo, Subject, textbody, options, )
attachments: attach[1];
}
}
First you have to get the id of your file wich is uploaded by your form to google drive.
You tried with:
var attach = e.response.getItemResponses();
But this will return you an array of objects with all your answers of your form.
From this object you have to extract the id of the uploaded PDF.
If you know the position, for example the first question in your form is for the pdf you can access it with attach[0] if it is e.g. in second position with attach[1], cause arrays index start with 0.
(You could look it also up with a for loop check for the name of the object.
attach[0].getItem().getTitle()
)
With attach[0] you get the next object and from this you get with attach[0].getResponse() finaly the id of your PDF.
attach[0].getResponse()
Now you "load" the file with the given id from google Drive (Make sure you have the permissions for access GoogleDrive)
var file = DriveApp.getFileById(attach[0].getResponse())
You can now attach your file (blob) to your attachments with the right MimeType
attachments: [file.getAs(MimeType.PDF)]
You should also place the attachments in the options of your email.
function sendPDF (e) {
var html = HtmlService.createTemplateFromFile("emailbolladireso.html");
var htmlText = html.evaluate().getContent();
var emailTo = e.response.getRespondentEmail();
var Subject = "Form with PDF"
var textbody = "Your PDF is attached."
var attach = e.response.getItemResponses();
var file = DriveApp.getFileById(attach[0].getResponse())
var options = { htmlBody: htmlText, attachments: [file.getAs(MimeType.PDF)]};
if(emailTo !== undefined){
GmailApp.sendEmail(emailTo, Subject, textbody, options);
}
}
Finaly it should work...
I tested it like this and it works for me.
DON'T PANIC!
Read also the docs -> https://developers.google.com/apps-script/reference/forms/item-response
[How to insert picture to google docs using the url link coming from google form response spreadsheet]
I need help, I have a google form that allow the user to upload their photo. My problem is, I have to link the google docs report to the url photo under the column [11] of the response spreadsheet.
here is my code
var Photo = e.values[11];
var templateFile = DriveApp.getFileById("link-of-docReport");
var templateResponseFolder = DriveApp.getFolderById("this-is-the-path-for-uploaded-photo");
var copy = templateFile.makeCopy(LastName + ", " + FirstName, templateResponseFolder);
var doc = DocumentApp.openById(copy.getId());
var body = doc.getBody();
body.replaceText("Photo", Photo);
Using replaceText will replace a string through another string - not through an actual photo
Instead you need to
find the placeholder as an element
find its parent
insert the picture into the parent
delete the placeholder element
Sample how to insert a file that it on your drive where the id is known:
var blob = DriveApp.getFileById("id").getBlob();
var body = doc.getBody();
var element = body.findText("Photo").getElement();
element.getParent().asParagraph().insertInlineImage(1, blob);
element.removeFromParent();
To extract the id from the url of a file on your drive, you nee to use regex, e.g. as done here.
I'm trying to code something that search for a PDF (gmail) with a serial number I already have, save it in Drive, get OCR on it and read the content.
No problem with the first step, and the second one is managed with the following code, but the last two lines to open the document with DocumentApp in order to getText(), are not working :
var serial = "123456789";
var ret = DriveApp.searchFiles('fullText contains "' + serial + '"');
if (ret.hasNext()) {
var file = ret.next();
var n_blob = Utilities.newBlob(file.getBlob().getDataAsString(), MimeType.PDF);
n_blob.setName(serial);
var n_file = DriveApp.createFile(n_blob);
var rt = DocumentApp.openById(n_file.getId()); **//not working**
var text = rt.getBody().getText(); **//not working**
}
I tried many differents ways, including the solution based on Drive.Files.insert() which is not working anymore..
I'm pretty stuck here, if anyone has any idea or suggestion to help me out?
Thanks
You want to convert a PDF file to Google Document file.
file of var file = ret.next(); is always PDF file.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification points:
Unfortunately, var n_blob = Utilities.newBlob(file.getBlob().getDataAsString(), MimeType.PDF) and var n_file = DriveApp.createFile(n_blob) cannot create Google Document. By this, an error occurs.
Pattern 1:
In this pattern, Drive.Files.copy is used for converting PDF to Google Document. Because in your question, I saw Drive.Files.insert() which is not working anymore.
Modified script:
Please modify your script as follows. Before you run the script, please enable Drive API at Advanced Google services.
From:
if (ret.hasNext()) {
var file = ret.next();
var n_blob = Utilities.newBlob(file.getBlob().getDataAsString(), MimeType.PDF);
n_blob.setName(serial);
var n_file = DriveApp.createFile(n_blob);
var rt = DocumentApp.openById(n_file.getId()); **//not working**
var text = rt.getBody().getText(); **//not working**
}
To:
if (ret.hasNext()) {
var file = ret.next();
if (file.getMimeType() === MimeType.PDF) {
var fileId = Drive.Files.copy({mimeType: MimeType.GOOGLE_DOCS}, file.getId()).id;
var rt = DocumentApp.openById(fileId);
var text = rt.getBody().getText();
Logger.log(text)
}
}
Pattern 2:
I thought that Drive.Files.insert might be able to be used. So in this pattern, I propose the modified script using Drive.Files.insert. Could you please test this?
Modified script:
Please modify your script as follows. Before you run the script, please enable Drive API at Advanced Google services.
From:
if (ret.hasNext()) {
var file = ret.next();
var n_blob = Utilities.newBlob(file.getBlob().getDataAsString(), MimeType.PDF);
n_blob.setName(serial);
var n_file = DriveApp.createFile(n_blob);
var rt = DocumentApp.openById(n_file.getId()); **//not working**
var text = rt.getBody().getText(); **//not working**
}
To:
if (ret.hasNext()) {
var file = ret.next();
if (file.getMimeType() === MimeType.PDF) {
var fileId = Drive.Files.insert({title: serial, mimeType: MimeType.GOOGLE_DOCS}, file.getBlob()).id;
var rt = DocumentApp.openById(fileId);
var text = rt.getBody().getText();
Logger.log(text)
}
}
Note:
Unfortunately, I cannot understand about Drive.Files.insert() which is not working anymore. So if above modified script didn't work, please tell me. I would like to think of other methods.
When you check the log, if you cannot see the texts of Google Document converted from PDF, it means that all files of var file = ret.next(); are not PDF type. Please be careful this.
References:
Advanced Google services
Files: copy
Files: insert
If I misunderstood your question and this was not the direction you want, I apologize.
I've been writing some javascript to fill in fields of a PDF form. I initially wrote the code in the "Action Wizard" in Adobe. I did not realize at the time that I was adding it to my local application, not the form itself. So I then copied it to a button on the from and now it is not working.
The code:
/* Test to read in a file and update the fields*/
var dataFrom = null;
//Grab the current path and update it to indicate the TempInfo location
var strPath = this.path;
strPath = strPath.slice(0,-12);
strPath = strPath + "TempInfo.txt"
//Get data from TempFile into array, display message if no file found
try{
var dataStream = util.readFileIntoStream(strPath);
var dataFrom = util.stringFromStream(dataStream);
}catch(e){
app.alert("Temp file not found");
}
//Put the data into an array and update the fields
var strTest = new Array();
strTest = dataFrom.split(/\n/);
getField("Username").value = strTest[0];
getField("UID").value = strTest[1];
//Clear the data
dataStream = null;
dataFrom = null;
strTest = null;
I am getting the app.alert "Temp file not found" so the "var dataStream = readFileInfoStream(strPath);" isn't reading in the file. I did app.alerts to verify the strPath variable has the right path and one to verify that dataStream is coming up null. Being that I copied it from the Action Wizard, I am unsure why its not working.
Just to make this a little odder (at least to me), if I open the JavaScript editor and highlight the code, it works fine.
For the util.readFileIntoStream method, when the cDIPath parameter is specified, the method can only be executed in a privileged context meaning during a batch, console event, or Action. It won't work when executed within the document context unless you create a Trusted Function.
Read this to understand how to executing privileged methods in a non-privileged context...
http://help.adobe.com/en_US/acrobat/acrobat_dc_sdk/2015/HTMLHelp/index.html#t=Acro12_MasterBook%2FJS_Dev_Contexts%2FExecuting_privileged_methods_in_a_non-privileged_context.htm&rhsearch=trusted%20function&rhsyns=%20