Installation et configuration de la file d'impression
Les API
L'applicationdepot-vente.fvdw.fr présente une API pour consommer les données de la file d'impression.
Les requêtes s'effectuent en GET et sont disponibles aux adresses suivantes
- https://depot-vente.fvdw.fr/SPL-PING-
code organisation - https://depot-vente.fvdw.fr/SPL-NEXT-
code organisation - https://depot-vente.fvdw.fr/SPL-GET-
numéro de document - https://depot-vente.fvdw.fr/SPL-DEL-
numéro de document
PING
Permet de tester la connexion au serveur et valider le code organisation.Cet appel retourne un flux JSON.
> curl https:/depot-vente.fvdw.fr/SPL-PING-6B024676
{'error':false,'message':'OK Démo'}
Valeurs de retour
| Clé | Type | Valeur |
|---|---|---|
| error | boolean | true|false |
| message | string | OK ou la cause de l'erreur |
NEXT
Interroge le serveur : si il existe : donne le prochain document à imprimer.Si il existe au moins un document est dans la file
> curl https:/depot-vente.fvdw.fr/SPL-NEXT-6B024676
{'pdf_b64':'JVBERi … U9GCg==','spool_slug':'285481266561','crc':2025417623,'error':false}
Si la file d'attente est vide
> curl https:/depot-vente.fvdw.fr/SPL-NEXT-6B024676
{'pdf_b64':'','spool_slug':'','crc':false,'error':false,'message':"Aucun document PDF dans la file d'attente"}
Valeurs de retour
| Clé | Type | Valeur |
|---|---|---|
| pdf_b64 | string | s'il existe : une chaine encodée en base 64 ou vide s'il n'existe pas |
| spool_slug | string | s'il existe : une série de chiffres, identifiant unique du document ou vide s'il n'existe pas |
| crc | string | s'il existe : une série de chiffres, résultat du CRC32 du pdf (non encodé) ou False s'il n'existe pas |
| error | boolean | true|false |
| message | string | Cette clé existe uniquement si une erreur se produit la cause de l'erreur |
GET
Demande un document de la file d'attente.On spécifie l'identifiant du document dans l'url
SPL-GET-xxx où xxx est le numéro
retourné lors de l'appel de SPL-NEXT, sous la clé "spool_slug". Sur base de l'exemple ci-dessus : l'url devient SPL-GET-285481266561
Le document est dans la file d'attente.
> curl https:/depot-vente.fvdw.fr/SPL-GET-285481266561
{'pdf_b64':"JVBERi0 … RU9GCg==','spool_slug':'285481266561','crc':2025417623,'error":false}
Le document n'est pas dans la file d'attente.
> curl https:/depot-vente.fvdw.fr/SPL-GET-285481266000
{'error':true,'message':'Aucun document PDF avec le code #285481266560'}
Valeurs de retour
| Clé | Type | Valeur |
|---|---|---|
| pdf_b64 | string | s'il existe : une chaine encodée en base 64 |
| spool_slug | string | s'il existe : une série de chiffres, identifiant unique du document ou vide s'il n'existe pas |
| crc | string | s'il existe : une série de chiffres, résultat du CRC32 du pdf (non encodé) ou False s'il n'existe pas |
| error | boolean | true|false |
| message | string | Cette clé existe uniquement si une erreur se produit la cause de l'erreur |
DEL
Demande l'effacement d'un document de la file d'attente.On spécifie l'identifiant du document dans l'url
SPL-GET-xxx où xxx est le numéro
retourné lors de l'appel de SPL-NEXT, sous la clé 'spool_slug'. Sur base de l'exemple ci-dessus : l'url devient
SPL-DEL-285481266561
Le document est dans la file d'attente.
> curl https:/depot-vente.fvdw.fr/SPL-DEL-285481266561
{'error':false,'message':"Document #285481266561 effac\u00e9 de la file d'attente"}
Le document n'est pas dans la file d'attente.
> curl https:/depot-vente.fvdw.fr/SPL-DEL-285481266000
{'error':false,'message':"Aucun document PDF \u00e0 effacer de la file d'attente"}
Valeurs de retour
| Clé | Type | Valeur |
|---|---|---|
| error | boolean | true|false |
| message | string | message de confirmation ou la cause de l'erreur |
Le client
Le client (installé sur le Poste 3) doit utiliser les API (service impression) pour obtenir les documents PDF à imprimer issus de la file d'attente (sur le serveur depot-vente.fvdw.fr).
Le fonctionnement préconisé est une boucle sur la méthode
SPL-NEXT-… qui attend les documents de la file d'impression.
Si des documents sont disponibles, on transforme les données reçues encodées en base 64 pour obtenir un fichier PDF que l'on passe à
un programme chargé d'imprimer ce document.Quand le document est traité, il faut demander au serveur d'effacer ce document de la file d'attente
Exemple de client d'impression sous windows
Pour cet exemple, vous aurez besoin de python et de Sumatra PDF.Un script (qui tient sur un seul fichier) écrit en python interroge le serveur via les API, et utilise le programme Sumatra PDF pour imprimer le fichier PDF sur l'imprimante par défaut.
Le choix de Sumatra PDF se justifie par le fait que ce programme est gratuit, léger et peut même être installé en version portable (dézippez l'archive là où vous le désirez).
Script python
1 # (c) depot-vente.fvdw.fr - mars 2026 2 # 3 # Script pour consommer la file d'attente des documents PDF pour impression 4 # 5 import base64 6 import time 7 import tempfile 8 import os 9 import subprocess 10 import json 11 import binascii 12 from urllib.request import urlopen 13 from urllib.error import URLError, HTTPError 14 15 # ------------------------------------------------------------------------------------- 16 def getRemote(url): 17 try: 18 with urlopen(url, timeout=10) as response: 19 resp_data = json.loads(response.read()) 20 except HTTPError as e: 21 return {'success' : False, 'message': f"Erreur HTTP : {e.code} - {e.reason}" } 22 except URLError as e: 23 return {'success' : False, 'message': f"Erreur URL : {e.reason}" } 24 except TimeoutError: 25 return {'success' : False, 'message': "Erreur Timeout 10s" } 26 except Exception as e: 27 return {'success' : False, 'message': f"Une erreur inattendue est survenue : {e}"} 28 finally: 29 # print(f"Requête reussie. Code HTTP : {response.getcode()}") 30 # print(content[:100]) # Affiche les 100 premiers caracteres 31 resp_data["success"] = True 32 return resp_data 33 34 # ------------------------------------------------------------------------------------- 35 def print_pdf(pdf_data, sumatra_path): 36 # Enregistre le PDF dans un fichier temporaire 37 with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as f: 38 f.write(pdf_data) 39 pdf_path = f.name 40 41 # Imprime le PDF via SumatraPDF 42 try: 43 subprocess.run([sumatra_path, "-print-to-default", pdf_path], check=True) 44 except Exception as e: 45 print( f"Impression via Sumatra : Une erreur inattendue est survenue : {e}") 46 return False 47 finally: 48 # Supprime le fichier local temporaire apres impression 49 os.unlink(pdf_path) 50 return True 51 52 # ------------------------------------------------------------------------------------- 53 def ping(url): 54 ret = getRemote(url) 55 56 ret["action"] = "ping" 57 if not ret["success"]: 58 ret["error"] = True 59 else : 60 if ret["error"]: 61 ret["success"] = False 62 return ret 63 64 # ------------------------------------------------------------------------------------- 65 def del_document(url): 66 """ 67 Demande de supression du document cote serveur (file d'attente) 68 """ 69 ret = getRemote(url) 70 ret["action"] = "del" 71 if not ret["success"]: 72 print("Erreur " + ret["message"]) 73 return ret 74 75 # ------------------------------------------------------------------------------------- 76 def next_document(url): 77 """ 78 Interroge la file d'attente : si au moins un document en attente retourne 79 le binaire du 1er document de la file 80 """ 81 content = getRemote(url) 82 content["action"] = "next" 83 if not content['success']: 84 # Erreur 85 content["pdf_data"] = False 86 return content 87 88 if not content['pdf_b64']: 89 # Pas de fichier en attente 90 content["pdf_data"] = False 91 return content 92 93 # ctrl CRC 94 pdf_data = base64.b64decode(content['pdf_b64']) 95 crc = binascii.crc32(pdf_data) 96 if crc != content["crc"] : 97 content["success"] = False 98 content["message"] = "Le flux reçu est corrompu !" 99 content["pdf_b64"] = "/" 100 content["pdf_data"] = False 101 return content 102 content["pdf_b64"] = "/" 103 content["pdf_data"] = pdf_data # data binaires 104 105 ## print("Ctrl : local crc = %d - remote crc = %d " % (crc, content["crc"]) ) 106 return content 107 108 # ------------------------------------------------------------------------------------- 109 def main(): 110 """ 111 Boucle sur les douments de la file d'attente 112 """ 113 ret = ping(g_ping_url) 114 if not ret["success"]: 115 print("Echec de connexion au serveur : " + ret["message"]) 116 return 117 118 print("Appuyez sur 'Ctrl'+'Z' pour arrêter") 119 120 while True: 121 ret = next_document(g_next_url) 122 if ret["success"]: 123 if ret["pdf_data"]: 124 # document a traiter 125 print("Impression du document #%s..." % (ret["spool_slug"])) 126 if not print_pdf(ret["pdf_data"], g_sumatra_path): 127 print("Echec impression") 128 else: 129 print("Document imprime") 130 # supression cote serveur 131 r = del_document(g_del_url + ret["spool_slug"]) 132 if not r["success"]: 133 print("Echec mise a jour du serveur") 134 else: 135 print("Serveur mis a jour") 136 else: 137 print("Pas de document en attente ... pause (30 sec)") 138 # ATTENTION : ne pas utiliser une valeur inferieure a 30 (secondes) sans quoi les 139 # performances globales seront diminuees 140 time.sleep(30) 141 else: 142 print("Erreur : %s" % (ret["message"])) 143 break 144 145 146 # ------------------------------------------------------------------------------------- 147 # 148 # ------------------------------------------------------------------------------------- 149 if __name__ == "__main__": 150 151 # ICI : les variables a ajuster selon votre configuration 152 # Vous trouverez les url depuis le menu "administration" -> "parametres de l'application". 153 # Si vous avez active "Utiliser la file d'impression des documents PDF" = Oui, les url seront affichees 154 # en dessous des parametres 155 g_ping_url = "https://depot-vente.fvdw.fr/SPL-PING-6B024676" 156 g_next_url = "https://depot-vente.fvdw.fr/SPL-NEXT-6B024676" 157 g_del_url = "https://depot-vente.fvdw.fr/SPL-DEL-" 158 g_sumatra_path = r"C:\Program Files\SumatraPDF\SumatraPDF.exe" 159 # FIN des variables 160 161 main() 162