Stampa di documenti HTML

Per stampare contenuti oltre una semplice foto su Android, è necessario comporre testo e grafica in un documento stampato. Il framework Android consente di utilizzare il codice HTML per scrivere un documento e stamparlo con un minimo di codice.

In Android 4.4 (livello API 19), la classe WebView è stata aggiornata per consentire la stampa di contenuti HTML. La classe consente di caricare una risorsa HTML locale o di scaricare una pagina dal Web, creare un processo di stampa e passarlo ai servizi di stampa di Android.

Questa lezione spiega come creare rapidamente un documento HTML contenente testo e grafica e utilizzare WebView per stamparlo.

Carica un documento HTML

La stampa di un documento HTML con WebView comporta il caricamento di una risorsa HTML o la creazione di un documento HTML come stringa. Questa sezione descrive come creare una stringa HTML e caricarla in un WebView per la stampa.

Questo oggetto visualizzazione viene solitamente utilizzato come parte di un layout di attività. Tuttavia, se la tua applicazione non utilizza WebView, puoi creare un'istanza della classe appositamente per la stampa. Di seguito sono riportati i passaggi principali per la creazione di questa visualizzazione di stampa personalizzata:

  1. Crea un WebViewClient che avvii un processo di stampa dopo il caricamento della risorsa HTML.
  2. Carica la risorsa HTML nell'oggetto WebView.

Il seguente esempio di codice mostra come creare una semplice WebViewClient e caricare un documento HTML creato all'istante:

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;
}

Nota: assicurati che la chiamata per la generazione di un processo di stampa venga eseguita nel metodo onPageFinished() dell'WebViewClient creato nella sezione precedente. Se non attendi il termine del caricamento della pagina, l'output di stampa potrebbe essere incompleto o vuoto oppure non riuscire completamente.

Nota: il codice di esempio riportato sopra contiene un'istanza dell'oggetto WebView in modo che non venga eseguita la garbage collection prima della creazione del processo di stampa. Assicurati di svolgere la stessa operazione nella tua implementazione, altrimenti il processo di stampa potrebbe non riuscire.

Se vuoi includere elementi grafici nella pagina, inserisci i file grafici nella directory assets/ del progetto e specifica un URL di base nel primo parametro del metodo loadDataWithBaseURL(), come mostrato nel seguente esempio di codice:

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);

Puoi anche caricare una pagina web da stampare sostituendo il metodo loadDataWithBaseURL() con loadUrl(), come mostrato di seguito.

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");

Quando utilizzi WebView per creare documenti di stampa, tieni presente le seguenti limitazioni:

  • Non puoi aggiungere al documento intestazioni o piè di pagina, inclusi i numeri di pagina.
  • Le opzioni di stampa per il documento HTML non includono la possibilità di stampare intervalli di pagine, ad esempio: la stampa delle pagine da 2 a 4 di un documento HTML di 10 pagine non è supportata.
  • Un'istanza di WebView può elaborare un solo processo di stampa alla volta.
  • Un documento HTML contenente attributi di stampa CSS, come le proprietà orizzontali, non è supportato.
  • Non puoi utilizzare JavaScript in un documento HTML per attivare la stampa.

Nota: il contenuto di un oggetto WebView incluso in un layout può essere stampato anche dopo il caricamento di un documento.

Se vuoi creare un output di stampa più personalizzato e avere il controllo completo del disegno dei contenuti sulla pagina stampata, passa alla lezione successiva: Stampa di un documento personalizzato.

Dopo aver creato un WebView e caricato i tuoi contenuti HTML, l'applicazione è quasi completata con la sua parte del processo di stampa. I passaggi successivi includono l'accesso a PrintManager, la creazione di un adattatore di stampa e, infine, la creazione di un processo di stampa. L'esempio seguente illustra come eseguire questi passaggi:

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);
}

Questo esempio salva un'istanza dell'oggetto PrintJob per l'utilizzo da parte dell'applicazione, il che non è obbligatorio. L'applicazione potrebbe utilizzare questo oggetto per tenere traccia dell'avanzamento del processo di stampa durante l'elaborazione. Questo approccio è utile quando vuoi monitorare lo stato del processo di stampa nella tua applicazione per il completamento, l'errore o l'annullamento da parte dell'utente. Non è necessario creare una notifica in-app perché il framework di stampa crea automaticamente una notifica di sistema per il processo di stampa.