/// <summary> /// 绑定数据源,把模板的标签写入数据 /// </summary> public void DataBind() { if (string.IsNullOrEmpty(this.TemplateFileName)) { this.bindBlankTemplate(); return; } this.initTemplate(); //有参数表,更新模板的参数表数据字段 if (this.dataSource.Tables.Contains("参数表")) { DataTable tabparam = this.dataSource.Tables["参数表"]; if (tabparam.Rows.Count > 0) { DataRow drparam = tabparam.Rows[0]; XmlNodeList xncells = this.xmldoc.SelectNodes("/*/ss:Worksheet/ss:Table/ss:Row/ss:Cell/ss:Data", this.xmlNsMgl); foreach (XmlNode xn in xncells) { if (!(xn is XmlElement)) continue; this.BindData(xn as XmlElement, drparam); } } } XmlElement xeTemplate = this.xmldoc.SelectSingleNode("/*/ss:Worksheet", this.xmlNsMgl) as XmlElement; XmlElement xeTpClone = xeTemplate.Clone() as XmlElement; //清除模板表格 XmlNode xnRow = xeTemplate.SelectSingleNode(".//ss:Row", this.xmlNsMgl); while (null != xnRow) { XmlNode xnT = xnRow.NextSibling; if ("Row" == xnRow.LocalName) xnRow.ParentNode.RemoveChild(xnRow); xnRow = xnT; } //初始化绑定区域结果主从关系 IDictionary<string, BindResult> listResult = new Dictionary<string, BindResult>(); BindResult rootResult = new BindResult(); rootResult.boundResult = Bound.ParseBound("A1:A1"); foreach (PrintInfo pinfo in this.printInfos) { string key = pinfo.DbName; if (!this.dataSource.Tables.Contains(key) && PrintType.Data==pinfo.RegionType) continue; BindResult bindInstance = new BindResult(); bindInstance.rowIndex = 0; bindInstance.printInfo = pinfo; listResult.Add(pinfo.DbName, bindInstance); } for (int i=0;i<this.printInfos.Count;i++) { string key = this.printInfos[i].DbName; PrintInfo pinfo = this.printInfos[i]; DataRelation rf = null; if (PrintType.Text == pinfo.RegionType) { foreach (PrintInfo p in this.printInfos) { if (PrintType.Data != p.RegionType || !this.dataSource.Tables.Contains(p.DbName)) continue; if (pinfo.GroupName != p.GroupName) continue; if (this.dataSource.Tables[p.DbName].ParentRelations.Count < 1) continue; rf = this.dataSource.Tables[p.DbName].ParentRelations[0]; break; } } else { if (this.dataSource.Tables[key].ParentRelations.Count < 1) continue; rf = this.dataSource.Tables[key].ParentRelations[0]; } if (null == rf) continue; BindResult rsParent = listResult[rf.ParentTable.TableName]; BindResult bindrs = listResult[key]; rsParent.resultChildren.Add(key, bindrs); bindrs.parentResult = rsParent; } for (int i = 0; i < this.printInfos.Count; i++) { string key = this.printInfos[i].DbName; BindResult bindrs = listResult[key]; if (rootResult.boundResult.Right < bindrs.printInfo.PgBound.Right) rootResult.boundResult.Right = bindrs.printInfo.PgBound.Right; if (rootResult.boundResult.Bottom < bindrs.printInfo.PgBound.Bottom) rootResult.boundResult.Bottom = bindrs.printInfo.PgBound.Bottom; if (null != bindrs.parentResult) listResult.Remove(key); else rootResult.resultChildren.Add(key,bindrs); } string pagePrint = "类型=文本\n数据表=页\n页范围=A1:{0}{1}\n行范围=A1:{0}{1}"; string col=""; int colindex = rootResult.boundResult.Right; while (colindex > 0) { int mod = colindex % 27; if (colindex > 26) mod += 1; col = Convert.ToString(Convert.ToChar(mod + Convert.ToInt16('A') - 1)) + col; colindex = colindex / 27; } pagePrint = string.Format(pagePrint, col , rootResult.boundResult.Bottom); rootResult.printInfo = PrintInfo.SerialFromString(pagePrint); rootResult.boundRow = rootResult.boundResult; //按照数据源的表个数循环,行号-1表示已经绑定完,子级数据递归绑定 //把结果页xeTp加入文档 XmlElement xeTable = this.xmldoc.SelectSingleNode("/*/ss:Worksheet/ss:Table", this.xmlNsMgl) as XmlElement; while (true) { bool isBreak = true; foreach (BindResult bindInstance in listResult.Values) { if (bindInstance.rowIndex < 0) continue; isBreak = false; break; } if (isBreak) break; //分页绑定 XmlElement xeTp = xeTpClone.CloneNode(true) as XmlElement; foreach (BindResult rs in listResult.Values) { rs.boundResult = null; rs.boundRow = null; } foreach (PrintInfo pinfo in this.printInfos) { if (!listResult.ContainsKey(pinfo.DbName)) continue; BindResult rs = listResult[pinfo.DbName]; if (rs.rowIndex < 0 && PrintType.Data == rs.printInfo.RegionType) continue; rs.xeTemplate = xeTp; rootResult.initChildBound(pinfo.DbName); if (null == rs.boundResult) continue; //子级范围 if (PrintType.Text == pinfo.RegionType && !rootResult.isComplete(pinfo.DbName)) { this.CopyCell(xeTpClone, pinfo.RowBound, rs.xeTemplate, rs.boundResult.Left, rs.boundResult.Top); rs.rowIndex = -1; } else if (PrintType.Data == pinfo.RegionType && this.dataSource.Tables.Contains(pinfo.DbName)) { DataRow[] drs = this.dataSource.Tables[pinfo.DbName].Select(); this.BindNode(xeTpClone, drs, rs); } } xnRow = xeTp.SelectSingleNode(".//ss:Row", this.xmlNsMgl); while (null != xnRow) { XmlNode xnT = xnRow.NextSibling; if ("Row" == xnRow.LocalName) xeTable.AppendChild(xnRow); xnRow = xnT; } }//while (true) //合并单元格 this.MergeCell(xeTemplate); }
/// <summary> /// 数据源页内绑定模板,完成绑定则返回-1,非法返回null,内范围超限返回 /// </summary> /// <param name="xeTemplate">独立模板</param> /// <param name="drs">数据记录集</param> /// <param name="bindEnv">当前绑定结果:当前行及范围</param> /// <returns>绑定结果:rowIndex=-1表示绑定完毕</returns> private BindResult BindNode(XmlElement xeTemplate, DataRow[] drs, BindResult bindEnv) { //检查 if (null == xeTemplate || null == drs || drs.Length < 1 || null == bindEnv || null == bindEnv.xeTemplate || bindEnv.rowIndex < 0 || bindEnv.rowIndex >= drs.Length) { if (null != bindEnv) bindEnv.rowIndex = -1; return bindEnv; } DataTable tab=drs[0].Table; string dbName = tab.TableName; if (!this.printInfoList.Keys.Contains(dbName)) { if (null != bindEnv) bindEnv.rowIndex = -1; return bindEnv; } ICollection<String> pinfoKeys = this.printInfoList.Keys; PrintInfo pinfo = this.printInfoList[dbName]; if (null == bindEnv.boundResult) bindEnv.boundResult = Bound.ParseBound(pinfo.RowBound); bindEnv.boundRow = new Bound(); //当前行位置ileft,itop int ileft = bindEnv.boundResult.Left; int itop = bindEnv.boundResult.Top; while (bindEnv.rowIndex < drs.Length) { //复制模板区域 bindEnv.boundRow.Left = ileft; bindEnv.boundRow.Top = itop; bindEnv.boundResult.Right = bindEnv.boundRow.Right = ileft + (pinfo.RwBound.Right - pinfo.RwBound.Left); bindEnv.boundResult.Bottom =bindEnv.boundRow.Bottom = itop + (pinfo.RwBound.Bottom - pinfo.RwBound.Top); this.CopyCell(xeTemplate, pinfo.RowBound, bindEnv.xeTemplate, ileft, itop); //更新父项的结果区域 BindResult childResult = bindEnv; BindResult parentResult = bindEnv.parentResult; while (null != parentResult) { Bound bdP = parentResult.boundResult; Bound bdC = childResult.boundResult; if (bdP.Right >= bdC.Right && bdP.Bottom >= bdC.Bottom) break; if (bdC.Right > bdP.Right) bdP.Right = bdC.Right; if (bdC.Bottom > bdP.Bottom) bdP.Bottom = bdC.Bottom; childResult = parentResult; parentResult = parentResult.parentResult; } //绑定字段值(父级字段或自身字段) string strTabFind = "ss:Table/ss:Row/ss:Cell[@r='{0}']"; string strRowFind = "ss:Cell[@c='{0}']"; XmlNode xnField=null, xnRowF=null; for (int i = itop; i <= bindEnv.boundResult.Bottom; i++) { if (null == xnRowF) { xnField = bindEnv.xeTemplate.SelectSingleNode(string.Format(strTabFind, i), this.xmlNsMgl); if (null == xnField) continue; xnRowF = xnField.ParentNode; } xnField = xnRowF.SelectSingleNode(string.Format(strRowFind, ileft), this.xmlNsMgl); for (int j = ileft; j <= bindEnv.boundResult.Right; j++) { if (null == xnField) xnField = xnRowF.SelectSingleNode(string.Format(strRowFind, j), this.xmlNsMgl); if (null == xnField) continue; if (null != xnField.FirstChild && null != xnField.FirstChild.Attributes["field"]) this.BindData((XmlElement)xnField.FirstChild, drs[bindEnv.rowIndex]); xnField = xnField.NextSibling; if (null == xnField || null == xnField.FirstChild || null == xnField.FirstChild.Attributes["c"] || Convert.ToString(j+1) != xnField.FirstChild.Attributes["c"].Value) xnField = null; } xnRowF = xnRowF.NextSibling; } //页内绑定子级 foreach (BindResult rs in bindEnv.resultChildren.Values) { rs.boundResult = null; rs.boundRow = null; } foreach (BindResult rs in bindEnv.resultChildren.Values) { PrintInfo pinfoChild = rs.printInfo; string key = pinfoChild.DbName; DataRelation rlChild = null; foreach (DataRelation rl in tab.ChildRelations) { if (key != rl.ChildTable.TableName) continue; rlChild = rl; break; } //检查配置区域是否合理,不在当前区域忽略 if (pinfoChild.RwBound.Left < pinfo.RwBound.Left || pinfoChild.RwBound.Top < pinfo.RwBound.Top || pinfoChild.RwBound.Right > pinfo.RwBound.Right || pinfoChild.RwBound.Bottom > pinfo.RwBound.Bottom) continue; rs.xeTemplate = bindEnv.xeTemplate; if (rs.parentRowIndex != bindEnv.rowIndex) { rs.parentRowIndex = bindEnv.rowIndex; rs.rowIndex = 0; } //初始化计算子区域,超界则为空 bindEnv.initChildBound(key); if (null == rs.boundResult) continue; //子级范围 if (PrintType.Text == pinfoChild.RegionType && !bindEnv.isComplete(key)) { this.CopyCell(xeTemplate, pinfoChild.RowBound, rs.xeTemplate, rs.boundResult.Left, rs.boundResult.Top); rs.rowIndex = -1; } else if (PrintType.Data == pinfoChild.RegionType && null != rlChild) this.BindNode(xeTemplate, drs[bindEnv.rowIndex].GetChildRows(rlChild), rs); } //检查是否下一行 bool isNext = true; foreach(BindResult srChild in bindEnv.resultChildren.Values) if (srChild.rowIndex > -1) { isNext=false; break; } if (isNext) bindEnv.rowIndex++; if (bindEnv.rowIndex >= drs.Length) break; //根据行输出方式计算下一条记录的区域位置 if (OutRowModel.VeriNextHori == pinfo.OutRowType) { itop = bindEnv.boundResult.Bottom + 1; if (itop + pinfo.RwBound.Bottom - pinfo.RwBound.Top > pinfo.PgBound.Bottom) { itop = bindEnv.boundResult.Top; ileft = bindEnv.boundResult.Right + 1; } } else { ileft = bindEnv.boundResult.Right+1; if (ileft + pinfo.RwBound.Right - pinfo.RwBound.Left > pinfo.PgBound.Right) { ileft = bindEnv.boundResult.Left; itop = bindEnv.boundResult.Bottom + 1; } } //检查下一个记录是否页面超限 if (bindEnv.boundResult.Right > pinfo.PgBound.Right || bindEnv.boundResult.Bottom > pinfo.PgBound.Bottom || (itop + pinfo.RwBound.Bottom - pinfo.RwBound.Top) > pinfo.PgBound.Bottom || (ileft + pinfo.RwBound.Right - pinfo.RwBound.Left) > pinfo.PgBound.Right) return bindEnv; }//for (int i = 0; bindEnv.rowIndex < drs.Length; i++) //子项重置 bindEnv.rowIndex = -1; foreach (BindResult srChild in bindEnv.resultChildren.Values) srChild.parentRowIndex = srChild.rowIndex = -1; return bindEnv; }