- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我今天在这个网站上看到了使用 OleDbConnection
从 Microsoft Excel 文件读取数据的说明:OLE DB Providers
这允许我从 Excel 文件中读取所有数据:
private const string EXCEL_CON =
@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};" +
@"Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'";
public DataTable ExtractExcel(string fullFilename, string tableName)
{
var table = new DataTable();
string strCon = string.Format(EXCEL_CON, fullFilename);
using (var xlConn = new System.Data.OleDb.OleDbConnection(strCon))
{
ConnectionState initialState = xlConn.State;
try
{
if ((initialState & ConnectionState.Open) != ConnectionState.Open)
{
xlConn.Open();
}
string sql = string.Format("SELECT * FROM `{0}`;", tableName);
using (var cmd = new System.Data.OleDb.OleDbCommand(sql, xlConn))
{
table.Load(cmd.ExecuteReader());
}
}
finally
{ // it seems like Access does not always close the connection
if ((initialState & ConnectionState.Open) != ConnectionState.Open)
{
xlConn.Close();
}
}
}
return table;
}
当我插入数据时,第 1 步是删除 Microsoft Access 数据库中的现有表,以防添加、更改或删除列:
public void InsertExcel(OleDbConnection dbConn, DataTable table) {
ConnectionState initState = dbConn.State;
try {
if ((initState & ConnectionState.Open) != ConnectionState.Open) {
dbConn.Open();
}
string sql = string.Format("SELECT * FROM {0};", table.TableName);
DataTable original = new DataTable();
using (OleDbCommand cmd = new OleDbCommand(sql, dbConn)) {
try {
original.Load(cmd.ExecuteReader());
} catch (Exception) { // table does not exist
}
}
if (0 < original.Rows.Count) {
sql = string.Format("DROP TABLE {0};", table.TableName);
using (OleDbCommand cmd = new OleDbCommand(sql, dbConn)) {
cmd.ExecuteNonQuery();
}
}
// ****************
// CODE NEEDED HERE
// ****************
} finally {
if ((initState & ConnectionState.Open) != ConnectionState.Open) {
dbConn.Close();
}
}
}
DROP TABLE
命令执行后(在 CODE NEEDED HERE
部分),我需要以某种方式将信息插入 DataTable .
如果我没有任何类型的主键、列名或列数据类型,我将如何插入表?
OleDbParameter有 AddWithValue允许添加数据而无需知道数据类型的方法。 是否有类似的东西可以用来转储整个 DataTable
(或 DataSet
)?
最佳答案
这是一个静态类
,是我通过合并我发现或开发的各种代码片段构建的。您需要注意的主要方法是 ExportToExcelOleDb
,给定一个 DataSet
和一个连接字符串,该方法会将 DataSet
写入 Excel 文件您的选择,格式为 DataSet
。
请注意,Access Engine 写入 Excel 的方式存在一个“错误”——它在写入 Excel 工作簿时无法保留数据类型,这意味着所有数据类型都以 Excel TEXT 格式写入
/字符串
。不管怎样,它就在这里……
// Structures used for conversion between data-types.
private struct ExcelDataTypes
{
public const string NUMBER = "NUMBER";
public const string DATETIME = "DATETIME";
public const string TEXT = "TEXT"; // also works with "STRING".
}
private struct NETDataTypes
{
public const string SHORT = "int16";
public const string INT = "int32";
public const string LONG = "int64";
public const string STRING = "string";
public const string DATE = "DateTime";
public const string BOOL = "Boolean";
public const string DECIMAL = "decimal";
public const string DOUBLE = "double";
public const string FLOAT = "float";
}
/// <summary>
/// Routine to export a given DataSet to Excel. For each DataTable contained
/// in the DataSet the overloaded routine will create a new Excel sheet based
/// upon the currently selected DataTable. The proceedure loops through all
/// DataRows in the selected DataTable and pushes each one to the specified
/// Excel file using ADO.NET and the Access Database Engine (Excel is not a
/// prerequisit).
/// </summary>
/// <param name="dataSet">The DataSet to be written to Excel.</param>
/// <param name="connectionString">The connection string.</param>
/// <param name="fileName">The Excel file name to export to.</param>
/// <param name="deleteExistFile">Delete existing file?</param>
public static void ExportToExcelOleDb(DataSet dataSet, string connectionString,
string fileName, bool deleteExistFile)
{
// Support for existing file overwrite.
if (deleteExistFile && File.Exists(fileName))
File.Delete(fileName);
ExportToExcelOleDb(dataSet, connectionString, fileName);
}
/// <summary>
/// Overloaded version of the above.
/// </summary>
/// <param name="dataSet">The DataSet to be written to Excel.</param>
/// <param name="connectionString">The SqlConnection string.</param>
/// <param name="fileName">The Excel file name to export to.</param>
public static bool ExportToExcelOleDb(DataSet dataSet, string connectionString, string fileName)
{
try
{
// Check for null set.
if (dataSet != null && dataSet.Tables.Count > 0)
{
using (OleDbConnection connection = new OleDbConnection(String.Format(connectionString, fileName)))
{
// Initialise SqlCommand and open.
OleDbCommand command = null;
connection.Open();
// Loop through DataTables.
foreach (DataTable dt in dataSet.Tables)
{
// Build the Excel create table command.
string strCreateTableStruct = BuildCreateTableCommand(dt);
if (String.IsNullOrEmpty(strCreateTableStruct))
return false;
command = new OleDbCommand(strCreateTableStruct, connection);
command.ExecuteNonQuery();
// Puch each row into Excel.
for (int rowIndex = 0; rowIndex < dt.Rows.Count; rowIndex++)
{
command = new OleDbCommand(BuildInsertCommand(dt, rowIndex), connection);
command.ExecuteNonQuery();
}
}
}
}
return true;
}
catch (Exception eX)
{
Utils.ErrMsg(eX.Message);
return false;
}
}
/// <summary>
/// Build the various sheet names to be inserted based upon the
/// number of DataTable provided in the DataSet. This is not required
/// for XCost purposes. Coded for completion.
/// </summary>
/// <param name="connectionString">The connection string.</param>
/// <returns>String array of sheet names.</returns>
private static string[] BuildExcelSheetNames(string connectionString)
{
// Variables.
DataTable dt = null;
string[] excelSheets = null;
using (OleDbConnection schemaConn = new OleDbConnection(connectionString))
{
schemaConn.Open();
dt = schemaConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
// No schema found.
if (dt == null)
return null;
// Insert 'TABLE_NAME' to sheet name array.
int i = 0;
excelSheets = new string[dt.Rows.Count];
foreach (DataRow row in dt.Rows)
excelSheets[i++] = row["TABLE_NAME"].ToString();
}
return excelSheets;
}
/// <summary>
/// Routine to build the CREATE TABLE command. The conversion of
/// .NET to Excel data types is also handled here (supposedly!).
/// Help: http://support.microsoft.com/kb/316934/en-us.
/// </summary>
/// <param name="dataTable"></param>
/// <returns>The CREATE TABLE command string.</returns>
private static string BuildCreateTableCommand(DataTable dataTable)
{
// Get the type look-up tables.
StringBuilder sb = new StringBuilder();
Dictionary<string, string> dataTypeList = BuildExcelDataTypes();
// Check for null data set.
if (dataTable.Columns.Count <= 0)
return null;
// Start the command build.
sb.AppendFormat("CREATE TABLE [{0}] (", BuildExcelSheetName(dataTable));
// Build column names and types.
foreach (DataColumn col in dataTable.Columns)
{
string type = ExcelDataTypes.TEXT;
if (dataTypeList.ContainsKey(col.DataType.Name.ToString().ToLower()))
{
type = dataTypeList[col.DataType.Name.ToString().ToLower()];
}
sb.AppendFormat("[{0}] {1},", col.Caption.Replace(' ', '_'), type);
}
sb = sb.Replace(',', ')', sb.ToString().LastIndexOf(','), 1);
return sb.ToString();
}
/// <summary>
/// Routine to construct the INSERT INTO command. This does not currently
/// work with the data type miss matches.
/// </summary>
/// <param name="dataTable"></param>
/// <param name="rowIndex"></param>
/// <returns></returns>
private static string BuildInsertCommand(DataTable dataTable, int rowIndex)
{
StringBuilder sb = new StringBuilder();
// Remove whitespace.
sb.AppendFormat("INSERT INTO [{0}$](", BuildExcelSheetName(dataTable));
foreach (DataColumn col in dataTable.Columns)
sb.AppendFormat("[{0}],", col.Caption.Replace(' ', '_'));
sb = sb.Replace(',', ')', sb.ToString().LastIndexOf(','), 1);
// Write values.
sb.Append("VALUES (");
foreach (DataColumn col in dataTable.Columns)
{
string type = col.DataType.ToString();
string strToInsert = String.Empty;
strToInsert = dataTable.Rows[rowIndex][col].ToString().Replace("'", "''");
sb.AppendFormat("'{0}',", strToInsert);
//strToInsert = String.IsNullOrEmpty(strToInsert) ? "NULL" : strToInsert;
//String.IsNullOrEmpty(strToInsert) ? "NULL" : strToInsert);
}
sb = sb.Replace(',', ')', sb.ToString().LastIndexOf(','), 1);
return sb.ToString();
}
/// <summary>
/// Build the Excel sheet name.
/// </summary>
/// <param name="dataTable"></param>
/// <returns></returns>
private static string BuildExcelSheetName(DataTable dataTable)
{
string retVal = dataTable.TableName;
if (dataTable.ExtendedProperties.ContainsKey(TABLE_NAME_PROPERTY))
retVal = dataTable.ExtendedProperties[TABLE_NAME_PROPERTY].ToString();
return retVal.Replace(' ', '_');
}
/// <summary>
/// Dictionary for conversion between .NET data types and Excel
/// data types. The conversion does not currently work, so I am
/// pushing all data upto excel as Excel "TEXT" type.
/// </summary>
/// <returns></returns>
private static Dictionary<string, string> BuildExcelDataTypes()
{
Dictionary<string, string> dataTypeLookUp = new Dictionary<string, string>();
// I cannot get the Excel formatting correct here!?
dataTypeLookUp.Add(NETDataTypes.SHORT, ExcelDataTypes.NUMBER);
dataTypeLookUp.Add(NETDataTypes.INT, ExcelDataTypes.NUMBER);
dataTypeLookUp.Add(NETDataTypes.LONG, ExcelDataTypes.NUMBER);
dataTypeLookUp.Add(NETDataTypes.STRING, ExcelDataTypes.TEXT);
dataTypeLookUp.Add(NETDataTypes.DATE, ExcelDataTypes.DATETIME);
dataTypeLookUp.Add(NETDataTypes.BOOL, ExcelDataTypes.TEXT);
dataTypeLookUp.Add(NETDataTypes.DECIMAL, ExcelDataTypes.NUMBER);
dataTypeLookUp.Add(NETDataTypes.DOUBLE, ExcelDataTypes.NUMBER);
dataTypeLookUp.Add(NETDataTypes.FLOAT, ExcelDataTypes.NUMBER);
return dataTypeLookUp;
}
希望对你有用。
注意。我知道这种类型的答案是不受欢迎的,但我花了一些时间来开发它,但最终没有用到它——而是转向 COM/interop。不分享真是可惜!
关于c# - 通过 OleDb 使用 Microsoft Access 数据库引擎将 DataTable 插入 Excel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10591600/
我想制作一个引用另一个 excel 文件中的单元格的公式。我已经弄清楚了,如下所示: ='C:\Users\17\Desktop\[JAN-11 2011.xlsx]1'!$H$44 但由于此工作表中
有谁知道是否可以在 Excel 中生成缺少地址门牌号的报告? 例如,我们在 Apple St (no.5, 9, 11) 有三个地址记录,是否可以生成一个报告: 列出工作簿中每条街道的所有记录街道编号
这个问题已经有答案了: VBA auto hide ribbon in Excel 2013 (7 个回答) 已关闭 4 年前。 我试图在打开工作文件时隐藏我的丝带。 我已点击以下链接,但不断收到运行
我编写了一个 VBA 程序来删除元音。我无法从 excel 调用该函数。我收到 #NAME 错误。下面的代码 Function REMOVEVOWELS(Txt) As String 'Removes
嗨,我正在尝试在 MS excel 中应用一个函数(正确函数) 但是当我编写这个函数并使用填充句柄将其复制到其他单元格时,我在所有复制的单元格中得到相同的输出。 但是当我点击单元格时,引用是好的。但结
假设我有一个格式如下的电子表格: Sheet 1 | Sheet 2 name email | name e
我正在尝试简化财务报告中的数据输入,因此我尝试使用 Excel Visual Basic 制作表格。 到目前为止我做了2个用户表单,以后我会做5个。我做了用户表单,以便数据输入运算符(operator
我需要对单元格公式而不是单元格内容执行 Mid 或 Find。 如果我的单元格公式是: =[功能](Arg1, Arg2, Arg3) 我需要能够将 Arg2 提取到另一个单元格。 如果不使用 VBA
我想用 VBA 管理嵌入在另一个 Excel 文件中的 Excel 文件。我可以使用 .docx 文档找到很多结果,但我坚持使用 .xlsx 文档。 我最后一次尝试是使用 OLE 对象,但停留在“Sa
我最近一直在尝试使用 perl 和一些模块来读取 Excel 文件,尤其是单元格的格式。 例如,我写了一段使用 ParseExcel 模块读取单元格背景颜色的 perl 代码。然而,在测试时我注意到对
我目前正在使用 Maatwebsite 的 Excel 包,并且能够很好地生成一个包含我想要的列和值的表格,但我希望能够生成表格,其他表格位于单个 Excel 工作表的下方。可能吗? 上面附上的屏幕截
我需要以下方面的指导。我有一个包含 150000 条记录的文件 (excel)。收到另一个包含 5000-6000 条记录的 excel 文件,需要根据第二个文件中信息的某些条件删除该行。 我使用字典
我有我认为的标准公式,根据我使用的 Excel 版本、Excel 365 或 Excel 2019 的不同,它的行为会有所不同 =IF(F5=$M$1;IFERROR(IF(AND(IFERROR(F
信息: 我有一个名为 Demo.xlsm 的 Excel 文件 此文件包含一个名为 UserForm1 的用户表单,该用户表单会在打开文件时自动加载。 打开文件时,名为 Demo.xlsm 的工作簿也
我在A Excel工作表中有一个列,其值是1 1 1 2 2 2 3 3 3 4 4 4....,在B Excel工作表中有另一列,其值1 2 4 ....,什么我想要的是从 B 读取值并查看它们是否
所以,我有这个问题,我想通过使用 OR 函数检查调整列的条件来找到列的平均值,我尝试将 OR 放入 AverageIf 函数,失败,还尝试了“Average(IF( OR("再次不是正确的返回。认为这
假设我想要这种类型的formula = SUM(startcell:endcell)的答案,但是startcell和endcell组件发生了变化。 因此,我希望能够使用 和 中的任何值,而不是直接在公
我正在寻找一个简单的 Excel 宏,它可以根据单元格中的特定数字/值将行从一张工作表复制到 Excel 中的另一张工作表。我有两张纸。一个称为“master”,另一个表称为“top10”。 这是数据
我正在尝试调用另一个工作簿中的 Excel 宏。它是一个特定于工作表的宏,但 Microsoft 文档和网上研究给出的语法仅提供了一种仅通过工作簿访问宏的方法。该语法是: Application.Ru
我检查了很多不同的帖子,但似乎找不到我正在寻找的确切代码。另外,我以前从未使用过 VBA,因此我尝试从其他帖子中获取代码并输入我的信息以使其正常工作。还没有运气。在工作中,我们有一个 Excel 薪资
我是一名优秀的程序员,十分优秀!