Excel列名与数字的相互转换

来源:互联网 发布:模特兼职知乎 编辑:程序博客网 时间:2024/05/01 00:34

    public static class Excel2007Index    {        private static int nextDatum = 17576;        private static int[] baseNum = new int[] { 1, 26, 676 };        private static List<long> baseNumList = new List<long>(new long[]{1, 26, 676});        private static System.Text.RegularExpressions.Regex matchCStart = new System.Text.RegularExpressions.Regex("^[A-Z]{1,3}$", System.Text.RegularExpressions.RegexOptions.Compiled);        private delegate string CalColumnRangeDelegate(int columnIndex);        private static CalColumnRangeDelegate[] CalColumnRange = new CalColumnRangeDelegate[] { CalColumnRange1, CalColumnRange2, CalColumnRange3 };         /// <summary>        /// 从指定Excel的列序号获得索引值(1 表示为 A)。        /// </summary>        /// <param name="columnIndex">从1开始的列序号。</param>        /// <returns></returns>        public static string GetAnyColumnRangeFromIndex(int columnIndex)        {            if (columnIndex <= 0)                throw new ArgumentOutOfRangeException("columnIndex");            return CalColumnRange4(columnIndex);        }         /// <summary>        /// 从指定Excel的列序号获得索引值(A 表示为 1)。        /// </summary>        /// <param name="columnIndex">从A开始的列序号。</param>        /// <returns></returns>        public static long GetAnyColumnIndexFromRange(string columnRange)        {            columnRange = columnRange.ToUpper(Excel2007Workbook.invariantCulture);            if (!System.Text.RegularExpressions.Regex.IsMatch(columnRange, "[A-Z]{1}"))                throw new ArgumentOutOfRangeException("columnRange");            UpdateBaseNum(columnRange);            long sum = 0, multi = 0;            int i = columnRange.Length - 1;            foreach (var ch in columnRange)            {                multi = (int)ch - 64;                multi = multi * baseNumList[i];                sum += multi;                i--;            }            return sum;        }         /// <summary>        /// 从指定Excel的列序号获得索引值(A 表示为 1)。        /// </summary>        /// <param name="columnRange">从A开始的列序号,最大不超过ZZZ(18278)。</param>        /// <returns></returns>        public static int GetColumnIndexFromRange(string columnRange)        {            columnRange = columnRange.ToUpper(Excel2007Workbook.invariantCulture);            if (!matchCStart.IsMatch(columnRange))                throw new ArgumentException("", "columnRange");            int sum = 0, multi = 0;            int i = columnRange.Length - 1;            foreach (var ch in columnRange)            {                multi = (int)ch - 64;                multi = multi * baseNum[i];                sum += multi;                i--;            }            return sum;        }         /// <summary>        /// 从指定索引值获得Excel的列序号表示(1 表示为 A)。        /// </summary>        /// <param name="columnIndex">从1开始不大于17576的列索引。</param>        /// <returns></returns>        public static string GetColumnRangeFromIndex(int columnIndex)        {            if (columnIndex <= 0 || columnIndex > nextDatum)                throw new ArgumentOutOfRangeException("columnIndex");            int c = 0;            if (columnIndex != 1)                c = (int)Math.Log(columnIndex - 1, 26);            return CalColumnRange[c](columnIndex);        }         /// <summary>        /// 适用于小于等于26列的Excel列算法。        /// </summary>        /// <param name="columnIndex">从1开始的列索引。</param>        /// <returns></returns>        private static string CalColumnRange1(int columnIndex)        {            return ((char)(columnIndex + 64)).ToString();        }        /// <summary>        /// 适用于大于26列小于等于676列的Excel列算法。        /// </summary>        /// <param name="columnIndex">从1开始的列索引。</param>        /// <returns></returns>        private static string CalColumnRange2(int columnIndex)        {            // resuide 余数,quotient商            int residue = 0, quotient = 0;            StringBuilder str = new StringBuilder(2);            quotient = Math.DivRem(columnIndex, baseNum[1], out residue);            if (residue == 0)            {                quotient--;                residue = 26;            }            str.Append((char)(quotient + 64));            str.Append((char)(residue + 64));            return str.ToString();        }        /// <summary>        /// 适用于大于676列小于等于17576列的Excel列算法。        /// </summary>        /// <param name="columnIndex">从1开始的列索引。</param>        /// <returns></returns>        private static string CalColumnRange3(int columnIndex)        {            // resuide 余数,quotient商            int residue = 0, quotient = 0;            StringBuilder str = new StringBuilder(3);            for (int i = 2; i >= 0; i--)            {                quotient = Math.DivRem(columnIndex, baseNum[i], out residue);                 if (residue == 0 && i != 0)                {                    quotient--;                    residue = baseNum[i];                }                str.Append((char)(quotient + 64));                columnIndex = residue;            }            return str.ToString();        }        /// <summary>        /// 适用于有可能超出17576列的Excel列算法。        /// </summary>        /// <param name="columnIndex">从1开始的列索引。</param>        /// <returns></returns>        private static string CalColumnRange4(int columnIndex)        {            if(columnIndex <=0)                throw new ArgumentOutOfRangeException("columnIndex");            UpdateBaseNum(columnIndex);            // resuide 余数,quotient商            int residue = 0, quotient = 0;            StringBuilder str = new StringBuilder(baseNum.Length);            for (int i = str.Length - 1; i >= 0; i--)            {                quotient = Math.DivRem(columnIndex, (int)baseNumList[i], out residue);                 if (residue == 0 && i != 0)                {                    quotient--;                    residue = (int)baseNumList[i];                }                str.Append((char)(quotient + 64));                columnIndex = residue;            }            return str.ToString();        }        /// <summary>        /// 当给定值大于所能计算的最大范围时,更新baseNumList列表。        /// </summary>        /// <param name="columnIndex">从1开始的列索引</param>        private static void UpdateBaseNum(int columnIndex)        {            while (columnIndex > nextDatum)            {                baseNumList.Add(nextDatum);                nextDatum *= 26;            }        }         /// <summary>        /// 当给定列序号大于所能计算的最大范围时,更新baseNumList列表。        /// </summary>        /// <param name="columnRange">从A开始的列序号。</param>        private static void UpdateBaseNum(string columnRange)        {            for (int i = baseNumList.Count - 1; i < columnRange.Length; i++)            {                baseNumList.Add(nextDatum);                nextDatum *= 26;            }        }    }


原创粉丝点击