Drukowanie dokumentów HTML

Wydrukowanie zawartości poza prostym zdjęciem w Androidzie wymaga utworzenia tekstu i grafiki w drukowanym dokumencie. Platforma Androida umożliwia tworzenie dokumentów w języku HTML i drukowanie go przy użyciu minimalnej ilości kodu.

W Androidzie 4.4 (poziom interfejsu API 19) klasa WebView została zaktualizowana, aby umożliwić drukowanie treści HTML. Dzięki niej można wczytać lokalny zasób HTML, pobrać stronę z internetu, utworzyć zadanie drukowania i przekazać je usługom drukowania na Androidzie.

Z tej lekcji dowiesz się, jak szybko utworzyć dokument HTML zawierający tekst i grafikę oraz użyć WebView, aby go wydrukować.

Wczytaj dokument HTML

Drukowanie dokumentu HTML za pomocą WebView obejmuje wczytanie zasobu HTML lub utworzenie dokumentu HTML pod postacią ciągu znaków. W tej sekcji opisujemy, jak utworzyć ciąg znaków HTML i wczytać go w elemencie WebView na potrzeby drukowania.

Ten obiekt widoku jest zwykle używany jako część układu aktywności. Jeśli jednak aplikacja nie korzysta z WebView, możesz utworzyć instancję klasy specjalnie do drukowania. Główne kroki tworzenia niestandardowego widoku wydruku to:

  1. Utwórz WebViewClient, który po wczytaniu zasobu HTML rozpoczyna zadanie drukowania.
  2. Wczytaj zasób HTML do obiektu WebView.

Poniższy przykładowy kod pokazuje, jak utworzyć prosty plik WebViewClient i wczytać dokument HTML utworzony na bieżąco:

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

Uwaga: upewnij się, że wywołanie generowania zadania drukowania odbywa się w metodzie onPageFinished() obiektu WebViewClient utworzonego w poprzedniej sekcji. Jeśli nie zaczekasz na zakończenie wczytywania strony, wydruki mogą być niekompletne lub puste albo zawierać błąd.

Uwaga: przykładowy kod powyżej zawiera wystąpienie obiektu WebView, aby nie zostały one usunięte przed utworzeniem zadania drukowania. Upewnij się, że robisz to we własnej implementacji. W przeciwnym razie proces drukowania może się nie udać.

Jeśli chcesz umieścić grafikę na stronie, umieść pliki graficzne w katalogu assets/ swojego projektu i w pierwszym parametrze metody loadDataWithBaseURL() podaj podstawowy adres URL, jak pokazano w tym przykładzie kodu:

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

Możesz też wczytać stronę internetową do wydrukowania, zastępując metodę loadDataWithBaseURL() metodą loadUrl(), jak pokazano poniżej.

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

Podczas tworzenia dokumentów drukowanych za pomocą usługi WebView pamiętaj o tych ograniczeniach:

  • Do dokumentu nie można dodawać nagłówków ani stopek, w tym numerów stron.
  • Opcje drukowania dokumentu HTML nie obejmują możliwości drukowania zakresów stron, np.: nie jest obsługiwane drukowanie stron 2–4 z 10-stronicowego dokumentu HTML.
  • Instancja WebView może jednocześnie przetwarzać tylko jedno zadanie drukowania.
  • Dokument HTML zawierający atrybuty CSS Print, np. właściwości poziomej, nie jest obsługiwany.
  • Do wywołania drukowania nie można użyć JavaScriptu w dokumencie HTML.

Uwaga: zawartość obiektu WebView zawartego w układzie można wydrukować po wczytaniu dokumentu.

Jeśli chcesz uzyskać bardziej spersonalizowane wyniki drukowania i mieć pełną kontrolę nad zawartością drukowaną strony, przejdź do następnej lekcji: Drukowanie dokumentu niestandardowego.

Po utworzeniu pliku WebView i wczytaniu treści HTML proces drukowania jest prawie gotowy w aplikacji. Kolejne kroki to uzyskanie dostępu do urządzenia PrintManager, utworzenie adaptera drukowania, a na koniec utworzenie zadania drukowania. Poniższy przykład pokazuje, jak wykonać te czynności:

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

W tym przykładzie zapisujemy instancję obiektu PrintJob, która jest używana przez aplikację, co nie jest wymagane. Aplikacja może używać tego obiektu do śledzenia postępu przetwarzania zadania drukowania. Ta metoda jest przydatna, gdy chcesz monitorować stan zadania drukowania w aplikacji pod kątem ukończenia, niepowodzenia lub anulowania przez użytkownika. Tworzenie powiadomienia w aplikacji nie jest wymagane, ponieważ platforma drukowania automatycznie tworzy powiadomienie systemowe dla zadania drukowania.