Output Management dans ABAP Cloud

Catégorie
Integration
Publié
Auteur
Johannes

L’Output Management dans ABAP Cloud diffère fondamentalement de l’On-Premise. Le Spool classique avec des transactions comme SP01, SP02 et SPAD n’est pas disponible sur SAP BTP. Au lieu de cela, ABAP Cloud utilise des concepts modernes et Cloud-natives pour le traitement des sorties.

Concepts de base

Dans ABAP Cloud, il existe plusieurs façons de sortir des documents :

ConceptDescriptionCas d’utilisation
SAP Cloud Print ManagerService d’impression CloudImpression directe sur imprimantes réseau
Génération PDFCréer des documents en PDFTéléchargement, envoi par e-mail
Output ControlGestion centralisée des sortiesSortie basée sur formulaires
Envoi par e-mailEnvoyer des documents par e-mailFactures, notifications

Vue d’ensemble de l’architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│ Output Management dans ABAP Cloud │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ RAP Business Object / Application │ │
│ │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ Output Request │ │ │
│ │ │ (Ordre impres.) │ │ │
│ │ └──────────┬──────────┘ │ │
│ └─────────────┼────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Options de sortie │ │
│ │ │ │
│ │ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │ │
│ │ │ Cloud Print │ │ Téléchargement │ │ Envoi par e-mail │ │ │
│ │ │ Manager │ │ PDF │ │ │ │ │
│ │ │ - Print Queue │ │ - RAP Action │ │ - cl_bcs_mail │ │ │
│ │ │ - Imprimante │ │ - Attachment │ │ - Attachment │ │ │
│ │ └───────────────────┘ └───────────────────┘ └───────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Destinations de sortie │ │
│ │ - Imprimante réseau via Cloud Print │ │
│ │ - Téléchargement navigateur │ │
│ │ - Boîte e-mail │ │
│ │ - Gestion documentaire (DMS) │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘

SAP Cloud Print Manager

Le SAP Cloud Print Manager est le remplaçant Cloud-native du système Spool classique. Il permet l’impression sur des imprimantes physiques depuis le Cloud.

Composants

ComposantDescription
Cloud Print ManagerService SAP BTP pour gestion des ordres d’impression
Print QueueFile d’attente pour ordres d’impression
Print AgentComposant On-Premise qui connecte les imprimantes
PrinterImprimante de sortie configurée

Architecture avec Print Agent

┌───────────────────────────────────────────────────────────────────────────┐
│ Architecture Cloud Print │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ SAP BTP │ │
│ │ │ │
│ │ ┌───────────────────┐ ┌───────────────────┐ │ │
│ │ │ ABAP Cloud │ ────► │ Cloud Print │ │ │
│ │ │ Application │ HTTP │ Manager Service │ │ │
│ │ └───────────────────┘ └─────────┬─────────┘ │ │
│ │ │ │ │
│ └──────────────────────────────────────────┼───────────────────────────┘ │
│ │ │
│ │ Cloud Connector │
│ │ ou accès direct │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ On-Premise / Réseau entreprise │ │
│ │ │ │
│ │ ┌───────────────────┐ ┌───────────────────┐ │ │
│ │ │ Print Agent │ ────► │ Imprimante │ │ │
│ │ │ (SAP Software) │ Print │ réseau │ │ │
│ │ └───────────────────┘ └───────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘

Configurer Print Queue

La configuration se fait dans l’environnement SAP BTP Cloud Foundry :

  1. Activer le service Cloud Print Manager dans le Subaccount BTP
  2. Créer une Service Instance
  3. Générer une Service Key pour l’authentification
  4. Installer et configurer le Print Agent On-Premise

Exemple de code : Créer un ordre d’impression

" Ordre d'impression via Cloud Print Manager
CLASS zcl_print_manager DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_print_request,
queue_name TYPE string,
document_name TYPE string,
content TYPE xstring,
content_type TYPE string, " application/pdf, text/plain
copies TYPE i,
duplex TYPE abap_bool,
color TYPE abap_bool,
END OF ty_print_request.
TYPES:
BEGIN OF ty_print_response,
job_id TYPE string,
status TYPE string,
message TYPE string,
queue_name TYPE string,
END OF ty_print_response.
METHODS:
constructor
IMPORTING iv_comm_scenario TYPE string.
METHODS:
submit_print_job
IMPORTING is_request TYPE ty_print_request
RETURNING VALUE(rs_response) TYPE ty_print_response
RAISING cx_http_dest_provider_error
cx_web_http_client_error.
METHODS:
get_print_queues
RETURNING VALUE(rt_queues) TYPE string_table
RAISING cx_http_dest_provider_error
cx_web_http_client_error.
METHODS:
get_job_status
IMPORTING iv_job_id TYPE string
RETURNING VALUE(rv_status) TYPE string
RAISING cx_http_dest_provider_error
cx_web_http_client_error.
PRIVATE SECTION.
DATA: mv_comm_scenario TYPE string.
METHODS:
get_http_client
RETURNING VALUE(ro_client) TYPE REF TO if_web_http_client
RAISING cx_http_dest_provider_error
cx_web_http_client_error.
ENDCLASS.
CLASS zcl_print_manager IMPLEMENTATION.
METHOD constructor.
mv_comm_scenario = iv_comm_scenario.
ENDMETHOD.
METHOD submit_print_job.
" Créer HTTP Client
DATA(lo_client) = get_http_client( ).
TRY.
DATA(lo_request) = lo_client->get_http_request( ).
" Chemin pour Print Job API
lo_request->set_uri_path( '/v1/print-jobs' ).
lo_request->set_header_field(
i_name = 'Content-Type"
i_value = 'application/json"
).
" Request Body
DATA(lv_content_base64) = cl_http_utility=>encode_base64( is_request-content ).
DATA(lv_request_body) = |\{| &&
|"queueName": "{ is_request-queue_name }",| &&
|"documentName": "{ is_request-document_name }",| &&
|"contentType": "{ is_request-content_type }",| &&
|"content": "{ lv_content_base64 }",| &&
|"numberOfCopies": { is_request-copies },| &&
|"duplex": { COND #( WHEN is_request-duplex = abap_true THEN 'true' ELSE 'false' ) },| &&
|"color": { COND #( WHEN is_request-color = abap_true THEN 'true' ELSE 'false' ) }| &&
|\}|.
lo_request->set_text( lv_request_body ).
" Appeler l'API
DATA(lo_response) = lo_client->execute( if_web_http_client=>post ).
DATA(lv_status) = lo_response->get_status( ).
IF lv_status-code = 201 OR lv_status-code = 200.
" Parser la réponse
DATA(lv_response_json) = lo_response->get_text( ).
" Extraire le Job ID (simplifié)
rs_response-status = 'SUBMITTED'.
rs_response-queue_name = is_request-queue_name.
" Parser le Job ID depuis JSON...
ELSE.
rs_response-status = 'ERROR'.
rs_response-message = lo_response->get_text( ).
ENDIF.
CATCH cx_web_http_client_error INTO DATA(lx_http).
rs_response-status = 'ERROR'.
rs_response-message = lx_http->get_text( ).
ENDTRY.
lo_client->close( ).
ENDMETHOD.
METHOD get_print_queues.
DATA(lo_client) = get_http_client( ).
TRY.
DATA(lo_request) = lo_client->get_http_request( ).
lo_request->set_uri_path( '/v1/queues' ).
DATA(lo_response) = lo_client->execute( if_web_http_client=>get ).
IF lo_response->get_status( )-code = 200.
" Parser les queues depuis JSON
DATA(lv_json) = lo_response->get_text( ).
" JSON-Parsing avec /ui2/cl_json...
ENDIF.
CLEANUP.
lo_client->close( ).
ENDTRY.
ENDMETHOD.
METHOD get_job_status.
DATA(lo_client) = get_http_client( ).
TRY.
DATA(lo_request) = lo_client->get_http_request( ).
lo_request->set_uri_path( |/v1/print-jobs/{ iv_job_id }| ).
DATA(lo_response) = lo_client->execute( if_web_http_client=>get ).
IF lo_response->get_status( )-code = 200.
" Parser le statut depuis JSON
rv_status = 'COMPLETED'. " simplifié
ELSE.
rv_status = 'UNKNOWN'.
ENDIF.
CLEANUP.
lo_client->close( ).
ENDTRY.
ENDMETHOD.
METHOD get_http_client.
" Destination depuis Communication Arrangement
DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = mv_comm_scenario
service_id = 'PRINT_SERVICE"
).
ro_client = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
ENDMETHOD.
ENDCLASS.

Output Control - Gestion centralisée des sorties

Pour les scénarios complexes avec différents canaux de sortie, SAP propose Output Control (également connu sous le nom de PPF - Post Processing Framework).

Concept

Output Control permet :

  • Sortie automatique de documents basée sur des règles
  • Différents canaux de sortie (impression, e-mail, EDI)
  • Contrôle du timing (immédiat, planifié, manuel)
  • Logique de retry en cas d’erreur

Types de sortie

Type de sortieDescriptionExemple
PrintImpression physiqueBon de livraison
EmailEnvoi par e-mailConfirmation de commande
EDIÉchange de données électroniquesCommande au fournisseur
ArchiveArchivageFacture vers DMS

Exemple de code : Créer une demande de sortie

" Créer une Output Request pour un document
CLASS zcl_output_control DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_output_request,
document_id TYPE string,
document_type TYPE string,
output_type TYPE string, " PRINT, EMAIL, ARCHIVE
output_channel TYPE string,
recipient TYPE string,
priority TYPE i,
scheduled_time TYPE timestampl,
END OF ty_output_request.
METHODS:
create_output_request
IMPORTING is_request TYPE ty_output_request
RETURNING VALUE(rv_request_id) TYPE string.
METHODS:
process_output_request
IMPORTING iv_request_id TYPE string
RAISING zcx_output_error.
METHODS:
get_output_status
IMPORTING iv_request_id TYPE string
RETURNING VALUE(rv_status) TYPE string.
ENDCLASS.
CLASS zcl_output_control IMPLEMENTATION.
METHOD create_output_request.
" Sauvegarder l'Output Request dans une table
DATA ls_request TYPE zoutput_request.
ls_request-request_uuid = cl_system_uuid=>create_uuid_x16_static( ).
ls_request-document_id = is_request-document_id.
ls_request-document_type = is_request-document_type.
ls_request-output_type = is_request-output_type.
ls_request-output_channel = is_request-output_channel.
ls_request-recipient = is_request-recipient.
ls_request-priority = is_request-priority.
ls_request-scheduled_time = is_request-scheduled_time.
ls_request-status = 'PENDING'.
ls_request-created_at = cl_abap_tstmp=>utclong_current( ).
INSERT zoutput_request FROM @ls_request.
rv_request_id = cl_system_uuid=>convert_uuid_x16_static(
uuid = ls_request-request_uuid
).
ENDMETHOD.
METHOD process_output_request.
" Charger la request
SELECT SINGLE *
FROM zoutput_request
WHERE request_uuid = @( cl_system_uuid=>convert_uuid_c36_static( iv_request_id ) )
INTO @DATA(ls_request).
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE zcx_output_error
EXPORTING
textid = zcx_output_error=>request_not_found.
ENDIF.
" Statut sur Processing
UPDATE zoutput_request
SET status = 'PROCESSING"
WHERE request_uuid = @ls_request-request_uuid.
TRY.
" Traiter selon le type de sortie
CASE ls_request-output_type.
WHEN 'PRINT'.
process_print_output( ls_request ).
WHEN 'EMAIL'.
process_email_output( ls_request ).
WHEN 'ARCHIVE'.
process_archive_output( ls_request ).
WHEN OTHERS.
RAISE EXCEPTION TYPE zcx_output_error
EXPORTING
textid = zcx_output_error=>unknown_output_type.
ENDCASE.
" Succès
UPDATE zoutput_request
SET status = 'COMPLETED',
processed_at = @( cl_abap_tstmp=>utclong_current( ) )
WHERE request_uuid = @ls_request-request_uuid.
CATCH zcx_output_error INTO DATA(lx_error).
" Enregistrer l'erreur
UPDATE zoutput_request
SET status = 'ERROR',
error_message = @( lx_error->get_text( ) )
WHERE request_uuid = @ls_request-request_uuid.
RAISE EXCEPTION lx_error.
ENDTRY.
ENDMETHOD.
METHOD get_output_status.
SELECT SINGLE status
FROM zoutput_request
WHERE request_uuid = @( cl_system_uuid=>convert_uuid_c36_static( iv_request_id ) )
INTO @rv_status.
ENDMETHOD.
ENDCLASS.

Envoi par e-mail comme canal de sortie

L’envoi par e-mail est une alternative courante à l’impression dans ABAP Cloud.

Exemple de code : Envoyer un document par e-mail

" Envoyer un document par e-mail
CLASS zcl_email_document_sender DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_email_request,
recipient TYPE string,
subject TYPE string,
body_text TYPE string,
attachment TYPE xstring,
attachment_name TYPE string,
attachment_type TYPE string,
END OF ty_email_request.
METHODS:
send_document
IMPORTING is_request TYPE ty_email_request
RAISING cx_bcs_exception.
ENDCLASS.
CLASS zcl_email_document_sender IMPLEMENTATION.
METHOD send_document.
" Envoyer un e-mail avec pièce jointe
DATA(lo_mail) = cl_bcs_mail_message=>create_instance( ).
" Définir le destinataire
lo_mail->add_recipient( is_request-recipient ).
" Définir le sujet
lo_mail->set_subject( is_request-subject ).
" Définir le corps
lo_mail->set_main(
cl_bcs_mail_textpart=>create_instance(
iv_content = is_request-body_text
iv_content_type = 'text/plain"
)
).
" Ajouter une pièce jointe
IF is_request-attachment IS NOT INITIAL.
lo_mail->add_attachment(
cl_bcs_mail_binarypart=>create_instance(
iv_content = is_request-attachment
iv_content_type = is_request-attachment_type
iv_filename = is_request-attachment_name
)
).
ENDIF.
" Envoyer l'e-mail
lo_mail->send( ).
ENDMETHOD.
ENDCLASS.

Intégration avec RAP

" RAP Action pour envoi de document
METHOD sendDocument FOR MODIFY
IMPORTING keys FOR ACTION Document~sendDocument RESULT result.
" Charger les documents
READ ENTITIES OF zi_document IN LOCAL MODE
ENTITY Document
ALL FIELDS WITH CORRESPONDING #( keys )
RESULT DATA(lt_documents).
LOOP AT lt_documents INTO DATA(ls_document).
TRY.
" Générer le PDF
DATA(lo_pdf_gen) = NEW zcl_pdf_generator( ).
DATA(lv_pdf) = lo_pdf_gen->generate_document_pdf( ls_document ).
" Envoyer par e-mail
DATA(lo_email_sender) = NEW zcl_email_document_sender( ).
lo_email_sender->send_document(
VALUE #(
recipient = ls_document-contact_email
subject = |Votre document : { ls_document-document_number }|
body_text = |Mesdames, Messieurs,\n\n| &&
|Veuillez trouver ci-joint votre document.\n\n| &&
|Cordialement|
attachment = lv_pdf
attachment_name = |Document_{ ls_document-document_number }.pdf|
attachment_type = 'application/pdf"
)
).
" Message de succès
APPEND VALUE #(
%tky = ls_document-%tky
%param = ls_document
) TO result.
CATCH cx_bcs_exception INTO DATA(lx_mail).
APPEND VALUE #(
%tky = ls_document-%tky
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = lx_mail->get_text( )
)
) TO reported-document.
ENDTRY.
ENDLOOP.
ENDMETHOD.

Alternatives au Spool classique

Comparaison On-Premise vs. Cloud

AspectOn-Premise (Spool)ABAP Cloud
Ordres d’impressionSP01, Ordres SpoolCloud Print Manager, Print Queues
Configuration imprimanteSPADBTP Cockpit, Print Agent
FormulairesSmartForms, Adobe FormsSAP Forms Service, services externes
Gestion sortieNACE, Output TypesOutput Control, RAP Actions
ArchivageArchiveLinkSAP Document Management
MonitoringSP02, SMXApps Fiori, Logging

Alternative 1 : Téléchargement PDF au lieu d’impression

L’alternative la plus simple à l’impression est le téléchargement PDF :

" Téléchargement PDF via RAP Action
action downloadDocument
parameter ZA_DownloadParams
result [1] ZA_DownloadResult;

L’utilisateur peut ensuite imprimer le PDF localement.

Alternative 2 : Impression basée navigateur

" Générer HTML avec Print-CSS
CLASS zcl_browser_print DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
generate_printable_html
IMPORTING is_data TYPE any
RETURNING VALUE(rv_html) TYPE string.
ENDCLASS.
CLASS zcl_browser_print IMPLEMENTATION.
METHOD generate_printable_html.
" HTML avec CSS optimisé pour impression
rv_html =
|<!DOCTYPE html>| &&
|<html>| &&
|<head>| &&
|<style>| &&
|@media screen \{| &&
| .print-button \{ display: block; margin: 20px; padding: 10px; \}| &&
|\}| &&
|@media print \{| &&
| .print-button \{ display: none; \}| &&
| body \{ margin: 0; padding: 15mm; font-family: Arial; \}| &&
| @page \{ size: A4; margin: 15mm; \}| &&
| table \{ width: 100%; border-collapse: collapse; \}| &&
| th, td \{ border: 1px solid #000; padding: 5px; \}| &&
|\}| &&
|</style>| &&
|</head>| &&
|<body>| &&
|<button class="print-button" onclick="window.print()">| &&
| Imprimer le document| &&
|</button>| &&
|<!-- Contenu du document ici -->| &&
|</body>| &&
|</html>|.
ENDMETHOD.
ENDCLASS.

Alternative 3 : Services d’impression tiers

Pour des besoins spécifiques, des services d’impression externes peuvent être utilisés :

" Intégration avec service d'impression externe
CLASS zcl_external_print_service DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
submit_to_print_service
IMPORTING iv_document TYPE xstring
iv_printer_id TYPE string
RETURNING VALUE(rv_job_id) TYPE string
RAISING cx_web_http_client_error.
ENDCLASS.

Configuration d’imprimante

Configurer Print Agent

Le Print Agent est un composant On-Premise qui établit la connexion entre Cloud Print Manager et les imprimantes locales :

  1. Téléchargement : Télécharger Print Agent depuis SAP Software Center
  2. Installation : Installer sur un serveur dans le réseau d’entreprise
  3. Configuration : Établir la connexion au service BTP
  4. Enregistrer imprimantes : Enregistrer les imprimantes locales sur l’Agent

Propriétés d’imprimante

" Obtenir les informations d'imprimante
TYPES:
BEGIN OF ty_printer_info,
printer_id TYPE string,
printer_name TYPE string,
queue_name TYPE string,
location TYPE string,
capabilities TYPE string_table, " duplex, color, staple
status TYPE string, " online, offline, error
END OF ty_printer_info.

Sélection d’imprimante dans l’application

" Sélection d'imprimante pour l'utilisateur
METHOD get_available_printers.
DATA(lo_print_mgr) = NEW zcl_print_manager( 'Z_PRINT_COMM' ).
" Obtenir les queues
DATA(lt_queues) = lo_print_mgr->get_print_queues( ).
" Afficher dans l'UI (par ex. comme Value Help)
rt_printers = lt_queues.
ENDMETHOD.

Monitoring et gestion des erreurs

Surveiller les ordres d’impression

" Classe de monitoring pour ordres d'impression
CLASS zcl_print_monitor DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_job_info,
job_id TYPE string,
document_name TYPE string,
queue_name TYPE string,
status TYPE string,
submitted_at TYPE timestampl,
completed_at TYPE timestampl,
error_message TYPE string,
END OF ty_job_info.
METHODS:
get_pending_jobs
RETURNING VALUE(rt_jobs) TYPE STANDARD TABLE OF ty_job_info WITH KEY job_id.
METHODS:
get_failed_jobs
RETURNING VALUE(rt_jobs) TYPE STANDARD TABLE OF ty_job_info WITH KEY job_id.
METHODS:
retry_failed_job
IMPORTING iv_job_id TYPE string
RAISING zcx_output_error.
ENDCLASS.

Logging avec Application Log

" Enregistrer les actions de sortie
CLASS zcl_output_logger DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
log_output_request
IMPORTING iv_request_id TYPE string
iv_action TYPE string
iv_status TYPE string
iv_message TYPE string OPTIONAL.
ENDCLASS.
CLASS zcl_output_logger IMPLEMENTATION.
METHOD log_output_request.
TRY.
DATA(lo_log) = cl_bali_log=>create_with_header(
header = cl_bali_header_setter=>create(
object = 'ZOUTPUT"
subobject = 'PRINT"
)
).
DATA(lv_severity) = COND #(
WHEN iv_status = 'ERROR"
THEN if_bali_constants=>c_severity_error
WHEN iv_status = 'WARNING"
THEN if_bali_constants=>c_severity_warning
ELSE if_bali_constants=>c_severity_status
).
lo_log->add_item(
item = cl_bali_message_setter=>create(
severity = lv_severity
id = 'ZOUTPUT"
number = '001"
variable_1 = CONV #( iv_request_id )
variable_2 = CONV #( iv_action )
variable_3 = CONV #( iv_message )
)
).
cl_bali_log_db=>get_instance( )->save_log( log = lo_log ).
CATCH cx_bali_runtime.
" Ignorer les erreurs de logging
ENDTRY.
ENDMETHOD.
ENDCLASS.

Best Practices

Recommandations pour Output Management

AspectRecommandation
Documents simplesTéléchargement PDF avec impression navigateur
Impression régulièreCloud Print Manager avec Print Agent
Sortie de masseTraitement asynchrone avec Background Jobs
TraçabilitéApplication Logging pour toutes les sorties
Gestion erreursLogique de retry et notifications

Checklist pour implémentation de sortie

  1. Définir le canal de sortie : Impression, e-mail, téléchargement ?
  2. Définir le format de document : PDF, HTML, autre ?
  3. Configurer imprimantes/destinations : Print Agent, serveur e-mail
  4. Implémenter la gestion d’erreurs : Retries, notifications
  5. Mettre en place le monitoring : Logging, suivi de statut
  6. Vérifier les autorisations : Qui peut sortir quoi ?

Sujets complémentaires

Résumé

Output Management dans ABAP Cloud nécessite de nouvelles approches :

  1. Cloud Print Manager remplace le Spool classique et permet l’impression Cloud-vers-On-Premise
  2. Print Agent connecte le Cloud aux imprimantes réseau locales
  3. Téléchargement PDF est l’alternative la plus simple à l’impression directe
  4. Envoi par e-mail convient pour la livraison automatisée de documents
  5. Output Control gère des scénarios de sortie complexes avec différents canaux
  6. Monitoring et logging sont essentiels pour les systèmes productifs

Le choix de la bonne méthode de sortie dépend de vos besoins : pour des scénarios simples, le téléchargement PDF suffit, pour des exigences d’entreprise, Cloud Print Manager est la solution robuste.