使用 OleDb 和 Access 数据库引擎的 C# Excel 插入错误
Posted
技术标签:
【中文标题】使用 OleDb 和 Access 数据库引擎的 C# Excel 插入错误【英文标题】:C# Excel INSERT Error using OleDb and the Access Database Engine 【发布时间】:2012-05-08 02:41:04 【问题描述】:所有,关于这个主题有很多问题,但没有一个能解决我的问题。我编写了一个相当复杂的例程,使用 OleDb 和 Access 数据库引擎将传递的DataSet
/DataTable
导出到 Excel(我在 Win7 下运行 Office 2010)。问题是无论我如何定义要写入 Excel 的列,所有值都导出为 TEXT/STRING
字段。
我正在使用OleDbConnection
字符串
string fileName = @"F:\SomePath\MyExcel.xlsx";
string connectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=
0;Extended Properties=""Excel 12.0 Xml;HDR=YES;MaxScanRows=0;IMEX=0""", fileName);
并尝试了许多其他connection string options,但都没有运气。
我在代码中生成 Excel 定义,但这些定义明确地生成为
CREATE TABLE [MetaTab] ([Table] TEXT,[Field] TEXT,[Seq] NUMBER,[DataLevel] NUMBER)
然后我为插入生成代码,对于上面的示例,这是
INSERT INTO [MetaTab$]([Table],[Field],[Seq],[DataLevel])VALUES('B1A','EstabID','1','9')
这可行,但所有值都写为 TEXT。 如何强制 Excel 采用其他数据格式?
注意:我尝试删除非字符串的撇号,但这也不起作用。我真的被困住了,任何想法都将不胜感激。感谢您的宝贵时间。
【问题讨论】:
你试过HDR=NO,我认为如果你创建表,第一行不包含任何标题 是的。我试过这个。谢谢。 【参考方案1】:我不认为你可以。 excel 格式实际上并不类似于数据库列数据类型 - 最终基础值始终是数字或字符串;然后格式决定它的显示方式。
即使我错了——我个人更喜欢使用http://epplus.codeplex.com/ 来生成我的 Excel 电子表格——你可以在其中做很多非常高级的东西以及格式化等简单的东西。
【讨论】:
但是我已经看到了代码,其中有一个现有的 Excel 文件,并且使用了与上述相同的INSERT
语句,并且以正确的格式插入了数据。我想这表明格式是在 INSERT
发生之前在工作簿中预先建立的。在我看来,您可以使用 CREATE TABLE
指定列类型,这对我来说似乎很奇怪,而 INSERT
并没有遵守这一点...
@Killercam - oledb 提供程序不必支持您可以触发的 SQL DDL 的所有功能 - 它只需要正确解释它。在 Excel 的情况下,将行插入现有工作表将使用 Excel 的智能格式传播行为是有意义的;但除此之外,SQL 数据类型不是 excel 格式的类似物,因此提供者不解释它们是有道理的。还是方便吗?绝对不是!
我很欣赏提供者不必支持 SQL DDL,但如果不指定所需的列格式,CREATE 声明将无法工作。这清楚地表明 Excel 正在使用这些类型以正确构建表结构 - 当然这似乎没有发生。我看过你的链接,我非常喜欢它!我目前使用“Microsoft.Office.Interop.Excel”库来导出我的格式化 Excel 文件,这既慢又笨重!我喜欢你的回答,但我不相信你不能做我想做的事......谢谢你的时间。
我认为你在这里是正确的。我现在尝试编辑一些处理默认数据类型的核心注册表值 - 这不起作用。感谢您的帮助...【参考方案2】:
在 Excel 工作表中插入数值时,无法向 OleDbCommand 提供任何提示(语法)以插入数值。打开工作表时,它不会在工作表中将数值显示为数字。
有一种解决方法,当在 excel 文件中创建第一条记录时,然后转到第一条记录并在已存在记录的单元格(需要数字数据的地方)中重新输入相同的值。
或
您可以在该 Excel 工作表中放置带有数值的默认记录。
下面提到了示例代码,用于在工作表中创建第一条记录后将数据类型转换为数字。当任何记录插入工作表时调用一次 ChangeFormat 函数,进一步的数据将以正确的格式保存。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using System.Data;
namespace ConsoleApplication3
class Program
static void Main(string[] args)
System.Data.DataTable xlsData = new System.Data.DataTable();
string xlsConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=d:\\romil.xlsx;Extended Properties=\"Excel 12.0;HDR=Yes;\"";
System.Data.OleDb.OleDbConnection xlsCon = new System.Data.OleDb.OleDbConnection(xlsConnectionString);
System.Data.OleDb.OleDbCommand xlsCommand;
int recUpdate;
int recordsinSheet;
xlsCommand = new System.Data.OleDb.OleDbCommand("Select count(*) as RecCount from [Sheet1$]");
xlsCommand.Connection = xlsCon;
xlsCon.Open();
recordsinSheet =Convert.ToInt32( xlsCommand.ExecuteScalar());
xlsCommand= new System.Data.OleDb.OleDbCommand("Insert into [Sheet1$] (Field1,Field2) values ('123',2)");
xlsCommand.Connection = xlsCon;
recUpdate = xlsCommand.ExecuteNonQuery();
xlsCon.Close();
if ((recordsinSheet + recUpdate) == 1)
ChangeFormat();
Console.ReadKey();
private static void ChangeFormat()
string filename = "d:\\romil.xlsx";
object missing = System.Reflection.Missing.Value ;
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wb = excel.Workbooks.Open(filename, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
Microsoft.Office.Interop.Excel.Worksheet wsh=null;
foreach (Microsoft.Office.Interop.Excel.Worksheet sheet in wb.Sheets)
if (sheet.Name == "Sheet1")
wsh = sheet;
break;
for (int rCnt = 2; rCnt <= wsh.Rows.Count; rCnt++)
if ( wsh.Cells[rCnt, 2].Value== null)
break;
wsh.Cells[rCnt, 2] = wsh.Cells[rCnt, 2].Value;
wb.SaveAs(filename, missing,
missing, missing, missing, missing,
Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
missing, missing, missing,
missing, missing);
wb.Close();
【讨论】:
+1 非常感谢您的回答。但是,这假定用户安装了 Office,并且在这种情况下为我使用 OleDb 的全部目的是避免使用 Interop。我已经有一个使用“Microsoft.Office.Interop.Excel”写入 Excel 的例程。再次感谢,这是一个很好的解决方法,我将来可能会使用......以上是关于使用 OleDb 和 Access 数据库引擎的 C# Excel 插入错误的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft Office 12.0 Access 数据库引擎 OLE DB 提供程序问题
在 C# 中使用 microsoft access 和 OleDb 在数据库中添加数据
使用 c# 和 oledb 查询更新 Ms-Access 2010 中的列值
如何使用 C# 和 OleDB 向 Access 数据库表中添加富文本列?