1

I'm trying to do 2 actions from Google Drive with Google Apps Scripts :

  1. Creating a file from a Google Doc template and insert data inside this file
  2. Doing an export of this Google Doc file to PDF file inside Google Drive (at the same)

Step 1 is working : the Google Docs file is correclty created with values updated inside it.

Step 2 : I have 2 questions/problems :

  1. The code I have found to generate PDF has been made to convert all Google Docs files to PDF files but from my side, I need just to export/convert the file which has been created (not all the files already located in the folder).
  2. Despite of point 1, the script is working and PDF is generated but when I open the PDF file, the values added inside it have been lost, I have only the tags present in the template.

Have you got some ideas?

Here is the code :

function replaceTags () {
 // Global vars
  var ui = DocumentApp.getUi ();
  var date = Utilities.formatDate(new Date(), "GMT", "dd-MM-yyyy");
  var folderOutId = 'xxxxxxxxxxxxxxxxxxxx';
  var tplMaintenanceId = 'xxxxxxxxxxxxxxxxxxxx';
  var fileOutName = 'my file name';
  var clientCompany = ui.prompt ('Company Name :');
  
  // Do a copy from template file to a new file inside a specific folder
  targetFolder = DriveApp.getFolderById (folderOutId);
  var documentId = DriveApp.getFileById (tplMaintenanceId). makeCopy (targetFolder). getId ();
      
  // Rename filed copied
  DriveApp.getFileById (documentId) .setName (fileOutName + ' - ' + clientCompany.getResponseText ());
      
  // Add document body inside variable
  var body = DocumentApp.openById (documentId) .getBody ();
    
  // Insert data inside Google Doc document
  body.replaceText ('##DATE##', date);
  body.replaceText ('##CLIENT_COMPANY##', clientCompany.getResponseText ());
  
  gdocToPDF(documentId);
}

function gdocToPDF(fileID) {
  var documentRootfolder = DriveApp.getFolderById("xxxxxxxxxxxxxxxxxxxx") // replace this with the ID of the folder that contains the documents you want to convert
  var pdfFolder = DriveApp.getFolderById("xxxxxxxxxxxxxxxxxxxx"); // replace this with the ID of the folder that the PDFs should be put in. 
  
  var docFile = DriveApp.getFileById(fileID)
  
  createPDF(docFile.getId(), pdfFolder.getId(), function (fileID, folderID) {
    if (fileID) createPDFfile(fileID, folderID);
  }
 )
}

function createPDF(fileID, folderID, callback) {
    var templateFile = DriveApp.getFileById(fileID);
    var templateName = templateFile.getName();
    
    var existingPDFs = DriveApp.getFolderById(folderID).getFiles();

    //in case no files exist
    if (!existingPDFs.hasNext()) {
        return callback(fileID, folderID);
    }

    for (; existingPDFs.hasNext();) {

        var existingPDFfile = existingPDFs.next();
        var existingPDFfileName = existingPDFfile.getName();
        if (existingPDFfileName == templateName + ".pdf") {
            Logger.log("PDF exists already. No PDF created")
            return callback();
        }
        if (!existingPDFs.hasNext()) {
            Logger.log("PDF is created")
            return callback(fileID, folderID)
        }
    }
}

function createPDFfile(fileID, folderID) {
    var templateFile = DriveApp.getFileById(fileID);
    var folder = DriveApp.getFolderById(folderID);
    var theBlob = templateFile.getBlob().getAs('application/pdf');
    var newPDFFile = folder.createFile(theBlob);

    var fileName = templateFile.getName().replace(".", ""); //otherwise filename will be shortened after full stop    
    newPDFFile.setName(fileName + ".pdf");
}
TooNetCreation
  • 159
  • 1
  • 3
  • 17

1 Answers1

3

I tried recreating your code and I converted a doc to pdf successfully.

What you can do to is to edit your gdocToPDF() function to accept only the document that you want to be converted to PDF. Please see below sample code(might not be exactly the way you want it):

Pass the document id used in replaceTags() function to gdocToPDF()

function replaceTags () {
 ....
 .... 
  DocumentApp.openById(documentId).saveAndClose()
  gdocToPDF(documentId);
}

Instead of fetching all the files in a drive folder, use this code instead to use the file with replaced tags only

function gdocToPDF(fileID) { 
  var documentRootfolder = DriveApp.getFolderById(folder-id) // replace this with the ID of the folder that contains the documents you want to convert
  var pdfFolder = DriveApp.getFolderById(folder-id); // replace this with the ID of the folder that the PDFs should be put in. 
  
  var docFile = DriveApp.getFileById(fileID)
  
  createPDF(docFile.getId(), pdfFolder.getId(), function (fileID, folderID) {
    if (fileID) createPDFfile(fileID, folderID);
  }
 )
}

This will make a doc to pdf conversion to the only document that you wanted to be converted.

Have a great day ahead!

Jason E.
  • 1,201
  • 1
  • 3
  • 10
  • I have just a strange issue, inside the PDF file generated the values added inside it have been lost, I have only the tags present in the template. – TooNetCreation Nov 26 '20 at 17:03
  • Is your PDF existing already? Some part of the code do not allow you to overwrite the PDF file if it is already created. – Jason E. Nov 26 '20 at 17:10
  • No, PDF does not exist. at the beginning, there is just an empty Google Docs file template with some tags inside, see here: https://prnt.sc/vqozso , then I launch the App Script code where tags will be replaced by values, see here : https://prnt.sc/vqp0ul and at the end, the PDF file is generated but values are missing, see here : https://prnt.sc/vqp1v0 . But I don't understand why the new Google Docs file is correctly generated with values and PDF no. – TooNetCreation Nov 26 '20 at 17:16
  • I see. I've edited my answer. Please let me know if that solves it. Basically, I just made it sure that we will use the same document that we replace the tags with. – Jason E. Nov 26 '20 at 17:30
  • OK I did it but I get this error : ReferenceError: fileID is not defined (ligne 53, fichier "Code") – TooNetCreation Nov 26 '20 at 18:14
  • Can you try it again this time? I mistyped the capitalization of the variable fileID which should only be fileId. – Jason E. Nov 26 '20 at 18:52
  • I did it and same problem : Exception: Argument non valide : id (ligne 53, fichier "Code") – TooNetCreation Nov 26 '20 at 19:08
  • line 53 is this one : var docFile = DriveApp.getFileById(fileId) – TooNetCreation Nov 26 '20 at 19:09
  • It is a bit weird because the code is working fine on my end. Can you make sure that all fileID variables are in sync with regards to its capitalization? – Jason E. Nov 26 '20 at 19:19
  • yes I have verified and same problem :-/ .. I did a copy paste of your code. – TooNetCreation Nov 26 '20 at 19:28
  • I always have this message : Exception: Argument non valide : id (ligne 53, fichier "Code")I – TooNetCreation Nov 26 '20 at 19:30
  • OK works fine for PDF generated, I get the correct file name but values inside PDF files are lost. – TooNetCreation Nov 26 '20 at 19:35
  • Can you update your code in your post so I can recheck again? Thank you – Jason E. Nov 26 '20 at 19:39
  • OK done, I have replaced the code in my first post. – TooNetCreation Nov 26 '20 at 20:05
  • @TooNetCreation. Upon checking further, it seems that the state of the document being converted as PDF is the original one. To solve this, you need to use saveAndClose to the document to be converted to save the changes/replacement of tags. Please see edited answer. – Jason E. Nov 27 '20 at 10:25
  • sorry another question, if you have an idea : how can I het the file ID of the new google doc generated? because if you look at the code, the script is running from the doc template inside google template gallery and not from the new Gdoc file created. – TooNetCreation Nov 27 '20 at 13:33
  • You can use DocumentApp.create("docname") to create a new google doc and then copy the content of the template to your newly created google doc. You can refer here: https://stackoverflow.com/questions/19349641/how-to-copy-a-template-and-insert-content-from-another-document for the copying from the template. Does this answer your question? :) – Jason E. Nov 27 '20 at 13:39
  • .saveAndClose() saved me so much headache! Thanks!!! – Yeti Jun 27 '22 at 12:38