طباعة مستندات HTML

لطباعة محتوى بخلاف صورة بسيطة على نظام التشغيل Android، يتطلب ذلك إنشاء نص ورسومات في مستند طباعة. يوفّر إطار عمل Android طريقة لاستخدام HTML لإنشاء مستند وطباعته باستخدام الحدّ الأدنى من الرموز.

في نظام التشغيل Android 4.4 (المستوى 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;
}

ملاحظة: تأكَّد من أنّ مكالمتك لإنشاء مهمة طباعة تتم باستخدام طريقة 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 ليستخدمه التطبيق، وهو غير مطلوب. قد يستخدم تطبيقك هذا العنصر لتتبُّع مستوى تقدُّم مهمة الطباعة أثناء معالجتها. ويُعدّ هذا الأسلوب مفيدًا عندما تريد مراقبة حالة مهمة الطباعة التي قدّمتها في طلبك لمعرفة مدى اكتمالها أو تعذُّر إكمالها أو إلغائها من قِبل المستخدم. ولا يلزم إنشاء إشعار داخل التطبيق، لأنّ إطار عمل الطباعة ينشئ تلقائيًا إشعار نظام لمهمة الطباعة.