在我这次所从事的编程练习中需要读取Excel表格中的数据。一开始,我使用连接数据库的方法,进行表格数据的读取(以文本方式),数据读取没有问题。但随着练习难度的加大,发现使用连接数据库的方式打开表格具有很大的局限性,例如在我的练习中,我需要C#平台为X64,而不是X86,当我使用X64平台打开Excel文件时,就会报错,如下图所示:
代码如下:
private DataSet getData()
{
OpenFileDialog file = new OpenFileDialog();//实例化file
file.Filter = "Excel(*.xlsx)|*.xlsx|Excel(*.xls)|*.xls";//指定打开文件的类型为EXCEL文件
file.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
file.Multiselect = false;//每次打开一个EXCEL文件
if (file.ShowDialog() == DialogResult.Cancel)
return null;
string fileSuffix = System.IO.Path.GetExtension(path);
if (string.IsNullOrEmpty(fileSuffix))
return null;
using (ds)
{
//判断Excel文件是2003版本还是2007版本
string connString = "";
if (fileSuffix == ".xls")
{
connString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + path + ";" + ";Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1\"";
}
else
{
connString = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + path + ";" + ";Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"";
}
//读取文件
string sql_select = " SELECT * FROM [Sheet1$]";//读取sheet1
//string sql_select = " SELECT * FROM [Sheet2$]";//读取sheet2
using (OleDbConnection conn = new OleDbConnection(connString))
using (OleDbDataAdapter cmd = new OleDbDataAdapter(sql_select, conn))
{
conn.Open();
cmd.Fill(ds);
}
if (ds == null || ds.Tables.Count <= 0) return null;
return ds;
}
}
public void ARRAY()//将从EXCEl表格中得到的字符数据存到数组中
{
DataTable myT = getData().Tables[0];
myT.Dispose();
//mystr前面以定义string[,] mystr; float[]
//myT.Rows.Count;//datatable的行数
//myT.Columns.Count;//datatable的列数
mystr = new string[myT.Rows.Count, myT.Columns.Count];//新建数组用于存放datatable的数据
for (int i = 0; i <= myT.Rows.Count - 1; i++)//行循环
{
for (int j = 0; j <= myT.Columns.Count] - 1; j++)//列循环
{
if (myT.Rows[i][j].ToString() == null)
{
break;
}
else
{
mystr[i, j] = myT.Rows[i][j].ToString();//将datatable的值存入数组中
}
}
}
myT.Clear();
}
注:Excel表格内的数据尽量用文本型的,特别是读取时间,如06:11:11,代码在X86平台下使用没有问题
打开上图设置页的方式,点击C#界面>项目,选中下拉框中最后一个,打开后选择旁边的生成;如上图。当选中X64时,就无法打开Excel表格了。在这种情况下,我调了3天程序,一直以为是系统不兼容,应该找得到解决方案,结果解决方法都是安装AccessDatabaseEngine_X64的组件,或者将平台改成X86的。白白浪费了几天时间,今天一次偶然的机会,我同学给我推荐使用NPOI的方式去读取Excel表格。查阅了相关资料后,得到以下的代码,已经被我修改过,并且能够使用。
代码如下:
public DataTable ExcelToDataTable()
{
OpenFileDialog file = new OpenFileDialog();//实例化file
file.Filter = "Excel(*.xlsx)|*.xlsx|Excel(*.xls)|*.xls";//指定打开文件的类型为EXCEL文件
file.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
file.Multiselect = false;//每次打开一个EXCEL文件
if (file.ShowDialog() == DialogResult.Cancel)
{
ARRAY();
MessageBox.Show("请重新选择");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
string path = file.FileName;
int min = 100;
int max = 0;
for (int i = 0; i < path.Length; i++)
{
if (path[i] >= 0x4e00 && path[i] <= 0x9fbb)
{
max = i;
if (i <= min)
{
min = i;
}
}
}
path1 = path.Substring(min, max - min + 1);
string filePath = path;
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)
{
rowCount = sheet.LastRowNum;//总行数
if (rowCount > 0)
{
IRow firstRow = sheet.GetRow(0);//第一行
cellCount = firstRow.LastCellNum;//列数
ExcelCell = new string[rowCount, cellCount];
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;
ExcelCell[i, j] = (string)dataRow[j];
}
else
{
dataRow[j] = cell.NumericCellValue;
ExcelCell[i, j] = (string)dataRow[j];
}
break;
case CellType.String:
{
dataRow[j] = cell.StringCellValue;
ExcelCell[i, j] = (string)dataRow[j];
}
break;
}
}
}
dataTable.Rows.Add(dataRow);
}
}
}
}
}
return dataTable;
}
catch (Exception)
{
if (fs != null)
{
fs.Close();
}
return null;
}
}
public void ARRAY()//打开文件
{
DataTable myT = ExcelToDataTable();
}
有的需要在前面进行定义和相应控件的请自行添加,这里不备注了,请需要的进行添加使用。使用改代码之后,在X64平台下也可打开Excel表格。使用NPOI组件打开文件需要添加相应的dll文件,添加方法:点击项目>管理NuGet程序包,点击浏览进行搜索“NPOI”,下载即可。命名空间加上:
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
参考资料:https://www.cnblogs.com/shiyh/p/7478222.html
目前正在使用C#、matlab混合编程,今后还会对此进行适当的总结。