I have created a a google app script that create a pdf from a google sheet and send it via email.
I have three script that work perfectly. But with the fourth script (identical to the other)I lost always the authorization after about one - two hours.
Has someone the same problem?
Thanks
Pasquale
Attached code. I use a trigger to lunch code every time the form is submitted.
// When Form Gets submitted
function onFormSubmit(e) {
var docTemplate = "1mI4SQQe4muuW386jgzkxBlZBWuH0OBRdbz1hItOPjK4";
var docName = "DDT";
var ss = SpreadsheetApp.openById("1HzZFDJYAU6H1pptqcA5fEAVelkZw1LP7si9bBrsF_u0")
var sheet = ss.getSheets()[0];
var lastrow = ss.getLastRow();
var d = new Date ();
var id ="0B1-7TPSHWZ1bMlNLTV9tTFJNb2c"; // cartella Raccolta DDT
var folder = DriveApp.getFolderById(id);
//Get information from form and set as variables
//var email = "pasquale.martucci#decathlon.com";
var email = e.values[1];
var mittente = e.values[2];
var destinatario = e.values[3];
var primaQnt = e.values[4];
var primaDescr = e.values[5];
var secondaQnt = e.values[6];
var secondaDescr = e.values[7];
var terzaQnt = e.values[8];
var terzaDescr = e.values[9];
var quartaQnt = e.values[10];
var quartaDescr = e.values[11];
var quintaQnt = e.values[12];
var quintaDescr = e.values[13];
var aspetto = e.values[14];
var colli = e.values[15];
var peso = e.values[16];
var vettore = e.values[17];
// Ricava indirizzi e città
var cell1 = sheet.getRange("S"+lastrow);
cell1.setFormula("=VLOOKUP(C"+lastrow+";Foglio2!A1:C35;2;FALSE)");
var indirMitt = cell1.getValue()
var cell2 = sheet.getRange("T"+lastrow);
cell2.setFormula("=VLOOKUP(C"+lastrow+";Foglio2!A1:C35;3;FALSE)");
var citMitt = cell2.getValue()
var cell3 = sheet.getRange("U"+lastrow);
cell3.setFormula("=VLOOKUP(D"+lastrow+";Foglio2!A1:C35;2;FALSE)");
var indirDest = cell3.getValue()
var cell4 = sheet.getRange("V"+lastrow);
cell4.setFormula("=VLOOKUP(D"+lastrow+";Foglio2!A1:C35;3;FALSE)");
var citDest = cell4.getValue()
//Ricava data
var day = sheet.getRange("W"+lastrow);
day.setFormula("=(DAY(A"+lastrow+"))");
var month = sheet.getRange("X"+lastrow);
month.setFormula("=(MONTH(A"+lastrow+"))");
var year = sheet.getRange("Y"+lastrow);
year.setFormula("=(YEAR(A"+lastrow+"))");
var day1 = sheet.getRange("W"+lastrow).getValue();
var month1 = sheet.getRange("X"+lastrow).getValue();
var year1 = sheet.getRange("Y"+lastrow).getValue();
var data = day1+"/"+month1+"/"+year1;
// Get document template, copy it as a new temp doc, and save the Doc’s id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName+' N° '+lastrow+' ' +mittente , folder)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document’s body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyMittente', mittente);
copyBody.replaceText('keyDestinatario', destinatario);
copyBody.replaceText('keyQNT1', primaQnt);
copyBody.replaceText('keyDescrizione1', primaDescr);
copyBody.replaceText('keyQNT2', secondaQnt);
copyBody.replaceText('keyDescrizione2',secondaDescr);
copyBody.replaceText('keyQNT3', terzaQnt);
copyBody.replaceText('keyDescrizione3', terzaDescr);
copyBody.replaceText('keyQNT4', quartaQnt);
copyBody.replaceText('keyDescrizione4', quartaDescr);
copyBody.replaceText('keyQNT5', quintaQnt);
copyBody.replaceText('keyDescrizione5', quintaDescr);
copyBody.replaceText('keyAspetto', aspetto);
copyBody.replaceText('keyKg', peso);
copyBody.replaceText('keyColli', colli);
copyBody.replaceText('keyVettore', vettore);
copyBody.replaceText('keyIndirMitt', indirMitt);
copyBody.replaceText('keyCitMitt', citMitt);
copyBody.replaceText('keyIndirDest', indirDest);
copyBody.replaceText('keyCitDest', citDest);
copyBody.replaceText('keyNum', lastrow);
copyBody.replaceText('keyData', data);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "DDT";
var body = "In allegato il DDT generato tramite il portale SimplyCar.";
GmailApp.sendEmail(email, subject, body, {htmlBody: body, attachments: pdf});
// Delete temp file
// DriveApp.getFileById(copyId).setTrashed(true);
}
Related
I need to update a file automatically that already has data in it.
The document is filled with an SQL data base thanks to the code below
However, I want it to update itself everyday without deleting any data that are already in the document and only adding new ones (don't want any duplicates).
function readData(db, queryString) {
//connect to the database
var server = 'your-servername-OR-serverPublicIpAddress';
var username = 'your-sql-username';
var password = 'your-password';
var dbUrl = 'jdbc:sqlserver://' + server + ':1433;databaseName=' + db;
var conn = Jdbc.getConnection(dbUrl, username, password );
//query the data
var stmt = conn.createStatement();
var exec_query = stmt.executeQuery(queryString);
var metaData = exec_query.getMetaData();
var numCols = metaData.getColumnCount();
//save query data to an array
var result=[]; //initiate a blank array
//save the column header
header = []; //initiate the header row
for (var col = 0; col < numCols; col++) {
header.push(metaData.getColumnName(col + 1)); //add the name of each column to the header row
};
result.push(header);//after the header row is formed, put it to the result array
//save the data of each row
while (exec_query.next()) {
row_data = [];
for (var col = 0; col < numCols; col++) {
row_data.push(exec_query.getString(col + 1));//add data of each column to the row data
//Logger.log(row_data);
};
result.push(row_data); // add row data to result
//Logger.log(result);
};
exec_query.close();
return result
};
function pushDataToGoogleSheet(data, SheetName) {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheetByName(SheetName));
var lastRow = sheet.getLastRow();
sheet.getRange(lastRow+1, 1, data.length, data[0].length).setValues(data);
sheet.getDataRange().removeDuplicates();
};
function main() {
db = 'YOUR_DATABASE_NAME'
SQLquery = 'YOUR_SQL_QUERY'
raw_statistics = readData(db, SQLquery); //get raw statistics
pushDataToGoogleSheet(raw_statistics, 'YOUR_SHEET_NAME'); //push to google sheet
};
function main() {
db = 'YOUR_DATABASE_NAME'
SQLquery = 'YOUR_SQL_QUERY'
raw_statistics = readData(db, SQLquery); //get raw statistics
pushDataToGoogleSheet(raw_statistics, 'YOUR_SHEET_NAME'); //push to google sheet
};
However, in the pushDataToGoogleSheet it says that it can't define the length. So, I don't know if I put the right thing for data or not or if there is an issue in my code...
Do you have an idea ?
Thank you for your help !
Link to original question where I found the below script: How to batch-copy range with Google Sheets Api
Question: How do I modify the below to write into a different spreadsheetId? I've Googled everything I can and can only find examples where the copyPaste occurs within the same SpreadsheetID.
function Test_Copy() {
var spreadsheetId = "1hLXq9zq-tAaGpPtGiY6859h4oKxIbNimxCHPPZOzdE0";
var sheetId = "1792457718";
var sheetIdd = "760382355";
var rangeFrom = Sheets.newGridRange();
rangeFrom.sheetId = sheetId;
rangeFrom.startRowIndex = 0;
rangeFrom.endRowIndex = 23637;
rangeFrom.startColumnIndex = 0;
rangeFrom.endColumnIndex = 23;
var rangeTo = Sheets.newGridRange();
rangeTo.sheetId = sheetIdd;
rangeTo.startRowIndex = 0;
rangeTo.endRowIndex = 23637;
rangeTo.startColumnIndex = 0;
rangeTo.endColumnIndex = 23;
var copyPasteRequest = Sheets.newCopyPasteRequest();
copyPasteRequest.destination = rangeTo;
copyPasteRequest.source = rangeFrom;
copyPasteRequest.pasteType = "PASTE_VALUES";
copyPasteRequest.pasteOrientation = "NORMAL";
var resource = Sheets.newBatchUpdateSpreadsheetRequest();
//Create request object
var request = Sheets.newRequest();
request.copyPaste = copyPasteRequest;
resource.requests = [request];
var res = Sheets.Spreadsheets.batchUpdate(resource , spreadsheetId);
//Logger.log(res.replies);
//Logger.log(res.spreadsheetId);
}
Sorry that this is so similar to a recent post but I can't find the solution anywhere. I have created a simple script that loops through each artboard in an open illustrator document and exports it as a separate PNG file. All is working well except that I want to set the resolution to 150 dpi and not the default 72 dpi, for production reasons. This is an option that you can set when exporting manually to PNG but I don't seem to be able to set it in the PNG options in the code, although the script runs without errors it ignores the resolution setting. Could someone let me know how to do this, many thanks. Code as follows:
var doc = app.activeDocument;;//Gets the active document
var fileName = doc.name.slice(0, 9);//Gets the G Number
var numArtboards = doc.artboards.length;//returns the number of artboards in the document
var filePath = (app.activeDocument.fullName.parent.fsName).toString().replace(/\\/g, '/');
var options = new ExportOptionsPNG24();
for (var i = 0; i < numArtboards; i++ ) {
doc.artboards.setActiveArtboardIndex( i );
options.artBoardClipping = true;
options.matte = false;
options.horizontalScale = 100;
options.verticalScale = 100;
options.transparency = true;
var artboardName = doc.artboards[i].name;
//$.writeln("artboardName= ", artboardName);
var destFile = new File(filePath + "/" + fileName + " " + artboardName + ".png");
//$.writeln("destFile= ",destFile);
doc.exportFile(destFile,ExportType.PNG24,options);
}
After doing some digging I've found that if you use imageCapture you can set the resolutuion. So new script below. thanks to CarlosCanto for providing this link via the Adobe Forum https://forums.adobe.com/message/9075307#9075307
var doc = app.activeDocument;;//Gets the active document
var fileName = doc.name.slice(0, 9);//Gets the G Number
var numArtboards = doc.artboards.length;//returns the number of artboards in the document
var filePath = (app.activeDocument.fullName.parent.fsName).toString().replace(/\\/g, '/');
var options = new ImageCaptureOptions();
for (var i = 0; i < numArtboards; i++) {
doc.artboards.setActiveArtboardIndex(i);
var activeAB = doc.artboards[doc.artboards.getActiveArtboardIndex()];
options.artBoardClipping = true;
options.resolution = 150;
options.antiAliasing = true;
options.matte = false;
options.horizontalScale = 100;
options.verticalScale = 100;
options.transparency = true;
var artboardName = doc.artboards[i].name;
var destFile = new File(filePath + "/" + fileName + " " + artboardName + ".png");
doc.imageCapture(destFile, activeAB.artboardRect, options);
}
I'm trying to setup a gradebook, I would like to loop through the list of students in a sheet that has various vlookups to create an individual mark sheet. I would then like to make a pdf for each of the students. I keep hitting a timeout on the server requests after about 6 students. An error message reports "returned code 429."
I thought I had it working but it would just create a pdf for each student with the first student's information and name. I've tried various code snippets found around the internet but those also time out due to the number of requests.
function PrintReport() {
SpreadsheetApp.getActiveSpreadsheet().toast('Writing the reports.','Printing Reports');
var email = Session.getActiveUser().getEmail();
var TodayDate = new Date();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ClassName = ss.getName()
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
var StudentList = ss.getSheetByName('Mark Sheet');
var StudentCount = StudentList.getRange("A2").getValue();
var SLData = StudentList.getRange(7,1,StudentCount).getValues();
var ReportSheet = ss.getSheetByName('Student Report');
var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=false' // orientation, false for landscape
+ '&fitw=true&source=labnol' // fit to page width, false for actual size
+ '&sheetnames=False&printtitle=True' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid='; // the sheet's Id
var token = ScriptApp.getOAuthToken();
var blobs = [];
var sheetID = ss.getSheetByName('Student Report').getSheetId();
var url_base = ss.getUrl().replace(/edit/,'');
for (var i = 0; i < StudentCount; i++){
ReportSheet.setActiveSelection("B1").setValue(SLData[i][0].toString());
SpreadsheetApp.flush();
var response = UrlFetchApp.fetch(url + url_ext + sheetID, {
headers: {'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob and store in our array
blobs[i] = response.getBlob().setName(SLData[i][0] + '.pdf');
}
ReportSheet.setActiveSelection("B1").setValue(SLData[0][0]);
//create new blob that is a zip file containing our blob array
var zipBlob = Utilities.zip(blobs).setName(ClassName+': Student Reports'+'.zip');
var subject = ClassName+ ": Individual Reports";
var body = "How to print multiple files: Just select all the items you wish to print in Finder and tap Command-P (or choose File>Print). If your system can print those items, it will.";
// If allowed to send emails, send the email with the PDF attachment
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments:[zipBlob]
});
SpreadsheetApp.getActiveSpreadsheet().toast('Reports are all done, please check you email.','Reports',5);
}
It is supposed to create a zipped file of pdfs with the student's names. When the zip is downloaded and extracted, the pdfs contain the mark break down for each student.
If I move the "response" code outside the loop, it produces multiple PDFs with just one student's data.
UPDATE
Modified to the code below but now it makes a pdf for each student but everyone has the last student's information (mark and name).
function PrintReport() {
SpreadsheetApp.getActiveSpreadsheet().toast('Writing the reports.','Printing Reports');
var email = Session.getActiveUser().getEmail();
var TodayDate = new Date();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ClassName = ss.getName();
var StudentList = ss.getSheetByName('Mark Sheet');
var StudentCount = StudentList.getRange("A2").getValue();
var SLData = StudentList.getRange(7,1,StudentCount).getValues();
var ReportSheet = ss.getSheetByName('Student Report');
var sheetID = ss.getSheetByName('Student Report').getSheetId();
var blobs = [];
hideAllSheetsExcept('Student Report');
for (var i = 0; i < StudentCount; i++){
ReportSheet.setActiveSelection("B1").setValue(SLData[i][0].toString());
SpreadsheetApp.flush();
//convert the response to a blob and store in array
blobs.push(ss.getBlob().getAs('application/pdf').setName(SLData[i][0] + '.pdf'));
//creates a pdf of the last student's information for everyone!
}
ReportSheet.setActiveSelection("B1").setValue(SLData[0][0]);
//create new blob that is a zip file containing our blob array
var zipBlob = Utilities.zip(blobs).setName(ClassName+': Student Reports'+'.zip');
var subject = ClassName+ ": Individual Reports";
var body = "How to print multiple files: Just select all the items you wish to print in Finder and tap Command-P (or choose File>Print). If your system can print those items, it will.";
// If allowed to send emails, send the email with the PDF attachment
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments:[zipBlob]
});
SpreadsheetApp.getActiveSpreadsheet().toast('Reports are all done, please check you email.','Reports',5);
UnHideEverything();
}
I added a try catch in a while loop and a timeout. Works perfectly
So nest your response like this:
var theurl = 'https://docs.google.com/a/mydomain.org/spreadsheets/d/'
+ ssID
+ '/export?exportFormat=pdf&format=pdf'
+ '&size=A4'
+ '&portrait=true'
+ '&fitw=true'
+ '&top_margin=0.50'
+ '&bottom_margin=0.50'
+ '&left_margin=0.50'
+ '&right_margin=0.50'
+ '&sheetnames=false&printtitle=false'
+ '&pagenum=false'
+ '&gridlines=false'
+ '&fzr=FALSE'
+ '&gid='
+ GID;
var response
var done = false
while (!done){
try{
response = UrlFetchApp.fetch(theurl, params)
done = true
} catch (e) {
console.log(e)
done = false
Utilities.sleep(10000)
}
}
I got the problem generating csv file based on the section. I currently using LinqToCsv dll to generate the file. How do I generate the file by section. Please help. Thanks.
Currenly I have 3 section
Header Section
Detail Section
Footer Section
Here my codes.
TTMSEntities DB = new TTMSEntities();
CsvFileDescription outputFileDescription = new CsvFileDescription();
outputFileDescription.NoSeparatorChar = false;
outputFileDescription.FirstLineHasColumnNames = true;
outputFileDescription.FileCultureName = "en-US";
List<HeaderRec> list1 = new List<HeaderRec>();
HeaderRec header = new HeaderRec();
header.RecordType = "";
header.RetailerID = "";
header.FileDate = "";
header.FileSequence = "";
header.LastTransRef = "";
list1.Add(header);
var Data = (from p in DB.TT_TNG_KFC_TRANSACTION_UPLOAD
select new DetailRec
{
RecordType = "D",
TransIDType ="AA"
});
List<FooterRec> list2 = new List<FooterRec>();
FooterRec footer = new FooterRec();
footer.RecordType = "T";
footer.TotalAmount = "100";
list2.Add(footer);
CsvContext cc = new CsvContext();
cc.Write(Data, "TestData.csv", outputFileDescription);
How to I concat the List ?