הדפסת מסמכי HTML

כדי להדפיס תוכן מעבר לתמונה פשוטה ב-Android, צריך לכתוב טקסט וגרפיקה להדפיס את המסמך. ה-framework של Android מספק דרך להשתמש ב-HTML כדי לכתוב מסמך להדפיס אותה עם מינימום של קוד.

ב-Android 4.4 (רמת API 19), המחלקה WebView עודכנה ל לאפשר הדפסת תוכן HTML. הכיתה מאפשרת לטעון משאב HTML מקומי או להוריד דף מהאינטרנט, ליצור משימת הדפסה ולהעביר אותה לשירותי ההדפסה של Android.

בשיעור הזה תלמדו איך לבנות במהירות מסמך HTML שמכיל טקסט וגרפיקה אפשר להשתמש ב-WebView כדי להדפיס אותו.

טעינת מסמך HTML

כדי להדפיס מסמך HTML באמצעות WebView צריך לטעון HTML או בניית מסמך HTML כמחרוזת. בקטע הזה נסביר איך ליצור קוד HTML וטוענים אותו לתוך WebView להדפסה.

אובייקט התצוגה הזה משמש בדרך כלל כחלק מפריסת פעילות. אבל אם הבקשה שלכם לא משתמש ב-WebView, ניתן ליצור מופע של הכיתה במיוחד למטרות הדפסה. השלבים העיקריים ליצירת תצוגת הדפסה מותאמת אישית:

  1. יצירה של WebViewClient שמתחילה משימת הדפסה אחרי משאב ה-HTML נטען.
  2. טוענים את משאב ה-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;
}

הערה: חשוב לוודא שהקריאה ליצירת משימת הדפסה מתבצעת ב-method 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 לא כוללות אפשרות להדפיס דף טווחים, לדוגמה: אין תמיכה בהדפסת דפים 2 עד 4 מתוך מסמך HTML בן 10 דפים.
  • במכונה של 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 לשימוש באפליקציה, אבל זה לא נדרש. האפליקציה שלך עשויה להשתמש באובייקט הזה כדי לעקוב אחר ההתקדמות של את משימת ההדפסה בזמן שהיא מעובדת. הגישה הזו שימושית אם רוצים לעקוב אחרי הסטטוס של משימת ההדפסה באפליקציה להשלמת משימת ההדפסה, לכשל או לביטול על ידי המשתמש. יצירת לא נדרשת הודעה בתוך האפליקציה, כי מסגרת ההדפסה יוצרת מערכת באופן אוטומטי עבור משימת ההדפסה.