相關連結
最佳Excel匯入實踐(一)
最佳Excel匯入實踐(二)
最佳Excel匯入實踐(三)
最佳Excel匯入實踐(四)
最佳Excel匯入實踐(五)
上一篇我們講了Excel匯入模板的產生,這一節我們將完成資料匯入的功能。整個方案的主要類圖如下(圖中僅顯示出了主要的方法):
為了做到通用,能滿足所有業務單據的匯入,我們大量用到了.net的反射技術。如構造訂單表頭實體的代碼大致如下(構建表體的與此類似):
private Object GetHeadEntity(int rowIndex)
{
HSSFRow row=sheet.GetRow(rowIndex);
HSSFCell cell;
Type cls=Type.GetType(regulation.HeadClass);
Object obj=Activator.CreateInstance(cls);
PropertyInfo pi;
Object val;
int colIndex;
foreach(Column col in regulation.Columns)
{
if(!col.IsEntry)
{
//根據列名找出Excel中對應的列序號
colIndex=GetExcelColumnIndex(col.ColumnName);
cell=row.GetCell(colIndex);
//根據Column的資料類型取出Cell中的內容。如果為空白將取Column對象中定義的預設值
val=GetCellValue(cell,col.DataType);
//擷取實體類中的屬性
pi=cls.GetProperty(col.Property);
//給實體類中的屬性賦值
pi.SetValue(obj,val);
}
}
return obj;
}
執行儲存的Execute()方法代碼大致如下:
private void Execute()
{
int rowsCount = sheet.PhysicalNumberOfRows;
Object headEntity,entryEntity;
List <object> entries;
for (int rowIndex = 0; rowIndex < rowsCount; rowIndex++)
{
if (headEntity == null)
{
//構建表頭實體
headEntity = GetHeadEntity(rowIndex);
//構建表體實體
entries = new List<object>();
entryEntity = GetHeadEntity(rowIndex);
entries.Add(entryEntity);
}
//檢查表頭關鍵字段值是否與下一行相等,如果相等則當同一張單據處理,只用構建表體;如果不等說明是一張新的單據,要先把當前單據儲存。
if (IsSameToNextRow(rowIndex))
{
entryEntity = GetHeadEntity(rowIndex);
entries.Add(entryEntity);
}
else
{
//設定分錄屬性的值
Type head = Type.GetType(regulation.HeadClass);
PropertyInfo entryProperty = head.GetProperty(regulation.EntryProperty);
entryProperty.SetValue(headEntity, entries);
Type clsMethod=Type.GetType(regulation.MethodClass);
Object service=Activator.CreateInstance(clsMethod);
MethodInfo saveMethod = clsMethod.GetMethod(regulation.SaveMethod);
MethodInfo exValidateMethod = clsMethod.GetMethod(regulation.ExValidateMethod);
if (exValidateMethod != null)
//執行附加的檢查方法
exValidateMethod.Invoke(service, new object[]{headEntity});
if (saveMethod != null)
//執行儲存方法
exValidateMethod.Invoke(service,new object[]{headEntity});
//重設為一張新的單據
headEntity = null;
entries = null;
}
}
}
最後,細心的讀者可能會發現,上面的代碼我並沒有進行資料有效性驗證和出錯時的處理。在剛剛不久做的一個系統中,我是將最終的出錯資訊用動態產生的一張Excel顯示的,其顯示了和模板結構一樣的未經處理資料和批註的出錯資訊(正確資料已被匯入,不會顯示),這樣可以直接在這個Excel中對原來的資料進行修改後再直接執行匯入,這樣做也是為了讓使用者出錯後只用關心出錯後的資料,提高可用性。由於有效性驗證和出錯資訊顯示相對簡單,也不是本方案的重點,所以不作詳細說明。
至此,基本的匯入資料功能已經實現。我們發現,基於這個方案對於普通的Excel匯入主要的工作就是寫那個配置引入規則的XML檔案,所以可以輕鬆實現整個業務系統中所有的匯入工作。當然,本方案是以表頭表體的案例來進行設計的,對於單表結構稍作修改就可以實現,然而如果要對應一對多的關係,比如一條Excel中的記錄要寫到多個表中,本設計本不適用,但基本的基於反射的思想是不會變的,如果有需要讀者可以自已試試。