workbook 0.4.6.0 → 0.4.7
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +14 -15
- data/lib/workbook.rb +22 -11
- data/lib/workbook/book.rb +47 -25
- data/lib/workbook/cell.rb +20 -26
- data/lib/workbook/generatetypes.rb +14 -0
- data/lib/workbook/modules/cache.rb +52 -0
- data/lib/workbook/modules/{table_diff_sort.rb → diff_sort.rb} +64 -16
- data/lib/workbook/modules/raw_objects_storage.rb +7 -2
- data/lib/workbook/readers/ods_reader.rb +1 -1
- data/lib/workbook/readers/xls_reader.rb +55 -55
- data/lib/workbook/readers/xls_shared.rb +47 -0
- data/lib/workbook/readers/xlsx_reader.rb +34 -153
- data/lib/workbook/row.rb +47 -4
- data/lib/workbook/sheet.rb +4 -0
- data/lib/workbook/table.rb +36 -16
- data/lib/workbook/types/Date.rb +9 -0
- data/lib/workbook/types/False.rb +0 -0
- data/lib/workbook/types/FalseClass.rb +9 -0
- data/lib/workbook/types/Nil.rb +0 -0
- data/lib/workbook/types/NilClass.rb +9 -0
- data/lib/workbook/types/Numeric.rb +9 -0
- data/lib/workbook/types/String.rb +9 -0
- data/lib/workbook/types/Time.rb +9 -0
- data/lib/workbook/types/True.rb +0 -0
- data/lib/workbook/types/TrueClass.rb +9 -0
- data/lib/workbook/version.rb +1 -1
- data/lib/workbook/writers/html_writer.rb +40 -18
- data/lib/workbook/writers/xls_writer.rb +47 -5
- data/lib/workbook/writers/xlsx_writer.rb +123 -0
- data/test/artifacts/bigtable.xls +0 -0
- data/test/artifacts/bigtable.xlsx +0 -0
- data/test/artifacts/simple_sheet.xlsx +0 -0
- data/test/artifacts/simple_sheet_many_sheets.xls +0 -0
- data/test/test_book.rb +50 -2
- data/test/test_cell.rb +1 -1
- data/test/test_format.rb +8 -0
- data/test/test_modules_cache.rb +68 -0
- data/test/test_modules_table_diff_sort.rb +12 -1
- data/test/test_readers_xls_reader.rb +6 -0
- data/test/test_readers_xlsx_reader.rb +10 -9
- data/test/test_row.rb +65 -8
- data/test/test_sheet.rb +8 -0
- data/test/test_table.rb +48 -0
- data/test/test_writers_html_writer.rb +18 -8
- data/test/test_writers_xls_writer.rb +90 -0
- data/test/test_writers_xlsx_writer.rb +153 -0
- data/workbook.gemspec +9 -7
- metadata +71 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d3acc182ee042e589c65b4ddfc3be95015d96fa
|
4
|
+
data.tar.gz: d23f5bd2cac3dccfb863997fb5e6ea8ced3e70a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b81415ada844fae07c02d146e4d2a9cbd1898ec0e64a8781ef40fc5c4cb8edbbddba6a83fda301f15666fceae5716c38e198f8769adc238cf4a8822e7aea919
|
7
|
+
data.tar.gz: eebcd14f3191d8c26654d16b2e71f31863504b773da470d1ab11a5960c021631e614c2a036795eda7138c1d3b38d6c6314fed7c21705ed0dc5d0a512d373e655
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# Workbook
|
2
|
+
[](https://codeclimate.com/github/murb/workbook) [](https://travis-ci.org/murb/workbook)
|
2
3
|
|
3
4
|
Goal of this gem is to make working with workbooks (spreadsheets) as programmer friendly as possible. Not reinventing a totally new DSL or all kinds of new methodnames, but just borrowing from known concepts such as hashes and arrays (much like (Faster)CSV does)). Workbook is a gem that mimicks a typical spreadsheet, a bundle of sheets, bundled in a *workbook*. A sheet may contain one or more tables (which might the multi table sheets of Apple Numbers or Excel ranges). Basically:
|
4
5
|
|
@@ -89,18 +90,6 @@ Another typical use case is exporting a list of ActiveRecord-objects to xls (it
|
|
89
90
|
# in the endresult
|
90
91
|
b.write("recent_orders.xls") # write it!
|
91
92
|
|
92
|
-
|
93
|
-
<!-- Feature *to implement*:
|
94
|
-
|
95
|
-
Feature *to implement*, get a single column:
|
96
|
-
|
97
|
-
t[:b]
|
98
|
-
# returns [<Workbook::Cel @value=2>,<Workbook::Cel @value=4>,<Workbook::Cel @value=6>]
|
99
|
-
|
100
|
-
On my wishlist: In the future I hope to return the cell value directly, without the intermediate Workbook::Cell class in between.
|
101
|
-
|
102
|
-
-->
|
103
|
-
|
104
93
|
## Utilities
|
105
94
|
|
106
95
|
### Sorting
|
@@ -115,13 +104,15 @@ To some extent, sort_by works, it doesn't, however, adhere to the header setting
|
|
115
104
|
|
116
105
|
t.sort_by {|r| r[:b]}
|
117
106
|
|
118
|
-
### Comparing tables
|
107
|
+
### Comparing tables or entire workbooks
|
119
108
|
|
120
109
|
Simply call on a Workbook::Table
|
121
110
|
|
122
111
|
t1.diff t2
|
123
112
|
|
124
|
-
And a new book with a new
|
113
|
+
And a new book with a new table will be returned containing the differences between the two tables.
|
114
|
+
|
115
|
+
Alternatively you can run the same command on workbooks, which will compare sheet by sheet and return a new Workbook
|
125
116
|
|
126
117
|
## Writing
|
127
118
|
|
@@ -132,12 +123,20 @@ Currently writing is limited to the following formats. Templating support is sti
|
|
132
123
|
t.(write_)to_csv # returns a csv-string (called on tables)
|
133
124
|
b.(write_)to_html # returns a clean html-page with all tables; unformatted, format-names are used in the classes
|
134
125
|
t.(write_)to_json # returns the values of a table in json
|
126
|
+
t.(write_)to_xlsx # returns/writes using RubyXL to XLS (unstable, work in progress)
|
135
127
|
|
136
128
|
In case you want to display a formatted table in HTML, some conversion is offered to convert text/background properties to css-entities. Internally the hash storing style elements tries to map to CSS where possible.
|
137
129
|
|
138
130
|
## Compatibility
|
139
131
|
|
140
|
-
Workbook
|
132
|
+
Workbook is automatically tested for ruby 1.9, 2.0 and 2.1. Most of it works with 1.8.7 and jruby but not all tests give equal results.
|
133
|
+
Check [Travis for Workbook's current build status](https://travis-ci.org/murb/workbook) [](https://travis-ci.org/murb/workbook).
|
134
|
+
|
135
|
+
## Future
|
136
|
+
|
137
|
+
* Column support, e.g. t[:b] could then return Workbook::Column<[<Workbook::Cel @value=2>,<Workbook::Cel @value=4>,<Workbook::Cel @value=6>]>
|
138
|
+
* In the future I hope to return the cell value as inheriting from the original value's class, so you don't have to call #value as often.
|
139
|
+
* xlsx support definitly needs to be improved. Especially template based support.
|
141
140
|
|
142
141
|
## Alternatives
|
143
142
|
|
data/lib/workbook.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
$KCODE="u" if RUBY_VERSION < "1.9"
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
require_relative 'workbook/modules/cache'
|
4
|
+
require_relative 'workbook/book'
|
5
|
+
require_relative 'workbook/sheet'
|
6
|
+
require_relative 'workbook/table'
|
7
|
+
require_relative 'workbook/nil_value'
|
8
|
+
require_relative 'workbook/row'
|
9
|
+
require_relative 'workbook/cell'
|
10
|
+
require_relative 'workbook/format'
|
11
|
+
require_relative 'workbook/template'
|
12
|
+
require_relative 'workbook/version'
|
13
|
+
require_relative 'workbook/column'
|
13
14
|
|
14
15
|
module Workbook
|
15
16
|
class << self
|
16
|
-
|
17
|
+
def caching_enabled?
|
18
|
+
@@caching_enabled ||= true
|
19
|
+
end
|
20
|
+
# Disable caching globally (wherever applicable)
|
21
|
+
def disable_caching!
|
22
|
+
@@caching_enabled = false
|
23
|
+
end
|
24
|
+
# Enable caching globally (wherever applicable)
|
25
|
+
def enable_caching!
|
26
|
+
@@caching_enabled = true
|
27
|
+
end
|
17
28
|
end
|
18
29
|
end
|
data/lib/workbook/book.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require 'workbook/writers/xls_writer'
|
3
|
+
require 'workbook/writers/xlsx_writer'
|
3
4
|
require 'workbook/writers/html_writer'
|
4
5
|
require 'workbook/readers/xls_reader'
|
5
6
|
require 'workbook/readers/xls_shared'
|
@@ -7,28 +8,36 @@ require 'workbook/readers/xlsx_reader'
|
|
7
8
|
require 'workbook/readers/ods_reader'
|
8
9
|
require 'workbook/readers/csv_reader'
|
9
10
|
require 'workbook/readers/txt_reader'
|
11
|
+
require 'workbook/readers/txt_reader'
|
12
|
+
require 'workbook/modules/diff_sort'
|
10
13
|
|
11
14
|
module Workbook
|
12
15
|
# The Book class is the container of sheets. It can be inialized by either the standard initalizer or the open method. The
|
13
16
|
# Book class can also keep a reference to a template class, storing shared formatting options.
|
14
17
|
#
|
18
|
+
SUPPORTED_MIME_TYPES = %w(application/zip text/plain application/x-ariadne-download application/vnd.ms-excel application/excel application/vnd.ms-office text/csv text/tab-separated-values application/x-ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/vnd.oasis.opendocument.spreadsheet application/x-vnd.oasis.opendocument.spreadsheet)
|
19
|
+
|
15
20
|
class Book < Array
|
21
|
+
|
22
|
+
|
16
23
|
include Workbook::Readers::XlsShared
|
17
24
|
include Workbook::Writers::XlsWriter
|
25
|
+
include Workbook::Writers::XlsxWriter
|
18
26
|
include Workbook::Writers::HtmlWriter
|
19
27
|
include Workbook::Readers::XlsReader
|
20
28
|
include Workbook::Readers::OdsReader
|
21
29
|
include Workbook::Readers::XlsxReader
|
22
30
|
include Workbook::Readers::CsvReader
|
23
31
|
include Workbook::Readers::TxtReader
|
32
|
+
include Workbook::Modules::BookDiffSort
|
24
33
|
|
25
34
|
# @param [Workbook::Sheet, Array] sheet create a new workbook based on an existing sheet, or initialize a sheet based on the array
|
26
35
|
# @return [Workbook::Book]
|
27
36
|
def initialize sheet=Workbook::Sheet.new([], self, options={})
|
28
37
|
if sheet.is_a? Workbook::Sheet
|
29
|
-
push sheet
|
38
|
+
self.push sheet
|
30
39
|
else
|
31
|
-
push Workbook::Sheet.new(sheet, self, options)
|
40
|
+
self.push Workbook::Sheet.new(sheet, self, options)
|
32
41
|
end
|
33
42
|
end
|
34
43
|
|
@@ -59,8 +68,19 @@ module Workbook
|
|
59
68
|
# @param [Workbook::Sheet] sheet
|
60
69
|
def push sheet=Workbook::Sheet.new
|
61
70
|
super(sheet)
|
71
|
+
sheet.book=(self)
|
72
|
+
end
|
73
|
+
|
74
|
+
# << (like in array) a sheet to the workbook (parameter is optional, default is a new sheet)
|
75
|
+
#
|
76
|
+
# @param [Workbook::Sheet] sheet
|
77
|
+
def << sheet=Workbook::Sheet.new
|
78
|
+
sheet = Workbook::Sheet.new(sheet) unless sheet.is_a? Workbook::Sheet
|
79
|
+
super(sheet)
|
80
|
+
sheet.book=(self)
|
62
81
|
end
|
63
82
|
|
83
|
+
|
64
84
|
# Sheet returns the first sheet of a workbook, or an empty one.
|
65
85
|
#
|
66
86
|
# @return [Workbook::Sheet] The first sheet, and creates an empty one if one doesn't exists
|
@@ -145,35 +165,13 @@ module Workbook
|
|
145
165
|
return text
|
146
166
|
end
|
147
167
|
|
148
|
-
# @param [String] filename The full filename, or path
|
168
|
+
# @param [String, File] filename The full filename, or path
|
149
169
|
#
|
150
170
|
# @return [String] The file extension
|
151
171
|
def file_extension(filename)
|
152
172
|
File.extname(filename).gsub('.','').downcase if filename
|
153
173
|
end
|
154
174
|
|
155
|
-
# Create an instance from a file, using open.
|
156
|
-
#
|
157
|
-
# @param [String] filename of the document
|
158
|
-
# @param [String] extension of the document (not required). The parser used is based on the extension of the file, this option allows you to override the default.
|
159
|
-
# @return [Workbook::Book] A new instance, based on the filename
|
160
|
-
def self.open filename, extension=nil
|
161
|
-
wb = self.new
|
162
|
-
wb.open filename, extension
|
163
|
-
return wb
|
164
|
-
end
|
165
|
-
|
166
|
-
# Create an instance from the given stream or string, which should be in CSV or TXT format
|
167
|
-
#
|
168
|
-
# @param [StringIO] stringio_or_string StringIO stream or String object, with data in CSV or TXT format
|
169
|
-
# @param [Symbol] filetype (currently only :csv or :txt), indicating the format of the first parameter
|
170
|
-
# @return [Workbook::Book] A new instance
|
171
|
-
def self.read(stringio_or_string, filetype)
|
172
|
-
wb = self.new
|
173
|
-
wb.read(stringio_or_string, filetype)
|
174
|
-
wb
|
175
|
-
end
|
176
|
-
|
177
175
|
# Load the CSV data contained in the given StringIO or String object
|
178
176
|
#
|
179
177
|
# @param [StringIO] stringio_or_string StringIO stream or String object, with data in CSV format
|
@@ -195,5 +193,29 @@ module Workbook
|
|
195
193
|
s
|
196
194
|
end
|
197
195
|
|
196
|
+
class << self
|
197
|
+
# Create an instance from a file, using open.
|
198
|
+
#
|
199
|
+
# @param [String] filename of the document
|
200
|
+
# @param [String] extension of the document (not required). The parser used is based on the extension of the file, this option allows you to override the default.
|
201
|
+
# @return [Workbook::Book] A new instance, based on the filename
|
202
|
+
def open filename, extension=nil
|
203
|
+
wb = self.new
|
204
|
+
wb.open filename, extension
|
205
|
+
return wb
|
206
|
+
end
|
207
|
+
|
208
|
+
# Create an instance from the given stream or string, which should be in CSV or TXT format
|
209
|
+
#
|
210
|
+
# @param [StringIO] stringio_or_string StringIO stream or String object, with data in CSV or TXT format
|
211
|
+
# @param [Symbol] filetype (currently only :csv or :txt), indicating the format of the first parameter
|
212
|
+
# @return [Workbook::Book] A new instance
|
213
|
+
def read(stringio_or_string, filetype)
|
214
|
+
wb = self.new
|
215
|
+
wb.read(stringio_or_string, filetype)
|
216
|
+
wb
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
198
220
|
end
|
199
221
|
end
|
data/lib/workbook/cell.rb
CHANGED
@@ -9,7 +9,7 @@ module Workbook
|
|
9
9
|
attr_accessor :formula
|
10
10
|
|
11
11
|
# Note that these types are sorted by 'importance'
|
12
|
-
VALID_TYPES = [Numeric,String,Time,Date,TrueClass,FalseClass,NilClass,Workbook::NilValue]
|
12
|
+
VALID_TYPES = [Numeric,String,Time,Date,TrueClass,FalseClass,NilClass,Workbook::NilValue,Symbol]
|
13
13
|
|
14
14
|
# Evaluates a value for class-validity
|
15
15
|
#
|
@@ -24,24 +24,20 @@ module Workbook
|
|
24
24
|
# @param [Numeric,String,Time,Date,TrueClass,FalseClass,NilClass] value a valid value
|
25
25
|
# @param [Hash] options a reference to :format (Workbook::Format) can be specified
|
26
26
|
def initialize value=nil, options={}
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@to_sym = nil
|
31
|
-
else
|
32
|
-
raise ArgumentError, "value should be of a primitive type, e.g. a string, or an integer, not a #{value.class} (is_a? [TrueClass,FalseClass,Date,Time,Numeric,String, NilClass])"
|
33
|
-
end
|
27
|
+
self.format = options[:format]
|
28
|
+
self.value = value
|
29
|
+
@to_sym = nil
|
34
30
|
end
|
35
31
|
|
36
32
|
# Change the current value
|
37
33
|
#
|
38
|
-
# @param [Numeric,String,Time,Date,TrueClass,FalseClass,NilClass] value a valid value
|
34
|
+
# @param [Numeric,String,Time,Date,TrueClass,FalseClass,NilClass,Symbol] value a valid value
|
39
35
|
def value= value
|
40
36
|
if valid_value? value
|
41
37
|
@value = value
|
42
38
|
@to_sym = nil
|
43
39
|
else
|
44
|
-
raise ArgumentError, "value should be of a primitive type, e.g. a string, or an integer, not a #{value.class} (is_a? [TrueClass,FalseClass,Date,Time,Numeric,String, NilClass])"
|
40
|
+
raise ArgumentError, "value should be of a primitive type, e.g. a string, or an integer, not a #{value.class} (is_a? [TrueClass,FalseClass,Date,Time,Numeric,String, NilClass, Symbol])"
|
45
41
|
end
|
46
42
|
end
|
47
43
|
|
@@ -97,25 +93,21 @@ module Workbook
|
|
97
93
|
# <Workbook::Cell value="yet another value">.to_sym # returns :yet_another_value
|
98
94
|
def to_sym
|
99
95
|
return @to_sym if @to_sym
|
100
|
-
#mb_chars.normalize(:kd).
|
101
96
|
v = nil
|
102
97
|
if value
|
103
98
|
ends_with_exclamationmark = (value[-1] == '!')
|
104
99
|
ends_with_questionmark = (value[-1] == '?')
|
105
100
|
v = value.to_s.downcase
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
gsub('-','')
|
117
|
-
|
118
|
-
accents = {
|
101
|
+
|
102
|
+
replacements = {
|
103
|
+
[/[\(\)\.\?\,\!\=\$\:]/,] => '',
|
104
|
+
[/\&/] => 'amp',
|
105
|
+
[/\+/] => '_plus_',
|
106
|
+
[/\s/,'/_','/',"\\"] => '_',
|
107
|
+
['–_','-_','+_','-'] => '',
|
108
|
+
['__']=>'_',
|
109
|
+
['>']=>'gt',
|
110
|
+
['<']=>'lt',
|
119
111
|
['á','à','â','ä','ã','å'] => 'a',
|
120
112
|
['Ã','Ä','Â','À','�?','Å'] => 'A',
|
121
113
|
['é','è','ê','ë'] => 'e',
|
@@ -133,9 +125,11 @@ module Workbook
|
|
133
125
|
['ž','ź'] => 'z',
|
134
126
|
['Ž','Ź'] => 'Z',
|
135
127
|
['ñ'] => 'n',
|
136
|
-
['Ñ'] => 'N'
|
128
|
+
['Ñ'] => 'N',
|
129
|
+
['#'] => 'hash',
|
130
|
+
['*'] => 'asterisk'
|
137
131
|
}
|
138
|
-
|
132
|
+
replacements.each do |ac,rep|
|
139
133
|
ac.each do |s|
|
140
134
|
v = v.gsub(s, rep)
|
141
135
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
["Numeric","String","Time","Date","TrueClass","FalseClass","NilClass"].each do |type|
|
2
|
+
f = File.open(File.join(File.dirname(__FILE__),"types","#{type}.rb"),'w+')
|
3
|
+
puts f.inspect
|
4
|
+
doc="require 'workbook/cell'
|
5
|
+
|
6
|
+
module Workbook
|
7
|
+
module Types
|
8
|
+
class #{type} < #{type}
|
9
|
+
include Workbook::Cell
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end"
|
13
|
+
f.write(doc)
|
14
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Workbook
|
3
|
+
module Modules
|
4
|
+
# Adds simple caching
|
5
|
+
module Cache
|
6
|
+
attr_accessor :debug_cache
|
7
|
+
|
8
|
+
# Caching enabled?
|
9
|
+
# @return [Boolean]
|
10
|
+
def caching_enabled?
|
11
|
+
Workbook.caching_enabled?
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return valid cache time, if caching is enabled, otherwise calls #invalidate_cache!
|
15
|
+
# @return [Time] Timestamp after which cache is valid
|
16
|
+
def cache_valid_from
|
17
|
+
if caching_enabled?
|
18
|
+
@cache_valid_from ||= Time.now
|
19
|
+
else
|
20
|
+
invalidate_cache!
|
21
|
+
end
|
22
|
+
@cache_valid_from
|
23
|
+
end
|
24
|
+
|
25
|
+
# Invalidate all caches on this instance, and reset
|
26
|
+
# @return [Time] Timestamp after which cache is valid (=current time, hence everything stored before is invalid)
|
27
|
+
def invalidate_cache!
|
28
|
+
@cache_valid_from = Time.now
|
29
|
+
end
|
30
|
+
|
31
|
+
# Check if currently stored key is available and still valid
|
32
|
+
# @return [Boolean]
|
33
|
+
def valid_cache_key?(key, expires=nil)
|
34
|
+
cache_valid_from
|
35
|
+
rv = (@cache[key] and (@cache[key][:inserted_at] > cache_valid_from) and (expires.nil? or @cache[key][:inserted_at] < expires)) ? true : false
|
36
|
+
rv
|
37
|
+
end
|
38
|
+
def fetch_cache(key, expires=nil)
|
39
|
+
@cache ||= {}
|
40
|
+
if valid_cache_key?(key, expires)
|
41
|
+
return @cache[key][:value]
|
42
|
+
else
|
43
|
+
@cache[key] = {
|
44
|
+
value: yield,
|
45
|
+
inserted_at: Time.now
|
46
|
+
}
|
47
|
+
end
|
48
|
+
return @cache[key][:value]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,11 +1,57 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
module Workbook
|
3
3
|
module Modules
|
4
|
+
# Adds essential diffing and comparing support, as well as diffing entire books
|
5
|
+
module BookDiffSort
|
6
|
+
module ClassMethods
|
7
|
+
# Return template table to write the diff result in; in case non exists a default is generated.
|
8
|
+
#
|
9
|
+
# @return [Workbook::Table] the empty table, linked to a book
|
10
|
+
def new_diff_template
|
11
|
+
diffbook = Workbook::Book.new
|
12
|
+
template = diffbook.template
|
13
|
+
f = template.create_or_find_format_by 'destroyed'
|
14
|
+
f[:background_color]=:red
|
15
|
+
f = template.create_or_find_format_by 'updated'
|
16
|
+
f[:background_color]=:yellow
|
17
|
+
f = template.create_or_find_format_by 'created'
|
18
|
+
f[:background_color]=:lime
|
19
|
+
f = template.create_or_find_format_by 'header'
|
20
|
+
f[:rotation] = 72
|
21
|
+
f[:font_weight] = :bold
|
22
|
+
f[:height] = 80
|
23
|
+
diffbook
|
24
|
+
end
|
25
|
+
end
|
26
|
+
def self.included(base)
|
27
|
+
base.extend(ClassMethods)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Diff an entire workbook against another, sheet by sheet
|
31
|
+
#
|
32
|
+
# @param [Workbook::Book] to_workbook to compare against
|
33
|
+
# @return [Workbook::Book] workbook with compared result
|
34
|
+
def diff to_workbook, options={:sort=>true,:ignore_headers=>false}
|
35
|
+
diff_template = Workbook::Book.new_diff_template
|
36
|
+
self.each_with_index do |from_sheet, sheet_index|
|
37
|
+
to_sheet = to_workbook[sheet_index]
|
38
|
+
if to_sheet
|
39
|
+
from_table = from_sheet.table
|
40
|
+
to_table = to_sheet.table
|
41
|
+
diff_table_template = diff_template.create_or_open_sheet_at(sheet_index).table
|
42
|
+
from_table.diff_template = diff_table_template
|
43
|
+
from_table.diff(to_table, options)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
return diff_template #the template has been filled in the meanwhile, not to use as a template anymore... :)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
4
50
|
# Adds diffing and sorting functions
|
5
51
|
module TableDiffSort
|
6
52
|
# create an overview of the differences between itself with another 'previous' table, returns a book with a single sheet and table (containing the diffs)
|
7
53
|
#
|
8
|
-
# @return [Workbook::
|
54
|
+
# @return [Workbook::Table] the return result
|
9
55
|
def diff other, options={:sort=>true,:ignore_headers=>false}
|
10
56
|
|
11
57
|
aligned = align(other, options)
|
@@ -45,7 +91,6 @@ module Workbook
|
|
45
91
|
f = diff_template.template.create_or_find_format_by 'updated'
|
46
92
|
dcell.format = f
|
47
93
|
end
|
48
|
-
|
49
94
|
row[ci]=dcell
|
50
95
|
end
|
51
96
|
end
|
@@ -56,26 +101,29 @@ module Workbook
|
|
56
101
|
diff_table
|
57
102
|
end
|
58
103
|
|
104
|
+
# Return template table to write the diff result in; in case non exists a default is generated.
|
105
|
+
#
|
106
|
+
# @return [Workbook::Table] the empty table, linked to a book
|
59
107
|
def diff_template
|
60
108
|
return @diff_template if @diff_template
|
61
|
-
diffbook = Workbook::Book.
|
109
|
+
diffbook = Workbook::Book.new_diff_template
|
62
110
|
difftable = diffbook.sheet.table
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
f[:height] = 80
|
74
|
-
@diff_template = diffbook
|
75
|
-
return difftable
|
111
|
+
@diff_template ||= difftable
|
112
|
+
end
|
113
|
+
|
114
|
+
# Set the template table to write the diff result in; in case non exists a default is generated. Make sure that
|
115
|
+
# the following formats exists: destroyed, updated, created and header.
|
116
|
+
#
|
117
|
+
# @param [Workbook::Table] table to diff inside
|
118
|
+
# @return [Workbook::Table] the passed table
|
119
|
+
def diff_template= table
|
120
|
+
@diff_template= table
|
76
121
|
end
|
77
122
|
|
78
123
|
# aligns itself with another table, used by diff
|
124
|
+
#
|
125
|
+
# @param [Workbook::Table] other table to align with
|
126
|
+
# @param [Hash] options default to: `{:sort=>true,:ignore_headers=>false}`
|
79
127
|
def align other, options={:sort=>true,:ignore_headers=>false}
|
80
128
|
|
81
129
|
options = {:sort=>true,:ignore_headers=>false}.merge(options)
|