O segundo Visualização do Desenvolvedor do Android 11 já está disponível, teste e compartilhe seu feedback.

Como imprimir documentos HTML

A impressão de conteúdos que vão além de uma foto simples no Android requer a composição de texto e gráficos em um documento de impressão. O framework do Android oferece uma maneira de usar HTML para compor um documento e imprimi-lo com pouquíssimo código.

No Android 4.4 (API de nível 19), a classe WebView foi atualizada para habilitar a impressão de conteúdo HTML. A classe permite carregar um recurso HTML local ou fazer o download de uma página da Web, criar um trabalho de impressão e enviá-lo aos serviços de impressão do Android.

Esta lição mostra como criar rapidamente um documento HTML com texto e gráficos e usar o WebView para imprimi-lo.

Carregar um documento HTML

Imprimir um documento HTML com WebView envolve carregar um recurso HTML ou criar um documento HTML como uma string. Esta seção descreve como criar uma string HTML e carregá-la em um WebView para impressão.

Esse objeto de visualização normalmente é usado como parte de um layout de atividade. No entanto, se seu aplicativo não estiver usando um WebView, você poderá criar uma instância da classe especificamente para impressão. As principais etapas para a criação dessa visualização de impressão personalizada são as seguintes:

  1. Crie um WebViewClient que inicie um trabalho de impressão após o carregamento do recurso HTML.
  2. Carregue o recurso HTML no objeto WebView.

O exemplo de código a seguir demonstra como criar um WebViewClient simples e carregar um documento HTML criado em tempo real:

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

Observação: a chamada para gerar um trabalho de impressão precisa ocorrer no método onPageFinished() do WebViewClient criado na seção anterior. Se você não esperar até que o carregamento da página esteja concluído, a saída de impressão pode ficar incompleta ou em branco ou pode falhar completamente.

Observação: o código de exemplo acima contém uma instância do objeto WebView para que ele não seja coletado como lixo antes da criação do trabalho de impressão. É necessário fazer o mesmo em sua própria implementação, caso contrário, o processo de impressão poderá falhar.

Caso queira incluir gráficos na página, coloque os arquivos gráficos no diretório assets/ do seu projeto e especifique um URL base no primeiro parâmetro do método loadDataWithBaseURL(), conforme mostrado no exemplo de código a seguir:

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

Também é possível carregar uma página da Web para impressão, substituindo o método loadDataWithBaseURL() por loadUrl(), conforme mostrado abaixo.

Kotlin

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

Java

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

Ao usar o WebView para criar documentos de impressão, é necessário estar ciente das seguintes limitações:

  • Não é possível adicionar cabeçalhos ou rodapés, incluindo números de página, ao documento.
  • As opções de impressão para o documento HTML não incluem a capacidade de imprimir intervalos de páginas. Não é possível imprimir as páginas 2 a 4 de um documento HTML de 10 páginas, por exemplo.
  • Uma instância do WebView só pode processar um trabalho de impressão por vez.
  • Documentos HTML com atributos de impressão CSS, como propriedades de paisagem, não são compatíveis.
  • Não é possível usar JavaScript em um documento HTML para acionar a impressão.

Observação: o conteúdo de um objeto WebView incluído em um layout também pode ser impresso após carregar um documento.

Se você quiser criar uma saída de impressão mais personalizada e ter controle total do desenho do conteúdo na página impressa, vá para a próxima lição: Como imprimir um documento personalizado.

Depois de criar um WebView e carregar seu conteúdo HTML, o aplicativo estará perto de concluir o respectivo processo de impressão. As próximas etapas são acessar o PrintManager, criar um adaptador de impressão e, finalmente, criar um trabalho de impressão. O exemplo a seguir ilustra como realizar essas etapas:

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

Esse exemplo salva uma instância do objeto PrintJob para uso do aplicativo, o que não é necessário. Seu aplicativo pode usar esse objeto para acompanhar o andamento do trabalho de impressão enquanto ele acontece. Essa abordagem é útil quando você quer monitorar o status do trabalho de impressão em seu aplicativo para verificar se houve conclusão, falha ou cancelamento pelo usuário. Não é necessário criar uma notificação no app, porque o framework de impressão cria uma notificação do sistema para o trabalho de impressão automaticamente.