export_to 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4359e4a3d0f73c554990815260ffb54104fea537
4
- data.tar.gz: a4c3f34ea3cc77b40f8fc68ff87b9355edc8057c
3
+ metadata.gz: 6457e74385201c5b900c9ccd219348ae675853f6
4
+ data.tar.gz: b9595214bc9ad0228fbc90830130b80c050e2496
5
5
  SHA512:
6
- metadata.gz: 2a765688b85e6ea915968606f06ecb14d110a6307e5fdef7347d63b17fca5f6bf670d04fa6924a1ad1dad321eac789dc55f0a8f297e736e7d51adeb7f49d9d83
7
- data.tar.gz: 8264fd6d0902cd63e6a76232e5262e8233e1c3022bde5ef357090d870c1d3aa5ad46a0008caf2bfe53aeaa0450ebb16575c40b907fdcae7f70efa25f2e2cc436
6
+ metadata.gz: 832043736ed5cb9f89b45fac1e2b2a768ca80cabc716c5b1e9b8c6797b7e2066fc5697253eb71d4d5b91b957f091bbe55c4c2ef7fcfd68bb932677522d5ac531
7
+ data.tar.gz: 4d74f611a3f2b8962d8ae9f4c00ebc360b7eb99b1a07dc1c2e4678c32b140e47b347b3dbfb258f7e1d35cf776442e4c5ca86cac72f9d6688a33a79f634c3cb02
data/Gemfile.lock CHANGED
@@ -3,10 +3,9 @@ PATH
3
3
  specs:
4
4
  export_to (0.1.0)
5
5
  activesupport
6
+ fast_excel
6
7
  iconv
7
- roo
8
8
  spreadsheet
9
- write_xlsx
10
9
 
11
10
  GEM
12
11
  remote: https://rubygems.org/
@@ -17,30 +16,21 @@ GEM
17
16
  minitest (~> 5.1)
18
17
  tzinfo (~> 1.1)
19
18
  concurrent-ruby (1.0.5)
19
+ fast_excel (0.2.5)
20
+ ffi (> 1.9, < 2)
21
+ ffi (1.9.25)
20
22
  i18n (1.1.1)
21
23
  concurrent-ruby (~> 1.0)
22
24
  iconv (1.0.5)
23
- mini_portile2 (2.3.0)
24
25
  minitest (5.11.3)
25
- nokogiri (1.8.5)
26
- mini_portile2 (~> 2.3.0)
27
26
  rake (10.5.0)
28
- roo (2.7.1)
29
- nokogiri (~> 1)
30
- rubyzip (~> 1.1, < 2.0.0)
31
27
  ruby-ole (1.2.12.1)
32
- rubyzip (1.2.2)
33
28
  shoulda-context (1.2.2)
34
29
  spreadsheet (1.1.8)
35
30
  ruby-ole (>= 1.0)
36
31
  thread_safe (0.3.6)
37
32
  tzinfo (1.2.5)
38
33
  thread_safe (~> 0.1)
39
- write_xlsx (0.85.5)
40
- rubyzip (>= 1.0.0)
41
- zip-zip
42
- zip-zip (0.3)
43
- rubyzip (>= 1.0.0)
44
34
 
45
35
  PLATFORMS
46
36
  ruby
data/export_to.gemspec CHANGED
@@ -28,9 +28,8 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency "minitest", "~> 5.0"
29
29
  spec.add_development_dependency "shoulda-context"
30
30
 
31
- spec.add_dependency "write_xlsx"
31
+ spec.add_dependency "fast_excel"
32
32
  spec.add_dependency "spreadsheet"
33
- spec.add_dependency "roo"
34
33
  spec.add_dependency "iconv"
35
34
  spec.add_dependency "activesupport"
36
35
  end
@@ -2,39 +2,52 @@ module ExportTo
2
2
  class Base < Struct.new(:records)
3
3
  class_attribute :head_titles
4
4
  class_attribute :body_keys
5
+ class_attribute :body_column_proc
5
6
  class_attribute :presenter_klass
6
7
  class_attribute :join_relation
8
+ class_attribute :each_proc, :each_method
9
+ class_attribute :xlsx_file_path, :xlsx_file_name
7
10
 
8
11
  # 預設 presenter
9
12
  self.presenter_klass = Presenter
13
+ self.each_method = :each
14
+ self.xlsx_file_path = '/tmp'
15
+ self.xlsx_file_name = '/file'
10
16
 
11
17
  attr_accessor :object
12
18
 
13
19
  def to_csv
14
20
  CSV.generate do |csv|
15
- each do |columns, order, i|
21
+ rows! do |columns, model, x|
16
22
  csv << columns
17
23
  end
18
24
  end
19
25
  end
20
26
 
21
27
  # 新版 Excel
22
- def to_xlsx
23
- io = StringIO.new
24
- book = WriteXLSX.new(io)
25
- sheet = book.add_worksheet
28
+ def to_xlsx(file_path=nil, file_name=nil)
29
+ file_path ||= self.class.xlsx_file_path
30
+ file_name ||= self.class.xlsx_file_name
31
+ path = to_xlsx_file(file_path, file_name)
32
+ # TODO: 讀取檔案回傳
33
+ File.open(path, 'rb') { |f| f.read }
34
+ end
26
35
 
27
- # 表格頭 (粗體紅字)
28
- format_head = book.add_format.tap { |f| f.set_bold }.tap { |f| f.set_color('red') }
36
+ # 新版 Excel (outpuut: path)
37
+ def to_xlsx_file(file_path="tmp", file_name="export")
38
+ path = "#{file_path}/#{file_name}_#{Time.now.to_i}_#{SecureRandom.hex}.xlsx"
39
+ workbook = FastExcel.open(path, constant_memory: true)
40
+ worksheet = workbook.add_worksheet("Default")
29
41
 
30
- each do |columns, order, x|
31
- columns.each_with_index do |column, y|
32
- sheet.write(x, y, column, format_head)
33
- end
42
+ bold = workbook.bold_cell_format
43
+ worksheet.set_row(0, FastExcel::DEF_COL_WIDTH, bold)
44
+
45
+ rows! do |columns, model, x|
46
+ worksheet.write_row(x, columns)
34
47
  end
35
48
 
36
- book.close
37
- io.string
49
+ workbook.close
50
+ path
38
51
  end
39
52
 
40
53
  # 舊版 Excel
@@ -42,9 +55,10 @@ module ExportTo
42
55
  book = Spreadsheet::Workbook.new
43
56
  sheet = book.create_worksheet
44
57
 
45
- each do |columns, order, x|
58
+ rows! do |columns, model, x|
46
59
  sheet.row(x).concat(columns)
47
60
  end
61
+
48
62
  spreadsheet = StringIO.new
49
63
  book.write(spreadsheet)
50
64
  spreadsheet.string
@@ -52,39 +66,77 @@ module ExportTo
52
66
 
53
67
  protected
54
68
 
55
- def each
69
+ def rows
70
+ data = []
71
+ rows! do |columns, model, x|
72
+ data.push(columns)
73
+ end
74
+ data
75
+ end
76
+
77
+ def rows!
56
78
  i = 0
79
+
57
80
  yield(self.class.head_titles, nil, i)
58
81
 
59
82
  join_relation = self.class.join_relation
60
- records.each do |record|
61
- run_records = if join_relation && record.send(join_relation).nil? == false
83
+
84
+ each_models do |record, x|
85
+ run_records = if join_relation.present? && record.send(join_relation).present?
62
86
  record.send(join_relation)
63
87
  else
64
88
  [ record ]
65
89
  end
66
90
 
67
91
  # 指定目前 order 讓 subclass 可以 override
68
- run_records.each do |run_record|
92
+ run_records.each_with_index do |run_record, y|
69
93
  i = i + 1
70
- self.object = if run_record != record
71
- self.class.presenter_klass.new(record, run_record)
94
+ object = if run_record != record
95
+ self.class.presenter_klass.new(record, run_record, x, y)
72
96
  else
73
- self.class.presenter_klass.new(run_record)
97
+ self.class.presenter_klass.new(run_record, nil, x, y)
74
98
  end
75
- yield(columns!, run_record, i)
99
+
100
+ each_proc.call(object) if self.class.each_proc.present?
101
+
102
+ columns = fetch_columns!(object)
103
+
104
+ yield(columns, run_record, i)
105
+ end
106
+ end
107
+ end
108
+
109
+ def each_models(&block)
110
+ case self.class.each_method
111
+ when :each
112
+ records.each.with_index(&block)
113
+ when :find_in_batches
114
+ find_in_batches(&block)
115
+ end
116
+ end
117
+
118
+ def find_in_batches
119
+ i = 0
120
+ records.find_in_batches do |group|
121
+ group.each do |model|
122
+ yield(model, i)
123
+ i = i + 1
76
124
  end
77
125
  end
78
126
  end
79
127
 
80
128
  class << self
129
+
81
130
  protected
82
131
 
83
- def set(title, key)
132
+ def set(title, key, &block)
84
133
  self.head_titles ||= []
85
134
  self.body_keys ||= []
135
+ self.body_column_proc ||= []
136
+
86
137
  self.head_titles.push(title)
87
138
  self.body_keys.push(key)
139
+ self.body_column_proc.push(block)
88
140
  end
89
141
 
90
142
  def presenter(&block)
@@ -103,14 +155,25 @@ module ExportTo
103
155
  def joins(relation)
104
156
  self.join_relation = relation
105
157
  end
158
+
159
+ def each_with(&block)
160
+ self.each_proc = block
161
+ end
106
162
  end
107
163
 
108
164
  private
109
165
 
110
- def columns!
111
- self.class.body_keys.map do |key|
112
- data = object.send(key)
113
- data = data.gsub("\n", " ").gsub("\r", " ") if data.is_a?(String)
166
+ def fetch_columns!(object)
167
+ self.class.body_keys.map.with_index do |key, i|
168
+ data = case key
169
+ when String
170
+ key
171
+ when Symbol
172
+ (object.send(key) || "")
173
+ end
174
+
175
+ column_proc = self.class.body_column_proc[i]
176
+ data = self.class.body_column_proc[i].call(data) if column_proc.present?
114
177
  data
115
178
  end
116
179
  end
@@ -1,15 +1,15 @@
1
1
  module ExportTo
2
2
  class Presenter
3
- attr_accessor :model, :relation
3
+ attr_accessor :model, :relation, :x, :y
4
4
  NoAttributeError = Class.new(NoMethodError)
5
5
 
6
- def initialize(model, relation=nil)
7
- self.model = model
8
- self.relation = relation
6
+ def initialize(model, relation=nil, x, y)
7
+ self.model, self.relation = model, relation
8
+ self.x, self.y = x, y
9
9
  end
10
10
 
11
11
  def relation?
12
- relation != nil
12
+ relation.present?
13
13
  end
14
14
 
15
15
  def method_missing(m, *args, &block)
@@ -1,3 +1,3 @@
1
1
  module ExportTo
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/export_to.rb CHANGED
@@ -1,6 +1,8 @@
1
- require 'active_support/core_ext/class/attribute'
2
- require 'write_xlsx'
3
- require 'roo'
1
+ require 'active_support/core_ext/object'
2
+ require 'active_support/core_ext/class'
3
+ require 'active_support'
4
+ require 'fast_excel'
5
+ require 'spreadsheet'
4
6
  require 'csv'
5
7
  require 'iconv'
6
8
  require 'export_to/version'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: export_to
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - eddie
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-21 00:00:00.000000000 Z
11
+ date: 2018-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: write_xlsx
70
+ name: fast_excel
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: roo
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: iconv
113
99
  requirement: !ruby/object:Gem::Requirement