使用WinForm演示,重点在于方法的使用;
该文章功能可用于批量获取固定样式的CSV文档中。
目录
二、获取每个CSV文档指定内容并展示在Datagridview控件上
有两个月没写文章了,一直有想写,但是自己确实偷懒,忙的时候是一回事,主要还是自觉性高不起来,今天有些想法,干脆把想的内容写成文章当笔记了,顺便巩固一下。
看起标题其实可以拆分为三个功能:
1.获取文件夹内的每个CSV文档;
2.获取每个CSV文档指定内容并展示在Datagridview控件上;
3.保存Datagridview内容为一个新的CSV文件。
那这么理解其实就开始有思路了,接下来文章将会逐一实现。
演示效果:
学生文件夹内有 1班 和 2班 两个CSV文档,格式一样,详情如下图:
文章示例我们只获取两个班学生的时间和姓名,演示GIF如下:
导出保存新CSV后,在自己保存的路径就可打开阅览CSV文档了,这里我保存在了文档里:
正文:
界面
一、获取文件夹内的每个CSV文档
此标题对应Button2控件 “导入文件夹”功能
代码如下:
#region 导入文件夹功能
private void button2_Click(object sender, EventArgs e)
{
try
{
GetFolderPath(textBox1.Text);
string filepath = textBox1.Text;
var rel = Directory.GetFiles(filepath, "*", SearchOption.AllDirectories).ToList();
List<string> Filee = new List<string>();
foreach (var file in rel)
{
//Console.WriteLine(file);
Filee.Add(file);
}
string[] newtargetRowArrCSVname = String.Join(",", Filee).Split(',');//转string数组
CSVALL = newtargetRowArrCSVname;
}
catch (Exception)
{
MessageBox.Show("请选择路径");
//throw;
}
}
/// <summary>
/// 获取文件夹路径
/// </summary>
/// <param name="HistoryPath">历史路径,可以在弹出选择路径前选定此路径,当然也可以不用设置</param>
/// <returns></returns>
private string GetFolderPath(string HistoryPath)
{
try
{
string FolderPath = "";
FolderBrowserDialog Dialog = new FolderBrowserDialog();
Dialog.Description = "请选择文件路径";
if (!string.IsNullOrWhiteSpace(HistoryPath)) Dialog.SelectedPath = HistoryPath;
//Dialog.RootFolder = Environment.SpecialFolder.Programs;
if (Dialog.ShowDialog() == DialogResult.OK)
{
FolderPath = Dialog.SelectedPath;
textBox1.Text = FolderPath;
if (string.IsNullOrWhiteSpace(FolderPath))
{
MessageBox.Show(this, "文件夹路径不能为空", "提示");
return "";
}
else
{
return FolderPath;
}
}
return FolderPath;
}
catch (Exception e)
{
MessageBox.Show(e.Message + e.InnerException);
return "";
}
}
#endregion
二、获取每个CSV文档指定内容并展示在Datagridview控件上
此标题对应Button3控件 “生成在控件上”功能,
代码如下:
#region 生成在datagridview控件上
private void button3_Click(object sender, EventArgs e)
{
try
{
if (textBox1.Text == "")
{
MessageBox.Show("请导入文件夹");
}
else
{
dataGridView1.DataSource = null;
dt = new DataTable();
for (int i = 0; i < CSVALL.Length; i++)
{
SelectRowInTheCsv1(CSVALL[i], "时间", "姓名");
}
MessageBox.Show("生成成功");
quanDataLoad = 0;
}
}
catch (Exception)
{
MessageBox.Show("失败,有文件被占用/软件被占用");
}
}
string[] CSVALL;//是选中文件夹路径下所有CSV文件的文件名
int quanDataLoad = 0; //控制表头第一行增加次数,也就第一次需要(因为是标题)
DataTable dt = new DataTable();//用来存储数据
public void DataLoad(string[] data)
{
string[] columnName = { "入学时间", "姓名"};//列名
if (quanDataLoad == 0)
{
for (int i = 0; i < columnName.Length; i++)
{
dt.Columns.Add(columnName[i], typeof(string));
}
}
quanDataLoad++;
DataRow dr = dt.NewRow();
for (int j = 0; j < data.Length; j++)
{
dr[columnName[j]] = data[j].ToString();
}
dt.Rows.Add(dr);
dataGridView1.DataSource = dt;
dataGridView1.ReadOnly = true;
dataGridView1.DefaultCellStyle.Font = new Font("微软雅黑", 12, FontStyle.Bold);
dataGridView1.ClearSelection();//加载表格生成后,放在最后面,用于清除默认选中第一行
}
public void SelectRowInTheCsv1(string fileName, string time, string Name)
{
StreamReader sr = new StreamReader(fileName);
string[] readText = File.ReadAllLines(fileName);//逐行读取文件并标注行列
string targetRow = "";//目标行
List<string> newtargetRowArrOne = new List<string>();
List<string> newtargetRowArrTwo = new List<string>();
//查询时间所在行并获取时间
for (int i = 0; i < readText.Length; i++)
{
string[] strNew = readText[i].Split(new char[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries);
List<string> itemsList = new List<string>(strNew);
List<string> itemsListFind = itemsList.FindAll(
delegate (string item)
{
return
item.ToUpper().Contains(time);
}
);
string[] result = itemsListFind.ToArray();
if (result.Length != 0)
{
targetRow = readText[i+1];//读取“入学时间”行的下1行内容,所以这里i+1
string[] targetRowArr = targetRow.Split(',');
newtargetRowArrOne.Add(targetRowArr[0]);//targetRowArr[0]就是这行第一列的时间
targetRow = readText[i + 2];//读取目标行的下2行内容,所以这里i+2
targetRowArr = targetRow.Split(',');
newtargetRowArrTwo.Add(targetRowArr[0]);//targetRowArr[0]就是这行第一列的时间
}
sr.Close();
}
//查询姓名所在行并获取姓名
for (int i = 0; i < readText.Length; i++)
{
string[] strNew = readText[i].Split(new char[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries);
List<string> itemsList = new List<string>(strNew);
List<string> itemsListFind = itemsList.FindAll(
delegate (string item)
{
return
item.ToUpper().Contains(Name);
}
);
string[] result = itemsListFind.ToArray();
if (result.Length != 0)
{
targetRow = readText[i + 1];//读取“姓名”行的下1行内容,所以这里i+1
string[] targetRowArr = targetRow.Split(',');
newtargetRowArrOne.Add(targetRowArr[1]);//targetRowArr[1]就是这行第2列的姓名
targetRow = readText[i + 2];//读取“姓名”行的下2行内容,所以这里i+2
targetRowArr = targetRow.Split(',');
newtargetRowArrTwo.Add(targetRowArr[1]);//targetRowArr[1]就是这行第2列的姓名
string[] newtargetRowArrshuzu = String.Join(",", newtargetRowArrOne).Split(',');//转string数组
DataLoad(newtargetRowArrshuzu);
string[] newtargetRowArrshuzu2 = String.Join(",", newtargetRowArrTwo).Split(',');//转string数组
DataLoad(newtargetRowArrshuzu2);
}
sr.Close();
}
}
#endregion
三、保存datagridview内容为一个新的CSV文件
此标题对应Button1控件 “保存新CSV”功能,
代码如下:
#region 保存CSV文件功能
private void button1_Click(object sender, EventArgs e)
{
DataGridViewToExcel(dataGridView1);
}
//保存CSV
public void DataGridViewToExcel(DataGridView dgv)
{
//程序实例化SaveFileDialog控件,并对该控件相关参数进行设置
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "Execl files (*.csv)|*.csv";
dlg.FilterIndex = 0;
dlg.RestoreDirectory = true;
dlg.CreatePrompt = true;
dlg.Title = "保存为csv文件";
//以上过程也可以通过添加控件,再设置控件属性完成,此处用程序编写出来了,在移植时就可摆脱控件的限制
if (dlg.ShowDialog() == DialogResult.OK)//打开SaveFileDialog控件,判断返回值结果
{
Stream myStream;//流变量
myStream = dlg.OpenFile();//返回SaveFileDialog控件打开的文件,并将所选择的文件转化成流
StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(-0));//将选择的文件流生成写入流
string columnTitle = "";
try
{
//写入列标题
for (int i = 0; i < dgv.ColumnCount; i++)
{
if (i > 0)
{
columnTitle += ",";
}
columnTitle += dgv.Columns[i].HeaderText;//符号 , 的添加,在保存为Excel时就以 , 分成不同的列了
}
sw.WriteLine(columnTitle);//将内容写入文件流中
//写入列内容
for (int j = 0; j < dgv.Rows.Count; j++)
{
string columnValue = "";
for (int k = 0; k < dgv.Columns.Count; k++)
{
if (k > 0)
{
columnValue += ",";
}
if (dgv.Rows[j].Cells[k].Value == null)
columnValue += "";
else if (dgv.Rows[j].Cells[k].Value.ToString().Contains(","))
{
columnValue += "\"" + dgv.Rows[j].Cells[k].Value.ToString().Trim() + "\"";//将单元格中的,号转义成文本
}
else
{
columnValue += dgv.Rows[j].Cells[k].Value.ToString().Trim() + "\t";//\t 横向跳格
}
}//获得写入到列中的值
sw.WriteLine(columnValue);//将内容写入文件流中
}
sw.Close();//关闭写入流
myStream.Close();//关闭流变量
MessageBox.Show("导出表格成功!");
}
catch (Exception e)
{
MessageBox.Show("导出表格失败!");
}
finally
{
sw.Close();
myStream.Close();
}
}
else
{
MessageBox.Show("取消导出表格操作!");
}
}
#endregion
四、总结
主要掌握对应行内容如何获取 以及 在datagridview控件上显示对应行内容为主,理解之后就可以自己改代码,用到那些内容格式相同的CSV文档,有的项目和实例,生成的CSV其实格式都大差不差,只有内容不一样,所以也可以用到这些项目实例去批量导出自己要的CSV内容。
完整代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CSDNCsvDatagridview
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
#region 生成在datagridview控件上
private void button3_Click(object sender, EventArgs e)
{
try
{
if (textBox1.Text == "")
{
MessageBox.Show("请导入文件夹");
}
else
{
dataGridView1.DataSource = null;
dt = new DataTable();
for (int i = 0; i < CSVALL.Length; i++)
{
SelectRowInTheCsv1(CSVALL[i], "时间", "姓名");
}
MessageBox.Show("生成成功");
quanDataLoad = 0;
}
}
catch (Exception)
{
MessageBox.Show("失败,有文件被占用/软件被占用");
}
}
string[] CSVALL;//是选中文件夹路径下所有CSV文件的文件名
int quanDataLoad = 0; //控制表头第一行增加次数,也就第一次需要(因为是标题)
DataTable dt = new DataTable();//用来存储数据
public void DataLoad(string[] data)
{
string[] columnName = { "入学时间", "姓名" };//列名
if (quanDataLoad == 0)
{
for (int i = 0; i < columnName.Length; i++)
{
dt.Columns.Add(columnName[i], typeof(string));
}
}
quanDataLoad++;
DataRow dr = dt.NewRow();
for (int j = 0; j < data.Length; j++)
{
dr[columnName[j]] = data[j].ToString();
}
dt.Rows.Add(dr);
dataGridView1.DataSource = dt;
dataGridView1.ReadOnly = true;
dataGridView1.DefaultCellStyle.Font = new Font("微软雅黑", 12, FontStyle.Bold);
dataGridView1.ClearSelection();//加载表格生成后,放在最后面,用于清除默认选中第一行
}
public void SelectRowInTheCsv1(string fileName, string time, string Name)
{
StreamReader sr = new StreamReader(fileName);
string[] readText = File.ReadAllLines(fileName);//逐行读取文件并标注行列
string targetRow = "";//目标行
List<string> newtargetRowArrOne = new List<string>();
List<string> newtargetRowArrTwo = new List<string>();
//查询时间所在行并获取时间
for (int i = 0; i < readText.Length; i++)
{
string[] strNew = readText[i].Split(new char[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries);
List<string> itemsList = new List<string>(strNew);
List<string> itemsListFind = itemsList.FindAll(
delegate (string item)
{
return
item.ToUpper().Contains(time);
}
);
string[] result = itemsListFind.ToArray();
if (result.Length != 0)
{
targetRow = readText[i + 1];//读取“入学时间”行的下1行内容,所以这里i+1
string[] targetRowArr = targetRow.Split(',');
newtargetRowArrOne.Add(targetRowArr[0]);//targetRowArr[0]就是这行第一列的时间
targetRow = readText[i + 2];//读取目标行的下2行内容,所以这里i+2
targetRowArr = targetRow.Split(',');
newtargetRowArrTwo.Add(targetRowArr[0]);//targetRowArr[0]就是这行第一列的时间
}
sr.Close();
}
//查询姓名所在行并获取姓名
for (int i = 0; i < readText.Length; i++)
{
string[] strNew = readText[i].Split(new char[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries);
List<string> itemsList = new List<string>(strNew);
List<string> itemsListFind = itemsList.FindAll(
delegate (string item)
{
return
item.ToUpper().Contains(Name);
}
);
string[] result = itemsListFind.ToArray();
if (result.Length != 0)
{
targetRow = readText[i + 1];//读取“姓名”行的下1行内容,所以这里i+1
string[] targetRowArr = targetRow.Split(',');
newtargetRowArrOne.Add(targetRowArr[1]);//targetRowArr[1]就是这行第2列的姓名
targetRow = readText[i + 2];//读取“姓名”行的下2行内容,所以这里i+2
targetRowArr = targetRow.Split(',');
newtargetRowArrTwo.Add(targetRowArr[1]);//targetRowArr[1]就是这行第2列的姓名
string[] newtargetRowArrshuzu = String.Join(",", newtargetRowArrOne).Split(',');//转string数组
DataLoad(newtargetRowArrshuzu);
string[] newtargetRowArrshuzu2 = String.Join(",", newtargetRowArrTwo).Split(',');//转string数组
DataLoad(newtargetRowArrshuzu2);
}
sr.Close();
}
}
#endregion
#region 导入文件夹功能
private void button2_Click(object sender, EventArgs e)
{
try
{
GetFolderPath(textBox1.Text);
string filepath = textBox1.Text;
var rel = Directory.GetFiles(filepath, "*", SearchOption.AllDirectories).ToList();
List<string> Filee = new List<string>();
foreach (var file in rel)
{
//Console.WriteLine(file);
Filee.Add(file);
}
string[] newtargetRowArrCSVname = String.Join(",", Filee).Split(',');//转string数组
CSVALL = newtargetRowArrCSVname;
}
catch (Exception)
{
MessageBox.Show("请选择路径");
//throw;
}
}
/// <summary>
/// 获取文件夹路径
/// </summary>
/// <param name="HistoryPath">历史路径,可以在弹出选择路径前选定此路径,当然也可以不用设置</param>
/// <returns></returns>
private string GetFolderPath(string HistoryPath)
{
try
{
string FolderPath = "";
FolderBrowserDialog Dialog = new FolderBrowserDialog();
Dialog.Description = "请选择文件路径";
if (!string.IsNullOrWhiteSpace(HistoryPath)) Dialog.SelectedPath = HistoryPath;
//Dialog.RootFolder = Environment.SpecialFolder.Programs;
if (Dialog.ShowDialog() == DialogResult.OK)
{
FolderPath = Dialog.SelectedPath;
textBox1.Text = FolderPath;
if (string.IsNullOrWhiteSpace(FolderPath))
{
MessageBox.Show(this, "文件夹路径不能为空", "提示");
return "";
}
else
{
return FolderPath;
}
}
return FolderPath;
}
catch (Exception e)
{
MessageBox.Show(e.Message + e.InnerException);
return "";
}
}
#endregion
#region 保存CSV文件功能
private void button1_Click(object sender, EventArgs e)
{
DataGridViewToExcel(dataGridView1);
}
//保存CSV
public void DataGridViewToExcel(DataGridView dgv)
{
//程序实例化SaveFileDialog控件,并对该控件相关参数进行设置
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "Execl files (*.csv)|*.csv";
dlg.FilterIndex = 0;
dlg.RestoreDirectory = true;
dlg.CreatePrompt = true;
dlg.Title = "保存为csv文件";
//以上过程也可以通过添加控件,再设置控件属性完成,此处用程序编写出来了,在移植时就可摆脱控件的限制
if (dlg.ShowDialog() == DialogResult.OK)//打开SaveFileDialog控件,判断返回值结果
{
Stream myStream;//流变量
myStream = dlg.OpenFile();//返回SaveFileDialog控件打开的文件,并将所选择的文件转化成流
StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(-0));//将选择的文件流生成写入流
string columnTitle = "";
try
{
//写入列标题
for (int i = 0; i < dgv.ColumnCount; i++)
{
if (i > 0)
{
columnTitle += ",";
}
columnTitle += dgv.Columns[i].HeaderText;//符号 , 的添加,在保存为Excel时就以 , 分成不同的列了
}
sw.WriteLine(columnTitle);//将内容写入文件流中
//写入列内容
for (int j = 0; j < dgv.Rows.Count; j++)
{
string columnValue = "";
for (int k = 0; k < dgv.Columns.Count; k++)
{
if (k > 0)
{
columnValue += ",";
}
if (dgv.Rows[j].Cells[k].Value == null)
columnValue += "";
else if (dgv.Rows[j].Cells[k].Value.ToString().Contains(","))
{
columnValue += "\"" + dgv.Rows[j].Cells[k].Value.ToString().Trim() + "\"";//将单元格中的,号转义成文本
}
else
{
columnValue += dgv.Rows[j].Cells[k].Value.ToString().Trim() + "\t";//\t 横向跳格
}
}//获得写入到列中的值
sw.WriteLine(columnValue);//将内容写入文件流中
}
sw.Close();//关闭写入流
myStream.Close();//关闭流变量
MessageBox.Show("导出表格成功!");
}
catch (Exception e)
{
MessageBox.Show("导出表格失败!");
}
finally
{
sw.Close();
myStream.Close();
}
}
else
{
MessageBox.Show("取消导出表格操作!");
}
}
#endregion
}
}
希望对你有帮助,感谢观看。