通用Excel導入工具V1.0
使用說明
有時候我們的數據存放在Excel中(特別是對於用戶來說更喜歡使用Excel收集一些常用數據),而系統又需要這些數據來處理其他業務,那么此時我們就 需要將這些數據導入到數據庫中。但是鑒於Excel的樣式多種多樣,因此每次導入時都必須書寫很多重復的代碼。很明顯對於一個軟件開發者做這些重復勞動是 一件很無趣的事情。那么怎樣來尋找一種通用的方法呢?今天我們就看一下如何解決這個問題。
總體設計思路
設 計通用Excel的目的就是為了避免重復工作,也就是說不必因為Excel的樣式、數據等變化而重新從零做起、重復勞動。因此我們就必須抽取一個通用的東 西出來,使用時只需要關注相關的業務而不必過度關注相關excel操作和存儲。再簡單一點就是封裝共同點,暴漏個性點。考慮到這種情況,我們可以使用配置 文件的方式來解決這個問題。在配置文件中我們配置Excle要導入的表、字段等信息,在進行導入時再依據配置文件將數據導入到數據庫中。這樣一來,在需要 進行Excel導入時只需要為某個或多個excel配置一個xml文件,然后調用相關的類就可以完成整個excel導入工作了。
補充說明:通用的局限性
在 這里說明一下,雖然我們設計的是一個通用的Excel導入程序,但是這里的"通用"只是相對來說的,並不是考慮了所有Excel的情況,因為Excel的 設計情況十分的復雜多樣,要將所有的情況都考慮進去是一個漫長的過程。程序目前暫時不考慮包含統計行的情況(可以包含合並行、代碼表字段等)。
配置文件設計
考 慮使用xml配置的方式來設計通用Excel導入,如何設計好xml就成了設計的重點。對於單表導入(一個Excel主要導入到一個數據庫表中,不排除牽 扯其他代碼表的情況)我們的配置文件無論以數據庫為基礎設計(主要依據數據庫表結構)還是以Excel(主要依據Excel格式設計)為基礎設計都可以, 但如果是多表導入(也就是一個Excel可以導入到幾張表中的情況)考慮其復雜性還是以數據庫為基礎更為合適。基於此種考慮,我們整個配置設計會以數據庫 表結構為基礎來設計。最終的配置文件設計樣例如下:
<?xml version="1.0"?> <Config EndTag="RowBlank" HeaderIndex="1" DataIndex="2" WorkSheetCount="0"> <Table Name="" DeleteRepeat="true" ExcludedColumns="" > <Column IsPrimaryKey="" ColumnName="" HeaderText="" Required="true" DataType="number" DataLength="100" DefaultValue="" Comment=""> <CodeTalbe Name="" PrimaryKey="" ReferenceColumn="" Condition=""/> </Column> </Table> </Config>
Config節點
Config節點位於最外層,代表整個配置。其屬性EndTag(數據讀取的結束標志,例如"RowBlank"代表空行結束,在讀取Excel時遇到某行沒有任何數據的情況則視為結束;也可以為某個列地址(如C),在導入時到了此列為空就會結束導入操作);
HeaderIndex代表excel表頭對應的行值,相當於標題行(默認從1開始)。
DataIndex表示數據行起始行索引(從2開始)。
WorkSheetCount表示對於整個Excel文件,如果其包含多個工作表,則會根據所設的值處理前幾個工作表,屬性值為0,則會處理所有工作表,默認為0。
Table節點
Table節點位於Config節點內,對應數據庫中的表,可以有多個;
Name屬性對應要導入的表名稱;
DeleteRepeat屬性表示是否刪除重復行(如果為true則會根據主鍵先刪除重復行再執行插入操作);
ExcludedColumns表示排除列,多個列名使用","分割(這些字段不會導入)。
Column節點
Column節點位於Table節點內,對列的相應配置,通常有多個(注意對於excel中沒有的列,而數據庫表需要導入的,也需要配置Column節點,此時HeaderText為空或不配置HeaderText屬性);
IsPrimarykey屬性表示是否為主鍵(當Table節點配置DeleteRepeat為ture時必須至少指定一個Column節點的 IsPrimaryKey為true,此屬性是為delete條件做准備的[有可能它不是真正的主鍵]);
ColumnName表示對應的列名;
HeaderText表示對應的Excel列頭(在依據Excel別名導入時根據此值確定導入的列);
Required指定此列是否為必須導入的列(如果配置為true,excel中此列為空並且沒有配置默認值則會拋出異常);
DataType為數據類型(例如string、number、datetime用於數據校驗);
DefaultValue 為默認值(注意其值不一定是指定的字符值,可以是"Max"、"NewID"、如果指定為“WORKSHEETNAME”則取當前工作薄的名稱做為其值, 如果為Max,那么此列必須為數值類型,此時在導入的時候如果需要使用默認值,就會在原來數據庫表中此列最大值的基礎上加上1導入到數據庫中,如果為 NewID在導入的時候需要使用默認值系統就會自動生成Guid值);
Comment是此列的說明。
CodeTable節點
在Column節點中還可以配置CodeTable節點,表示代碼表。
Name屬性值表示引用表的表名稱;
PrimaryKey指待引用主表的主鍵,也就是子表的外鍵,Column配置節點的ColumnName屬性值應該與CodeTable節點的PrimaryKey屬性值設置一至,如以下配置:
<Column ColumnName="CategoryID" HeaderText="商品種類" DefaultValue="">
<CodeTalbe Name="Categories" PrimaryKey="CategoryID" ReferenceColumn="CategoryName"/>
</Column>
ReferenceColumn 表示對應代碼字段關聯名稱列,就是我們導入時所依據的excel對應值(例如CategoryID對應CategoryName,那么 ReferenceColumn就是CategoryName,往往Excel中可能存放的是類似於CategoryName的東西而不是 CategoryID,而導入操作時需要CategoryID)。
導入實例說明:
圖一 待導入Excel文件,可同時導入多個工作薄(WorkSheet)
圖二 設置導入規則
圖三 使用開發的導入工具進行導入
圖四 導入完成后入庫的數據