基於Metronic的Bootstrap開發框架經驗總結(9)--實現Web頁面內容的列印預覽和保存操作

来源:http://www.cnblogs.com/wuhuacong/archive/2016/01/21/5147368.html
-Advertisement-
Play Games

在前面介紹了很多篇相關的《Bootstrap開發框架》的系列文章,這些內容基本上覆蓋到了我這個Bootstrap框架的各個主要方面的內容,總體來說基本達到了一個穩定的狀態,隨著時間的推移可以會引入一些更好更新的內容進行完善,本篇繼續這個系列,主要介紹如何實現Web頁面內容的列印預覽和保存操作。


在前面介紹了很多篇相關的《Bootstrap開發框架》的系列文章,這些內容基本上覆蓋到了我這個Bootstrap框架的各個主要方面的內容,總體來說基本達到了一個穩定的狀態,隨著時間的推移可以會引入一些更好更新的內容進行完善,本篇繼續這個系列,主要介紹如何實現Web頁面內容的列印預覽和保存操作。

1、Web頁面列印的問題

在此之前,我一般使用比較好用的LODOP來執行列印的操作,這個在我之前有很多文章都有涉及,這個控制項是一個ActiveX的控制項,需要下載安裝後就可以在頁面是進行列印的排版設計,預覽,列印等操作,還是很方便的一個控制項,因此都很適合普通內容的列印,證件的套打等操作。

不過隨著瀏覽器技術的更新,這個插件在Chrome或者FireFox上好像不受支持了,基本上摒棄了這種插件的處理方式了。例如如果我在頁面上需要列印對話框裡面的內容,如下所示。

如果按正常使用LODOP的方式來進行處理的話,那麼會得到Chrome瀏覽器的提示,並且這個不管你重新下載安裝、更新LODOP控制項,都會繼續這個錯誤提示的。

這個在一篇《Lodop頁面總提示"未安裝"或"請升級"的可能原因》,以及《Lodop用戶應對谷歌瀏覽器停用Plugin技術的處理辦法》都有說明,因此我們需要另闢蹊徑來處理這個頁面列印等的處理了。

對於替代方式,這裡就是本篇內容介紹的主題了,我一直喜歡尋找一些比較好的方式的方式來實現自己需要的功能,於是找到了PrintThis的這個插件(https://github.com/jasonday/printThis)以及jquery-print-preview-plugin(https://github.com/etimbo/jquery-print-preview-plugin),對比兩者我比較喜歡第一個的簡潔方便的使用。

2、PrintThis列印插件的使用

有了上面的問題,我們引入一個新的列印方式,也就是JQuery插件來實現我們所需要頁面內容的列印操作。

這個插件的使用非常簡潔方便,首先需要在頁面裡面引入對應的JS文件,如下所示。

<script src="~/Content/JQueryTools/printThis/printThis.js"></script>

我們再在頁面頂部增加兩個按鈕,如列印和導出操作,代碼如下所示

<div class="toolbar">
 <a href="#" onclick="javascript:Preview();"><img alt="列印預覽" src="~/Content/images/print.gif" /><br />列印預覽</a>
 <a href="#" onclick="javascript:SaveAs();"><img alt="另存為" src="~/Content/images/saveas.gif" /><br />另存為</a>         
</div>

然後我們還需要聲明一個DIV用來放置顯示的Web頁面內容,這樣也方便對它調用進行列印操作。

我們列印的處理代碼也很簡單,就是直接對層進行列印處理就可以了,可以看到下麵的使用代碼非常簡單。

        //列印預覽
        function Preview() {
            $("#printContent").printThis({
                debug: false,
                importCSS: true,
                importStyle: true,
                printContainer: true,
                loadCSS: "/Content/Themes/Default/style.css",
                pageTitle: "通知公告",
                removeInline: false,
                printDelay: 333,
                header: null,
                formValues: true
            });
        };

列印執行後,IE和Chrome都會彈出一個列印預覽對話框,確認是否進行列印的操作。

 

3、頁面內容的保存操作

有時候,為了方便業務處理,我們一般也可以提供給用戶一個導出列印內容的操作,如下所示代碼就是把列印的內容導出到Word裡面給用戶加工等用途。

        function SaveAs() {
            var id = $('#ID2').val();
            window.open('/Information/ExportWordById?id=' + id );
        }

上面的操作,主要就是調用了MVC的控制器方法進行處理,傳入一個id就可以把內容提取出來,然後把它生成所需的Word內容即可。

這裡後臺我們主要利用Apose.Word控制項來進行模板化的文檔生成,具體可以參考一下我前面介紹過的使用方法文章《利用Aspose.Word控制項實現Word文檔的操作》、《利用Aspose.Word控制項和Aspose.Cell控制項,實現Word文檔和Excel文檔的模板化導出》。

其中我們可以在書簽裡面定義或者查看一些書簽的信息,如下圖所示。

這樣我們在代碼裡面,就可以獲取信息並指定這個Word模板了。

            InformationInfo info = BLLFactory<Information>.Instance.FindByID(id);
            if (info != null)
            {
                string template = "~/Content/Template/政策法規模板.doc";
                string templateFile = Server.MapPath(template);
                Aspose.Words.Document doc = new Aspose.Words.Document(templateFile);

WORD模板的內容,可以使用文本替換方式,如下所示。

SetBookmark(ref doc, "Content", info.Content);

也可以使用書簽BookMark方式查詢替換,如下代碼所示。

            Aspose.Words.Bookmark bookmark = doc.Range.Bookmarks[title];
            if (bookmark != null)
            {
                bookmark.Text = value;
            }

對於主體的HTML內容,這需要特殊對待,一般需要使用插入HTML的專用方式進行寫入內容,否則就顯示HTML代碼了,使用專用HTML方法寫入的內容,和我們在網頁上看到的基本沒有什麼差異了。如下代碼所示。

                DocumentBuilder builder = new DocumentBuilder(doc);
                Aspose.Words.Bookmark bookmark = doc.Range.Bookmarks["Content"];
                if (bookmark != null)
                {
                    builder.MoveToBookmark(bookmark.Name);
                    builder.InsertHtml(info.Content);
                } 

整個導入WORD文檔的方法就是利用這些內容的整合,實現一個標準文檔的生成,這種業務文檔是固定模板的,因此很適合在實際業務中使用,比起使用其他方式自動生成的HTML文件或者文檔,有更好的可塑性和美觀性。

整個代碼如下所示。

        public FileStreamResult ExportWordById(string id)
        {
            if (string.IsNullOrEmpty(id)) return null;

            InformationInfo info = BLLFactory<Information>.Instance.FindByID(id);
            if (info != null)
            {
                string template = "~/Content/Template/政策法規模板.doc";
                string templateFile = Server.MapPath(template);
                Aspose.Words.Document doc = new Aspose.Words.Document(templateFile);

                #region 使用文本方式替換
                //Dictionary<string, string> dictSource = new Dictionary<string, string>();
                //dictSource.Add("Title", info.Title);
                //dictSource.Add("Content", info.Content);
                //dictSource.Add("Editor", info.Editor);
                //dictSource.Add("EditTime", info.EditTime.ToString());
                //dictSource.Add("SubType", info.SubType);  
                //foreach (string name in dictSource.Keys)
                //{
                //    doc.Range.Replace(name, dictSource[name], true, true);
                //} 
                #endregion

                //使用書簽方式替換
                SetBookmark(ref doc, "Title", info.Title);
                SetBookmark(ref doc, "Editor", info.Editor);
                SetBookmark(ref doc, "EditTime", info.EditTime.ToString());
                SetBookmark(ref doc, "SubType", info.SubType);
                
                //SetBookmark(ref doc, "Content", info.Content);
                //對於HTML內容,需要通過InsertHtml方式進行寫入
                DocumentBuilder builder = new DocumentBuilder(doc);
                Aspose.Words.Bookmark bookmark = doc.Range.Bookmarks["Content"];
                if (bookmark != null)
                {
                    builder.MoveToBookmark(bookmark.Name);
                    builder.InsertHtml(info.Content);
                }                
                
                doc.Save(System.Web.HttpContext.Current.Response, info.Title, Aspose.Words.ContentDisposition.Attachment,
                    Aspose.Words.Saving.SaveOptions.CreateSaveOptions(Aspose.Words.SaveFormat.Doc));

                HttpResponseBase response = ControllerContext.HttpContext.Response;
                response.Flush();
                response.End();
                return new FileStreamResult(Response.OutputStream, "application/ms-word");
            }
            return null;
        }

        private void SetBookmark(ref Aspose.Words.Document doc, string title, string value)
        {
            Aspose.Words.Bookmark bookmark = doc.Range.Bookmarks[title];
            if (bookmark != null)
            {
                bookmark.Text = value;
            }
        }

最後導出的WORD文檔就是模板化的具體文檔內容了,WORD預覽界面如下所示。

 

如果有興趣,可以繼續參考系列文章:

基於Metronic的Bootstrap開發框架經驗總結(1)-框架總覽及菜單模塊的處理

基於Metronic的Bootstrap開發框架經驗總結(2)--列表分頁處理和插件JSTree的使用

基於Metronic的Bootstrap開發框架經驗總結(3)--下拉列表Select2插件的使用

基於Metronic的Bootstrap開發框架經驗總結(4)--Bootstrap圖標的提取和利用 

基於Metronic的Bootstrap開發框架經驗總結(5)--Bootstrap文件上傳插件File Input的使用

基於Metronic的Bootstrap開發框架經驗總結(6)--對話框及提示框的處理和優化

基於Metronic的Bootstrap開發框架經驗總結(7)--數據的導入、導出及附件的查看處理

基於Metronic的Bootstrap開發框架經驗總結(8)--框架功能總體界面介紹

基於Metronic的Bootstrap開發框架經驗總結(9)--實現Web頁面內容的列印預覽和保存操作

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 自旋鎖與互斥量功能一樣,唯一一點不同的就是互斥量阻塞後休眠讓出cpu,而自旋鎖阻塞後不會讓出cpu,會一直忙等待,直到得到鎖!!!自旋鎖在用戶態使用的比較少,在內核使用的比較多!自旋鎖的使用場景:鎖的持有時間比較短,或者說小於2次上下文切換的時間。自旋鎖在用戶態的函數介面和互斥量一樣,把pthrea...
  • 一.概述 讀寫鎖與互斥量的功能類似,對臨界區的共用資源進行保護!互斥量一次只讓一個線程進入臨界區,讀寫鎖比它有更高的並行性。讀寫鎖有以下特點:1.如果一個線程用讀鎖鎖定了臨界區,那麼其他線程也可以用讀鎖來進入臨界區,這樣就可以多個線程並行操作。但這個時...
  • 1.使用命令parted /dev/sdb 1 [root@server ~]# parted /dev/sdb 2 GNU Parted 2.1 3 使用 /dev/sdb 4 Welcome to GNU Parted! Type 'help' to view a list of command...
  • 今天一同事報告Linux伺服器上的crontab作業沒有運行,檢查/var/log/cron日誌後發現下麵錯誤信息 Jan 19 16:30:01 xxxx crond[31399]: Authentication token is no longer valid; new one required...
  • 1.使用fdisk創建6個分區[1P+1E(5L)] //dev/sdb1 /dev/sdb5 /dev/sdb6 /dev/sdb7 /dev/sdb8 /deb/sdb9 1 [root@server ~]# fdisk -l 2 3 Disk /dev/sda: 8589 MB, 8589.....
  • 用的是VMware10.0版本的虛擬機,很早之前下載的今天就直接用了,安裝挺簡單記得需要一個序列號。在這裡:http://mirrors.163.com/ubuntu-releases/15.04/ubuntu-15.04-desktop-i386.iso 下載的ubuntu15.04ISO鏡像(....
  • at命令用於在指定時間執行命令。at允許使用一套相當複雜的指定時間的方法。它能夠接受在當天的hh:mm(小時:分鐘)式的時間指定。假如該時間已過去,那麼就放在第二天執行。當然也能夠使用midnight(深夜),noon(中午),teatime(飲茶時間,一般是下午4點)等比較模糊的 詞語來指定時間。...
  • 我最近開發了一個winform項目,用的是access資料庫,當開發成功以後,有些電腦上就能正常運行,有些電腦就無法讀取資料庫文件,剛開始我以為是許可權問題,後來我把安裝程式卸載了,裝在其它盤中(非C盤),奇跡發生了,正常運行,但是我又在其它電腦上安裝不管是C盤還是其它盤都不行,後來我以為是電...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...