In tài liệu HTML

Để in nội dung không chỉ là một bức ảnh đơn giản trên Android, bạn cần phải soạn văn bản và hình ảnh đồ hoạ trong một tài liệu in. Khung Android cung cấp một cách sử dụng HTML để soạn tài liệu và in tài liệu đó bằng mã tối thiểu.

Trong Android 4.4 (API cấp 19), lớp WebView đã được cập nhật để cho phép in nội dung HTML. Lớp này cho phép bạn tải một tài nguyên HTML cục bộ hoặc tải một trang xuống từ web, tạo một lệnh in và chuyển lệnh đó cho các dịch vụ in của Android.

Bài học này sẽ hướng dẫn bạn cách tạo nhanh một tài liệu HTML chứa văn bản và đồ hoạ, đồng thời sử dụng WebView để in tài liệu đó.

Tải tài liệu HTML

In tài liệu HTML bằng WebView bao gồm việc tải tài nguyên HTML hoặc tạo tài liệu HTML dưới dạng một chuỗi. Phần này mô tả cách tạo một chuỗi HTML và tải chuỗi đó vào WebView để in.

Đối tượng khung hiển thị này thường được dùng như một phần của bố cục hoạt động. Tuy nhiên, nếu ứng dụng của bạn không sử dụng WebView, thì bạn có thể tạo một thực thể của lớp dành riêng cho mục đích in. Các bước chính để tạo chế độ xem bản in tuỳ chỉnh này là:

  1. Tạo một WebViewClient bắt đầu lệnh in sau khi tài nguyên HTML được tải.
  2. Tải tài nguyên HTML vào đối tượng WebView.

Mã mẫu sau đây minh hoạ cách tạo một WebViewClient đơn giản và tải nhanh một tài liệu HTML được tạo:

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

Lưu ý: Hãy đảm bảo rằng lệnh gọi để tạo lệnh in diễn ra trong phương thức onPageFinished() của WebViewClient mà bạn đã tạo ở phần trước. Nếu bạn chỉ đợi đến khi tải trang xong, thì bản in ra có thể chưa hoàn chỉnh hoặc bị trống, hoặc có thể bị lỗi hoàn toàn.

Lưu ý: Mã ví dụ ở trên lưu giữ một thực thể của đối tượng WebView để không thu thập rác trước khi tạo lệnh in. Hãy nhớ làm như vậy trong quá trình triển khai của riêng bạn, nếu không thì quá trình in có thể không thành công.

Nếu bạn muốn đưa hình ảnh đồ hoạ vào trang, hãy đặt tệp đồ hoạ vào thư mục assets/ của dự án và chỉ định một URL cơ sở trong tham số đầu tiên của phương thức loadDataWithBaseURL(), như trong đoạn mã ví dụ sau:

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

Bạn cũng có thể tải một trang web để in bằng cách thay thế phương thức loadDataWithBaseURL() bằng loadUrl() như minh hoạ dưới đây.

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

Khi sử dụng WebView để tạo tài liệu in, bạn nên lưu ý các hạn chế sau:

  • Bạn không thể thêm đầu trang hoặc chân trang, bao gồm cả số trang, vào tài liệu.
  • Các tuỳ chọn in cho tài liệu HTML không bao gồm các tuỳ chọn in phạm vi trang, ví dụ: Không hỗ trợ in trang 2 đến 4 của tài liệu HTML gồm 10 trang.
  • Mỗi thực thể của WebView chỉ có thể xử lý một lệnh in tại mỗi thời điểm.
  • Tài liệu HTML có chứa các thuộc tính in của CSS, chẳng hạn như các thuộc tính ngang, không được hỗ trợ.
  • Bạn không thể sử dụng JavaScript trong tài liệu HTML để kích hoạt tính năng in.

Lưu ý: Nội dung của đối tượng WebView có trong một bố cục cũng có thể được in sau khi tải tài liệu.

Nếu bạn muốn tạo một bản in đầu ra tuỳ chỉnh hơn và có toàn quyền kiểm soát nội dung được vẽ trên trang được in, hãy chuyển đến bài học tiếp theo: Bài học In tài liệu tuỳ chỉnh.

Sau khi tạo WebView và tải nội dung HTML, ứng dụng của bạn gần như đã hoàn tất một phần của quá trình in. Các bước tiếp theo là truy cập vào PrintManager, tạo bộ chuyển đổi in và cuối cùng là tạo một lệnh in. Ví dụ sau minh hoạ cách thực hiện các bước này:

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

Ví dụ này lưu một thực thể của đối tượng PrintJob để ứng dụng dùng (không bắt buộc). Ứng dụng của bạn có thể sử dụng đối tượng này để theo dõi tiến trình của lệnh in trong quá trình xử lý. Phương pháp này hữu ích khi bạn muốn theo dõi trạng thái của lệnh in trong ứng dụng để hoàn tất, không thành công hoặc khi người dùng huỷ. Bạn không bắt buộc phải tạo thông báo trong ứng dụng vì khung in tự động tạo thông báo hệ thống cho lệnh in.