Outils pour utilisateurs

Outils du site


etiquettes_pdf

Imprimer des étiquettes autocollantes en passant par un fichier pdf

[modif 1/11/2015: correction instruction painter.drawText: inversion de pash et pasv]

Objectif

Dans le cadre d'un projet écrit en PyQt4, j'avais plusieurs impressions d'étiquettes à faire, et j'ai fini par mettre au point le code suivant.

La particularité, c'est que le programme n'imprime pas lui-même: il crée des pages .pdf. Cela permet de vérifier visuellement ce qui va être imprimé, et on laissera le visualiseur pdf utilisé (acrobat reader ou autres) imprimer lui-même.

Ce code est multiplateforme (au moins Windows-Linux)

Code proposé

L'impression et l'affichage des étiquettes est présenté sous forme de classe.

Les principales données à passer à l'instanciation de la classe sont:

  • etiq: liste des chaines, éventuellement multilignes (avec os.linesep) et en unicode
    • par exemple: [u“nom1 prénom” + os.linesep + u“rue” + os.linesep + u“ville”, u“nom2 prénom” + os.linesep + u“rue” + os.linesep + u“ville”, ……]
  • deph: point de départ en mm à partir du bord gauche de la feuille
  • pash: pas horizontal en mm entre 2 étiquettes
  • nbeh: nombre d'étiquettes en horizontal
  • depv: point de départ en mm à partir du bord supérieur de la feuille
  • pasv: pas vertical en mm entre 2 étiquettes
  • nbev: nombre d'étiquettes en vertical
  • font: police de caractères à utiliser de type QFont (voir l'exemple en bas de page)

D'autres données peuvent être modifiées (voir le code auto-documenté).

Voilà le code proposé avec son exemple d'application. Vous pouvez l'essayer avec un simple copier-coller dans idle, mais il vous faut bien sûr le module PyQt4 installé avant. Et c'est écrit en Python 2.7.

#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
# Python 2.7
 
import os, sys
 
from PyQt4 import QtCore, QtGui
 
Apppdf = QtGui.QApplication(sys.argv)
 
#############################################################################
class Etiquettespdf(object):
    """Imprime en fichier .pdf et affiche la liste d'étiquettes à imprimer"""
 
    # =======================================================================
    def __init__(self, etiq, deph, pash, nbeh, depv, pasv, nbev, font=None):
        """Initialise toutes les variables nécessaires
        etiq: liste des chaines, éventuellement multilignes (avec os.linesep)
        deph: point de départ en mm à partir du bord gauche de la feuille
        pash: pas horizontal en mm entre 2 étiquettes
        nbeh: nombre d'étiquettes en horizontal
        depv: point de départ en mm à partir du bord supérieur de la feuille
        pasv: pas vertical entre 2 étiquettes (mm)
        nbev: nombre d'étiquettes en vertical
        font: police de caractères à utiliser (de type QFont)
        """
        self.etiq = etiq 
        self.deph = deph
        self.pash = pash 
        self.nbeh = nbeh 
        self.depv = depv 
        self.pasv = pasv 
        self.nbev = nbev 
        self.font = font
 
        # Les var. suivantes (modifiables) ont une valeur par défaut
 
        # nom du fichier pdf à créer
        self.nomfichierpdf = u"etiquettes.pdf"
        # nom de l'application qui crée le fichier pdf
        self.nomapplication = u""
        # nom du document pdf créé
        self.nomdocument = u""
        # orientation de la page à imprimer
        self.orientation = QtGui.QPrinter.Portrait
        # format de la page à imprimer
        self.formatpage = QtGui.QPrinter.A4
        # alignement de l'impression sur les étiquettes
        self.alignement = QtCore.Qt.AlignLeft
 
    # =======================================================================
    def imprime(self):
        """Lance l'impression des étiquettes dans le fichier pdf donné"""
 
        # création de l'instance printer => fichier etiquettes.pdf
        printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
        printer.setOutputFileName(self.nomfichierpdf)
        printer.setCreator(self.nomapplication)
        printer.setDocName(self.nomdocument)
        printer.setPageSize(self.formatpage)
        printer.setOrientation(self.orientation)
        printer.setFullPage(True)
        resolution = printer.resolution() # en principe, c'est 1200dpi
 
        # conversion en pixels des distances données en mm
        mm2px = lambda mm: int(mm/25.4*resolution)
        deph = mm2px(self.deph)
        pash = mm2px(self.pash)
        depv = mm2px(self.depv)
        pasv = mm2px(self.pasv)
 
        # Calcul du nombre de pages:
        pages, sup = divmod(len(self.etiq), self.nbeh*self.nbev)
        if sup > 0:
            # dans ce cas, il y a une dernière page incomplète
            pages += 1
 
        # page à créer
        painter = QtGui.QPainter()
 
        # impression sur le fichier pdf
        painter.begin(printer)
        if self.font!=None:
            painter.setFont(self.font)
        k = 0 # compteur du nombre d'étiquettes imprimées
        for page in xrange(1, pages+1):
            v = depv # initialisation de la coordonnée verticale de chaque étiquette
            for i in xrange(self.nbev):
                # traiter chaque ligne d'étiquette de la page
                h = deph# initialisation de la coordonnée horizontale de chaque étiquette
                for j in xrange(self.nbeh):
                    # traiter chaque étiquette de la ligne
                    if k < len(etiq):
                        # écrire l'étiquette k de coordonnées [h, v] en pixels
                        painter.drawText(h, v, pash-1, pasv-1, self.alignement, etiq[k])
                        k += 1
                    h += pash
                v += pasv        
            if page < pages:
                # faire un 'newPage' à la fin de chaque page, sauf pour la dernière
                printer.newPage()
        painter.end()
 
    # =======================================================================
    def affiche(self):
        """affiche le pdf créé, dans le visualiseur pdf par défaut de l'OS"""
        if os.path.exists(self.nomfichierpdf):
            try:
                # solution pour Windows
                os.startfile(self.nomfichierpdf)
            except:
                # solution pour les Linux récents
                os.system('xdg-open ' + self.nomfichierpdf)
 
#############################################################################
if __name__ == "__main__":
 
    #========================================================================
    # test pour les étiquettes
    etiq = []
    for i in xrange(32):
        etiq.append((u"Etiquette%d" % (i+1)) + os.linesep + u"2ème ligne" + os.linesep + u"3ème ligne" + os.linesep + u"4ème ligne")
 
    deph = 26.0 # mm 
    pash = 60.0 # mm 
    nbeh = 3
 
    depv = 32.0 # mm 
    pasv = 30.0 # mm 
    nbev = 8
 
    font = QtGui.QFont()
    #font.setFamily(u"Courier New")
    font.setPointSize(8)
    #font.setItalic(True)
    #font.setBold(True)
    #font.setUnderline(True)
 
    etiquettes = Etiquettespdf(etiq, deph, pash, nbeh, depv, pasv, nbev, font)
    etiquettes.imprime()
    etiquettes.affiche()

Après impression d'une des pages, vous avez peut-être un écart de positionnement dû à un manque de précision de l'imprimante. La correction est simple. Par exemple, si vous mesurez un pas horizontal de 58 au lieu des 60 voulus, il vous suffit de multiplier les valeurs initiales par 60/58 = 1.034.


Amusez-vous bien!

etiquettes_pdf.txt · Dernière modification: 2015/11/01 16:26 de tyrtamos

Outils de la page