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:

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

webView.loadDataWithBaseURL(
       
"file:///android_asset/images/",
        htmlBody
,
       
"text/HTML",
       
"UTF-8",
       
null
)
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.

webView.loadUrl("https://developer.android.com/about/index.html")
// 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:

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