Imprimer en masse - publipostage

Voici un custom widget simple qui permet d’imprimer en masse plusieurs documents à la fois, générés par du publipostage.

Nov-28-2025 20-22-55

Pas à pas :

  • Ajouter une vue personnalisée > custom widget builder, basée sur la table qui contient votre formule dynamique qui génère le html
  • Ouvrez la configuration du widget, et dans le code html collez ce code qui affiche un bouton « Imprimer tout » :
<html>
<head>
  <script src="https://docs.getgrist.com/grist-plugin-api.js"></script>
</head>
<body>
  <button id="printBtn">Imprimer tout</button>
</body>
</html>
  • Dans l’onglet js, collez le code suivant en remplaçant formule_avec_style par l’identifiant de votre colonne qui contient le html dynamique :
grist.ready({ requiredAccess: 'full' });

const printBtn = document.querySelector("#printBtn");
let tableData = [];

grist.onRecords(table => {
 tableData = table;
});

printBtn.addEventListener('click', () => {
 if (tableData.length === 0) {
   alert("Aucune donnée à imprimer");
   return;
}

const printWindow = window.open('', '_blank');
let htmlContent = '<html><head><title>Impression</title></head><body>';
     
tableData.forEach((row) => {
 htmlContent += row.formule_avec_style || '';
 htmlContent += '<div style="page-break-after: always;"></div>';
});
     
htmlContent += '</body></html>';
     
printWindow.document.write(htmlContent);
printWindow.document.close();
printWindow.print();
});

Un document d’exemple avec le custom widget est disponible ici :

PS : je pense qu’on peut faire mieux sans ouvrir de nouvel onglet

1 « J'aime »

Si vous souhaitez imprimer seulement les vues de certaines lignes (= filtrer votre table), vous pouvez créer une colonne « Imprimer » de type booléen, et cocher les lignes que vous souhaitez enregistrer/imprimer.

Puis utiliser ce code dans le js, en remplaçant Imprimer par l’id de votre colonne booléen :

grist.ready({ requiredAccess: 'full' });

const printBtn = document.querySelector("#printBtn");
let tableData = [];

grist.onRecords(table => {
  tableData = table;
});

printBtn.addEventListener('click', () => {
  if (tableData.length === 0) {
    alert("Aucune donnée à imprimer");
    return;
  }

  // Filtrer uniquement les lignes où Imprimer est True
  const rowsToPrint = tableData.filter(row => row.Imprimer === true);
      
  if (rowsToPrint.length === 0) {
    alert("Aucune ligne avec Envoyer = True");
    return;
  }

  const printWindow = window.open('', '_blank');
  let htmlContent = '<html><head><title>Impression</title></head><body>';
      
  rowsToPrint.forEach((row) => {
    htmlContent += row.formule_avec_style || '';
    htmlContent += '<div style="page-break-after: always;"></div>';
  });
      
  htmlContent += '</body></html>';
      
  printWindow.document.write(htmlContent);
  printWindow.document.close();
  printWindow.print();
});

Ex ici : Ex - Imprimer en masse publipostage - Grist

1 « J'aime »

Je me suis aidé de cette doc de mozilla pour ne pas avoir de fenêtre qui s’ouvre.

Il faut remplacer

src

par

srcdoc = htmlContent

grist.ready({ requiredAccess: 'full' });

const printBtn = document.querySelector("#printBtn");
let tableData = [];

grist.onRecords(table => {
 tableData = table;
});

function setPrint() {
  const closePrint = () => {
    document.body.removeChild(this);
  };
  this.contentWindow.onbeforeunload = closePrint;
  this.contentWindow.onafterprint = closePrint;
  this.contentWindow.print();
}

document.getElementById("printBtn").addEventListener("click", () => {

  if (tableData.length === 0) {
   alert("Aucune donnée à imprimer");
   return;
  }

  let htmlContent = '<html><head><title>Impression</title></head><body>';
  tableData.forEach((row) => {
  htmlContent += row.PDF || '';
  htmlContent += '<div style="page-break-after: always;"></div>';
  });
  htmlContent += '</body></html>';

  const hideFrame = document.createElement("iframe");
  hideFrame.onload = setPrint;
  hideFrame.style.display = "none"; // hide iframe
  hideFrame.srcdoc = htmlContent;
  document.body.appendChild(hideFrame);
});

Par contre, ce dont j’ai besoin ce serait de générer un pdf par ligne.
Je n’ai pas encore trouvé.
Enfin si avec html2pdf, mais cela créé des images, ce que je ne veux pas.

Pierre

Bonjour, est-ce que ce widget pourrait vous convenir ?

Salut, oui cela m’a inspiré.
Avec quelques modifications et un peu de chatgpt pour les corrections (je ne suis pas un as de la programmation), j’obtiens quelque chose d’intéressant :

Cela génère chaque page à imprimer vers une liste, puis imprime cette liste de document.
Cela fait toujours 2 clics par document à faire mais ça progresse.

grist.ready({ requiredAccess: 'full' });

const printBtn = document.querySelector("#printBtn");
let tableData = [];

// Récupérer la table
grist.onRecords(table => {
  tableData = table;
});

// Gestion de l'impression en iframe
function setPrint(contents, index) {
  if (index >= contents.length) return; // Sortie si tous les documents ont été traités

  const hideFrame = document.createElement("iframe");
  
  const closePrint = () => {
    document.body.removeChild(hideFrame); // Supprimer le cadre une fois l'impression terminée
    setTimeout(() => setPrint(contents, index + 1), 500); // Attendre 500 ms avant d'imprimer le suivant
  };

  hideFrame.onload = function () {
    this.contentWindow.onbeforeunload = function() { return null; }; // Pour empêcher des alertes 
    this.contentWindow.onafterprint = closePrint; // Gestion après l'impression
    this.contentWindow.print(); // Démarre l'impression
  };

  hideFrame.style.display = "none"; // Cacher l'iframe
  hideFrame.srcdoc = contents[index]; // Charger le document à imprimer
  document.body.appendChild(hideFrame); // Ajouter l'iframe au corps du document
}

//Après avoir cliqué sur téléchargement
printBtn.addEventListener("click", () => {
  if (tableData.length === 0) {
    alert("Aucune donnée à imprimer");
    return;
  }

  // Vérifier que la colonne "Télécharger" existe
  if (!('Telecharger' in tableData[0])) {
    alert("La colonne 'Télécharger' n'existe pas dans la table");
    return;
  }

  // Sélection des lignes à télécharger
  const rowsToDownload = tableData.filter(row => row.Telecharger === true);
  
  if (rowsToDownload.length === 0) {
    alert("Aucune ligne avec Télécharger = True");
    return;
  }

  // Créer et stocker les pages à imprimer
  const contentsToPrint = []; // Liste du contenu à imprimer
  try {
    for (let i = 0; i < rowsToDownload.length; i++) {
      const row = rowsToDownload[i];
      let htmlContent = row.PDF || '<p>Aucun contenu disponible</p>'; // Assurez-vous d'avoir du contenu
      contentsToPrint.push(htmlContent); // Ajout à la liste
    }

  } catch (error) {
    alert(error.message);
    return;
  }
  
  setPrint(contentsToPrint, 0); // Démarre l'impression à partir du premier document
});

Il me reste a cocher automatiquement téléchargé dans le formulaire.
Et décoché téléchargement après l’impression (ou un fois le contenu html généré).