tallty_import_export 1.1.0 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +13 -9
- data/lib/tallty_import_export/attr/export_header.rb +1 -1
- data/lib/tallty_import_export/common.rb +2 -2
- data/lib/tallty_import_export/excel.rb +1 -0
- data/lib/tallty_import_export/export.rb +33 -23
- data/lib/tallty_import_export/export_form.rb +1 -1
- data/lib/tallty_import_export/import.rb +68 -28
- data/lib/tallty_import_export/importable.rb +4 -0
- data/lib/tallty_import_export/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 284928193ebed0e079f44ba98ee7a2f0d51c05f0c1ea5100dd68973940f56369
|
4
|
+
data.tar.gz: 75dbf1351c7a08ce445b508ea60aba31da811fcfc87e9355c5f8c710f66be47a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d335d50b6059608dcdb41cc3f44e16f75746d900d698ff1ea3960de8d2541b0fdfadf9b7fceeadef33f70906a3c4673f8247c6aa9406195826f0b45a9977d5e
|
7
|
+
data.tar.gz: e72f4ddf2a9bb43f00d031aa74c56723870b63ce0b548110d6c3112a0945dbd21f789759a88834fb1101f24c61e30ce179bd14dea19001c2e4bb81f5e7721c9e
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tallty_import_export (1.
|
4
|
+
tallty_import_export (1.1.1)
|
5
5
|
activesupport
|
6
6
|
attr_json
|
7
7
|
caxlsx
|
@@ -27,27 +27,31 @@ GEM
|
|
27
27
|
tzinfo (~> 2.0)
|
28
28
|
attr_json (1.4.0)
|
29
29
|
activerecord (>= 5.0.0, < 7.1)
|
30
|
-
caxlsx (3.
|
30
|
+
caxlsx (3.3.0)
|
31
31
|
htmlentities (~> 4.3, >= 4.3.4)
|
32
32
|
marcel (~> 1.0)
|
33
33
|
nokogiri (~> 1.10, >= 1.10.4)
|
34
34
|
rubyzip (>= 1.3.0, < 3)
|
35
35
|
concurrent-ruby (1.1.10)
|
36
|
+
connection_pool (2.3.0)
|
36
37
|
diff-lcs (1.4.4)
|
37
38
|
htmlentities (4.3.4)
|
38
|
-
i18n (1.
|
39
|
+
i18n (1.12.0)
|
39
40
|
concurrent-ruby (~> 1.0)
|
40
41
|
marcel (1.0.2)
|
41
42
|
mini_portile2 (2.8.0)
|
42
|
-
minitest (5.
|
43
|
-
nokogiri (1.13.
|
43
|
+
minitest (5.16.3)
|
44
|
+
nokogiri (1.13.9)
|
44
45
|
mini_portile2 (~> 2.8.0)
|
45
46
|
racc (~> 1.4)
|
46
47
|
racc (1.6.0)
|
47
48
|
rake (12.3.3)
|
48
|
-
redis (
|
49
|
-
|
50
|
-
|
49
|
+
redis (5.0.5)
|
50
|
+
redis-client (>= 0.9.0)
|
51
|
+
redis-client (0.10.0)
|
52
|
+
connection_pool
|
53
|
+
redis-objects (1.7.0)
|
54
|
+
redis
|
51
55
|
roo (2.9.0)
|
52
56
|
nokogiri (~> 1)
|
53
57
|
rubyzip (>= 1.3.0, < 3.0.0)
|
@@ -77,7 +81,7 @@ GEM
|
|
77
81
|
activesupport (>= 5.0)
|
78
82
|
tallty_form (1.0.0)
|
79
83
|
tallty_duck_record
|
80
|
-
tzinfo (2.0.
|
84
|
+
tzinfo (2.0.5)
|
81
85
|
concurrent-ruby (~> 1.0)
|
82
86
|
zip-zip (0.3)
|
83
87
|
rubyzip (>= 1.0.0)
|
@@ -14,7 +14,7 @@ module TalltyImportExport
|
|
14
14
|
attr_json :json, :string
|
15
15
|
attr_json :select, ActiveModel::Type::Value.new, array: true
|
16
16
|
attr_json :source, :boolean
|
17
|
-
attr_json :proc, ActiveModel::Type::Value.new
|
17
|
+
attr_json :proc, ActiveModel::Type::Value.new
|
18
18
|
attr_json :children, self.to_type, array: true
|
19
19
|
|
20
20
|
attr_accessor :depth, :parent_path, :seq
|
@@ -6,14 +6,14 @@ module TalltyImportExport
|
|
6
6
|
end
|
7
7
|
|
8
8
|
module ClassMethods
|
9
|
-
def model_headers
|
9
|
+
def model_headers(**args)
|
10
10
|
columns.map do |column|
|
11
11
|
{
|
12
12
|
key: column.name,
|
13
13
|
name: column.comment || column.name,
|
14
14
|
attr_type: column.type,
|
15
15
|
format: column.type == :string ? :string : nil,
|
16
|
-
primary_key: column.name == 'id'
|
16
|
+
primary_key: column.name == 'id',
|
17
17
|
}
|
18
18
|
end
|
19
19
|
end
|
@@ -2,7 +2,7 @@ module TalltyImportExport
|
|
2
2
|
class Export
|
3
3
|
attr_reader :klass, :context
|
4
4
|
|
5
|
-
def initialize
|
5
|
+
def initialize(klass)
|
6
6
|
@klass = klass
|
7
7
|
@context = Context.new({})
|
8
8
|
end
|
@@ -34,7 +34,7 @@ module TalltyImportExport
|
|
34
34
|
# proc: proc或者lamda,支持call,传入 record 和 context
|
35
35
|
# list: 对于list布局的,进行嵌套,生成子表格
|
36
36
|
|
37
|
-
def export_xlsx
|
37
|
+
def export_xlsx(records, **options)
|
38
38
|
records = with_scope records
|
39
39
|
process_options(options)
|
40
40
|
|
@@ -46,14 +46,16 @@ module TalltyImportExport
|
|
46
46
|
|
47
47
|
if @group_by.present?
|
48
48
|
if records.is_a?(Array)
|
49
|
-
records.group_by { |record| record.send(@group_by)}.each do |key, group_records|
|
49
|
+
records.group_by { |record| record.send(@group_by) }.each do |key, group_records|
|
50
50
|
next unless key.present?
|
51
|
+
|
51
52
|
@group_key = key
|
52
53
|
export_workbook workbook, group_records, **options
|
53
54
|
end
|
54
55
|
else
|
55
56
|
records.group(@group_by).count.keys.each do |key|
|
56
57
|
next unless key.present?
|
58
|
+
|
57
59
|
@group_key = key
|
58
60
|
export_workbook workbook, records.ransack("#{@group_where}" => key).result, **options
|
59
61
|
end
|
@@ -72,16 +74,16 @@ module TalltyImportExport
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
75
|
-
def export_workbook
|
77
|
+
def export_workbook(workbook, association_records, **options)
|
76
78
|
# excel导出样式
|
77
79
|
alignment = { vertical: :center, horizontal: :center }
|
78
80
|
border = { color: '969696', style: :thin }
|
79
81
|
title1 = workbook.styles.add_style(alignment: alignment, border: border, sz: 12, b: true)
|
80
|
-
title2 = workbook.styles.add_style(alignment: alignment, border: border, bg_color:
|
82
|
+
title2 = workbook.styles.add_style(alignment: alignment, border: border, bg_color: '2a5caa', sz: 12, fg_color: 'fffffb')
|
81
83
|
title3 = workbook.styles.add_style(alignment: alignment.merge(wrap_text: true), border: border, sz: 10)
|
82
|
-
headers = export_headers_result
|
84
|
+
headers = export_headers_result(**options)
|
83
85
|
|
84
|
-
_sheet_name = respond_to?(:sheet_name) ?
|
86
|
+
_sheet_name = respond_to?(:sheet_name) ? sheet_name : nil
|
85
87
|
|
86
88
|
workbook.add_worksheet(name: _sheet_name) do |sheet|
|
87
89
|
if respond_to?(:first_header)
|
@@ -90,7 +92,7 @@ module TalltyImportExport
|
|
90
92
|
sheet.add_row [first_header], style: title1, height: 30
|
91
93
|
end
|
92
94
|
|
93
|
-
sheet.add_row headers.map{|header| header[:name]}, style: title2, height: 25
|
95
|
+
sheet.add_row headers.map { |header| header[:name] }, style: title2, height: 25
|
94
96
|
|
95
97
|
last_row = nil
|
96
98
|
merge_column_hash = {}
|
@@ -133,12 +135,12 @@ module TalltyImportExport
|
|
133
135
|
merge_column_hash.each do |col_index, row_arr|
|
134
136
|
row_arr.each do |arr|
|
135
137
|
sheet.merge_cells(
|
136
|
-
Axlsx
|
138
|
+
Axlsx.cell_r(col_index, arr.first) + ':' + Axlsx.cell_r(col_index, arr.last),
|
137
139
|
)
|
138
140
|
end
|
139
141
|
end
|
140
142
|
end
|
141
|
-
sheet.column_widths(*headers.map{|header| (header[:width] || @width).to_f})
|
143
|
+
sheet.column_widths(*headers.map { |header| (header[:width] || @width).to_f })
|
142
144
|
end
|
143
145
|
end
|
144
146
|
|
@@ -147,7 +149,7 @@ module TalltyImportExport
|
|
147
149
|
{}
|
148
150
|
end
|
149
151
|
|
150
|
-
def process_options
|
152
|
+
def process_options(options = {})
|
151
153
|
options = export_options.merge(options).with_indifferent_access
|
152
154
|
|
153
155
|
@row_height ||= options.delete(:row_height) || 25
|
@@ -161,30 +163,30 @@ module TalltyImportExport
|
|
161
163
|
context.params = @params
|
162
164
|
end
|
163
165
|
|
164
|
-
def with_scope
|
166
|
+
def with_scope(records)
|
165
167
|
records
|
166
168
|
end
|
167
169
|
|
168
|
-
def export_headers_result
|
170
|
+
def export_headers_result(**options)
|
169
171
|
if @headers.present? && @group_key.blank?
|
170
172
|
headers_hash = @headers.to_h { |header| [header.with_indifferent_access[:key], header] }.with_indifferent_access
|
171
173
|
export_headers(**options.symbolize_keys).select do |_header|
|
172
174
|
_header.with_indifferent_access[:key].to_s.in?(headers_hash.keys)
|
173
175
|
end.map do |_header|
|
174
176
|
_header = _header.with_indifferent_access
|
175
|
-
_header.merge(headers_hash[_header[:key]].delete_if { |
|
177
|
+
_header.merge(headers_hash[_header[:key]].delete_if { |_k, v| v.blank? })
|
176
178
|
end
|
177
179
|
else
|
178
180
|
@headers = export_headers(**options.symbolize_keys)
|
179
181
|
end
|
180
182
|
end
|
181
183
|
|
182
|
-
def export_headers
|
184
|
+
def export_headers(**args)
|
183
185
|
@headers || klass.try(:headers) || klass.try(:model_headers)
|
184
186
|
end
|
185
187
|
|
186
188
|
# 处理一个记录的数据
|
187
|
-
def handle_data
|
189
|
+
def handle_data(record, header, index = 0, **opts)
|
188
190
|
data =
|
189
191
|
if header[:key] == '_index'
|
190
192
|
index
|
@@ -200,28 +202,36 @@ module TalltyImportExport
|
|
200
202
|
data = handle_format(data, header, **opts)
|
201
203
|
data = handle_data_type(data, **opts)
|
202
204
|
data = handle_select(data, header, **opts)
|
203
|
-
rescue
|
205
|
+
rescue StandardError
|
204
206
|
''
|
205
207
|
end
|
206
208
|
|
207
|
-
def try_chain
|
209
|
+
def try_chain(record, arr)
|
208
210
|
arr.reduce(record) do |r, m|
|
209
211
|
if r.is_a?(Array)
|
210
212
|
r.try(m) || r.try(:[], m.to_i)
|
211
213
|
else
|
212
|
-
|
214
|
+
begin
|
215
|
+
r.try(:[], m)
|
216
|
+
rescue StandardError
|
217
|
+
nil
|
218
|
+
end || begin
|
219
|
+
r.try(:[], m.to_sym)
|
220
|
+
rescue StandardError
|
221
|
+
nil
|
222
|
+
end || r.try(m)
|
213
223
|
end
|
214
224
|
end
|
215
225
|
end
|
216
226
|
|
217
|
-
def try_method
|
227
|
+
def try_method(record, method, prefix: nil)
|
218
228
|
prefix_arr = prefix.to_s.split(/\./)
|
219
229
|
arr = method.to_s.split(/\./)
|
220
230
|
try_chain record, prefix_arr + arr
|
221
231
|
end
|
222
232
|
|
223
233
|
# 根据数据类型 attr_type 进行数据的格式化
|
224
|
-
def handle_format
|
234
|
+
def handle_format(data, header, **opts)
|
225
235
|
case header[:attr_type].to_s
|
226
236
|
when 'string'
|
227
237
|
data.to_s
|
@@ -234,7 +244,7 @@ module TalltyImportExport
|
|
234
244
|
end
|
235
245
|
end
|
236
246
|
|
237
|
-
def handle_data_type
|
247
|
+
def handle_data_type(data, **opts)
|
238
248
|
if data.is_a?(Time)
|
239
249
|
data.in_time_zone.strftime('%F %H:%M')
|
240
250
|
elsif data.is_a?(Date)
|
@@ -257,7 +267,7 @@ module TalltyImportExport
|
|
257
267
|
end
|
258
268
|
end
|
259
269
|
|
260
|
-
def handle_select
|
270
|
+
def handle_select(data, header, **opts)
|
261
271
|
if header[:select].present?
|
262
272
|
select_option = header[:select].find { |option| option[:value].to_s == data.to_s }
|
263
273
|
select_option.present? ? select_option[:label] : data
|
@@ -126,7 +126,7 @@ module TalltyImportExport
|
|
126
126
|
|
127
127
|
def export_headers_result **options
|
128
128
|
@headers = options.symbolize_keys[:headers]
|
129
|
-
super(**options)
|
129
|
+
@headers = super(**options)
|
130
130
|
@headers = TalltyImportExport::Attr::ExportHeader.new({ items: @headers })
|
131
131
|
end
|
132
132
|
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module TalltyImportExport
|
2
2
|
class Import
|
3
3
|
require 'roo'
|
4
|
+
require 'roo-xls'
|
4
5
|
attr_reader :klass, :context, :primary_keys, :associations
|
5
6
|
|
6
|
-
def initialize
|
7
|
+
def initialize(klass)
|
7
8
|
@klass = klass
|
8
9
|
@context = Context.new({})
|
9
10
|
end
|
@@ -20,13 +21,41 @@ module TalltyImportExport
|
|
20
21
|
# skip: 用来综合使用的数据,但是不导入
|
21
22
|
|
22
23
|
# xlsx_file 为 file path or file object or TalltyImportExport::Excel.new
|
23
|
-
def import_xlsx
|
24
|
+
def import_xlsx(xlsx_file, associations, **options)
|
24
25
|
process_xlsx_line_info(xlsx_file, associations, **options) do |line_info, associations|
|
25
26
|
process_line_info(line_info, associations)
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
+
# 导出excel的空模版
|
31
|
+
def export_template_xlsx(**options)
|
32
|
+
origin_options = options.dup
|
33
|
+
process_options(options)
|
34
|
+
|
35
|
+
Axlsx::Package.new do |pack|
|
36
|
+
pack.use_shared_strings = true
|
37
|
+
workbook = pack.workbook
|
38
|
+
|
39
|
+
export_workbook workbook, **origin_options
|
40
|
+
|
41
|
+
file_path = File.join(Rails.root, 'public', 'import')
|
42
|
+
FileUtils.mkdir_p(file_path) unless Dir.exist?(file_path)
|
43
|
+
file_name = "#{Time.now.strftime('%Y%m%d%H%M%S')}#{@filename}.xlsx"
|
44
|
+
file_path_with_name = File.join(file_path, file_name)
|
45
|
+
pack.serialize(file_path_with_name)
|
46
|
+
return file_path_with_name
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def export_workbook(workbook, **options)
|
51
|
+
export_instance = TalltyImportExport::Export.new(@klass)
|
52
|
+
opts = options.symbolize_keys.merge({ headers: @headers })
|
53
|
+
Rails.logger.info opts
|
54
|
+
export_instance.process_options(opts)
|
55
|
+
export_instance.export_workbook(workbook, [], **opts)
|
56
|
+
end
|
57
|
+
|
58
|
+
def exchange_to_ids(xlsx_file, associations, **options)
|
30
59
|
errors = []
|
31
60
|
ids = []
|
32
61
|
process_xlsx_line_info(xlsx_file, associations, **options) do |line_info, associations|
|
@@ -37,33 +66,34 @@ module TalltyImportExport
|
|
37
66
|
error_msg = errors.map do |line_info|
|
38
67
|
"【#{@primary_keys.map { |key| line_info[key] }.join(' - ')}】"
|
39
68
|
end.join(' ')
|
40
|
-
raise RecordNotFountError
|
69
|
+
raise RecordNotFountError, "以下内容未找到: #{error_msg}"
|
41
70
|
end
|
42
|
-
|
71
|
+
ids.compact.uniq
|
43
72
|
end
|
44
73
|
|
45
|
-
def process_xlsx_line_info
|
74
|
+
def process_xlsx_line_info(xlsx_file, associations, **options)
|
46
75
|
@associations = associations
|
47
76
|
# 先处理获取出来Excel每行的数据, line_info
|
48
77
|
process_options(options)
|
49
78
|
|
50
|
-
if TalltyImportExport::Excel
|
79
|
+
if xlsx_file.is_a?(TalltyImportExport::Excel)
|
51
80
|
xlsx_file.rows.each_with_excel_hash(@excel_hash) do |line_info|
|
52
81
|
yield line_info.with_indifferent_access, associations
|
53
82
|
end
|
54
83
|
else
|
55
84
|
file_path = xlsx_file.is_a?(String) ? xlsx_file : xlsx_file.path
|
56
|
-
xlsx = ::Roo::
|
85
|
+
xlsx = ::Roo::Spreadsheet.open(file_path, extension: File.extname(file_path) == '.xls' ? :xls : :xlsx)
|
57
86
|
xlsx.each_with_pagename do |_sheetname, sheet|
|
58
87
|
sheet.each(**@excel_hash).with_index do |line_info, index|
|
59
88
|
next if index == 0
|
89
|
+
|
60
90
|
yield line_info.with_indifferent_access, associations
|
61
91
|
end
|
62
92
|
end
|
63
93
|
end
|
64
94
|
end
|
65
95
|
|
66
|
-
def import_data
|
96
|
+
def import_data(data, associations, **options)
|
67
97
|
process_options(options)
|
68
98
|
TalltyImportExport::Excel::Rows.new(data).each_with_excel_hash(@excel_hash) do |line_info|
|
69
99
|
process_line_info(line_info.with_indifferent_access, associations)
|
@@ -74,25 +104,25 @@ module TalltyImportExport
|
|
74
104
|
TalltyImportExport::Excel
|
75
105
|
end
|
76
106
|
|
77
|
-
def process_options
|
107
|
+
def process_options(options)
|
78
108
|
options = import_options.merge(options).with_indifferent_access
|
79
|
-
@headers = options.delete(:headers) || import_headers
|
109
|
+
@headers = options.delete(:headers) || import_headers(**options)
|
80
110
|
@primary_keys = options.delete(:primary_keys) || @headers.map { |header| header[:primary_key] ? header[:key].to_sym : nil }.compact
|
81
111
|
@skip_keys = options.delete(:skip_keys) || @headers.map { |header| header[:skip] ? header[:key].to_sym : nil }.compact
|
82
112
|
@params = options
|
83
113
|
context.params = @params
|
84
114
|
|
85
|
-
@excel_hash = @headers.
|
115
|
+
@excel_hash = @headers.each_with_object({}) do |header, h|
|
86
116
|
h[header[:key].to_sym] = header[:name]
|
87
|
-
h
|
88
117
|
end
|
89
118
|
|
90
119
|
options
|
91
120
|
end
|
92
121
|
|
93
|
-
def process_line_info
|
122
|
+
def process_line_info(line_info, associations)
|
94
123
|
# 去除空行内容
|
95
124
|
return unless line_info.values.any?(&:present?)
|
125
|
+
|
96
126
|
context.line_info = line_info
|
97
127
|
# 转换处理导入的数据格式
|
98
128
|
line_info = convert_data(line_info)
|
@@ -104,14 +134,16 @@ module TalltyImportExport
|
|
104
134
|
context.last_line_info = line_info
|
105
135
|
end
|
106
136
|
|
107
|
-
def convert_data
|
137
|
+
def convert_data(line_info)
|
108
138
|
info = line_info.with_indifferent_access
|
109
|
-
import_headers_result.
|
139
|
+
import_headers_result.each_with_object({}.with_indifferent_access) do |header, h|
|
110
140
|
k = header[:key]
|
141
|
+
k_arr = k.to_s.split(/\./)
|
111
142
|
v = info[k]
|
112
143
|
# header[:convert] = handle_xxx
|
113
144
|
# handle_xxx(val, processing_line_info, raw_line_info)
|
114
145
|
val = header[:convert] ? send(header[:convert], v, h, info) : v
|
146
|
+
val.strip! if val.is_a?(String)
|
115
147
|
if header[:json]
|
116
148
|
h[header[:json]] ||= {}
|
117
149
|
h[header[:json]][k] = val
|
@@ -120,15 +152,20 @@ module TalltyImportExport
|
|
120
152
|
elsif header[:finder]
|
121
153
|
# $SAFE = 2
|
122
154
|
h[k.to_sym] = eval header[:finder]
|
155
|
+
elsif k_arr.size > 1
|
156
|
+
# hash设置
|
157
|
+
attr = k_arr.first
|
158
|
+
val = { k_arr[1..-1].join('.') => v }.to_nested_hash
|
159
|
+
h[attr.to_sym] ||= {}
|
160
|
+
h[attr.to_sym].merge! val
|
123
161
|
else
|
124
162
|
h[k.to_sym] = val
|
125
163
|
end
|
126
|
-
h
|
127
164
|
end.with_indifferent_access
|
128
165
|
end
|
129
166
|
|
130
167
|
# 通过转换后,数据是否合法,如果不合法,则直接跳过不处理这个数据
|
131
|
-
def valid?
|
168
|
+
def valid?(line_info)
|
132
169
|
true
|
133
170
|
end
|
134
171
|
|
@@ -141,12 +178,12 @@ module TalltyImportExport
|
|
141
178
|
_header.with_indifferent_access[:key].to_s.in?(headers_hash.keys)
|
142
179
|
end.map do |_header|
|
143
180
|
_header = _header.with_indifferent_access
|
144
|
-
_header.merge(headers_hash[_header[:key]].delete_if { |
|
181
|
+
_header.merge(headers_hash[_header[:key]].delete_if { |_k, v| v.blank? })
|
145
182
|
end
|
146
183
|
else
|
147
|
-
@headers = import_headers
|
184
|
+
@headers = import_headers
|
148
185
|
end
|
149
|
-
rescue
|
186
|
+
rescue StandardError
|
150
187
|
@headers
|
151
188
|
end
|
152
189
|
|
@@ -154,8 +191,8 @@ module TalltyImportExport
|
|
154
191
|
{}
|
155
192
|
end
|
156
193
|
|
157
|
-
def import_headers
|
158
|
-
@headers || klass.try(:headers) || klass.try(:model_headers) || (raise ArgumentError
|
194
|
+
def import_headers(**args)
|
195
|
+
@headers || klass.try(:headers) || klass.try(:model_headers) || (raise ArgumentError, 'missing import_headers')
|
159
196
|
end
|
160
197
|
|
161
198
|
# # 只保留 key, name, json, 合并到 import_header
|
@@ -182,12 +219,12 @@ module TalltyImportExport
|
|
182
219
|
# @headers = result
|
183
220
|
# end
|
184
221
|
|
185
|
-
def skip
|
222
|
+
def skip(val, processing_line_info, raw_line_info)
|
186
223
|
# do nothing there, use for header[:convert]
|
187
224
|
end
|
188
225
|
|
189
226
|
### 这个方法是可以由复杂业务进行重载的 ###
|
190
|
-
def import_record
|
227
|
+
def import_record(line_info, associations)
|
191
228
|
if primary_keys.present?
|
192
229
|
_record = associations.find_or_initialize_by(line_info.clone.extract!(*primary_keys))
|
193
230
|
_record.update!(line_info.clone.except!(*primary_keys, *@skip_keys))
|
@@ -196,23 +233,26 @@ module TalltyImportExport
|
|
196
233
|
end
|
197
234
|
end
|
198
235
|
|
199
|
-
def exchange_line_info_to_id
|
236
|
+
def exchange_line_info_to_id(line_info, associations, errors)
|
200
237
|
# 去除空行内容
|
201
238
|
return unless line_info.values.any?(&:present?)
|
239
|
+
|
202
240
|
context.line_info = line_info
|
203
241
|
|
204
242
|
return unless primary_keys.present?
|
243
|
+
|
205
244
|
ids = associations.where(line_info.clone.extract!(*primary_keys)).pluck(:id)
|
206
245
|
|
207
246
|
context.last_line_info = line_info
|
208
247
|
|
209
248
|
errors << line_info unless ids[0]
|
210
|
-
|
249
|
+
ids[0]
|
211
250
|
end
|
212
251
|
|
213
252
|
class RecordNotFountError < StandardError
|
214
253
|
attr_accessor :message
|
215
|
-
|
254
|
+
|
255
|
+
def initialize(message)
|
216
256
|
@message = message
|
217
257
|
super()
|
218
258
|
end
|
@@ -28,6 +28,10 @@ module TalltyImportExport
|
|
28
28
|
def exchange_to_ids xlsx_file, associations, **options
|
29
29
|
import_instance.exchange_to_ids(xlsx_file, associations, **options)
|
30
30
|
end
|
31
|
+
|
32
|
+
def export_template_xlsx **options
|
33
|
+
import_instance.export_template_xlsx(**options)
|
34
|
+
end
|
31
35
|
end
|
32
36
|
end
|
33
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tallty_import_export
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- liyijie
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zip-zip
|