Browse Source

1. 数制转换支持起始值偏移设置
2. Excel导出支持列格式设置

懒得勤快 4 years ago
parent
commit
ca8f34fa1a

+ 22 - 8
Masuit.Tools.Abstractions/Strings/NumberFormater.cs

@@ -20,7 +20,12 @@ namespace Masuit.Tools.Strings
         /// <summary>
         /// 进制长度
         /// </summary>
-        public int Length => Characters?.Length ?? 0;
+        public int Length => Characters.Length;
+
+        /// <summary>
+        /// 起始值偏移
+        /// </summary>
+        private readonly int _offset;
 
         /// <summary>
         /// 数制格式化器
@@ -33,17 +38,25 @@ namespace Masuit.Tools.Strings
         /// <summary>
         /// 数制格式化器
         /// </summary>
-        /// <param name="characters">进制转换</param>
-        public NumberFormater(string characters)
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public NumberFormater(string characters, int offset = 0)
         {
+            if (string.IsNullOrEmpty(characters))
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
             Characters = characters;
+            _offset = offset;
         }
 
         /// <summary>
         /// 数制格式化器
         /// </summary>
         /// <param name="bin">进制</param>
-        public NumberFormater(int bin)
+        /// <param name="offset">起始值偏移</param>
+        public NumberFormater(int bin, int offset = 0)
         {
             if (bin < 2)
             {
@@ -56,6 +69,7 @@ namespace Masuit.Tools.Strings
             }
 
             Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/".Substring(0, bin);
+            _offset = offset;
         }
 
         /// <summary>
@@ -71,7 +85,7 @@ namespace Masuit.Tools.Strings
             {
                 var mod = t % Length;
                 t = Math.Abs(t / Length);
-                var character = Characters[Convert.ToInt32(mod)].ToString();
+                var character = Characters[Convert.ToInt32(mod) - _offset].ToString();
                 result.Insert(0, character);
             }
 
@@ -103,7 +117,7 @@ namespace Masuit.Tools.Strings
             {
                 var mod = t % Length;
                 t = BigInteger.Abs(BigInteger.Divide(t, Length));
-                var character = Characters[(int)mod].ToString();
+                var character = Characters[(int)mod - _offset].ToString();
                 result.Insert(0, character);
             }
 
@@ -118,7 +132,7 @@ namespace Masuit.Tools.Strings
         public long FromString(string str)
         {
             int j = 0;
-            return new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch)).Sum(ch => Characters.IndexOf(ch) * (long)Math.Pow(Length, j++));
+            return new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch)).Sum(ch => (Characters.IndexOf(ch) + _offset) * (long)Math.Pow(Length, j++));
         }
 
         /// <summary>
@@ -130,7 +144,7 @@ namespace Masuit.Tools.Strings
         {
             int j = 0;
             var chars = new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch));
-            return chars.Aggregate(BigInteger.Zero, (current, c) => current + Characters.IndexOf(c) * BigInteger.Pow(Length, j++));
+            return chars.Aggregate(BigInteger.Zero, (current, c) => current + (Characters.IndexOf(c) + _offset) * BigInteger.Pow(Length, j++));
         }
 
         /// <summary>Returns a string that represents the current object.</summary>

+ 82 - 0
Masuit.Tools.Excel/ColumnSettings.cs

@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Masuit.Tools.Excel
+{
+    /// <summary>
+    /// 表格列设置项
+    /// </summary>
+    public class ColumnSettings
+    {
+        internal readonly Dictionary<int, string> ColumnTypes = new();
+        private readonly NumberFormater _numberFormater = new("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1);
+
+        /// <summary>
+        /// 设置列格式
+        /// </summary>
+        /// <param name="index">列索引,从1开始</param>
+        /// <param name="format">格式字符串,例如:"¥"#,##0.00;"¥"\-#,##0.00</param>
+        /// <returns></returns>
+        public ColumnSettings SetColumnFormat(int index, string format)
+        {
+            ColumnTypes.Add(index, format);
+            return this;
+        }
+
+        /// <summary>
+        /// 设置列格式
+        /// </summary>
+        /// <param name="column">列索引,从A开始</param>
+        /// <param name="format">格式字符串,例如:"¥"#,##0.00;"¥"\-#,##0.00</param>
+        /// <returns></returns>
+        public ColumnSettings SetColumnFormat(string column, string format)
+        {
+            if (string.IsNullOrEmpty(column))
+            {
+                throw new ArgumentException("列索引不能为空");
+            }
+
+            column = string.Intern(column.ToUpper());
+            if (column.Except(_numberFormater.Characters).Any())
+            {
+                throw new ArgumentException("列索引非法:" + column);
+            }
+
+            ColumnTypes.Add((int)_numberFormater.FromString(column), format);
+            return this;
+        }
+
+        /// <summary>
+        /// 设置列格式
+        /// </summary>
+        /// <param name="index">列索引,从1开始</param>
+        /// <param name="format">格式字符串,例如:"¥"#,##0.00;"¥"\-#,##0.00</param>
+        /// <returns></returns>
+        public ColumnSettings SetColumnFormat(int[] index, string format)
+        {
+            foreach (var i in index)
+            {
+                SetColumnFormat(i, format);
+            }
+
+            return this;
+        }
+
+        /// <summary>
+        /// 设置列格式
+        /// </summary>
+        /// <param name="columns">列索引,从A开始</param>
+        /// <param name="format">格式字符串,例如:"¥"#,##0.00;"¥"\-#,##0.00</param>
+        /// <returns></returns>
+        public ColumnSettings SetColumnFormat(string[] columns, string format)
+        {
+            foreach (var i in columns)
+            {
+                SetColumnFormat(i, format);
+            }
+
+            return this;
+        }
+    }
+}

+ 30 - 20
Masuit.Tools.Excel/ExcelExtension.cs

@@ -22,18 +22,16 @@ namespace Masuit.Tools.Excel
         /// <param name="sheetTables">sheet名和内存表的映射</param>
         /// <param name="password">密码</param>
         /// <returns>内存流</returns>
-        public static MemoryStream ToExcel(this Dictionary<string, DataTable> sheetTables, string password = null)
+        public static MemoryStream ToExcel(this Dictionary<string, DataTable> sheetTables, string password = null, ColumnSettings settings = null)
         {
-            using (var pkg = new ExcelPackage())
+            using var pkg = new ExcelPackage();
+            foreach (var pair in sheetTables)
             {
-                foreach (var pair in sheetTables)
-                {
-                    pair.Value.TableName = pair.Key;
-                    CreateWorksheet(pkg, pair.Value);
-                }
-
-                return SaveAsStream(pkg, password);
+                pair.Value.TableName = pair.Key;
+                CreateWorksheet(pkg, pair.Value, settings);
             }
+
+            return SaveAsStream(pkg, password);
         }
 
         /// <summary>
@@ -42,12 +40,12 @@ namespace Masuit.Tools.Excel
         /// <param name="tables">内存表</param>
         /// <param name="password">密码</param>
         /// <returns>内存流</returns>
-        public static MemoryStream ToExcel(this List<DataTable> tables, string password = null)
+        public static MemoryStream ToExcel(this List<DataTable> tables, string password = null, ColumnSettings settings = null)
         {
             using var pkg = new ExcelPackage();
             foreach (var table in tables)
             {
-                CreateWorksheet(pkg, table);
+                CreateWorksheet(pkg, table, settings);
             }
 
             return SaveAsStream(pkg, password);
@@ -59,10 +57,10 @@ namespace Masuit.Tools.Excel
         /// <param name="table">内存表</param>
         /// <param name="password">密码</param>
         /// <returns>内存流</returns>
-        public static MemoryStream ToExcel(this DataTable table, string password = null)
+        public static MemoryStream ToExcel(this DataTable table, string password = null, ColumnSettings settings = null)
         {
             using var pkg = new ExcelPackage();
-            CreateWorksheet(pkg, table);
+            CreateWorksheet(pkg, table, settings);
             return SaveAsStream(pkg, password);
         }
 
@@ -81,7 +79,7 @@ namespace Masuit.Tools.Excel
             return ms;
         }
 
-        public static void CreateWorksheet(this ExcelPackage pkg, DataTable table)
+        public static void CreateWorksheet(this ExcelPackage pkg, DataTable table, ColumnSettings settings = null)
         {
             if (string.IsNullOrEmpty(table.TableName))
             {
@@ -104,6 +102,13 @@ namespace Masuit.Tools.Excel
             sheet.Row(1).CustomHeight = true; // 自动调整行高
             sheet.Cells.AutoFitColumns(); // 表头自适应列宽
             sheet.Cells.Style.WrapText = true;
+            if (settings != null)
+            {
+                foreach (var x in settings.ColumnTypes)
+                {
+                    sheet.Column(x.Key).Style.Numberformat.Format = x.Value;
+                }
+            }
 
             // 填充内容
             for (var i = 0; i < table.Rows.Count; i++)
@@ -242,14 +247,19 @@ namespace Masuit.Tools.Excel
                         default:
                             {
                                 sheet.SetValue(i + 2, j + 1, table.Rows[i][j] ?? "");
-
-                                // 根据单元格内容长度来自适应调整列宽
-                                maxWidth[j] = Math.Max(Encoding.UTF8.GetBytes(table.Rows[i][j].ToString() ?? string.Empty).Length, maxWidth[j]);
-                                if (sheet.Column(j + 1).Width < maxWidth[j])
+                                if (table.Rows[i][j] is ValueType)
                                 {
-                                    sheet.Cells[i + 2, j + 1].AutoFitColumns(18, 110); // 自适应最大列宽,最小18,最大110
+                                    sheet.Column(j + 1).AutoFit();
+                                }
+                                else
+                                {
+                                    // 根据单元格内容长度来自适应调整列宽
+                                    sheet.Column(j + 1).Width = Math.Max(Encoding.UTF8.GetBytes(table.Rows[i][j].ToString() ?? string.Empty).Length + 2, sheet.Column(j + 1).Width);
+                                    if (sheet.Column(j + 1).Width > 110)
+                                    {
+                                        sheet.Column(j + 1).AutoFit(100, 110);
+                                    }
                                 }
-
                                 break;
                             }
                     }

+ 3 - 3
Masuit.Tools.Excel/Masuit.Tools.Excel.csproj

@@ -4,7 +4,7 @@
         <LangVersion>latest</LangVersion>
         <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
         <CodeAnalysisRuleSet />
-        <Version>1.0.4</Version>
+        <Version>1.0.5</Version>
         <Authors>懒得勤快</Authors>
         <Description>Masuit.Tools.Excel导出库,支持一些简单数据的导出,支持图片列</Description>
         <Copyright>懒得勤快</Copyright>
@@ -17,9 +17,9 @@
         <RepositoryType>Github</RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
         <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
-        <FileVersion>1.0.4</FileVersion>
+        <FileVersion>1.0.5</FileVersion>
         <Company>ldqk.org</Company>
-        <AssemblyVersion>1.0.4</AssemblyVersion>
+        <AssemblyVersion>1.0.5</AssemblyVersion>
         <PackageLicenseUrl>https://github.com/ldqk/Masuit.Tools/blob/master/LICENSE</PackageLicenseUrl>
         <EmbedUntrackedSources>true</EmbedUntrackedSources>
         <IncludeSymbols>true</IncludeSymbols>

+ 155 - 0
Masuit.Tools.Excel/NumberFormater.cs

@@ -0,0 +1,155 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+
+namespace Masuit.Tools.Excel
+{
+    /// <summary>
+    /// 数制格式化器
+    /// </summary>
+    internal class NumberFormater
+    {
+        /// <summary>
+        /// 数制表示字符集
+        /// </summary>
+        internal string Characters { get; set; }
+
+        /// <summary>
+        /// 进制长度
+        /// </summary>
+        public int Length => Characters.Length;
+
+        /// <summary>
+        /// 起始值偏移
+        /// </summary>
+        private readonly int _offset;
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        public NumberFormater()
+        {
+            Characters = "0123456789";
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">符号集</param>
+        /// <param name="offset">起始值偏移</param>
+        public NumberFormater(string characters, int offset = 0)
+        {
+            if (string.IsNullOrEmpty(characters))
+            {
+                throw new ArgumentException("符号集不能为空");
+            }
+
+            Characters = characters;
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="bin">进制</param>
+        /// <param name="offset">起始值偏移</param>
+        public NumberFormater(int bin, int offset = 0)
+        {
+            if (bin < 2)
+            {
+                bin = 2;
+            }
+
+            if (bin > 64)
+            {
+                throw new ArgumentException("默认进制最大支持64进制");
+            }
+
+            Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/".Substring(0, bin);
+            _offset = offset;
+        }
+
+        /// <summary>
+        /// 数字转换为指定的进制形式字符串
+        /// </summary>
+        /// <param name="number"></param>
+        /// <returns></returns>
+        public string ToString(long number)
+        {
+            List<string> result = new List<string>();
+            long t = Math.Abs(number);
+            while (t != 0)
+            {
+                var mod = t % Length;
+                t = Math.Abs(t / Length);
+                var character = Characters[Convert.ToInt32(mod) - _offset].ToString();
+                result.Insert(0, character);
+            }
+
+            if (number < 0)
+            {
+                result.Insert(0, "-");
+            }
+
+            return string.Join("", result);
+        }
+
+        /// <summary>
+        /// 数字转换为指定的进制形式字符串
+        /// </summary>
+        /// <param name="number"></param>
+        /// <returns></returns>
+        public string ToString(BigInteger number)
+        {
+            List<string> result = new List<string>();
+            if (number < 0)
+            {
+                number = -number;
+                result.Add("0");
+            }
+
+            BigInteger t = number;
+
+            while (t != 0)
+            {
+                var mod = t % Length;
+                t = BigInteger.Abs(BigInteger.Divide(t, Length));
+                var character = Characters[(int)mod - _offset].ToString();
+                result.Insert(0, character);
+            }
+
+            return string.Join("", result);
+        }
+
+        /// <summary>
+        /// 指定字符串转换为指定进制的数字形式
+        /// </summary>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public long FromString(string str)
+        {
+            int j = 0;
+            return new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch)).Sum(ch => (Characters.IndexOf(ch) + _offset) * (long)Math.Pow(Length, j++));
+        }
+
+        /// <summary>
+        /// 指定字符串转换为指定进制的大数形式
+        /// </summary>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public BigInteger FromStringBig(string str)
+        {
+            int j = 0;
+            var chars = new string(str.ToCharArray().Reverse().ToArray()).Where(ch => Characters.Contains(ch));
+            return chars.Aggregate(BigInteger.Zero, (current, c) => current + (Characters.IndexOf(c) + _offset) * BigInteger.Pow(Length, j++));
+        }
+
+        /// <summary>Returns a string that represents the current object.</summary>
+        /// <returns>A string that represents the current object.</returns>
+        public override string ToString()
+        {
+            return Length + "进制模式,进制符:" + Characters;
+        }
+    }
+}

+ 1 - 1
NetCoreTest/Program.cs

@@ -27,7 +27,7 @@ namespace NetCoreTest
                 {
                     ["https://ldqk.org/1383"] = File.OpenRead(@"D:\images\emotion\16.jpg")
                 }
-            }).ToDataTable("aa").ToExcel2().SaveFile(@"Y:\2.xlsx");
+            }).ToDataTable("aa").ToExcel().SaveFile(@"Y:\2.xlsx");
             var myClass = new MyClass()
             {
                 MyProperty1 = 1,