Erreur "Google Docs" à l'export d'un fichier pdf
Bonjour à tous,
Comme d'habitude, je me tourne vers vous après des recherches infructueuses.
Voici le déroulé du script :
- Génération d'un fichier pdf à partir d'un template (rempli au préalable mais cette partie fonctionne et n'est pas en rapport avec le problème)
- Téléchargement du pdf dans le navigateur pour impression
- Archivage de ce pdf dans un dossier drive
C'est la partie 3 qui déconne. En réalité, il n'y a pas d'erreur d'exécution, le script va bien au bout, mais alors que le fichier téléchargé s'affiche correctement, celui archivé (l'archivage en lui même fonctionne) présente cette erreur lorsqu'on essaye de l'ouvrir :
Je précise qu'aux premiers essais, tout fonctionnait parfaitement, les 2 pdf s'affichaient (côté téléchargement et dossier). Au bout d'un moment, cette erreur est apparue et reste. J'ai essayé de rebooter mais rien n'y fait.
Voici le code utilisé :
Je sais qu'il est probablement redondant (je créé 2 fois un url), mais ce sont des fonctions vraiment peu familières et j'ai bricolé
function generer_BL()
{
//Boucle pour remplir le template feuille "Temp_BL_XXX"
var fuseauHoraire = Session.getScriptTimeZone();
var feuille_temp_XXX = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Temp_BL_XXX");
var utilisateur = Session.getActiveUser().toString();
//...........
//Maintenant, les données sont copiées sur le template du BL, il faut l'envoyer à imprimer
var iD_feuille_trescal = feuille_temp_XXX.getSheetId();
var iD_tableur = SpreadsheetApp.getActiveSpreadsheet().getId();
//url d'exportation en pdf
var url = 'https://docs.google.com/spreadsheets/d/' + iD_tableur + '/export?';
//Paramètres d'impression
var options_impression =
{
format: 'pdf',
size: 'A4',
portrait: true, // Orientation paysage (false) ou portrait (true)
gridlines: false, // Inclure ou non les grilles
printtitle: true, // Inclure les titres de colonnes et lignes
sheetnames: false, // Inclure le nom de l'onglet
pagenumbers: true, // Ajouter des numéros de page
top_margin: 0.50, // Marges en pouces
bottom_margin: 0.50,
left_margin: 0.50,
right_margin: 0.50,
gid: iD_feuille_trescal // ID de l'onglet à imprimer
};
// Construction de l'URL selon les options d'impression
var queryString = [];
for (var option in options_impression) {
queryString.push(option + '=' + options_impression[option]);
}
//Création du lien
var lien_telechargement = url + queryString.join('&');
//Lance le téléchargement du pdf sur le navigateur
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutput(`<script>window.addEventListener('load',()=>{window.open('${lien_telechargement}'),google.script.host.close()});</script></body></html>`), 'Téléchargement du BL à imprimer ...');
Logger.log("Un BL XXX a été téléchargé par " + utilisateur);
//Masque la feuille
Utilities.sleep(9000); //Temporise car l'exécution d'une autre ligne provoque une erreur dans le téléchargement du pdf
feuille_temp_XXX.hideSheet();
Utilities.sleep(2000);
//Archiver le pdf dans un dossier drive
var nom = "BL XXX du " + Utilities.formatDate(new Date(), fuseauHoraire, "dd/MM/yyyy") + " par " + utilisateur + '.pdf';
var token = ScriptApp.getOAuthToken();
var docurl = UrlFetchApp.fetch(lien_telechargement, { headers: { 'Authorization': 'Bearer ' + token }, muteHttpExceptions: true });
var pdf = docurl.getAs('application/pdf').setName(nom); // Correction ici
var file = DriveApp.createFile(pdf);
var folder = DriveApp.getFolderById("XXXXXXXXXXXXXXXXXX");
file.moveTo(folder);
Logger.log("Un BL XXX a été archivé");
feuille_temp_XXX.hideSheet();
}Voilà, si l'un d'entre vous sait comment éviter cette erreur à coup sûr.... Merci !
Jules
Si ça peut apporter quelque chose : je pense que le problème vient de l'url généré.
Si on met entre parenthèses l'étape :
//Lance le téléchargement du pdf sur le navigateur
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutput(`<script>window.addEventListener('load',()=>{window.open('${lien_telechargement}'),google.script.host.close()});</script></body></html>`), 'Téléchargement du BL à imprimer ...');alors dans ce cas le pdf archivé est bien lisible !
Cela voudrait donc dire que je n'ai pas le droit d'utiliser 2 fois le "lien-telechargement" ? Seulement, je n'arrive pas à en construire un second...
Salut, essaye d'inverser ton script :
1- génère le fichier, stock le dans une variable
2- mets le dans ton drive
3- envoie le par email
J'ai une compilation de script pré-fabriqué pour ce genre de cas, demain je te le partage au besoin.
Bonjour Pierre,
Quand tu dis "génère le fichier et stocke le dans une variable", tu parles de ce morceau ?
var iD_feuille_trescal = feuille_temp_XXX.getSheetId();
var iD_tableur = SpreadsheetApp.getActiveSpreadsheet().getId();
//url d'exportation en pdf
var url = 'https://docs.google.com/spreadsheets/d/' + iD_tableur + '/export?';
//Paramètres d'impression
var options_impression =
{
format: 'pdf',
size: 'A4',
portrait: true, // Orientation paysage (false) ou portrait (true)
gridlines: false, // Inclure ou non les grilles
printtitle: true, // Inclure les titres de colonnes et lignes
sheetnames: false, // Inclure le nom de l'onglet
pagenumbers: true, // Ajouter des numéros de page
top_margin: 0.50, // Marges en pouces
bottom_margin: 0.50,
left_margin: 0.50,
right_margin: 0.50,
gid: iD_feuille_trescal // ID de l'onglet à imprimer
};
// Construction de l'URL selon les options d'impression
var queryString = [];
for (var option in options_impression) {
queryString.push(option + '=' + options_impression[option]);
}
//Création du lien
var lien_telechargement = url + queryString.join('&');Et la variable en question c'est "lien_telechargement" ?
Désolé pour ces questions, mais avec ce genre de fonctions je nage complètement !
Salut,
Voici un script type permettant de faire un pdf, l'archiver dans le drive et l'envoyer par email :
function savePDF(){
// Selection de la feuille à PDFiser
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
//générer URL de la feuille
const ssUrl = ss.getUrl();
const sheetId= sheet.getSheetId();
var url = ssUrl.replace(/\/edit.*$/,'') // ici sont indiquées les caractéristiques de l'impression PDF, il necessite d'adapter les marges, orientation en fonction de vos données.
+ '/export?exportformat=pdf&format=pdf'
+ '&size=A4'
+ '&portrait=true'
+ '&fitw=true'
+ '&top_margin=-0.95'
+ '&bottom_margin=0.50'
+ '&left_margin=0.50'
+ '&right_margin=0.50'
+ '&sheetnames=false'
+ '&printtitle=false'
+ '&pagenum=false'
+ '&gridlines=false'
+ '&fzr=FALSE'
+ '&gid='+sheetId;
// Création du nom du PDF, dans mon cas une cellule située en A6, vous pouvez y mettre un nom directement, ou bien un autre celulle.
var docName = sheet.getRange('A6').getValue();
// CRÉER LE PDF A PARTIR DE L'URL
var token = ScriptApp.getOAuthToken();
var docurl = UrlFetchApp.fetch(url, { headers: { 'Authorization': 'Bearer ' + token } });
var pdf = docurl.getAs('application/pdf').setName(docName);
var file = DriveApp.createFile(pdf);
// enregistrement du PDF dans le Drive
var folder = DriveApp.getFolderById(""17LmzDRdzPpH3zt_4rufGfgffbBWbQNo5"");/* Important ! > Ici on doit mettre l'adresse du dossier drive où on veut sauvegarder le PDF, allez dans votre dossier et dans la barre d'URL en haut copier le code qui ressemble à ça : 0AGuVhN09TP00Uk9PVA */
var finalFile = file.moveTo(folder);
var docUrl = finalFile.getUrl();
// Envoi du PDF par mail
var demandeurEmail = sheet.getRange('F5').getValue(); /* ici l'adresse mail de mon destinataire se situe dans une cellule, il est possible de changer directement l'information, ou de mettre une autre cellule */
var message = ""Bonjour""+""<p>Ci-joint le ""+docName+""</p>""+""<a href='""+docUrl+""'>Cliquez ici pour ouvrir le recap.</a>""; // texte du mail
MailApp.sendEmail({to:demandeurEmail , subject: """"+docName, htmlBody:message}) ;
// facultatif, cela sert à confirmer à l'utilisateur que le mail à bien été envoyé
var demandeur = ""Prénom NOM""; // nom du destinataire
var ui = SpreadsheetApp.getUi();
ui.alert(""Le ""+ docName +"" a bien été créé\n et été envoyé à ""+ demandeur +"" "");
}
}"Je vais essayer ton code, même si dans mon besoin l'idée est vraiment de télécharger le fichier en plus de l'archiver, car les utilisateurs doivent l'imprimer directement.
J'ai inversé la séquence comme tu l'as suggéré. Cela a fonctionné le premier coup, mais dès le 2ème essai, l'erreur "Google doc" s'affiche sur le pdf archivé et le téléchargement ne se lance même pas !
Vraiment je ne comprends pas comment un script peut fonctionner une fois et ne plus marcher quelques minutes plus tard, alors que rien n'a été modifié ! Cela fait plusieurs jours que je bloque sur ce morceau de code, je perds patience...
Voici le nouveau script réarrangé selon tes conseils :
PS : j'ai remarqué que les pauses aident le fichier à s'archiver/télécharger correctement
function archiver_telecharger_pdf ()
{
var utilisateur = Session.getActiveUser().toString();
var feuille_temp_XXX = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Temp_BL_XXX");
//ici boucle et instructions pour noter les infos dans le template du BL, sur la feuille "Temp_ BL_XXX"
//Maintenant, les données sont copiées sur le template du BL, il faut créer le pdf
var iD_feuille_XXX = feuille_temp_XXX.getSheetId();
var iD_tableur = SpreadsheetApp.getActiveSpreadsheet().getId();
//url d'exportation en pdf
var url = 'https://docs.google.com/spreadsheets/d/' + iD_tableur + '/export?';
//Paramètres d'impression
var options_impression =
{
format: 'pdf',
size: 'A4',
portrait: true, // Orientation paysage (false) ou portrait (true)
gridlines: false, // Inclure ou non les grilles
printtitle: true, // Inclure les titres de colonnes et lignes
sheetnames: false, // Inclure le nom de l'onglet
pagenumbers: true, // Ajouter des numéros de page
top_margin: 0.50, // Marges en pouces
bottom_margin: 0.50,
left_margin: 0.50,
right_margin: 0.50,
gid: iD_feuille_XXX // ID de l'onglet à imprimer
};
// Construction de l'URL selon les options d'impression
var queryString = [];
for (var option in options_impression) {
queryString.push(option + '=' + options_impression[option]);
}
//Création du lien
var lien_telechargement = url + queryString.join('&');
//Archiver le pdf dans un dossier drive
var nom = "BL XXX du " + Utilities.formatDate(new Date(), fuseauHoraire, "dd/MM/yyyy") + " par " + utilisateur + '.pdf';
var token = ScriptApp.getOAuthToken();
var docurl = UrlFetchApp.fetch(lien_telechargement, { headers: { 'Authorization': 'Bearer ' + token }, muteHttpExceptions: true });
var pdf = docurl.getAs('application/pdf').setName(nom); // Correction ici
var file = DriveApp.createFile(pdf);
var folder = DriveApp.getFolderById("XXXXXXXXXXXXXXX");
file.moveTo(folder);
Logger.log("Un BL XXX a été archivé");
Utilities.sleep(9000);
//Lance le téléchargement du pdf sur le navigateur
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutput(`<script>window.addEventListener('load',()=>{window.open('${lien_telechargement}'),google.script.host.close()});</script></body></html>`), 'Téléchargement du BL à imprimer ...');
Utilities.sleep(9000); //Temporise car l'exécution d'une autre ligen provoque une erreur dans le téléchargement du pdf
Logger.log("Un BL XXX a été téléchargé par " + utilisateur);
}Update !
Tout fonctionne ! Merci Pierre, ta solution d'inverser la séquence était la bonne.
Je dépose ici le code final, si ça peut aider certain.
Pour rappel, ce code :
- Génère un pdf à partir d'une feuille sheets (pré remplie selon un template)
- Archive ce pdf dans un dossier drive
- Télécharge ce pdf sur le navigateur (pour impression dans mon cas)
Merci encore au forum !!
PS : le code que tu m'as proposé renvoie une erreur "500" sur la construction du pdf, au niveau de la "var docurl = UrlFetchApp.fetch(url, { headers: { 'Authorization': 'Bearer ' + token } });"
function generer_archiver_telecharger_pdf ()
{
var fuseauHoraire = Session.getScriptTimeZone();
var feuille_temp_europe = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Temp_BL_Europe");
var utilisateur = Session.getActiveUser().toString();
//Ici boucle et instructions pour remplir le template de la feuille Temp_BL_Europe
//Maintenant, les données sont copiées sur le template, il faut créer le pdf
var iD_feuille_europe = feuille_temp_europe.getSheetId();
var iD_tableur = SpreadsheetApp.getActiveSpreadsheet().getId();
//url d'exportation en pdf
var url = 'https://docs.google.com/spreadsheets/d/' + iD_tableur + '/export?';
//Paramètres d'impression
var options_impression =
{
format: 'pdf',
size: 'A4',
portrait: true, // Orientation paysage (false) ou portrait (true)
gridlines: false, // Inclure ou non les grilles
printtitle: true, // Inclure les titres de colonnes et lignes
sheetnames: false, // Inclure le nom de l'onglet
pagenumbers: true, // Ajouter des numéros de page
top_margin: 0.50, // Marges en pouces
bottom_margin: 0.50,
left_margin: 0.50,
right_margin: 0.50,
gid: iD_feuille_europe // ID de l'onglet à imprimer
};
// Construction de l'URL selon les options d'impression
var queryString = [];
for (var option in options_impression) {
queryString.push(option + '=' + options_impression[option]);
}
//Création du lien
var lien_telechargement = url + queryString.join('&');
//Archiver le pdf dans un dossier drive
var nom = "BL EQ du " + Utilities.formatDate(new Date(), fuseauHoraire, "dd/MM/yyyy HH:mm") + " par " + utilisateur + '.pdf';
var token = ScriptApp.getOAuthToken();
var docurl = UrlFetchApp.fetch(lien_telechargement, { headers: { 'Authorization': 'Bearer ' + token }, muteHttpExceptions: true });
var pdf = docurl.getAs('application/pdf').setName(nom); // Correction ici
var file = DriveApp.createFile(pdf);
var folder = DriveApp.getFolderById("ID du dossier drive");
file.moveTo(folder);
Logger.log("Un BL EQ a été archivé");
Utilities.sleep(9000); //Temporise car l'exécution d'une autre ligne provoque une erreur dans le téléchargement du pdf
//Lance le téléchargement du pdf sur le navigateur
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutput(`<script>window.addEventListener('load',()=>{window.open('${lien_telechargement}'),google.script.host.close()});</script></body></html>`), 'Téléchargement du BL à imprimer ...');
Utilities.sleep(9000); //Temporise car l'exécution d'une autre ligne provoque une erreur dans le téléchargement du pdf
Logger.log("Un BL EQ a été téléchargé par " + utilisateur);
}