首先引入Execl NPOI程序集,百度上有的下载;
官网链接在此:NPOI官方下载地址
下载好之后,解压引入新建的项目程序中来:如图 我这里使用的WindowsForm应用程序 名称为NPOI_EXECL
然后再新建一个单独的类,因为考虑到可能封装跟扩展,新建类名为:ExeclHelper.cs
顾名思义为Execl帮助类;
接下来看代码,此类新鞋两个静态方法;一个是ExcelToDataTable(string filePath, bool isColumnName) 很明显 这是从execl文件导入数据到Datatable。另外一个为DataTableToExcel(DataTable dt,string Outpath),这是从现有的Datatable数据源中导出数据到Execl文件。
代码如下:
//==============================================================
// 作者:zhoupei
// 时间:2019/1/18 8:23:54
// 文件名:ExeclHelper
// 版本:V1.0.1
// 说明:读取Execl到DataGridviewer以及从程序导出数据到Execl
//==============================================================
///
/// Execl工具辅助类
///
public class ExeclHelper
{
///
/// 读取Execl数据到DataTable中
///
/// 指定Execl文件路径
/// 设置第一行是否是列名
/// 返回一个DataTable数据集
public static DataTable ExcelToDataTable(string filePath, bool isColumnName)
{
DataTable dataTable = null;
FileStream fs = null;
DataColumn column = null;
DataRow dataRow = null;
IWorkbook workbook = null;
ISheet sheet = null;
IRow row = null;
ICell cell = null;
int startRow = 0;
try
{
using (fs = File.OpenRead(filePath))
{
// 2007版本
if (filePath.IndexOf(".xlsx") > 0)
workbook = new XSSFWorkbook(fs);
// 2003版本
else if (filePath.IndexOf(".xls") > 0)
workbook = new HSSFWorkbook(fs);
if (workbook != null)
{
sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet
dataTable = new DataTable();
if (sheet != null)
{
int rowCount = sheet.LastRowNum;//总行数
if (rowCount > 0)
{
IRow firstRow = sheet.GetRow(0);//第一行
int cellCount = firstRow.LastCellNum;//列数
//构建datatable的列
if (isColumnName)
{
startRow = 1;//如果第一行是列名,则从第二行开始读取
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
cell = firstRow.GetCell(i);
if (cell != null)
{
if (cell.StringCellValue != null)
{
column = new DataColumn(cell.StringCellValue);
dataTable.Columns.Add(column);
}
}
}
}
else
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
column = new DataColumn("column" + (i + 1));
dataTable.Columns.Add(column);
}
}
//填充行
for (int i = startRow; i <= rowCount; ++i)
{
row = sheet.GetRow(i);
if (row == null) continue;
dataRow = dataTable.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
cell = row.GetCell(j);
if (cell == null)
{
dataRow[j] = "";
}
else
{
//CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)
switch (cell.CellType)
{
case CellType.Blank:
dataRow[j] = "";
break;
case CellType.Numeric:
short format = cell.CellStyle.DataFormat;
//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
if (format == 14 || format == 31 || format == 57 || format == 58)
dataRow[j] = cell.DateCellValue;
else
dataRow[j] = cell.NumericCellValue;
break;
case CellType.String:
dataRow[j] = cell.StringCellValue;
break;
}
}
}
dataTable.Rows.Add(dataRow);
}
}
}
}
}
return dataTable;
}
catch (Exception)
{
if (fs != null)
{
fs.Close();
}
return null;
}
}
///
/// 将DataTable导出到Execl文档
///
/// 传入一个DataTable数据集
/// 返回一个Bool类型的值,表示是否导出成功
/// True表示导出成功,Flase表示导出失败
public static bool DataTableToExcel(DataTable dt,string Outpath)
{
bool result = false;
IWorkbook workbook = null;
FileStream fs = null;
IRow row = null;
ISheet sheet = null;
ICell cell = null;
try
{
if (dt != null && dt.Rows.Count > 0)
{
workbook = new HSSFWorkbook();
sheet = workbook.CreateSheet("Sheet0");//创建一个名称为Sheet0的表
int rowCount = dt.Rows.Count;//行数
int columnCount = dt.Columns.Count;//列数
//设置列头
row = sheet.CreateRow(0);//excel第一行设为列头
for (int c = 0; c < columnCount; c++)
{
cell = row.CreateCell(c);
cell.SetCellValue(dt.Columns[c].ColumnName);
}
//设置每行每列的单元格,
for (int i = 0; i < rowCount; i++)
{
row = sheet.CreateRow(i + 1);
for (int j = 0; j < columnCount; j++)
{
cell = row.CreateCell(j);//excel第二行开始写入数据
cell.SetCellValue(dt.Rows[i][j].ToString());
}
}
//向outPath输出数据
using (fs = File.OpenWrite(Outpath))
{
workbook.Write(fs);//向打开的这个xls文件中写入数据
result = true;
}
}
return result;
}
catch (Exception ex)
{
if (fs != null)
{
fs.Close();
}
return false;
}
}
}
以上就是ExeclHelper类里的所有内容。
帮助类写好了,接下来就是引用了。
新建一个窗体,拖几个控件到窗体内。如图所示;
反正很简单啦!
导入之后的效果为: 此处我有用到一个Stopwatch()来计算过程所消耗的时间;可忽略;
接着把窗体下的代码贴出来; 如下
public Frm_For_Execl()
{
InitializeComponent();
}
///
/// 选择文件
///
///
///
private void lk_chioce_file_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "请选择Execl文件";
fdlg.InitialDirectory = @"c:\"; //@是取消转义字符的意思
fdlg.Filter = "Microsoft Excel files(*.xls)|*.xls;*.xlsx";
/*
* FilterIndex 属性用于选择了何种文件类型,缺省设置为0,系统取Filter属性设置第一项
* ,相当于FilterIndex 属性设置为1.如果编了3个文件类型,当FilterIndex =2时是指第2个.
*/
fdlg.FilterIndex = 2;
/*
*如果值为false,那么下一次选择文件的初始目录是上一次你选择的那个目录,
*不固定;如果值为true,每次打开这个对话框初始目录不随你的选择而改变,是固定的
*/
fdlg.RestoreDirectory = true;
if (fdlg.ShowDialog() == DialogResult.OK)
{
txtenterpath.Text = fdlg.FileName;
}
}
///
/// 定义计时器,计算导出导入所花费的时间
///
private Stopwatch stopwatch = new Stopwatch();
private void btn_toread_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtenterpath.Text.ToString().Trim()))
{
stopwatch.Start();
dgv_ExeclData.DataSource = ExeclHelper.ExcelToDataTable(txtenterpath.Text, true);
stopwatch.Stop();
MessageBox.Show("导入所花时间为: " + stopwatch.ElapsedMilliseconds + "ms");
}
else
{
MessageBox.Show("请选择路径!");
lk_chioce_file.Focus();
return;
}
}
///
/// 导出数据到指定路径
///
///
///
private void btn_toWrite_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtoutpath.Text) && dgv_ExeclData.Rows.Count > 0)
{
DataTable dt = dgv_ExeclData.DataSource as DataTable;
stopwatch.Restart();
bool flag = ExeclHelper.DataTableToExcel(dt,txtoutpath.Text.ToString().Trim());
if (flag)
{
stopwatch.Stop();
MessageBox.Show("导出成功!导出所花时间为: " + stopwatch.ElapsedMilliseconds + "ms");
return;
}
else
{
MessageBox.Show("导出失败,请检查!");
return;
}
}
else
{
MessageBox.Show("导出路径不能为空,或者数据源不能为空");
return;
}
}
///
/// 打开并保存数据到任意路径
///
///
///
private void lk_execl_out_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
SaveFileDialog SaveDialog = new SaveFileDialog();
SaveDialog.Filter = "Excel 文件(*.xls)|*.xls|Excel 文件(*.xlsx)|*.xlsx|所有文件(*.*)|*.*";
SaveDialog.FileName = System.DateTime.Now.ToString("yyyyMMddHHmmssfff") + "导出的execl数据";//设置默认文件名
SaveDialog.RestoreDirectory = true;
if (SaveDialog.ShowDialog() == DialogResult.OK)
{
txtoutpath.Text = SaveDialog.FileName;
}
}
导出的效果为:
Execl文件中的数据为以下:
一个Execl导入导出就完成了,本人亲测Execl_2016是OK的。如有问题请指正,有问题请反馈;也可加博主微信[zp2013822];留言讨论谢谢;
以上为本期全部内容,还请斧正,敬请谅解;