Skip to content

Commit 9a918d3

Browse files
committed
basic test after refactoring
1 parent f948eee commit 9a918d3

18 files changed

+564
-9
lines changed

.byebug_history

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
q
2+
o_row.nil?
3+
o_row.empty?
4+
o_row.to_a
5+
o_row
6+
7+
8+

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
/pkg/
88
/spec/reports/
99
/tmp/
10+
/spec/results/
11+
/palestra.rb

ecco.xlsx

5.08 KB
Binary file not shown.

lib/merge_excel.rb

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1-
require "merge_excel/version"
1+
require 'spreadsheet' # https://github.com/zdavatz/spreadsheet/blob/master/GUIDE.md
2+
require 'rubyXL' # https://github.com/weshatheleopard/rubyXL
3+
require 'fileutils'
4+
require 'date'
5+
require 'byebug'
26

3-
module MergeExcel
4-
# Your code goes here...
5-
end
7+
require "merge_excel/wbook"
8+
require "merge_excel/sheet"
9+
require "merge_excel/header"
10+
require "merge_excel/data_row"
11+
require "merge_excel/version"
12+
require "merge_excel/excel"
13+
require "merge_excel/spreadsheet_parser"
14+
require "merge_excel/spreadsheet_writer"
15+
require "merge_excel/extensions/spreadsheet/worksheet"
16+
require "merge_excel/extensions/spreadsheet/workbook"
17+
require "merge_excel/extensions/rubyXL/worksheet"
18+
require "merge_excel/extensions/rubyXL/workbook"

lib/merge_excel/data_row.rb

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module MergeExcel
2+
class DataRow
3+
attr_reader :array
4+
def initialize(array, extra_data_hash, book_filename, book)
5+
if extra_data_hash
6+
extra_array = extra_data_hash[:data].map do |e|
7+
case e[:data]
8+
when :filename
9+
book_filename
10+
else
11+
cell_value_at(e[:data][:sheet_idx], e[:data][:row_idx], e[:data][:col_idx])
12+
# if is_xls
13+
# book.worksheet(e[:data][:sheet_idx]).row(e[:data][:row_idx])[e[:data][:col_idx]]
14+
# else
15+
# c = book.worksheets[e[:data][:sheet_idx]][e[:data][:row_idx]][e[:data][:col_idx]]
16+
# c && c.value
17+
# end
18+
end
19+
end
20+
case extra_data_hash[:position]
21+
when :beginning
22+
@array = extra_array + array
23+
else
24+
@array = array + extra_array
25+
end
26+
else
27+
@array = array
28+
end
29+
end
30+
31+
def to_a
32+
@array.to_a
33+
end
34+
end
35+
end

lib/merge_excel/excel.rb

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module MergeExcel
2+
class Excel
3+
attr_reader :files
4+
def initialize(hash, selector_pattern="*.{xls,xlsx}")
5+
@h = hash
6+
@files = Dir.glob(File.join(@h[:input_dir], selector_pattern))
7+
check_options
8+
end
9+
10+
def merge
11+
wbook = WBook.new(@files.first, @h)
12+
@files.each do |i_xls_filepath|
13+
puts i_xls_filepath
14+
wbook.import_data(i_xls_filepath)
15+
end
16+
output_file_path = @h[:output_file_path]
17+
wbook.export output_file_path
18+
end
19+
20+
21+
private
22+
23+
def check_options
24+
@h = {
25+
sheets_idxs: :all,
26+
header_rows: {
27+
any: {
28+
row_idx: 0,
29+
from_col_idx: 0,
30+
to_col_idx: :last
31+
}
32+
},
33+
data_rows: {
34+
any: {
35+
first_row_idx: 1,
36+
from_col_idx: 0,
37+
to_col_idx: :last
38+
}
39+
},
40+
extra_data: {}
41+
}.merge(@h)
42+
end
43+
end
44+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module RubyXL
2+
class Workbook
3+
def add_worksheet_at(idx, name)
4+
sheet = Worksheet.new(sheet_name: name, workbook: self)
5+
worksheets[idx] = sheet
6+
sheet
7+
end
8+
9+
def cell_value_at(sheet_idx, row_idx, col_idx)
10+
c = worksheets[sheet_idx][row_idx][col_idx]
11+
c && c.value
12+
end
13+
end
14+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module RubyXL
2+
class Worksheet
3+
def row_values(row_idx, from_col_idx=0, to_col_idx=-1)
4+
values = sheet_data[row_idx] && sheet_data[row_idx].cells[from_col_idx..to_col_idx].map{|c| c && c.value}
5+
return nil if values.nil? || values.empty? || values.all?(&:nil?)
6+
values
7+
end
8+
9+
def add_row_at(row_idx, cells_array)
10+
cells_array.to_a.each_with_index do |cell, col_idx|
11+
if cell.is_a? DateTime
12+
c = add_cell(row_idx, col_idx)
13+
c.set_number_format('yyyy-mm-dd')
14+
c.change_contents(cell)
15+
else
16+
add_cell(row_idx, col_idx, cell)
17+
end
18+
end
19+
end
20+
end
21+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module Spreadsheet
2+
class Workbook
3+
def add_worksheet_at(idx, name)
4+
ws = Worksheet.new(name: name)
5+
add_worksheet(ws)
6+
end
7+
8+
def cell_value_at(sheet_idx, row_idx, col_idx)
9+
worksheet(sheet_idx).row(row_idx)[col_idx]
10+
end
11+
end
12+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module Spreadsheet
2+
class Worksheet
3+
def sheet_name
4+
name
5+
end
6+
7+
def row_values(row_idx, from_col_idx=0, to_col_idx=-1)
8+
values = row(row_idx) && row(row_idx).to_a[from_col_idx..to_col_idx]
9+
return nil if values.nil? || values.empty? || values.all?(&:nil?)
10+
values
11+
end
12+
13+
def add_row_at(row_idx, cells_array)
14+
row(row_idx).concat cells_array.to_a
15+
end
16+
end
17+
end

lib/merge_excel/header.rb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module MergeExcel
2+
class Header
3+
def initialize(array, extra_data_hash)
4+
if extra_data_hash
5+
extra_array = extra_data_hash[:data].map{|e| e[:heading_text]}
6+
case extra_data_hash[:position]
7+
when :beginning
8+
@array = extra_array + array
9+
else
10+
@array = array + extra_array
11+
end
12+
else
13+
@array = array
14+
end
15+
end
16+
17+
def to_a
18+
@array.to_a
19+
end
20+
end
21+
end

lib/merge_excel/sheet.rb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module MergeExcel
2+
class Sheet
3+
attr_reader :original_idx, :idx, :name, :header, :data_rows
4+
def initialize(original_idx, idx, name, book)
5+
@original_idx = original_idx
6+
@idx = idx
7+
@name = name
8+
@header = nil
9+
@book = book
10+
@data_rows = []
11+
end
12+
13+
def add_header(array, extra_data)
14+
@header = Header.new(array, extra_data)
15+
end
16+
17+
def add_data_row(array, extra_data, book_filename, book)
18+
@data_rows << DataRow.new(array || [], extra_data, book_filename, book).array
19+
end
20+
end
21+
end

lib/merge_excel/spreadsheet_parser.rb

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module MergeExcel
2+
class SpreadsheetParser
3+
def self.open(filepath, format)
4+
case format
5+
when :xls
6+
Spreadsheet.open(filepath)
7+
when :xlsx
8+
RubyXL::Parser.parse(filepath)
9+
else
10+
raise "Invalid format"
11+
end
12+
end
13+
end
14+
end

lib/merge_excel/spreadsheet_writer.rb

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module MergeExcel
2+
class SpreadsheetWriter
3+
def self.create(filepath, format)
4+
wb = case format
5+
when :xls
6+
Spreadsheet::Workbook.new
7+
8+
when :xlsx
9+
RubyXL::Workbook.new
10+
else
11+
raise "Invalid format"
12+
end
13+
14+
yield(wb)
15+
wb.write filepath
16+
end
17+
end
18+
end

lib/merge_excel/wbook.rb

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
module MergeExcel
2+
class WBook
3+
attr_reader :sheets, :hash, :format, :filepath, :filename
4+
5+
def initialize(filepath, hash)
6+
@sheets = []
7+
@hash = hash
8+
@format = detect_format(filepath) # :xls or :xlsx
9+
@filepath = filepath
10+
@filename = File.basename(filepath)
11+
12+
book = SpreadsheetParser.open(filepath, @format)
13+
book.worksheets.each_with_index do |sheet, idx|
14+
i = 0
15+
if @hash[:sheets_idxs]==:all || @hash[:sheets_idxs].include?(idx)
16+
raise InvalidOptions if !@hash[:header_rows].keys.include?(idx)
17+
s = @hash[:header_rows][idx] # settings
18+
sh = Sheet.new(idx, i, sheet.sheet_name, self)
19+
arr = sheet.row_values(s[:row_idx], s[:from_col_idx], s[:to_col_idx])
20+
sh.add_header(arr, @hash[:extra_data][idx])
21+
@sheets << sh
22+
i+=1
23+
end
24+
end
25+
end
26+
27+
28+
def sheet(original_idx: )
29+
@sheets.find{|s| s.original_idx==original_idx}
30+
end
31+
32+
33+
def import_data(filepath)
34+
book = SpreadsheetParser.open(filepath, @format)
35+
filename = File.basename(filepath)
36+
@hash[:sheets_idxs].each do |idx|
37+
s = sheet(original_idx: idx)
38+
sheet_to_read = book.worksheets[idx]
39+
if row_settings = @hash[:data_rows][idx] # is an hash
40+
row_idx = row_settings[:first_row_idx]
41+
loop do
42+
break unless cells = sheet_to_read.row_values(row_idx, row_settings[:from_col_idx], row_settings[:to_col_idx])
43+
s.add_data_row(cells, @hash[:extra_data][idx], filename, book)
44+
row_idx+=1
45+
end
46+
end
47+
end
48+
end
49+
50+
51+
def export(filepath)
52+
print "Exporting data..."
53+
SpreadsheetWriter.create(filepath, @format) do |wb|
54+
@sheets.each_with_index do |sheet, sheet_idx|
55+
s = wb.add_worksheet_at(sheet_idx, sheet.name)
56+
s.add_row_at(0, sheet.header)
57+
sheet.data_rows.each_with_index do |data_row, row_idx|
58+
s.add_row_at(row_idx+1, data_row)
59+
end
60+
end
61+
end
62+
63+
# if xls?
64+
# merged_book = Spreadsheet::Workbook.new
65+
# @sheets.each do |sheet|
66+
# s = merged_book.create_worksheet name: sheet.name
67+
# s.row(0).concat sheet.header.to_a
68+
# sheet.data_rows.each_with_index do |data_row, i|
69+
# s.row(i+1).concat data_row.to_a
70+
# end
71+
# end
72+
# merged_book.write filename
73+
#
74+
# else
75+
# merged_book = RubyXL::Workbook.new
76+
# @sheets.each_with_index do |sheet, i|
77+
# if i==0
78+
# s = merged_book.worksheets[0]
79+
# s.sheet_name = sheet.name
80+
# else
81+
# s = merged_book.add_worksheet sheet.name
82+
# end
83+
#
84+
# sheet.header.to_a.each_with_index do |header_cell, idx|
85+
# s.add_cell(0, idx, header_cell)
86+
# end
87+
# sheet.data_rows.each_with_index do |data_row, row_idx|
88+
# data_row.to_a.each_with_index do |data_cell, col_idx|
89+
# # puts "#{data_cell} -> #{data_cell.class}"
90+
# # exit if row_idx>8
91+
# if data_cell.is_a? DateTime
92+
# c = s.add_cell(row_idx+1, col_idx)
93+
# c.set_number_format('yyyy-mm-dd')
94+
# c.change_contents(data_cell)
95+
# else
96+
# s.add_cell(row_idx+1, col_idx, data_cell)
97+
# end
98+
#
99+
# end
100+
# end
101+
# end
102+
# merged_book.write filename
103+
# end
104+
puts "finished!"
105+
end
106+
107+
private
108+
def detect_format(filepath)
109+
case File.extname(filepath)
110+
when ".xls"
111+
:xls
112+
when ".xlsx"
113+
:xlsx
114+
else
115+
raise "Invalid format"
116+
end
117+
end
118+
end
119+
end

0 commit comments

Comments
 (0)