最近要做一个导入数据的小程序,然后总结了一下C#读取Excel的方法和简单操作数据库的工具类
<pre class="csharp" name="code"> /// <summary>
/// Excel表通用访问类
/// 此类为抽象类,不允许实例化,在应用时直接调用
/// </summary>
public abstract class ExcelHelper
{
/// <summary>
/// 判断文件是否是Excel文件
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>结果</returns>
public static bool IsExcelFile(string filePath)
{
//如果该路径文件不存在,则返回False
if (!File.Exists(filePath)) { return false; }
//获得指定路径文件的扩展名
string extName = Path.GetExtension(filePath).Trim().ToLower();
if (".xls".Equals(extName) || ".xlsx".Equals(extName))
{
return true;
}
return false;
}
/// <summary>
/// 判断Excel的版本,返回连接字符串
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>连接字符串</returns>
public static string GetExcelConnString(string filePath)
{
//如果文件不是Excel文件则返回字空
if (IsExcelFile(filePath) == false) { return string.Empty; }
string extName = Path.GetExtension(filePath).Trim().ToLower();
if (".xlsx".Equals(extName))
{
//2007 2010版Excel连接字符串
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES;IMEX=0\"", filePath);
}
else if (".xls".Equals(extName))
{
//2003版Excel连接字符串
//return string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source ={0};Extended Properties = \"Excel 8.0;HDR=NO;IMEX=1\"", filePath);
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=YES;IMEX=0\"", filePath);
}
return string.Empty;
}
/// <summary>
/// 获得工作区的名字集合
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>名字字符串</returns>
public static string[] GetExcelSheetNames(string filePath)
{
string connString = GetExcelConnString(filePath);
if (string.IsNullOrEmpty(connString)) { return null; }
DataTable dt = null;
using (OleDbConnection conn = new OleDbConnection(connString))
{
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
conn.Close();
}
//如果没有结果返回空
if (dt == null) { return null; }
string[] sheetNames = new string[dt.Rows.Count];
int i = 0;
foreach (DataRow row in dt.Rows)
{
sheetNames[i] = row["TABLE_NAME"].ToString().Trim();
i++;
}
return sheetNames;
}
/// <summary>
/// 判断Sheet名称是否存在
/// </summary>
/// <param name="fileName">文件名称</param>
/// <param name="sheetName">Sheet名称</param>
/// <returns>是否存在</returns>
public static bool IsSheetNameExist(string filePath, string sheetName)
{
string[] sheetNames = GetExcelSheetNames(filePath);
if (sheetNames == null) { return false; }
foreach (string sn in sheetNames)
{
if (sn.Equals(sheetName)) { return true; }
}
return false;
}
/// <summary>
/// 获得制定sheet的数据
/// </summary>
/// <param name="filePath">Excel路径</param>
/// <param name="sheetName">sheet名称</param>
/// <returns>数据</returns>
public static DataTable GetExcelDataTable(string filePath, string sheetName)
{
string connString = GetExcelConnString(filePath);
//如果链接字符串错误或者未输入sheet名称则返回空
if (string.IsNullOrEmpty(connString) || string.IsNullOrEmpty(sheetName)) { return null; }
//定义返回的DataTable
DataTable dt = new DataTable();
//获得指定sheet的所有数据
string sqlExcel = string.Format("select * from [{0}]", sheetName);
using (OleDbConnection conn = new OleDbConnection(connString))
{
//打开连接
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(sqlExcel, conn);
try
{
adapter.Fill(dt);
}
catch
{
return null;
}
finally
{
//最后关闭连接
conn.Close();
}
}
return dt;
}
/// <summary>
/// 获得Excel文件第一个sheet的数据
/// </summary>
/// <param name="filePath">Excel路径</param>
/// <returns>数据</returns>
public static DataTable GetExcelDataTable(string filePath)
{
string connString = GetExcelConnString(filePath);
//如果链接字符串错误或者未输入sheet名称则返回空
if (string.IsNullOrEmpty(connString)) { return null; }
DataTable dt = new DataTable();
using (OleDbConnection conn = new OleDbConnection(connString))
{
conn.Open();
DataTable sheetNames = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
//获取第一个sheet的所有数据
string sqlExcel = string.Format("select * from [" + sheetNames.Rows[0]["TABLE_NAME"] + "]");
OleDbDataAdapter adapter = new OleDbDataAdapter(sqlExcel, conn);
try
{
adapter.Fill(dt);
}
catch (Exception ex)
{
throw new Exception("Excel文件打开失败!\r\n" + ex.Message);
}
finally
{
conn.Close();
}
}
return dt;
}
/// <summary>
/// 从DataTable中导出到Excel表中
/// </summary>
/// <param name="filePath">Excel文件</param>
/// <param name="sheetName">SheetName名称</param>
/// <param name="dataTable">DataTable</param>
/// <returns>是否导出成功</returns>
public static bool ExportExcel(string filePath, string sheetName, DataTable dataTable)
{
if (string.IsNullOrEmpty(filePath) || dataTable == null) { return false; }
string connString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES;IMEX=0\"", filePath);
if (Path.GetExtension(filePath).ToLower().Equals("xls")) { connString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=YES;IMEX=0\"", filePath); }
if (string.IsNullOrEmpty(sheetName)) { sheetName = "[Sheet1$]"; }
OleDbConnection conn = new OleDbConnection(connString);
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
//存在则删除
if (IsSheetNameExist(filePath, sheetName) == true) { return false; }
//创建表
string tableColumnStr = "";
DataColumn dc = null;
for (int i = 0; i < dataTable.Columns.Count; i++)
{
dc = dataTable.Columns[i];
tableColumnStr += "[" + dc.ColumnName + "] Varchar,";
}
tableColumnStr = tableColumnStr.Trim().Trim(',');
string sqlCreate = string.Format("Create TABLE [{0}]({1})", sheetName, tableColumnStr);
conn.Open();
cmd.CommandText = sqlCreate;
cmd.ExecuteNonQuery();
conn.Close();
string sqlInsert = "";
conn.Open();
DataRow dr = null;
try
{
for (int i = 0; i < dataTable.Rows.Count; i++)
{
dr = dataTable.Rows[i];
string tableValuesStr = "";
for (int j = 0; j < dataTable.Columns.Count; j++)
{
tableValuesStr += "'" + Convert.ToString(dr[j]) + "',";
}
sqlInsert = string.Format("INSERT INTO [{0}] VALUES({1})", sheetName, tableValuesStr.Trim().Trim(','));
cmd.CommandText = sqlInsert;
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
return false;
}
finally
{
conn.Close();
}
return true;
}
/ <summary>
/ 创建文件
/ </summary>
/ <param name="filePath">文件完整路径</param>
/ <returns>文件的完整路径</returns>
//public static String CreateExcel(string filePath)
//{
// //如果只是路径,则创建失败
// if (string.IsNullOrEmpty(Path.GetFileName(filePath))) { return null; }
// //如果该路径文件存在,返回完整路径
// if (File.Exists(filePath)) { return Path.GetFullPath(filePath); }
// //如果目录存在
// else if (Directory.Exists(Path.GetDirectoryName(filePath)))
// {
// File.Create(filePath);
// }
// else
// {
// if (!string.IsNullOrEmpty(Path.GetDirectoryName(filePath)))
// {
// Directory.CreateDirectory(Path.GetDirectoryName(filePath));
// }
// File.Create(filePath);
// }
// return Path.GetFullPath(filePath);
//}
}
数据库操作的工具类,网上有很多
/// <summary>
/// 数据库的通用访问类
/// 此类为抽象类,不允许实例化,在应用时直接调用
/// </summary>
public abstract class SqlHelper
{
//获取数据库连接字符串,其属于静态变量且只读,项目中所有文档可以直接使用,但不能修改
public static readonly string ConnectionStringLocalTransaction = System.Configuration.ConfigurationManager.AppSettings["SqlConnectionString"].ToString().Trim();
/// <summary>
/// 执行一条INSERT/UPDATE/DELETE SQL 语句
/// </summary>
/// <param name="cmdText">SQL语句</param>
/// <returns>执行是否成功</returns>
public static bool ExecuteNonQuery(string cmdText)
{
SqlCommand cmd = new SqlCommand();
//影响行数
int n = 0;
using (SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction))
{
cmd.Connection = conn;
//打开连接
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
conn.Open();
cmd.CommandText = cmdText;
cmd.CommandType = CommandType.Text;
n = cmd.ExecuteNonQuery();
}
if (n > 0)
{
//影响行数大于零则返回操作成功
return true;
}
else
{
//操作失败
return false;
}
}
/// <summary>
/// 用Transaction方式同时执行多条SQL语句,如果出错,回滚
/// 使用参数数组提供参数
/// </summary>
/// <remarks>
/// 使用示例:
/// ExecuteNonQuery(SqlStringList);
/// </remarks>
/// <param name="cmdTextList">SQL语句列表</param>
/// <returns>无返回值</returns>
public static void ExecuteNonQuery(List<string> cmdTextList)
{
SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);
SqlCommand cmd = new SqlCommand();
//打开连接
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
conn.Open();
SqlTransaction trans = conn.BeginTransaction("SampleTransaction");
try
{
PrepareCommand(cmd, conn, trans, CommandType.Text, null, null);
foreach (string cmdText in cmdTextList)
{
cmd.CommandText = cmdText;
cmd.ExecuteNonQuery();
}
trans.Commit();
}
catch (Exception ex)
{
//如果执行出错,则回滚
trans.Rollback();
throw ex;
}
finally
{
cmd.Dispose();
conn.Close();
}
}
/// <summary>
///执行一个不需要返回值的SqlCommand命令
/// 使用参数数组形式提供参数列表
/// </summary>
/// <remarks>
/// 使用示例:
/// int result = ExecuteNonQuery( CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="commandType">SqlCommand命令类型(存储过程,T-SQL语句,等等。)</param>
/// <param name="commandText">存储过程的名字或者T-SQL 语句</param>
/// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
/// <returns>返回是否执行成功</returns>
public static bool ExecuteNonQuery(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
//影响行数
int n = 0;
using (SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction))
{
//通过PrePareCommand方法将参数逐个加入到SqlCommand的参数集合中
PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
n = cmd.ExecuteNonQuery();
//清空SqlCommand中的参数列表
cmd.Parameters.Clear();
}
if (n > 0)
{
//影响行数大于零则返回操作成功
return true;
}
else
{
//操作失败
return false;
}
}
/// <summary>
/// 返回查询语句查询到的记录数
/// </summary>
/// <param name="cmdText">查询SQL语句</param>
/// <returns>查询到的记录数,0:未查找到 </returns>
public static int GetRecordQty(string cmdText)
{
int recordQty = 0;
SqlDataReader rd = ExecuteReader(cmdText);
while (rd.Read())
{
recordQty = recordQty + 1;
}
rd.Close();
return recordQty;
}
/// <summary>
/// 执行一条返回结果集的SqlCommand命令,通过专用的连接字符串。
/// 使用参数数组提供参数
/// </summary>
/// <remarks>
/// 使用示例:
/// SqlDataReader r = ExecuteReader( CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="commandType">SqlCommand命令类型(存储过程,T-SQL语句,等等。)</param>
/// <param name="commandText">存储过程的名字或者T-SQL 语句</param>
/// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
/// <returns>返回一个包含结果的SqlDataReader</returns>
public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);
// 在这里使用try/catch处理是因为如果方法出现异常,则SqlDataReader就不存在,
//CommandBehavior.CloseConnection的语句就不会执行,触发的异常由catch捕获。
//关闭数据库连接,并通过throw再次引发捕捉到的异常。
try
{
PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;
}
catch
{
conn.Close();
throw;
}
}
/// <summary>
/// 执行一条SQL查询语句,返回查询结果DataReader
/// </summary>
/// <param name="cmdText">查询SQL语句</param>
/// <returns>查询结果SqlDataReader</returns>
public static SqlDataReader ExecuteReader(string cmdText)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);
// 在这里使用try/catch处理是因为如果方法出现异常,则SqlDataReader就不存在,
//CommandBehavior.CloseConnection的语句就不会执行,触发的异常由catch捕获。
//关闭数据库连接,并通过throw再次引发捕捉到的异常。
try
{
PrepareCommand(cmd, conn, null, CommandType.Text, cmdText, null);
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return rdr;
}
catch
{
conn.Close();
throw;
}
}
/// <summary>
/// 执行一条SQL查询语句,将查询结果填充到指定的DataSet中
/// </summary>
/// <param name="cmdText">SQL查询语句</param>
/// <param name="dataSet">需要填充的DataSet</param>
public static void Fill(string cmdText, DataSet dataSet)
{
SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);
//初始化数据适配器
SqlDataAdapter da = new SqlDataAdapter(cmdText, conn);
try
{
//填充数据表
da.Fill(dataSet);
}
catch
{
throw;
}
finally
{
da.Dispose();
conn.Close();
}
}
/// <summary>
/// 执行一条SQL查询语句,将查询结果填充到指定的DataSet中
/// </summary>
/// <param name="cmdText">SQL查询语句</param>
/// <param name="dataSet">需要填充的DataSet</param>
public static void Fill(string cmdText, SqlParameter[] cmdParams, DataSet dataSet)
{
SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(cmdParams);
cmd.Connection = conn;
//初始化数据适配器
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
//填充数据表
da.Fill(dataSet);
}
conn.Close();
conn.Dispose();
}
/// <summary>
/// 执行一条SQL查询语句,将查询结果填充到DataSet指定的表中
/// </summary>
/// <param name="cmdText">SQL查询语句</param>
/// <param name="dataSet">需要填充的DataSet</param>
/// <param name="srcTable">填充的表名</param>
public static void Fill(string cmdText, DataSet dataSet, string srcTable)
{
SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);
//初始化数据适配器
SqlDataAdapter da = new SqlDataAdapter(cmdText, conn);
//如果DataSet中已经存在的表
if (dataSet.Tables.Contains(srcTable))
{
dataSet.Tables[srcTable].Clear();
}
try
{
//填充数据表
da.Fill(dataSet, srcTable);
}
catch
{
throw;
}
finally
{
da.Dispose();
conn.Close();
}
}
/// <summary>
/// 执行一条SQL查询语句,将查询结果填充到DataTable里面
/// </summary>
/// <param name="cmdText">SQL语句</param>
/// <param name="dataTable">需要填充的DataTable</param>
public static void Fill(string cmdText, DataTable dataTable)
{
SqlConnection conn = new SqlConnection(ConnectionStringLocalTransaction);
//初始化数据适配器
SqlDataAdapter da = new SqlDataAdapter(cmdText, conn);
if (dataTable.Rows.Count > 0)
{
dataTable.Rows.Clear();
}
try
{
//填充数据表
da.Fill(dataTable);
}
catch
{
throw;
}
finally
{
da.Dispose();
conn.Close();
}
}
/// <summary>
/// 执行一条SQL查询语句,返回执行结果DataTable
/// </summary>
/// <param name="cmdText">SQL查询语句</param>
/// <returns>查询结果DataTable</returns>
public static DataTable ExecuteQuery(string cmdText)
{
DataTable dataTable = new DataTable();
//填充DataTable
Fill(cmdText, dataTable);
//返回结果
return dataTable;
}
/// <summary>
/// 为执行命令准备参数
/// </summary>
/// <param name="cmd">SqlCommand 命令</param>
/// <param name="conn">已经存在的数据库连接</param>
/// <param name="trans">数据库事物处理</param>
/// <param name="cmdType">SqlCommand命令类型(存储过程,T-SQL语句,等等。)</param>
/// <param name="cmdText">Command text,T-SQL语句例如Select * from Products</param>
/// <param name="cmdParms">返回带参数的命令</param>
private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
{
//判断数据库连接状态
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
//判断SQL语句是否为空
if (!string.IsNullOrEmpty(cmdText))
{
cmd.CommandText = cmdText;
}
//else
//{
// throw new Exception("CommandText shouldn't be Null Or Empty!");
//}
//判断是否需要事物处理
if (trans != null)
{
cmd.Transaction = trans;
}
cmd.CommandType = cmdType;
if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
}
/// <summary>
/// 初始化Sql参数
/// </summary>
/// <param name="parameterName">参数名</param>
/// <param name="dataType">参数类型</param>
/// <param name="length">长度</param>
/// <param name="parameterDirection">参数方向</param>
/// <param name="parameterValue">参数值</param>
/// <returns></returns>
public static SqlParameter InitialParameter(string parameterName, SqlDbType dataType, int length, ParameterDirection parameterDirection, Object parameterValue)
{
SqlParameter param = new SqlParameter();
//参数名
param.ParameterName = parameterName;
//参数类型
param.SqlDbType = dataType;
//参数长度
if (length != 0)
{
param.Size = length;
}
//参数方向
param.Direction = parameterDirection;
//参数值
if (parameterValue != null && parameterValue.ToString() != "" && parameterDirection != ParameterDirection.ReturnValue)
{
param.Value = parameterValue;
}
else if ((parameterValue == null || parameterValue.ToString() == "") && parameterDirection != ParameterDirection.ReturnValue)
{
param.Value = System.DBNull.Value;
}
return param;
}
}
配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!--test数据库连接字符串-->
<add key="SqlConnectionString" value="Data Source=127.0.0.1;Initial Catalog=test;User ID=sa;Password=sa"/>
<!--日志文件地址-->
<add key="LogFilePath" value="E:/Log/"/>
<!--日志文件名称-->
<add key="LogFileName" value="SelectExcelLog.txt"/>
</appSettings>
</configuration>
自写的简单日志
<pre class="csharp" name="code">using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SelectExcel
{
/// <summary>
/// 日志 抽象类不允许实例化
/// </summary>
public static class LogHelper
{
static LogHelper()
{
//判断路径是否存在
if (!string.IsNullOrEmpty(_LogFilePath))
{
if (!Directory.Exists(_LogFilePath)) { Directory.CreateDirectory(_LogFilePath); }
}
//判断日志名称
if (string.IsNullOrEmpty(_LogFileName))
{
_LogFileName = "SelectExcelLog.txt";
}
}
/// <summary>
/// 日志文件地址
/// </summary>
private static string _LogFilePath = System.Configuration.ConfigurationManager.AppSettings["LogFilePath"].ToString().Trim();
/// <summary>
/// 日志文件名称
/// </summary>
private static string _LogFileName = System.Configuration.ConfigurationManager.AppSettings["LogFileName"].ToString().Trim();
/// <summary>
/// 记录日志信息
/// </summary>
/// <param name="infoStr">消息</param>
/// <returns>是否记录成功</returns>
public static bool Info(string infoStr)
{
//判断需要记录的日志是否为空
if (string.IsNullOrEmpty(infoStr.Trim())) { return false; }
return SaveLog(DateTime.Now.ToString(("yyyy年MM月dd日 HH:mm:ss")) + " - " + infoStr);
}
/// <summary>
/// 记录日志信息包含异常
/// </summary>
/// <param name="infoStr">消息</param>
/// <param name="ex">异常</param>
/// <returns>是否记录成功</returns>
public static bool Info(string infoStr, Exception ex)
{
if (ex == null) { return false; }
return SaveLog(DateTime.Now.ToString("yyyy年MM月dd日 HH:mm:ss") + " - " + infoStr + "\r\n异常:\r\n" + ex.Message);
}
/// <summary>
/// 写入日志文件
/// </summary>
/// <param name="logString"></param>
/// <returns></returns>
private static bool SaveLog(string logString)
{
try
{
FileStream fs = new FileStream(_LogFilePath.Trim('/') + "/" + _LogFileName, FileMode.Append);
StreamWriter sw = new StreamWriter(fs, UTF8Encoding.UTF8);
sw.WriteLine(logString);
sw.Close();
fs.Close();
return true;
}
catch
{
return false;
}
}
}
}
具体的逻辑就不贴了,毕竟都不一样