根據配置檔案 将EXCEL中資料讀入目标結構的DATASET,并對合并單元格作處理
1、類設計,EXCEL要據配置讀入DATASET
using System;
using System.Data;
using System.Collections;
using System.Data.OleDb;
namespace HKH.Common
{
/// <summary>
/// 從Excel導入資料到DataSet,帶有虛函數的基類
/// </summary>
/// <remarks>Create By Liwt on 2006 - 09 - 15
/// </remarks>
public class clsImportExcel
{
#region 變量
protected String m_MappingFile; //映射配置檔案路徑
protected String m_ExcelSheetName; //Excel中要導入資料的表名
protected String m_SqlTableName; //要導入的Sql表名,也可為其它類型的,如Oracle
protected ArrayList[] m_ColumnMapping; //列映射配置清單,包括3部分 0--Sql列名,1--Excel列索引
//2-- 如目前Excel行為空,是否指派為上一行的值
private bool isLoadMapping;
#endregion
#region 構造函數
/// <summary>
/// 無參構造
/// </summary>
public clsImportExcel()
{
m_MappingFile = "";
m_ExcelSheetName = "";
isLoadMapping = false;
m_ColumnMapping = new ArrayList[3];
m_ColumnMapping[0] = new ArrayList();
m_ColumnMapping[1] = new ArrayList();
m_ColumnMapping[2] = new ArrayList();
}
/// <summary>
/// 構造函數重載
/// </summary>
/// <param name="mappingFilePath">映射配置檔案路徑</param>
/// <param name="excelSheetName">Excel中要導入資料的表名</param>
public clsImportExcel(String mappingFilePath, String excelSheetName)
{
m_MappingFile = mappingFilePath;
m_ExcelSheetName = excelSheetName;
isLoadMapping = false;
m_ColumnMapping = new ArrayList[3];
m_ColumnMapping[0] = new ArrayList();
m_ColumnMapping[1] = new ArrayList();
m_ColumnMapping[2] = new ArrayList();
}
#endregion
#region 屬性
/// <summary>
/// 讀取或設定 映射配置檔案路徑
/// </summary>
public String MappingFilePath
{
get
{
return m_MappingFile;
}
set
{
m_MappingFile = value;
isLoadMapping = false;
}
}
/// <summary>
/// 讀取或設定 Excel中要導入資料的表名
/// </summary>
public String ExcelSheetName
{
get
{
return m_ExcelSheetName;
}
set
{
m_ExcelSheetName = value;
isLoadMapping = false;
}
}
#endregion
#region 公共方法
/// <summary>
/// 導入資料
/// </summary>
/// <param name="excelFilePath">要導入的Excel檔案路徑</param>
/// <param name="dsTarget">目标DataSet</param>
/// <returns>ture -- 成功, false -- 失敗
/// </returns>
public bool Import(String excelFilePath,ref DataSet dsTarget)
{
try
{
if (!isLoadMapping)
{
if (!LoadMapping())
{
return false;
}
}
//利用Ole讀取Excel資料
OleDbConnection oleConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + excelFilePath + ";");
OleDbDataAdapter oleDA = new OleDbDataAdapter("SELECT * FROM [" + m_ExcelSheetName + "$]",oleConn);
DataSet dsExcel = new DataSet();
oleDA.Fill(dsExcel,m_ExcelSheetName);
oleDA.Dispose();
oleConn.Dispose();
//對建立資料行緩存,以備填充對空單元格進行處理
DataRow tempRow = dsExcel.Tables[m_ExcelSheetName].Rows[0];
for ( int i = 0 ;i<dsExcel.Tables[m_ExcelSheetName].Rows.Count; i ++ )
{
DataRow excelRow = dsExcel.Tables[m_ExcelSheetName].Rows[i];
//調用導入前資料處理函數,并根據傳回值确定下一步處理
if (!ImportingBefore(ref excelRow))
{
continue;
}
DataRow sqlNewRow = dsTarget.Tables[0].NewRow();
for ( int j = 0 ;j<m_ColumnMapping[0].Count; j ++ )
{
String sqlColName = m_ColumnMapping[0][j].ToString();
int excelColindex = (int)m_ColumnMapping[1][j];
bool inherit = Convert.ToBoolean(m_ColumnMapping[2][j]);
//如果目前行目前列為空
if (Convert.IsDBNull(excelRow[excelColindex]))
{
//如果允許以臨時值填充
if (inherit)
{
sqlNewRow[sqlColName] = tempRow[excelColindex];
}
}
else
{
//填充資料,更新緩存行資料
sqlNewRow[sqlColName] = excelRow[excelColindex];
tempRow[excelColindex] = excelRow[excelColindex];
}
}
//調用導入後資料處理,并根據傳回值決定下一步處理
if (ImportingAfter(ref sqlNewRow))
{
dsTarget.Tables[0].Rows.Add(sqlNewRow);
}
}
return true;
}
catch(Exception ex)
{
throw ex;
}
}
#endregion
#region 受保護的虛函數,子類須重寫
/// <summary>
/// 在導入前對Excel行資料進行處理
/// </summary>
/// <param name="drExcelRow">正在讀取的目前Excel行</param>
/// <returns>true -- 繼續處理,false -- 跳過目前行
/// </returns>
protected virtual bool ImportingBefore(ref DataRow drExcelRow)
{
return true;
}
/// <summary>
/// 在資料轉存後對目前行進行處理
/// </summary>
/// <param name="drSqlRow">已經轉存資料的目前Sql行</param>
/// <returns>true -- 繼續處理,false -- 跳過目前行
/// </returns>
protected virtual bool ImportingAfter(ref DataRow drSqlRow)
{
return true;
}
#endregion
#region 私有方法
/// <summary>
/// 加載配置檔案,取得表和列的映射
/// </summary>
/// <returns></returns>
private bool LoadMapping()
{
try
{
//清除已過時的配置
m_ColumnMapping[0].Clear();
m_ColumnMapping[1].Clear();
m_ColumnMapping[2].Clear();
if ( null == m_MappingFile || "" == m_MappingFile )
{
throw new Exception("找不到配置檔案");
}
//讀入配置檔案
DataSet dsMaping = new DataSet();
dsMaping.ReadXml(m_MappingFile);
if (dsMaping.Tables.Count == 0)
{
throw new Exception("讀取配置檔案失敗");
}
//讀取表映射
DataRow[] tableMap = dsMaping.Tables["TableMapping"].Select("excelSheet='" + m_ExcelSheetName + "'");
if (tableMap.Length != 1)
{
throw new Exception("該Sheet不存在或多次配置");
}
//讀取列映射
DataRow[] colMap = dsMaping.Tables["ColumnMapping"].Select("TableMapping_id="+tableMap[0]["TableMapping_id"].ToString());
if ( colMap.Length <= 0)
{
throw new Exception("沒有為該表配置列映射");
}
for (int i = 0; i < colMap.Length; i ++)
{
m_ColumnMapping[0].Add(colMap[i]["sqlCol"]);
m_ColumnMapping[1].Add(ExecColumnIndex(colMap[i]["excelCol"].ToString()));
m_ColumnMapping[2].Add(colMap[i]["inherit"]);
}
//設定為已加載配置
isLoadMapping = true;
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 計算EXCEL中列标題對應的索引 (A = 0 )
/// </summary>
/// <param name="strColumnTitle"></param>
/// <returns></returns>
private int ExecColumnIndex( string strColumnTitle )
{
if ( null == strColumnTitle || "" == strColumnTitle.Trim() )
return -1;
string temp = strColumnTitle.Trim().ToUpper();
if( 2 == temp.Length )
{
// return temp[0] - 65 + 26 + temp[1] - 65;
return temp[0] - 104 + temp[1];
}
else
{
return temp[0] - 65;
}
}
#endregion
}
}
2、配置檔案XSD
3、 配置檔案樣例
excelSheet ----要導入資料庫的EXCEL檔案中的工作薄名
SQLTABLE---要導入的資料庫表名
EXCELCOL--EXCEL表中列标頭
SQLCOL--SQL資料庫中列名
inherit---當EXCEL中有表格合并時,是否繼續上面的單元格值,此處用于拆解單元格,本處指合并行,TRUE為拆解,即所有單元格都以合并值填充,為FALSE則第一行為填充值,其它各行以空填充
<ImportConfiguration>
<TableMapping excelSheet="Sheet1" sqlTable="CNKI_illegalIPInfo">
<ColumnMapping excelCol="A" sqlCol="UnitName" inherit="false"/>
<ColumnMapping excelCol="B" sqlCol="StartIP" inherit="false"/>
<ColumnMapping excelCol="C" sqlCol="EndIP" inherit="false"/>
</TableMapping>
</ImportConfiguration>