word嵌入表格,完美解决报表

    【背景概要】
    项目中,有很多地方涉及到需要打印各种表格,静态的,动态的,都有。而之前利用锐浪报表实现了显示表格的需求,但在进行条件筛选后,报表中的数据并不能显示了。这个问题一直搁置了很久,一直得不到解决。
    【问题解决】
    在放下报表问题实现其它需求期间,偶然发现,我们可以动态的将表格嵌入到word文件中,利用word将各种表格显示打印。这里用到的就是Aspose Word控件,不但可以帮助我们实现在word中插入必要的参数,也可以帮助我们在word中插入必要的表格。
    【项目环境】
    项目前台利用的MVC框架,EasyUI样式,VS2012开发环境。
    【实现步骤】
    1.在本地新建一个word模板,在项目中添加现有项,把制作好的word模板添加到项目中。
    word模板如下图所示,
    word嵌入表格,完美解决报表
    参数说明:模板{}中的字段都是灵活的,所以在此写成这样作为参数,在项目中通过代码动态加载。
    2.前台页面已经实现通过按条件搜索,将查询到的数据显示在datagrid表格中,具体效果如下图所示:  
  word嵌入表格,完美解决报表
    3.查询结果出来后,下面真正开始利用代码实现将表格嵌入word模板中。关键步骤如下:
      第一,获取招标文件制作模板:
            //获得程序集根目录
            string rootPath = AppDomain.CurrentDomain.BaseDirectory;
 
            //招标文件模板路径
            var mainDocPath = rootPath + "/Content/评委签到记录表/" + "评委签到表.doc";
            Aspose.Words.Document docMain = new Aspose.Words.Document(mainDocPath);
            DocumentBuilder builder = new DocumentBuilder(docMain);
     第二,通过前台页面和后台方法,获取各个参数:
    //获取招标项目编号
    string BidProjectId = Request["BidProjectId"].ToString();
    //获取招标项目名称
    string BidCompanyName = iBidZRecordInfoService.GetBidNameByBidProjectId(BidProjectId);
     第三,将获取到的参数值替换到模板中:
            //获取系统当前时间
            DateTime now = DateTime.Now;
            //替换招标编号        
            docMain.Range.Replace("{BidProjectId}", BidProjectId, false, false);
            //替换项目名称        
            docMain.Range.Replace("{ProjectName}", BidCompanyName, false, false);
            //替换评标报告生成日期
            docMain.Range.Replace("{Now}", now.Year + "年" + now.Month + "月" + now.Day + "日", false, false);
     第四,嵌入表格的表头:
            //开始添加值,书签设置,控制表格的起始位置
            builder.MoveToBookmark("table");
            //添加表头数据
            ArrayList tableHeadArray = new ArrayList();
            //添加固定的前两列表头信息
            tableHeadArray.Add("姓名");
            tableHeadArray.Add("工作单位");
            tableHeadArray.Add("职称");     
            tableHeadArray.Add("到达时间");
            tableHeadArray.Add("备注");
            for (int j = 0; j < tableHeadArray.Count; j++)
            {
                //插入单元格
                builder.InsertCell();
                //设置单元格边框样式及颜色
                builder.CellFormat.Borders.LineStyle = LineStyle.Single;
                builder.CellFormat.Borders.Color = System.Drawing.Color.Black;
                //设置单元格宽度
                builder.CellFormat.Width = 100;
                //将值填入表格
                builder.Write(tableHeadArray[j].ToString());
 
            }
            builder.EndRow();
     第五,将查询到的数据动态嵌入word中:
              //获取条件查询后的结果,返回值为List<ViewModel>
            List<SpecialistInfoViewModel> SpecialistInfo = iSpecialistService.GetSpecialInfo(BidProjectId);
             //定义一个新的List集合,以便最后直接将记录整行填充
            IList<IList<string>> temp= new List<IList<string>>();
             //控制表格的行数,即为查询到结果的count值
            for (int n = 0; n < SpecialistInfo.Count; n++)
            {
                //定义一个新的List集合,存储各行各字段的值
                List<string> newspecialist = new List<string>();
                newspecialist.Add(SpecialistInfo[n].SpecialistName.ToString());
                newspecialist.Add("");
                newspecialist.Add(SpecialistInfo[n].SpecialistType.ToString());
                newspecialist.Add("");
                newspecialist.Add(SpecialistInfo[n].SpecialistComment.ToString());
                //temp这个list中已经存放了每一行的记录值
                temp.Add(newspecialist);
            }
            //行数
            for (int i = 0; i < SpecialistInfo.Count; i++)
            {
                 //控制列数
                for (int m = 0; m < tableHeadArray.Count; m++)
                {                 
                    // 添加一个单元格   
                    builder.InsertCell();      
                    //设置单元格的样式和颜色          
                    builder.CellFormat.Borders.LineStyle = LineStyle.Single;
                    builder.CellFormat.Borders.Color = System.Drawing.Color.Black;                    
                    builder.CellFormat.VerticalMerge = Aspose.Words.Tables.CellMerge.None;
                    builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;//垂直居中对齐
                    builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;//水平居中对齐
                    //通过test这个List集合,填充每个单元格
                    builder.Write(test[i][m].ToString());
                }
                builder.EndRow();
            }
     第六,设置保存文件的路径和文件名,最终返回给视图:
             //将替换后的评委签到表保存在以下路径
            string outputPath = rootPath + "/Content/评委签到表.doc";
            //生成的评委签到表的名称
            string filename = "评委签到表" + now.ToString("yyyy年mm月dd日") + ".doc";
            //保存文件
            docMain.Save(outputPath);
            //将文件返回给视图
            return File(outputPath, "application/msword", filename);
     4.以上各步是Controller下的方法,最后通过js在点击按钮后,调用该方法即可,js代码如下:
    //生成评委签到记录表
function ExportSpecialistSign() {
    //获取查询的招标编号
    var BidProjectId = document.getElementById('BidProjectId').value;
     //调用Controller中对应的方法
    window.location.href = '/SpecialistSign/ExportSpecialistSign?BidProjectId=' + BidProjectId;
}
     【效果展示】
     通过以上步骤,终于实现了一直搁置的报表问题。下面是从word中截取的报表信息:

word嵌入表格,完美解决报表
    
    【编程总结】
    在实现这一功能的过程中,最复杂的是数组那部分的逻辑。另外,在巨人的肩膀上,也让我见识到了List的强大。一个List不仅仅是一个List那么简单,我们可以通过自己的创建,实现对List的拼接,实现对List的重组,从而完美得到自己想要的那一行行记录。积累,思考,应用,这都是自己在以后的学习需要特别值得注意的。 
上一篇:工具类用的好,下班下的早(上)


下一篇:Kubernetes 集群 Helm3 安装 ElasticSearch & Kibana 7集群