ASP.NET调用Word进行文件处理说明
一、 编程
1) 添加引用
2) 代码
利用标签对文档内容进行修改
将多个文档进行合并
#region 打开文件 private Document objDocLast = null; private Document objDocBeforeLast = null; Microsoft.Office.Interop.Word.Application objApp =null;
// 文档第一部分 const string sDocPart1 = "/doc/Model1.doc"; // 文档第三部分 const string sDocPart3 = "/doc/Model3.doc"; // 合并后文档 const string sDocMerge = "/doc/Model_All.doc"; // 新文档前缀[新文档为文件前缀+用户ID] const string sDocProv = "/doc/New";
// 打开Word文档,不能以只读方式打开 // 如果出现共享打开的时候,可以复制一份,再打开 private void Open(string tempDoc) { // 变量定义 object objTempDoc = tempDoc; object objMissing = System.Reflection.Missing.Value; object objReadOnly = true;
//创建一个名为WordApp的组件对象 objApp = new Microsoft.Office.Interop.Word.Application(); objApp.Visible = false;
// 打开文档 objDocLast = objApp.Documents.Open( ref objTempDoc, //FileName ref objMissing, //ConfirmVersions ref objMissing, //ReadOnly ref objMissing, //AddToRecentFiles ref objMissing, //PasswordDocument ref objMissing, //PasswordTemplate ref objMissing, //Revert ref objMissing, //WritePasswordDocument ref objMissing, //WritePasswordTemplate ref objMissing, //Format ref objMissing, //Enconding ref objMissing, //Visible ref objMissing, //OpenAndRepair ref objMissing, //DocumentDirection ref objMissing, //NoEncodingDialog ref objMissing //XMLTransform ); objDocLast.Activate(); } #endregion
#region 保存文件到输出模板 private void SaveAs(string outDoc) { object objMissing = System.Reflection.Missing.Value; object objOutDoc = outDoc; objDocLast.SaveAs( ref objOutDoc, //FileName ref objMissing, //FileFormat ref objMissing, //LockComments ref objMissing, //PassWord ref objMissing, //AddToRecentFiles ref objMissing, //WritePassword ref objMissing, //ReadOnlyRecommended ref objMissing, //EmbedTrueTypeFonts ref objMissing, //SaveNativePictureFormat ref objMissing, //SaveFormsData ref objMissing, //SaveAsAOCELetter, ref objMissing, //Encoding ref objMissing, //InsertLineBreaks ref objMissing, //AllowSubstitutions ref objMissing, //LineEnding ref objMissing //AddBiDiMarks ); } #endregion
#region 循环合并多个文件(插入合并文件) ///<summary> ///循环合并多个文件(插入合并文件) ///</summary> ///<param name="tempDoc">模板文件</param> ///<param name="arrCopies">需要合并的文件</param> ///<param name="outDoc">合并后的输出文件</param> /// ///其他参考代码 /* 测试代码,把光标放在文档尾部 //object start = objApp.ActiveWindow.Selection.End; //object end = objApp.ActiveWindow.Selection.End; //Range rng = objDocLast.Range(ref start, ref end); //rng.Select(); rng.Paste(); //object objEnd = rng; //objDocLast.ActiveWindow.Document.Range(ref start, ref end);
合并文档 //objDocLast.Merge( // strCopy, //FileName // ref objTarget, //MergeTarget // ref objMissing, //DetectFormatChanges // ref objUseFormatFrom, //UseFormattingFrom // ref objMissing //AddToRecentFiles // ); // objDocBeforeLast = objDocLast; // objDocLast = objApp.ActiveDocument; // if (objDocBeforeLast != null) // { // objDocBeforeLast.Close( // ref objFalse, //SaveChanges // ref objMissing, //OriginalFormat // ref objMissing //RouteDocument // ); // } */
// 进行文件合并 public void InsertMerge(string tempDoc, string[] arrCopies, string outDoc) { object objMissing = Missing.Value; object objFalse = false; object confirmConversion =false; object link = false; object attachment = false; object objTarget = WdMergeTarget.wdMergeTargetSelected; object objUseFormatFrom =WdUseFormattingFrom.wdFormattingFromSelected;
try { //只读方式打开模板文件 Open(tempDoc); foreach (string strCopyin arrCopies) { // 文档尾部追加 Object objUnit =WdUnits.wdStory; objApp.Selection.EndKey(ref objUnit); objApp.ActiveWindow.Selection.PasteAndFormat(WdRecoveryType.wdPasteDefault);
// 插入文档 objApp.Selection.InsertFile( strCopy, ref objMissing, ref confirmConversion, ref link, ref attachment ); } //保存到输出文件 SaveAs(outDoc); foreach (Document objDocumentin objApp.Documents) { objDocument.Close( ref objFalse,//SaveChanges ref objMissing,//OriginalFormat ref objMissing//RouteDocument ); } } catch(Exception ex) { objApp.Quit( ref objMissing,//SaveChanges ref objMissing,//OriginalFormat ref objMissing//RoutDocument ); objApp = null;
throw new Exception(ex.Message); } finally { if (objApp != null) objApp.Quit( ref objMissing,//SaveChanges ref objMissing,//OriginalFormat ref objMissing//RoutDocument ); objApp = null; } }
#endregion
public ActionResult GetDataSource() { int jdmxID = 0; jdmxID = Convert.ToInt32(Request["id"]); WB_RWS model = xmService.GetModel(jdmxID); RWSModel rwsModel = AutoCopy(model); rwsModel.rws01 = xmService.GetModel01(model.ID); rwsModel.rws02 = xmService.GetModel02(model.ID); rwsModel.wllj = string.Format(@"" +ConfigurationManager.AppSettings["AttachmentPath"].ToString() +"\\" + model.XWJM); rwsModel.url = "http://" + Request.Url.Host +"/" + model.XWJM;
// 对文档进行合并时,记录合并文件路径及顺序 string[] arrCopies = new string[2]; arrCopies[0] = rwsModel.wllj;// Server.MapPath("/doc/Model2.doc"); arrCopies[1] = Server.MapPath(sDocPart3);
// 对文档进行合并 InsertMerge(Server.MapPath(sDocPart1), arrCopies, Server.MapPath(sDocMerge));
// 给HashTable付值 Hashtable htCon; WorldModel world = kkk(rwsModel,out htCon);
// 标签内容写入Word文档 string FullFileName = Server.MapPath(GenWordDocument(sDocMerge, htCon));
// 下载文档[测试用] FileInfo DownloadFile =newFileInfo(FullFileName); if (DownloadFile.Exists) { Response.Clear(); Response.ClearHeaders(); Response.Buffer = false; Response.ContentType = "application/octet-stream"; Response.AppendHeader("Content-Disposition","attachment;filename=" +HttpUtility.UrlEncode(DownloadFile.FullName, System.Text.Encoding.ASCII)); Response.AppendHeader("Content-Length", DownloadFile.Length.ToString()); Response.WriteFile(DownloadFile.FullName); Response.Flush(); Response.End(); } else { //文件不存在
}
//string Json字符串 = JsonConvert.SerializeObject(rwsModel); //RWSModel dd = new WB_RWS(); return null; }
// 生成Word文档文档,返回文件下载相对路径 public string GenWordDocument(string t_filename, Hashtable htCont) { object Missing = Type.Missing; // 取得Word文件路径 string strTemp = t_filename;
// 新Word文件保存路径 CMS_Users user = Session["UserInfo"]asCMS_Users; string newFileName = sDocProv + user.Id +".doc";
// 创建一个名为WordApp的组件对象 Microsoft.Office.Interop.Word.Application WordApp =new Microsoft.Office.Interop.Word.Application(); //必须设置为不可见 WordApp.Visible = false;
try { //创建以strTemp为模板的文档 object oTemplate = Server.MapPath(strTemp); Microsoft.Office.Interop.Word.Document WordDoc = WordApp.Documents.Add(ref oTemplate,ref Missing,ref Missing,ref Missing); WordDoc.Activate();
//对标签进行循环填充 System.Collections.IEnumerator enu = WordApp.ActiveDocument.Bookmarks.GetEnumerator(); while (enu.MoveNext()) { Microsoft.Office.Interop.Word.Bookmark bk = (Microsoft.Office.Interop.Word.Bookmark)enu.Current; string strBM = bk.Name.ToString(); object objBM = strBM; if (WordApp.ActiveDocument.Bookmarks.Exists(strBM) ==true) { WordApp.ActiveDocument.Bookmarks.get_Item(ref objBM).Select(); if (htCont.ContainsKey(strBM)) WordApp.Selection.TypeText(htCont[strBM].ToString()); else { // 标签定义有问题。如果是有未找到的,说明书签有漏写部分 } } }
//保存为新文件 object oNewFileName = Server.MapPath(newFileName); WordDoc.SaveAs(ref oNewFileName,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);
// 退出资源 WordDoc.Close(ref Missing,ref Missing,ref Missing); WordApp.Quit(ref Missing,ref Missing,ref Missing); } catch (Exception Ex) { WordApp.Quit(ref Missing,ref Missing,ref Missing); throw new Exception(Ex.Message); }
return newFileName; } 二、 |
问题点及解决:
1、当服务器粘贴板中有内容时,在文件拼接的接缝处会将内容写入。原因待查。
2、如果有多个人同时操作,文档可能会出现共享读写的问题。可以定制相关模板如果多人同时操作,复制一份模板各自进行操作可以满足,但临时文件可能较多。
三、 部署
由于ASP.NET访问Word,需要相关权限,经过网上相关资料查询,一般情况下可以使用如下方法解决:
注意:服务器端安装Office尽量安装低版本,可以兼容其他用户较低版本的Office。
1、设置相关权限
i. 运行dcomcnfg
ii. 选中DCOM中的Word
iii. 右键属性相关设置如图示
2、其他问题及解决
64位系统偶尔可能会出现错误,有可能是利用到了一些其他的库。具体没查,会与IIS中的应用程序池设置相关,图形如下: