Script envoi automatique feuille Sheets PDF par mail

Hello,

Débutant sur les scripts Google, je cherche à envoyer une feuille sheets en automatique par mail.

J'ai pu trouver ce script sur le forum

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

  // variables
  const doc = SpreadsheetApp.getActive();
  const docID = '________mettre_ici_l_ID___du___fichier_____________';
  const feuilleID = '__ID_feuille__';
  const email = '___email_destinataire____;
  const dossier = DriveApp.getFolderById('__________ID_du_dossier______________');
  const d = Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd")
  const fichier = '____nom___du___fichier____suivi_ici_de_sa_date____________' + "_" + d + ".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. 
  dossier.createFile(reponse.setName(fichier));
}  

Cependant, j'ai une erreur lors de l'utilisation de celui-ci :

Exception: Request failed for https://docs.google.com returned code 400. Truncated server response: <!DOCTYPE html><html lang="fr"><head><meta name="description" content="Traitement de texte, présentations et feuilles de calcul en ligne"><meta nam... (use muteHttpExceptions option to examine full response)

Si quelqu'un a une idée du problème je serais heureux d'avoir une solution.

Deuxième petite question :

L'objectif ultime serait d'envoyer le fichier en pdf par mail lorsqu'une cellule est égale ou supérieure à 80%. Comment pourrais je procéder à cela ? Le but de cela est d'envoyer le fichier une fois la livraison est atteinte à 80%.

Merci pour votre aide

Bonne journée

Bonjour,

est-ce que const docID = '________mettre_ici_l_ID___du___fichier_____________'; a bien été renseigné ? il ne s'agit pas du nom mais de l'ID complet que l'on trouve dans la barre d'adresse ici (xxxxxxxxxxxxx)

https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxx/edit#gid=0

Bonjour,

Merci pour votre réponse

Oui il a bien été renseigné dans le bon format.

Bonjour;

une autre possibilité si ça peut aider il suffit de mettre l'adresse d'envoi en K1 de la première feuille

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('💤 Menu perso 💤');
  var item = menu.addItem('Envoi en PDF','emailFeuilleDeCalculVersPDF');
  item.addToUi();
}

/* Envoyer la feuille de calcul par courriel au format PDF */

function emailFeuilleDeCalculVersPDF() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();

   var sh = ss.getSheets()[0]; //il enverra la feuille 0 qui est la première feuille du classeur.
   // si vous changez le nombre, changez-le aussi dans les paramètres ci-dessous
  var shName = sh.getName();

  // Email réceptionant le PDF de cette feuille de calcul

  var email = sh.getRange('K1').getValue();
  // Obtenir l'URL de la feuille de calcul actuellement active (lien)
  var feuille = SpreadsheetApp.getActiveSpreadsheet();

  // Sujet du message
  var sujet = "PDF généré depuis la feuille de calcul " + feuille.getName(); 

  // Corps du mail
  var corpsDuMessage = "<p>Bonjour,</p>Veuillez trouver en pièce jointe le PDF de votre feuille de calcul.<p>Bonne réception,</p>";

  var contenant = DriveApp.getFileById(feuille.getId()).getAs("application/pdf");

  contenant.setName(feuille.getName() + ".pdf");

  // Si vous n'avez pas dépassé le quota, envoi du mail avec la pièce jointe en PDF.
  if (MailApp.getRemainingDailyQuota() > 0) 
    GmailApp.sendEmail(email, sujet, corpsDuMessage, {
      htmlBody: corpsDuMessage,
      attachments:[contenant]     
    });  
}

Bonjour Gilbert,

Merci pour votre script.

Le script se lance bien sans erreur, mais pas de réception de mail après test.

Il y a quelque chose que je dois mal faire, pourtant j'ai bien fais une adresse en K1 pour l'envoi, comme vous l'avez indiqué.

Problème résolu, c'était une petite coquille de ma part,merci Gilbert c'est parfait !

Pensez vous qu'il est possible que se script fonctionne lorsqu'une condition est remplie : par exemple lorsque A1 > ou = à 80% ?

Ainsi, le PDF s'envoie lorsque cette case atteinte les 80%

Dans tous les cas, merci pour ce premier script qui fonctionne :)

Bonjour,

function onEdit(event){
  var feuille = event.source.getActiveSheet();
  if (feuille.getName()=='Nom_feuille'){
    if(parseInt(feuille.getRange("A1").getValue().replace(/%/,''))>=80){
      emailFeuilleDeCalculVersPDF();
    }
  }
}
/* Envoyer la feuille de calcul par courriel au format PDF */

function emailFeuilleDeCalculVersPDF() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();

   var sh = ss.getSheets()[0]; //il enverra la feuille 0 qui est la première feuille du classeur.
   // si vous changez le nombre, changez-le aussi dans les paramètres ci-dessous
  var shName = sh.getName();

  // Email réceptionant le PDF de cette feuille de calcul

  var email = sh.getRange('K1').getValue();
  // Obtenir l'URL de la feuille de calcul actuellement active (lien)
  var feuille = SpreadsheetApp.getActiveSpreadsheet();

  // Sujet du message
  var sujet = "PDF généré depuis la feuille de calcul " + feuille.getName(); 

  // Corps du mail
  var corpsDuMessage = "<p>Bonjour,</p>Veuillez trouver en pièce jointe le PDF de votre feuille de calcul.<p>Bonne réception,</p>";

  var contenant = DriveApp.getFileById(feuille.getId()).getAs("application/pdf");

  contenant.setName(feuille.getName() + ".pdf");

  // Si vous n'avez pas dépassé le quota, envoi du mail avec la pièce jointe en PDF.
  if (MailApp.getRemainingDailyQuota() > 0) 
    GmailApp.sendEmail(email, sujet, corpsDuMessage, {
      htmlBody: corpsDuMessage,
      attachments:[contenant]     
    });  
}

Script à ne pas exécuter depuis l'éditeur, il s'exécute à chaque modification

Bonne Journée

Bonjour Imoka,

Merci pour ce script, c'est exactement ce que je recherche.

Cependant, cela n'a pas l'air de fonctionner.

Après tests de changement dans la case A1, aucun mail ne s'envoi même si la condition est ok.

Mon if est un peu douteux

function onEdit(event){
  var feuille = event.source.getActiveSheet();
  var texte = feuille.getRange("A1").getValue();
  texte = texte.replace("%","");
  if (feuille.getName()=='Nom_de_la_feuille'){//ex: Feuille 1
    if(Number(texte)>80||Number(texte)==80){
      emailFeuilleDeCalculVersPDF();
    }
  }
}

A tester,

J'ai testé la modif, toujours pas fonctionnel.

J'ai lancé le script dans l'éditeur voir si y'a une erreur, il me dit cela :

16:13:41    Erreur    
TypeError: Cannot read property 'source' of undefined
onEdit    @

Si cela ne fonctionne pas, c'est qu'il faut déclarer un déclencheur sur onEdit dans ce cas précise. En effet, onEdit a une large liberté d'utilisation à condition de ne pas engendrer des actions nécessitant une autorisation, et c'est le cas des mails. A lire ici https://developers.google.com/apps-script/guides/triggers

Because simple triggers fire automatically, without asking the user for authorization, they are subject to several restrictions:

Merci à tous pour votre aide, je vais me lancer sur les autres recherches

Bonne soirée à vous

Bonsoir,

Après plusieurs manipulation le script est fonctionnel

Il fallait effectivement mettre en place des déclencheurs.

Le dernier petit problème concerne le nombre d'envoi des notifications.

Avec le script actuel, la notification s'envoi automatiquement lorsqu'on dépasse les 80%. Ainsi, je reçois un premier mail à 80%, mais également de nouveaux mails lorsque cela passe à 81% 82% etc. En soit, 20 mails sont alors possible pour atteindre les 100%.

Je cherche donc à programmer l'envoi de la notification une et une seule fois lorsqu'on passe le seuil des 80%.

Avez-vous une idée sur ce sujet ?

Bonne soirée à tous et encore merci pour l'aide déjà apportée.

Un truc du genre

function test(){
  const s = Spreadsheet.getActiveSpreadsheet();
  const f = s.getSheetByName("Feuille 1");
  var texte = f.getRange("A2").getValue();
  texte = texte.replace("%","");
  if(f.getRange("B2").getValue() != "Envoyé !!" && (Number(texte) > 80 || Number(texte) == 80){
    emailFeuilleDeCalculVersPDF();
    f.getRange("B2").setValue("Envoyé !!");
  }else if(f.getRange("B2").getValue() != "Envoyé !!"){
    Browser.msgBox("Vous avez déjà envoyé le mail");
  }
}

Bonne Nuit

Il fallait effectivement mettre en place des déclencheurs.

...

Avec le script actuel, la notification s'envoi automatiquement lorsqu'on dépasse les 80%. Ainsi, je reçois un premier mail à 80%, mais également de nouveaux mails lorsque cela passe à 81% 82% etc. En soit, 20 mails sont alors possible pour atteindre les 100%.

Il faut toujours mettre un flag qui permet de savoir si cela a déjà été envoyé ou pas. Et le mieux est de mettre un horodatage avec new Date()

@Imoka

je ne pense pas que ta proposition soit fonctionnelle !!!

  • const s = Spreadsheet.getActiveSpreadsheet(); erreur
  • if(f.getRange("B2").getValue() != "Envoyé !!" && (Number(texte) > 80 || Number(texte) == 80){if erreur
  • texte = texte.replace("%","");erreur

Bonjour,

a nouveau, si 80% est bien un nombre, il n'y a aucune raison de le passer en texte pour enlever ensuite le %, il suffit de comparer comme suit >=0.8 avec un point qui est le séparateur des décimales dans l'écriture des scripts

sur ce point, je pense que Gilbert que je salue est d'accord !

Bonjour Mike

ce qui devrait donner ceci

//un seul envoi si A2 est à 80% 
function test() {
  const s = SpreadsheetApp.getActiveSpreadsheet();
  const f = s.getSheetByName("Feuille 1");
  var texte = f.getRange("A2").getValue();
   if (f.getRange("B2").getValue() != "Envoyé !!" && (Number(texte) >= 0.80)) {
    Browser.msgBox("Vous pouvez envoyé le mail");
    //emailFeuilleDeCalculVersPDF();// enlever la remarque pour rendre l'envoi fonctionnel
    f.getRange("B2").setValue("Envoyé !!");
  } else if (f.getRange("B2").getValue() == "Envoyé !!") {
    Browser.msgBox("Vous avez déjà envoyé le mail");
  }
}

Bonjour à tous !

Je reviens sur ce sujet qui m'avait permis d'accomplir le projet.

Pour un autre projet, je cherche également à envoyer une feuille sheets par PDF, mais seulement une feuille précise et non le spreadsheets en entier.

J'ai remixé le code de cette manière :

// Email réceptionant le PDF de cette feuille de calcul
  var email = "test@mail.com"; 

  // Obtenir l'URL de la feuille de calcul actuellement active (lien)

  var feuille = SpreadsheetApp.openByUrl(url);
  sheet = feuille.getSheetByName('Duplicate');

  // Sujet du message
  var sujet = "Bonjour XXXXXXXX  "; 

  // Corps du mail
  var corpsDuMessage = "<p>Bonjour,</p>TEXTE TEXTE TEXTE TEXTE.<p>Bonne réception,</p>";

  var contenant = DriveApp.getFileById(feuille.getId()).getAs("application/pdf");

  contenant.setName(sheet.getName() + ".pdf");

  // Si vous n'avez pas dépassé le quota, envoi du mail avec la pièce jointe en PDF.
  if (MailApp.getRemainingDailyQuota() > 0) 
    GmailApp.sendEmail(email, sujet, corpsDuMessage, {
      htmlBody: corpsDuMessage,
      attachments:[contenant]     
    });

}

la var URL est déjà spécifiée plus haut dans le code,

Je sais que le problème vient du driveApp, qui est actuellement basé sur la variable feuille, en revanche, je n'arrive pas à trouver la modification à faire pour que seule la feuille "Duplicate" soit générée en PDF vu que le getFileById ne fonctionne que pour un spreadsheet et non un Sheets si je ne me trompe pas.

Avez-vous une idée ?

Merci à tous et bon week end

Bonjour,

la réponse est justement ici https://forum.excel-pratique.com/sheets/script-envoi-automatique-feuille-sheets-pdf-par-mail-161960#...

la discussion s'est ensuite orientée vers le fichier complet, mais pour une seule feuille, ceci fonctionne, sous une forme un peu différente car tu semblais avoir eu des problèmes

function envoyerFichierPDF() {
  const docID = SpreadsheetApp.getActiveSpreadsheet().getId();
  const feuilleID = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Duplicate').getSheetId();
  const fichier = 'test' + ".pdf"
  const url = 'https://docs.google.com/spreadsheets/d/' + docID + '/export?';
  const exportOptions =
    'exportFormat=pdf&format=pdf' +
    '&size=A4' +
    '&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();
      GmailApp.sendEmail('xxxxxxxxxxx@gmail.com', 'fichier pdf', 'ci-joint ...', {
      htmlBody: 'ci-joint ...',
      attachments: [{
            fileName: fichier,
            content: reponse.getBytes(),
            mimeType: "application/pdf"
        }]
    });
}
Rechercher des sujets similaires à "script envoi automatique feuille sheets pdf mail"