C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例
本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正。
在工程中引用word的动态库
在项目中,点击项目名称右键-->管理NuGet程序包,打开NuGet包管理器窗口,进行搜索下载即可,如下图所示:
涉及知识点
- _Application: 表示word应用程序的接口,对应的实现类是Application类。
- _Document:表示一个word文档,通过_Application对应的文档接口进行创建。
- Paragraph:表示一个段落,通过_Document对象的相关方法进行创建。
- Table:表示一个表格,通过_Document对象的相关方法进行创建。
- Range:表示一个区域,可以是一个段落,也可以是一个表格,也可以是一个单元格,可以Range.select()将光标移动到当前区域。
- 移动焦点:wordApp.Selection.MoveDown(ref wdLine, ref ncount, ref oMissing);//移动焦点
生成文档效果图
核心代码
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 using Microsoft.Office.Interop.Word; 2 using System; 3 using System.Collections.Generic; 4 using System.Data; 5 using System.IO; 6 using System.Linq; 7 using System.Reflection; 8 using System.Text; 9 using System.Threading.Tasks; 10 11 namespace ETWord 12 { 13 public class WordHelper 14 { 15 public static void CreateWordFile(string filePath) 16 { 17 18 try 19 { 20 CreateFile(filePath); 21 // 22 MessageFilter.Register(); 23 object wdLine = WdUnits.wdLine; 24 object oMissing = Missing.Value; 25 object fileName = filePath; 26 object heading2 = WdBuiltinStyle.wdStyleHeading2; 27 object heading3 = WdBuiltinStyle.wdStyleHeading3; 28 29 _Application wordApp = new Application(); 30 wordApp.Visible = true; 31 _Document wordDoc = wordApp.Documents.Open(ref fileName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); 32 System.Data.DataTable dtDepts = DatabaseHelper.getDept(); 33 int ii = 0; 34 foreach (DataRow dr in dtDepts.Rows) 35 { 36 string dept = dr["dept"].ToString(); 37 Paragraph oPara0 = wordDoc.Content.Paragraphs.Add(ref oMissing); 38 oPara0.Range.Text = string.Format("{0}-{1}", ii + 1, dept); 39 //oPara0.Range.Font.Bold = 1; 40 //oPara0.Format.SpaceAfter = 5; 41 oPara0.Range.Select(); 42 oPara0.set_Style(ref heading2); 43 oPara0.Range.InsertParagraphAfter(); 44 System.Data.DataTable dtTemplate = DatabaseHelper.getTemplateByDept(dept); 45 int jj = 0; 46 foreach (DataRow dr1 in dtTemplate.Rows) 47 { 48 string template = dr1["template"].ToString(); 49 string user1 = dr1["user1"].ToString(); 50 string remark = dr1["remark"].ToString(); 51 System.Data.DataTable dtData = DatabaseHelper.getDataByDeptAndTemplate(dept, template); 52 int count = dtData.Rows.Count; 53 int row = count + 4; 54 int column = 5; 55 object ncount = 1; 56 57 wordApp.Selection.MoveDown(ref wdLine, ref ncount, ref oMissing); 58 wordApp.Selection.TypeParagraph(); 59 Paragraph oPara1 = wordDoc.Content.Paragraphs.Add(ref oMissing); 60 oPara1.Range.Select(); 61 oPara1.Range.Text = string.Format("{0}-{1}、{2}", ii + 1, jj + 1, template); 62 //oPara1.Range.Font.Bold = 1; 63 //oPara1.Format.SpaceAfter = 5; 64 oPara1.set_Style(ref heading3); 65 oPara1.Range.InsertParagraphAfter(); 66 wordApp.Selection.MoveDown(ref wdLine, ref ncount, ref oMissing); 67 wordApp.Selection.TypeParagraph(); 68 //设置表格 69 Table table = wordDoc.Tables.Add(wordApp.Selection.Range, row, column, ref oMissing, ref oMissing); 70 71 table.Borders.OutsideLineStyle = WdLineStyle.wdLineStyleSingle; 72 table.Borders.InsideLineStyle = WdLineStyle.wdLineStyleSingle; 73 table.Range.Font.Bold = 0; 74 table.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthAuto; 75 table.Columns[1].Width = 60f; 76 table.Columns[2].Width = 100f; 77 table.Columns[3].Width = 100f; 78 table.Columns[4].Width = 60f; 79 table.Columns[5].Width = 100f; 80 //列的合并 81 Cell cell = table.Cell(1, 2); 82 cell.Merge(table.Cell(1, 5)); 83 Cell cell2 = table.Cell(2, 2); 84 cell2.Merge(table.Cell(2, 5)); 85 Cell cell3 = table.Cell(3, 2); 86 cell3.Merge(table.Cell(3, 5)); 87 //赋值 88 table.Cell(1, 1).Range.Text = "流程名称:"; 89 table.Cell(2, 1).Range.Text = "使用人:"; 90 table.Cell(3, 1).Range.Text = "流程说明:"; 91 table.Cell(4, 1).Range.Text = "节点"; 92 table.Cell(4, 2).Range.Text = "节点名"; 93 table.Cell(4, 3).Range.Text = "处理人员"; 94 table.Cell(4, 4).Range.Text = "处理方式"; 95 table.Cell(4, 5).Range.Text = "跳转信息"; 96 table.Cell(1, 2).Range.Text = template; 97 table.Cell(2, 2).Range.Text = user1; 98 table.Cell(3, 2).Range.Text = remark; 99 int kk = 5; 100 foreach (DataRow dr2 in dtData.Rows) 101 { 102 table.Cell(kk, 1).Range.Text = (kk - 4).ToString(); 103 table.Cell(kk, 2).Range.Text = dr2["NodeName"].ToString(); 104 table.Cell(kk, 3).Range.Text = dr2["DoName"].ToString(); 105 table.Cell(kk, 4).Range.Text = dr2["DoType"].ToString(); 106 table.Cell(kk, 5).Range.Text = string.Empty; 107 kk++; 108 } 109 table.Cell(kk - 1, 5).Range.Select(); 110 111 wordApp.Selection.MoveDown(ref wdLine, ref ncount, ref oMissing);//移动焦点 112 wordApp.Selection.TypeParagraph();//插入段落 113 114 jj++; 115 } 116 ii++; 117 } 118 119 //保存 120 wordDoc.Save(); 121 wordDoc.Close(ref oMissing, ref oMissing, ref oMissing); 122 wordApp.Quit(ref oMissing, ref oMissing, ref oMissing); 123 MessageFilter.Revoke(); 124 125 } 126 catch (Exception e) 127 { 128 Console.WriteLine(e.Message); 129 Console.WriteLine(e.StackTrace); 130 131 } 132 } 133 134 private static void CreateFile(string filePath) 135 { 136 if (!File.Exists(filePath)) 137 { 138 using (FileStream fs = File.Create(filePath)) 139 { 140 141 } 142 } 143 } 144 } 145 }
备注
- 插入多个表格时,表格容易嵌套,主要是由于往下移动的行数不对,后来通过选中表格右下角的单元格,将光标移动到表格右下角,然后再往下移动两行,即可解决表格嵌套的问题。
- 单元格合并问题,当单元格合并时,单元格的位置也随之改变,如:水平方向第二,三两个单元格合并,则原来的第四个单元格的坐标就会变成第三个单元格。
- 开发运行需要在电脑上安装office组件,或者也可以安装wps。
关于源码下载链接
[C#学习笔记3]关于Main(string[ ] args)中args命令行参数
Main(string[] args)方法是C#程序的入口,程序从这里开始执行,在这里结束。C#代码逻辑要包含在一个类型(Type)中,游离的、全局的变量或函数是不存在的,这里的类型包括类(class)、接口(interface)、结构(struct)、枚举(enum)和委托(delegate)。Main()方法包含在一个类中,这个类的默认名字叫作Program,包含Main()的类叫作应用程序对象(Application Object)。新建一个控制台应用程序(ConsoleApplication)。
程序中包含的初始代码为:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace exer 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 } 14 } 15 }
上面代码中,exer是定义的命名空间,与创建的控制台应用程序的名称相同;Main(string[] args)是程序的主方法(或称主函数),即程序的入口,程序将从这里开始执行,也在这里结束;Program是包含Main()方法的类,即上面提到的应用程序对象。
一个控制台应用程序项目中可以存在多个应用程序对象,即可以存在多个Main()方法分布在不同的类中。但是程序每次执行时只能选择启动一个应用程序对象,即只能选择一个Main()方法作为程序的入口。通知编译器将哪个Main()方法作为程序的入口可以在项目属性编辑器的应用程序(Application)选项卡中的启动对象(Startup Object)处设置。
下面编写两个应用程序对象,并分别启动测试,代码如下。其中,将用不到的using引用删去了;Console.ReadLine()方法用来从控制台接收键盘输入的一段以回车符结束的字符串,这里起到暂停控制台的作用(否则调试程序时,控制台会一闪而过!),但也可以不调试程序而是直接运行,就不会出现一闪而过的情况了。
1 using System; 2 3 namespace exer 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 Console.WriteLine("From Program!"); 10 Console.ReadLine(); 11 } 12 } 13 14 class AnotherProgram 15 { 16 static void Main(string[] args) 17 { 18 Console.WriteLine("From AnotherProgram!!"); 19 Console.ReadLine(); 20 } 21 } 22 }
调试程序,编译器报错。
打开项目属性编辑器,在应用程序(Application)选项卡中的启动对象(Startup Object)下拉框中选择程序入口点,分别运行程序,查看结果。
一、关于Main()方法
Main()方法形式一般如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 6 } 7 }
其中,static表示Main()方法是一个静态方法;void表示Main()方法返回值为空,是说我们不需要在Main()方法结尾处写上return语句来显示定义一个返回值,但程序在运行结束后还是会自动返回给系统一个表示程序是否正常结束的值(0或其他值,0表示程序正常结束、其他值如-1表示程序有错误发生);Main()方法中有一个字符串数组类型的形式参数,包含程序启动时传递给系统的命令行参数。
除了这种默认的形式,Main()方法还可以是其他的形式。构造什么样的Main()方法需要考虑两个问题:①程序执行结束后是否要向系统返回一个值 ②程序是否需要处理用户提供的命令行参数
1 class Program //默认形式 2 { 3 static void Main(string[] args) 4 { 5 6 } 7 } 8 class Program 9 {
10 static int Main(string[] args) 11 { 12 return 0; 13 } 14 } 15 class Program 16 { 17 static void Main() 18 { 19 20 } 21 } 22 class Program 23 { 24 static int Main() 25 { 26 return 0; 27 } 28 }
二、提供给程序命令行参数
Main(string[] args)方法中,用户提供的命令行参数是保存在args字符串数组中的,当提供参数后,在Main()方法中就可以遍历args数组查看这些参数。设置遍历参数的C#语句(也可以使用foreach)。
1 for(int i=0;i<args.Length;i++) 2 Console.WriteLine("arg:{0}",args[i]);
那么,如何提供给程序这些命令行参数呢?有两种方法。
①Developer Command Prompt命令行中提供参数
打开DCP(开发人员命令提示),切换到程序所在路径,运行已经编译好的exer.exe应用程序同时输入参数,参数可以不包括前缀('\'或'-',当然也可以包含..),以空格分隔。
②Visual Studio项目属性编辑器中指定命令行参数,同样以空格分隔
三、代码访问命令行参数的其他方法
当提供给程序命令行参数后,可以使用for或者foreach语句进行args参数的遍历,还可以使用System.Environment类的静态方法GetCommandLineArgs()进行参数的访问。System.Environment.GetCommandLineArgs()返回一个字符串数组,即包含命令行参数的数组。
1 static void Main(string[] args) 2 { 3 Console.WriteLine("From Program!"); 4 5 //for(int i=0;i<args.Length;i++) 6 // Console.WriteLine("arg:{0}",args[i]); 7 8 string[] arr = System.Environment.GetCommandLineArgs(); 9 for(int i=0;i<arr.Length;i++) 10 Console.WriteLine("arg:{0}",arr[i]); 11 Console.ReadLine(); 12 }
System.Environment.GetCommandLineArgs()返回的字符串数组中,第一个字符串是当前应用程序的完全路径名,其他字符串是用户提供给程序的命令行参数。当使用这种方法获取命令行参数时,Main()括号中可以去掉string[] args形式参数了。
实现DataTables搜索框查询结果高亮显示
DataTables是封装好的HTML表格插件,丰富了HTML表格的样式,提供了即时搜索、分页等多种表格高级功能。用户可以编写很少的代码(甚至只是使用官方的示例代码),做出一个漂亮的表格以展示数据。关于DataTables的更多信息,请查看:http://www.datatables.club/、https://datatables.net/。下图将要展示的南京景点游记的相关数据,在DataTables表格中展示出来。
上面DataTable表格中的即时搜索、分页等功能是创建好DataTables对象后就有的,不用编写相关代码。“即时搜索”是指随着键入字符的变化,表格中会出现变化着的匹配信息。
但是DataTables本身没有提供搜索结果高亮显示的功能,需要引入相关JavaScript文件并编写相关代码。DataTables中文网提供了这一js文件,但是例子中少写了一条设置样式的语句,所以无法实现高亮显示的功能。http://www.datatables.club/blog/2014/10/22/search-result-highlighting.html
一、DataTables的相关代码
1.代码骨架
使用DataTables表格需要引入jQuery;例子使用了在线的DataTables CDN。
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title>..</title> 5 6 <!-- jQuery 引入 --> 7 <script src="jquery-3.0.0.min.js"></script> 8 9 <!-- DataTables 引入 --> 10 <link rel="stylesheet" href="http://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css"> 11 <script src="http://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script> 12 </head> 13 14 <body> 15 16 </body> 17 </html>
2.创建表格
在<body></body>标签中创建一个<table>元素,设置table表格的表头信息。
1 <body> 2 <table id="table" class="display"> 3 <thead> 4 <tr> 5 <th>昵称</th> 6 <th>所在地</th> 7 <th>游记文章</th> 8 <th>出发时间</th> 9 <th>出行天数</th> 10 <th>人物</th> 11 <th>人均费用</th> 12 <th>相关链接</th> 13 </tr> 14 </thead> 15 16 <tbody> 17 18 </tbody> 19 </table> 20 </body>
3.配置table成DataTable
<script></script>标签中对DataTable进行相关设置,这里不对其他样式进行设置,只配置表格的数据源。DataTables表格支持多种数据源,JavaScript对象数组、ajax返回来的数据、json格式数据等等。这里将Excel表格中的数据以对象数组的形式存放在"南京游记.js"文件里(数组中每一个元素是一个对象,即一条游记记录信息),再在DataTables所在HTML页面中src引入("南京景点.js"文件中只有一个JavaScript对象数组)。采用这种方法配置数据源,需要在DataTable的构造函数中设置columns属性,注意这里和Table表头信息要相对应。关于DataTables样式设置及数据源配置的其他方式请查看官方文档中的相关内容:https://datatables.net/examples/index。
1 <body> 2 <table id="table" class="display"> 3 <thead> 4 <tr> 5 <th>昵称</th> 6 <th>所在地</th> 7 <th>游记文章</th> 8 <th>出发时间</th> 9 <th>出行天数</th> 10 <th>人物</th> 11 <th>人均费用</th> 12 <th>相关链接</th> 13 </tr> 14 </thead> 15 16 <tbody> 17 18 </tbody> 19 </table> 20 21 <!-- DataTables 数据源 --> 22 <script src="南京游记.js"></script> 23 24 <!-- DataTables 设置 --> 25 <script> 26 $(document).ready(function(){ 27 var table=$('#table').DataTable({ 28 data:data, 29 columns:[ 30 {data:'昵称'}, 31 {data:'所在地'}, 32 {data:'游记文章'}, 33 {data:'出发时间'}, 34 {data:'出行天数'}, 35 {data:'人物'}, 36 {data:'人均费用'}, 37 {data:'相关链接'} 38 ] 39 }) 40 }); 41 </script> 42 </body>
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title>..</title> 5 6 <!-- jQuery 引入 --> 7 <script src="jquery-3.0.0.min.js"></script> 8 9 <!-- DataTables 引入 --> 10 <link rel="stylesheet" href="http://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css"> 11 <script src="http://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script> 12 13 </head> 14 15 <body> 16 <table id="table" class="display"> 17 <thead> 18 <tr> 19 <th>昵称</th> 20 <th>所在地</th> 21 <th>游记文章</th> 22 <th>出发时间</th> 23 <th>出行天数</th> 24 <th>人物</th> 25 <th>人均费用</th> 26 <th>相关链接</th> 27 </tr> 28 </thead> 29 30 <tbody> 31 32 </tbody> 33 </table> 34 35 <!-- DataTables 数据源 --> 36 <script src="南京游记.js"></script> 37 38 <!-- DataTables 设置 --> 39 <script> 40 $(document).ready(function(){ 41 var table=$('#table').DataTable({ 42 data:data, 43 columns:[ 44 {data:'昵称'}, 45 {data:'所在地'}, 46 {data:'游记文章'}, 47 {data:'出发时间'}, 48 {data:'出行天数'}, 49 {data:'人物'}, 50 {data:'人均费用'}, 51 {data:'相关链接'} 52 ] 53 }) 54 }); 55 </script> 56 </body> 57 </html>
二、官方提供的搜索框高亮显示的方法
DataTables中文网提供了高亮显示的一种方法(http://www.datatables.club/blog/2014/10/22/search-result-highlighting.html),提供的js文件是可以实现高亮显示功能的,但是要在<head></head>中添加<style>样式以设置高亮显示的颜色,否则将没有高亮显示的效果。
1 <!-- DataTables搜索内容后高亮显示 --> 2 <style> 3 .highlight { 4 background-color: skyblue 5 } 6 </style>
这种方法的具体步骤为:
1.将提供的js文件复制后保存成一个js文件,并在代码中src引入
2.在DataTable的构造函数后,添加Table的draw事件,即时搜索框中字符变化时会触发事件
1 <!-- DataTables 设置 --> 2 <script> 3 $(document).ready(function(){ 4 var table=$('#table').DataTable({ 5 data:data, 6 columns:[ 7 {data:'昵称'}, 8 {data:'所在地'}, 9 {data:'游记文章'}, 10 {data:'出发时间'}, 11 {data:'出行天数'}, 12 {data:'人物'}, 13 {data:'人均费用'}, 14 {data:'相关链接'} 15 ] 16 }); 17 18 //监听DataTable重绘事件(*) 19 table.on('draw', function () { 20 var body = $(table.table().body()); 21 body.unhighlight(); 22 body.highlight(table.search()); 23 }); 24 }); 25 </script>
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title>..</title> 5 6 <!-- jQuery 引入 --> 7 <script src="jquery-3.0.0.min.js"></script> 8 9 <!-- DataTables 引入 --> 10 <link rel="stylesheet" href="http://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css"> 11 <script src="http://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script> 12 13 <!-- DataTables搜索框查询结果高亮显示 --> 14 <script src="highlight.js"></script> 15 16 <!-- DataTables搜索内容后高亮显示 --> 17 <style> 18 .highlight { 19 background-color: skyblue 20 } 21 </style> 22 </head> 23 24 <body> 25 <table id="articlesTable" class="display"> 26 <thead> 27 <tr> 28 <th>昵称</th> 29 <th>所在地</th> 30 <th>游记文章</th> 31 <th>出发时间</th> 32 <th>出行天数</th> 33 <th>人物</th> 34 <th>人均费用</th> 35 <th>相关链接</th> 36 </tr> 37 </thead> 38 <tbody> 39 40 </tbody> 41 </table> 42 43 <script src="南京游记.js"></script> 44 45 <!-- DataTables 设置 --> 46 <script> 47 $(document).ready(function(){ 48 var table=$('#articlesTable').DataTable({ 49 data:data, 50 columns:[ 51 {data:'昵称'}, 52 {data:'所在地'}, 53 {data:'游记文章'}, 54 {data:'出发时间'}, 55 {data:'出行天数'}, 56 {data:'人物'}, 57 {data:'人均费用'}, 58 {data:'相关链接'} 59 ] 60 }); 61 62 //监听DataTable重绘事件(*) 63 table.on('draw', function () { 64 var body = $(table.table().body()); 65 body.unhighlight(); 66 body.highlight(table.search()); 67 }); 68 }); 69 </script> 70 </body> 71 </html>
注意,官网提供的这个js文件中,定义高亮显示的函数是highlight(),去除高亮显示的函数是unhighlight()。
三、搜索框查询结果高亮显示的其他方法
https://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html。这里提供了可以实现高亮显示功能的其他两个JavaScript文件,如果引入这里面的js文件,高亮显示的函数是highlight()没有变,但去除高亮显示的函数变成了removeHighlight()。
引入这3个js文件中的任一个并编写相应高亮/去高亮的代码语句,都是可以实现DataTables搜索框查询结果高亮显示功能的,但是注意要在<head></head>标签中设置高亮显示的背景颜色,否则没有高亮显示的效果。
四、总结
实现DataTables搜索框查询结果高亮显示的功能需要引入JavaScript文件,文中提供了3种这类文件,并说明了要配套编写的相关代码。
文中例子的链接分享:https://pan.baidu.com/s/1sT3K9tXskhx-YNAs7W5gHw
二维码神器
现在出门在外,二维码随处可见,吃个东西、买个青菜,没有weixin或者zhifubao的扫一扫来付款,阿姨都嫌弃你了。
这里推荐一款开源二维码的第三方库:QRCoder
QRCoder:https://github.com/codebude/QRCoder/
QRCoder是一个简单的库,用C#.NET编写,可以创建QR码,没有与其他的库有任何依赖关系, 引用就一个几百kb的dll,并且效率还不错。
引入
新建一个winform项目,然后从nuget上引入即可
然后再引入命名空间
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using QRCoder; //就是它,没有多余的创建第一张二维码
在GayHub上,QRCoder的readme已经介绍过了,只要4行简单的代码,就可以完成二维码生成了。
QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode("The text which should be encoded.", QRCodeGenerator.ECCLevel.Q); QRCode qrCode = new QRCode(qrCodeData); Bitmap qrCodeImage = qrCode.GetGraphic(20);不过这里做了一个简单的winform来使用它,
private void CreateQR(int pixelsPerModule, string info, Color qrColor, Color qrBackgroundColor, Bitmap logo, int iconSizePercent = 15, int iconBorderWidth = 6) { QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode(info, QRCodeGenerator.ECCLevel.Q); QRCode qrCode = new QRCode(qrCodeData); Bitmap qrCodeImage = qrCode.GetGraphic(pixelsPerModule, qrColor, qrBackgroundColor, logo, iconSizePercent, iconBorderWidth, true); picBoxQRCode.Image = qrCodeImage; } private void CreateQR(int pixelsPerModule, string info, Color qrColor, Color qrBackgroundColor) { QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode(info, QRCodeGenerator.ECCLevel.Q); QRCode qrCode = new QRCode(qrCodeData); Bitmap qrCodeImage = qrCode.GetGraphic(pixelsPerModule, qrColor, qrBackgroundColor, true); picBoxQRCode.Image = qrCodeImage; }界面效果:
QRCoder还有许多设置,根据不同需要来传入不同参数即可。
文章中的Demo代码很简单,大家借鉴参考玩玩,欢迎大家来到GayHub交流:https://github.com/EminemJK/QRCodeForm
.Net生态社区希望越来越壮大,不断有优秀的开源组件的加入。
Asp.net MVC 中 CodeFirst 开发模式实例
昨天写的这篇博客因为下班时间到了忘记保存了,好郁闷,得重新写一遍。实习所在公司使用的是CodeFirst开发模式,最近开始参与到公司的项目里面来了,发现这个模式特别好用,建库建表改变字段属性添加删除字段等等操作都无需自己在数据库动手操作,只需要编写代码即可实现,着实是方便了许多。今天来记录一下如何使用CodeFirst开发模式,闲言少叙,下面进入正题。
(一)准备工作
新建三个项目,其中一个为MVC项目(Console),另外两个为类库项目(Moel和ORM),三者用途如下:
Console:这个就不说了;
Model:这个项目里专门书写数据实体类;
ORM:这个项目用来创建上下文,构建数据库与实体类之间的映射关系;
如下图所示:
(二)在Model中添加实体类User.cs
代码如下:
namespace Model { [Table("Sys_User")] //自动建表的表名 public class User { /// <summary> /// 主键 /// </summary> [Key] public Guid Id { get; set;} /// <summary> /// 登录名 /// </summary> [Required] //必填项(非空) [MaxLength(50)] //最大长度(50) public string LoginName { get; set;} /// <summary> /// 密码 /// </summary> [Required] [MaxLength(50)] public string Password { get; set; } /// <summary> /// 性别 /// </summary> [Required] public bool Gender { set; get; } /// <summary> /// 是否启用 /// </summary> [Required] public bool IsEnable { get; set; } /// <summary> /// 真实姓名 /// </summary> [MaxLength(50)] public string RealName { get; set; } [MaxLength(300)] public string Remark { get; set; } /// <summary> /// 创建时间 /// </summary> public DateTime CreateTime { get; set; } } }
(三)在ORM中书写上下文,建立映射关系
1.在ORM中利用Nuget工具添加EF包:
2.新建类文件,添加如下代码:
namespace ORM { public class MyDbContext : DbContext { public MyDbContext() : base(GetConnectionString()) { } private static string GetConnectionString() { return "SqlServerConnectionString"; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } public DbSet<User> Users { get; set; }//建立实体类与表的映射关系 } }
上面的构造函数public MyDbContext():base("XXX"){},这个xxx位置填写的是你在配置文件里配置数据库链接的链接名,上面代码我写的是 SqlServerConnectionString。
(四)在配置文件中配置数据库连接字符串 SqlServerConnectionString
首先,同样要用nuget工具将EF添加到 Console中,然后,在代码中如下位置添加连接字符串:
需要注意的是:
<connectionStrings> 加到<configSections></configSections>的后面,不要加到前面去了,否则可能会出问题哦!代码如下:
<connectionStrings> <add name="SqlServerConnectString" providerName="System.Data.SqlClient" connectionString="Server=localhost;Database=CodeFirstDb;Integrated Security=False;User ID=sa;Password=168168;" / </connectionStrings>
连接字符串里的内容就不多说了,这里的数据库也会自动生成,不用自己手动去建库。
配置完ConnectionString后,记得要把System.Configuration这个引用添加到ORM项目中。
(五)数据迁移Migration (将Model的修改应用到数据库中,且不会改变对应的表中的原始数据)
在ORM项目中,打开nuget管理工具的控制台模式
然后输入指令:Enable-Migration:
完成此步后,我们可以看到,ORM中多了一个文件夹,里面有如下的内容:
下面对Configuration.cs里的内容进行更改:
改动点见上图。
(六)在Application_Start事件中初始化数据库策略
打开Console中的global.aspx文件,找到Application_Start事件,添加如下代码:
//当提供了初始化数据时,使用该形式,以初始化数据库策略并填充一些数据(当某个Model改变了,就删除原来的数据库创建新的数据库) Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext,ORM.Migrations.Configuration>());如下图所示:
(七)在Console新建控制器,实现一个对User表的简单应用
前面6步做好了,就基本大功告成了,下面验证一下,有没有自动生成数据库。
在控制器中添加控制器,直接选自动生成增删改查功能的模板,如下所示:
这样就自动生成了一些关于User的功能,我们打开这一页面,可以看到:
这里的一组数据是我加上去的,如果是首次运行,这里没有数据,只会显示这一排字段。
下面看一下我的数据库
这个数据库已经生成了,要知道我之前是并没有建这个库和表的。
下面,我将User.cs中的Remark实体删除,看看数据库中有何变化:
然后再次运行程序:
结果是这样的:
哦。。。。哦。。尴尬了啊,他禁止了我的数据迁移,说因为这会造成数据丢失,怎么办呢。好办,只需要在ORM下的Configuration.cs中添加如下代码即可解决:
// 自动迁移时如果引起数据丢失是否可接受 AutomaticMigrationDataLossAllowed = true;
看图:
然后我再运行一下代码:
再查看数据库:
看数据库,我们的Remark字段已经不见了。
因为缺少这个字段,所以在进行增删改查功能是会出错:
这是由于我们原来生成的View中有这个字段,现在实体类里这个字段删除了,而view页面中没删除造成的,只需要自己去把与Remark相关的字段删除就可以正常运行的。
下面,我再把这个Remark字段加上去,看看结果。
结果为:
看看数据库:
关于其他的新建表,添加字段等等功能,都是适用的,这里我就再一 一演示了。
好了,这篇就写到这里了哦,希望能帮到你!加油!
大佬看到了 ,也希望指点一下,感激不尽!