workbook 0.4.6.0 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Code Climate](https://codeclimate.com/github/murb/workbook.png)](https://codeclimate.com/github/murb/workbook) [![Build Status](https://travis-ci.org/murb/workbook.png?branch=master)](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) [![Build Status](https://travis-ci.org/murb/workbook.png?branch=master)](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)
|