Skip to content

Commit bd2545a

Browse files
committed
Add HeaderCell to simplify humanizing names
1 parent 5c3663f commit bd2545a

File tree

4 files changed

+39
-29
lines changed

4 files changed

+39
-29
lines changed

lib/spreadsheet_exporter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative './spreadsheet_exporter/xlsx'
44
require 'active_support'
55
require 'active_support/core_ext/object/json'
6+
require 'active_support/core_ext/hash/reverse_merge'
67

78
module SpreadsheetExporter
89
VALIDATION_ERROR_TYPES = %w[stop warning information].freeze

lib/spreadsheet_exporter/spreadsheet.rb

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# TODO: Find out why we can't detect arrays properly and must resort to crappy class.name comparison
22
module SpreadsheetExporter
3+
HeaderCell = Struct.new(:attribute_name, :human_attribute_name) do
4+
def to_s
5+
human_attribute_name.presence || attribute_name
6+
end
7+
end
8+
9+
310
module Spreadsheet
411
def self.from_objects(objects, options = {})
512
headers = []
@@ -15,17 +22,23 @@ def self.from_objects(objects, options = {})
1522
get_values(object.as_json(options))
1623
end
1724

18-
headers |= data.keys
25+
headers |= data.keys.map { |v| HeaderCell.new(v) }
1926
rows << data
2027
end
2128

2229
# Create the csv, ensuring to place each row's attributes under the appropriate header (since rows may not have all the same attributes)
2330
[].tap do |spreadsheet|
24-
spreadsheet << (options[:humanize_headers_class] ? han(options[:humanize_headers_class], headers) : headers)
31+
if options[:humanize_headers_class]
32+
headers = han(headers, **options)
33+
end
34+
35+
spreadsheet << headers
36+
2537
rows.each do |row|
2638
sorted_row = []
2739
row.each do |header, value|
28-
sorted_row[headers.index(header)] = value
40+
col_index = headers.find_index { |h| h.attribute_name == header }
41+
sorted_row[col_index] = value
2942
end
3043

3144
spreadsheet << sorted_row
@@ -35,14 +48,14 @@ def self.from_objects(objects, options = {})
3548

3649
# Return an array of human_attribute_name's
3750
# Used by the CSV Import/Export process to match CSV headers to model attribute names
38-
def self.han(klass, *attributes)
39-
options = attributes.extract_options!
51+
def self.han(headers, humanize_headers_class:, downcase: false, **)
52+
headers.flatten!
4053

41-
attributes.flatten!
42-
attributes.collect! {|attribute| klass.human_attribute_name(attribute) }
43-
attributes.collect!(&:downcase) if options[:downcase]
44-
45-
return attributes.many? ? attributes : attributes.first
54+
headers.collect! do |header|
55+
header.human_attribute_name = humanize_headers_class.human_attribute_name(header.attribute_name)
56+
header.human_attribute_name.downcase! if downcase
57+
header
58+
end
4659
end
4760

4861
def self.get_values(node, current_header = nil)

lib/spreadsheet_exporter/xlsx.rb

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ def self.from_spreadsheet(spreadsheet, options = {})
2727
column_indexes = {}
2828

2929
# Write header row
30-
Array(spreadsheet.first).each_with_index do |column_name, col|
31-
worksheet.write(0, col, column_name, header_format)
32-
column_indexes[column_name] = col
30+
Array(spreadsheet.first).each_with_index do |header, col|
31+
worksheet.write(0, col, header.to_s, header_format)
32+
column_indexes[header.attribute_name] = col
3333
end
3434

3535
Array(spreadsheet[1..]).each_with_index do |values, row|
@@ -101,25 +101,10 @@ def self.add_data_source(workbook, data_sheet, data_key, data_values, column_ind
101101
defined_name
102102
end
103103

104-
# TODO: we should DRY this up with the Spreadsheet.from_objects logic
105-
def self.rewrite_validation_column_names(column_validations, options)
106-
return column_validations unless options["humanize_headers_class"]
107-
108-
klass = options["humanize_headers_class"]
109-
110-
column_validations.each_with_object({}) do |(attribute, v), obj|
111-
rewritten = klass.human_attribute_name(attribute)
112-
rewritten.downcase! if options[:downcase]
113-
obj[rewritten] = v
114-
end
115-
end
116-
117104
def self.add_worksheet_validation(workbook, worksheet, column_indexes, data_sources, header_format, options = {})
118105
column_validations = options.fetch("validations", {}) || {}
119106
return if column_validations.empty?
120107

121-
column_validations = rewrite_validation_column_names(column_validations, options)
122-
123108
column_validations.each do |column_name, column_validation|
124109
column_index = column_indexes[column_name]
125110

@@ -133,7 +118,8 @@ def self.add_worksheet_validation(workbook, worksheet, column_indexes, data_sour
133118
if column_validation.indirect_built_from
134119
parent_column_index = column_indexes[column_validation.indirect_built_from]
135120

136-
(1..100).each do |row_index|
121+
# TODO: que pasa
122+
(1..20).each do |row_index|
137123
indirect_cell = xl_rowcol_to_cell(row_index, parent_column_index, false, false)
138124
defined_name = "INDIRECT(\"#{column_validation.data_source}\" & \"_\" & SUBSTITUTE(#{indirect_cell}, \" \", \"\"))"
139125

test.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,15 @@
5353
)
5454
}
5555
}
56+
class Yoda
57+
def self.human_attribute_name(att)
58+
att.reverse
59+
end
60+
end
61+
62+
# debugger
63+
# SpreadsheetExporter::CSV.from_objects(data, :humanize_headers_class => Yoda)
64+
65+
options[:humanize_headers_class] = Yoda
5666

5767
File.binwrite("output.xlsx", SpreadsheetExporter::XLSX.from_objects(data, options))

0 commit comments

Comments
 (0)