白开心

  IT博客 :: 首页 ::  :: 联系 :: 聚合  :: 管理 ::
  9 随笔 :: 76 文章 :: 28 评论 :: 0 Trackbacks

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Xml;

namespace WayGo.ExcelMergeTool.Common
{
    public class WayGoTable : System.Data.DataTable
    {
        private XmlNode _SchemaSheet;

        private XmlNode _SheetNode;

        private XmlNamespaceManager _nsmgr;

        public XmlNode SchemaSheet
        {
            get
            {
                return this._SchemaSheet;
            }
            set
            {
                this._SchemaSheet = value;
            }
        }

        public XmlNode SheetNode
        {
            get
            {
                return this._SheetNode;
            }
            set
            {
                this._SheetNode = value;
            }
        }

        public XmlNamespaceManager nsmgr
        {
            get
            {
                return this._nsmgr;
            }
            set
            {
                this._nsmgr = value;
            }
        }

        public WayGoTable(XmlNode sheetNode,XmlNode schemaSheet,XmlNamespaceManager ns):base()
        {
            this.Columns.Add("ID", typeof(System.String));
            this.Columns.Add("StartRow", typeof(System.Int16));
            this.Columns.Add("EndRow", typeof(System.Int16));
            this.Columns.Add("StartCol", typeof(System.Int16));
            this.Columns.Add("EndCol", typeof(System.Int16));
            this.Columns.Add("Method", typeof(System.String));

            this._SchemaSheet = schemaSheet;
            this._SheetNode = sheetNode;
            this._nsmgr = ns;

            this.Initial();
            this.sort();
        }

        public WayGoTable() : base()
        {
       
        }

        /// <summary>
        /// 添加一行
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="startRow"></param>
        /// <param name="endRow"></param>
        /// <param name="startCol"></param>
        /// <param name="endCol"></param>
        /// <param name="method"></param>
        private void addRow(string ID, int startRow, int endRow, int startCol, int endCol, MergeMethod method)
        {
            DataRow r = this.NewRow();
            r["ID"] = ID;
            r["StartRow"] = startRow;
            r["EndRow"] = endRow;
            r["StartCol"] = startCol;
            r["EndCol"] = endCol;
            r["Method"] = method;
            this.Rows.Add(r);
        }

        /// <summary>
        /// 根据 Schema和Sheet File的Sheet节点 初始化表格
        /// </summary>
        /// <param name="schemaSheet"></param>
        /// <param name="sheetNode"></param>
        private void Initial()
        {
            string ID,startRefValue;
            MergeMethod method;
            int startRow, endRow, startCol, endCol;
            int find;
            int row,col,repeat;
            int rowoffset, rowend;
            int coloffset,colend;
            XmlNodeList colNodes;
            XmlNode Item;

            rowend = 0;
            startRow = 0;
            endRow = 0;

            #region 遍历Schema中Sheet的子节点
            foreach (XmlNode node in SchemaSheet.ChildNodes)
            {
                method = SchemaNode.Instance.getNodeName(node.Name);
                if(method == MergeMethod.AddInString)
                {
                    continue;
                }

                ID = node.Attributes["id"].Value.ToString();
                col = Convert.ToInt16(node.SelectSingleNode(SchemaNode.StartRefColumn).InnerText);

                Item = node.SelectSingleNode("Item");
                repeat = Convert.ToInt16(node.SelectSingleNode(SchemaNode.StartRefRepeat).InnerText);
                rowoffset = Convert.ToInt16(Item.Attributes["rowoffset"].Value);

                coloffset = Convert.ToInt16(Item.Attributes["coloffset"].Value);
                colend = Convert.ToInt16(Item.Attributes["colend"].Value);

                startCol = col + coloffset;
                endCol = col + colend;

                if (method == MergeMethod.Add)
                {
                    rowend = Convert.ToInt16(Item.Attributes["rowend"].Value);
                }
               
                startRefValue = node.SelectSingleNode(SchemaNode.StartRefValue).InnerText;

                colNodes = SheetNode.SelectNodes("Table/Row/Cell[@ss:Index=" + col + "]", nsmgr);
                find = 0;
                #region Col Node  ----
                foreach (XmlNode n in colNodes)
                {
                    row = Convert.ToInt16(n.ParentNode.Attributes["ss:Index"].Value);
                    if (!string.IsNullOrEmpty(n.InnerText) && n.InnerText == startRefValue && !isExistsMergeArea(row,col))
                    {
                        find++;
                        if (find == repeat)
                        {
                            startRow = row  + rowoffset;
                            if (method == MergeMethod.Add)
                            {
                                endRow = row + rowend;  
                            }

                            this.addRow(ID, startRow, endRow, startCol, endCol, method);
                            break;
                        }
                    }
                }
                #endregion
               
            }
            #endregion
        }

        /// <summary>
        /// 排序
        /// </summary>
        private void sort()
        {
            if (this.Rows.Count < 2)
            {
                return;
            }


            DataRow[] rows = this.Select("", "StartRow");
            DataTable t = this.Clone();
            t.Clear();
            foreach (DataRow row in rows)
            {
                t.ImportRow(row);
            }
            this.Clear();
            foreach (DataRow row in t.Rows)
            {
                this.ImportRow(row);
            }

        }

        /// <summary>
        /// 判断某个单元格是否位于其他合并区域中
        /// </summary>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <returns></returns>
        private bool isExistsMergeArea(int row,int col)
        {
            foreach (DataRow r in this.Rows)
            {
                if (Convert.ToInt16(r["StartRow"]) <= row &&
                Convert.ToInt16(r["EndRow"]) >= row &&
                Convert.ToInt16(r["StartCol"]) <= col &&
                Convert.ToInt16(r["EndCol"]) >= col)
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 判断某个单元格是否位于其他合并区域中
        /// </summary>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <param name="rowIndex"></param>
        /// <returns></returns>
        private bool isExistsMergeArea(int row, int col, int rowIndex)
        {
            for (int i = 0; i < rowIndex; i++)
            {
                if (Convert.ToInt16(this.Rows[i]["StartRow"]) <= row &&
                Convert.ToInt16(this.Rows[i]["EndRow"]) >= row &&
                Convert.ToInt16(this.Rows[i]["StartCol"]) <= col &&
                Convert.ToInt16(this.Rows[i]["EndCol"]) >= col)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 修复合并当前行以下的行
        /// </summary>
        /// <param name="row"></param>
        /// <param name="rowIndex"></param>
        public void Repair(DataRow row,int rowIndex)
        {
            int rowI, find, startRow, repeat, rowoffset;
            find = 0;

            DataRow[] r = this.Select("ID=" + row["ID"].ToString());

            XmlNode node,Item;
            if (row["Method"].ToString() == MergeMethod.Add.ToString())
            {
                node = this.SchemaSheet.SelectSingleNode(SchemaNode.Add + "[@id='" + row["ID"].ToString() + "']");
            }
            else
            {
                node = this.SchemaSheet.SelectSingleNode(SchemaNode.Append + "[@id='" + row["ID"].ToString() + "']");
            }

            Item = node.SelectSingleNode("Item");

            int col = Convert.ToInt16(node.SelectSingleNode(SchemaNode.StartRefColumn).InnerText);
            string startRefValue = node.SelectSingleNode(SchemaNode.StartRefValue).InnerText;
            repeat = Convert.ToInt16(node.SelectSingleNode(SchemaNode.StartRefRepeat).InnerText);
            rowoffset = Convert.ToInt16(Item.Attributes["rowoffset"].Value);

            XmlNodeList colNodes = SheetNode.SelectNodes("Table/Row/Cell[@ss:Index=" + col + "]", nsmgr);

            #region Col Node  ----
            foreach (XmlNode n in colNodes)
            {
                rowI = Convert.ToInt16(n.ParentNode.Attributes["ss:Index"].Value);
                if (!string.IsNullOrEmpty(n.InnerText) && n.InnerText == startRefValue && !isExistsMergeArea(rowI, col, rowIndex))
                {
                    find++;
                    if (find == repeat)
                    {
                        startRow = rowI + rowoffset;
                       
                        //如果该行是正确的,则不继续修复,退出程序
                        if(startRow == Convert.ToInt16(row["StartRow"]))
                        {
                            return;
                        }
                        else
                        {
                            //如果该行的起始行错误,则修正该行后重新排序,并继续修复处于该行的位置的行
                            r[0]["StartRow"] = startRow;
                            this.sort();

                            this.Repair(this.Rows[rowIndex], rowIndex);
                        }
                    }
                }
            }
            #endregion
        }
    }
}

posted on 2007-07-15 15:50 白开心 阅读(127) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。