rails_data 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +165 -0
  3. data/README.md +41 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/config/rails_data_manifest.js +1 -0
  6. data/app/assets/javascripts/channels/done.js +10 -0
  7. data/app/assets/javascripts/controllers/the_data_admin/data_lists/edit.js +1 -0
  8. data/app/assets/javascripts/controllers/the_data_admin/data_lists/new.js +1 -0
  9. data/app/assets/javascripts/controllers/the_data_admin/table_lists/index.js +10 -0
  10. data/app/channels/done_channel.rb +7 -0
  11. data/app/channels/rails_data_connection.rb +29 -0
  12. data/app/controllers/rails_data_admin/base_controller.rb +3 -0
  13. data/app/controllers/rails_data_admin/data_lists_controller.rb +75 -0
  14. data/app/controllers/rails_data_admin/data_records_controller.rb +71 -0
  15. data/app/controllers/rails_data_admin/record_lists_controller.rb +105 -0
  16. data/app/controllers/rails_data_admin/table_lists_controller.rb +115 -0
  17. data/app/helpers/data_records_helper.rb +2 -0
  18. data/app/helpers/rails_data_helper.rb +21 -0
  19. data/app/jobs/table_job.rb +11 -0
  20. data/app/mailers/report_finish_mailer.rb +17 -0
  21. data/app/models/rails_data/concerns/data_cache_service.rb +26 -0
  22. data/app/models/rails_data/concerns/data_export_helper.rb +55 -0
  23. data/app/models/rails_data/concerns/data_import_helper.rb +40 -0
  24. data/app/models/rails_data/concerns/data_import_service.rb +35 -0
  25. data/app/models/rails_data/data_list.rb +47 -0
  26. data/app/models/rails_data/data_lists/data_export.rb +11 -0
  27. data/app/models/rails_data/data_lists/data_import.rb +11 -0
  28. data/app/models/rails_data/data_lists/data_record.rb +18 -0
  29. data/app/models/rails_data/export_services/csv_export_service.rb +24 -0
  30. data/app/models/rails_data/export_services/pdf_export_service.rb +74 -0
  31. data/app/models/rails_data/export_services/xlsx_export_service.rb +51 -0
  32. data/app/models/rails_data/record_list.rb +69 -0
  33. data/app/models/rails_data/table_item.rb +5 -0
  34. data/app/models/rails_data/table_list.rb +47 -0
  35. data/app/pdfs/concerns/pdf_page_helper.rb +37 -0
  36. data/app/pdfs/concerns/pdf_table_helper.rb +107 -0
  37. data/app/pdfs/concerns/pdf_text_helper.rb +18 -0
  38. data/app/pdfs/rails_data_pdf.rb +32 -0
  39. data/app/views/rails_data_admin/base/_nav.html.erb +9 -0
  40. data/app/views/rails_data_admin/data_lists/_item_form.html.erb +15 -0
  41. data/app/views/rails_data_admin/data_lists/add_item.js.erb +4 -0
  42. data/app/views/rails_data_admin/data_lists/edit.html.erb +33 -0
  43. data/app/views/rails_data_admin/data_lists/index.html.erb +43 -0
  44. data/app/views/rails_data_admin/data_lists/new.html.erb +17 -0
  45. data/app/views/rails_data_admin/data_lists/remove_item.js.erb +1 -0
  46. data/app/views/rails_data_admin/data_lists/reportable.html.erb +31 -0
  47. data/app/views/rails_data_admin/data_lists/show.html.erb +20 -0
  48. data/app/views/rails_data_admin/data_records/_item_form.html.erb +15 -0
  49. data/app/views/rails_data_admin/data_records/add_item.js.erb +4 -0
  50. data/app/views/rails_data_admin/data_records/edit.html.erb +33 -0
  51. data/app/views/rails_data_admin/data_records/index.html.erb +57 -0
  52. data/app/views/rails_data_admin/data_records/new.html.erb +16 -0
  53. data/app/views/rails_data_admin/data_records/remove_item.js.erb +1 -0
  54. data/app/views/rails_data_admin/data_records/reportable.html.erb +31 -0
  55. data/app/views/rails_data_admin/data_records/show.html.erb +20 -0
  56. data/app/views/rails_data_admin/record_lists/_edit_columns.html.erb +19 -0
  57. data/app/views/rails_data_admin/record_lists/_edit_table.erb +44 -0
  58. data/app/views/rails_data_admin/record_lists/_index.html.erb +22 -0
  59. data/app/views/rails_data_admin/record_lists/_search_form.html.erb +9 -0
  60. data/app/views/rails_data_admin/record_lists/_show.html.erb +16 -0
  61. data/app/views/rails_data_admin/record_lists/_table.html.erb +12 -0
  62. data/app/views/rails_data_admin/record_lists/edit.html.erb +19 -0
  63. data/app/views/rails_data_admin/record_lists/edit_columns.html.erb +30 -0
  64. data/app/views/rails_data_admin/record_lists/edit_columns.js.erb +9 -0
  65. data/app/views/rails_data_admin/record_lists/find.js.erb +8 -0
  66. data/app/views/rails_data_admin/record_lists/index.html.erb +52 -0
  67. data/app/views/rails_data_admin/record_lists/new.html.erb +19 -0
  68. data/app/views/rails_data_admin/record_lists/show.html.erb +19 -0
  69. data/app/views/rails_data_admin/record_lists/show.js.erb +8 -0
  70. data/app/views/rails_data_admin/record_lists/update_columns.js.erb +8 -0
  71. data/app/views/rails_data_admin/table_lists/_import.html.erb +17 -0
  72. data/app/views/rails_data_admin/table_lists/_index.html.erb +22 -0
  73. data/app/views/rails_data_admin/table_lists/_process.html.erb +5 -0
  74. data/app/views/rails_data_admin/table_lists/_show.html.erb +10 -0
  75. data/app/views/rails_data_admin/table_lists/_table.html.erb +38 -0
  76. data/app/views/rails_data_admin/table_lists/create_import.js.erb +8 -0
  77. data/app/views/rails_data_admin/table_lists/edit.html.erb +19 -0
  78. data/app/views/rails_data_admin/table_lists/find.js.erb +2 -0
  79. data/app/views/rails_data_admin/table_lists/index.html.erb +55 -0
  80. data/app/views/rails_data_admin/table_lists/new.html.erb +19 -0
  81. data/app/views/rails_data_admin/table_lists/new_import.js.erb +30 -0
  82. data/app/views/rails_data_admin/table_lists/run.js.erb +10 -0
  83. data/app/views/rails_data_admin/table_lists/show.html.erb +11 -0
  84. data/app/views/report_finish_mailer/finish_notify.text.erb +5 -0
  85. data/config/initializers/the_data.rb +4 -0
  86. data/config/locales/en.yml +10 -0
  87. data/config/locales/zh.yml +10 -0
  88. data/config/routes.rb +35 -0
  89. data/db/migrate/20150618053929_create_report_lists.rb +51 -0
  90. data/lib/rails_data/config.rb +23 -0
  91. data/lib/rails_data/engine.rb +18 -0
  92. data/lib/rails_data/export.rb +52 -0
  93. data/lib/rails_data/import.rb +42 -0
  94. data/lib/rails_data/record.rb +42 -0
  95. data/lib/rails_data/version.rb +3 -0
  96. data/lib/rails_data.rb +5 -0
  97. data/test/controllers/data_records_controller_test.rb +48 -0
  98. data/test/controllers/rails_data_admin/report_lists_controller_test.rb +49 -0
  99. data/test/controllers/rails_data_admin/table_lists_controller_test.rb +49 -0
  100. data/test/factories/combines.rb +7 -0
  101. data/test/factories/report_lists.rb +14 -0
  102. data/test/factories/table_items.rb +6 -0
  103. data/test/factories/table_lists.rb +6 -0
  104. data/test/integration/navigation_test.rb +10 -0
  105. data/test/models/data_list_test.rb +10 -0
  106. data/test/system/data_records_test.rb +41 -0
  107. data/test/test_helper.rb +21 -0
  108. data/test/the_data_test.rb +7 -0
  109. metadata +247 -0
@@ -0,0 +1,2 @@
1
+ module DataRecordsHelper
2
+ end
@@ -0,0 +1,21 @@
1
+ module RailsDataHelper
2
+
3
+ def text_field_tag(name, value = nil, options = {})
4
+ if options[:as]
5
+ type = RailsData.config.mapping[options[:as]][:input]
6
+
7
+ if type == 'textarea'
8
+ return text_area_tag(name, value, options)
9
+ end
10
+
11
+ if type == 'select'
12
+ opts = RailsData.config.mapping[options[:as]][:options]
13
+ selected = RailsData.config.mapping[options[:as]][:selected]
14
+ return select_tag name, options_for_select(opts, selected), options
15
+ end
16
+ end
17
+
18
+ super
19
+ end
20
+
21
+ end
@@ -0,0 +1,11 @@
1
+ class TableJob < ActiveJob::Base
2
+ queue_as :default
3
+
4
+ def perform(table_list_id, user_id)
5
+ @table_list = TableList.find(table_list_id)
6
+ @table_list.run
7
+
8
+ ActionCable.server.broadcast "user:#{user_id}", body: '<i class="green checkmark icon"></i>', done_id: table_list_id
9
+ end
10
+
11
+ end
@@ -0,0 +1,17 @@
1
+ class ReportFinishMailer < ActionMailer::Base
2
+ default from: ""
3
+
4
+ def finish_notify(id)
5
+ @report_list = ReportList.find(id)
6
+ @message = @report_list.notice_body
7
+
8
+ if Rails.env == 'production'
9
+ @email = @report_list.notice_email
10
+ else
11
+ @email = 'mingyuan0715@foxmail.com'
12
+ end
13
+
14
+ mail to: @email, subject: "Generation Complete"
15
+ end
16
+
17
+ end
@@ -0,0 +1,26 @@
1
+ class DataCacheService
2
+ include DataExportHelper
3
+
4
+ def initialize(table_list)
5
+ @table_list = table_list
6
+ @data_list = @table_list.data_list
7
+ @config_table = table_list.data_list.config_table
8
+ convert_parameters(@table_list.parameters)
9
+ end
10
+
11
+ def cache_table
12
+ @table_list.headers = header_result
13
+ cache_table_items
14
+ @table_list.footers = footer_result
15
+ @table_list.done = true
16
+ @table_list.save
17
+ end
18
+
19
+ def cache_table_items
20
+ @config_table.collection.call(@params).each_with_index do |object, index|
21
+ row = field_result(object, index)
22
+ @table_list.table_items.create(fields: row)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,55 @@
1
+ module DataExportHelper
2
+
3
+ def convert_parameters(parameters)
4
+ @params = {}
5
+ parameters.each do |k, v|
6
+ @params.merge! k.to_sym => v.send(RailsData.config.mapping[@data_list.parameters[k].to_sym][:output])
7
+ end
8
+ @params
9
+ end
10
+
11
+ def header_result
12
+ results = []
13
+
14
+ @config_table.columns.each do |_, column|
15
+ if column[:header].respond_to?(:call)
16
+ results << column[:header].call
17
+ else
18
+ results << column[:header]
19
+ end
20
+ end
21
+ results
22
+ end
23
+
24
+ def field_result(object, index)
25
+ results = []
26
+ @config_table.columns.each do |_, column|
27
+ params = column[:field].parameters.to_combined_h
28
+ if Array(params[:key]).include? :index
29
+ results << column[:field].call(object, index)
30
+ elsif params[:key]
31
+ results << column[:field].call(object, **@params.slice(params[:key]))
32
+ elsif params[:key].blank? && params[:req]
33
+ results << column[:field].call(object)
34
+ else
35
+ results << nil
36
+ end
37
+ end
38
+
39
+ results
40
+ end
41
+
42
+ def footer_result
43
+ results = []
44
+
45
+ @config_table.columns.each do |_, column|
46
+ if column[:footer].respond_to?(:call)
47
+ results << column[:footer].call
48
+ else
49
+ results << column[:footer]
50
+ end
51
+ end
52
+ results
53
+ end
54
+
55
+ end
@@ -0,0 +1,40 @@
1
+ module DataImportHelper
2
+
3
+ def import_to_table_list(file)
4
+ importer = data_list.importer(file)
5
+ self.headers = importer.results[0]
6
+ self.done = true
7
+ self.save
8
+ importer.results[1..-1].each do |row|
9
+ table_items.create(fields: row)
10
+ end
11
+ end
12
+
13
+ def import_columns
14
+ config = data_list.config_table
15
+ columns = {}
16
+ config.columns.each do |key, value|
17
+ columns[key] = config.columns[key].merge(index: self.headers.find_index(value[:header]))
18
+ end
19
+ columns.reject { |_, v| v[:index].nil? }
20
+ end
21
+
22
+ def migrate
23
+ config = data_list.config_table
24
+ columns = import_columns
25
+ self.table_items.each do |table_item|
26
+ attr = {}
27
+ columns.map do |key, value|
28
+ r = table_item.fields[value[:index]]
29
+ if value[:field] && value[:field].respond_to?(:call)
30
+ attr[key] = value[:field].call(r)
31
+ else
32
+ attr[key] = r
33
+ end
34
+ end
35
+ config.record.create attr
36
+ end
37
+ self.destroy
38
+ end
39
+
40
+ end
@@ -0,0 +1,35 @@
1
+ require 'roo'
2
+ class DataImportService
3
+ attr_reader :sheet, :column_index
4
+
5
+ def initialize(config, sheet_file)
6
+ if File.extname(sheet_file.path) == '.xls'
7
+ require 'roo-xls'
8
+ xlsx = Roo::Excel.new(sheet_file)
9
+ else
10
+ xlsx = Roo::Excelx.new(sheet_file)
11
+ end
12
+ @sheet = xlsx.sheet(xlsx.sheets[0])
13
+ @config = config
14
+
15
+ @column_index = init_header.compact
16
+ end
17
+
18
+ def init_header
19
+ headers = @config.columns.map { |_, v| v[:header] }
20
+ file_header = @sheet.row(1)
21
+
22
+ headers.map do |header|
23
+ file_header.find_index(header)
24
+ end
25
+ end
26
+
27
+ def results
28
+ results = []
29
+ @sheet.each do |row|
30
+ results << column_index.map { |index| row[index] }
31
+ end
32
+ results
33
+ end
34
+
35
+ end
@@ -0,0 +1,47 @@
1
+ require 'rails_com/utils/setting'
2
+ class DataList < ApplicationRecord
3
+ serialize :parameters, Hash
4
+ serialize :columns, Hash
5
+
6
+ has_many :table_lists, dependent: :destroy
7
+ has_many :table_items, through: :table_lists
8
+
9
+ scope :published, -> { where(published: true) }
10
+
11
+ before_create :update_parameters
12
+
13
+ def rebuild!
14
+ self.save
15
+ end
16
+
17
+ def form_parameters
18
+ r = parameters.map { |k, v| { key: k, value: v } }
19
+ if r.blank?
20
+ r = [{ key: nil, value: nil }]
21
+ end
22
+ Settings.new(r)
23
+ end
24
+
25
+ def update_parameters
26
+ self.parameters = config_params
27
+ end
28
+
29
+ def config_params
30
+ hash = {}
31
+ config_table.parameters.map { |p| hash[p] = nil }
32
+ hash
33
+ end
34
+
35
+ def config_table
36
+ @config_table ||= data_table.to_s.safe_constantize
37
+ end
38
+
39
+ def config_excel
40
+ @config_excel ||= export_excel.to_s.safe_constantize
41
+ end
42
+
43
+ def config_pdf
44
+ @config_pdf ||= export_pdf.to_s.safe_constantize
45
+ end
46
+
47
+ end
@@ -0,0 +1,11 @@
1
+ class DataExport < DataList
2
+
3
+ def headers
4
+ config_table.columns.map { |p| p[1][:header] }
5
+ end
6
+
7
+ def just_run
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ class DataImport < DataList
2
+
3
+ def importer(file)
4
+ @importer ||= DataImportService.new(config_table, file)
5
+ end
6
+
7
+
8
+ def config_params
9
+ {}
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ class DataRecord < DataList
2
+ has_many :record_lists, foreign_key: 'data_list_id', dependent: :destroy
3
+ has_many :record_items, through: :record_lists
4
+
5
+ def rebuild!
6
+ self.columns = self.config_params
7
+ super
8
+ end
9
+
10
+ def update_parameters
11
+ self.columns = config_columns
12
+ end
13
+
14
+ def config_columns
15
+ config_table.columns.transform_values { |x| x[:as] }
16
+ end
17
+
18
+ end
@@ -0,0 +1,24 @@
1
+ require 'csv'
2
+ class CsvExportService
3
+ include DataExportHelper
4
+
5
+ attr_reader :sheet, :headers
6
+
7
+ def initialize
8
+ headers =
9
+ config_table
10
+
11
+
12
+ end
13
+
14
+
15
+ def to_csv
16
+ csv = ''
17
+ csv << headers.to_csv
18
+ self.table_items.each do |table_item|
19
+ csv << table_item.fields.to_csv
20
+ end
21
+ csv
22
+ end
23
+
24
+ end
@@ -0,0 +1,74 @@
1
+ require 'prawn/table'
2
+ class PdfExportService
3
+ include DataExportHelper
4
+
5
+ def pdf
6
+ if reportable.respond_to?(:pdf_object)
7
+ @pdf ||= reportable.pdf_object(reportable_name)
8
+ else
9
+ @pdf ||= TablePdf.new
10
+ end
11
+ end
12
+
13
+ def remove_file_save
14
+ self.remove_file = true
15
+ self.save
16
+ self.remove_file = nil
17
+ end
18
+
19
+ def pdf_data
20
+ if file_id
21
+ file.read
22
+ else
23
+ pdf_string
24
+ end
25
+ end
26
+
27
+ def pdf_string
28
+ pdf_result.render
29
+ end
30
+
31
+ def pdf_result
32
+ pdf.table_data = table_lists.includes(:table_items).map { |i| i.csv_array }
33
+ pdf.header_data = header_data
34
+ pdf.ending_data = ending_data
35
+ pdf.run
36
+ pdf
37
+ end
38
+
39
+ def header_data
40
+ if reportable.respond_to? :header_info
41
+ reportable.header_info
42
+ else
43
+ [
44
+ ['', ''],
45
+ ['', '']
46
+ ]
47
+ end
48
+ end
49
+
50
+ def ending_data
51
+ if reportable.respond_to? :ending_data
52
+ reportable.try(:ending_data)
53
+ else
54
+ ''
55
+ end
56
+ end
57
+
58
+ def filename(extension = 'pdf')
59
+ if file_filename.present?
60
+ filename = file_filename
61
+ elsif reportable.respond_to?(:filename)
62
+ filename = reportable.filename
63
+ else
64
+ filename = "#{reportable_name.camelize}-#{reportable_id}"
65
+ end
66
+
67
+ unless filename.end_with?(extension)
68
+ filename << '.' << extension
69
+ end
70
+
71
+ filename
72
+ end
73
+
74
+ end
@@ -0,0 +1,51 @@
1
+ require 'write_xlsx'
2
+ class XlsxExportService
3
+ include DataExportHelper
4
+ attr_reader :sheet,
5
+ :table_list,
6
+ :params, :headers
7
+
8
+ def initialize(table_list: nil, data_list: nil, params: {}, headers: [])
9
+ if table_list
10
+ @table_list = table_list
11
+ @data_list = table_list.data_list
12
+ @headers = headers.presence || table_list.headers
13
+ convert_parameters(params)
14
+ elsif data_list
15
+ @data_list = data_list
16
+ @headers = headers
17
+ convert_parameters(params)
18
+ end
19
+ @config_table = @data_list.config_table
20
+
21
+ @io = StringIO.new
22
+ @workbook = WriteXLSX.new(@io)
23
+ @sheet = @workbook.add_worksheet
24
+ end
25
+
26
+ def direct_xlsx
27
+ sheet.write_row(0, 0, headers)
28
+
29
+ @config_table.collection.call(@params).each_with_index do |object, index|
30
+ row = field_result(object, index)
31
+ sheet.write_row(index + 1, 0, row)
32
+ end
33
+
34
+ @workbook.close
35
+ @io.string
36
+ end
37
+
38
+ def cached_xlsx
39
+ sheet.write_row(0, 0, table_list.headers)
40
+
41
+ table_list.table_items.each_with_index do |table_item, index|
42
+ sheet.write_row(index + 1, 0, table_item.fields)
43
+ end
44
+
45
+ sheet.write_row table_list.table_items_count + 1, 0, table_list.footers
46
+
47
+ @workbook.close
48
+ @io.string
49
+ end
50
+
51
+ end
@@ -0,0 +1,69 @@
1
+ class RecordList < ApplicationRecord
2
+ serialize :columns, Hash
3
+ serialize :parameters, Hash
4
+ belongs_to :data_list
5
+
6
+ default_scope -> { order(id: :desc) }
7
+
8
+ def run
9
+ to_table
10
+ end
11
+
12
+ def to_table
13
+ initialize_table
14
+ self.to_table_items
15
+ self.done = true
16
+ self.save
17
+ end
18
+
19
+ def initialize_table
20
+ @config_table = data_list.config_table
21
+ @record = @config_table.record.call(converted_parameters)
22
+ @config_table
23
+ end
24
+
25
+ def converted_parameters
26
+ param = {}
27
+ parameters.each do |k, v|
28
+ param.merge! k.to_sym => v.send(RailsData.config.mapping[data_list.parameters[k].to_sym][:output])
29
+ end
30
+ param
31
+ end
32
+
33
+ def to_table_items
34
+ self.columns = field_result(@record)
35
+ end
36
+
37
+ def field_result(object)
38
+ results = {}
39
+ @config_table.columns.each do |key, column|
40
+ if column[:field].arity == 1
41
+ results[key] = column[:field].call(object)
42
+ else
43
+ results[key] = nil
44
+ end
45
+ end
46
+
47
+ results
48
+ end
49
+
50
+ def to_xlsx
51
+ @config_excel = data_list.config_excel.new(self.columns)
52
+ @config_excel.render
53
+ end
54
+
55
+ def to_pdf
56
+ @config_pdf ||= data_list.config_pdf.new(self.columns)
57
+ @config_pdf.render
58
+ end
59
+
60
+ def xlsx_file_name
61
+ @config_excel.file_name || "#{self.id}.xlsx"
62
+ end
63
+
64
+ def file_name(format)
65
+ name = self.id || 'example'
66
+ "#{name}.#{format}"
67
+ end
68
+
69
+ end
@@ -0,0 +1,5 @@
1
+ class TableItem < ApplicationRecord
2
+ serialize :fields, Array
3
+ belongs_to :table_list, counter_cache: true
4
+
5
+ end
@@ -0,0 +1,47 @@
1
+ class TableList < ApplicationRecord
2
+ include DataImportHelper
3
+ serialize :parameters, Hash
4
+ serialize :headers, Array
5
+ serialize :footers, Array
6
+
7
+ belongs_to :data_list, optional: true
8
+ has_many :table_items, dependent: :delete_all
9
+
10
+ def run
11
+ clear_old
12
+ export = DataCacheService.new(self)
13
+ export.cache_table
14
+ end
15
+
16
+ def direct_xlsx
17
+ _headers = self.headers.presence || self.data_list.headers
18
+ export = XlsxExportService.new(data_list: self.data_list, params: self.parameters, headers: _headers)
19
+ export.direct_xlsx
20
+ end
21
+
22
+ def cached_xlsx
23
+ export = XlsxExportService.new(table_list: self)
24
+ export.cached_xlsx
25
+ end
26
+
27
+ def cached_run(_timestamp = nil)
28
+ unless self.timestamp.present? && self.timestamp == _timestamp.to_s
29
+ self.timestamp = _timestamp
30
+ run
31
+ end
32
+ end
33
+
34
+ def clear_old
35
+ self.done = false
36
+ self.class.transaction do
37
+ self.save!
38
+ table_items.delete_all
39
+ end
40
+ end
41
+
42
+ def file_name(format)
43
+ name = self.id || 'example'
44
+ "#{name}.#{format}"
45
+ end
46
+
47
+ end
@@ -0,0 +1,37 @@
1
+ module PdfPageHelper
2
+
3
+ def repeat_header(data = nil)
4
+ repeat :all do
5
+ canvas do
6
+ bounding_box [bounds.left+75, bounds.top-20], :width => bounds.width do
7
+ process_header(data)
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ def process_header(data)
14
+ default_options = {
15
+ cell_style: { borders: [] },
16
+ column_widths: [225, 220]
17
+ }
18
+
19
+ table(data, default_options) do
20
+ row(0).style font_style: :bold, size: 14
21
+ row(1..-1).style size: 10
22
+ column(0).style align: :left, padding: 0
23
+ column(1).style align: :right, padding: 0
24
+ cells[2, 0].style size: 12 if cells[2, 0].present?
25
+ end
26
+
27
+ move_down 50
28
+ end
29
+
30
+ def footer(data = nil, options = {})
31
+ text data
32
+ if options[:page]
33
+ number_pages "<page> / <total>", at: [bounds.right - 50, 0]
34
+ end
35
+ end
36
+
37
+ end