社畜猿 - 💯C#
type: channel
link: https://blog.wely.top/category/CSharp
description: C#技术
items: .NET 6.0 + 在Linux的Docker容器中 不安装任何依赖生成图形验证码教程
items: .NET(C#)发送邮件的实现方法
items: C# 使用原生 System.IO.Compression 实现 zip 的压缩与解压
items: c# Mysqlhelper 笔记
items: C# 线程执行笔记【多线程定时任务】
items: .NET C#使用NPOI将Excel中的数据批量导入到MySQL
items: .NET C#使用NPOI导出Word详解
items: .NET c# 使用NPOI导出复杂Excel
items: C# datatable 用于二次修改
items: C#数据库datRow泛型反射实体类,

.NET 6.0 + 在Linux的Docker容器中 不安装任何依赖生成图形验证码教程
type: item
date: 2025-12-22T08:43:00+08:00
description: 推荐使用SkiaSharp首先，安装SkiaSharp编写好图形生成代码。在windows 上简易代码using SkiaSharp; using System.Drawing; using System.Drawing.Text; namespace VertifyCode { public class VerifyCodeHelper { private static readonly char[] Chars = { '0','1','2','3','4','5','6','8','9', 'A','B','C','D','E','F','G','H','I','J','K', 'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' }; //private static readonly int Width = 90; //private static readonly int Height = 35; private static string GenCode(int num) { var code = string.Empty; var r = new Random(); for (int i = 0; i < num; i++) { code += Chars[r.Next(Chars.Length)].ToString(); } return code; } /// /// 获取图像数字验证码 /// /// <returns></returns> public static (string code, byte[] bytes) GetVerifyCode() { var code = GenCode(4); int width = 128; int height = 45; Random random = new(); //创建bitmap位图 using SKBitmap image = new(width, height, SKColorType.Bgra8888, SKAlphaType.Premul); //创建画笔 using SKCanvas canvas = new(image); //填充背景颜色为白色 canvas.DrawColor(SKColors.White); //画图片的背景噪音线 for (int i = 0; i < (width * height * 0.015); i++) { using SKPaint drawStyle = new(); drawStyle.Color = new(Convert.ToUInt32(random.Next(Int32.MaxValue))); canvas.DrawLine(random.Next(0, width), random.Next(0, height), random.Next(0, width), random.Next(0, height), drawStyle); }//将文字写到画布上 using (SKPaint drawStyle = new()) { drawStyle.Color = SKColors.Red; drawStyle.TextSize = height; drawStyle.StrokeWidth = 1; float emHeight = height - (float)height * (float)0.14; float emWidth = ((float)width / code.Length) - ((float)width * (float)0.13); canvas.DrawText(code, emWidth, emHeight, drawStyle); } //画图片的前景噪音点 for (int i = 0; i < (width * height * 0.15); i++) { image.SetPixel(random.Next(0, width), random.Next(0, height), new SKColor(Convert.ToUInt32(random.Next(Int32.MaxValue)))); } using var img = SKImage.FromBitmap(image); using SKData p = img.Encode(SKEncodedImageFormat.Png, 100); return (code, p.ToArray()); } } }以上代码docker 不可用，如果需要在linux 上课用，还需要下载SkiaSharp.linux,【SkiaShar…

.NET(C#)发送邮件的实现方法
type: item
date: 2024-09-03T11:30:00+08:00
description: {mtitle title="引用"/}阿里云服务器上不可用，需使用SSL，此代码不适用163邮箱using System.Net; using System.Net.Mail;方法如下/// /// 发送邮件方法 /// /// 接收人邮件 /// 发送邮件标题 /// 发送邮件内容 /// <returns></returns> public static bool SendEmail(string mailTo, string mailTitle, string mailContent) { //设置发送方邮件信息，例如：163邮箱（163已测试，其他邮箱未测试请根据实际自行测试） string stmpServer = @"smtp.163.com";//smtp服务器地址 string mailAccount = @"123456789@163.com";//邮箱账号 string pwd = @"12345678";//邮箱密码（qq邮箱请在此处使用授权码，其他邮箱见邮箱规定使用的是邮箱密码还是授权码） //邮件服务设置 SmtpClient smtpClient = new SmtpClient(); smtpClient.Port=25; smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;//指定电子邮件发送方式 smtpClient.Host = stmpServer;//指定发送方SMTP服务器 smtpClient.EnableSsl = true;//使用安全加密连接 smtpClient.UseDefaultCredentials = true;//不和请求一起发送 smtpClient.Credentials = new NetworkCredential(mailAccount, pwd);//设置发送账号密码 MailMessage mailMessage = new MailMessage(mailAccount, mailTo);//实例化邮件信息实体并设置发送方和接收方 mailMessage.Subject = mailTitle;//设置发送邮件得标题 mailMessage.Body = mailContent;//设置发送邮件内容 mailMessage.BodyEncoding = Encoding.UTF8;//设置发送邮件得编码 mailMessage.IsBodyHtml = false;//设置内容是否为HTML格式（true可以添加html标签） mailMessage.Priority = MailPriority.Normal;//设置邮件发送优先级 try { smtpClient.Send(mailMessage);//发送邮件 return true; } catch (SmtpException ex) { console.WriteLine(ex.message); throw ex; } }

C# 使用原生 System.IO.Compression 实现 zip 的压缩与解压
type: item
date: 2024-08-20T09:53:22+08:00
description: using System.IO.Compression;/// /// 将指定目录压缩为Zip文件 /// /// 文件夹地址 D:/download/ /// zip地址 D:/download/test.zip public static void CompressDirectoryZip(string folderPath, string zipPath) { DirectoryInfo directoryInfo = new(zipPath); if (directoryInfo.Parent != null) { directoryInfo = directoryInfo.Parent; } if (!directoryInfo.Exists) { directoryInfo.Create(); } ZipFile.CreateFromDirectory(folderPath, zipPath, CompressionLevel.Optimal, false); }其中 CompressionLevel 是个枚举，支持下面四种类型枚举值表意Optimal0压缩操作应以最佳方式平衡压缩速度和输出大小。Fastest1即使结果文件未可选择性地压缩，压缩操作也应尽快完成。NoCompression2该文件不应执行压缩。SmallestSize3压缩操作应尽可能小地创建输出，即使该操作需要更长的时间才能完成。这里直接固定了采用 CompressionLevel.Optimal/// /// 将指定文件压缩为Zip文件 /// /// 文件地址 D:/test.txt /// zip地址 D:/test.zip public static void CompressFileZip(string filePath, string zipPath) { //如果是多个文件请考虑一下整个文件夹迁移还是分文件迁移到临时目录 FileInfo fileInfo = new FileInfo(filePath); string dirPath = fileInfo.DirectoryName?.Replace("\\", "/") + "/"; string tempPath = dirPath + Guid.NewGuid() + "_temp/"; if (!Directory.Exists(tempPath)) { Directory.CreateDirectory(tempPath); } fileInfo.CopyTo(tempPath + fileInfo.Name); CompressDirectoryZip(tempPath, zipPath); DirectoryInfo directory = new(tempPath); if (directory.Exists) { //将文件夹属性设置为普通,如：只读文件夹设置为普通 directory.Attributes = FileAttributes.Normal; directory.Delete(true); } }这里压缩文件的逻辑其实就是先将我们要压缩的文件复制到一个临时目录，然后对临时目录执行了压缩动作，压缩完成之后又删除了临时目录以下是解压文件/// /// 解压Zip文件到指定目录 /// /// zip地址 D:/download/test.zip /// 文件夹地址 D:/test/ public static void DecompressZip(string zipPath, string folderPath) { DirectoryInfo directoryInfo = new(folderPath); ///这里注意，如果压缩文件已存在会报错，请自行判断处理 ///我的做法是先删除，请根据自己也无需要合理处理 if (!directoryInfo.Exists) { directoryInfo.Create(); } ZipFile.ExtractToDirectory(zipPath, folderPath); }至此 C# 使用原生 System.IO.Compression 实现 zip 的压缩与解压 就讲解完了

c# Mysqlhelper 笔记
type: item
date: 2024-05-14T09:35:49+08:00
description: MysqlHelper.csusing System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using MySql.Data.MySqlClient; public class MySQLHelper { private string connectionString; public MySQLHelper(string connectionString) { this.connectionString = connectionString; } // /// /// 执行不返回结果集的SQL语句,影响的行数 /// /// /// /// <returns></returns> public int ExecuteNonQuery(string sql, params MySqlParameter[] parameters) { using (MySqlConnection connection = new MySqlConnection(connectionString)) { using (MySqlCommand command = new MySqlCommand(sql, connection)) { // 添加参数 command.Parameters.AddRange(parameters); // 打开连接 connection.Open(); // 执行SQL语句并返回影响行数 return command.ExecuteNonQuery(); } } } // /// /// 执行一个查询，并返回结果集中第一行的第一列 /// /// /// /// <returns></returns> public object ExecuteScalar(string sql, params MySqlParameter[] parameters) { using (MySqlConnection connection = new MySqlConnection(connectionString)) { using (MySqlCommand command = new MySqlCommand(sql, connection)) { // 添加参数 command.Parameters.AddRange(parameters); // 打开连接 connection.Open(); // 执行SQL查询并返回第一行第一列的值 return command.ExecuteScalar(); } } } // 执行一个查询，并返回结果集 public DataTable ExecuteQuery(string sql, params MySqlParameter[] parameters) { using (MySqlConnection connection = new MySqlConnection(connectionString)) { using (MySqlCommand command = new MySqlCommand(sql, connection)) { // 添加参数 command.Parameters.AddRange(parameters); // 打开连接 connection.Open(); // 创建DataAdapter和DataTable对象，并填充数据 using (MySqlDataAdapter adapter = new MySqlDataAdapter(command)) { DataTable dataTable = new DataTable(); adapter.Fill(dataTable); return dataTable; } } } } // 执行一个查询，并将结果集映射到一个对象列表 public List<T> ExecuteQuery<T>(string sql, Func<IDataRecord, T> selector, params MySqlParameter[] parameters) { using (MySqlConnection connection = new MySqlConnection(connectionString)) { using (MySqlCommand command = new MySqlCommand(sql, connection)) { // 添加参数 command.Parameters.AddRange(parameters); // 打开连接 connection.Op…

C# 线程执行笔记【多线程定时任务】
type: item
date: 2024-04-09T10:05:00+08:00
description: 一定要声明成全局变量以保持对Timer的引用，不要声明成业务内的局部变量，否则会被垃圾收集器回收！using System; using System.Threading; using System.Threading.Tasks; namespace ActionStudy { class Program { private System.Threading.Timer timer; public static Action Print_Action;//声明事件 static void Main(string[] args) { //创建定时器，2000是延迟多少毫秒，10000是间隔时间 timer = new Timer(new TimerCallback(Execute), null, 2000, 10000); //timer= new System.Threading.Timer(new TimerCallback(Print), this, 5000, 0); //事件触发绑定的方法 Print_Action += Print; Console.ReadKey(); } /// /// 创建回调触发方法 /// /// public static void Execute(object o) { //Console.WriteLine("just run now"); Print_Action?.Invoke(); } /// /// 需要定时执行的方法 /// public static void Print() { Console.WriteLine("Action我是狗子 希望你幸福!"+DateTime.Now.ToString()); } } }

.NET C#使用NPOI将Excel中的数据批量导入到MySQL
type: item
date: 2024-01-10T14:00:00+08:00
description: 一、引入NPOI NuGet：通过NuGet管理解决方案安装：搜索：NPOI进行安装：二、ASP.NET Core使用EF Core连接MySQL执行简单的CRUD操作：因为该篇文章会涉及到MySQL数据库的操作，所以前提我们需要有一点的CRUD的基础。这里就不做详细的讲解了三、使用NPOI获取Excel数据注意点：1、关于Excel的版本问题做过Excel相关工作的人应该都清楚Office Excel的格式有两种：a、一种是.XLS是03版的Office Excel，无法打开高版本的。b、一种是.XLSX是07版(或者07以上的)的Office Excel，可以打开低版本的。所以我们在使用NPOI导入数据时不同格式获取Excel工作簿对象也有所不同，如下代码所示：//Workbook对象代表一个工作簿,首先定义一个Excel工作薄 IWorkbook workbook; //XSSFWorkbook 适用XLSX格式，HSSFWorkbook 适用XLS格式 #region 判断Excel版本 switch (fileType) { //.XLSX是07版(或者07以上的)的Office Excel case ".xlsx": workbook = new XSSFWorkbook(stream); break; //.XLS是03版的Office Excel case ".xls": workbook = new HSSFWorkbook(stream); break; default: throw new Exception("Excel文档格式有误"); } #endregion2、NPOI获取Excel单元格中不同类型的数据：{message type="info" content="注意，咱们填写在Excel单元格中的数据可能为多种不同的数据类型，因此我们需要对单元格中的数据类型做判断然后在获取，否则程序会报异常。"/}#region NPOI获取Excel单元格中不同类型的数据 //获取指定的单元格信息 var cell = row.GetCell(j); switch (cell.CellType) { //首先在NPOI中数字和日期都属于Numeric类型 //通过NPOI中自带的DateUtil.IsCellDateFormatted判断是否为时间日期类型 case CellType.Numeric when DateUtil.IsCellDateFormatted(cell): dataRow[j] = cell.DateCellValue; break; case CellType.Numeric: //其他数字类型 dataRow[j] = cell.NumericCellValue; break; //空数据类型 case CellType.Blank: dataRow[j] = ""; break; //公式类型 case CellType.Formula: { HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(workbook); dataRow[j] = eva.Evaluate(cell).StringValue; break; } //布尔类型 case CellType.Boolean: dataRow[j] = row.GetCell(j).BooleanCellValue; break; //错误 case CellType.Error: dataRow[j] = HSSFErrorConstants.GetText(row.GetCell(j).ErrorCellValue); break; //其他类型都按字符串类型来处理（未知类型CellType.Unknown，字符串类型CellType.String） default: dataRow[j] = cell.StringCellValue; break; } #endregion 四、通用的NPOI Excel导入数据帮助类（NpoiExcelImportHelper）：/** * Description：Npoi数据导入帮助类 * Description：2024年1月10日 */ using System; using System.Data; using System.IO; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; namespace YY_Utility { public class NpoiExcelImportHelper { private s…

.NET C#使用NPOI导出Word详解
type: item
date: 2024-01-10T13:50:00+08:00
description: 一、首先引入NPOI NuGet通过NuGet管理解决方案安装,搜索：NPOI进行安装：二、导出的Work文档内容展示格式如下图所示：三、NPOI中的XWPFRun文本对象创建和常用属性简单概述XWPFRun文本对象说明： XWPFRun是段落的文本对象，先创建段落对象才能够在段落对象的基础上创建文本对象，并设置相关文本样式。使用方式，如下所示：/// /// 创建word文档中的段落对象和设置段落文本的基本样式（字体大小，字体，字体颜色，字体对齐位置） /// /// document文档对象 /// 段落第一个文本对象填充的内容 /// 是否加粗 /// 字体大小 /// 字体 /// 段落排列（左对齐，居中，右对齐） /// 是否在同一段落创建第二个文本对象（解决同一段落里面需要填充两个或者多个文本值的情况，多个文本需要自己拓展，现在最多支持两个） /// 第二次声明的文本对象填充的内容，样式与第一次的一致 /// 字体颜色--十六进制 /// 是否设置斜体（字体倾斜） /// <returns></returns> public XWPFParagraph ParagraphInstanceSetting(XWPFDocument document, string fillContent, bool isBold, int fontSize, string fontFamily, ParagraphAlignment paragraphAlign, bool isStatement = false, string secondFillContent = "", string fontColor = "000000", bool isItalic = false) { XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象 paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列（左对齐，居中，右对齐） XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象 xwpfRun.IsBold = isBold;//文字加粗 xwpfRun.SetText(fillContent);//填充内容 xwpfRun.FontSize = fontSize;//设置文字大小 xwpfRun.IsItalic = isItalic;//是否设置斜体（字体倾斜） xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制 xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如：（微软雅黑，隶书，楷体）根据自己的需求而定 if (!isStatement) return paragraph; XWPFRun secondXwpfRun = paragraph.CreateRun();//创建段落文本对象 secondXwpfRun.IsBold = isBold;//文字加粗 secondXwpfRun.SetText(secondFillContent);//填充内容 secondXwpfRun.FontSize = fontSize;//设置文字大小 secondXwpfRun.IsItalic = isItalic;//是否设置斜体（字体倾斜） secondXwpfRun.SetColor(fontColor);//设置字体颜色--十六进制 secondXwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如：（微软雅黑，隶书，楷体）根据自己的需求而定 return paragraph; }XWPFRun文本对象的属性比较多，以下我简单介绍下常用的一些属性：XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象 XWPFRun xwpfRun= paragraph.CreateRun();//创建段落文本对象 xwpfRun.IsBold = isBold;//文字加粗 xwpfRun.SetText(fillContent);//填充内容 xwpfRun.FontSize = fontSize;//设置文字大小 xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如：（微软雅黑，隶书，楷体）根据自己的需求而定 xwpfRun.SetColor("BED4F1");//…

.NET c# 使用NPOI导出复杂Excel
type: item
date: 2024-01-10T13:24:00+08:00
description: 一、通过NuGet管理解决方案安装 搜索：NPOI进行安装： 二、导出Excel文档内容展示格式如下如所示： 三、CellStyle单元格常用样式概述HSSFCellStyle cellStyle = (HSSFCellStyle)workbook.CreateCellStyle(); //创建列头单元格实例样式 cellStyle.Alignment = hAlignment; //水平布局方式（HorizontalAlignment hAlignment） cellStyle.VerticalAlignment = vAlignment; //垂直布局方式（VerticalAlignment vAlignment） cellStyle.WrapText =false;//是否自动换行 //TODO:十分注意，要设置单元格背景色必须是FillForegroundColor和FillPattern两个属性同时设置，否则是不会显示背景颜色 //如下设置黄色背景色 cellStyle.FillForegroundColor = cellBackgroundColor;//单元格背景颜色（short cellBackgroundColor = HSSFColor.Yellow.Index） cellStyle.FillPattern = fillPattern;//填充图案样式(FineDots 细点，SolidForeground立体前景，isAddFillPattern=true时存在（FillPattern fillPattern = FillPattern.SolidForeground） //设置单元格边框样式 //常用的边框样式 None(没有),Thin(细边框，瘦的),Medium(中等),Dashed(虚线),Dotted(星罗棋布的),Thick(厚的),Double(双倍),Hair(头发)[上右下左顺序设置] cellStyle.BorderBottom = BorderStyle.Thin; cellStyle.BorderRight = BorderStyle.Thin; cellStyle.BorderTop = BorderStyle.Thin; cellStyle.BorderLeft = BorderStyle.Thin; //设置单元格边框颜色[上右下左顺序设置] cellStyle.TopBorderColor = HSSFColor.DarkGreen.Index;//DarkGreen(黑绿色) cellStyle.RightBorderColor = HSSFColor.DarkGreen.Index; cellStyle.BottomBorderColor = HSSFColor.DarkGreen.Index; cellStyle.LeftBorderColor = HSSFColor.DarkGreen.Index;四、Font字体常用属性概述：var cellStyleFont = (HSSFFont)workbook.CreateFont();//创建字体对象实例 //假如字体大小只需要是粗体的话直接使用下面该属性即可 cellStyleFont.IsBold = true; //或者通过下面属性，设置字体weight来设置字体是否加粗 cellStyleFont.Boldweight = boldWeight; //字体加粗（字体加粗 (None = 0,Normal = 400，Bold = 700） cellStyleFont.FontHeightInPoints = fontHeightInPoints; //字体大小（short fontHeightInPoints） cellStyleFont.FontName = fontName;//字体（仿宋，楷体，宋体 ） cellStyleFont.Color = fontColor;//设置字体颜色（short fontColor = HSSFColor.Black.Index） cellStyleFont.IsItalic =true;//是否将文字变为斜体（true是，false否） cellStyleFont.Underline = underlineStyle;//字体下划线（下划线样式（无下划线[None],单下划线[Single],双下划线[Double],会计用单下划线[SingleAccounting],会计用双下划线[DoubleAccounting]）） cellStyleFont.TypeOffset = typeOffset;//字体上标下标（字体上标下标(普通默认值[None],上标[Sub],…

C# datatable 用于二次修改
type: item
date: 2023-12-25T10:14:00+08:00
description: MySqlDataReader reader = cmd.ExecuteReader(); DataTable dt = new DataTable(); DataTable schemaTable = reader.GetSchemaTable(); foreach (DataRow dr in schemaTable.Rows) { DataColumn dc = new DataColumn(); dc.DataType = dr[0].GetType(); dc.ColumnName = dr[0].ToString(); dt.Columns.Add(dc); } while (reader.Read()) { DataRow row = dt.NewRow(); for (int i = 0; i < schemaTable.Rows.Count; i++) { row[i] = reader[i].ToString(); } dt.Rows.Add(row); row = null; } schemaTable.Clear(); dt.DefaultView.Sort = "land_time ASC"; dt = dt.DefaultView.ToTable(); foreach (DataRow item in dt.Rows){ Console.WrintLine(item[0]); }

C#数据库datRow泛型反射实体类,
type: item
date: 2023-12-23T15:15:00+08:00
description: 代码如下 public static class Tomodel{ public static Tmodel DataRowToModel<Tmodel>(this DataRow dr){ Type type = typeof(Tmodel); Tmodel md = (Tmodel)Activator.CreateInstance(type); foreach(var prop in type.GetProperties()){ prop.SetValue(md,dr[prop.Name]); } return md; } }使用（this 是扩展方法） dr.DataRowToModell<userModel>(); user.Add(dr.DataRowToModel<userModel>());