Печать HTML-документов

Для печати контента, помимо простой фотографии, на Android требуется составить текст и графику в печатном документе. Платформа Android предоставляет возможность использовать HTML для составления документа и его печати с минимальным количеством кода.

В Android 4.4 (уровень API 19) класс WebView был обновлен и теперь позволяет печатать HTML-содержимое. Класс позволяет вам загрузить локальный ресурс HTML или загрузить страницу из Интернета, создать задание на печать и передать его службам печати Android.

В этом уроке показано, как быстро создать HTML-документ, содержащий текст и графику, и использовать WebView для его печати.

Загрузите HTML-документ

Печать HTML-документа с помощью WebView включает загрузку HTML-ресурса или создание HTML-документа в виде строки. В этом разделе описывается, как создать строку HTML и загрузить ее в WebView для печати.

Этот объект представления обычно используется как часть макета действия. Однако если ваше приложение не использует WebView , вы можете создать экземпляр класса специально для целей печати. Основные шаги для создания этого пользовательского представления печати:

  1. Создайте WebViewClient , который запускает задание печати после загрузки ресурса HTML.
  2. Загрузите ресурс HTML в объект WebView .

В следующем примере кода показано, как создать простой WebViewClient и загрузить HTML-документ, созданный «на лету».

Котлин

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

Примечание. Убедитесь, что вызов для создания задания печати происходит в методе onPageFinished() класса WebViewClient , созданного в предыдущем разделе. Если вы не дождетесь завершения загрузки страницы, результат печати может оказаться неполным или пустым, либо может произойти полный сбой.

Примечание. В приведенном выше примере кода содержится экземпляр объекта WebView , поэтому мусор не собирается перед созданием задания печати. Обязательно сделайте то же самое в своей реализации, иначе процесс печати может завершиться неудачно.

Если вы хотите включить графику на страницу, поместите графические файлы в каталог assets/ вашего проекта и укажите базовый URL-адрес в первом параметре метода loadDataWithBaseURL() , как показано в следующем примере кода:

Котлин

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

Ява

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

Вы также можете загрузить веб-страницу для печати, заменив метод loadDataWithBaseURL() на loadUrl() как показано ниже.

Котлин

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

При использовании WebView для создания документов для печати следует учитывать следующие ограничения:

  • В документ нельзя добавлять верхние и нижние колонтитулы, включая номера страниц.
  • Параметры печати HTML-документа не включают возможность печати диапазонов страниц, например: Печать страниц со 2 по 4 из 10-страничного HTML-документа не поддерживается.
  • Экземпляр WebView может обрабатывать только одно задание печати одновременно.
  • Документ HTML, содержащий атрибуты печати CSS, такие как свойства ландшафта, не поддерживается.
  • Вы не можете использовать JavaScript в документе HTML для запуска печати.

Примечание. Содержимое объекта WebView , включенного в макет, также можно распечатать после загрузки документа.

Если вы хотите создать более персонализированный вывод на печать и иметь полный контроль над отображением содержимого на печатной странице, перейдите к следующему уроку: Урок «Печать пользовательского документа» .

После создания WebView и загрузки содержимого HTML ваше приложение почти завершило свою часть процесса печати. Следующие шаги — доступ к PrintManager , создание адаптера печати и, наконец, создание задания на печать. Следующий пример иллюстрирует, как выполнить эти шаги:

Котлин

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

В этом примере сохраняется экземпляр объекта PrintJob для использования приложением, что не является обязательным. Ваше приложение может использовать этот объект для отслеживания хода выполнения задания печати по мере его обработки. Этот подход полезен, когда вы хотите отслеживать состояние задания печати в вашем приложении на предмет завершения, сбоя или отмены пользователем. Создание уведомления в приложении не требуется, поскольку платформа печати автоматически создает системное уведомление для задания печати.