2016-08-05 45 views
0

我正在使用引擎,在這裏我使用Roo gem解析excel文件。我面臨的問題是我不知道如何映射列。Rails將excel文件的列映射到db列

例如,我的db-table有列first_name,last_name,emp_id,designation等。但我的excel文件可以有任何列名稱,例如,它可能是fnamelnamee_iddesignation或者它可能是FirstNameLastNameEmployeeId

現在我該怎樣映射,使得它會被存儲在相應的列數據。

我檢查了this question但我該如何設置別名,因爲我的Excel列標題可以是任何東西。如果可以別名請告訴我我該怎麼做。這是我第一次使用rails引擎。我也是新來的紅寶石。 任何幫助,將不勝感激。

+0

而不是使用動態的數據庫列,它可能是更容易的CSV序列化到數據庫中的一個字符串,商店,答覆方式 –

回答

1

如果Excel列順序是固定的比你可以存儲這樣的數據:

@xls = Roo::Spreadsheet.open(file, extension: :xls) 
for i in [email protected]_row 
    Table.create(first_name: @xls.row(i)[1],last_name: @xls.row(i)[2],..) 
end 

希望它會幫助你...

+0

感謝,我會嘗試這一點。 – Sinscary

+0

歡迎,如果您需要進一步幫助,請在此處註釋... –

+0

您的答案適用於小型excel文件,但是當db中有許多列時,此代碼將變得更大。有沒有什麼辦法可以對'Table.create(first_name:@ xls.row(i)[1],last_name:@ xls.row(i)[2],..)'這個代碼進行優化 – Sinscary

1

對於這種東西,我會用一個服務對象。

class ImportExcel 
    DEFAULT_MAPPING = { 
     excel_col_name => db_colname 
    }.freezy 

    def initialize(mapping=nil, model_class=nil) 
     @mapping = mapping || DEFAULT_MAPPING 
     @model_class = model_class || DefaultModelClass 
    end 

    def import(excel_sheet) 
     records = [] 
     header = excel_sheet.first_row 
     2.upto(excel_sheet.last_row) do |line| 
     record = @model_class.new 
     records << record 
     header.each_with_index do |name, col| 
      record[@mapping[name]]= excel_sheet.row[line][col] 
     end 
     end 
     records 
    end 
end 

# Where ever 
importer = ImportExcel.new({ a: :b , c: :d}, MyModel) 
new_records = importer.import(sheet) 
new_records.map(&:save!) 
+0

好吧,我想保存在數據庫中的數據。你的映射似乎工作,但你會保存數組到db。 – Sinscary

+0

你可以打電話給record.save!在標題之後... end或imorter.import(...)。map(&:save!) – slowjack2k

+0

我還有一個疑問。實際上,我正在構建一個引擎,所以我的引擎只會將列和數據提供給應用程序的模型,而我的引擎會將這些數據保存到數據庫。在這種情況下我們如何映射數據。 – Sinscary