Como imprimir documentos HTML

Para imprimir conteúdo além de uma simples foto no Android, é necessário escrever textos e gráficos de uma forma imprimir documento. O framework do Android oferece uma maneira de usar HTML para compor um documento e imprimi-la com o mínimo de código.

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

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

Carregar um documento HTML

Imprimir um documento HTML com WebView envolve o carregamento de um HTML recurso ou criar um documento HTML como uma string. Esta seção descreve como criar um arquivo HTML e carregá-lo em um WebView para exibiçã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, é possível 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 uma WebViewClient que inicie um trabalho de impressão após o recurso HTML é carregado.
  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 ocorre no método onPageFinished() do WebViewClient criado na seção anterior. Se você não esperar até a página o carregamento for concluído, o resultado da impressão poderá estar incompleto ou em branco, ou poderá falhar completamente.

Observação: o código de exemplo acima contém uma instância do Objeto WebView para que não seja coletado como lixo antes do trabalho de impressão é criada. Faça o mesmo na sua implementação. Caso contrário, o processo de impressão podem falhar.

Se você quiser incluir gráficos na página, coloque os arquivos gráficos no assets/ do seu projeto e especifique um URL base no primeiro parâmetro do método loadDataWithBaseURL(), conforme mostrado 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);

Você também pode carregar uma página da Web para impressão substituindo loadDataWithBaseURL() com loadUrl(), conforme mostrado abaixo.

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

Ao usar WebView para criar documentos de impressão, considere o seguinte: estas 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 do documento HTML não incluem a capacidade de imprimir a página por exemplo: a impressão das páginas 2 a 4 de um documento HTML de 10 páginas não é suportada.
  • Uma instância do WebView só pode processar um trabalho de impressão por vez.
  • Um documento HTML que contém atributos de impressão CSS, como propriedades de paisagem, não é suporte.
  • 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 no um layout também pode ser impresso depois de 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 documentos personalizados.

Depois de criar um WebView e carregar o conteúdo HTML, o aplicativo está quase terminando com sua parte do processo de impressão. A próxima etapa é acessar PrintManager, criando um adaptador de impressão e, por fim, uma impressão trabalho. 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);
}

Este exemplo salva uma instância do objeto PrintJob para uso pelo o que não é necessário. O aplicativo pode usar esse objeto para acompanhar o andamento da o trabalho de impressão enquanto ele é processado. Essa abordagem é útil quando você quer monitorar o status do trabalho de impressão no seu pedido para 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.