Imprimer des documents HTML

Pour imprimer du contenu au-delà d'une simple photo sur Android, vous devez rédiger du texte et des graphiques dans un document imprimé. Le framework Android permet d'utiliser le langage HTML pour composer un document et l'imprimer avec un minimum de code.

Dans Android 4.4 (niveau d'API 19), la classe WebView a été mise à jour pour permettre l'impression de contenu HTML. La classe vous permet de charger une ressource HTML locale ou de télécharger une page depuis le Web, de créer une tâche d'impression et de la transmettre aux services d'impression d'Android.

Cette leçon vous explique comment créer rapidement un document HTML contenant du texte et des graphiques, puis utiliser WebView pour l'imprimer.

Charger un document HTML

L'impression d'un document HTML avec WebView implique le chargement d'une ressource HTML ou la création d'un document HTML sous forme de chaîne. Cette section explique comment créer une chaîne HTML et la charger dans un WebView pour l'imprimer.

Cet objet de vue est généralement utilisé dans la mise en page d'une activité. Toutefois, si votre application n'utilise pas de WebView, vous pouvez créer une instance de la classe spécialement à des fins d'impression. Voici les principales étapes à suivre pour créer ce mode d'affichage personnalisé:

  1. Créez un WebViewClient qui lance une tâche d'impression après le chargement de la ressource HTML.
  2. Chargez la ressource HTML dans l'objet WebView.

L'exemple de code suivant montre comment créer un WebViewClient simple et charger un document HTML créé à la volée:

Kotlin

private var mWebView: WebView? = null

private fun doWebViewPrint() {
    // Create a WebView object specifically for printing
    val webView = WebView(activity)
    webView.webViewClient = object : WebViewClient() {

        override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = false

        override fun onPageFinished(view: WebView, url: String) {
            Log.i(TAG, "page finished loading $url")
            createWebPrintJob(view)
            mWebView = null
        }
    }

    // Generate an HTML document on the fly:
    val htmlDocument =
            "<html><body><h1>Test Content</h1><p>Testing, testing, testing...</p></body></html>"
    webView.loadDataWithBaseURL(null, htmlDocument, "text/HTML", "UTF-8", null)

    // Keep a reference to WebView object until you pass the PrintDocumentAdapter
    // to the PrintManager
    mWebView = webView
}

Java

private WebView mWebView;

private void doWebViewPrint() {
    // Create a WebView object specifically for printing
    WebView webView = new WebView(getActivity());
    webView.setWebViewClient(new WebViewClient() {

            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                return false;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                Log.i(TAG, "page finished loading " + url);
                createWebPrintJob(view);
                mWebView = null;
            }
    });

    // Generate an HTML document on the fly:
    String htmlDocument = "<html><body><h1>Test Content</h1><p>Testing, " +
            "testing, testing...</p></body></html>";
    webView.loadDataWithBaseURL(null, htmlDocument, "text/HTML", "UTF-8", null);

    // Keep a reference to WebView object until you pass the PrintDocumentAdapter
    // to the PrintManager
    mWebView = webView;
}

Remarque:Assurez-vous que l'appel pour générer une tâche d'impression s'effectue dans la méthode onPageFinished() du WebViewClient que vous avez créé dans la section précédente. Si vous n'attendez pas la fin du chargement de la page, le résultat d'impression peut être incomplet, vide ou échouer complètement.

Remarque:L'exemple de code ci-dessus contient une instance de l'objet WebView afin d'éviter la récupération de mémoire avant la création de la tâche d'impression. Assurez-vous de procéder de la même manière dans votre propre implémentation, sinon le processus d'impression risque d'échouer.

Si vous souhaitez inclure des graphiques dans la page, placez les fichiers graphiques dans le répertoire assets/ de votre projet et spécifiez une URL de base dans le premier paramètre de la méthode loadDataWithBaseURL(), comme indiqué dans l'exemple de code suivant:

Kotlin

webView.loadDataWithBaseURL(
        "file:///android_asset/images/",
        htmlBody,
        "text/HTML",
        "UTF-8",
        null
)

Java

webView.loadDataWithBaseURL("file:///android_asset/images/", htmlBody,
        "text/HTML", "UTF-8", null);

Vous pouvez également charger une page Web pour l'imprimer en remplaçant la méthode loadDataWithBaseURL() par loadUrl(), comme indiqué ci-dessous.

Kotlin

webView.loadUrl("https://developer.android.com/about/index.html")

Java

// Print an existing web page (remember to request INTERNET permission!):
webView.loadUrl("https://developer.android.com/about/index.html");

Lorsque vous utilisez WebView pour créer des documents d'impression, vous devez tenir compte des limites suivantes:

  • Vous ne pouvez pas ajouter d'en-têtes ni de pieds de page au document, y compris des numéros de page.
  • Les options d'impression du document HTML ne permettent pas d'imprimer des plages de pages. Par exemple: l'impression des pages 2 à 4 sur un document HTML de 10 pages n'est pas prise en charge.
  • Une instance de WebView ne peut traiter qu'une seule tâche d'impression à la fois.
  • Les documents HTML contenant des attributs d'impression CSS, tels que les propriétés en mode paysage, ne sont pas acceptés.
  • Vous ne pouvez pas utiliser de code JavaScript dans un document HTML pour déclencher l'impression.

Remarque:Le contenu d'un objet WebView inclus dans une mise en page peut également être imprimé après le chargement d'un document.

Si vous souhaitez créer une sortie d'impression plus personnalisée et contrôler entièrement le dessin de contenu sur la page imprimée, passez à la leçon suivante : Imprimer un document personnalisé.

Après avoir créé un WebView et chargé votre contenu HTML, votre application a presque terminé sa partie du processus d'impression. Les étapes suivantes consistent à accéder à PrintManager, à créer un adaptateur d'impression et à créer une tâche d'impression. L'exemple suivant montre comment effectuer ces étapes:

Kotlin

private fun createWebPrintJob(webView: WebView) {

    // Get a PrintManager instance
    (activity?.getSystemService(Context.PRINT_SERVICE) as? PrintManager)?.let { printManager ->

        val jobName = "${getString(R.string.app_name)} Document"

        // Get a print adapter instance
        val printAdapter = webView.createPrintDocumentAdapter(jobName)

        // Create a print job with name and adapter instance
        printManager.print(
                jobName,
                printAdapter,
                PrintAttributes.Builder().build()
        ).also { printJob ->

            // Save the job object for later status checking
            printJobs += printJob
        }
    }
}

Java

private void createWebPrintJob(WebView webView) {

    // Get a PrintManager instance
    PrintManager printManager = (PrintManager) getActivity()
            .getSystemService(Context.PRINT_SERVICE);

    String jobName = getString(R.string.app_name) + " Document";

    // Get a print adapter instance
    PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(jobName);

    // Create a print job with name and adapter instance
    PrintJob printJob = printManager.print(jobName, printAdapter,
            new PrintAttributes.Builder().build());

    // Save the job object for later status checking
    printJobs.add(printJob);
}

Cet exemple enregistre une instance de l'objet PrintJob pour une utilisation par l'application, ce qui n'est pas obligatoire. Votre application peut utiliser cet objet pour suivre la progression de la tâche d'impression en cours de traitement. Cette approche est utile lorsque vous souhaitez surveiller l'état de la tâche d'impression dans votre application pour détecter son achèvement, son échec ou son annulation par l'utilisateur. La création d'une notification dans l'application n'est pas nécessaire, car le framework d'impression crée automatiquement une notification système pour la tâche d'impression.