目录
01 前言
02 创建winform窗体应用项目
1 “浏览文件”自定义控件的制作
2 DataGirdView控件读取.dat文件数据并显示
2.1 添加DataGridView控件
2.2 通过Button控件往表格中添加数据
3 将显示在DataGirdView中的数据导出到Excel表格文件
4. 重写OnLayout方法,让窗口中的控件大小随窗口大小自适应。
因为最近要用到winform制作插件,学习了c#和winform控件基础功能,以一个小项目进行练习,在此记录一下。
本项目实现如下功能:
1. 通过浏览文件的形式读取.dat文本数据;
2. 使用dataGridView控件显示数据;
3. 点击导出Excel按钮输出Excel文件;
4. 控件大小随窗口大小的改变自适应。
制作的窗口如下图。
选c#;Windows;桌面;Windows窗体应用;(没有的话需要先安装一下)
在工具箱里拖进去一个TextBox控件和PictureBox控件。调整大小和位置如下图。
这里也可用Button控件代替PictureBox控件,用到的都是Click事件,效果是一样的。
在属性里面修改text文本框的(Name)属性。改名字是为了程序里面调用的时候好区分。
修改ImageBox控件的(Name)和Image属性。Image属性用来更改图标样式(这里的图标来源于iconfont-阿里巴巴矢量图标库,搜索“打开”关键字即可下载,文件名最好别用汉字)
给ImageBox控件添加一个Click事件。在自动生成的Click事件中添加点击事件处理程序。
代码如下:
private void Search_btn_Click(object sender, EventArgs e) {
//浏览文件
OpenFileDialog openFileDialog2 = new OpenFileDialog();
openFileDialog2.Multiselect = false; //该值确定是否可以选择多个文件
openFileDialog2.Title = "请选择文件";
openFileDialog2.Filter = "文档(*.dat;*.txt)|*.dat;*.txt";
if (openFileDialog2.ShowDialog() == DialogResult.OK) {
if (openFileDialog2.FileName != "") {
this.Search_text.Text = openFileDialog2.FileName;
}
}
}
控件使用效果如下:选择文件后左侧自动出现文件路径和名称
为什么要自定义一个控件?其实可以直接在form1中直接添加TextBox控件和ImageBox控件实现同样的功能,只是这样封装成一个控件觉得可以练习一下制作自定义控件,也方便以后直接拿来用。
给DataGridView控件添加列。因为这需要显示的表格数据列名是固定的,所以可以直接编辑添加。点击添加的DataGridView控件,点击右上角会出现的小三角 , 点击编辑列。
从工具箱中拖入一个Button控件。在属性栏中修改(Name)属性和Text属性,Text属性用于更改按钮上显示的文字。
在事件栏中添加一个Click事件。跟之前一样,鼠标点一下Click事件右侧按回车键即可自动生成点击事件。
在Click事件中添加如下代码。程序思路:先按条件筛取.dat文件中有用的一行数据存入input中,然后分别截取有用的数据段赋值给对应的每一列。
///
/// 获取两个字符串中间的字符串
///
/// 要处理的字符串,例ABCD
/// 第1个字符串,例AB
/// 第2个字符串,例D
/// 例返回C
private string GetBetweenStr(string str, string str1, string str2) {
int i1 = str.IndexOf(str1);
if (i1 < 0) //找不到返回空
{
return "";
}
int i2 = str.IndexOf(str2, i1 + str1.Length); //从找到的第1个字符串后再去找
if (i2 < 0) //找不到返回空
{
return "";
}
return str.Substring(i1 + str1.Length, i2 - i1 - str1.Length);
}
//确定按钮点击事件
private void button_Confirm_Click(object sender, EventArgs e) {
//点击确认按钮事件,读取.dat文件数据并显示出来,弹出对话框“数据已显示”
//先确认是否选择了正确文件
string filePath = SearchBox1.Search_text.Text;//文件地址
string fileExt = Path.GetExtension(filePath).ToLower();//获取文件的拓展名
string fileNameData = Path.GetFileName(filePath);
if (!File.Exists(filePath)) {
MessageBox.Show("文件不存在");
return;
}
if (!(fileExt == ".dat")) {
MessageBox.Show("请选择.dat格式文件");
return;
}
using (StreamReader sr = File.OpenText(filePath)) {
string input; //存放.dat文件的单行数据
while ((input = sr.ReadLine()) != null) { //循环取出.dat文件的每行数据
//判断前十位是否为DECL E6POS
if (input.Contains("DECL E6POS")) {
Console.WriteLine(input);
string name = GetBetweenStr(input, "E6POS ", "=");
string X = GetBetweenStr(input, "X ", ",");
string Y = GetBetweenStr(input, "Y ", ",");
string Z = GetBetweenStr(input, "Z ", ",");
string A = GetBetweenStr(input, "A ", ",");
string B = GetBetweenStr(input, "B ", ",");
string C = GetBetweenStr(input, "C ", ",");
//创建一个object[7]存表格中的一行数据,一共7列
object[] row = new object[7];
row[0] = name; row[1] = X; row[2] = Y;
row[3] = Z; row[4] = A; row[5] = B; row[6] = C;
//在dataGridView1中新建一行并将存在row中的数据写入
dataGridView1.Rows.Add(row);
}
}
sr.Close();
}
添加Button控件。修改(Name)属性和Text属性。
添加Click事件。
在自动生成的Click事件是添加下面代码。
private void saveButton_Click(object sender, EventArgs e) {
//保存按钮,弹出对话框选择保存路径和文件名
//验证是否有文件
//弹出对话框浏览保存路径和文件名称
string filePath = SearchBox1.Search_text.Text; //.dat文件地址
string fileNameData = Path.GetFileNameWithoutExtension(filePath); //.dat文件名
string fileName = fileNameData; //可以在这里设置默认文件名
string saveFileName = ""; //文件保存名
SaveFileDialog saveDialog = new SaveFileDialog(); //实例化文件对象
saveDialog.DefaultExt = "xlsx";//文件默认扩展名
saveDialog.Filter = "Excel文件|*.xlsx";//获取或设置当前文件名筛选器字符串,该字符串决定对话框的“另存为文件类型”或“文件类型”框中出现的选择内容。
saveDialog.FileName = fileName;
saveDialog.ShowDialog();//打开保存窗口给你选择路径和设置文件名
saveFileName = saveDialog.FileName;
if (saveFileName.IndexOf(":") < 0) return; //被点了取消
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null) {
MessageBox.Show("无法创建Excel对象,您的电脑可能未安装Excel");
return;
}
Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;//Workbooks代表一个 Microsoft Excel 工作簿
Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);//新建一个工作表。 新工作表将成为活动工作表。
Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];//取得sheet1
//写入标题
for (int i = 0; i < dataGridView1.ColumnCount; i++)//遍历循环获取DataGridView标题
{ worksheet.Cells[1, i + 1] = dataGridView1.Columns[i].HeaderText; }// worksheet.Cells[1, i + 1]表示工作簿第一行第i+1列,Columns[i].HeaderText表示第i列的表头
//写入数值
for (int r = 0; r < dataGridView1.Rows.Count; r++)//这里表示数据的行标,dataGridView1.Rows.Count表示行数
{
for (int i = 0; i < dataGridView1.ColumnCount; i++)//遍历r行的列数
{
worksheet.Cells[r + 2, i + 1] = dataGridView1.Rows[r].Cells[i].Value;//Cells[r + 2, i + 1]表示工作簿从第二行开始第一行保存为表头了,dataGridView1.Rows[r].Cells[i].Value获取列的r行i值
}
System.Windows.Forms.Application.DoEvents();//实时更新表格
}
worksheet.Columns.EntireColumn.AutoFit();//列宽自适应
MessageBox.Show(fileName + "资料保存成功", "提示", MessageBoxButtons.OK);//提示保存成功
if (saveFileName != "")//saveFileName保存文件名不为空
{
try {
workbook.Saved = true;//获取或设置一个值,该值指示工作簿自上次保存以来是否进行了更改
workbook.SaveCopyAs(saveFileName); //fileSaved = true;将工作簿副本保存到文件中,但不修改内存中打开的工作簿
}
catch (Exception ex) {//fileSaved = false;
MessageBox.Show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
}
}
xlApp.Quit();
GC.Collect();//强行销毁
}
效果如下:
实现代码如下:
protected override void OnLayout(LayoutEventArgs levent) {
//1 调用父类的OnLayout(),不是必需的
base.OnLayout(levent);
//2 获取窗口大小 ClientSize (仅客户区,不含标题栏)
int w = this.ClientSize.Width;
int h = this.ClientSize.Height;
//3 计算每一个控件的位置和大小
int yoff = 0;//此变量用于设置间隔
yoff = 30;//第一行控件距顶部的间隔
this.SearchBox1.Location = new Point(30, yoff);
this.SearchBox1.Size = new Size(w - 145, 30);
this.button_Confirm.Location = new Point(w - 110, yoff);
this.button_Confirm.Size = new Size(80, 30);
yoff += 30;//the height of the first row
yoff += 5;//与上一行控件的间隔
this.dataGridView1.Location = new Point(30, yoff);
this.dataGridView1.Size = new Size(w - 60, 300);
yoff += 300;//the height of the second row
yoff += 5;//与上一行控件的间隔
this.saveButton.Location = new Point(w - 160, yoff);
this.saveButton.Size = new Size(130, 30);
}
说明:本文中的许多代码来源于CSDN、B站视频等,部分链接如下,有些是边学边写的可能会遗忘一些原文链接。
b站教程:https://b23.tv/LUcoVRM
C#:获取两个字符串中间的字符串_小鸿1983的博客-CSDN博客
C# DataGridView数据导出Excel文件_IC00的博客-CSDN博客_c# datagridview 导出到excel