Aspose.Words實現郵件合併功能和列印

前言

      最近公司要做一個B/S架構的web列印系統,主要是可以上傳、下載、郵件合併、列印等等,還有就是角色的分配、用戶的創建、日誌記錄等等,跟一般的web系統一樣。可能不一樣的就是需求:想把excel的數據填充到  word的模板裡面。做一個通用的版本。大概了解了一下,微軟其實在word裡面已經實現了這個功能,叫做:郵件合併功能。簡單的說就是:只要word的域和excel的列名是一樣的時候,就可以把數據填充到相應 的域裡面。當時想的就是微軟實現了,那我就直接調用它的Com組件吧!

第一次使用COM組件

首先需要添加COM引用——-Microsoft Word 11.0 Object Library

添加命名空間——————-using Word = Microsoft.Office.Interop.Word;

    用這個組件還有一些問題,會拋出異常:《索 COM 類工廠中 CLSID 為 {000209FF-0000-0000-C000-000000000046} 的組件失敗,原因是出現以下錯誤: 8000401a 因為配置標識不正確,系統無法開始服務  器進程。請檢查用戶名和密碼。 (異常來自 HRESULT:0x8000401A)》網上的解決辦法都是配置什麼許可權什麼的,其實不用。只需要配置程式池就行,點擊站點的程式池,右擊高級設置,把標識改LocalSystem就不會報異常了。

我的計劃是先調通列印的工作再做郵件列印功能,直接上列印的方法吧!

 wDoc.PrintOut(ref background, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref
missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing);
object saveOption = Word.WdSaveOptions.wdSaveChanges;
wDoc.Close(ref saveOption, ref missing, ref missing); //關閉當前文檔
saveOption = Word.WdSaveOptions.wdDoNotSaveChanges;       
wApp.Quit(ref saveOption, ref missing, ref missing); //關閉Word進程

 

   厄運也就開始了!我寫好後直接生產解決方案可以列印,但是問題來了,我的web程式經常出現假死,重新啟動IIS都沒有用,關閉了程式池,不能再次啟動,會報錯,感覺是資源被佔用了一樣。只有關機再開機才行。上網查了很多資料發現web系統使用COM組件不是明智之舉。

1.微軟Office是主要針對普通用戶開發的桌面辦公應用軟體,是一套純粹的本地運行軟體或者說是客戶端軟體。Word自動化介面主要是為了方便窗口應用程式調用而設計的。例如Delphi、VB、C# Winform等開發的本地應用程式。雖然可以強制Visible為false,Word可以運行在伺服器端程式碼里,但畢竟還是會帶來許多棘手問題。

2.由於Word是複雜的桌面程式,並不符合一般Web服務程式簡潔高效的標準,所以在伺服器端運行時速度慢,並且還會消耗大量資源(CPU、記憶體),尤其不能支援大量用戶同時訪問,資源會很快耗盡。

3.ASP.NET是基於B/S架構的。B/S架構下用戶訪問都是並發的,也就是說經常會出現同時N個用戶對一個伺服器頁面發出請求。在這種情況下Word自動化調用會時常出現死進程。

4.絕大部分開發者對COM技術比較陌生(至少我是第一次接觸),在編程調用Word介面時經常存在一些程式碼錯誤,而又很難檢查到問題所在,這又是導致死進程的經常因素。Word死進程不僅會消耗伺服器資源,還經常會導致伺服器頁面不能創建新的Word自動化對象而無法繼續工作。

    基於此種情況我百度了許久,決定用Aspose.Words組件,在網上複製了一些內容下來:

1.基本介紹

Aspose.Words是一個商業.NET類庫,可以使得應用程式處理大量的文件任務。Aspose.Words支援Doc,Docx,RTF,HTML,OpenDocument,PDF,XPS,EPUB和其他格式。使用Aspose.Words可以在不使用Microsoft.Word的情況下生成、修改、轉換和列印文檔。在項目中使用Aspose.Words可以有以下好處。

1.1豐富的功能集

其豐富的功能特性主要有以下4個方面:

1)格式轉換。Aspose.Words具有高品質的文件格式轉換功能,可以和Doc,OOXL,RTF,TXT等格式互相轉換。

2)文檔對象模型。通過豐富的API以編程方式訪問所有的文檔元素和格式,允許創建,修改,提取,複製,分割,加入,和替換文件內容。

3)文件渲染。可以在伺服器端轉換整個文檔或者頁面為PDF,XPS,SWF格式,同樣可以轉換文檔頁面為影像格式,或者.NET Graphics對象,這些功能和Microsoft.Word是一樣的。

4)報表。可以從對象或者數據源填充模版生成文件。

1.2不需要Microsoft.Word

Aspose.Words可以在沒有安裝Microsoft Office的機器上工作。所有的Aspose組件都是獨立,不需要微軟公司的授權。總之, Aspose.Words在安全性、穩定性、可擴展性、速度、價格和自動化功能方面,是一個很不錯的選擇。

1.3獨立的平台

Aspose.Words可以運行在Windows,Linux和Mac OS作業系統上面。可以使用Aspose.Words去創建32位或者64位的.NET應用程式,包括Asp.NET、WCF、WinForm等等,還可以使用Com組件在Asp、Perl、PHP和Python語言中使用,同樣可以在Mono平台上使用Aspose.Words建立.NET應用程式。

1.4性能和可伸縮性

Aspose.Words可以運行在伺服器和客戶端,它是一個獨立的.NET程式集,可以被任何.NET應用程式複製和部署。使用Aspose.Words可以在短時間內產生成千上萬的文檔,可以打開文檔,並修改格式和內容,填充數據並保存。Aspose.Words是多執行緒安全的,不同的執行緒在同一時間處理不同的文檔。

Aspose.Words郵件合併

 

 using Aspose.Words;
public ActionResult PrintFile(string template, string fileName)
        {
            try
            {
                var isInstall = false;
                foreach (string sPrint in PrinterSettings.InstalledPrinters)//獲取所有印表機名稱
                {
                    if (sPrint == "CoverPrinter203")
                    {
                        isInstall = true;
                    }
                }
                if (!isInstall)
                {
                    return AjaxJsonResult(new { errorMessage = "請安裝列印驅動" });
                }
                string tmpDocFile = Server.MapPath("../Content/files/Word/" + template);//word模板

                Document doc = new Document(tmpDocFile);
                DocumentBuilder builder = new DocumentBuilder(doc);
                string excelFile = Server.MapPath("../Content/files/Import/" + fileName);//excel表
                DataTable dt = _baseDataService.GetDataFromExcel(excelFile);//excel轉datatable  注意版本轉換
 
                var printerSetting = new PrinterSettings();

                printerSetting.PrinterName = "CoverPrinter203";//設置印表機名稱
                printerSetting.Collate = true;
                foreach (DataRow row in dt.Rows)//遍歷每一行
                {
                    if (string.IsNullOrEmpty(row.ItemArray[0].ToString()))
                    {
                        break;
                    }
                    Document dstDoc = (Document)doc.Clone(true);

                    dstDoc.MailMerge.Execute(row);//郵件合併
                    dstDoc.Print(printerSetting);//列印
                }
            }
            catch (Exception ex)
            {
                return AjaxJsonResult(new { errorMessage = ex.Message });
            }

            return AjaxJsonResult(new { errorMessage = "OK" });
        }

 

自己記錄一下,有這方面的需求,大家可以借鑒一下。