一、DataTable转List Json
DataTable是.NET中一个非常常用的数据类型。然而,当我们需要将DataTable转化成其他数据类型的时候,就需要考虑DataTable转化成List Json。下面我们就从以下几个方面来详细讲解如何完成转化过程。
1. 使用Json.net进行DataTable转换
using Newtonsoft.Json;
using System.Data;
using System.Web.Mvc;
public JsonResult GetJsonData()
{
DataTable dt = GetDataTable(); //获取DataTable数据
string json = JsonConvert.SerializeObject(dt); //DataTable转换成Json字符串
return Json(json, JsonRequestBehavior.AllowGet); // "AllowGet" 这个参数允许 Get 方式的HTTP请求.
}
从上面的代码中可以看出,我们通过Json.net这个类库中的SerializeObject()函数,很容易地将DataTable转化成了Json格式的字符串。需要注意的是,一定要在Controller层的函数中将返回类型设置成JsonResult类型,否则会引发异常。
2. 使用JavaScriptSerializer进行DataTable转换
using System.Web.Script.Serialization;
using System.Data;
using System.Web.Mvc;
public JsonResult GetJsonData()
{
DataTable dt = GetDataTable(); //获取DataTable数据
JavaScriptSerializer js = new JavaScriptSerializer();
string json = js.Serialize(dt); //DataTable转换成Json字符串
return Json(json, JsonRequestBehavior.AllowGet); // "AllowGet" 这个参数允许 Get 方式的HTTP请求.
}
我们也可以使用.NET自带的JavaScriptSerializer进行DataTable转换,它与Json.net类库差不多,只是Transform DataTable to List Json过程多了一步,需要先实例化一个JavaScriptSerializer类。
3. 优化DataTable转Json的性能
为了提高DataTable转换成List Json的性能,我们可以使用异步的方式进行数据转换。下面是代码的实现:
public async Task<JsonResult> GetJsonData()
{
DataTable dt = GetDataTable(); //获取DataTable数据
string json = string.Empty;
await Task.Factory.StartNew(() =>
{
json = JsonConvert.SerializeObject(dt); // DataTable转换成Json字符串
});
return Json(json, JsonRequestBehavior.AllowGet); // "AllowGet" 这个参数允许 Get 方式的HTTP请求.
}
通过在Controller层的函数中使用Task.Factory.StartNew()方法,我们就可以将数据转换和返回的Http响应分别挂起,从而达到提高程序性能的目的。
二、List转DataTable
除了将DataTable转成Json格式的字符串,还有一种常用的操作就是将List转成DataTable。那么,如何实现List转DataTable呢?下面我们就从以下几个方面详细介绍。
1. 将List元素插入到DataTable的行中
public static DataTable ToDataTable<T>(List<T> iList)
{
DataTable dataTable = new DataTable();
PropertyDescriptorCollection propertyDescriptorCollection = TypeDescriptor.GetProperties(typeof(T));
for (int i = 0; i < propertyDescriptorCollection.Count; i++)
{
PropertyDescriptor propertyDescriptor = propertyDescriptorCollection[i];
Type type = propertyDescriptor.PropertyType;
if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable)))
{
type = Nullable.GetUnderlyingType(type);
}
dataTable.Columns.Add(propertyDescriptor.Name, type);
}
object[] values = new object[propertyDescriptorCollection.Count];
foreach (T iListItem in iList)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = propertyDescriptorCollection[i].GetValue(iListItem);
}
dataTable.Rows.Add(values);
}
return dataTable;
}
通过定义ToDataTable()函数,我们可以将List转成DataTable,并且在其中逐一遍历List中的元素,将其插入到DataTable的每一行中,从而得到我们需要的结果。
2. 将List元素的属性作为DataTable的列
public static DataTable ToDataTable<T>(this IList<T> data)
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable)))
{
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType));
}
else
{
table.Columns.Add(prop.Name, prop.PropertyType);
}
}
object[] values = new object[props.Count];
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = props[i].GetValue(item);
}
table.Rows.Add(values);
}
return table;
}
通过重载ToDataTable()函数,我们就可以将List中元素的属性名作为DataTable的列名。这种方法在将List转成DataTable时非常有用。
三、DataTable转成List
DataTable直接转为List是我们常用到的方式之一。下面我们就从以下几个方面详细介绍如何实现DataTable转List操作。
1. 遍历每一行数据转成List元素
public static List<T> ToList<T>(this DataTable table) where T : class, new()
{
List<T> list = new List<T>();
foreach (DataRow row in table.Rows)
{
T item = new T();
foreach (DataColumn column in table.Columns)
{
PropertyInfo property = item.GetType().GetProperty(column.ColumnName);
if (property != null && row[column] != DBNull.Value)
{
property.SetValue(item, row[column], null);
}
}
list.Add(item);
}
return list;
}
将DataTable逐行遍历,将每一行数据转化成List元素,这是最为直接的方法。同时,在List中需要指定泛型参数类型T。
2. 使用Linq进行数据的筛选和过滤
public static List<T> ToList<T>(this DataTable table) where T : new()
{
List<T> result = new List<T>();
foreach (var row in table.AsEnumerable())
{
T item = new T();
foreach (var prop in item.GetType().GetProperties())
{
try
{
PropertyInfo propertyInfo = item.GetType().GetProperty(prop.Name);
object propertyValue = row[prop.Name];
if (propertyValue == null)
{
propertyValue = DBNull.Value;
}
propertyInfo.SetValue(item, propertyValue, null);
}
catch (Exception ex)
{
continue;
}
}
result.Add(item);
}
return result;
}
我们还可以使用Linq进行筛选和过滤操作,将DataTable转换成指定泛型T的List。这种方式操作更为灵活,并可以直接通过Lambda表达式对数据进行操作。
四、DataTable转Sheet
DataTable转Sheet通常用于Excel表格的导出操作。下面我们就从以下几个方面详细介绍如何将DataTable转成Sheet。
1. 使用NPOI库转换成Sheet
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.IO;
public ActionResult ExportExcel()
{
DataTable dt = GetDataTable(); //获取DataTable数据
HSSFWorkbook workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet("sheet1");
IRow headerRow = sheet.CreateRow(0);
for (int i = 0; i < dt.Columns.Count; i++)
headerRow.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
for (int i = 0; i < dt.Rows.Count; i++)
{
IRow row = sheet.CreateRow(i + 1);
for (int j = 0; j < dt.Columns.Count; j++)
row.CreateCell(j).SetCellValue(dt.Rows[i][j].ToString());
}
MemoryStream ms = new MemoryStream();
workbook.Write(ms);
Response.BinaryWrite(ms.ToArray());
Response.End();
return View();
}
这里使用NPOI库来将DataTable转成Sheet,主要用到了HSSFWorkbook和ISheet两个类。NPOI库是.NET中操作Excel的最好选择之一。
2. 使用EPPlus库转换成Sheet
using OfficeOpenXml;
using System.Web.Mvc;
using System.IO;
public void ExportExcel()
{
List<MyObj> myList = new List<MyObj>();
DataTable dt = myList.ToDataTable();
byte[] fileContents;
using (var package = new ExcelPackage())
{
// Add a new worksheet to the empty workbook
ExcelWorksheet worksheet = null;
worksheet = package.Workbook.Worksheets.Add("sheet1");
worksheet.Cells[1, 1].LoadFromDataTable(dt, true);
fileContents = package.GetAsByteArray();
}
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", "MyExcel.xlsx"));
Response.OutputStream.Write(fileContents, 0, fileContents.Length);
Response.OutputStream.Flush();
Response.OutputStream.Close();
Response.End();
}
使用EPPlus库将DataTable转成Sheet非常方便。EPPlus基于Open XML标准,支持新的Excel格式,并且速度快,使用方便。
五、Dataframe转List
Dataframe是pandas库中的常用数据类型,通常需要将其转成List,以方便后续操作。以下是如何将Dataframe转成List的几种方法。
1. 使用values属性转换成List
import pandas as pd
import numpy as np
df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
list1 = df.values.tolist()
print(list1)
使用pandas库中的values属性,可以将Dataframe转成List。Cpandas库的values属性是将值以数组形式返回,然后变成List。
2. 使用to_dict()方法将Dataframe转成List
import pandas as pd
import numpy as np
df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
dict1 = df.to_dict('records')
print(dict1)
利用pandas库中的to_dict()方法,可以将Dataframe转成字典形式,然后再以字典形式返回List。
3. 合并列名和数据,并将Dataframe转为List
import pandas as pd
import numpy as np
df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
result = []
for col in df.columns:
values = df[col].values
col_values = [{col: value} for value in values]
for i in range(len(col_values)):
if len(result) <= i:
result.append({})
result[i].update(col_values[i])
list1 = []
for item in result:
row = []
for col in df.columns:
row.append(item[col])
list1.append(row)
print(list1)
通过合并列名和数据两个属性,然后将Dataframe转化成List。这种方法较为麻烦,但是可以准确地实现Goal。
六、DataTable转String
将DataTable转成String,是我们在后端计算和前端展示时常用的操作。下面我们就从如下几个方面详细讲解如何将DataTable转成String。
1. 拼接字符串输出
private static string DataTable2String(DataTable dt)
{
string result = string.Empty;
for (int i = 0; i < dt.Rows.Count; i++)
{
result += dt.Rows[i]["ColumnName