Commit 950b4433 by Ivan Lan

增加 import 测试

parent bb4f3054
...@@ -2,7 +2,7 @@ PATH ...@@ -2,7 +2,7 @@ PATH
remote: . remote: .
specs: specs:
tallty_import_export (0.1.0) tallty_import_export (0.1.0)
activesupport (~> 6.0.3) activesupport
caxlsx caxlsx
roo roo
roo-xls roo-xls
......
...@@ -8,7 +8,10 @@ module TalltyImportExport ...@@ -8,7 +8,10 @@ module TalltyImportExport
autoload :Common autoload :Common
autoload :Exportable autoload :Exportable
autoload :Export
autoload :Importable autoload :Importable
autoload :Import
autoload :Context
class Error < StandardError; end class Error < StandardError; end
end end
...@@ -3,7 +3,7 @@ module TalltyImportExport ...@@ -3,7 +3,7 @@ module TalltyImportExport
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do |base| included do |base|
base.include(Common) # base.include(Common)
base.const_set('Export', Class.new(TalltyImportExport::Export)) base.const_set('Export', Class.new(TalltyImportExport::Export))
end end
......
class Import module TalltyImportExport
attr_reader :klass, :content, :headers, :primary_keys class Import
require 'roo'
attr_reader :klass, :context, :headers, :primary_keys
def initialize klass def initialize klass
@klass = klass @klass = klass
@content = Context.new({}) @context = Context.new({})
end end
# key: 属性的英文名 # key: 属性的英文名
...@@ -18,15 +20,14 @@ class Import ...@@ -18,15 +20,14 @@ class Import
options = options.with_indifferent_access options = options.with_indifferent_access
self.headers = options.delete(:headers) || import_headers self.headers = options.delete(:headers) || import_headers
self.primary_keys = options.delete(:primary_keys) || headers.map { |header| header[:primary_key] ? header[:key].to_sym : nil }.compact @primary_keys = options.delete(:primary_keys) || headers.map { |header| header[:primary_key] ? header[:key].to_sym : nil }.compact
excel_hash = headers.reduce({}) do |h, header| excel_hash = headers.reduce({}) do |h, header|
h[header[:key]] = header[:name] h[header[:key]] = header[:name]
h h
end end
file_path = xlsx_file.is_a?(String) ? xlsx_file : xlsx_file.path file_path = xlsx_file.is_a?(String) ? xlsx_file : xlsx_file.path
xlsx = Roo::Excelx.new(file_path) xlsx = ::Roo::Excelx.new(file_path)
xlsx.each_with_pagename do |_sheetname, sheet| xlsx.each_with_pagename do |_sheetname, sheet|
sheet.each(**excel_hash).with_index do |line_info, index| sheet.each(**excel_hash).with_index do |line_info, index|
next if index == 0 next if index == 0
...@@ -36,6 +37,7 @@ class Import ...@@ -36,6 +37,7 @@ class Import
# 处理每行对于导入的动作,处理line_info # 处理每行对于导入的动作,处理line_info
import_record(line_info, associations) import_record(line_info, associations)
context.last_line_info = line_info
end end
end end
end end
...@@ -45,7 +47,9 @@ class Import ...@@ -45,7 +47,9 @@ class Import
header = headers.find do |_header| header = headers.find do |_header|
_header[:key].to_sym == k.to_sym _header[:key].to_sym == k.to_sym
end end
val = header[:convert] ? send(header[:convert], v) : v # header[:convert] = handle_xxx
# handle_xxx(val, processing_line_info, raw_line_info)
val = header[:convert] ? send(header[:convert], v, h, line_info) : v
if header[:json] if header[:json]
h[header[:json]] ||= {} h[header[:json]] ||= {}
h[header[:json]][k] = val h[header[:json]][k] = val
...@@ -57,7 +61,15 @@ class Import ...@@ -57,7 +61,15 @@ class Import
end end
def import_headers def import_headers
klass.try(:headers) || kless.try(:model_headers) klass.try(:headers) || klass.try(:model_headers)
end
def headers= val
@headers = val.map { |header| header.with_indifferent_access }
end
def skip val, processing_line_info, raw_line_info
# do nothing there, use for header[:convert]
end end
### 这个方法是可以由复杂业务进行重载的 ### ### 这个方法是可以由复杂业务进行重载的 ###
...@@ -70,4 +82,5 @@ class Import ...@@ -70,4 +82,5 @@ class Import
end end
end end
end
end end
...@@ -3,13 +3,13 @@ module TalltyImportExport ...@@ -3,13 +3,13 @@ module TalltyImportExport
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do |base| included do |base|
base.include(Common) # base.include(Common)
base.const_set('Import', Class.new(TalltyImportExport::Import)) base.const_set('Import', Class.new(TalltyImportExport::Import))
end end
module ClassMethods module ClassMethods
def import_instance def import_instance
Import.new(self) const_get('Import').new(self)
end end
def import_xlsx *args def import_xlsx *args
......
RSpec.describe TalltyImportExport::Importable do
before do
class Test
include TalltyImportExport::Importable
class << self
def model_headers
[
{ key: 'name', name: '名称' },
{ key: 'code', name: '学号', convert: :handle_code },
{ key: 'sub_code', name: '副学号', convert: :skip},
{ key: 'meta1', name: 'meta字段1', json: :meta },
{ key: 'meta2', name: 'meta字段2', json: :meta },
]
end
end
class Import
def import_record line_info, associations
associations << line_info
end
def handle_code code, processing_line_info, raw_line_info
"#{code}_#{raw_line_info['sub_code']}"
end
end
end
end
it "has a version number" do
# 名称 学号 副学号 meta字段1 meta字段2
# 1 20070101 1 meta1 metaA
# 2 20070102 2 meta2 metaB
# 3 20070103 3 meta3 metaC
# 4 20070104 4 meta4 metaD
# 5 20070105 5 meta5 metaE
@result = []
Test.import_xlsx('./spec/test1.xlsx', @result)
expect(@result).to eq([
{"name"=>1, "code"=>"20070101_1", "sub_code"=>nil, "meta"=>{"meta1"=>"meta1", "meta2"=>"metaA"}},
{"name"=>2, "code"=>"20070102_2", "sub_code"=>nil, "meta"=>{"meta1"=>"meta2", "meta2"=>"metaB"}},
{"name"=>3, "code"=>"20070103_3", "sub_code"=>nil, "meta"=>{"meta1"=>"meta3", "meta2"=>"metaC"}},
{"name"=>4, "code"=>"20070104_4", "sub_code"=>nil, "meta"=>{"meta1"=>"meta4", "meta2"=>"metaD"}},
{"name"=>5, "code"=>"20070105_5", "sub_code"=>nil, "meta"=>{"meta1"=>"meta5", "meta2"=>"metaE"}},
])
end
end
...@@ -2,8 +2,4 @@ RSpec.describe TalltyImportExport do ...@@ -2,8 +2,4 @@ RSpec.describe TalltyImportExport do
it "has a version number" do it "has a version number" do
expect(TalltyImportExport::VERSION).not_to be nil expect(TalltyImportExport::VERSION).not_to be nil
end end
it "does something useful" do
expect(false).to eq(true)
end
end end
File added
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment