C# 当第一行为字符串时,GetValue()不读取十进制值
“我使用Microsoft.ACE.OLEDB.12.0提供程序从Excel工作表中读取数据。 我正在使用C# 当第一行为字符串时,GetValue()不读取十进制值,c#,sql-server,excel,c#-3.0,oledb,C#,Sql Server,Excel,C# 3.0,Oledb,“我使用Microsoft.ACE.OLEDB.12.0提供程序从Excel工作表中读取数据。 我正在使用OleDbDataReader和他的GetValue()获取数据。 第一行(可以不止一行)是字符串头,我不能跳过它。 接下来是设置为小数点后0位的数字数据,但当我选择其中一个时,它会以正确的十进制格式显示在条形图中 我怎样才能以完整的原始十进制格式(如Excel中的条形图)读取这些混合数据? 我无法更改excel工作表的设置 这是我的密码: using System.Data.OleDb;
OleDbDataReader
和他的GetValue()
获取数据。
第一行(可以不止一行)是字符串头,我不能跳过它。
接下来是设置为小数点后0位的数字数据,但当我选择其中一个时,它会以正确的十进制格式显示在条形图中
我怎样才能以完整的原始十进制格式(如Excel中的条形图)读取这些混合数据?
我无法更改excel工作表的设置
这是我的密码:
using System.Data.OleDb;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string query = "SELECT * FROM [List1$]";
string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\Temp\Test.xls;Extended Properties=""Excel 12.0;HDR=NO;IMEX=1""";
using (OleDbConnection connection = new OleDbConnection(connString))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand(query, connection))
{
using (OleDbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
object value = reader.GetValue(0);
}
}
}
}
}
}
}
尝试在连接字符串中使用
HDR=YES
,并停止跳过第一行:
string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\Temp\Test.xls;Extended Properties=""Excel 12.0;HDR=YES;IMEX=1""";
[更新]
我建议您使用的一种解决方法是读取两次文件(使用相同的方法):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.OleDb;
using System.Data;
using System.IO;
class Program
{
static void Main(string[] args)
{
// the Excel file
string file = @"c:\Temp\Test.xls";
if (!File.Exists(file))
{
Console.WriteLine("File not found.");
return;
}
// DataTable bonus! :)
System.Data.DataTable dt = new System.Data.DataTable();
IEnumerable<List<object>> header = new List<List<object>>();
IEnumerable<List<object>> rows = new List<List<object>>();
// read the header first
header = GetData(file, true);
// read the rows
rows = GetData(file, false);
// add the columns
foreach (var column in header.First())
{
dt.Columns.Add(column.ToString());
}
// add the rows
foreach (var row in rows)
{
dt.Rows.Add(row.ToArray());
}
// now you may use the dt DataTable for your purpose
}
/// <summary>
/// Read from the Excel file
/// </summary>
/// <param name="file">The path to the Excel file</param>
/// <param name="readHeader">True if you want to read the header,
/// False if you want to read the rows</param>
/// <returns></returns>
private static IEnumerable<List<object>> GetData(string file, bool readHeader)
{
string query = "SELECT * FROM [List1$]";
string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;" +
@"Data Source=" + file + @";Extended Properties=""Excel 12.0 Xml;HDR=NO;IMEX="
+ ((readHeader) ? "1" : "0") + @";""";
using (OleDbConnection connection = new OleDbConnection(connString))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand(query, connection))
{
using (OleDbDataReader reader = command.ExecuteReader())
{
bool isHeaderRead = false;
while (reader.Read())
{
if (readHeader && isHeaderRead)
{ break; }
isHeaderRead = true;
List<object> values = new List<object>();
for (int i = 0; i < reader.FieldCount; i++)
{
values.Add(reader.GetValue(i));
}
yield return values;
}
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Data.OleDb;
使用系统数据;
使用System.IO;
班级计划
{
静态void Main(字符串[]参数)
{
//Excel文件
字符串文件=@“c:\Temp\Test.xls”;
如果(!File.Exists(File))
{
WriteLine(“未找到文件”);
返回;
}
//数据表奖金!:)
System.Data.DataTable dt=新的System.Data.DataTable();
IEnumerable头=新列表();
IEnumerable rows=新列表();
//先读标题
header=GetData(文件,true);
//读这些行
rows=GetData(文件,false);
//添加列
foreach(header.First()中的var列)
{
Add(column.ToString());
}
//添加行
foreach(行中的变量行)
{
Add(row.ToArray());
}
//现在,您可以使用dt DataTable
}
///
///从Excel文件中读取
///
///Excel文件的路径
///如果要读取标题,则为True,
///如果要读取行,则为False
///
私有静态IEnumerable GetData(字符串文件,bool readHeader)
{
string query=“从[List1$]中选择*”;
string connString=@“Provider=Microsoft.ACE.OLEDB.12.0;”+
@“数据源=“+文件+@”;扩展属性=“”Excel 12.0 Xml;HDR=否;IMEX=”
+((readHeader)?“1”:“0”)+@“;
使用(OLEDB连接=新OLEDB连接(connString))
{
connection.Open();
使用(OleDbCommand命令=新OleDbCommand(查询、连接))
{
使用(OleDbDataReader=command.ExecuteReader())
{
bool-ishaderread=false;
while(reader.Read())
{
if(readHeader&&ishaderread)
{break;}
ISHEADREAD=真;
列表值=新列表();
对于(int i=0;i
根据经验,您可能要做的最好的事情是以下几点。
我在读取数据时总是遇到excel文件的问题。
这就是我鄙视excel作为数据传输机制的原因
我在一家通过excel获取所有“银行数据”的公司工作。
我很高兴被证明是错的
注意。GetValue(0)运行后,在其上放置一个手表。它可能会告诉你这是一根线。
但是你可以确定它认为它是什么,然后稍微调整一下你的“获取”方法。
例如,如果值是“字符串”,则可以将GetValue(0)更改为GetString(0)
额外建议
我通常把一些私人常数放在类的顶部来告诉我列是什么,而不是“0”、“1”、“2”等
private const int EXCEL_COLUMN_TOTAL_AMOUNT = 0;
(你可以做类似的事情,你只是保持了这个例子的简单性)
额外提示:
我认为它的工作方式是excel将查看第一行数据,查看数据类型,并将其用于同一列中的其余行。我不认为它说“检查每行的数据类型”。这就是你的难题
如果您说没有标题行,它将在A1中查找a中所有行的数据类型。如果您说有标题行,它将在A2中查找a中所有行的数据类型。是否尝试了“.GetDecimal”而不是“.GetValue”?是。GetDecimal引发异常,因为存在空格字符。GetFieldType返回字符串。所以它必须在OleDbCommand或OleDbConnection设置中的某个位置,可能是连接字符串中的某个属性。我已经编辑了您的标题。请参阅“”,其中的共识是“不,他们不应该”。感谢您,对于这些示例,它是有效的,不幸的是,我无法使用HDR=YES禁用标头。谢谢您,您的解决方案看起来是很好的解决方法,但实现它对我来说并不容易。感谢您的帮助。如果GetValue()返回正确的数据,它就可以工作,但返回的数据没有小数点。关于十进制的信息丢失了。好的,我现在知道了。该列包含大量数据类型。是 啊“格式化”设置会让你抓狂。我们必须和我们的客户谈谈这件事。首先,我们有一条规则,即每一列的数据类型必须一致。他们有两行“一条记录”的数据。比如,在第1行中,colA有“LastName”,在第2行中,colA有“transactionmount”…(第1行和第2行制作了一个“记录”),所以我们必须让他们要么(1)在一个excel行上制作所有数据,要么(2)第1行colA有LastName,第2行colB有T
private const int EXCEL_COLUMN_TOTAL_AMOUNT = 0;