Commit e9126beb by liyijie

exportable support sheets

parent 9e3a100d
module TalltyImportExport module TalltyImportExport
class Export class Export
attr_reader :klass, :headers attr_reader :klass
def initialize klass def initialize klass
@klass = klass @klass = klass
end end
# [
# { 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 / headers # export_headers / headers
# key: 属性的英文名 # key: 属性的英文名
# name: 属性的中文名 # name: 属性的中文名
...@@ -13,44 +24,66 @@ module TalltyImportExport ...@@ -13,44 +24,66 @@ module TalltyImportExport
# format: excel是否需要特定的格式,目前主要是类似于身份证号,可以用string # format: excel是否需要特定的格式,目前主要是类似于身份证号,可以用string
# method: 导出时本地调用的方法 # method: 导出时本地调用的方法
# chain: 导出时对象属性通过链式调用 # chain: 导出时对象属性通过链式调用
# index: 数组方式,需要嵌套拿到里面的
def export_xlsx records, options={} def export_xlsx records, **options
exportable_defaults(options) exportable_defaults(options)
options = options.with_indifferent_access options = options.with_indifferent_access
Axlsx::Package.new do |pack| Axlsx::Package.new do |pack|
workbook = pack.workbook workbook = pack.workbook
if @group_by.present?
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.where(@group_by => key)
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"
pack.serialize(File.join(file_path, file_name))
url = ActionController::Base.helpers.asset_url("/export/#{file_name}")
return url
end
end
def export_workbook workbook, records
# excel导出样式 # excel导出样式
alignment = { vertical: :center, horizontal: :center } alignment = { vertical: :center, horizontal: :center }
border = { color: '969696', style: :thin } border = { color: '969696', style: :thin }
title1 = workbook.styles.add_style(alignment: alignment, border: border, sz: 16, b: true) title1 = workbook.styles.add_style(alignment: alignment, border: border, sz: 16, b: true)
title2 = workbook.styles.add_style(alignment: alignment, border: border, bg_color: "2a5caa", sz: 16, fg_color: "fffffb") title2 = workbook.styles.add_style(alignment: alignment, border: border, bg_color: "2a5caa", sz: 16, fg_color: "fffffb")
title3 = workbook.styles.add_style(alignment: alignment.merge(wrap_text: true), border: border, sz: 14) title3 = workbook.styles.add_style(alignment: alignment.merge(wrap_text: true), border: border, sz: 14)
headers = export_headers
workbook.add_worksheet do |sheet| workbook.add_worksheet do |sheet|
if respond_to?(:first_header) if respond_to?(:first_header)
row_index = Axlsx.col_ref(headers.size - 1) row_index = Axlsx.col_ref(headers.size - 1)
sheet.merge_cells("A1:#{row_index}1") sheet.merge_cells("A1:#{row_index}1")
sheet.add_row [first_header], style: title1, height: 40 sheet.add_row [first_header], style: title1, height: 40
end end
sheet.add_row @headers.map{|header| header[:name]}, style: title2, height: 39 sheet.add_row headers.map{|header| header[:name]}, style: title2, height: 39
each_method = records.is_a?(Array) ? :each : :find_each each_method = records.is_a?(Array) ? :each : :find_each
records.send(each_method) do |record| records.send(each_method) do |record|
row = [] row = []
headers.each{ |header| row.push(handle_data(record, header)) } headers.each{ |header| row.push(handle_data(record, header)) }
sheet.add_row row, style: title3, height: @row_height, types: @headers.map{|header| header[:format]} sheet.add_row row, style: title3, height: @row_height, types: headers.map{|header| header[:format]}
end
sheet.column_widths *@headers.map{|header| header[:width] || @width}
end end
file_path = File.join(Rails.root, 'public', 'export') sheet.column_widths *headers.map{|header| header[:width] || @width}
FileUtils.mkdir_p(file_path) unless Dir.exist?(file_path)
file_name = "#{Time.now.strftime('%Y%m%d%H%M%S')}#{@filename}.xlsx"
pack.serialize(File.join(file_path, file_name))
url = ActionController::Base.helpers.asset_url("/export/#{file_name}")
return url
end end
end end
...@@ -60,7 +93,7 @@ module TalltyImportExport ...@@ -60,7 +93,7 @@ module TalltyImportExport
@row_height ||= options.delete(:row_height) || 35 @row_height ||= options.delete(:row_height) || 35
@width ||= options.delete(:width) || 30 @width ||= options.delete(:width) || 30
@filename ||= options.delete(:filename) @filename ||= options.delete(:filename)
self.headers = export_headers @group_by ||= options.delete(:group_by)
end end
def headers= val def headers= val
...@@ -68,14 +101,14 @@ module TalltyImportExport ...@@ -68,14 +101,14 @@ module TalltyImportExport
end end
def export_headers def export_headers
klass.try(:headers) || klass.try(:model_headers) @headers || klass.try(:headers) || klass.try(:model_headers)
end end
# 处理一个记录的数据 # 处理一个记录的数据
def handle_data record, header def handle_data record, header
data = data =
if header[:method].present? if header[:method].present?
send(header[:method], record, header[:key]) send(header[:method], record, header)
elsif header[:chain].present? elsif header[:chain].present?
header[:chain].reduce(record) do |obj, method| header[:chain].reduce(record) do |obj, method|
obj.send(method) obj.send(method)
......
...@@ -13,8 +13,8 @@ module TalltyImportExport ...@@ -13,8 +13,8 @@ module TalltyImportExport
const_get('Export').new(self) const_get('Export').new(self)
end end
def export_xlsx *args def export_xlsx records, **options
export_instance.export_xlsx(*args) export_instance.export_xlsx(records, **options)
end end
end end
end end
......
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