-
Notifications
You must be signed in to change notification settings - Fork 3
/
xlsx_output.rb
132 lines (112 loc) · 3.71 KB
/
xlsx_output.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
65
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
123
124
125
126
127
128
129
130
131
132
require 'rubyXL'
module WorkerTools
module XlsxOutput
def xlsx_output_entries
raise "xlsx_output_entries has to be defined in #{self}"
end
def xlsx_output_column_headers
# These columns are used to set the headers, also
# to set the row values depending on your implementation.
#
# To ignore them set it to _false_
#
# Ex:
# @xlsx_output_column_headers ||= {
# foo: 'Foo Header',
# bar: 'Bar Header'
# }
raise "xlsx_output_column_headers has to be defined in #{self}"
end
def xlsx_output_content
{
sheet1: {
label: 'Sheet 1',
headers: xlsx_output_column_headers,
rows: xlsx_output_entries.lazy.map { |entry| xlsx_output_row_values(entry) },
column_style: xlsx_output_column_format
}
}
end
def xlsx_output_row_values(entry)
entry.values_at(*xlsx_output_column_headers.keys)
end
def xlsx_output_column_format
# These columns are used to set the headers, also
# to set the row values depending on your implementation.
#
# To ignore them set it to _false_
#
# Ex:
# @xlsx_output_column_format ||= {
# foo: { width: 10, text_wrap: true },
# bar: { width: 20, text_wrap: false }
# }
{}
end
def xlsx_output_insert_headers(spreadsheet, headers)
return unless headers
iterator =
if headers.is_a? Hash
headers.values
else
headers
end
iterator.each_with_index do |header, index|
spreadsheet.add_cell(0, index, header.to_s)
end
end
def xlsx_output_insert_rows(spreadsheet, rows, headers)
rows.each_with_index do |row, row_index|
xlsx_output_iterators(row, headers).each_with_index do |value, col_index|
spreadsheet.add_cell(row_index + 1, col_index, value.to_s)
end
end
end
def xlsx_output_iterators(iterable, compare_hash = nil)
if iterable.is_a? Hash
raise 'parameter compare_hash should be a hash, too.' if compare_hash.nil? || !compare_hash.is_a?(Hash)
iterable.values_at(*compare_hash.keys)
else
iterable
end
end
def xlsx_output_style_columns(spreadsheet, styles, headers)
return false unless headers
xlsx_output_iterators(styles, headers).each_with_index do |format, index|
next unless format
spreadsheet.change_column_width(index, format[:width])
spreadsheet.change_text_wrap(index, format[:text_wrap])
end
true
end
def xlsx_output_tmp_file
@xlsx_output_tmp_file ||= Tempfile.new(['output', '.xlsx'])
end
def xlsx_output_file_name
"#{model_kind}.xlsx"
end
def xlsx_output_add_attachment
model.add_attachment(
xlsx_output_tmp_file,
file_name: xlsx_output_file_name,
content_type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
end
def xlsx_output_write_sheet(workbook, sheet_content, index)
sheet = workbook.worksheets[index]
sheet = workbook.add_worksheet(sheet_content[:label]) if sheet.nil?
sheet.sheet_name = sheet_content[:label]
xlsx_output_style_columns(sheet, sheet_content[:column_style], sheet_content[:headers])
xlsx_output_insert_headers(sheet, sheet_content[:headers])
xlsx_output_insert_rows(sheet, sheet_content[:rows], sheet_content[:headers])
end
def xlsx_output_write_file
book = RubyXL::Workbook.new
xlsx_output_content.each_with_index do |(_, object), index|
xlsx_output_write_sheet(book, object, index)
end
book.write xlsx_output_tmp_file
xlsx_output_add_attachment
end
end
end