在 Android 上打印出简单的照片以外的内容需要在打印文档中组合文本和图形。Android 框架提供了一种使用 HTML 组合文档并以最少的代码将其打印出来的方法。
在 Android 4.4(API 级别 19)中,WebView
类已更新以启用打印 HTML 内容。该类允许您加载本地 HTML 资源或从网络下载页面,创建打印作业并将其传递给 Android 的打印服务。
本课程将向您展示如何快速构建包含文本和图形的 HTML 文档,并使用 WebView
打印它。
加载 HTML 文档
使用 WebView
打印 HTML 文档涉及加载 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()
方法中。如果您不等到页面加载完成,则打印输出可能不完整或为空,甚至可能完全失败。
注意: 上面的示例代码保存了 WebView
对象的实例,这样在创建打印作业之前不会被垃圾回收。请确保在自己的实现中也这样做,否则打印过程可能会失败。
如果要将图形包含在页面中,请将图形文件放在项目的 assets/
目录中,并在 loadDataWithBaseURL()
方法的第一个参数中指定一个基本 URL,如下面的代码示例所示
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 文档的打印选项不包括打印页码范围的功能,例如:不支持打印 10 页 HTML 文档中的第 2 页到第 4 页。
WebView
的实例一次只能处理一个打印作业。- 包含 CSS 打印属性(如横向属性)的 HTML 文档不受支持。
- 您无法在 HTML 文档中使用 JavaScript 来触发打印。
注意: 包含在布局中的 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
对象的实例供应用程序使用,这不是必需的。您的应用程序可以使用此对象跟踪打印作业的处理进度。当您想在应用程序中监控打印作业的状态(以了解其完成情况、失败情况或用户取消情况)时,这种方法非常有用。创建应用内通知不是必需的,因为打印框架会自动为打印作业创建系统通知。