workbook 0.7.3 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -1
- data/lib/workbook.rb +1 -1
- data/lib/workbook/book.rb +7 -15
- data/lib/workbook/cell.rb +1 -1
- data/lib/workbook/column.rb +4 -1
- data/lib/workbook/format.rb +7 -2
- data/lib/workbook/generatetypes.rb +1 -0
- data/lib/workbook/modules/cache.rb +1 -0
- data/lib/workbook/modules/cell.rb +86 -76
- data/lib/workbook/modules/diff_sort.rb +1 -0
- data/lib/workbook/modules/raw_objects_storage.rb +1 -0
- data/lib/workbook/modules/type_parser.rb +1 -0
- data/lib/workbook/nil_value.rb +1 -0
- data/lib/workbook/readers/csv_reader.rb +5 -9
- data/lib/workbook/readers/ods_reader.rb +1 -1
- data/lib/workbook/readers/txt_reader.rb +2 -1
- data/lib/workbook/readers/xls_reader.rb +64 -51
- data/lib/workbook/readers/xls_shared.rb +1 -1
- data/lib/workbook/readers/xlsx_reader.rb +1 -0
- data/lib/workbook/row.rb +1 -1
- data/lib/workbook/sheet.rb +1 -0
- data/lib/workbook/table.rb +1 -0
- data/lib/workbook/template.rb +1 -0
- data/lib/workbook/types/date.rb +1 -0
- data/lib/workbook/types/false.rb +1 -0
- data/lib/workbook/types/false_class.rb +1 -0
- data/lib/workbook/types/nil.rb +1 -0
- data/lib/workbook/types/nil_class.rb +1 -0
- data/lib/workbook/types/numeric.rb +1 -0
- data/lib/workbook/types/string.rb +1 -0
- data/lib/workbook/types/time.rb +1 -0
- data/lib/workbook/types/true.rb +1 -0
- data/lib/workbook/types/true_class.rb +1 -0
- data/lib/workbook/version.rb +2 -1
- data/lib/workbook/writers/csv_table_writer.rb +1 -0
- data/lib/workbook/writers/html_writer.rb +1 -0
- data/lib/workbook/writers/json_table_writer.rb +5 -4
- data/lib/workbook/writers/xls_writer.rb +1 -0
- data/lib/workbook/writers/xlsx_writer.rb +1 -0
- data/test/test_modules_cell.rb +7 -1
- data/workbook.gemspec +2 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11e8d0a279d7da324133ad5d1451518716049334
|
4
|
+
data.tar.gz: d0501d220b67ce8cd0161a2fdf600fe7834504f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eeec53fc99efc09a2aebd0a0b7a2429dabaa20fd9efd33e878c63a5b6948ffc8762741e89ec68dbea4232d3b932f21b4422d3cfa190d29c82847a786ce9eeb17
|
7
|
+
data.tar.gz: e983e2a8e83bec46581240c4a1645ff2c181bf01a7541d7f530a83897e9d8c8191a98253651a6108076c7747b34aba92d8d358416ad3f50c1367fc7dbfc83da6
|
data/.travis.yml
CHANGED
@@ -1,10 +1,19 @@
|
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- CC_TEST_REPORTER_ID=f208db3cda3089cf4020651d7500fe34389b97d65ccb5b23b674a2f828fa5abb
|
1
4
|
sudo: false
|
2
5
|
language: ruby
|
3
6
|
rvm:
|
4
|
-
- 2.0.0
|
5
7
|
- 2.1.0
|
6
8
|
- 2.2.0
|
7
9
|
- 2.3.0
|
8
10
|
- 2.4.0
|
11
|
+
- 2.5.0
|
9
12
|
before_install:
|
10
13
|
- gem install bundler
|
14
|
+
before_script:
|
15
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
16
|
+
- chmod +x ./cc-test-reporter
|
17
|
+
- ./cc-test-reporter before-build
|
18
|
+
after_script:
|
19
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/lib/workbook.rb
CHANGED
data/lib/workbook/book.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
require 'open-uri'
|
3
4
|
require 'workbook/writers/xls_writer'
|
4
5
|
require 'workbook/writers/xlsx_writer'
|
@@ -160,22 +161,13 @@ module Workbook
|
|
160
161
|
#
|
161
162
|
# @param [String] text a string to convert
|
162
163
|
def text_to_utf8 text
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
text = Iconv.conv("UTF-8//TRANSLIT//IGNORE",detected_encoding,text)
|
169
|
-
text = text.gsub("\xEF\xBB\xBF", '') # removing the BOM...
|
170
|
-
else
|
171
|
-
unless text.valid_encoding? and text.encoding == "UTF-8"
|
172
|
-
# TODO: had some ruby 1.9 problems with rchardet ... but ideally it or a similar functionality will be reintroduced
|
173
|
-
source_encoding = text.valid_encoding? ? text.encoding : "US-ASCII"
|
174
|
-
text = text.encode('UTF-8', source_encoding, {:invalid=>:replace, :undef=>:replace, :replace=>""})
|
175
|
-
text = text.gsub("\u0000","") # TODO: this cleanup of nil values isn't supposed to be needed...
|
176
|
-
end
|
164
|
+
unless text.valid_encoding? and text.encoding == "UTF-8"
|
165
|
+
# TODO: had some ruby 1.9 problems with rchardet ... but ideally it or a similar functionality will be reintroduced
|
166
|
+
source_encoding = text.valid_encoding? ? text.encoding : "US-ASCII"
|
167
|
+
text = text.encode('UTF-8', source_encoding, {:invalid=>:replace, :undef=>:replace, :replace=>""})
|
168
|
+
text = text.gsub("\u0000","") # TODO: this cleanup of nil values isn't supposed to be needed...
|
177
169
|
end
|
178
|
-
|
170
|
+
text
|
179
171
|
end
|
180
172
|
|
181
173
|
# @param [String, File] filename The full filename, or path
|
data/lib/workbook/cell.rb
CHANGED
data/lib/workbook/column.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
module Workbook
|
3
4
|
|
4
5
|
# Column helps us to store general properties of a column, and lets us easily perform operations on values within a column
|
@@ -17,10 +18,12 @@ module Workbook
|
|
17
18
|
table[1..500].each do |row|
|
18
19
|
if row[ind] and row[ind].cell_type
|
19
20
|
cel_column_type = row[ind].cell_type
|
20
|
-
if !defined?(@column_type) or @column_type.nil?
|
21
|
+
if !defined?(@column_type) or @column_type.nil?
|
21
22
|
@column_type = cel_column_type
|
23
|
+
elsif cel_column_type == @column_type or cel_column_type == :nil
|
22
24
|
else
|
23
25
|
@column_type = :string
|
26
|
+
break
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
data/lib/workbook/format.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
require 'workbook/modules/raw_objects_storage'
|
3
4
|
|
4
5
|
module Workbook
|
@@ -34,8 +35,12 @@ module Workbook
|
|
34
35
|
|
35
36
|
# Does the current format feature a background *color*? (not black or white or transparant).
|
36
37
|
def has_background_color? color=:any
|
37
|
-
|
38
|
-
|
38
|
+
bg_color = flattened[:background_color] ? flattened[:background_color].to_s.downcase : nil
|
39
|
+
|
40
|
+
if color != :any and bg_color
|
41
|
+
return bg_color == color.to_s.downcase
|
42
|
+
elsif bg_color
|
43
|
+
return !(flattened[:background_color].downcase=='#ffffff' or flattened[:background_color]=='#000000')
|
39
44
|
else
|
40
45
|
return false
|
41
46
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
require 'workbook/modules/type_parser'
|
3
4
|
require 'workbook/nil_value'
|
4
5
|
require 'date'
|
@@ -8,19 +9,59 @@ module Workbook
|
|
8
9
|
module Cell
|
9
10
|
include Workbook::Modules::TypeParser
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
CHARACTER_REPACEMENTS = {
|
13
|
+
[/[\(\)\.\?\,\!\=\$\:]/,] => '',
|
14
|
+
[/\&/] => 'amp',
|
15
|
+
[/\+/] => '_plus_',
|
16
|
+
[/\s/,'/_','/',"\\"] => '_',
|
17
|
+
['–_','-_','+_','-'] => '',
|
18
|
+
['__']=>'_',
|
19
|
+
['>']=>'gt',
|
20
|
+
['<']=>'lt',
|
21
|
+
['á','à','â','ä','ã','å'] => 'a',
|
22
|
+
['Ã','Ä','Â','À','�?','Å'] => 'A',
|
23
|
+
['é','è','ê','ë'] => 'e',
|
24
|
+
['Ë','É','È','Ê'] => 'E',
|
25
|
+
['í','ì','î','ï'] => 'i',
|
26
|
+
['�?','Î','Ì','�?'] => 'I',
|
27
|
+
['ó','ò','ô','ö','õ'] => 'o',
|
28
|
+
['Õ','Ö','Ô','Ò','Ó'] => 'O',
|
29
|
+
['ú','ù','û','ü'] => 'u',
|
30
|
+
['Ú','Û','Ù','Ü'] => 'U',
|
31
|
+
['ç'] => 'c',
|
32
|
+
['Ç'] => 'C',
|
33
|
+
['š', 'ś'] => 's',
|
34
|
+
['Š', 'Ś'] => 'S',
|
35
|
+
['ž','ź'] => 'z',
|
36
|
+
['Ž','Ź'] => 'Z',
|
37
|
+
['ñ'] => 'n',
|
38
|
+
['Ñ'] => 'N',
|
39
|
+
['#'] => 'hash',
|
40
|
+
['*'] => 'asterisk'
|
41
|
+
}
|
42
|
+
CLASS_CELLTYPE_MAPPING = {
|
43
|
+
'Numeric' => :integer,
|
44
|
+
'Integer' => :integer,
|
45
|
+
'Fixnum' => :integer,
|
46
|
+
'Float' => :float,
|
47
|
+
'String' => :string,
|
48
|
+
'Symbol' => :string,
|
49
|
+
'Time' => :time,
|
50
|
+
'Date' => :date,
|
51
|
+
'DateTime' => :datetime,
|
52
|
+
'TrueClass' => :boolean,
|
53
|
+
'FalseClass' => :boolean,
|
54
|
+
'NilClass' => :nil,
|
55
|
+
'Workbook::NilValue' => :nil
|
56
|
+
}
|
13
57
|
# Note that these types are sorted by 'importance'
|
14
|
-
VALID_TYPES = [Numeric,String,Time,Date,TrueClass,FalseClass,NilClass,Workbook::NilValue,Symbol]
|
15
58
|
|
16
59
|
# Evaluates a value for class-validity
|
17
60
|
#
|
18
61
|
# @param [Numeric,String,Time,Date,TrueClass,FalseClass,NilClass,Object] value the value to evaluate
|
19
62
|
# @return [Boolean] returns true when the value is a valid cell value
|
20
63
|
def valid_value? value
|
21
|
-
|
22
|
-
VALID_TYPES.each {|t| return true if value.is_a? t}
|
23
|
-
valid_type
|
64
|
+
!CLASS_CELLTYPE_MAPPING[value.class.to_s].nil?
|
24
65
|
end
|
25
66
|
|
26
67
|
def formula
|
@@ -64,22 +105,9 @@ module Workbook
|
|
64
105
|
#
|
65
106
|
# @return [Symbol] the type of cell, compatible with Workbook::Column'types
|
66
107
|
def cell_type
|
67
|
-
|
68
|
-
when "String" then :string
|
69
|
-
when "FalseClass" then :boolean
|
70
|
-
when "TrueClass" then :boolean
|
71
|
-
when 'Time' then :time
|
72
|
-
when "Date" then :date
|
73
|
-
when "DateTime" then :datetime
|
74
|
-
when "Float" then :float
|
75
|
-
when "Integer" then :integer
|
76
|
-
when "Numeric" then :integer
|
77
|
-
when "Fixnum" then :integer
|
78
|
-
when "Symbol" then :string
|
79
|
-
end
|
108
|
+
CLASS_CELLTYPE_MAPPING[value.class.to_s]
|
80
109
|
end
|
81
110
|
|
82
|
-
|
83
111
|
# Returns the current value
|
84
112
|
#
|
85
113
|
# @return [Numeric,String,Time,Date,TrueClass,FalseClass,NilClass] a valid value
|
@@ -142,7 +170,15 @@ module Workbook
|
|
142
170
|
# returns true when the value of the cell is nil.
|
143
171
|
# @return [Boolean]
|
144
172
|
def nil?
|
145
|
-
|
173
|
+
value.nil?
|
174
|
+
end
|
175
|
+
|
176
|
+
def nil_or_empty?
|
177
|
+
value.nil? || value.to_s == ""
|
178
|
+
end
|
179
|
+
|
180
|
+
def value_to_s
|
181
|
+
value.to_s.downcase
|
146
182
|
end
|
147
183
|
|
148
184
|
# returns a symbol representation of the cell's value
|
@@ -153,59 +189,25 @@ module Workbook
|
|
153
189
|
def to_sym
|
154
190
|
return @to_sym if @to_sym
|
155
191
|
v = nil
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
ends_with_exclamationmark = (v[-1] == '!')
|
162
|
-
ends_with_questionmark = (v[-1] == '?')
|
163
|
-
|
164
|
-
replacements = {
|
165
|
-
[/[\(\)\.\?\,\!\=\$\:]/,] => '',
|
166
|
-
[/\&/] => 'amp',
|
167
|
-
[/\+/] => '_plus_',
|
168
|
-
[/\s/,'/_','/',"\\"] => '_',
|
169
|
-
['–_','-_','+_','-'] => '',
|
170
|
-
['__']=>'_',
|
171
|
-
['>']=>'gt',
|
172
|
-
['<']=>'lt',
|
173
|
-
['á','à','â','ä','ã','å'] => 'a',
|
174
|
-
['Ã','Ä','Â','À','�?','Å'] => 'A',
|
175
|
-
['é','è','ê','ë'] => 'e',
|
176
|
-
['Ë','É','È','Ê'] => 'E',
|
177
|
-
['í','ì','î','ï'] => 'i',
|
178
|
-
['�?','Î','Ì','�?'] => 'I',
|
179
|
-
['ó','ò','ô','ö','õ'] => 'o',
|
180
|
-
['Õ','Ö','Ô','Ò','Ó'] => 'O',
|
181
|
-
['ú','ù','û','ü'] => 'u',
|
182
|
-
['Ú','Û','Ù','Ü'] => 'U',
|
183
|
-
['ç'] => 'c',
|
184
|
-
['Ç'] => 'C',
|
185
|
-
['š', 'ś'] => 's',
|
186
|
-
['Š', 'Ś'] => 'S',
|
187
|
-
['ž','ź'] => 'z',
|
188
|
-
['Ž','Ź'] => 'Z',
|
189
|
-
['ñ'] => 'n',
|
190
|
-
['Ñ'] => 'N',
|
191
|
-
['#'] => 'hash',
|
192
|
-
['*'] => 'asterisk'
|
193
|
-
}
|
194
|
-
replacements.each do |ac,rep|
|
195
|
-
ac.each do |s|
|
196
|
-
v = v.gsub(s, rep)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
if RUBY_VERSION < '1.9'
|
200
|
-
v = v.gsub(/[^\x00-\x7F]/n,'')
|
192
|
+
unless nil_or_empty?
|
193
|
+
if cell_type == :integer
|
194
|
+
v = "num#{value}".to_sym
|
195
|
+
elsif cell_type == :float
|
196
|
+
v = "num#{value}".sub(".","_").to_sym
|
201
197
|
else
|
202
|
-
|
203
|
-
|
204
|
-
|
198
|
+
v = value_to_s
|
199
|
+
|
200
|
+
ends_with_exclamationmark = (v[-1] == '!')
|
201
|
+
ends_with_questionmark = (v[-1] == '?')
|
202
|
+
|
203
|
+
v = _replace_possibly_problematic_characters_from_string(v)
|
204
|
+
|
205
|
+
v = v.encode(Encoding.find('ASCII'), {:invalid => :replace, :undef => :replace, :replace => ''})
|
206
|
+
|
207
|
+
v = "#{v}!" if ends_with_exclamationmark
|
208
|
+
v = "#{v}?" if ends_with_questionmark
|
209
|
+
v = v.downcase.to_sym
|
205
210
|
end
|
206
|
-
v = "#{v}!" if ends_with_exclamationmark
|
207
|
-
v = "#{v}?" if ends_with_questionmark
|
208
|
-
v = v.downcase.to_sym
|
209
211
|
end
|
210
212
|
@to_sym = v
|
211
213
|
return @to_sym
|
@@ -243,10 +245,7 @@ module Workbook
|
|
243
245
|
#
|
244
246
|
# @param value a potential value for a cell
|
245
247
|
def importance_of_class value
|
246
|
-
|
247
|
-
return i if value.is_a? c
|
248
|
-
end
|
249
|
-
return nil
|
248
|
+
CLASS_CELLTYPE_MAPPING.keys.index value.class.to_s
|
250
249
|
end
|
251
250
|
|
252
251
|
# Returns whether special formatting is present on this cell
|
@@ -302,6 +301,17 @@ module Workbook
|
|
302
301
|
def rowspan
|
303
302
|
@rowspan.to_i if defined?(@rowspan) and @rowspan.to_i > 1
|
304
303
|
end
|
304
|
+
|
305
|
+
private
|
306
|
+
|
307
|
+
def _replace_possibly_problematic_characters_from_string(string)
|
308
|
+
Workbook::Modules::Cell::CHARACTER_REPACEMENTS.each do |ac,rep|
|
309
|
+
ac.each do |s|
|
310
|
+
string = string.gsub(s, rep)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
string
|
314
|
+
end
|
305
315
|
end
|
306
316
|
end
|
307
317
|
end
|
data/lib/workbook/nil_value.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# -*- encoding : utf-8 -*-
|
2
3
|
|
3
4
|
module Workbook
|
@@ -9,12 +10,7 @@ module Workbook
|
|
9
10
|
end
|
10
11
|
|
11
12
|
def csv_lib
|
12
|
-
|
13
|
-
require 'faster_csv'
|
14
|
-
return FasterCSV
|
15
|
-
else
|
16
|
-
return CSV
|
17
|
-
end
|
13
|
+
return CSV
|
18
14
|
end
|
19
15
|
|
20
16
|
def parse_csv csv_raw, options={}
|
@@ -25,16 +21,16 @@ module Workbook
|
|
25
21
|
|
26
22
|
csv=nil
|
27
23
|
begin
|
28
|
-
csv =
|
24
|
+
csv = CSV.parse(csv_raw,options)
|
29
25
|
|
30
26
|
rescue CSV::MalformedCSVError
|
31
|
-
csv_excel =
|
27
|
+
csv_excel = CSV.parse(csv_raw,options.merge({:col_sep=>';'}))
|
32
28
|
csv = csv_excel if csv_excel[0].count > 1
|
33
29
|
|
34
30
|
end
|
35
31
|
|
36
32
|
if csv==nil or csv[0].count == 1
|
37
|
-
csv_excel =
|
33
|
+
csv_excel = CSV.parse(csv_raw,options.merge({:col_sep=>';'}))
|
38
34
|
csv = csv_excel if csv_excel[0].count > 1
|
39
35
|
end
|
40
36
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
module Workbook
|
3
4
|
module Readers
|
4
5
|
module TxtReader
|
@@ -9,7 +10,7 @@ module Workbook
|
|
9
10
|
|
10
11
|
def parse_txt csv_raw, options={}
|
11
12
|
csv = []
|
12
|
-
csv_raw.split("\n").each {|l| csv <<
|
13
|
+
csv_raw.split("\n").each {|l| csv << CSV.parse_line(l,{:col_sep=>"\t"});nil}
|
13
14
|
self[0]=Workbook::Sheet.new(csv,self,{:parse_cells_on_batch_creation=>true, :cell_parse_options=>{:detect_date=>true}}) unless sheet.has_contents?
|
14
15
|
end
|
15
16
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
require 'spreadsheet'
|
3
4
|
require 'workbook/readers/xls_shared'
|
4
5
|
|
@@ -24,67 +25,79 @@ module Workbook
|
|
24
25
|
|
25
26
|
end
|
26
27
|
|
28
|
+
def parse_xls_cell xls_cell, xls_row, ci
|
29
|
+
rv = Workbook::Cell.new nil
|
30
|
+
begin
|
31
|
+
rv = Workbook::Cell.new xls_cell
|
32
|
+
rv.parse!
|
33
|
+
rescue ArgumentError => e
|
34
|
+
if e.message.match('not a Spreadsheet::Formula')
|
35
|
+
v = xls_cell.value
|
36
|
+
if v.class == Float and xls_row.format(ci).date?
|
37
|
+
xls_row[ci] = v
|
38
|
+
v = xls_row.datetime(ci)
|
39
|
+
end
|
40
|
+
if v.is_a? Spreadsheet::Excel::Error
|
41
|
+
v = "----!"
|
42
|
+
end
|
43
|
+
rv = Workbook::Cell.new v
|
44
|
+
elsif e.message.match('not a Spreadsheet::Link')
|
45
|
+
rv = Workbook::Cell.new xls_cell.to_s
|
46
|
+
elsif e.message.match('not a Spreadsheet::Link')
|
47
|
+
rv = Workbook::Cell.new xls_cell.to_s
|
48
|
+
elsif e.message.match('not a Spreadsheet::Excel::Error')
|
49
|
+
rv = "._."
|
50
|
+
else
|
51
|
+
rv = "._." # raise e (we're going to be silent for now)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rv
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse_xls_format xls_row, ci, ri, col_widths
|
58
|
+
xls_format = xls_row.format(ci)
|
59
|
+
col_width = nil
|
60
|
+
|
61
|
+
if ri == 0
|
62
|
+
col_width = col_widths[ci]
|
63
|
+
end
|
64
|
+
|
65
|
+
f = template.create_or_find_format_by "object_id_#{xls_format.object_id}",col_width
|
66
|
+
f[:width]= col_width
|
67
|
+
f[:rotation] = xls_format.rotation if xls_format.rotation
|
68
|
+
f[:background_color] = xls_color_to_html_hex(xls_format.pattern_fg_color)
|
69
|
+
f[:number_format] = ms_formatting_to_strftime(xls_format.number_format)
|
70
|
+
f[:text_direction] = xls_format.text_direction
|
71
|
+
f[:font_family] = "#{xls_format.font.name}, #{xls_format.font.family}"
|
72
|
+
f[:font_weight] = xls_format.font.weight
|
73
|
+
f[:color] = xls_color_to_html_hex(xls_format.font.color)
|
74
|
+
|
75
|
+
f.add_raw xls_format
|
76
|
+
f
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_xls_row ri, s, xls_sheet
|
80
|
+
xls_row = xls_sheet.row(ri)
|
81
|
+
r = s.table.create_or_open_row_at(ri)
|
82
|
+
col_widths = xls_sheet.columns.collect{|c| c.width if c}
|
83
|
+
xls_row.each_with_index do |xls_cell,ci|
|
84
|
+
r[ci] = parse_xls_cell xls_cell, xls_row, ci
|
85
|
+
r[ci].format = parse_xls_format xls_row, ci, ri, col_widths
|
86
|
+
end
|
87
|
+
end
|
27
88
|
|
28
89
|
def parse_xls xls_spreadsheet=template.raws[Spreadsheet::Excel::Workbook], options={}
|
29
90
|
options = {:additional_type_parsing=>true}.merge options
|
30
91
|
number_of_worksheets = xls_spreadsheet.worksheets.count
|
31
|
-
|
92
|
+
number_of_worksheets.times do |si|
|
32
93
|
xls_sheet = xls_spreadsheet.worksheets[si]
|
33
94
|
if [:visible, :hidden, nil].include? xls_sheet.visibility # don't read :strong_hidden sheets, symmetrical to the writer
|
34
95
|
begin
|
35
96
|
number_of_rows = xls_sheet.count
|
36
97
|
s = create_or_open_sheet_at(si)
|
37
98
|
s.name = xls_sheet.name
|
38
|
-
|
39
|
-
|
40
|
-
r = s.table.create_or_open_row_at(ri)
|
41
|
-
col_widths = xls_sheet.columns.collect{|c| c.width if c}
|
42
|
-
xls_row.each_with_index do |xls_cell,ci|
|
43
|
-
|
44
|
-
begin
|
45
|
-
r[ci] = Workbook::Cell.new xls_cell
|
46
|
-
r[ci].parse!
|
47
|
-
rescue ArgumentError => e
|
48
|
-
if e.message.match('not a Spreadsheet::Formula')
|
49
|
-
v = xls_cell.value
|
50
|
-
if v.class == Float and xls_row.format(ci).date?
|
51
|
-
xls_row[ci] = v
|
52
|
-
v = xls_row.datetime(ci)
|
53
|
-
end
|
54
|
-
if v.is_a? Spreadsheet::Excel::Error
|
55
|
-
v = "----!"
|
56
|
-
end
|
57
|
-
r[ci] = Workbook::Cell.new v
|
58
|
-
elsif e.message.match('not a Spreadsheet::Link')
|
59
|
-
r[ci] = Workbook::Cell.new xls_cell.to_s
|
60
|
-
elsif e.message.match('not a Spreadsheet::Link')
|
61
|
-
r[ci] = Workbook::Cell.new xls_cell.to_s
|
62
|
-
elsif e.message.match('not a Spreadsheet::Excel::Error')
|
63
|
-
r[ci] = "._."
|
64
|
-
else
|
65
|
-
r[ci] = "._." # raise e (we're going to be silent for now)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
xls_format = xls_row.format(ci)
|
69
|
-
col_width = nil
|
70
|
-
|
71
|
-
if ri == 0
|
72
|
-
col_width = col_widths[ci]
|
73
|
-
end
|
74
|
-
f = template.create_or_find_format_by "object_id_#{xls_format.object_id}",col_width
|
75
|
-
f[:width]= col_width
|
76
|
-
f[:rotation] = xls_format.rotation if xls_format.rotation
|
77
|
-
f[:background_color] = xls_color_to_html_hex(xls_format.pattern_fg_color)
|
78
|
-
f[:number_format] = ms_formatting_to_strftime(xls_format.number_format)
|
79
|
-
f[:text_direction] = xls_format.text_direction
|
80
|
-
f[:font_family] = "#{xls_format.font.name}, #{xls_format.font.family}"
|
81
|
-
f[:font_weight] = xls_format.font.weight
|
82
|
-
f[:color] = xls_color_to_html_hex(xls_format.font.color)
|
83
|
-
|
84
|
-
f.add_raw xls_format
|
85
|
-
|
86
|
-
r[ci].format = f
|
87
|
-
end
|
99
|
+
number_of_rows.times do |ri|
|
100
|
+
parse_xls_row ri, s, xls_sheet
|
88
101
|
end
|
89
102
|
rescue TypeError
|
90
103
|
puts "WARNING: Failed at worksheet (#{si})... ignored"
|
data/lib/workbook/row.rb
CHANGED
data/lib/workbook/sheet.rb
CHANGED
data/lib/workbook/table.rb
CHANGED
data/lib/workbook/template.rb
CHANGED
data/lib/workbook/types/date.rb
CHANGED
data/lib/workbook/types/false.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
# frozen_string_literal: true
|
data/lib/workbook/types/nil.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
# frozen_string_literal: true
|
data/lib/workbook/types/time.rb
CHANGED
data/lib/workbook/types/true.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
# frozen_string_literal: true
|
data/lib/workbook/version.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
require 'json'
|
3
4
|
|
4
5
|
module Workbook
|
@@ -6,21 +7,21 @@ module Workbook
|
|
6
7
|
module JsonTableWriter
|
7
8
|
# Output the current workbook to JSON format
|
8
9
|
#
|
9
|
-
# @param [Hash] options
|
10
|
+
# @param [Hash] options
|
10
11
|
# @return [String] json string
|
11
12
|
def to_json options={}
|
12
13
|
JSON.generate(to_array_of_hashes_with_values(options))
|
13
14
|
end
|
14
|
-
|
15
|
+
|
15
16
|
# Output the current workbook to an array_of_hashes_with_values format
|
16
17
|
#
|
17
|
-
# @param [Hash] options
|
18
|
+
# @param [Hash] options
|
18
19
|
# @return [Array<Hash>] array with hashes (comma separated values in a string)
|
19
20
|
def to_array_of_hashes_with_values options={}
|
20
21
|
array_of_hashes = self.collect{|a| a.to_hash_with_values unless a.header?}.compact
|
21
22
|
return array_of_hashes
|
22
23
|
end
|
23
|
-
|
24
|
+
|
24
25
|
# Write the current workbook to JSON format
|
25
26
|
#
|
26
27
|
# @param [String] filename
|
data/test/test_modules_cell.rb
CHANGED
@@ -33,6 +33,12 @@ class TestModulesCell < Minitest::Test
|
|
33
33
|
assert_equal(Float,w.value.class)
|
34
34
|
end
|
35
35
|
|
36
|
+
def test_importance_of_class
|
37
|
+
a = Workbook::Cell.new
|
38
|
+
assert_equal(4, a.importance_of_class("a"))
|
39
|
+
assert_equal(5, a.importance_of_class(:a))
|
40
|
+
end
|
41
|
+
|
36
42
|
def test_comp
|
37
43
|
a = Workbook::Cell.new 1
|
38
44
|
b = Workbook::Cell.new 2
|
@@ -82,7 +88,7 @@ class TestModulesCell < Minitest::Test
|
|
82
88
|
"A-B!" => :ab!,
|
83
89
|
"éåšžÌ?" => :easzi?,
|
84
90
|
1 => :num1,
|
85
|
-
1.0 => :
|
91
|
+
1.0 => :num1_0
|
86
92
|
}
|
87
93
|
examples.each do |k,v|
|
88
94
|
assert_equal(v, Workbook::Cell.new(k).to_sym)
|
data/workbook.gemspec
CHANGED
@@ -18,16 +18,12 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_development_dependency("rake", '~> 10.0')
|
19
19
|
s.add_development_dependency('minitest', '~> 5.4')
|
20
20
|
s.add_dependency('spreadsheet', '~> 1.1')
|
21
|
-
s.add_dependency('fastercsv') if RUBY_VERSION < "1.9"
|
22
21
|
s.add_dependency("rchardet", "~> 1.3")
|
23
22
|
s.add_dependency("json", '~> 2.1')
|
24
23
|
# s.add_dependency("rubyzip", '~> 1.2', '>= 1.2.1')
|
25
24
|
s.add_dependency('axlsx', '~> 3.0.0.pre')
|
26
|
-
|
27
|
-
|
28
|
-
else
|
29
|
-
s.add_dependency('nokogiri', '~> 1.6')
|
30
|
-
end
|
25
|
+
s.add_dependency('nokogiri', '~> 1.8')
|
26
|
+
|
31
27
|
s.platform = Gem::Platform::RUBY
|
32
28
|
s.files = `git ls-files`.split($/)
|
33
29
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: workbook
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maarten Brouwers
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '1.
|
117
|
+
version: '1.8'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '1.
|
124
|
+
version: '1.8'
|
125
125
|
description: Workbook contains workbooks, as in a table, contains rows, contains cells,
|
126
126
|
reads/writes excel, ods and csv and tab separated files, and offers basic diffing
|
127
127
|
and sorting capabilities.
|