Для печати контента, помимо простой фотографии, на Android требуется составить текст и графику в печатном документе. Фреймворк Android позволяет использовать HTML для создания документа и его печати с минимальным количеством кода.
В Android 4.4 (уровень API 19) класс WebView был обновлен, чтобы обеспечить печать HTML-контента. Этот класс позволяет загрузить локальный ресурс HTML или скачать страницу из интернета, создать задание печати и передать его службам печати Android.
В этом уроке показано, как быстро создать HTML-документ, содержащий текст и графику, и использовать WebView для его печати.
Загрузка HTML-документа
Чтобы распечатать HTML-документ с помощью WebView, нужно загрузить HTML-ресурс или создать HTML-документ в виде строки. В этом разделе описывается, как создать строку HTML и загрузить ее в WebView для печати.
Этот объект представления обычно используется как часть макета действия. Однако если в вашем приложении не используется WebView, вы можете создать экземпляр класса специально для печати. Вот основные шаги для создания такого представления:
- Создайте
WebViewClient, который запускает задание печати после загрузки ресурса HTML. - Загрузите HTML-ресурс в объект
WebView.
В приведенном ниже примере кода показано, как создать простой объект WebViewClient и загрузить HTML-документ, созданный на лету.
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; }
Примечание. Убедитесь, что вызов для создания задания печати происходит в методе onPageFinished() класса WebViewClient, который вы создали в предыдущем разделе. Если вы не дождетесь окончания загрузки страницы, распечатанный документ может быть неполным или пустым, или печать может не удаться.
Примечание. В приведенном выше примере кода содержится экземпляр объекта WebView, поэтому он не удаляется до создания задания печати. Убедитесь, что вы сделали то же самое в своей реализации, иначе процесс печати может завершиться ошибкой.
Если вы хотите включить в страницу графику, поместите графические файлы в каталог assets/ проекта и укажите базовый URL в первом параметре метода loadDataWithBaseURL(), как показано в следующем примере кода:
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);
Вы также можете загрузить веб-страницу для печати, заменив метод loadDataWithBaseURL() на loadUrl(), как показано ниже.
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");
При использовании WebView для создания печатных документов следует учитывать следующие ограничения:
- В документ нельзя добавить верхние и нижние колонтитулы, в том числе номера страниц.
- В настройках печати HTML-документа нет возможности указать диапазон страниц. Например, нельзя распечатать страницы со второй по четвертую из десяти.
- Экземпляр
WebViewможет обрабатывать только одно задание печати за раз. - HTML-документы, содержащие атрибуты печати CSS, например свойства альбомной ориентации, не поддерживаются.
- Вы не можете использовать JavaScript в HTML-документе для запуска печати.
Примечание. Контент объекта WebView, включенного в макет, также можно распечатать после загрузки документа.
Если вы хотите настроить печать и полностью контролировать содержимое на печатной странице, перейдите к следующему уроку: Печать пользовательского документа.
Как создать задание печати
После создания объекта WebView и загрузки HTML-контента приложение практически готово к печати. Далее необходимо получить доступ к PrintManager, создать адаптер печати и, наконец, создать задание печати. Ниже приведен пример того, как это сделать.
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); }
В этом примере экземпляр объекта PrintJob сохраняется для использования приложением, но это необязательно. Приложение может использовать этот объект для отслеживания хода выполнения задания печати. Этот подход полезен, если вы хотите отслеживать статус задания печати в приложении, чтобы узнать, было ли оно выполнено, отменено пользователем или произошел сбой. Создавать уведомление в приложении не требуется, поскольку фреймворк печати автоматически создает системное уведомление для задания печати.