前言
最近公司要做一个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, refmissing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, refmissing,
refmissing);
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邮件合并
usingAspose.Words;
public ActionResult PrintFile(string template, stringfileName)
{
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 = newDocument(tmpDocFile);
DocumentBuilder builder = newDocumentBuilder(doc);
string excelFile = Server.MapPath("../Content/files/Import/" + fileName);//excel表
DataTable dt = _baseDataService.GetDataFromExcel(excelFile);//excel转datatable 注意版本转换
var printerSetting = newPrinterSettings();
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"});
}
自己记录一下,有这方面的需求,大家可以借鉴一下。