当前位置: 代码迷 >> C# >> C# 导出word文档及批量导出word文档(四)
  详细解决方案

C# 导出word文档及批量导出word文档(四)

热度:366   发布时间:2016-05-05 03:19:06.0
C# 导出word文档及批量导出word文档(4)
      接下来是批量导出word文档和批量打印word文件,批量导出word文档和批量打印word文件的思路差不多,只是批量打印不用打包压缩文件,而是把所有文件合成一个word,然后通过js来调用word,提交打印机,把word文档的内容都打印出来。
     批量导出word文档需要用到ICSharpCode.SharpZipLib.dll 插件,思路是,先单独导出所勾选的数据的单个文档,保存到生成的临时目录下,再把同一个的人相关文档合并一个word文档,并删除已经合并的那个文档(不是合并后生成的文档),以姓名和编号命名生成后的文档,最后将临时目录下的所有文件打包压缩下载,并删除临时目录和临时目录下的所有文件(都是生成在服务器上,所以若文件太大,可能会慢)。批量导出是用form来提交所传的参数,并下载。(因为懒,不解释代码了)
      首先新建一个空文档,插入书签,书签名为“p”(随便定义的),命名文件名为“test.doc”,保存在项目目录下。       
      相关js代码为:     
  1  /***************************************  2  * @methodname→批量导出word文档  3  * @createtime 2015-05-11  4  ***************************************/  5 function AllExportWord(objid, tfile) {  6     var ckvalue = "", ntid = "", code = "", name = "";  7     var chkbox = $("input[type=checkbox][name=chk]:checked");  8     for (var i = 0; i < chkbox.length; i++) {  9         ckvalue = ckvalue + chkbox[i].value + ",";  //主键值 10         ntid = ntid + $(chkbox[i]).attr("data-ntid") + ","; //学生主键 11         code = code + $(chkbox[i]).attr("data-code") + ","; //胸卡号 12         name = name + $(chkbox[i]).attr("data-name") + ","; //姓名 13     } 14     if (ckvalue != "") { 15         ntid = ntid.substring(0, ntid.length - 1); 16         code = code.substring(0, code.length - 1); 17         name = name.substring(0, name.length - 1); 18         $.ajax({ 19             type: "POST", 20             url: "/NewStudent/BatchExportWord", 21             dataType: "json", 22             data: { tempFile: tfile, ntid: ntid }, 23             async: false, 24             success: function (data) { 25                 if (data.isOK) { 26                     var count = ntid.split(',').length; 27                     if (count == data.ls.length && count > 0) { 28                         DownLoadWord(objid, tfile, ntid, code, name, true); 29                     } 30                     else { 31                         if (confirm("选择导出的数据中包含没有学习记录的数据,是否确认导出或打印?")) { 32                             DownLoadWord(objid, tfile, ntid, code, name, true); 33                         } 34                     } 35                 } 36                 else { 37                     alert(data.msg); 38                 } 39             } 40         }); 41     } 42     else { 43         alert("请选择数据!"); 44     } 45 } 46 /*************************************** 47  * @methodname→批量导出word文档 48  * @createtime 2015-05-11 49  ***************************************/ 50 function BatchExportWord(objid, tfile) {    51     var ckvalue = "", ntid = "", code = "", name = ""; 52     var chkbox = $("input[type=checkbox][name=chk]:checked"); 53     for (var i = 0; i < chkbox.length; i++) { 54         ckvalue = ckvalue + chkbox[i].value + ",";  //主键值 55         ntid = $(chkbox[i]).attr("data-ntid"); //学生主键 56         code = $(chkbox[i]).attr("data-code"); //胸卡号 57         name = $(chkbox[i]).attr("data-name"); //姓名 58     } 59     if (ckvalue != "") { 60         ckvalue = ckvalue.substring(0, ckvalue.length - 1); //去掉最后一个逗号 61         $.ajax({ 62             type: "POST", 63             url: "/NewStudent/BatchExportWord", 64             dataType: "json", 65             data: { tempFile: tfile }, 66             async: false, 67             success: function (data) { 68                 if (data.isOK) { 69                     DownLoadWord(objid, tfile, ntid, code, name, false) 70                 } 71                 else { 72                     alert(data.msg); 73                 } 74  75             } 76         }); 77     } 78     else { 79         alert("请选择数据!"); 80     } 81 } 82 /************************************************* 83  * @methodname→只能通过流的方式批量导出word文档 84    在页尾添加form,通过提交form表单才能下载 85  * @createtime 2015-05-12 86  *************************************************/ 87 function DownLoadWord(idName, tfile, ntid, code, name, isAll) {    88     $("body").find("form.#form1").remove(); 89     var form = "<form id='form1'></form>"; 90     var input = "<input />"; 91     var input1 = "", input2 = "", input3 = "", input4 = "", input5 = "", input6 = ""; 92     input1 = $(input); input1.attr("type", "hidden"); input1.attr("name", "tempFile"); input1.attr("value", tfile); 93     input2 = $(input); input2.attr("type", "hidden"); input2.attr("name", "ntid"); input2.attr("value", ntid); 94     input3 = $(input); input3.attr("type", "hidden"); input3.attr("name", "code"); input3.attr("value", code); 95     input4 = $(input); input4.attr("type", "hidden"); input4.attr("name", "name"); input4.attr("value", name); 96     input5 = $(input); input5.attr("type", "hidden"); input5.attr("name", "isAll"); input5.attr("value", isAll); 97     input6 = $(input); input6.attr("type", "hidden"); input6.attr("name", "idName"); input6.attr("value", idName); 98     $("body").append(form); //将表单放置在web中 99     //添加表单属性100     $("#form1").attr("style", "display:none");101     $("#form1").attr("target", "");102     $("#form1").attr("method", "post");   103     $("#form1").attr("action", "/NewStudent/DownLoadWord");  104   105     //添加input到表单里106     $("#form1").append(input1)107     $("#form1").append(input1);108     $("#form1").append(input2);109     $("#form1").append(input3);110     $("#form1").append(input4);111     $("#form1").append(input5);112     $("#form1").append(input6);113     $("#form1").submit();114 }
js

     相关后台代码如下: 

  1 #region 压缩文件及文件夹  2     /// <summary>  3     /// 压缩文件及文件夹  4     /// </summary>  5     public class CompressFileZip  6     {  7         private ZipOutputStream zos = null;  8         private string strBaseDir = "";  9  10         #region 临时文件夹名称 11         /// <summary> 12         /// 临时文件夹名称 13         /// </summary> 14         /// <param name="name">学生名称</param> 15         /// <param name="value">学生卡号</param> 16         /// <returns></returns> 17         public string FolderName(string name, string value) 18         { 19             string tempName = ""; 20             if (!string.IsNullOrEmpty(name)) 21             { 22                 tempName = name; 23                 if (!string.IsNullOrEmpty(value)) 24                     tempName += "_" + value; 25                 tempName += "_" + DateTime.Now.ToString("yyyyMMddHHmm"); 26             } 27             else 28             { 29                 tempName = DateTime.Now.ToString("yyyyMMddHHmmss"); //临时文件夹名称 30             } 31             return tempName; 32         } 33         #endregion 34  35         #region 创建临时文件夹 36         /// <summary> 37         /// 创建临时文件夹 38         /// </summary> 39         /// <param name="name">学生名称</param> 40         /// <param name="value">学生卡号</param> 41         /// <returns></returns> 42         public string CreateTempFolder(string name, string value = null) 43         { 44             //遍历服务器指定文件夹下的所有文件 45             string path = "UploadFile"; 46             string serverPath = WordFilePath.GetFilePath(path); 47             string tempName = ""; 48             if (!string.IsNullOrEmpty(value)) 49                 tempName = FolderName(name, value); 50             else 51                 tempName = name; 52             string tempFolder = Path.Combine(serverPath, tempName); 53             Directory.CreateDirectory(tempFolder); //创建临时文件夹 54             //DirectoryInfo folder = new DirectoryInfo(serverPath); 55             return tempFolder + "\\"; 56         } 57         #endregion 58  59         #region 添加文件到压缩文件中 60         /// <summary> 61         /// 添加文件到压缩文件中 62         /// </summary> 63         /// <param name="PathStr">路径</param> 64         public void addZipEntry(string PathStr) 65         { 66             DirectoryInfo di = new DirectoryInfo(PathStr); 67             foreach (DirectoryInfo item in di.GetDirectories()) 68             { 69                 addZipEntry(item.FullName); 70             } 71             foreach (FileInfo item in di.GetFiles()) 72             { 73                 FileStream fs = System.IO.File.OpenRead(item.FullName); 74                 byte[] buffer = new byte[fs.Length]; 75                 fs.Read(buffer, 0, buffer.Length); 76                 string strEntryName = item.FullName.Replace(strBaseDir, ""); 77                 ZipEntry entry = new ZipEntry(strEntryName); 78                 zos.PutNextEntry(entry); 79                 zos.Write(buffer, 0, buffer.Length); 80                 fs.Close(); 81             } 82         } 83         #endregion 84  85         #region 输出下载压缩包 86         /// <summary> 87         /// 输出下载压缩包 88         /// </summary> 89         /// <param name="response">页面响应</param> 90         /// <param name="strPath">文件所在的路径</param> 91         /// <param name="strFileName">压缩文件名</param> 92         /// <param name="strExt">压缩文件的扩展名</param> 93         public void dlZipDir(HttpResponseBase response, string strPath, string strFileName, string strExt = null) 94         { 95             if (string.IsNullOrEmpty(strExt)) 96                 strExt = ".zip"; //默认压缩文件扩展名 97             MemoryStream ms = null; 98             response.ContentType = "application/octet-stream"; 99             strFileName = HttpUtility.UrlEncode(strFileName).Replace('+', ' ');100             response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName + strExt);101             ms = new MemoryStream();102             zos = new ZipOutputStream(ms);103             strBaseDir = strPath + "\\";104             addZipEntry(strBaseDir);105             zos.Finish();106             zos.Close();107             response.Clear();108             response.BinaryWrite(ms.ToArray());109             //删除临时目录下的所有文件110             DeleteTempFiles(strPath);111             //删除空目录112             Directory.Delete(strPath);113             response.End();114         }115         #endregion116 117         #region 保存文件到临时文件夹中118         /// <summary>119         /// 保存文件到临时文件夹中120         /// </summary>121         /// <param name="content">将流内容写入字节组</param>122         /// <param name="SaveName">保存的文件名</param>123         /// /// <param name="dirPath">保存路径</param>124         /// <param name="fileExtend">保存的文件扩展名</param>125         /// <returns></returns>126         public void SaveFile(byte[] content, string SaveName, string dirPath, string fileExtend = null)127         {128 129             if (string.IsNullOrEmpty(fileExtend))130                 fileExtend = ".doc"; //文件扩展名默认是word文档131             try132             {133                 DateTime dt = DateTime.Now;134                 //设置文件夹路径135                 //directory = CreateTempFolder(strName, strCode);136                 //文件保存完整路径137                 string path = dirPath + SaveName + fileExtend;138                 //验证文件夹是否存在   不存在则创建139                 if (!Directory.Exists(dirPath))140                 {141                     Directory.CreateDirectory(dirPath);142                 }143                 //以创建文件的方式写入内容144                 FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write);145                 BinaryWriter w = new BinaryWriter(fs);146                 w.Write(content);147                 w.Close();148                 fs.Close();149             }150             catch (Exception ex)151             {152                 throw new System.IO.FileNotFoundException("目录:" + dirPath + "没有找到!");153             }154         }155         #endregion156 157         #region 删除临时目录下的所有文件158         /// <summary>159         /// 删除临时目录下的所有文件160         /// </summary>161         /// <param name="tempPath">临时目录路径</param>162         private void DeleteTempFiles(string tempPath)163         {164             DirectoryInfo directory = new DirectoryInfo(tempPath);165             try166             {167                 foreach (FileInfo file in directory.GetFiles())168                 {169                     if (file.Attributes.ToString().IndexOf("ReadOnly") != -1)170                     {171                         file.Attributes = FileAttributes.Normal;172                     }173                     System.IO.File.Delete(file.FullName);174                 }175             }176             catch (Exception)177             {178                 throw;179             }180         }181         #endregion182 183         #region 获取指定文件夹下的所有文件184         /// <summary>185         /// 获取指定文件夹下的所有文件186         /// </summary>187         /// <param name="Folder">文件夹名称</param>188         /// <param name="strName">文件夹下所包含指定文件名的文件</param>189         /// <returns></returns>190         public List<string> GetFileList(string Folder, string strName = null)191         {192             List<string> lsFile = new List<string>();193             if (!string.IsNullOrEmpty(Folder))194             {195                 Folder = WordFilePath.GetFilePath("UploadFile", Folder + "\\");196                 DirectoryInfo di = new DirectoryInfo(Folder);197                 foreach (FileInfo item in di.GetFiles())198                 {199                     if (!string.IsNullOrEmpty(strName))200                     {201                         if (item.FullName.Contains(strName))202                             lsFile.Add(item.FullName);203                     }204                     else205                         lsFile.Add(item.FullName);206                 }207             }208             return lsFile;209         } 210         #endregion211 212     }213     #endregion 214 215     #region 插入文档216     public class InsertFile217     {218         #region 在书签位置插入另一个文档的内容219         /// <summary>220         /// 使用DocumentBuilder对象插入一些文档对象,如插入书签,插入文本框,插入复选框221         /// 插入一个段落,插入空白页,追加或另一个word文件的内容等。222         /// </summary>223         /// <param name="doc">载入模板</param>224         /// <param name="tempFile"></param>225         /// <param name="mark">载入模版名称</param>226         /// <param name="lsFile"></param>227         public static void InsertDoc(Document doc, string mark, List<string> lsFile, string SaveName = null)228         {229             string savePath = "";230             var builder = new DocumentBuilder(doc);231             if (!string.IsNullOrEmpty(SaveName))232                 SaveName = SaveName.Substring(0, SaveName.LastIndexOf("_"));233             Document doc1;234             for (int i = 0; i < lsFile.Count; i++)235             {236                 if (i == 0)237                     savePath = lsFile[i].Substring(0, lsFile[i].LastIndexOf('\\') + 1);238                 doc1 = new Document(lsFile[i]);//新文档239                 var bookmark = doc.Range.Bookmarks[mark];240                 //清空书签的文本241                 //bookmark.Text = "";242                 //定位到指定位置进行插入操作243                 builder.MoveToBookmark(mark, false, false);244                 InsertDocument(bookmark.BookmarkStart.ParentNode, doc1);245                 //doc.FirstSection.PageSetup.SectionStart = SectionStart.NewPage;246                 //doc1.AppendDocument(doc, ImportFormatMode.KeepSourceFormatting);247 248                 System.IO.File.Delete(lsFile[i]); //删除已经插入的文件                249             }250             if (!string.IsNullOrEmpty(SaveName))251                 doc.Save(savePath + SaveName + ".doc");252         }253         #endregion254 255         #region 插入文档256         /// <summary>257         /// 插入文档258         /// </summary>259         /// <param name="insertAfterNode">节点在目标文件中的内容后插入。这个节点应该是一个块级节点(段落或表格)。</param>260         /// <param name="srcDoc">插入文档</param>261         private static void InsertDocument(Node insertAfterNode, Document srcDoc)262         {263             // 确保插入点是一个段落或表格。264             if ((!insertAfterNode.NodeType.Equals(NodeType.Paragraph)) &265               (!insertAfterNode.NodeType.Equals(NodeType.Table)))266                 throw new ArgumentException("插入的目的节点应该是一个段落或表格。");267 268             // 插入到目标段落269             CompositeNode dstStory = insertAfterNode.ParentNode;270             NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.KeepSourceFormatting);271 272             //在源文件中循环273             foreach (Section srcSection in srcDoc.Sections)274             {275                 foreach (Node srcNode in srcSection.Body)276                 {277                     // 跳过空节点278                     if (srcNode.NodeType.Equals(NodeType.Paragraph))279                     {280                         Paragraph para = (Paragraph)srcNode;281                         if (para.IsEndOfSection && !para.HasChildNodes)282                             continue;283                     }284                     // 插入到目标文档285                     Node newNode = importer.ImportNode(srcNode, true);286                     // 参考节点后插入新节点287                     dstStory.InsertAfter(newNode, insertAfterNode);288                     insertAfterNode = newNode;289                 }290             }291         }292         #endregion293     }294     #endregion 
Code

    页面调用的方式如下:

1 <input id="Export" type="button" class="s_btn" value="批量导出" onclick="AllExportWord(this.id, '接收进修生手册导出模板')" />2  <input id="Print" type="button" class="s_btn" value="批量打印" onclick="AllExportWord(this.id, '接收进修生手册导出模板')" />3  <input type="checkbox" name="chk" id="chk" value[email protected]' data-ntid="@item.NTID" data-code="@item.CardNo" data-name="@item.NTName" /></td>
Html

    这里的this.id是传当前请求的按钮的id,因为调用的方法都一样,所以同时传id,加以区分页面的请求,以实现不同的功能。
controller调用的方法: 

  1        #region 批量下载文件前的验证  2       /// <summary>  3         /// 批量下载文件前的验证  4      /// </summary>  5         /// <param name="tempFile">模板</param>  6         /// <param name="ntid">学生主键</param>  7         /// <returns></returns>  8         public JsonResult BatchExportWord(string tempFile, string ntid = null)  9         { 10             bool isOK = false; 11             string msg = ""; 12             string strpath = "Content/templates"; 13             List<string> ls = new List<string>(); 14             if (!string.IsNullOrEmpty(tempFile)) 15             { 16                 if (Path.GetExtension(tempFile) != ".doc") 17                     tempFile = tempFile + ".doc"; 18                 isOK = WordFilePath.ExistFile(strpath, tempFile); 19                 if (!isOK) 20                     msg = "导出的模板不存在!"; 21                 else 22                 { 23                     if (!string.IsNullOrEmpty(ntid)) 24                     { 25                         string[] strNTID = ntid.Split(','); 26                         for (int i = 0; i < strNTID.Length; i++) 27                         { 28                             NameValueCollection nvc = new NameValueCollection(); 29                             nvc.Add(GetPropertyName<Model.MajorCycle>(m => m.NTID), strNTID[i]); 30                             IList<Model.MajorCycle> lsMCycle = new BLL.MajorCycle().GetModelList<Model.MajorCycle>(nvc); 31                             if (lsMCycle.Count > 0) 32                                 ls.Add(string.Join(",", lsMCycle.Select(m => m.ID))); 33                         } 34                     } 35                 } 36             } 37             else 38             { 39                 msg = "导出的模板为空!"; 40             } 41             return Json(new { isOK = isOK, msg = msg, ls = ls }); 42         } 43         #endregion 44  45         #region 下载压缩包 46         /// <summary> 47         /// 下载压缩包 48         /// </summary> 49         /// <param name="tempFile">模板</param> 50         /// <param name="ntid">学生主键</param> 51         /// <param name="code">学生编号</param> 52         /// <param name="name">学生名称</param> 53         /// <param name="isAll">是否全部导出</param> 54         /// <param name="idName">请求按钮id名称</param> 55         /// <returns></returns> 56         public FileContentResult DownLoadWord(string tempFile, string ntid, string code, string name, string isAll, string idName) 57         { 58             CompressFileZip fileZip = new CompressFileZip(); 59             string saveName = "", dirPath = "", GzipFileName = "", mid = "", stype = "", sequence = ""; 60             Document doc = new Document(); 61             var docStream = new MemoryStream(); 62             if (!string.IsNullOrEmpty(ntid)) 63             { 64                 string[] strNTID = ntid.Split(','); 65                 string[] strCode = code.Split(','); 66                 string[] strName = name.Split(','); 67                 for (int i = 0; i < strNTID.Length; i++) 68                 { 69                     if (i == 0) //第一次时创建临时文件夹 70                     { 71                         if (!string.IsNullOrEmpty(isAll) && isAll == "true") 72                             GzipFileName = fileZip.FolderName(tempFile.Substring(0, tempFile.IndexOf("") + 1), ""); 73                         else 74                             GzipFileName = fileZip.FolderName(strName[i], strCode[i]); 75                         dirPath = fileZip.CreateTempFolder(GzipFileName); 76                     } 77                     NameValueCollection nvc = new NameValueCollection(); 78                     nvc.Add(GetPropertyName<Model.MajorCycle>(m => m.NTID), strNTID[i]); 79                     IList<Model.MajorCycle> lsMCycle = new BLL.MajorCycle().GetModelList<Model.MajorCycle>(nvc); 80                     if (lsMCycle.Count > 0) //如果不以这方式,则没有学习记录的数据导出来会是一个空的压缩包,什么文件也没有 81                     { 82                         mid = string.Join(",", lsMCycle.Select(m => m.MajorID)); // 轮转科室id 83                         stype = lsMCycle[0].StudentType.ToString().Trim(); // 学生类型 84                         sequence = string.Join(",", lsMCycle.Select(m => m.Sequence)); // 轮转次数 85                     } 86                     string[] midArr = mid.Split(','); 87                     string[] sequenceArr = sequence.Split(','); 88                     mid = ""; sequence = ""; 89                     for (int j = 0; j < midArr.Length; j++) 90                     { 91                         saveName = strName[i] + "_" + strCode[i] + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff"); 92                         WordHelper wordhelper = new WordHelper(tempFile); 93                         getWordInfo(wordhelper, tempFile, strNTID[i], stype, midArr[j], sequenceArr[j]); 94                         fileZip.SaveFile(wordhelper.ExportDoc().ToArray(), saveName, dirPath); 95                     } 96                     if (!string.IsNullOrEmpty(isAll) && isAll == "true" && idName == "Export") 97                     { 98                         doc = new Document(WordFilePath.GetFilePath("Content/templates", "test.doc")); 99                         InsertFile.InsertDoc(doc, "p", fileZip.GetFileList(GzipFileName, strName[i]), saveName);100                     }101 102                 }103                 if (idName == "Export")104                     fileZip.dlZipDir(Response, WordFilePath.GetFilePath("UploadFile", GzipFileName), GzipFileName); //压缩下载105             }106 107             if (idName == "Print") //打印108             {109                 doc = new Document(WordFilePath.GetFilePath("Content/templates", "test.doc"));110                 InsertFile.InsertDoc(doc, "p", fileZip.GetFileList(GzipFileName));                111                 doc.Save(docStream, SaveOptions.CreateSaveOptions(SaveFormat.Doc));112                 Directory.Delete(WordFilePath.GetFilePath("UploadFile", GzipFileName));113             }114             return base.File(docStream.ToArray(), "application/msword", GzipFileName);115         }116         #endregion 
View Code

  导出的效果如下图:             图片              生成的临时文件夹:          

图片

      同一人的首先生成单个文件

图片

        将两个文件合并成一个文件,以姓名和编号命名,同时删除合并前生成的那两个文件:

图片

      循环生成 下一个人的单个文档

图片

     合并文件,以姓名和编号命名,同时删除合并前的文件:

图片
     打包压缩合并后的这两个文件,并下载:
图片   
 

       打印的效果如下图:         将所有人的有关文档都生成单个文件 

图片

       最后合并成一个文件,并输出:

图片
  相关解决方案