《C#常用工具类》--01.DataTable读写,Excel读写使用详解

本文详细介绍了C#中DataTable的初始化、写操作(包括写入行、列和综合写入)及读操作(基本读、复杂读和select)。同时,讲解了Excel的读写方法,利用NPOI库进行数据交互,并强调了DataTable在复杂查询中的应用。


提示:以下是本篇文章正文内容,下面案例可供参考

一、简介

一种与数据库表结构,和Excel表结构类型非常相似的常用工具类,常用与excel文件读写

二、初始化

注意有一个DataSet是用来存多个DataTable的

//1.直接创建
public DataTable();
//2.创建对象并声明一个别名,如果用到多个DataTable时建议使用
DataTable(string tableName);
//3.创建对象并使用命名空间来区分
public DataTable(string tableName, string tableNamespace)

三.DataTable写操作

如果要写入到dataTable中一个cell的值,必须要行和列都创建之后使用

写入行

DataTable dt = new DataTable();
//方式一
//1.1 创建一行,返回值就是当前创建的行对象
DataRow row1 = dt.NewRow();
//1.2 但是当前表格中并没有此行,需要手动加入
Console.WriteLine($"当前行数{dt.Rows.Count}");
dt.Rows.Add(row1);
Console.WriteLine($"当前行数{dt.Rows.Count}");

//方式二
//2.创建一行,并直接加入到dt中,返回当前行对象
DataRow row2 = dt.Rows.Add();
Console.WriteLine($"当前行数{dt.Rows.Count}");

//方式三
//3. 创建一行,并直接加入到dt中,并直接写入当前行的值
/**  注意此方式,如果没有创建列,是不能写入值的,值是存在cell格子里的,
 *cell格子就包含了行和列两个方向
 */
//DataRow row3 = dt.Rows.Add(new int[] { 1, 2, 3 });
//Console.WriteLine($"当前行数{dt.Rows.Count}");

//方式四
//插入一行,会把当前位置上的行往后移一位;
//如果插入位置大于当前指向的最大位置,会忽略自定义的位置,
//相当于默认插入按序插入一行,与dt.Rows.Add();用法一样
DataRow row4 = dt.NewRow();
dt.Rows.InsertAt(row4, 12);
int row1_index = dt.Rows.IndexOf(row1);
int row4_index = dt.Rows.IndexOf(row4);
Console.WriteLine(row1_index+"---"+ row4_index);

写入列

//方式一
DataColumn col1 = new DataColumn();
Console.WriteLine($"当前列数{dt.Columns.Count}");
dt.Columns.Add(col1);
Console.WriteLine($"当前列数{dt.Columns.Count}");

//方式二:创建后自动加入表格列中
DataColumn col2 = dt.Columns.Add();
//给某一列添加公式
DataColumn col3 = dt.Columns.Add("sum",typeof(int),"excel里面的公式");

//指定这一列的别名,方便我们后续插入cell值时,进行
DataColumn col3 = dt.Columns.Add("name");

综合写入

//方式一:写入值到某个cell单元格
row1[0] = "xzp";
row1["name"] = "xzp";

//方式二:遍历写入值,行下标,列别名赋值
foreach (var item in dt.Rows)
{
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        (item as DataRow)[i] = 12;
    }
}

//方式三:遍历写入值,行下标,列下标赋值
for (int i = 0; i < dt.Rows.Count; i++)
{
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        //循环遍历赋值
        dt.Rows[i][j] = "xxxx";
    }
}

四、DataTable读操作

如果要读到dataTable中一个cell的值,必须要确切直到行列的下标或别名信息
读写操作大体上非常相似

基本读

注意,如果你拿到了列对象,你是取不出信息的,但是如果你拿到行对象是可以取出数据的

//方式一:确定直到读某个cell
string v1 = dt.Rows[1][0].ToString();
string v2 = dt.Rows[1]["name"].ToString();
Console.WriteLine(v1+"------"+v2);

//方式二:遍历读,行下标,列别名
foreach (var item in dt.Rows)
{
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        string val = (item as DataRow)[i].ToString();
    }
}

//方式三:遍历写入值,行下标,列下标赋值
for (int i = 0; i < dt.Rows.Count; i++)
{
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        //循环遍历赋值
        string val=dt.Rows[i][j];
    }
}

复杂读

1)需求:查找数据DataTable中包含xxx的内容,将这些值信息存储起来返回。

public static Dictionary<string,string> getSumDataTable(DataTable dt,string search)
{
    var result=new Dictionary<string, string>();
    if (dt != null)
    {
        for (int i = 0; i < dt.Rows.Count; i++)
        {
           
            DataRow dataRow = dt.Rows[i];
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                if (dataRow[j].ToString().Contains("search"))
                {
                    result.Add(dt.Columns[j].ColumnName, dataRow[j].ToString());
                }
            }
        }
    }
    return result;
}

2)需求:读取DataTable中列名包含sum的字段,例如monthSum,yearSum,并返回到一个新的dataTable

public static DataTable getSumDataTable(DataTable dt)
{
    DataTable result = new DataTable();
    if(dt != null)
    {
        foreach (var item in dt.Columns)
        {
            if ((item as DataColumn).ColumnName.Contains("sum")) result.Columns.Add(item as DataColumn); 
        }
    }
    result.Rows.Add(dt.Rows);
    return result;
}

select

select方法在一些复杂的场景作用非常大,可以进行快速的查询,查询语法与SQL语法一致,也可以设置主键,设置主键时,优先从主键开始查询。

DataTable dt = new DataTable();
dt.Columns.Add("name");
dt.Columns.Add("age");
dt.Columns.Add("id");
dt.Rows.Add(new string[] { "xzp01", "15", "A0122ASA311" });
dt.Rows.Add(new string[] { "xzp02", "63", "A0AWQ131121" });
dt.Rows.Add(new string[] { "xz1p03", "42", "A0ASDA1SD121" });
dt.Rows.Add(new string[] { "xzp324", "52", "A0ASDSA12211" });

//可以设置主键
dt.PrimaryKey = new DataColumn[] { col3 };

//1.查询所有
DataRow[] dataRows1 = dt.Select();
DataRow[] dataRows2 = dt.Select("");
//2.条件查询
DataRow[] dataRows3 = dt.Select("name='xzp01'");
//3.模糊查询
DataRow[] dataRows4 = dt.Select("name like '%xzp0%'");
//4.多条件查询,
DataRow[] dataRows5 = dt.Select("name like '%xzp0%' and age='23'","age");
//5.并排序,第二个参数就是排序的字段名称
DataRow[] dataRows6 = dt.Select("","age");

五、excel读写

1)NPOI读取Excel
此处使用到POI第三方工具类,也可以转换成DataTable,但是没必要,轮子造好了,用法也很简单

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
public void ReadFromExcelFile(string filePath)
{
    IWorkbook wk = null;
    string extension = System.IO.Path.GetExtension(filePath);
    try
    {
        FileStream fs = File.OpenRead(filePath);
        if (extension.Equals(".xls"))
        {
            //把xls文件中的数据写入wk中
            wk = new HSSFWorkbook(fs);
        }
        else
        {
            //把xlsx文件中的数据写入wk中
            wk = new XSSFWorkbook(fs);
        }

        fs.Close();
        //读取当前表数据
        ISheet sheet = wk.GetSheetAt(0);

        IRow row = sheet.GetRow(0);  //读取当前行数据
        //LastRowNum 是当前表的总行数-1(注意)
        int offset = 0;
        for (int i = 0; i <= sheet.LastRowNum; i++)
        {
            row = sheet.GetRow(i);  //读取当前行数据
            if (row != null)
            {
                //LastCellNum 是当前行的总列数
                for (int j = 0; j < row.LastCellNum; j++)
                {
                    //读取该行的第j列数据
                    string value = row.GetCell(j).ToString();
                    Console.Write(value.ToString() + " ");
                }
                Console.WriteLine("\n");
            }
        }
    }
    
    catch (Exception e)
    {
        //只在Debug模式下才输出
        Console.WriteLine(e.Message);
    }
}

2)如果需要转换Datable,就是遍历存入DataTable就行了,注意第一行就是ColumnName

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
public void WriteFromDataTable(DataTable dt,string filePath)
{
    IWorkbook wk = null;
    string extension = Path.GetExtension(filePath);
    try
    {
        if (extension.Equals(".xls"))
        {
            //把xls文件中的数据写入wk中
            wk = new HSSFWorkbook();
        }
        else
        {
            //把xlsx文件中的数据写入wk中
            wk = new XSSFWorkbook();
        }
        ISheet sheet = wk.CreateSheet();

        //1.第一行是字段名
        IRow headerRow = sheet.CreateRow(0);
        foreach (DataColumn column in dt.Columns)
        {
            ICell headerCell = headerRow.CreateCell(column.Ordinal);//列的下标,使用for就不需要这样写
            headerCell.SetCellValue(column.ColumnName);
            sheet.AutoSizeColumn(headerCell.ColumnIndex);
        }
        for (int i = 1; i < dt.Rows.Count; i++)
        {
            IRow row = sheet.CreateRow(i);
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                ICell cell = row.CreateCell(j);
                //如果为null的判断
                cell.SetCellValue((dt.Rows[i][j]??"").ToString());
            }
        }
        FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
        wk.Write(fs);
        fs.Dispose();

        //释放内存
        sheet = null;
        headerRow = null;
        wk = null;
    }
    catch(Exception e)
    {
        throw new Exception(e.Message);
    }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值