曾被 Reporting Service 報表列印 ActiveX 元件版本問題惡整過,在羚羊簇擁之下一路初探二探三探,記憶猶新。造成我有個根深蒂固觀念-ReportViewer 藉由 ActiveX 元件解決列印需求,所以在非 IE 瀏覽器上不能直接從網頁印報表是天經地義的事,遇到同事詢問,我的回答都是「無解」。但前陣子研究使用 Visual Studio 2017 開發 RDLC 報表我才赫然發現-ReportViewer 14.0 已經支援非 IE 瀏覽器線上列印囉!

對照舊版 ReportViewer(以11.0為例),下圖由上到下分為 IE、Chrome及Firefox,可以看到雖然三種瀏覽器都能開啟報表,但只有 IE 的工具列會顯示列印按鈕。

換成 ReportViewer 14.0 再試一次,現在三種瀏覽器都有列印按鈕可用囉!(灑花)

實測觀察,ReportViewer 的新做法是先將報表匯出成 PDF 檔再列印。好奇追進程式碼,找到一個 PdfPrint() 函式:

在 PdfPrint() 找到以下邏輯,解開 ReportViewer 跨瀏覽器列印 PDF 的奧祕:

        var HasActiveXAdobe = function()
        {
            try
            {
                var adobePdf = new ActiveXObject("AcroPDF.PDF");
                return true;
            }
            catch (e)
            {
                return false;
            }
        }
 
        var HasActiveXFoxit = function ()
        {
            try
            {
                var foxitPdf = new ActiveXObject("FoxitReader.FoxitReaderCtl");
                return true;
            }
            catch (e)
            {
                return false;
            }
        }
 
        var GetPdfPluginName = function () {
            var browserInfo = GetBrowser();
            if (browserInfo.browser == "IE")
            {
                if (HasActiveXAdobe()) return "AdobePDF";
                if (HasActiveXFoxit()) return "FoxitPDF";
            }
            else
            {
                if (null == navigator.mimeTypes)
                {
                    return "NoPDFPlugin";
                }
                var pdfPlugin = navigator.mimeTypes["application/pdf"];
                if (pdfPlugin && pdfPlugin.enabledPlugin)
                {
                    return pdfPlugin.enabledPlugin.name;
                }
            }
            return "NoPDFPlugin";
        }

在 IE 瀏覽器需借助 Adobe Reader 或 Foxit 外掛,走的仍是 ActiveX 的老路;至於其他瀏覽器,則透過 naviagtor.mimeType["application/pdf"] 取得 PDF 對應的套件(在 Chrome 預設為內建 Chrome PDF Viewer),接著透過 PDF 外掛 API,便能直接列印 PDF 檔。

又偷學到一招~


Comments

# by y

這太棒了,之前為了在 chrome 顯示列印搞超久 偏偏伺服器那邊又不能直接升級

# by Leewen77

能否寫一下「Chrome 透過 PDF 外掛 API 列印」的寫法示範? 我有個需求是由瀏覽器「直接印出 pdf 檔」, 在IE可 <object id="Object1" name="obj_pdf" data="xxxx.pdf" type="application/pdf" ... 再 document.obj_pdf.printAll(); 即可直接列印。 但 Chrome 不知如何做? 謝謝!

Post a comment