尽管已经有很多关于如何使用OLEDB驱动器来操作Excel文件的文章,但本文旨在提供一个简单的方式来读取和写入Excel中的值。可以实现读取或写入单个值或数据表。然而,由于Excel驱动的限制,不能从表中删除行,也不能更新空范围。可以读取一个范围并更新或插入现有范围。Excel有它自己的方式对列进行数据类型推断。DaberElay根据文章做出了回应:
问题是如何发生的?
显然,引擎读取每列的前8个单元格并检查它的数据类型。如果前8个单元格中的大多数是整数/双精度类型,问题仍然存在。
这个问题可以解决吗?
可以,也不可以。可以要求引擎检查超过8个单元格(通过设置注册表值HKLM\Software\Microsoft\Jet\4.0\Engines\Excel\TypeGuessRows
为0,这将检查前16000行,并且会有轻微的性能损失)。但如果前16000行都是数值类型,然后才有文本值,就会遇到问题。
另一种可以做的事情是将TypeGuessRows
设置为1,并设置连接字符串的扩展属性HDR
为No,所以如果Excel总是有标题行,它会读取第一行并决定它是一个文本字段。
请注意,这意味着将不得不从现在拥有的不必要的额外的第一行中创建列名。如果OLEDB解决方案不符合需求,可以购买一个组件。有一些组件可以在没有MSExcel的情况下读取或写入Excel文件,并且能够编辑。
这里有一些想法:
对于一个项目,需要在Web服务器上读取和写入MS Excel文件。MS Excel文件将被上传并在服务器上读取到SQL Server数据库中。通常,会使用Microsoft发布的XML语法。不幸的是,这是MS Excel 2002或更高版本支持的语法。它使得制作一个组件来修改和读取Excel工作簿变得更容易。只有在项目中,客户总是使用像MS Excel '97这样的旧软件,这些软件不支持这种XML。也喜欢选择一个只使用一个版本的Excel 2002的解决方案,并有一个编程转换类。只有这个过程将在Web服务器上运行,其中MS Office及其组件是不可行的,也不允许。
所以,开始了一个使用OLEDB驱动器的类,它可以对上传的Excel文件执行一些基本任务。
演示表单使用以下代码来初始化ExcelReader
类:
C# exr = new ExcelReader();
DataTable _dt = new DataTable("par");
exr.KeepConnectionOpen = true;
exr.ExcelFilename = _strExcelFilename;
exr.Headers = false;
exr.MixedData = true;
exr.SheetName = this.txtSheet.Text;
exr.SheetRange = this.txtRange.Text;
exr.SetPrimaryKey(0);
_dt = exr.GetTable();
首先,创建这个类的一个新的实例。同时声明一个DataTable
。更喜欢将其作为私有类变量。在更新一个网格之后,将使用表格变量来更新表格与ExcelReader
类。keepconnection
open属性在ExcelReader
操作后保持连接打开,节省时间。标题选项意味着,在MS Excel中是否有一个行标题来解释列数据。MixedData
属性使用IMEX
选项(0=导出,1=导入,2=链接)。默认情况下,该属性为true
,IMEX
=2。如果为false
,则连接字符串中没有IMEX
选项。同时设置工作表名称和范围。
主键是需要的,以便能够更新Excel工作表。它现在只支持一个主键,但类可以扩展。如果表没有主键,DataAdapter
将无法工作。Excel驱动器不会发现主键,所以必须手动设置。DataColumnNumber
0是设置范围的第一列。GetTable()
返回请求的Excel范围中的数据在DataTable
中。更新Excel文件本身范围内可以通过SetTable(DataTable)
方法完成。只需下载演示并查看。
首先,设置连接:
C# private string ExcelConnection()
{
return @"Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source=" + _strExcelFilename + ";" +
@"Extended Properties=" + Convert.ToChar(34).ToString() +
@"Excel 8.0;" + ExcelConnectionOptions() + Convert.ToChar(34).ToString();
}
打开连接:
C# _oleConn = new OleDbConnection(ExcelConnection());
_oleConn.Open();
然后只需使用OledbCommand
进行选择,文本如下:
C# _oleCmdSelect = new OleDbCommand(
@"SELECT * FROM [" + _strSheetName +
"$" + _strSheetRange +
"]", _oleConn);
使用select
命令填充表格以检索数据:
C# OleDbDataAdapter oleAdapter = new OleDbDataAdapter();
oleAdapter.SelectCommand = _oleCmdSelect;
DataTable dt = new DataTable(strTableName);
oleAdapter.FillSchema(dt, SchemaType.Source);
oleAdapter.Fill(dt);
更新表格:
首先设置主键(s)。然后调用更新方法以更新Excel表。尝试在演示中更新一个空范围!会出现错误。
C# if (this._intPKCol > -1)
{
int[] intPKCols = new int[] { _intPKCol };
_exr.PKCols = intPKCols;
}
_exr.SetTable(_dt);
1.1 修复了一些错误并添加了一些功能
可以使用方法调用来检索Excel工作表名称。