我有一个Excel电子表格,它将位于网络共享驱动器上。它需要由我的Winforms C#3.0应用程序访问(许多用户可能正在使用该应用程序并同时点击此电子表格)。一个工作表上有很多数据。这些数据分为我命名为范围的区域。我需要能够单独访问这些范围,将每个范围作为数据集返回,然后将其绑定到网格。
我找到了使用OLE的示例,并使这些工作正常。但是,我看到有关使用此方法的一些警告,而且在工作中我们一直使用Microsoft.Office.Interop.Excel作为标准。除非必须,我真的不想偏离这个。据我所知,我们的用户将使用Office 2003。
我可以使用以下代码获得我需要的范围:
MyDataRange = (Microsoft.Office.Interop.Excel.Range)
MyWorkSheet.get_Range("MyExcelRange", Type.Missing);
OLE方式很好,因为它需要我的第一行并将它们转换为列。我的范围(总共12个)在列数方面大部分彼此不同。不知道这些信息是否会影响任何建议。
有没有办法使用Interop并将返回的范围返回到数据集中?
答案 0 :(得分:2)
我不知道内置函数,但自己编写它应该不难。伪代码:
DataTable MakeTableFromRange(Range range)
{
table = new DataTable
for every column in range
{
add new column to table
}
for every row in range
{
add new datarow to table
for every column in range
{
table.cells[column, row].value = range[column, row].value
}
}
return table
}
答案 1 :(得分:2)
我不知道您拥有什么类型的数据。但是对于此链接http://www.freeimagehosting.net/image.php?f8d4ef4173.png中显示的Excel数据,您可以使用以下代码加载到数据表中。
private void Form1_Load(object sender, EventArgs e)
{
try
{
DataTable sheetTable = loadSingleSheet(@"C:\excelFile.xls", "Sheet1$");
dataGridView1.DataSource = sheetTable;
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message, "");
}
}
private OleDbConnection returnConnection(string fileName)
{
return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\"");
}
private DataTable loadSingleSheet(string fileName, string sheetName)
{
DataTable sheetData = new DataTable();
using (OleDbConnection conn = this.returnConnection(fileName))
{
conn.Open();
// retrieve the data using data adapter
OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "]", conn);
sheetAdapter.Fill(sheetData);
}
return sheetData;
}
答案 2 :(得分:0)
在读取/写入Excel 2003 XLS文件时,有必要查看NPOI。 NPOI是一个救生员。
我认为你必须迭代你的范围并创建DataRows以放入你的DataTable。
StackOverflow上的这个问题提供了更多资源:
答案 3 :(得分:0)
当excel电子表格中的同一列包含文本和数字时,此方法无法正常工作。例如,如果Range("A3")=Hello
和Range("A7")=5
则只显示Hello,而Range("A7")
的值为DBNULL
private void Form1_Load(object sender, EventArgs e)
{
try
{
DataTable sheetTable = loadSingleSheet(@"C:\excelFile.xls", "Sheet1$");
dataGridView1.DataSource = sheetTable;
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message, "");
}
}
private OleDbConnection returnConnection(string fileName)
{
return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\"");
}
private DataTable loadSingleSheet(string fileName, string sheetName)
{
DataTable sheetData = new DataTable();
using (OleDbConnection conn = this.returnConnection(fileName))
{
conn.Open();
// retrieve the data using data adapter
OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "]", conn);
sheetAdapter.Fill(sheetData);
}
return sheetData;
答案 4 :(得分:0)
我制作了可以从Excel获取经过过滤的数据的方法 以范围格式
获取过滤后的数据 Worksheet sheet = null;
sheet = (Worksheet)context.cDocumentExcel.Sheets[requiredSheetName];
DataTable dt = new DataTable();
sheet.Activate();
sheet.UsedRange.Select();
List<Range> ranges = new List<Range>();
Range usedrange = sheet.UsedRange;
foreach (var oneRange in usedrange.SpecialCells(XlCellType.xlCellTypeVisible))
{
ranges.Add(oneRange);
}
dt = (_makeTableFromRange(ranges));
从范围转换为数据表
private static DataTable _makeTableFromRange(List<Range> ranges)
{
var table = new DataTable();
foreach (var range in ranges)
{
while (table.Columns.Count < range.Column)
{
table.Columns.Add();
}
while (table.Rows.Count < range.Row)
{
table.Rows.Add();
}
table.Rows[range.Row - 1][range.Column - 1] = range.Value2;
}
//clean from empty rows
var filteredRows = table.Rows.Cast<DataRow>().
Where(row => !row.ItemArray.All(field => field is System.DBNull ||
string.Compare((field as string).Trim(), string.Empty) ==
0));
table = filteredRows.CopyToDataTable();
return table;
}