Class: TalltyImportExport::Export
- Inherits:
-
Object
- Object
- TalltyImportExport::Export
- Defined in:
- lib/tallty_import_export/export.rb
Instance Attribute Summary collapse
-
#klass ⇒ Object
readonly
Returns the value of attribute klass.
Instance Method Summary collapse
- #export_headers(**args) ⇒ Object
- #export_headers_result ⇒ Object
- #export_workbook(workbook, records) ⇒ Object
-
#export_xlsx(records, **options) ⇒ Object
- { key: ‘entry_user_name’, name: ‘被考核人’, chain: [:entry, :user_name
-
}, { key: ‘entry_user_code’, name: ‘被考核人工号’ }, { key: ‘entry_user_department_name’, name: ‘被考核人部门’ }, { key: ‘dimension_name’, name: ‘考核维度’ }, { key: ‘user_name’, name: ‘考核人’ }, { key: ‘user_code’, name: ‘考核人工号’ }, { key: ‘user_department_name’, name: ‘考核人部门’ }, { key: ‘state’, name: ‘考核状态’, method: :state_zh }, { key: ‘score’, name: ‘考核分’ }, ] export_headers_result / headers key: 属性的英文名,可以支持user.name这样的方式 name: 属性的中文名 attr_type: 属性的类型 format: excel是否需要特定的格式,目前主要是类似于身份证号,可以用string method: 导出时本地调用的方法 chain: 导出时对象属性通过链式调用 index: 数组方式,需要嵌套拿到里面的 merge: true/false,默认false,某一列,如果上下行的内容相同,则直接合并单元格 json: model_payload,代表存储在某一个列中.
-
#handle_data(record, header, index = 0) ⇒ Object
处理一个记录的数据.
-
#handle_format(data, header) ⇒ Object
根据数据类型 attr_type 进行数据的格式化.
-
#initialize(klass) ⇒ Export
constructor
A new instance of Export.
- #process_options(options = {}) ⇒ Object
- #try_chain(record, arr) ⇒ Object
- #try_method(record, method) ⇒ Object
- #with_scope(records) ⇒ Object
Constructor Details
#initialize(klass) ⇒ Export
Returns a new instance of Export.
5 6 7 |
# File 'lib/tallty_import_export/export.rb', line 5 def initialize klass @klass = klass end |
Instance Attribute Details
#klass ⇒ Object (readonly)
Returns the value of attribute klass.
3 4 5 |
# File 'lib/tallty_import_export/export.rb', line 3 def klass @klass end |
Instance Method Details
#export_headers(**args) ⇒ Object
143 144 145 |
# File 'lib/tallty_import_export/export.rb', line 143 def export_headers **args @headers || klass.try(:headers) || klass.try(:model_headers) end |
#export_headers_result ⇒ Object
139 140 141 |
# File 'lib/tallty_import_export/export.rb', line 139 def export_headers_result @headers || export_headers end |
#export_workbook(workbook, records) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/tallty_import_export/export.rb', line 66 def export_workbook workbook, records # excel导出样式 alignment = { vertical: :center, horizontal: :center } border = { color: '969696', style: :thin } title1 = workbook.styles.add_style(alignment: alignment, border: border, sz: 12, b: true) title2 = workbook.styles.add_style(alignment: alignment, border: border, bg_color: "2a5caa", sz: 12, fg_color: "fffffb") title3 = workbook.styles.add_style(alignment: alignment.merge(wrap_text: true), border: border, sz: 10) headers = export_headers_result _sheet_name = respond_to?(:sheet_name) ? self.sheet_name : nil workbook.add_worksheet(name: _sheet_name) do |sheet| if respond_to?(:first_header) row_index = Axlsx.col_ref(headers.size - 1) sheet.merge_cells("A1:#{row_index}1") sheet.add_row [first_header], style: title1, height: 40 end sheet.add_row headers.map{|header| header[:name]}, style: title2, height: 39 last_row = nil merge_column_hash = {} first_content_row_index = respond_to?(:first_header) ? 2 : 1 each_method = records.is_a?(Array) ? :each : :each records.send(each_method).with_index do |record, index| row = [] headers.each_with_index do |header, col_index| _data = handle_data(record, header, index) if header[:merge].present? && last_row.present? && _data == last_row[col_index] # 这里使用二维数组,每个数组里都是列内容相同的各行 merge_column_hash[col_index] ||= [] if merge_column_hash[col_index].last&.last == index + first_content_row_index - 1 # 说明内容和上面的是延续的,继续加入之前的数组 merge_column_hash[col_index].last << index + first_content_row_index else merge_column_hash[col_index] << [index + first_content_row_index - 1, index + first_content_row_index] end end row.push(_data) end sheet.add_row row, style: title3, height: @row_height, types: headers.map{|header| header[:format]&.to_sym} last_row = row end # 需要根据column进行多行的内容合并 if merge_column_hash.present? merge_column_hash.each do |col_index, row_arr| row_arr.each do |arr| sheet.merge_cells( Axlsx::cell_r(col_index, arr.first) + ':' + Axlsx::cell_r(col_index, arr.last) ) end end end sheet.column_widths(*headers.map{|header| (header[:width] || @width).to_f}) end end |
#export_xlsx(records, **options) ⇒ Object
[
{ key: 'entry_user_name', name: '被考核人', chain: [:entry, :user_name] },
{ key: 'entry_user_code', name: '被考核人工号' },
{ key: 'entry_user_department_name', name: '被考核人部门' },
{ key: 'dimension_name', name: '考核维度' },
{ key: 'user_name', name: '考核人' },
{ key: 'user_code', name: '考核人工号' },
{ key: 'user_department_name', name: '考核人部门' },
{ key: 'state', name: '考核状态', method: :state_zh },
{ key: 'score', name: '考核分' },
] export_headers_result / headers key: 属性的英文名,可以支持user.name这样的方式name: 属性的中文名attr_type: 属性的类型format: excel是否需要特定的格式,目前主要是类似于身份证号,可以用string method: 导出时本地调用的方法chain: 导出时对象属性通过链式调用index: 数组方式,需要嵌套拿到里面的merge: true/false,默认false,某一列,如果上下行的内容相同,则直接合并单元格json: model_payload,代表存储在某一个列中
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/tallty_import_export/export.rb', line 31 def export_xlsx records, ** records = with_scope records () = .with_indifferent_access Axlsx::Package.new do |pack| workbook = pack.workbook if @group_by.present? @header = nil # 因为group_by的,基本上都是export_header动态变化的,因此去掉选择 if records.is_a?(Array) records.group_by { |record| record.send(@group_by)}.each do |key, group_records| @group_key = key export_workbook workbook, group_records end else records.group(@group_by).count.keys.each do |key| @group_key = key export_workbook workbook, records.ransack("#{@group_where}" => key).result end end else export_workbook workbook, records end file_path = File.join(Rails.root, 'public', 'export') FileUtils.mkdir_p(file_path) unless Dir.exist?(file_path) file_name = "#{Time.now.strftime('%Y%m%d%H%M%S')}#{@filename}.xlsx" file_path_with_name = File.join(file_path, file_name) pack.serialize(file_path_with_name) return file_path_with_name end end |
#handle_data(record, header, index = 0) ⇒ Object
处理一个记录的数据
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/tallty_import_export/export.rb', line 148 def handle_data record, header, index=0 data = if header[:key] == '_index' index + 1 elsif header[:method].present? send(header[:method], record, header) elsif header[:chain].present? try_chain(record, header[:chain]) elsif header[:json] record.send(header[:json])[header[:key]] else try_method(record, header[:key]) end handle_format(data, header) rescue '' end |
#handle_format(data, header) ⇒ Object
根据数据类型 attr_type 进行数据的格式化
176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/tallty_import_export/export.rb', line 176 def handle_format data, header case header[:attr_type].to_s when 'string' data.to_s when 'datetime' data ? data.strftime('%F %H:%M') : nil when 'date' data ? data.strftime('%F') : nil else data end end |
#process_options(options = {}) ⇒ Object
124 125 126 127 128 129 130 131 132 133 |
# File 'lib/tallty_import_export/export.rb', line 124 def = {} = .with_indifferent_access @row_height ||= .delete(:row_height) || 35 @width ||= (.delete(:width) || 20).to_f @filename ||= .delete(:filename) @group_by ||= .delete(:group_by) @group_where = "#{@group_by}_eq" if @group_by.present? @headers ||= .delete(:headers) end |
#try_chain(record, arr) ⇒ Object
166 167 168 |
# File 'lib/tallty_import_export/export.rb', line 166 def try_chain record, arr arr.inject(record, :try) end |
#try_method(record, method) ⇒ Object
170 171 172 173 |
# File 'lib/tallty_import_export/export.rb', line 170 def try_method record, method arr = method.to_s.split(/\./) try_chain record, arr end |
#with_scope(records) ⇒ Object
135 136 137 |
# File 'lib/tallty_import_export/export.rb', line 135 def with_scope records records end |