Adding page number in every page of pdf using google apps script - google-apps-script

var doc = DocumentApp.create("Text");
var body = doc.getBody();
doc.addHeader().appendParagraph("This is a header");
body.appendParagraph('text');
function addTable("dynamicTable parameters",doc);
var footer = doc.addFooter();
var table = footer.appendTable();
var tr = table.appendTableRow();
var count = 1;
var td = tr.appendTableCell();
td.appendParagraph('this is a document.');
td.setWidth(203);
var td1 = tr.appendTableCell();
td1.setWidth(260);
var table1x2 = td1.appendTable();
var tr1x2 = table1x2.appendTableRow();
tr1x2.appendTableCell("Document Type")
.appendParagraph("").appendText("Notes");
tr1x2.appendTableCell("Author")
.appendParagraph("").appendText("Text");
var table1x4 = td1.appendTable();
var tr1x4 = table1x4.appendTableRow();
tr1x4.appendTableCell("Document No.")
.appendParagraph("").appendText(count++);
var date = Utilities.formatDate(new Date(), "GMT"+5.5, "dd-MM-yyyy");
tr1x4.appendTableCell("Date")
.appendParagraph("").appendText(date);
tr1x4.appendTableCell("Volume No.");
tr1x4.appendTableCell("Page No.")
.appendParagraph("").appendText(PageNo);
The above is sample code I am using to generate footer in every page of pdf.I am trying to add page no in the last code shown above. But unable to increment it dynamically. Is there a way I can display the current page in the page No. column.Kindly let me know if there is any other way I can add page no while converting doc to pdf or any work around is also accepted.

Related

How can I use a variable as a parameter in getSheetByName?

I have the following code which generates some gslides slides from data in a spreadsheet. The code is attached to the gslides file and it works when the parameters for link/year are entered as strings. However, these parameters will sometimes vary from a set list (e.g. pull from a different sheet or from a different file) so the code sometimes needs to be edited.
I want to share this with colleagues who don't know how to use app scripts and so tried to edit it so that the link/year can be pulled from a textbox in one of the slides in the gslides file. They are pulling through ok but when I try to use it as a parameter I get an error for line 11 (var values = sheet.getRange('F2:aa2').getValues();) as the sheet returns as null.
I've tried wrapping it in quotes (" ' " + year + " ' ") but that doesn't work either.
Please let me know if I need to include more info or a link to the sheets/slides files.
function generateStarters() {
var deck = SlidesApp.getActivePresentation();
var slides = deck.getSlides();
var link = slides[2].getPageElements()[2].asShape().getText().asString()
var year = slides[2].getPageElements()[4].asShape().getText().asString()
var dataSpreadsheetUrl = link
var ss = SpreadsheetApp.openByUrl(dataSpreadsheetUrl);
var sheet = ss.getSheetByName(year);
var values = sheet.getRange('F2:aa2').getValues();
var templateSlide = slides[1];
var presLength = slides.length;
values.forEach(function(page){
if(page[0]){
var Q1 = page[0];
var A1 = page[1];
var Q2 = page[4];
var A2 = page[5];
var Q3 = page[8];
var A3 = page[9];
var Q4 = page[12];
var A4 = page[13];
var QK = page[16];
var AK = page[17];
var QF = page[20];
var AF = page[21];
templateSlide.duplicate(); //duplicate the template page
slides = deck.getSlides(); //update the slides array for indexes and length
newSlide = slides[3]; // declare the new page to update
var shapes = (newSlide.getShapes());
shapes.forEach(function(shape){
shape.getText().replaceAllText('{{q1}}',Q1);
shape.getText().replaceAllText('{{a1}}',A1);
shape.getText().replaceAllText('{{q2}}',Q2);
shape.getText().replaceAllText('{{a2}}',A2);
shape.getText().replaceAllText('{{q3}}',Q3);
shape.getText().replaceAllText('{{a3}}',A3);
shape.getText().replaceAllText('{{q4}}',Q4);
shape.getText().replaceAllText('{{a4}}',A4);
shape.getText().replaceAllText('{{qk}}',QK);
shape.getText().replaceAllText('{{ak}}',AK);
shape.getText().replaceAllText('{{qf}}',QF);
shape.getText().replaceAllText('{{af}}',AF);
});
presLength = slides.length;
newSlide.move(presLength);
}
});
} ```
The string from the slides file seems to always have a space at the end (from the textbox) so I just needed to add an extra line of code to remove that space.

I am unable to automate the population of footers in google docs

I am trying to automate the population of the footer of a google doc that I have with the values that a pop up dialogue gathers from the users when they open the document. The code that I am using can be seen below, however it only works with the footer of the first page, when and only when I activate the option "Different first page". If I de-activate it (because I want the footer to be consistent within the whole document) nothing changes (not even the first page of the document) when I run the script.
The footer looks like this:
Blablbla / ##value1##
Title: “##value2##” - blablabla
The script to substitute value1 and value2 looks like this:
function myFunction() {
// Display a dialog box for each field you need information for.
var ui = DocumentApp.getUi();
var value1Response = ui.prompt('Enter the value1');
var value2Response = ui.prompt('Enter the value2');
var date = new Date();
//Make a copy of the template file
var documentId = DriveApp.getFileById('google document Id').makeCopy().getId();
//Rename the copied file
DriveApp.getFileById(documentId).setName(value2Response.getResponseText() + date);
//Get the document footer as a variable
var footer = DocumentApp.openById(documentId).getFooter();
footer.replaceText('##value1##', value1Response.getResponseText());
footer.replaceText('##value2##', value2Response.getResponseText());
}
This works for me.
function myFunction() {
var doc=DocumentApp.getActiveDocument();
var ui = DocumentApp.getUi();
var value1Response = ui.prompt('Enter the value1');
var value2Response = ui.prompt('Enter the value2');
var value3Response = ui.prompt('Enter FileName');
var date = new Date();
var documentId = doc.getId();
var footer = doc.getFooter();
footer.replaceText('##value1##', value1Response.getResponseText());
footer.replaceText('##value2##', value2Response.getResponseText());
var doc=DocumentApp.openById("Doc Id");
var footer=doc.getFooter();
doc.setName(value3Response.getResponseText());
footer.replaceText('##value1##', value1Response.getResponseText());
footer.replaceText('##value2##', value2Response.getResponseText());
}

How to extract the url from a cell Spreadsheet to string and use DocumentApp.openByUrl

In a Spreadsheet cell I have a link to a Google doc and I want to recuperate it in order to open the Google Doc and modify it. So in my cell I've put this format https://docs.google.com/document/d/1Gb48I...... (without the /edit in the end) and I've tried
var body = '=HYPERLINK("'data[n][COLUMN_URL-1]'+'/edit'")'.getBody();
var body = '=HYPERLINK("'data[n][COLUMN_URL-1]'+'/edit'")'.getBody();
// this one works but I want to use data[n][COLUMN_URL-1] because I have several Google Docs links
var body = DocumentApp.openByUrl('https://docs.google.com/document/d/1Gb48IXos......../edit').getBody();
if(body){
//edit the Google doc
If you have ideas what to do thank you because with the concatenation of the /edit(3rd line of code) it works
Edit: The cell is not formatted(hyperlinked)/formula i have only the https://...
Edit 2: I've tried with a code from Suhail Ansari thank you but I have an error that the document is missing and I don't have nothing for the logs if you have others ideas:
var COLUMN_URL = 10 ;
function getIdFrom(url) {
var id = "";
var parts = url.split(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
if (url.indexOf('?id=') >= 0){
id = (parts[6].split("=")[1]).replace("&usp","");
return id;
} else {
id = parts[5].split("/");
//Using sort to get the id as it is the longest element.
var sortArr = id.sort(function(a,b){return b.length - a.length});
id = sortArr[0];
return id;
}
}
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
var numRows = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();
var data = sheet.getRange(1,1,numRows,lastColumn).getDisplayValues();
for(n=1;n < data.length;n++) {
var URL =data[n][COLUMN_URL-1];
Logger.log('The URL ',URL);
var id = getIdFrom(URL);
Logger.log('The ID ',id);
var body = DocumentApp.openById(id).getBody();
if(body)
{......//edit Google Doc
This is the 10 column with the URLs from the Google Docs
In fact I have docs.google.com/open?id=1qo0B_HCbjcBrYyJ ... as URL for the others rows I tried to do by hand for 3rd one as you can see in the picture
Edit 3: So I am very confused in this moment because the column I have in the spreadsheet commes from a loop where I put the URL of the Google Docs in the cell like this : var trange = sheet.getRange.. trange.setValue(doc.getUrl()); and now if i look at the table i have the links in this format
https://docs.google.com/open?id=1RYRVotAq6IOz5tys1krnENfgN_pU0KYuUzR24i
so now if i want to get back the Google Doc I have the following :
// var body = DocumentApp.openByUrl('https://docs.google.com/open?id=1Xb4QjiWwpn2TJ8-9kkIhU6m1rgmb48g6xYVopN').getBody();
//var body = DocumentApp.openByUrl('https://docs.google.com/1Xb4QjiWwpn2TJ8-9kkIhU6m1rgmb48g6xYVopN/edit').getBody();
var body = DocumentApp.openByUrl('https://docs.google.com/document/d/1Xb4QjiWwpn2TJ8-9kkIhU6m1rgmb48g6xYVopN/edit').getBody();
only the 3rd one works.Where I am doing wrong? Because I want to
for(n=1;n < data.length;n++) {... make a loop for and var URL =
data[n][COLUMN_URL-1];
You could add some code for getting the Doc ID from the URL and then open the doc by using
DocumentApp.openById(id);
Here is a link to do that.
A sample code below with help from the above linked answer:
function myFunction() {
var URL = SpreadsheetApp.getActiveSheet().getRange('A1').getValue();
var id = getIdFrom(URL);
var doc = DocumentApp.openById(id);
var body = doc.getBody();
Logger.log(body.getText());
}
function getIdFrom(url) {
var id = "";
var parts = url.split(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
if (url.indexOf('?id=') >= 0){
id = (parts[6].split("=")[1]).replace("&usp","");
return id;
} else {
id = parts[5].split("/");
//Using sort to get the id as it is the longest element.
var sortArr = id.sort(function(a,b){return b.length - a.length});
id = sortArr[0];
return id;
}
}
Demo Google Sheet

Directly Update Doc Template from Form

Is it possible to submit a form and update a Doc template from the form contents? The only way I have seen for doing anything similar was submitting the form to a spreadsheet and having an onFormsubmit function within the spreadsheet update the template.
Is this not possible via forms and a container bound script?
Thanks
yes it's possible, but it's not easy (essentially using doc as template, there is no evident tools for that)
I have initially gotten this to work replacing a few lines in my document template, but now nothing is working for some reason. I did edit the text in the template at one point so I am not sure if that changes the file ID. It creates the copy, but the replaceText is not working. Code attached:
`function onFormSubmit(e) {
var dt = Utilities.formatDate(new Date(), 'GMT', "MM/dd/yyyy")
var submitter = Session.getActiveUser().getEmail();
var copyDoc = DriveApp.getFileById('1t5r8IxLgunJ17J2tXkHfw3LRfuXQeTlP5MZURC-23e0').makeCopy('tmpAddress').getId();
var newDoc = DocumentApp.openById(copyDoc);
var body = newDoc.getBody();
var itemResponse = e.response;
var name = itemResponse.getItemResponses()[0].getResponse();
var email = itemResponse.getItemResponses()[1].getResponse();
var pphone = itemResponse.getItemResponses()[2].getResponse();
var paddress = itemResponse.getItemResponses()[3].getResponse();
var palot = itemResponse.getItemResponses()[4].getResponse();
var pcity = itemResponse.getItemResponses()[5].getResponse();
var pstate = itemResponse.getItemResponses()[6].getResponse();
var pzip = itemResponse.getItemResponses()[7].getResponse();
var nphone = itemResponse.getItemResponses()[8].getResponse();
var naddress = itemResponse.getItemResponses()[9].getResponse();
var nalot = itemResponse.getItemResponses()[10].getResponse();
var ncity = itemResponse.getItemResponses()[11].getResponse();
var nstate = itemResponse.getItemResponses()[12].getResponse();
var nzip = itemResponse.getItemResponses()[13].getResponse();
body.replaceText('#{name}', name);
body.replaceText('#{email}', email);
body.replaceText('#{pphone}', pphone);
body.replaceText('#{paddress}', paddress);
body.replaceText('#{palot}', palot);
body.replaceText('#{pcity}', pcity);
body.replaceText('#{pstate}', pstate);
body.replaceText('#{pzip}', pzip);
body.replaceText('#{nphone}', nphone);
body.replaceText('#{naddress}', naddress);
body.replaceText('#{nalot}', nalot);
body.replaceText('#{ncity}', ncity);
body.replaceText('#{nstate}', nstate);
body.replaceText('#{nzip}', nzip);
body.replaceText('#{dt}', dt)
body.replaceText('#{submitter}',submitter)
newDoc.saveAndClose();
}
`

Google Script Error - Cannot find method add

I have been puzzled by this error. I have not been able to figure out what I am missing. Without the calls to headPanel the UI was working but would not insert the title or text label so I added the Horizontal panel in hopes of adding the text, but alas error. Please help me with this problem and I need to know what I am messing up.
function doGet(e){
var app = UiApp.createApplication();
var headPanel = app.createHorizontalPanel().setId('headPanel');
var header = app.setTitle('Detention Attendance');
var label = app.createLabel("Please enter attendance for Detention by clicking the checkbox next to the student's name if they were present. Then click Sumbit.");
headPanel.add(header); //* ERROR OCCURS HERE
headPanel.add(label);
app.add(pane);
var panel = app.createVerticalPanel();
var flexTable = app.createFlexTable().setStyleAttribute('border', '2px solid black')
.setStyleAttribute('borderCollapse','collapse')
.setBorderWidth(2);
//Get Data from spreadsheet
var spreadsheetId = 'xxxxxxxxxxxxxxxxxxxxxxxx';//Change it to your Spreadsheet ID
var dataArray = getData(spreadsheetId);
//Load data into table cells
Logger.log(dataArray);
for (var row = 0; row<dataArray.length; row++){
if (row > 0) {
var ticketDate = dataArray[row] [0];
var dateStamp = Utilities.formatDate(ticketDate, "America/Chicago", "MM/dd/yyyy");
Logger.log("dateStamp = " +dateStamp);
dataArray[row] [0] = dateStamp;
var ticketDate2 = dataArray[row] [16];
var dateStamp2 = Utilities.formatDate(ticketDate2, "America/Chicago", "MM/dd/yyyy");
dataArray[row] [16] = dateStamp2;
Logger.log("DateStamp = " +dateStamp2);
}
flexTable.setStyleAttribute("color", "purple").setText(row, 2, dataArray[row][2].toString()).setWidth('300px');
flexTable.setText(row, 0, dataArray[row][0].toString()).setWidth('600px');
flexTable.setText(row, 4, dataArray[row][16].toString()).setWidth('300px');
}
panel.add(flexTable);
app.add(panel);
return app;
}
function getData(spreadsheetId){
var ss = SpreadsheetApp.openById(spreadsheetId);
var sheet = ss.getSheets()[0].getDataRange();
Logger.log(sheet);
return sheet.getValues();
}
Your header var is a UiInstance - in fact it's the same instance as app, returned as a convenience for chaining by the call to .setTitle().
The .add() method is looking for a Widget as a parameter, and not finding it.
You don't need to keep that header var - it's only causing you trouble. In fact, you could set the Title as you create the UiApp instance:
var app = UiApp.createApplication().setTitle('Detention Attendance');