C# 操作通过word模板合并N个word文档

C# 操作通过word模板合并N个word文档。在工作中遇到了这样一个工作场景,客户需要经常对上级上报或者汇报本阶段的工作, 比如:日报、周报、月总结、季度分析、年度汇总等,这些文档的模板下级不能自己创造, 只能按照上级的制定好的文档进行填报,部门领导需要汇总本部分若干个人的汇报成果再合并到一起, 人工量非常之大, 所以这个就是本文产生的场景。

本文介绍通过Aspose.Words这个第三方控件库来操作word,有点事脱离了引用原生word类库。

先把业务场景的图片贴上来, 假设有两个同类型的文档:

1.将使用同一个模板类型的文档按书签把对应的内容合并到对应的章节。

/// <summary>/// 文件合并,必须是同一类型的文件/// </summary>/// <param name="reportClassfication">获取上报报表模板dic_report_classfication</param>/// <param name="_product">产品,简称产品,本单位编辑的情报;一般是WORD文档,包括普通产品和加密产品。</param>/// <param name="_needMergeInformations">简称素材,下级单位向本单位上报的情报</param>/// <returns></returns>public bool MergeReportDocument(Models.Inteligence.ReportClassification reportClassfication,Models.Inteligence.ReportIntelProduct _product,List<Models.Inteligence.ReportIntelInformation> _needMergeInformations){string templateFile = reportClassfication.LocalPath;if (!File.Exists(templateFile)){throw new ArgumentException(templateFile, string.Format("{0} 文件不存在", Path.GetFileName(templateFile)));}List<Aspose.Words.Document> _ReportInformationDocs = new List<Aspose.Words.Document>();try{foreach (Models.Inteligence.ReportIntelInformation item in _needMergeInformations){Aspose.Words.Document _inforDoc = null;string InforFileName = item.File.LocalPath;_inforDoc = new Aspose.Words.Document(InforFileName);if (_inforDoc == null){Log.LogHelper.e(item.ID + "open _inforDoc Failed ");return false;}_ReportInformationDocs.Add(_inforDoc);}if (!File.Exists(reportClassfication.LocalPath)){File.Copy(reportClassfication.LocalPath, _product.File.LocalPath);}//创建_product_ReportProductDoc = new Aspose.Words.Document(templateFile);}catch (Exception e){Log.LogHelper.i("Open Word Failed, ", e);return false;}Dictionary<string, List<Aspose.Words.Paragraph>> dictBookMark = new Dictionary<string, List<Aspose.Words.Paragraph>>(); //创建键值对   第一个string 为书签名称 第二个string为要填充的数据//实例化新建一个空白的文档        Aspose.Words.DocumentBuilder builder = new Aspose.Words.DocumentBuilder(_ReportProductDoc);try{     //获取模板的标签List<string> listAllBookmark = new List<string>();foreach (Aspose.Words.Bookmark bookmark in _ReportProductDoc.Range.Bookmarks){if (!bookmark.Name.Equals("_GoBack")){listAllBookmark.Add(bookmark.Name);dictBookMark.Add(bookmark.Name, new List<Aspose.Words.Paragraph>());}                   }                List<Aspose.Words.Paragraph> listParagraph = new List<Aspose.Words.Paragraph>();for (int j = 0; j < _ReportInformationDocs.Count; j++){//包含书签的段落的索引int[] bookMarkIndex = new int[listAllBookmark.Count+1];Aspose.Words.ParagraphCollection paragraphs = GetAllWordParagraphs(_ReportInformationDocs[j]);// WordParagraphs_ReportInformationDocs[j].GetChildNodes(Aspose.Words.NodeType.Paragraph, true);if (paragraphs != null){GetBookMarkIndexInWordParagraphs(paragraphs, ref bookMarkIndex);//获取索引for (int loction = 0; loction < listAllBookmark.Count; loction++){listParagraph = dictBookMark[listAllBookmark[loction]];int rangeNext = GetRangeIndex(loction, bookMarkIndex);//获取两个书签之间的段落索引位置for (int section = bookMarkIndex[loction]; section < rangeNext; section++){if (rangeNext== paragraphs.Count){listParagraph.Add(paragraphs[section]);}else{if (section != rangeNext - 1){listParagraph.Add(paragraphs[section]);}                                  }}}}}             foreach (var key in dictBookMark.Keys)   //循环键值对{builder.MoveToBookmark(key);  //将光标移入书签的位置string strBookmark = "";foreach (Aspose.Words.Paragraph text in dictBookMark[key]){strBookmark += text.GetText();                       }builder.Write(strBookmark);}//文件输出路径,包含文件名//string saveFile = Path.Combine(templateFile, saveFileName);string fileName = _product.File.LocalPath;_ReportProductDoc.Save(fileName);}catch (Exception e){//if (MessageDxUtil.ShowYesNoAndTips("导出成功,是否打开文件?") == System.Windows.Forms.DialogResult.Yes)//{//    Process.Start(saveFile);//}Log.LogHelper.i("Merge Word Failed, ", e);return false;}return true;}

2.至此上面完成合并, 但会有一个问题,一旦标签处换行,内容则无法完整合并, 具体看如下图所示文档结构。

Aspose.Words文档DOM结构

为此我们需要遍历DOM结构,将内容获取到然后再合并。

//1.获取所有段落
public Aspose.Words.ParagraphCollection GetAllWordParagraphs(Aspose.Words.Document docfile){      if (docfile.FirstSection.Body.Paragraphs.Count > 0){return docfile.FirstSection.Body.Paragraphs;//word中的所有段落}return null;}//2.获取段落内的书签位置索引public void GetBookMarkIndexInWordParagraphs(Aspose.Words.ParagraphCollection paragraphs,ref int[] bookMarkIndex){List<int> list = new List<int>();for (int i = 0; i < paragraphs.Count; i++){if (paragraphs[i].Range.Bookmarks.Count > 0){list.Add(i);}}list.Add(paragraphs.Count);bookMarkIndex =list.ToArray();            }
//3.返回索引private int  GetRangeIndex(int currentLoc,int[] bookMarkIndex){if (currentLoc<bookMarkIndex.Length){return   bookMarkIndex[currentLoc + 1];}elsereturn -1;}

3.关于Aspose.Words 文档的详细DOM结构,大家可百度搜索。

C# 操作通过word模板合并N个word文档相关推荐

  1. Vue根据word模板导出页面所需文档

    今天看到前端页面感觉还挺神奇,决定学习一下这个功能是怎么写的. 这是报价单生成页面,当该填的内容填完之后,点击立即创建.然后就会生成一个报价单.是不是挺有意思的,一瞬间发现了前端的乐趣. 先说一下里面 ...

  2. SpringBoot集成文件 - 如何基于POI-tl和word模板导出庞大的Word文件?

    前文我们介绍了通过Apache POI通过来导出word的例子:那如果是word模板方式,有没有开源库通过模板方式导出word呢?poi-tl是一个基于Apache POI的Word模板引擎,也是一个 ...

  3. [OfficeExcel] Word+Excel邮件合并 生成多个文档

    王佩丰老师OfficeExcel2010 13讲 邮件合并--引用Excel数据 学习笔记 批量生成多个邮件 利用Word发送邮件 每页显示多条记录 邮件合并后得数字格式处理 批量生成多个邮件 邮件& ...

  4. Word中使用MathType批量调整文档公式的大小

    Word中使用MathType批量调整文档字母公式大小 背景:论文写作需要撰写大量的字母和数学公式,但是在协作撰写及内容中英文翻译过程中,字母和数学公式容易变形,因此Word中使用MathType批量 ...

  5. [.NET开发] C# 合并、拆分PDF文档

    在整理文件时,将多个同类型文档合并是实现文档归类的有效方法,也便于文档管理或者文档传输.当然,也可以对一些比较大的文件进行拆分来获取自己想要的部分文档.可以任意地对文档进行合并.拆分无疑为我们了提供极 ...

  6. java pdf合并_Java 合并、拆分PDF文档

    本文将介绍如何在Java程序中合并及拆分PDF文档,合并文档时,包括合并多个不同PDF文档为一个文档,以及合并PDF文档的不同页面为一页:拆分文档是,包括将PDF文档按每一页拆分,以及按指定页数范围来 ...

  7. WPS文字如何将多个文档快速合并成一个WPS文档?

    有些时候我们需要将多个WPS文档合并成一个文档,如我们写系列文章的时候是一篇一个文档保存,最后写完之后想将他们合并成一个WPS文档便于转换PDF格式输出.除了一个个文档打开然后复制粘贴到新文档外,我们 ...

  8. Java:多个文档合并输出到一个文档

    多个文档合并输出到一个文档 方法:Java NIO package First;import java.io.File; import java.io.FileInputStream; import ...

  9. word打开wps文件乱码_word文档打开是乱码解决方法

    上网搜索资料,好不容易下载一个心仪的文档,当我们再次打开这个文档时,发现Word文档却出现乱码,或者是已经损坏了的文档,这还怎么看呢?如果出现Word文档乱码这种情况,大家不要着急,现在分享word乱 ...

最新文章

  1. (multi)set的某些操作
  2. 将图片的二进制字节 在HTML页面中显示
  3. 多选框实现单选效果,并且把中文值赋值到特定输入框
  4. 套接字编程(VC_Win32)
  5. Spring MVC的web.xml配置详解(转)
  6. c++协程1 (boost::coroutine)
  7. 发生地震等灾难,死难者的存款会怎么处理?
  8. Android入门(15)| 网络
  9. 【过程改进】10分钟进阶Nuget
  10. 【技术体系】前端工程师
  11. 【转】和菜鸟一起学linux之DBUS基础学习记录
  12. Leetcode116. 填充每个节点的下一个右侧节点指针(宽搜或深搜)
  13. 项目管理课程体系——世纪德本PMCD品牌课程
  14. 乡镇村级别的地理经纬度数据网址
  15. 阿里云企业邮箱标准版多域名绑定
  16. linux虚拟机 dnw,在Linux下安装DNW
  17. 银盒子受邀出席银联云闪付大会,获“最佳行业合作”奖
  18. 双击xmind文件没反应
  19. Win10系统繁体字输入切换为简体字快捷键
  20. Matlab在win10运行不出图片,win10系统网页图片加载不出来的六种原因及解决方法...

热门文章

  1. 火狐插件restclient发送post请求
  2. 1.1.4实践环节--制作调查问卷
  3. 【论文排版】参考文献的格式设置
  4. Jekyll 教程——安装
  5. 内网外网服务器时间同步解决方案
  6. 评论回复功能 asp.net_LR2021颜色分级功能让照片调色简单有趣好玩!最新尝鲜测试...
  7. python有参函数和无参函数的区别_构造函数的有参和无参的区别,构造函数的参数是派什么用场的?...
  8. 注册kaggle帐号及kaggle绑定手机收不到验证码的问题
  9. C++11\14\17\20 新特性整理
  10. 根据人民币大写规则写的java工具类