C#DataTable操作技巧

1 数据列操作

1.1 向指定位置添加列

	/*
	 * dt数据列结构(dt的结构为:姓名,班级,成绩)
	 * 添加序号列,列序号为:0
	 * 操作结果:dt的结构为:序号,姓名,班级,成绩
	 */
	dt.Columns.Add("序号").SetOrdinal(0);

2.1 移动指定列的位置(数据跟随移动)

	/*
	 * dt数据列结构(dt的结构为:序号,姓名,班级,成绩)
	 * 移动列:成绩 => 班级前
	 * 移动结果:dt的结构为:序号,姓名,成绩,班级
	 */
	 dt.Columns["成绩"].SetOrdinal(2);

2 数据获取

2.1 获取数据列

   //数据“ID”列转为List集合:列名:ID 数据类型:int  转换为:List
   List<int> lstByIndex = dt.AsEnumerable().Select(it => it.Field<int>(0)).ToList();
   List<int> lstByName = dt.AsEnumerable().Select(it => it.Field<int>("ID")).ToList();

   //数据“value”列转为数组:列名:value 数据类型:string  转换为:double数组  
   double[] dArray = dt.AsEnumerable().Select(d => Convert.ToDouble(d.Field<string>("value"))).ToArray();

2.2 获取数据行

   List<object> lstObj = dt.Rows[0].ItemArray.ToList();

3 添加表2(结构和数据)至表1

   /// 
   /// 合并表(向表1增加表2的结构和数据)
   /// 
   /// 表1
   /// 表2
   private DataTable MergeTable(DataTable t1, DataTable t2)
   {
       try
       {
           //向表1添加表2数据列结构
           foreach (DataColumn col in t2.Columns)
           {
               t1.Columns.Add(col);
           }

           //向表1添加表2中的而所有列的数据
           int nCountT2 = t2.Rows.Count;      //获取表2总行数
           int firstCell = t1.Columns.Count;   //获取表的总列数
           int secondCell = t2.Columns.Count;   //获取表2的总列数

           //控制行循环
           for (int i = 0; i < nCountT2; i++)
           {
               //控制列循环
               for (int j = 0; j < secondCell; j++)
               { 
                   t1.Rows[i][firstCell + j] = t2.Rows[i][j];
               }
           }

           return t1;
       }
       catch(Exception ex)
       {
           throw new Exception(ex.Message);
       }
   }

4. DataTable => Excle之NPOI

4.1 添加NPOI

① 在打开的C#项目中,右击项目名称→管理Nuget程序包(N)→等待加载完成→在“搜索联机”中搜索NPOI→点击安装→等待安装完成,

② 包管理器无法使用时,直接在项目中添加引用—浏览NPOI的dll文件—添加

注:NPOI的dll文件可从其他项目中copy

4.2 单表导出

/// 
/// 导出单个DataTable→Excel
/// 
/// DataTable对象
/// 接收Excel的sheet的名称
/// 接收文件名
/// 导入数据行数(包含列名那一行)
public int DataTableToExcel(DataTable data, string sheetName, string filename)
{
    int count = 0;//控制返回状态,以及标记导出数据行
    IWorkbook workbook = null;
    FileStream fs = null;//创建文件流对象
    ISheet sheet = null;//工作表对象
    bool isColumnWritten = true;//设置列名是否导入

    #region 打开保存文件对话框,设置对话框属性,导出数据
    SaveFileDialog dialog = new SaveFileDialog();//创建保存文件对象
    dialog.Title = "请选择文件保存路径";//打开文件对话框标题设置为:请选择文件保存路径
    dialog.Filter = "Excel(*.xls)|*.xls|Excel(*.xlsx)|*.xlsx";//只显示Excel文件
    dialog.FileName = filename;//传入默认文件名(已经设置好的文件名)
    if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) //打开文件对话框,点击确定时运行以下代码
    {
        filename = dialog.FileName;//接收重新命名的文件名

        #region 设置工作部数据,导出数据,确定文件导出状态
        try
        {
            fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite);//文件流对象实例化,传入文件保存全路径,文件打开权限,文件读写权限

            #region 1.创建工作薄
            if (filename.IndexOf(".xlsx") > 0) // 2007版本(判断文件路径中是否包含".xlsx",确定为Excel那个版本)
                workbook = new XSSFWorkbook();
            else if (filename.IndexOf(".xls") > 0) // 2003版本(判断文件路径中是否包含".xlsx",确定为Excel那个版本)
                workbook = new HSSFWorkbook();
            #endregion

            #region 2.创建工作表
            if (workbook != null)//工作簿是否创建成功?创建工作表:返回(三目运算表达)
            {
                sheet = workbook.CreateSheet(sheetName);//传入工作表名称,并创建工作表
            }
            else
            {
                return -1;//返回值为-1时,则表示导出失败
            }
            #endregion

            #region 3.导出列名
            if (isColumnWritten) //控制列名是否导出bool对象:isColumnWritten
            {
                IRow row = sheet.CreateRow(0);//创建一行数据
                for (int j = 0; j < data.Columns.Count; j++)//
                {
                    row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
                }
                count = 1;
            }
            else
            {
                count = 0;
            }
            #endregion

            #region 4.设置导出文件的列宽
            for (int columnWidth = 0; columnWidth < 10; columnWidth++)
            {
                sheet.SetColumnWidth(columnWidth, 15 * 256);
            }
            #endregion

            #region 5.导出数据
            Type type;//创建保存数据类型对象

            //创建CellStyle与DataFormat并加载格式样式
            IDataFormat dataformat = workbook.CreateDataFormat();
            ICellStyle style = workbook.CreateCellStyle();
            //style.DataFormat = dataformat.GetFormat("0.00"); //改变小数精度【小数点后有几个0表示精确到小数点后几位】  

            // 循环数据表行
            for (int i = 0; i < data.Rows.Count; i++)
            {

                IRow row = sheet.CreateRow(count);
                row.Height = 20 * 20;//设置行高

                #region 循环导出数据列
                for (int j = 0; j < data.Columns.Count; j++)//
                {
                    try
                    {
                        type = data.Rows[i][j].GetType();//获取数据类型
                        //Debug.WriteLine(type);//打印数据类型

                        #region 根据当前单元格数据类型写入数据
                        if (type == typeof(string))
                        {
                            row.CreateCell(j).SetCellValue(Convert.ToDouble(data.Rows[i][j]));
                        }
                        else if (type == typeof(int))
                        {
                            row.CreateCell(j).SetCellValue(Convert.ToInt32(data.Rows[i][j]));
                        }
                        else if (type == typeof(double))
                        {
                            row.CreateCell(j).SetCellValue(Math.Round(Convert.ToDouble(data.Rows[i][j]), 4));
                        }
                        else if (type == typeof(Single))
                        {
                            row.CreateCell(j).SetCellValue(Math.Round(Convert.ToSingle(data.Rows[i][j]), 4));
                        }
                        else
                        {
                            row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
                        }
                        #endregion

                    }
                    catch (Exception)
                    {
                        //如果获取的数据类型出错则将数据对象转换为string类型导出
                        row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
                    }
                }
                #endregion

                ++count;
            }
            #endregion

            #region 6.将文件流对象写入Excel,释放文件权限资源,并返回
            workbook.Write(fs); //写入到excel
            fs.Dispose();//释放资源
            return count;
            #endregion
        }
        catch (Exception ex)
        {
            MessageBox.Show("导出文件时出错!\n", "提示");
            //Console.WriteLine("导出文件时出错,文件可能正被打开!\n" + ex.Message);
            return -1;
        }
        #endregion
    }
    else
        return -1;
    #endregion
}


4.3 多表导出

/// 
/// 导出多个DataTable→excel中
/// 
/// 要导入的数据
/// DataTable的列名是否要导入
/// 要导入的excel的sheet的名称
/// 获取文件路径
/// 导入数据行数(包含列名那一行)
/// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓多文件导出时,需借助↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
/// FolderBrowserDialog dilog = new FolderBrowserDialog();
/// dilog.Description = "请选择文件夹";
/// if (dilog.ShowDialog() == DialogResult.OK || dilog.ShowDialog() == DialogResult.Yes)//当选中文件并点击确定时运行
/// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓多文件导出时,需借助↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
public int DataTableToExcel1(DataTable data, string sheetName, string filePath)
{
    int count = 0;//控制返回状态,以及标记导出数据行
    IWorkbook workbook = null;
    FileStream fs = null;//创建文件流对象
    ISheet sheet = null;//工作表对象
    bool isColumnWritten = true;//设置列名是否导入

    #region DataTable→Excel
    try
    {
        fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);//文件流对象实例化,传入文件保存全路径,文件打开权限,文件读写权限

        #region 1.建立空的工作薄
        if (filePath.IndexOf(".xlsx") > 0) // 2007版本(判断文件路径中是否包含".xlsx",确定为Excel那个版本)
            workbook = new XSSFWorkbook();
        else if (filePath.IndexOf(".xls") > 0) // 2003版本(判断文件路径中是否包含".xlsx",确定为Excel那个版本)
            workbook = new HSSFWorkbook();
        #endregion

        #region 2.创建工作表
        if (workbook != null)//工作簿是否创建成功?创建工作表:返回(三目运算表达)
        {
            sheet = workbook.CreateSheet(sheetName);//传入工作表名称,并创建工作表
        }
        else
        {
            return -1;//返回值为-1时,则表示导出失败
        }
        #endregion

        #region 3.导出列名
        if (isColumnWritten) //控制列名是否导出bool对象:isColumnWritten
        {
            IRow row = sheet.CreateRow(0);//创建一行数据
            for (int j = 0; j < data.Columns.Count; j++)//
            {
                row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
            }
            count = 1;
        }
        else
        {
            count = 0;
        }
        #endregion

        #region 4.设置导出文件的列宽
        for (int columnWidth = 0; columnWidth < 10; columnWidth++)
        {
            sheet.SetColumnWidth(columnWidth, 15 * 256);
        }
        #endregion

        #region 5.导出数据
        Type type;//创建保存数据类型对象

        //创建CellStyle与DataFormat并加载格式样式
        IDataFormat dataformat = workbook.CreateDataFormat();
        ICellStyle style = workbook.CreateCellStyle();
        //style.DataFormat = dataformat.GetFormat("0.00"); //改变小数精度【小数点后有几个0表示精确到小数点后几位】  

        // 循环数据表行
        for (int i = 0; i < data.Rows.Count; i++)
        {

            IRow row = sheet.CreateRow(count);
            row.Height = 20 * 20;//设置行高

            #region 循环导出数据列
            for (int j = 0; j < data.Columns.Count; j++)//
            {
                try
                {
                    type = data.Rows[i][j].GetType();//获取数据类型
                    Debug.WriteLine(type);

                    #region 根据当前单元格数据类型写入数据
                    if (type == typeof(string))
                    {
                        row.CreateCell(j).SetCellValue(Convert.ToDouble(data.Rows[i][j]));
                    }
                    else if (type == typeof(int))
                    {
                        row.CreateCell(j).SetCellValue(Convert.ToInt32(data.Rows[i][j]));
                    }
                    else if (type == typeof(double))
                    {
                        row.CreateCell(j).SetCellValue(Math.Round(Convert.ToDouble(data.Rows[i][j]), 4));
                    }
                    else if (type == typeof(Single))
                    {
                        row.CreateCell(j).SetCellValue(Math.Round(Convert.ToSingle(data.Rows[i][j]), 4));
                    }
                    else
                    {
                        row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
                    }
                    #endregion

                }
                catch (Exception)
                {
                    //如果获取的数据类型出错则将数据对象转换为string类型导出
                    row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
                }
            }
            #endregion

            ++count;
        }
        #endregion

        #region 6.将文件流对象写入Excel,释放文件权限资源,并返回
        workbook.Write(fs); //写入到excel
        fs.Dispose();//释放资源
        return count;
        #endregion
    }
    catch (Exception ex)
    {
        MessageBox.Show("导出文件时出错!\n" + ex.Message, "提示");
        //Console.WriteLine("导出文件时出错,文件可能正被打开!\n" + ex.Message);
        return -1;
    }
    #endregion

}

你可能感兴趣的:(C#,c#)