[Sheets] Création de PDF en automatique lié à une liste déroulante

Bonjour,

Voici ma problématique ou mon souhait :

J'ai une liste déroulante dans un sheet "feuille1" en "A8" qui change les valeurs de plusieurs cellules de ma feuille (A4) et je souhaite enregistrer au format PDF à la chaîne, toutes les valeurs de ma liste déroulante dans un dossier spécifique sur mon drive et je souhaite que le nom du fichier soit : valeur-de-la-liste_date.pdf

En gros ma liste déroulante contient 60 entrées différentes (nom prénom) et je souhaite créer 60 PDF (A4) avec les données de chaque nom prénom

C'est quelque chose de compliqué à coder ?... existe t-il quelque chose que je pourrais adapter à mon besoin ?

Un grand merci encore pour votre aide ! ;)

silentman

RE-

On va commencer par la fin et le plus complexe : enregistrer une feuille en pdf !

  1. Avec google, tout se passe en ligne, avec des URLs attribuées par google, y compris pour les documents pdf qu'il faudra raccrocher au compte courant.
  2. Et comme tout est sécurisé, il faudra aussi obtenir une autorisation (un jeton) qui est faisable par macro.

Bon yapuka, cela va me prendre quand même un peu de temps de mise au point mais on doit pouvoir trouver des exemples.

Ensuite, il "suffira" de balayer tous les noms de la liste

Ok merci !!

J'ai trouvé ça, est-ce que ça peut t'aider ?

function printpdf(){

var id = SpreadsheetApp.getActiveSpreadsheet().getId();
     var sheetName = getConfig(SHEET_NAME_CELL);
     var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);

     if (!dataSheet) {
       Browser.msgBox("Can't find sheet named:" + sheetName);
       return;
     }

     var dataSheetIndex = dataSheet.getSheetId();

    //this is three level authorization 
     var oauthConfig = UrlFetchApp.addOAuthService("google");
     oauthConfig.setAccessTokenUrl(
     oauthConfig.setRequestTokenUrl(
     oauthConfig.setAuthorizationUrl(
     oauthConfig.setConsumerKey("anonymous");
     oauthConfig.setConsumerSecret("anonymous");

     //even better code
     //oauthConfig.setConsumerKey(ScriptProperties.getProperty("consumerKey"));
     //oauthConfig.setConsumerSecret(ScriptProperties.getProperty("consumerSecret"));

     var requestData = {
       "method": "GET",
       "oAuthServiceName": "google",
       "oAuthUseToken": "always"
     };

     var url = "lien internet du sheet =" + id +  "&gid=" + dataSheetIndex + "&fitw=true&size=A4&portrait=true&sheetnames=false&printtitle=false&exportFormat=pdf&format=pdf&gridlines=false";

     //Save File to Google Drive 
     var seplogoBlob = UrlFetchApp.fetch(url, requestData).getBlob().setName("Filename.pdf");
     DocsList.createFile(seplogoBlob);

}

J'ai pas le droit d'envoyer de liens encore...

image

je ne comprends pas ceci

     var sheetName = getConfig(SHEET_NAME_CELL);

j'ai donc testé juste les premières lignes et effectivement cela me donne une erreur !

Du reste, ce n'est pas à jour

Google has deprecated OAuth1 & OAuth1a authorization for their services.

In their guide, Migrating from OAuthConfig to the OAuth1 library, the Apps Script team describes how to migrate your code from one to the other. What they fail to mention is that you don't need to.

You can obtain the OAuth 2.0 access token for the current user with ScriptApp.getOAuthToken(), which means a simplifying change in any script that previously used OAuthConfig.

Ah, je ne sais pas trop... c'est un morceau de code que j'ai trouvé sur un site... il y avait des erreurs effectivement...

J'ai testé celui-ci :

function topdf() {

var foldersave=DriveApp.getFolderById('1FcwGF01ldAwnk2oUkqa8VXBEJgCfz-tj');
var d= new Date();

var request = {
"method": "GET",
"headers":{"Authorization": "Bearer "+ScriptApp.getOAuthToken()},
"muteHttpExceptions": true
};

var key='1REA2cSaqn8T_iowdKBqDxsO-gLSgoAHVFzClu7wOqmE';
var fetch=' ...// docs.google . com. rproxy.goskope . com /spreadsheets /d/'+key+'/export?format=pdf&size=A4&portrait=false'

var name = "Timestamp for: "+ d + ".pdf";
var pdf = UrlFetchApp.fetch(fetch, request);
pdf = pdf.getBlob().setName(name);
var file = foldersave.createFile(pdf)

}

==> Il me fait un PDF de tout mon sheet dans le dossier que je veux, peut-être quelque chose à exploiter.

Je ne suis pas un expert... malheureusement.

Bonjour,

effectivement, on trouve une solution ici https://stackoverflow.com/questions/30586559/printing-spreadsheet-to-pdf-then-saving-file-in-drive-u...

j'ai réactivé mon API-KEY mais a priori il faudrait que j'en redemande une autre pour les macros, ce qui n'est jamais simple avec google (j'apprécie le codage, mais les autorisations virent à l'obsession)

pour changer le nom du fichier, il faut changer ceci

var name = "Timestamp for: "+ d + ".pdf";

en reprenant la valeur de A8

et faire une boucle sur toutes les valeurs de A8 pour lancer les pdf ... je vais regarder de mon côté pour la boucle.

.

Il y a aussi une autre solution sans doute plus percutante : envoyer directement le pdf dans les boites aux lettres. Et là je n'ai pas besoin d mentionner mon API_KEY ... je te ferai un résumé dans la journée de cette solution avec un exemple.

Plus simple, pour le pdf :

pour l'essai, j'avais mis en D1 l'adresse mail et en D2 le nom du fichier, mais on peut aussi rendre variable l'objet, le texte du courriel etc. ou tout mettre en dur dans la macrro

j'ai structuré en

  1. une partie variables
    1. je voudrais capter en auto l'ID du fichier
    2. et le GID de la feuille
  2. une partie création du pdf, pas besoin de key
  3. une partie envoi
  4. une parti stockage (optionnelle)
function envoiCopieFeuillePDF() {
  DocumentApp.getActiveDocument();
  DriveApp.getFiles();

  // variables
  const doc = SpreadsheetApp.getActive();
  const docID = '___________ici_ID_du_document____________';
  const feuilleID = '___ici_GID_de_la_feuille_____';
  const email = doc.getActiveSheet().getRange("D1").getValue();
  const fichier = doc.getActiveSheet().getRange("D2").getValue().toString() +".pdf"
  const objet = 'Test pdf';
  const corps = "Veuillez trouver ci-joint ...";

  // Création du fichier pdf
  const url = 'https://docs.google.com/spreadsheets/d/' + docID + '/export?';
  const exportOptions =
    'exportFormat=pdf&format=pdf' + 
    '&size=A4' + 
    '&portrait=true' +                     // orientation portrait, false pour paysage
    '&fitw=false' +                        // pas d'ajustement en largeur
    '&sheetnames=false&printtitle=false' + // pas de nom ni de titre à l'impression
    '&pagenumbers=false&gridlines=false' + // pas de numérotation, pas de grille
    '&fzr=false' +                         // frozen rows = pas de répétition de l'en-tête
    '&gid=' + feuilleID;
  var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
  var reponse = UrlFetchApp.fetch(url + exportOptions, params).getBlob();

  // Envoi email avec fichier attaché 
    GmailApp.sendEmail(email, objet, corps, {
      htmlBody: corps,
      attachments: [{
            fileName: fichier,
            content: reponse.getBytes(),
            mimeType: "application/pdf"
        }]
    });

  // Sauvegarde du fichier. 
  DriveApp.createFile(reponse.setName(fichier));
}  

reste à faire une boucle sur les destinataires !

Et pour parcourir une liste ...

function parcourir() {
  var doc = SpreadsheetApp.getActive();
  var feuille = SpreadsheetApp.getActive();
  var data = feuille.getRange('MaListe').getValues();
  for (var i = 0; i < data.length; i++) {
    Browser.msgBox(data[i]);
  }
};

au lieu de Browser.msgBox il faut

  1. que ta cellule A8 soit égale à data[i]
  2. que tu enchaînes alors sur la macro envoiCopieFeuillePDF
    1. après avoir aussi identifié ou non l'email si tu veux envoyer par courriel
    2. et changé le nom du fichier

Salut Steelson,
Merci pour le grand coup de main !! Top, je test ça dans la journée (ou demain) et te dis.

Je comprends le langage, le code mais j'ai pas encore assez de pratique pour l'écrire... mais ça va venir !!

bon 11 novembre !!

Silentman

Re-

pas encore assez de pratique pour l'écrire... mais ça va venir !!

alors n'oublie pas que pour écrire dans une cellule il ne suffit pas de mettre = mais par exemple pour écrire dans I1

var feuille = SpreadsheetApp.getActive();
feuille.getRange('I1').setValue(data[i]);

Hello,

Je suis en train de tester ;)

Envoi au destinataire est une option, je suis plutôt dans l'impression PDF de chaque doc.

function envoiCopieFeuillePDF() {
DocumentApp.getActiveDocument();
DriveApp.getFiles();

// variables
const doc = SpreadsheetApp.getActive();
const docID = '1REA2cSaqn8T_iowdKBqDxsO-gLSgoAHVFzClu7wOqmE';
const feuilleID = '525395055';
//const email = doc.getActiveSheet().getRange("D1").getValue();
const fichier = doc.getActiveSheet().getRange("A8").getValue().toString() +".pdf"
const objet = 'Test pdf';
const corps = "Veuillez trouver ci-joint ...";

// Création du fichier pdf
const url = 'https://docs.google.com/spreadsheets/d/' + docID + '/export?';
const exportOptions =
'exportFormat=pdf&format=pdf' + 
'&size=A3' + 
'&portrait=false' + // orientation portrait, false pour paysage
'&fitw=false' + // pas d'ajustement en largeur
'&sheetnames=false&printtitle=false' + // pas de nom ni de titre à l'impression
'&pagenumbers=false&gridlines=false' + // pas de numérotation, pas de grille
'&fzr=false' + // frozen rows = pas de répétition de l'en-tête
'&gid=' + feuilleID;
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var reponse = UrlFetchApp.fetch(url + exportOptions, params).getBlob();

// Envoi email avec fichier attaché 
// GmailApp.sendEmail(email, objet, corps, {
// htmlBody: corps,
// attachments: [{
// fileName: fichier,
// content: reponse.getBytes(),
// mimeType: "application/pdf"
// }]
// });

// Sauvegarde du fichier. 
DriveApp.createFile(reponse.setName(fichier));
}

La feuille que je veux imprimer se nomme "Passeport", le GID est une suite de chiffre (525395055)

J'ai mis en commentaire la partie mail pour le moment

Je voudrais que le fichier PDF s'enregistre dans un dossier spécifique : '1FcwGF01ldAwnk2oUkqa8VXBEJ'

avec le nom de la cellule en A8 (= nom prénom de la personne) et la date de l'impression PDF (11112020) ==> Julie Martin_11112020

J'ai fait tourner le code, mais je ne sais pas où s'enregistre le PDF... (Edit : je les ai trouvé dans mon Drive !!)

Merci,

silentman ;)

Pour le dossier d'enregistrement, ajoute dans les variables

const dossier = DriveApp.getFolderById('1FcwGF01ldAwnk2oUkqa8VXBEJ');

et à la fin

  // Sauvegarde du fichier. 
  dossier.createFile(reponse.setName(fichier));

Pour le nom avec la date, tu peux changer l'ordre mais si tu veux faire un tri des fichiers sur le dossier j'emploie plutôt annee_mois_jour dans cet ordre

const d = Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd")
const fichier = doc.getActiveSheet().getRange("A8").getValue().toString() + "_" + d + ".pdf"

J'ai quelques erreur 403 / SSL... je ne sais pas trop pourquoi, je fais des tests.

Mais merci pour le coup de main, je testerai demain au boulot, peut-être que de chez moi ça foire.

J'ai quelques erreur 403 / SSL... je ne sais pas trop pourquoi

problème d'accès au dossier (certificat)

Hello,

Toujours le même problème, je n'avais pas ce problème avant... je l'ai depuis que j'ai modifié le code avec les dernières lignes.

Une idée ?

Edit : ça fonctionne !!

Il me manque juste une routine pour automatiser l'impression PDF via la liste déroulante.

C'est une fonction qui appelle une autre ?

Top sinon, merci !

Silentman

Il faut séparer alors les fonctionnalités

  1. conserve la date, supprime DriveApp.createFile(reponse.setName(fichier)); que tu remplaces par ce qui avait auparavant DriveApp.createFile(reponse.setName(fichier)); et regarde si tu les trouves dans ton drive >> à mon avis c'est là le problème ! as-tu les droits d'accès si c'est un dossier partagé et créé par un tiers ? il faudra demander une autorisation (je ne pourrai pas tester car je n'ai que mes propres sous-dossiers pour tester)
  2. après, supprime aussi la date pour revenir au point de départ mais je doute que ce soit cela
  3. la dernière solution serait de ne pas stocker ... et envoyer par mail, voire à toi-même !!! au moins à titre correctif temporaire

Salut Steelson,

le code fonctionne, c'est good, par contre, je vois pas comment je peux automatiser en déroulant ma liste de nom prénom ?

Faut-il que je parcours une colonne A1:A60 ou bien il est possible de lire une liste déroulante et parcourir les noms à partir de cette liste.

Sur VBA, j'aurais fait une boucle For, sur sheets, on peut faire la même chose ?

Merci,

Silentman

Oui il faut parcourir la liste et affecter la valeur à A8 à chaque tour. La boucle for existe avec une syntaxe un peu différente

function parcourir() {
  var doc = SpreadsheetApp.getActive();
  var feuille = SpreadsheetApp.getActive();
  var data = feuille.getRange('MaListe').getValues();
  for (var i = 0; i < data.length; i++) {
    feuille.getRange('A8').setValue(data[i]);
// faire appel à la fonction pdf
  }
};
function parcourir() {

var doc = SpreadsheetApp.getActive();

var feuille = SpreadsheetApp.getActive();

var data = feuille.getRange('MaListe').getValues();

for (var i = 0; i < data.length; i++) {

feuille.getRange('A8').setValue(data[i]);

// faire appel à la fonction pdf

}

};

Nickel, par contre, ma liste est lié à une range B8:B68 sur une autre feuille 'Database'. (via validation des données).

Dans ma feuille "passeport" où j'ai ma cellule avec la liste déroulante. Le code fonctionnera t-il ?

J'ai aussi testé avec une plage nommée (Liste_Nom_Prénom) lié sur la même range en B8:B68 sur une mon autre feuille 'Database'.

il faut donc indiquer dans quelle feuille elle se trouve avec .getSheetByName("___le_nom_de_la_feuille____")

var data = doc.getSheetByName("___le_nom_de_la_feuille____").getRange('MaListe').getValues();

et tu pourras aussi utiliser ta plage nommée (ici j'ai mis MaListe) - pas sûr que les noms aient une portée au-delà de la feuille

Rechercher des sujets similaires à "sheets creation pdf automatique lie liste deroulante"