spreadsheet_architect 4.1.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +70 -16
- data/README.md +22 -25
- data/lib/spreadsheet_architect/class_methods/ods.rb +18 -8
- data/lib/spreadsheet_architect/class_methods/xlsx.rb +76 -32
- data/lib/spreadsheet_architect/exceptions.rb +30 -13
- data/lib/spreadsheet_architect/utils/ods.rb +66 -0
- data/lib/spreadsheet_architect/utils/xlsx.rb +61 -32
- data/lib/spreadsheet_architect/utils.rb +29 -51
- data/lib/spreadsheet_architect/version.rb +1 -1
- data/lib/spreadsheet_architect.rb +3 -2
- data/test/dummy_app/app/controllers/spreadsheets_controller.rb +6 -3
- data/test/dummy_app/config/application.rb +4 -12
- data/test/dummy_app/config/environments/test.rb +1 -1
- data/test/dummy_app/config/routes.rb +1 -1
- data/test/dummy_app/db/migrate/20170103234524_add_posts.rb +1 -1
- data/test/dummy_app/db/test.sqlite3 +0 -0
- data/test/dummy_app/log/test.log +82177 -58559
- data/test/dummy_app/tmp/2.0.1/integration/alt_xlsx.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/integration/csv.csv +6 -0
- data/test/dummy_app/tmp/2.0.1/integration/ods.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/integration/xlsx.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/kitchen_sink.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/kitchen_sink.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.csv +3 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/empty.csv +1 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/empty.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.csv +6 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/data.csv +3 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/data.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/data.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/empty.csv +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/empty.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/empty.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/instances.csv +6 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/instances.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/instances.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.csv +3 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.csv +1 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.csv +6 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.csv +3 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.csv +1 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.csv +6 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.csv +3 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.csv +1 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.csv +6 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/data.csv +3 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/data.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/data.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/empty.csv +0 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/empty.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/empty.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/instances.csv +6 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/instances.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/models/Post/instances.xlsx +0 -0
- data/test/dummy_app/tmp/2.0.1/multi_sheet.ods +0 -0
- data/test/dummy_app/tmp/2.0.1/multi_sheet.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/integration/alt_xlsx.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/integration/csv.csv +5 -5
- data/test/dummy_app/tmp/3.0.0.pre/integration/ods.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/integration/xlsx.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/kitchen_sink.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/kitchen_sink.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.csv +1 -1
- data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/empty.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.csv +5 -5
- data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/data.csv +1 -1
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/data.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/data.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/empty.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/empty.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/instances.csv +5 -5
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/instances.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/instances.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.csv +1 -1
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/empty.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/empty.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.csv +5 -5
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.csv +1 -1
- data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/empty.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.csv +5 -5
- data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.csv +1 -1
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.csv +0 -1
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.csv +5 -5
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.csv +1 -1
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.csv +1 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/instances.csv +5 -5
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/instances.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/models/Post/instances.xlsx +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/multi_sheet.ods +0 -0
- data/test/dummy_app/tmp/3.0.0.pre/multi_sheet.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/integration/alt_xlsx.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/integration/csv.csv +6 -0
- data/test/dummy_app/tmp/axlsx-master/integration/ods.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/integration/xlsx.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/kitchen_sink.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/kitchen_sink.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.csv +4 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.csv +1 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.csv +6 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/data.csv +4 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/data.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/data.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/empty.csv +1 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/empty.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/empty.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/instances.csv +6 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/instances.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/instances.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.csv +4 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.csv +1 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.csv +6 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.csv +4 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.csv +1 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.csv +6 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.csv +4 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.csv +1 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.csv +6 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/data.csv +4 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/data.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/data.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/empty.csv +1 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/empty.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/empty.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/instances.csv +6 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/instances.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/models/Post/instances.xlsx +0 -0
- data/test/dummy_app/tmp/axlsx-master/multi_sheet.ods +0 -0
- data/test/dummy_app/tmp/axlsx-master/multi_sheet.xlsx +0 -0
- data/test/integration/application_test.rb +8 -16
- data/test/models/all_models_test.rb +15 -19
- data/test/test_helper.rb +48 -9
- data/test/unit/ods/general_test.rb +121 -0
- data/test/unit/{formats_test.rb → rails/formats_test.rb} +1 -1
- data/test/unit/{exceptions_test.rb → spreadsheet_architect/exceptions_test.rb} +19 -15
- data/test/unit/{general_test.rb → spreadsheet_architect/spreadsheet_architect_test.rb} +3 -3
- data/test/unit/spreadsheet_architect/utils/ods_test.rb +58 -0
- data/test/unit/{xlsx_utils_test.rb → spreadsheet_architect/utils/xlsx_test.rb} +13 -21
- data/test/unit/{utils_test.rb → spreadsheet_architect/utils_test.rb} +15 -31
- data/test/unit/xlsx/freeze_test.rb +79 -0
- data/test/unit/xlsx/general_test.rb +199 -0
- metadata +395 -128
- data/test/dummy_app/config/environments/development.rb +0 -30
- data/test/dummy_app/config/environments/production.rb +0 -60
- data/test/unit/kitchen_sink_test.rb +0 -110
- data/test/unit/multi_sheet_test.rb +0 -29
- data/test/unit/regressions_test.rb +0 -11
- data/test/unit/xlsx_freeze_test.rb +0 -44
@@ -0,0 +1,66 @@
|
|
1
|
+
module SpreadsheetArchitect
|
2
|
+
module Utils
|
3
|
+
module ODS
|
4
|
+
|
5
|
+
def self.get_cell_type(value, type=nil)
|
6
|
+
if type && !type.empty?
|
7
|
+
case type
|
8
|
+
when :hyperlink
|
9
|
+
return :string
|
10
|
+
when :date, :time
|
11
|
+
return :string
|
12
|
+
end
|
13
|
+
|
14
|
+
return type unless (type.respond_to?(:empty?) ? type.empty? : type.nil?)
|
15
|
+
end
|
16
|
+
|
17
|
+
if value.is_a?(Numeric)
|
18
|
+
type = :float
|
19
|
+
elsif value.respond_to?(:strftime)
|
20
|
+
type = :string
|
21
|
+
else
|
22
|
+
type = :string
|
23
|
+
end
|
24
|
+
|
25
|
+
return type
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.convert_styles(styles={})
|
29
|
+
styles = {} unless styles.is_a?(Hash)
|
30
|
+
styles = SpreadsheetArchitect::Utils.stringify_keys(styles)
|
31
|
+
|
32
|
+
property_styles = {}
|
33
|
+
|
34
|
+
text_styles = {}
|
35
|
+
text_styles['font-weight'] = styles.delete('bold') ? 'bold' : styles.delete('font-weight')
|
36
|
+
text_styles['font-size'] = styles.delete('font_size') || styles.delete('font-size')
|
37
|
+
text_styles['font-style'] = styles.delete('italic') ? 'italic' : styles.delete('font-style')
|
38
|
+
if styles['underline']
|
39
|
+
styles.delete('underline')
|
40
|
+
text_styles['text-underline-style'] = 'solid'
|
41
|
+
text_styles['text-underline-type'] = 'single'
|
42
|
+
end
|
43
|
+
if styles['align']
|
44
|
+
text_styles['align'] = true
|
45
|
+
end
|
46
|
+
if styles['color'].respond_to?(:sub) && !styles['color'].empty?
|
47
|
+
text_styles['color'] = "##{styles.delete('color').sub('#','')}"
|
48
|
+
end
|
49
|
+
text_styles.delete_if{|_,v| v.nil?}
|
50
|
+
property_styles['text'] = text_styles
|
51
|
+
|
52
|
+
cell_styles = {}
|
53
|
+
styles['background_color'] ||= styles.delete('background-color')
|
54
|
+
if styles['background_color'].respond_to?(:sub) && !styles['background_color'].empty?
|
55
|
+
cell_styles['background-color'] = "##{styles.delete('background_color').sub('#','')}"
|
56
|
+
end
|
57
|
+
|
58
|
+
cell_styles.delete_if{|_,v| v.nil?}
|
59
|
+
property_styles['cell'] = cell_styles
|
60
|
+
|
61
|
+
return property_styles
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -3,7 +3,14 @@ module SpreadsheetArchitect
|
|
3
3
|
module XLSX
|
4
4
|
|
5
5
|
def self.get_type(value, type=nil)
|
6
|
-
|
6
|
+
if type && !type.empty?
|
7
|
+
case type
|
8
|
+
when :hyperlink
|
9
|
+
return :string
|
10
|
+
end
|
11
|
+
|
12
|
+
return type unless (type.respond_to?(:empty?) ? type.empty? : type.nil?)
|
13
|
+
end
|
7
14
|
|
8
15
|
if value.is_a?(Numeric)
|
9
16
|
if value.is_a?(Float) || value.is_a?(BigDecimal)
|
@@ -25,10 +32,30 @@ module SpreadsheetArchitect
|
|
25
32
|
end
|
26
33
|
|
27
34
|
def self.convert_styles_to_axlsx(styles={})
|
28
|
-
|
35
|
+
if [nil, false, true].include?(styles)
|
36
|
+
return {}
|
37
|
+
end
|
29
38
|
|
30
39
|
styles = SpreadsheetArchitect::Utils.symbolize_keys(styles)
|
31
40
|
|
41
|
+
### BOOLEAN VALUES
|
42
|
+
if styles[:b].nil? && styles.has_key?(:bold)
|
43
|
+
styles[:b] = !!styles.delete(:bold)
|
44
|
+
end
|
45
|
+
|
46
|
+
if styles[:i].nil? && styles.has_key?(:italic)
|
47
|
+
styles[:i] = !!styles.delete(:italic)
|
48
|
+
end
|
49
|
+
|
50
|
+
if styles[:u].nil? && styles.has_key?(:underline)
|
51
|
+
styles[:u] = !!styles.delete(:underline)
|
52
|
+
end
|
53
|
+
|
54
|
+
### OTHER VALUES
|
55
|
+
if styles[:sz].nil? && !styles[:font_size].nil?
|
56
|
+
styles[:sz] = styles.delete(:font_size)
|
57
|
+
end
|
58
|
+
|
32
59
|
if styles[:fg_color].nil? && styles[:color] && styles[:color].respond_to?(:sub) && !styles[:color].empty?
|
33
60
|
styles[:fg_color] = styles.delete(:color).sub('#','')
|
34
61
|
end
|
@@ -37,7 +64,7 @@ module SpreadsheetArchitect
|
|
37
64
|
styles[:bg_color] = styles.delete(:background_color).sub('#','')
|
38
65
|
end
|
39
66
|
|
40
|
-
if styles[:alignment].nil? &&
|
67
|
+
if styles[:alignment].nil? && [:align, :valign, :wrap_text].any?{|k| styles.has_key?(k) }
|
41
68
|
if styles[:align].is_a?(Hash)
|
42
69
|
styles[:alignment] = {
|
43
70
|
horizontal: styles[:align][:horizontal],
|
@@ -45,37 +72,29 @@ module SpreadsheetArchitect
|
|
45
72
|
wrap_text: styles[:align][:wrap_text]
|
46
73
|
}
|
47
74
|
else
|
48
|
-
styles[:alignment] = {horizontal:
|
75
|
+
styles[:alignment] = {horizontal: styles.delete(:align), vertical: styles.delete(:valign), wrap_text: styles.delete(:wrap_text) }.compact
|
49
76
|
end
|
50
|
-
|
51
|
-
styles.delete(:align)
|
52
|
-
end
|
53
|
-
|
54
|
-
if styles[:b].nil?
|
55
|
-
styles[:b] = styles.delete(:bold) || nil
|
56
|
-
end
|
57
|
-
|
58
|
-
if styles[:sz].nil?
|
59
|
-
styles[:sz] = styles.delete(:font_size) || nil
|
60
|
-
end
|
61
|
-
|
62
|
-
if styles[:i].nil?
|
63
|
-
styles[:i] = styles.delete(:italic) || nil
|
64
|
-
end
|
65
|
-
|
66
|
-
if styles[:u].nil?
|
67
|
-
styles[:u] = styles.delete(:underline) || nil
|
68
77
|
end
|
69
78
|
|
79
|
+
### COMMENT SEEMS WRONG, TO BE RECONFIRMED
|
70
80
|
### If `:u` is false instead of nil, it may be incorrectly rendered as true in Excel
|
71
|
-
if styles[:u] == false
|
72
|
-
|
81
|
+
#if styles[:u] == false
|
82
|
+
# styles[:u] = nil
|
83
|
+
#end
|
84
|
+
|
85
|
+
### ENSURE CLEANUP OF ALL ALIAS KEYS
|
86
|
+
[:bold, :font_size, :italic, :underline, :align, :valign, :wrap_text, :color, :background_color].each do |k|
|
87
|
+
styles.delete(k)
|
73
88
|
end
|
74
89
|
|
75
|
-
styles
|
90
|
+
return styles
|
76
91
|
end
|
77
92
|
|
78
|
-
def self.range_hash_to_str(hash, num_columns, num_rows)
|
93
|
+
def self.range_hash_to_str(hash, num_columns, num_rows, use_zero_based_row_index: false)
|
94
|
+
if !hash.has_key?(:rows) && !hash.has_key?(:columns)
|
95
|
+
raise SpreadsheetArchitect::Exceptions::InvalidRangeError.new(:missing_range_keys, hash)
|
96
|
+
end
|
97
|
+
|
79
98
|
case hash[:columns]
|
80
99
|
when Integer
|
81
100
|
start_col = end_col = COL_NAMES[hash[:columns]]
|
@@ -92,24 +111,34 @@ module SpreadsheetArchitect
|
|
92
111
|
unless end_col.is_a?(String)
|
93
112
|
end_col = COL_NAMES[end_col]
|
94
113
|
end
|
95
|
-
when :all
|
114
|
+
when :all, nil
|
96
115
|
start_col = 'A'
|
97
116
|
end_col = COL_NAMES[num_columns-1]
|
98
117
|
else
|
99
|
-
raise SpreadsheetArchitect::Exceptions::
|
118
|
+
raise SpreadsheetArchitect::Exceptions::InvalidRangeOptionError.new(:columns, hash)
|
100
119
|
end
|
101
120
|
|
102
121
|
case hash[:rows]
|
103
122
|
when Integer
|
104
123
|
start_row = end_row = hash[:rows]
|
124
|
+
|
125
|
+
if use_zero_based_row_index
|
126
|
+
start_row += 1
|
127
|
+
end_row += 1
|
128
|
+
end
|
105
129
|
when Range
|
106
130
|
start_row = hash[:rows].first
|
107
131
|
end_row = hash[:rows].last
|
108
|
-
|
132
|
+
|
133
|
+
if use_zero_based_row_index
|
134
|
+
start_row += 1
|
135
|
+
end_row += 1
|
136
|
+
end
|
137
|
+
when :all, nil
|
109
138
|
start_row = 1
|
110
139
|
end_row = num_rows
|
111
140
|
else
|
112
|
-
raise SpreadsheetArchitect::Exceptions::
|
141
|
+
raise SpreadsheetArchitect::Exceptions::InvalidRangeOptionError.new(:rows, hash)
|
113
142
|
end
|
114
143
|
|
115
144
|
range_str = "#{start_col}#{start_row}:#{end_col}#{end_row}"
|
@@ -129,11 +158,11 @@ module SpreadsheetArchitect
|
|
129
158
|
end_col, end_row = back.scan(/\d+|\D+/)
|
130
159
|
|
131
160
|
unless COL_NAMES.include?(start_col) && COL_NAMES.include?(end_col)
|
132
|
-
raise SpreadsheetArchitect::Exceptions::
|
161
|
+
raise SpreadsheetArchitect::Exceptions::InvalidRangeValue.new(:columns, range)
|
133
162
|
end
|
134
163
|
|
135
164
|
unless start_row.to_i <= num_rows && end_row.to_i <= num_rows
|
136
|
-
raise SpreadsheetArchitect::Exceptions::
|
165
|
+
raise SpreadsheetArchitect::Exceptions::InvalidRangeValue.new(:rows, range)
|
137
166
|
end
|
138
167
|
else
|
139
168
|
raise SpreadsheetArchitect::Exceptions::InvalidRangeError.new(:format, range)
|
@@ -10,7 +10,9 @@ module SpreadsheetArchitect
|
|
10
10
|
if options[:headers] == true
|
11
11
|
headers = []
|
12
12
|
|
13
|
-
if
|
13
|
+
if options[:data]
|
14
|
+
headers = false
|
15
|
+
else
|
14
16
|
needs_headers = true
|
15
17
|
end
|
16
18
|
elsif options[:headers].is_a?(Array)
|
@@ -112,24 +114,22 @@ module SpreadsheetArchitect
|
|
112
114
|
def self.get_options(options, klass)
|
113
115
|
verify_option_types(options)
|
114
116
|
|
115
|
-
if options[:
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
klass::SPREADSHEET_OPTIONS.merge(options)
|
123
|
-
)
|
117
|
+
if !options[:skip_defaults]
|
118
|
+
if defined?(klass::SPREADSHEET_OPTIONS)
|
119
|
+
if klass::SPREADSHEET_OPTIONS.is_a?(Hash)
|
120
|
+
defaults = SpreadsheetArchitect.default_options.merge(klass::SPREADSHEET_OPTIONS)
|
121
|
+
else
|
122
|
+
raise SpreadsheetArchitect::Exceptions::OptionTypeError.new("#{klass}::SPREADSHEET_OPTIONS constant")
|
123
|
+
end
|
124
124
|
else
|
125
|
-
|
125
|
+
defaults = SpreadsheetArchitect.default_options
|
126
126
|
end
|
127
|
-
|
128
|
-
options =
|
127
|
+
|
128
|
+
options = defaults.merge(options)
|
129
129
|
end
|
130
130
|
|
131
131
|
if !options[:headers]
|
132
|
-
options
|
132
|
+
options.delete(:header_style)
|
133
133
|
end
|
134
134
|
|
135
135
|
if !options[:sheet_name]
|
@@ -144,47 +144,23 @@ module SpreadsheetArchitect
|
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
147
|
-
if options[:freeze]
|
148
|
-
|
149
|
-
end
|
147
|
+
if options[:freeze]
|
148
|
+
options[:freeze] = SpreadsheetArchitect::Utils.symbolize_keys(options[:freeze])
|
150
149
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
def self.convert_styles_to_ods(styles={})
|
155
|
-
styles = {} unless styles.is_a?(Hash)
|
156
|
-
styles = stringify_keys(styles)
|
157
|
-
|
158
|
-
property_styles = {}
|
159
|
-
|
160
|
-
text_styles = {}
|
161
|
-
text_styles['font-weight'] = styles.delete('bold') ? 'bold' : styles.delete('font-weight')
|
162
|
-
text_styles['font-size'] = styles.delete('font_size') || styles.delete('font-size')
|
163
|
-
text_styles['font-style'] = styles.delete('italic') ? 'italic' : styles.delete('font-style')
|
164
|
-
if styles['underline']
|
165
|
-
styles.delete('underline')
|
166
|
-
text_styles['text-underline-style'] = 'solid'
|
167
|
-
text_styles['text-underline-type'] = 'single'
|
168
|
-
end
|
169
|
-
if styles['align']
|
170
|
-
text_styles['align'] = true
|
171
|
-
end
|
172
|
-
if styles['color'].respond_to?(:sub) && !styles['color'].empty?
|
173
|
-
text_styles['color'] = "##{styles.delete('color').sub('#','')}"
|
150
|
+
if options[:freeze_headers]
|
151
|
+
raise SpreadsheetArchitect::Exceptions::ArgumentError.new('Cannot use both :freeze and :freeze_headers options at the same time')
|
152
|
+
end
|
174
153
|
end
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
cell_styles = {}
|
179
|
-
styles['background_color'] ||= styles.delete('background-color')
|
180
|
-
if styles['background_color'].respond_to?(:sub) && !styles['background_color'].empty?
|
181
|
-
cell_styles['background-color'] = "##{styles.delete('background_color').sub('#','')}"
|
154
|
+
|
155
|
+
if options[:escape_formulas].nil?
|
156
|
+
options[:escape_formulas] = true
|
182
157
|
end
|
183
158
|
|
184
|
-
|
185
|
-
|
159
|
+
if options[:use_zero_based_row_index].nil?
|
160
|
+
options[:use_zero_based_row_index] = false
|
161
|
+
end
|
186
162
|
|
187
|
-
return
|
163
|
+
return options
|
188
164
|
end
|
189
165
|
|
190
166
|
private
|
@@ -284,11 +260,13 @@ module SpreadsheetArchitect
|
|
284
260
|
instances: Array,
|
285
261
|
merges: Array,
|
286
262
|
range_styles: Array,
|
263
|
+
skip_defaults: [TrueClass, FalseClass],
|
287
264
|
row_style: Hash,
|
288
265
|
sheet_name: String,
|
289
266
|
spreadsheet_columns: [Proc, Symbol, String],
|
267
|
+
escape_formulas: [TrueClass, FalseClass, Array],
|
268
|
+
use_zero_based_row_index: [TrueClass, FalseClass],
|
290
269
|
}.freeze
|
291
270
|
|
292
|
-
|
293
271
|
end
|
294
272
|
end
|
@@ -4,6 +4,7 @@ require 'spreadsheet_architect/action_controller_renderers'
|
|
4
4
|
require 'spreadsheet_architect/exceptions'
|
5
5
|
require 'spreadsheet_architect/utils'
|
6
6
|
require 'spreadsheet_architect/utils/xlsx'
|
7
|
+
require 'spreadsheet_architect/utils/ods'
|
7
8
|
|
8
9
|
require 'spreadsheet_architect/class_methods/csv'
|
9
10
|
require 'spreadsheet_architect/class_methods/ods'
|
@@ -35,7 +36,7 @@ module SpreadsheetArchitect
|
|
35
36
|
@default_options
|
36
37
|
end
|
37
38
|
|
38
|
-
XLSX_COLUMN_TYPES = [:string, :integer, :float, :date, :time, :boolean].freeze
|
39
|
-
ODS_COLUMN_TYPES = [:string, :float, :date, :time, :boolean].freeze
|
39
|
+
XLSX_COLUMN_TYPES = [:string, :integer, :float, :date, :time, :boolean, :hyperlink].freeze
|
40
|
+
ODS_COLUMN_TYPES = [:string, :float, :date, :time, :boolean, :hyperlink].freeze
|
40
41
|
|
41
42
|
end
|
@@ -14,9 +14,12 @@ class SpreadsheetsController < ApplicationController
|
|
14
14
|
render xlsx: Post.to_xlsx, filename: 'Posts'
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
17
|
+
def test_respond_with
|
18
|
+
if Rails::VERSION::MAJOR >= 5
|
19
|
+
@posts = Post.all
|
20
|
+
|
21
|
+
respond_with @posts
|
22
|
+
end
|
20
23
|
end
|
21
24
|
|
22
25
|
def test_xlsx
|
@@ -2,9 +2,6 @@ require File.expand_path('../boot', __FILE__)
|
|
2
2
|
|
3
3
|
require 'rails/all'
|
4
4
|
|
5
|
-
require 'axlsx'
|
6
|
-
require 'axlsx_styler'
|
7
|
-
|
8
5
|
Bundler.require
|
9
6
|
|
10
7
|
require "spreadsheet_architect"
|
@@ -39,14 +36,6 @@ module Dummy
|
|
39
36
|
# Configure sensitive parameters which will be filtered from the log file.
|
40
37
|
config.filter_parameters += [:password]
|
41
38
|
|
42
|
-
# Enable the asset pipeline
|
43
|
-
config.assets.enabled = true
|
44
|
-
|
45
|
-
config.assets.quiet = true
|
46
|
-
|
47
|
-
# Version of your assets, change this if you want to expire all your assets
|
48
|
-
config.assets.version = '1.0'
|
49
|
-
|
50
39
|
config.generators.test_framework = false
|
51
40
|
config.generators.helper = false
|
52
41
|
config.generators.stylesheets = false
|
@@ -58,7 +47,10 @@ module Dummy
|
|
58
47
|
|
59
48
|
if ActiveRecord.respond_to?(:gem_version)
|
60
49
|
gem_version = ActiveRecord.gem_version
|
61
|
-
|
50
|
+
|
51
|
+
if gem_version >= Gem::Version.new("7.0.0")
|
52
|
+
config.active_record.legacy_connection_handling = false
|
53
|
+
elsif gem_version.to_s.start_with?("5.2.")
|
62
54
|
config.active_record.sqlite3.represent_boolean_as_integer = true
|
63
55
|
end
|
64
56
|
end
|
@@ -9,7 +9,7 @@ Dummy::Application.configure do
|
|
9
9
|
|
10
10
|
# Configure static asset server for tests with Cache-Control for performance
|
11
11
|
config.serve_static_files = true
|
12
|
-
config.public_file_server.
|
12
|
+
config.public_file_server.enabled = true
|
13
13
|
|
14
14
|
# Log error messages when you accidentally call methods on nil
|
15
15
|
config.whiny_nils = true
|
@@ -2,5 +2,5 @@ Dummy::Application.routes.draw do
|
|
2
2
|
get 'spreadsheets/csv', to: 'spreadsheets#csv'
|
3
3
|
get 'spreadsheets/ods', to: 'spreadsheets#ods'
|
4
4
|
get 'spreadsheets/xlsx', to: 'spreadsheets#xlsx'
|
5
|
-
get 'spreadsheets/
|
5
|
+
get 'spreadsheets/test_respond_with', to: 'spreadsheets#test_respond_with'
|
6
6
|
end
|
Binary file
|