workbook 0.1.2 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
data/lib/workbook/book.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'workbook/writers/xls_writer'
|
2
2
|
require 'workbook/readers/xls_reader'
|
3
|
+
require 'workbook/readers/xlsx_reader'
|
3
4
|
require 'workbook/readers/csv_reader'
|
4
5
|
require 'workbook/readers/txt_reader'
|
5
6
|
require 'rchardet'
|
@@ -8,6 +9,7 @@ module Workbook
|
|
8
9
|
class Book < Array
|
9
10
|
include Workbook::Writers::XlsWriter
|
10
11
|
include Workbook::Readers::XlsReader
|
12
|
+
include Workbook::Readers::XlsxReader
|
11
13
|
include Workbook::Readers::CsvReader
|
12
14
|
include Workbook::Readers::TxtReader
|
13
15
|
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'rubyXL'
|
2
|
+
|
3
|
+
#monkeypatching rubyXL, pull request submitted: https://github.com/gilt/rubyXL/pull/47
|
4
|
+
module RubyXL
|
5
|
+
class Workbook
|
6
|
+
def is_date_format?(num_fmt)
|
7
|
+
num_fmt.downcase!
|
8
|
+
skip_chars = ['$', '-', '+', '/', '(', ')', ':', ' ']
|
9
|
+
num_chars = ['0', '#', '?']
|
10
|
+
non_date_formats = ['0.00e+00', '##0.0e+0', 'general', '@']
|
11
|
+
date_chars = ['y','m','d','h','s']
|
12
|
+
|
13
|
+
state = 0
|
14
|
+
s = ''
|
15
|
+
num_fmt.split(//).each do |c|
|
16
|
+
if state == 0
|
17
|
+
if c == '"'
|
18
|
+
state = 1
|
19
|
+
elsif ['\\', '_', '*'].include?(c)
|
20
|
+
state = 2
|
21
|
+
elsif skip_chars.include?(c)
|
22
|
+
next
|
23
|
+
else
|
24
|
+
s << c
|
25
|
+
end
|
26
|
+
elsif state == 1
|
27
|
+
if c == '"'
|
28
|
+
state = 0
|
29
|
+
end
|
30
|
+
elsif state == 2
|
31
|
+
state = 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
s.gsub!(/\[[^\]]*\]/, '')
|
35
|
+
if non_date_formats.include?(s)
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
separator = ';'
|
39
|
+
got_sep = 0
|
40
|
+
date_count = 0
|
41
|
+
num_count = 0
|
42
|
+
s.split(//).each do |c|
|
43
|
+
if date_chars.include?(c)
|
44
|
+
date_count += 1
|
45
|
+
elsif num_chars.include?(c)
|
46
|
+
num_count += 1
|
47
|
+
elsif c == separator
|
48
|
+
got_sep = 1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
if date_count > 0 && num_count == 0
|
52
|
+
return true
|
53
|
+
elsif num_count > 0 && date_count == 0
|
54
|
+
return false
|
55
|
+
elsif date_count
|
56
|
+
# ambiguous result
|
57
|
+
elsif got_sep == 0
|
58
|
+
# constant result
|
59
|
+
end
|
60
|
+
return date_count > num_count
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
# end monkey patch submitted
|
65
|
+
|
66
|
+
# other monkey patch
|
67
|
+
module RubyXL
|
68
|
+
class Cell
|
69
|
+
def number_format
|
70
|
+
if !@value.is_a?(String)
|
71
|
+
if @workbook.num_fmts_by_id
|
72
|
+
num_fmt_id = xf_id()[:numFmtId]
|
73
|
+
tmp_num_fmt = @workbook.num_fmts_by_id[num_fmt_id]
|
74
|
+
return (tmp_num_fmt &&tmp_num_fmt[:attributes] && tmp_num_fmt[:attributes][:formatCode]) ? tmp_num_fmt[:attributes][:formatCode] : nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
def fill_color
|
79
|
+
if !@value.is_a?(String)
|
80
|
+
if @workbook.num_fmts_by_id
|
81
|
+
num_fmt_id = xf_id()[:numFmtId]
|
82
|
+
tmp_num_fmt = @workbook.num_fmts_by_id[num_fmt_id]
|
83
|
+
return (tmp_num_fmt &&tmp_num_fmt[:attributes] && tmp_num_fmt[:attributes][:formatCode]) ? tmp_num_fmt[:attributes][:formatCode] : nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
# end of monkey patch
|
91
|
+
|
92
|
+
module Workbook
|
93
|
+
module Readers
|
94
|
+
module XlsxReader
|
95
|
+
def load_xlsx file_obj
|
96
|
+
file_obj = file_obj.path if file_obj.is_a? File
|
97
|
+
sp = RubyXL::Parser.parse(file_obj)
|
98
|
+
template.add_raw sp
|
99
|
+
parse_xlsx sp
|
100
|
+
end
|
101
|
+
|
102
|
+
def parse_xlsx xlsx_spreadsheet=template.raws[RubyXL::Workbook], options={}
|
103
|
+
options = {:additional_type_parsing=>false}.merge options
|
104
|
+
#number_of_worksheets = xlsx_spreadsheet.worksheets.count
|
105
|
+
xlsx_spreadsheet.worksheets.each_with_index do |worksheet, si|
|
106
|
+
s = create_or_open_sheet_at(si)
|
107
|
+
col_widths = xlsx_spreadsheet.worksheets.first.cols.collect{|a| a[:attributes][:width].to_f if a[:attributes]}
|
108
|
+
worksheet.each_with_index do |row, ri|
|
109
|
+
r = s.table.create_or_open_row_at(ri)
|
110
|
+
|
111
|
+
row.each_with_index do |cell,ci|
|
112
|
+
|
113
|
+
r[ci] = Workbook::Cell.new cell.value
|
114
|
+
r[ci].parse!
|
115
|
+
|
116
|
+
xls_format = cell.style_index
|
117
|
+
col_width = nil
|
118
|
+
|
119
|
+
if ri == 0
|
120
|
+
col_width = col_widths[ci]
|
121
|
+
end
|
122
|
+
f = template.create_or_find_format_by "style_index_#{cell.style_index}", col_width
|
123
|
+
f[:width]= col_width
|
124
|
+
f[:background_color] = "##{cell.fill_color}"
|
125
|
+
f[:number_format] = ms_formatting_to_strftime(cell.number_format)
|
126
|
+
f[:font_family] = cell.font_name
|
127
|
+
f[:color] = "##{cell.font_color}"
|
128
|
+
|
129
|
+
f.add_raw xls_format
|
130
|
+
|
131
|
+
r[ci].format = f
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
private
|
137
|
+
def ms_formatting_to_strftime ms_nr_format
|
138
|
+
if ms_nr_format
|
139
|
+
ms_nr_format = ms_nr_format.downcase
|
140
|
+
return nil if ms_nr_format == 'general'
|
141
|
+
ms_nr_format.gsub('yyyy','%Y').gsub('dddd','%A').gsub('mmmm','%B').gsub('ddd','%a').gsub('mmm','%b').gsub('yy','%y').gsub('dd','%d').gsub('mm','%m').gsub('y','%y').gsub('%%y','%y').gsub('d','%e').gsub('%%e','%d').gsub('m','%m').gsub('%%m','%m').gsub(';@','').gsub('\\','')
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/readme.markdown
CHANGED
@@ -14,7 +14,7 @@ Subsequently a table consists of:
|
|
14
14
|
|
15
15
|
Book, Sheet, Table and Row inherit from the base Array class, and hence walks and quacks as such. The row is extended with hashlike lookups (`row[:id]`) and writers (`row[:id]=`). Values are converted to ruby native types, and optional parsers can be added to improve recognition.
|
16
16
|
|
17
|
-
In addition to offering you this plain structure it allows for importing
|
17
|
+
In addition to offering you this plain structure it allows for importing .xls, .csv, .xlsx, .txt files (more to come), writing .xls, and .csv (more to come) and includes several utilities to easily create an overview of the differences between two tables and output basic cell-styling properties as css.
|
18
18
|
|
19
19
|
## The Basics
|
20
20
|
|
Binary file
|
@@ -3,7 +3,7 @@ module Modules
|
|
3
3
|
class TestTypeParser < Test::Unit::TestCase
|
4
4
|
def examples
|
5
5
|
{"2312"=>2312,
|
6
|
-
|
6
|
+
# "12-12-2012"=>Date.new(2012,12,12),
|
7
7
|
"12-12-2012 12:24"=>DateTime.new(2012,12,12,12,24),
|
8
8
|
"2012-12-12 12:24"=>DateTime.new(2012,12,12,12,24),
|
9
9
|
"2011-05-19T15_37_49 - 52349.xml"=>"2011-05-19T15_37_49 - 52349.xml",
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
module Readers
|
3
|
+
class TestXlsxWriter < Test::Unit::TestCase
|
4
|
+
def test_open
|
5
|
+
w = Workbook::Book.new
|
6
|
+
w.open 'test/artifacts/book_with_tabs_and_colours.xlsx'
|
7
|
+
assert_equal([:a, :b, :c, :d, :e],w.sheet.table.header.to_symbols)
|
8
|
+
assert_equal(90588,w.sheet.table[2][:b].value)
|
9
|
+
assert_equal(DateTime.new(2011,11,15),w.sheet.table[3][:d].value)
|
10
|
+
# assert_equal("#CCFFCC",w.sheet.table[3][:c].format[:background_color]) #colour compatibility turned off for now...
|
11
|
+
assert_equal(8,w.sheet.table.first[:b].format[:width].round)
|
12
|
+
assert_equal(4,w.sheet.table.first[:a].format[:width].round)
|
13
|
+
assert_equal(25,w.sheet.table.first[:c].format[:width].round)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/workbook.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "workbook"
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'workbook'
|
7
7
|
s.rubyforge_project = 'workbook'
|
8
|
-
s.version = '0.1.
|
8
|
+
s.version = '0.1.5'
|
9
9
|
s.date = '2012-11-12'
|
10
10
|
s.summary = "Workbook is a datastructure to contain books of tables (an anlogy used in e.g. Excel)"
|
11
11
|
s.description = "Workbook contains workbooks, as in a table, contains rows, contains cells, reads/writes excels and csv's and tab separated, and offers basic diffing and sorting capabilities."
|
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.add_dependency('spreadsheet', '>= 0.6.8')
|
14
14
|
s.add_dependency('fastercsv')
|
15
15
|
s.add_dependency("rchardet", "~> 1.3")
|
16
|
+
s.add_dependency('rubyXL')
|
16
17
|
s.platform = Gem::Platform::RUBY
|
17
18
|
s.files = `git ls-files`.split("\n")
|
18
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 5
|
9
|
+
version: 0.1.5
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Maarten Brouwers
|
@@ -56,6 +56,18 @@ dependencies:
|
|
56
56
|
version: "1.3"
|
57
57
|
type: :runtime
|
58
58
|
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rubyXL
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
type: :runtime
|
70
|
+
version_requirements: *id004
|
59
71
|
description: Workbook contains workbooks, as in a table, contains rows, contains cells, reads/writes excels and csv's and tab separated, and offers basic diffing and sorting capabilities.
|
60
72
|
email:
|
61
73
|
- gem@murb.nl
|
@@ -80,6 +92,7 @@ files:
|
|
80
92
|
- lib/workbook/readers/csv_reader.rb
|
81
93
|
- lib/workbook/readers/txt_reader.rb
|
82
94
|
- lib/workbook/readers/xls_reader.rb
|
95
|
+
- lib/workbook/readers/xlsx_reader.rb
|
83
96
|
- lib/workbook/row.rb
|
84
97
|
- lib/workbook/sheet.rb
|
85
98
|
- lib/workbook/table.rb
|
@@ -88,6 +101,7 @@ files:
|
|
88
101
|
- lib/workbook/writers/xls_writer.rb
|
89
102
|
- readme.markdown
|
90
103
|
- test/artifacts/book_with_tabs_and_colours.xls
|
104
|
+
- test/artifacts/book_with_tabs_and_colours.xlsx
|
91
105
|
- test/artifacts/complex_types.xls
|
92
106
|
- test/artifacts/excel_different_types.csv
|
93
107
|
- test/artifacts/excel_different_types.txt
|
@@ -109,6 +123,7 @@ files:
|
|
109
123
|
- test/test_readers_csv_reader.rb
|
110
124
|
- test/test_readers_txt_reader.rb
|
111
125
|
- test/test_readers_xls_reader.rb
|
126
|
+
- test/test_readers_xlsx_reader.rb
|
112
127
|
- test/test_row.rb
|
113
128
|
- test/test_sheet.rb
|
114
129
|
- test/test_table.rb
|
@@ -147,6 +162,7 @@ specification_version: 3
|
|
147
162
|
summary: Workbook is a datastructure to contain books of tables (an anlogy used in e.g. Excel)
|
148
163
|
test_files:
|
149
164
|
- test/artifacts/book_with_tabs_and_colours.xls
|
165
|
+
- test/artifacts/book_with_tabs_and_colours.xlsx
|
150
166
|
- test/artifacts/complex_types.xls
|
151
167
|
- test/artifacts/excel_different_types.csv
|
152
168
|
- test/artifacts/excel_different_types.txt
|
@@ -168,6 +184,7 @@ test_files:
|
|
168
184
|
- test/test_readers_csv_reader.rb
|
169
185
|
- test/test_readers_txt_reader.rb
|
170
186
|
- test/test_readers_xls_reader.rb
|
187
|
+
- test/test_readers_xlsx_reader.rb
|
171
188
|
- test/test_row.rb
|
172
189
|
- test/test_sheet.rb
|
173
190
|
- test/test_table.rb
|