HTML-Dokumente drucken

Um Inhalte auf Android-Geräten über ein einfaches Foto hinaus auszudrucken, müssen Text und Grafiken in einem gedruckten Dokument verfasst werden. Das Android-Framework bietet eine Möglichkeit, HTML zum Erstellen eines Dokuments zu verwenden und es mit minimalem Code auszudrucken.

In Android 4.4 (API-Level 19) wurde die Klasse WebView aktualisiert, um das Drucken von HTML-Inhalten zu ermöglichen. Mit dieser Klasse kannst du eine lokale HTML-Ressource laden oder eine Seite aus dem Web herunterladen, einen Druckauftrag erstellen und an die Druckdienste von Android übergeben.

In dieser Lektion erfahren Sie, wie Sie schnell ein HTML-Dokument mit Text und Grafiken erstellen und es mit WebView drucken.

HTML-Dokument laden

Zum Drucken eines HTML-Dokuments mit WebView wird eine HTML-Ressource geladen oder ein HTML-Dokument als String erstellt. In diesem Abschnitt wird beschrieben, wie Sie einen HTML-String erstellen und zum Drucken in eine WebView laden.

Dieses Ansichtsobjekt wird normalerweise als Teil eines Aktivitätslayouts verwendet. Wenn Ihre Anwendung jedoch kein WebView verwendet, können Sie speziell zu Druckzwecken eine Instanz der Klasse erstellen. Die wichtigsten Schritte zum Erstellen dieser benutzerdefinierten Druckansicht sind:

  1. Erstellen Sie einen WebViewClient, der einen Druckauftrag startet, nachdem die HTML-Ressource geladen wurde.
  2. Laden Sie die HTML-Ressource in das WebView-Objekt.

Im folgenden Codebeispiel wird gezeigt, wie Sie ein einfaches WebViewClient-Element erstellen und ein HTML-Dokument laden, das direkt erstellt wurde:

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

Hinweis: Achten Sie darauf, dass der Aufruf zum Generieren eines Druckauftrags in der Methode onPageFinished() der WebViewClient erfolgt, die Sie im vorherigen Abschnitt erstellt haben. Wenn Sie nicht warten, bis das Laden der Seite abgeschlossen ist, ist die Druckausgabe möglicherweise unvollständig, leer oder schlägt ganz fehl.

Hinweis: Der Beispielcode oben enthält eine Instanz des WebView-Objekts, also keine automatische Speicherbereinigung vor dem Erstellen des Druckauftrags. Tun Sie dies unbedingt in Ihrer eigenen Implementierung, da der Druckvorgang andernfalls fehlschlagen kann.

Wenn du Grafiken in die Seite einfügen möchtest, platziere die Grafikdateien im Verzeichnis assets/ deines Projekts und gib im ersten Parameter der Methode loadDataWithBaseURL() eine Basis-URL an, wie im folgenden Codebeispiel gezeigt:

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

Sie können eine Webseite auch zum Drucken laden. Dazu ersetzen Sie die Methode loadDataWithBaseURL() durch loadUrl(), wie unten gezeigt.

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

Wenn Sie WebView zum Erstellen von Druckdokumenten verwenden, sollten Sie die folgenden Einschränkungen beachten:

  • Sie können dem Dokument keine Kopf- oder Fußzeilen hinzufügen, einschließlich Seitennummern.
  • Die Druckoptionen für das HTML-Dokument beinhalten nicht die Möglichkeit, Seitenbereiche zu drucken. Beispiel: Das Drucken von Seiten 2 bis 4 eines zehnseitigen HTML-Dokuments wird nicht unterstützt.
  • Eine Instanz von WebView kann jeweils nur einen Druckauftrag verarbeiten.
  • Ein HTML-Dokument mit CSS-Druckattributen wie Querformateigenschaften wird nicht unterstützt.
  • Sie können in einem HTML-Dokument kein JavaScript verwenden, um den Druckvorgang auszulösen.

Hinweis:Der Inhalt eines WebView-Objekts, das in einem Layout enthalten ist, kann auch gedruckt werden, nachdem ein Dokument geladen wurde.

Wenn Sie eine benutzerdefinierte Druckausgabe erstellen und die vollständige Kontrolle über das Zeichnen von Inhalten auf der gedruckten Seite haben möchten, fahren Sie mit der nächsten Lektion fort: Benutzerdefiniertes Dokument drucken.

Nachdem Sie eine WebView erstellt und die HTML-Inhalte geladen haben, ist der Druckvorgang Ihrer Anwendung fast abgeschlossen. Als Nächstes müssen Sie auf PrintManager zugreifen, einen Druckadapter erstellen und schließlich einen Druckauftrag erstellen. Das folgende Beispiel zeigt, wie diese Schritte ausgeführt werden:

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

In diesem Beispiel wird eine Instanz des PrintJob-Objekts zur Verwendung durch die Anwendung gespeichert. Dies ist nicht erforderlich. Die Anwendung kann dieses Objekt verwenden, um den Fortschritt des Druckauftrags während seiner Verarbeitung zu verfolgen. Diese Methode ist nützlich, wenn Sie den Status des Druckauftrags in Ihrer Anwendung im Hinblick auf dessen Abschluss, Fehler oder den Abbruch durch den Nutzer überwachen möchten. Das Erstellen einer In-App-Benachrichtigung ist nicht erforderlich, da das Druck-Framework automatisch eine Systembenachrichtigung für den Druckauftrag erstellt.