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         #endregion
116 
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             try
132             {
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         #endregion
156 
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             try
166             {
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         #endregion
182 
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                     else
205                         lsFile.Add(item.FullName);
206                 }
207             }
208             return lsFile;
209         } 
210         #endregion
211 
212     }
213     #endregion 
214 
215     #region 插入文档
216     public class InsertFile
217     {
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         #endregion
254 
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         #endregion
293     }
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='@item.CardNo' 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

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

图片

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

图片

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

图片

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

图片

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

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

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

图片

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

图片
原文地址:https://www.cnblogs.com/jingshuisihan/p/4604321.html