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

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];
            }
           else
            return -1;
        }

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

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是刘彦宏吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值