天天看點

c# 針對excel有合并行,導入資料庫

 根據配置檔案 将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>