在Windows窗体应用程序中加载Excel文件时,可以很好地加载.xls
和.xlsx
格式,但是当我选择.CSV
时出现以下错误:
System.NullReferenceException:“对象引用未设置为对象的实例。” sConnectionString为空。
该错误发生在行上:
if (sConnectionString.Length > 0)
在完整的代码部分中:
public string sConnectionString;
public void FillData()
{
if (sConnectionString.Length > 0)
{
OleDbConnection cn = new OleDbConnection(sConnectionString);
{
cn.Open();
DataTable dt = new DataTable();
OleDbDataAdapter Adpt = new OleDbDataAdapter("select * from [sheet1$]", cn);
Adpt.Fill(dt);
dataGridView1.DataSource = dt;
}
}
}
哪个在按钮代码之前:
private void Browse_Click(object sender, EventArgs e)
{
OpenFileDialog op = new OpenFileDialog();
op.InitialDirectory = @"C:\";
op.Title = "Browse Excel Files";
op.CheckFileExists = true;
op.CheckPathExists = true;
op.DefaultExt = "csv";
op.Filter = "CSV Files (*.csv)|*.csv";
op.FilterIndex = 2;
op.RestoreDirectory = true;
op.ReadOnlyChecked = true;
op.ShowReadOnly = true;
if (op.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
if (File.Exists(op.FileName))
{
string[] Arr = null;
Arr = op.FileName.Split('.');
if (Arr.Length > 0)
{
if (Arr[Arr.Length - 1] == "xls")
sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
op.FileName + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";
}
else if (Arr[Arr.Length - 1] == "xlsx")
{
sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + op.FileName + ";Extended Properties='Excel 12.0 Xml;HDR=YES';";
}
}
FillData();
fileTextBox.Text = op.FileName;
}
}
修改
已添加:
else if (Arr[Arr.Length - 1] == "csv")
{
sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + op.FileName +
";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";
}
仍然出现相同的错误。
答案 0 :(得分:1)
关于报告的错误:
System.NullReferenceException:'对象引用未设置为 对象的实例。'
sConnectionString为空。
生成异常是因为Connection字符串声明为:
public string sConnectionString;
由于它从未被初始化,因为Connection字符串的初始化仅对某些文件类型执行,而不对OpenFileDialog.Filter
中包含的所有文件类型执行。当代码测试字符串的长度时,字符串仍为null
。可以避免设置初始值:
public string sConnectionString = string.Empty;
关于使用.CSV
操作OleDbConnection
文件所需的连接字符串:
Microsoft.Jet.OLEDB.4.0
Microsoft.ACE.OLEDB.12.0
Microsoft.ACE.OLEDB.16.0
如果某些旧格式(旧的Access Microsoft.Jet.OLEDB.4.0
文件)需要.mdb
,则该应用程序必须编译为32Bit,因此请安装其他提供程序的相应32Bit版本:>
Microsoft Database Engine 2010 Redistributable
Microsoft Database Engine 2016 Redistributable
要读取CSV文件,对于所有提供商,连接字符串的组成如下:
{Provider};Data Source={Catalog}; Extended Properties="text; HDR=Yes; IMEX=1; FMT=Delimited;
位置:
{Provider} =>
其中一个OleDb提供程序。他们中的任何一个都会做。 {Catalog} =>
包含要打开文件的目录。 HDR=Yes/No =>
CSV
文件包含标题:如果为Yes
,则标题为文件的第一行IMEX=1 =>
将导入/导出模式设置为1(导出模式= 0;导入模式= 1,链接模式= 2),以忽略数值并仅使用字符串。在这里实际上不相关。最好保留它作为一般帮助(以防文件中没有标题和 HDR=Yes
)。 FMT=Delimited =>
:文件格式:定界。标题/字段由定界符分隔。公认的定界符是逗号(,
)。此设置可能取决于系统(第3部分应用可能出于自身原因修改了注册表)。要指定与默认分隔符不同的分隔符(C
中的CSV
表示逗号), Catalog
文件夹中必须有一个Schema.ini文件定义了特定文件的特定定界符:
[MyFile.csv]
Format=Delimited(;)
由于 Data Source
是目录名(考虑为数据库),因此在查询中指定了要打开的文件的文件名:
SELECT * FROM MyFile.csv
使用Microsoft.ACE.OLEDB.12.0
作为提供者的示例连接字符串:
string connectionString = $@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={dirName};" +
"Extended Properties=\"text; HDR=Yes; IMEX=1; FMT=Delimited\";";
有关其他可用的连接字符串格式,请参见The Connection Strings Reference网站
示例代码以测试结果(在这种情况下,使用Microsoft.Jet.OLEDB.4.0
):
private void Browse_Click(object sender, EventArgs e)
{
string userFileName = string.Empty;
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.RestoreDirectory = true;
ofd.Filter = "CSV Files|*.csv|Excel '97-2003|*.xls|Excel 2007-2019|*.xlsx";
if (ofd.ShowDialog(this) == DialogResult.OK)
userFileName = ofd.FileName;
}
if (userFileName.Length == 0) return;
this.dataGridView1.DataSource = GetData(userFileName);
}
private DataTable GetData(string userFileName)
{
string dirName = Path.GetDirectoryName(userFileName);
string fileName = Path.GetFileName(userFileName);
string fileExtension = Path.GetExtension(userFileName);
string connection = string.Empty;
string query = string.Empty;
switch (fileExtension)
{
case ".xls":
connection = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={userFileName};" +
"Extended Properties=\"Excel 8.0; HDR=Yes; IMEX=1\"";
query = "SELECT * FROM [Sheet1$]";
break;
case ".xlsx":
connection = $@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={userFileName};" +
"Extended Properties=\"Excel 12.0; HDR=Yes; IMEX=1\"";
query = "SELECT * FROM [Sheet1$]";
break;
case ".csv":
connection = $@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={dirName};" +
"Extended Properties=\"text; HDR=Yes; IMEX=1; FMT=Delimited\"";
query = $"SELECT * FROM {fileName}";
break;
}
return FillData(connection, query);
}
private DataTable FillData(string connection, string query)
{
DataTable dataTable = new DataTable();
using (OleDbConnection con = new OleDbConnection(connection))
{
OleDbDataAdapter adapter = new OleDbDataAdapter(query, con);
adapter.Fill(dataTable);
adapter.Dispose();
};
return dataTable;
}