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

愛一寧發表於2020-10-23

前言

      最近公司要做一個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" });
        }

 

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

 

相關文章