如何在 C# 中导入特定列和行的 excel 数据到没有 OLEDB 的 datagridview
How to import specific columns and rows of excel data to datagridview WITHOUT OLEDB in C#
我为自动映射网络驱动器的工作制作了一个简单的独立程序。该程序使用 DataGridView
列出所有驱动器号和路径,我编写的代码读取 DataGridView
中的条目并基于此映射驱动器 - 还从特定的驱动器号和路径excel sheet.
那个特定的 excel 文件使用 VB 代码跟踪用户计算机的某些信息。第三个作品sheet,名称为“Drives”,是网络驱动器所在的地方。盘符和路径在C和D列。除了名称“Network drives”外,没有headers在第 3 行开始之前的第 2 行。
不幸的是,在第 29 行之后,outlook pst 文件的条目开始。
由于我对 C# 的了解有限(我是 C# 的新手),我设法创建了这个:
public void FileSelect()
{
string filePath = string.Empty;
string fileExt = string.Empty;
OpenFileDialog file = new OpenFileDialog(); //open dialog to choose file
file.Filter = "Discovery Excel|*.xlsm| CSV (Coming Soon)| *.csv";
file.Title = "Please select a valid data file";
if (file.ShowDialog() == System.Windows.Forms.DialogResult.OK) //if there is a file choosen by the user
{
filePath = file.FileName; //get the path of the file
fileExt = Path.GetExtension(filePath); //get the file extension
if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsm") == 0)
{
try
{
DataTable dtExcel = new DataTable();
dtExcel = ReadExcel(filePath, fileExt); //read file
InfoTB.Visible = false;
dataGridView1.Visible = true;
FileSelectBT.Visible = false;
ManualBT.Visible = false;
RunBT.Visible = true;
ExitBT.Visible = true;
RunBT.Location = new System.Drawing.Point(109, 334);
ExitBT.Location = new System.Drawing.Point(190, 334);
dataGridView1.DataSource = dtExcel;
dataGridView1.AutoResizeColumns();
dataGridView1.Columns[0].HeaderText = "Drive Letter";
dataGridView1.Columns[1].HeaderText = "Drive Path";
for (int i = 1; i < dataGridView1.RowCount - 1; i++)
{
if (dataGridView1.Rows[i].Cells[0].Value.ToString() == "" || dataGridView1.Rows[i].Cells[1].Value.ToString() == "")
{
dataGridView1.Rows.RemoveAt(i);
i--;
}
}
}
catch (Exception ex)
{
MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error);
ManualMode();
OpenExcel(filePath);
TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file
txt.Write(ex.ToString());
txt.Close();
}
}
else
{
MessageBox.Show("Please choose .xlsm or .CSV file only.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error); //custom messageBox to show error
}
}
}
public DataTable ReadExcel(string fileName, string fileExt)
{
string conn = string.Empty;
DataTable dtexcel = new DataTable();
conn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + fileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";"; //loading the Access engine to load/read the Excel file
using (OleDbConnection con = new OleDbConnection(conn))
{
try
{
OleDbDataAdapter oleAdpt = new OleDbDataAdapter("Select TOP 24 F3,F4 FROM [Drives$]", conn); //read data from sheet 3 which should be the drives
oleAdpt.Fill(1, 24, dtexcel); //fill excel data into dataTable
}
catch (InvalidOperationException ex)
{
MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error);
ManualMode();
OpenExcel(fileName);
TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)+ "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file
txt.Write(ex.ToString());
txt.Close();
}
}
return dtexcel;
}
并且此代码有效!
Here's photo of what the program looks like when it has some entries
不幸的是,Microsoft.ACE.OLEDB.12.0 在将程序从一台计算机移动到另一台计算机时并不可靠。我无法在工作的每台计算机上都安装 ACE,因此我必须找到另一种方法来专门读取 Excel 文件,而无需使用 OLEDB。
我确实四处寻找替代解决方案,但我发现的东西似乎专注于特定的起始行而不是结束行。
公平地说,我是 C# 的新手,所以我可能忽略了一些对我的程序有帮助的东西。
也就是说,对于这种情况,是否有替代 OLEDB 的方法?
正如 PaulF 的评论所述,Excel Interop 是一种可能的解决方案,无需使用任何外部库。
以下假设您的数据将始终在 C3:D29
中,并且还假设工作表中的数据有效:
public DataTable ReadExcel(string fileName)
{
var excel = new Excel.Application();
var wkb = excel.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
var sheet = wkb.Sheets["Drives"] as Excel.Worksheet;
var range = sheet.Range[sheet.Cells[3, 3], sheet.Cells[29, 4]];
var data = range.Value2;
var dt = new DataTable();
dt.Columns.Add("Drive");
dt.Columns.Add("Path");
for (int i = 1; i <= range.Rows.Count; i++)
{
dt.Rows.Add(data[i, 1], data[i, 2]);
}
return dt;
}
我为自动映射网络驱动器的工作制作了一个简单的独立程序。该程序使用 DataGridView
列出所有驱动器号和路径,我编写的代码读取 DataGridView
中的条目并基于此映射驱动器 - 还从特定的驱动器号和路径excel sheet.
那个特定的 excel 文件使用 VB 代码跟踪用户计算机的某些信息。第三个作品sheet,名称为“Drives”,是网络驱动器所在的地方。盘符和路径在C和D列。除了名称“Network drives”外,没有headers在第 3 行开始之前的第 2 行。 不幸的是,在第 29 行之后,outlook pst 文件的条目开始。
由于我对 C# 的了解有限(我是 C# 的新手),我设法创建了这个:
public void FileSelect()
{
string filePath = string.Empty;
string fileExt = string.Empty;
OpenFileDialog file = new OpenFileDialog(); //open dialog to choose file
file.Filter = "Discovery Excel|*.xlsm| CSV (Coming Soon)| *.csv";
file.Title = "Please select a valid data file";
if (file.ShowDialog() == System.Windows.Forms.DialogResult.OK) //if there is a file choosen by the user
{
filePath = file.FileName; //get the path of the file
fileExt = Path.GetExtension(filePath); //get the file extension
if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsm") == 0)
{
try
{
DataTable dtExcel = new DataTable();
dtExcel = ReadExcel(filePath, fileExt); //read file
InfoTB.Visible = false;
dataGridView1.Visible = true;
FileSelectBT.Visible = false;
ManualBT.Visible = false;
RunBT.Visible = true;
ExitBT.Visible = true;
RunBT.Location = new System.Drawing.Point(109, 334);
ExitBT.Location = new System.Drawing.Point(190, 334);
dataGridView1.DataSource = dtExcel;
dataGridView1.AutoResizeColumns();
dataGridView1.Columns[0].HeaderText = "Drive Letter";
dataGridView1.Columns[1].HeaderText = "Drive Path";
for (int i = 1; i < dataGridView1.RowCount - 1; i++)
{
if (dataGridView1.Rows[i].Cells[0].Value.ToString() == "" || dataGridView1.Rows[i].Cells[1].Value.ToString() == "")
{
dataGridView1.Rows.RemoveAt(i);
i--;
}
}
}
catch (Exception ex)
{
MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error);
ManualMode();
OpenExcel(filePath);
TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file
txt.Write(ex.ToString());
txt.Close();
}
}
else
{
MessageBox.Show("Please choose .xlsm or .CSV file only.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error); //custom messageBox to show error
}
}
}
public DataTable ReadExcel(string fileName, string fileExt)
{
string conn = string.Empty;
DataTable dtexcel = new DataTable();
conn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + fileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";"; //loading the Access engine to load/read the Excel file
using (OleDbConnection con = new OleDbConnection(conn))
{
try
{
OleDbDataAdapter oleAdpt = new OleDbDataAdapter("Select TOP 24 F3,F4 FROM [Drives$]", conn); //read data from sheet 3 which should be the drives
oleAdpt.Fill(1, 24, dtexcel); //fill excel data into dataTable
}
catch (InvalidOperationException ex)
{
MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error);
ManualMode();
OpenExcel(fileName);
TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)+ "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file
txt.Write(ex.ToString());
txt.Close();
}
}
return dtexcel;
}
并且此代码有效!
Here's photo of what the program looks like when it has some entries
不幸的是,Microsoft.ACE.OLEDB.12.0 在将程序从一台计算机移动到另一台计算机时并不可靠。我无法在工作的每台计算机上都安装 ACE,因此我必须找到另一种方法来专门读取 Excel 文件,而无需使用 OLEDB。
我确实四处寻找替代解决方案,但我发现的东西似乎专注于特定的起始行而不是结束行。
公平地说,我是 C# 的新手,所以我可能忽略了一些对我的程序有帮助的东西。
也就是说,对于这种情况,是否有替代 OLEDB 的方法?
正如 PaulF 的评论所述,Excel Interop 是一种可能的解决方案,无需使用任何外部库。
以下假设您的数据将始终在 C3:D29
中,并且还假设工作表中的数据有效:
public DataTable ReadExcel(string fileName)
{
var excel = new Excel.Application();
var wkb = excel.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
var sheet = wkb.Sheets["Drives"] as Excel.Worksheet;
var range = sheet.Range[sheet.Cells[3, 3], sheet.Cells[29, 4]];
var data = range.Value2;
var dt = new DataTable();
dt.Columns.Add("Drive");
dt.Columns.Add("Path");
for (int i = 1; i <= range.Rows.Count; i++)
{
dt.Rows.Add(data[i, 1], data[i, 2]);
}
return dt;
}