/*
* dt数据列结构(dt的结构为:姓名,班级,成绩)
* 添加序号列,列序号为:0
* 操作结果:dt的结构为:序号,姓名,班级,成绩
*/
dt.Columns.Add("序号").SetOrdinal(0);
/*
* dt数据列结构(dt的结构为:序号,姓名,班级,成绩)
* 移动列:成绩 => 班级前
* 移动结果:dt的结构为:序号,姓名,成绩,班级
*/
dt.Columns["成绩"].SetOrdinal(2);
//数据“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();
List<object> lstObj = dt.Rows[0].ItemArray.ToList();
///
/// 合并表(向表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);
}
}
① 在打开的C#项目中,右击项目名称→管理Nuget程序包(N)→等待加载完成→在“搜索联机”中搜索NPOI→点击安装→等待安装完成,
② 包管理器无法使用时,直接在项目中添加引用—浏览NPOI的dll文件—添加
注:NPOI的dll文件可从其他项目中copy
///
/// 导出单个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
}
///
/// 导出多个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
}