majorsilence-reporting
Générez des rapports RDL en PDF, Excel, CSV et plus depuis Python — via sous-processus, un binaire AOT, ou une FFI ctypes en processus. Aucune dépendance runtime en dehors de la bibliothèque standard.
Installation
Installez depuis PyPI (Python 3.10+ requis) :
# PyPI pip install majorsilence-reporting # Ou en mode éditable depuis les sources pip install -e .
Aucune dépendance runtime — utilise uniquement la bibliothèque standard Python (subprocess, ctypes, tempfile).
Modes d'intégration
Trois classes sont disponibles selon la manière dont vous déployez le moteur de reporting :
| Classe | Mécanisme | Prérequis |
|---|---|---|
| Report | Lance dotnet RdlCmd.dll comme processus enfant. | Runtime .NET installé sur le serveur. |
| ReportAot | Lance un binaire RdlCmd autonome compilé en AOT. | Binaire AOT déployé aux côtés de l'application. Aucun runtime .NET requis. |
| report_native.Report | Charge librdlnative.so en processus via ctypes. | Bibliothèque native + fichiers .so associés déployés. Appelez load_library() une fois au démarrage. |
Report — sous-processus (dotnet)
from majorsilence_reporting import Report rpt = Report( report_path = '/path/to/report.rdl', rdl_cmd_path = '/path/to/RdlCmd.dll', ) rpt.set_connection_string('Data Source=/path/to/data.db') rpt.set_parameter('StartDate', '2026-01-01') # Enregistrer dans un fichier rpt.export('pdf', '/tmp/output.pdf') # Ou obtenir les octets en mémoire (par ex. pour une réponse Flask) data = rpt.export_to_memory('pdf') return Response(data, mimetype='application/pdf')
ReportAot — binaire AOT
Même API que Report, mais pointe vers un binaire autonome plutôt qu'une DLL. Aucun runtime .NET requis sur le serveur.
from majorsilence_reporting import ReportAot rpt = ReportAot( report_path = '/path/to/report.rdl', rdl_cmd_path = '/path/to/RdlCmd', # binaire autonome, sans extension .dll ) rpt.set_connection_string('Data Source=/path/to/data.db') data = rpt.export_to_memory('xlsx') # ReportAot prend aussi en charge xlsx_table, tifb, et mht data = rpt.export_to_memory('xlsx_table')
report_native — FFI en processus
Le mode natif charge librdlnative.so directement dans le processus Python via ctypes. Aucun processus enfant n'est lancé, ce qui en fait l'option à la plus faible latence. Il permet aussi un vrai rendu en mémoire — les octets du rapport sont renvoyés directement depuis le tampon natif sans écrire de fichier temporaire.
from majorsilence_reporting.report_native import load_library, Report # À appeler une fois au démarrage du processus. Charge librdlnative.so et toutes les bibliothèques associées. lib = load_library('/path/to/librdlnative.so') rpt = Report(lib, report_path='/path/to/report.rdl') rpt.set_connection_string('Data Source=/path/to/data.db') # Renvoie les octets directement depuis le tampon natif — aucun fichier temporaire écrit data = rpt.export_to_memory('pdf') # À transmettre à Django / FastAPI / Flask comme réponse binaire return Response(data, media_type='application/pdf')
load_library() définit RDLNATIVE_LIB_DIR et précharge toutes les bibliothèques .so / .dylib associées avec RTLD_GLOBAL afin que le résolveur P/Invoke .NET les trouve correctement. Appelez-la une fois par processus avant de créer la moindre instance Report.
API principale
Les trois classes partagent la même interface :
| Méthode | Description |
|---|---|
| set_connection_string(cs) | Définit la chaîne de connexion à la base de données utilisée par le rapport. À appeler avant export. |
| set_parameter(name, value) | Définit un paramètre de rapport nommé. Les deux arguments sont des chaînes. Peut être appelée autant de fois que nécessaire. |
| export(format, path) | Génère le rapport et écrit la sortie vers path sur le disque. |
| export_to_memory(format) | Génère et renvoie la sortie sous forme de bytes (formats binaires) ou str (formats texte). Pour report_native.Report, renvoie toujours des bytes. |
Jeux de données en mémoire
report_native.Report permet de fournir des données entièrement en mémoire via add_data() — aucune connexion à une base de données requise. Passez un nom de jeu de données et une liste de dictionnaires où chaque valeur est une chaîne.
from majorsilence_reporting.report_native import load_library, Report lib = load_library('/path/to/librdlnative.so') rpt = Report(lib, report_path='/path/to/report.rdl') rpt.add_data('SalesData', [ {'Product': 'PDF Library Pro', 'Revenue': '1200.00', 'Units': '3'}, {'Product': 'Report Designer', 'Revenue': '250.00', 'Units': '1'}, {'Product': 'Support (12 mo.)', 'Revenue': '500.00', 'Units': '1'}, ]) data = rpt.export_to_memory('pdf')
add_data() active automatiquement SkipDatabaseSchemaValidation. Le nom du jeu de données doit correspondre à un jeu de données défini dans le fichier .rdl. Toutes les valeurs de champs doivent être des chaînes — convertissez les nombres et les dates avant de les passer.
Formats d'export
| Chaîne de format | Sortie | Disponible dans |
|---|---|---|
pdf | Tous les modes | |
csv | Texte CSV | Tous les modes |
xlsx | Classeur Excel | Tous les modes |
xml | Données XML | Tous les modes |
rtf | Rich Text Format | Tous les modes |
tif | Image TIFF (couleur) | Tous les modes |
html | HTML | Tous les modes |
xlsx_table | Excel (style tableau) | ReportAot + natif uniquement |
tifb | Image TIFF (noir & blanc) | ReportAot + natif uniquement |
mht | Archive web MHTML | ReportAot + natif uniquement |
pdf. Toutes les méthodes sont synchrones — encapsulez-les dans asyncio.get_event_loop().run_in_executor(None, ...) si vous devez les appeler depuis du code asynchrone sans bloquer.