xmlss 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +28 -0
- data/README.rdoc +154 -0
- data/Rakefile +7 -0
- data/examples/example_workbook.rb +19 -0
- data/examples/layout.rb +81 -0
- data/examples/simple.rb +30 -0
- data/examples/styles.rb +85 -0
- data/examples/text.rb +36 -0
- data/lib/xmlss/cell.rb +38 -0
- data/lib/xmlss/column.rb +28 -0
- data/lib/xmlss/data.rb +67 -0
- data/lib/xmlss/enum.rb +56 -0
- data/lib/xmlss/item_set.rb +17 -0
- data/lib/xmlss/row.rb +34 -0
- data/lib/xmlss/style/alignment.rb +47 -0
- data/lib/xmlss/style/base.rb +63 -0
- data/lib/xmlss/style/border.rb +43 -0
- data/lib/xmlss/style/font.rb +41 -0
- data/lib/xmlss/style/interior.rb +41 -0
- data/lib/xmlss/style/number_format.rb +20 -0
- data/lib/xmlss/style/protection.rb +18 -0
- data/lib/xmlss/table.rb +22 -0
- data/lib/xmlss/version.rb +3 -0
- data/lib/xmlss/workbook.rb +33 -0
- data/lib/xmlss/worksheet.rb +37 -0
- data/lib/xmlss/xml.rb +55 -0
- data/lib/xmlss.rb +31 -0
- data/test/cell_test.rb +86 -0
- data/test/column_test.rb +46 -0
- data/test/data_test.rb +75 -0
- data/test/enum_test.rb +63 -0
- data/test/env.rb +10 -0
- data/test/helper.rb +49 -0
- data/test/item_set_test.rb +26 -0
- data/test/row_test.rb +67 -0
- data/test/style/alignment_test.rb +107 -0
- data/test/style/base_test.rb +126 -0
- data/test/style/border_test.rb +114 -0
- data/test/style/font_test.rb +100 -0
- data/test/style/interior_test.rb +87 -0
- data/test/style/number_format_test.rb +50 -0
- data/test/style/protection_test.rb +45 -0
- data/test/table_test.rb +53 -0
- data/test/thing.rb +5 -0
- data/test/workbook_test.rb +59 -0
- data/test/worksheet_test.rb +62 -0
- data/test/xml_test.rb +61 -0
- data/test/xmlss_test.rb +29 -0
- data/xmlss.gemspec +23 -0
- metadata +184 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
xmlss (0.0.1)
|
5
|
+
nokogiri (~> 1.4.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
json (1.5.1)
|
11
|
+
kelredd-useful (0.4.1)
|
12
|
+
json
|
13
|
+
leftright (0.9.0)
|
14
|
+
nokogiri (1.4.4)
|
15
|
+
shoulda (2.11.3)
|
16
|
+
test-belt (0.2.1)
|
17
|
+
kelredd-useful (~> 0.4.0)
|
18
|
+
leftright (~> 0.9.0)
|
19
|
+
shoulda (~> 2.11)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
bundler (~> 1.0)
|
26
|
+
nokogiri (~> 1.4.0)
|
27
|
+
test-belt (= 0.2.1)
|
28
|
+
xmlss!
|
data/README.rdoc
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
= Xmlss
|
2
|
+
|
3
|
+
== Description
|
4
|
+
|
5
|
+
This gem allows you to generate spreadsheets in the XML Spreadsheet format. It provides an api for constructing spreadsheet data and then uses that data to generate xml that can be interpreted by MS Excel.
|
6
|
+
|
7
|
+
** Note: this gem only generates XML according to a subset of the August 2001 XML Spreadsheet spec (http://msdn.microsoft.com/en-us/library/aa140066(office.10).aspx). It does not generate the more modern open office spreadsheet spec (xlsx).
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
gem install xmlss
|
12
|
+
|
13
|
+
== Simple Example
|
14
|
+
|
15
|
+
require 'xmlss'
|
16
|
+
|
17
|
+
workbook = Xmlss::Workbook.new
|
18
|
+
workbook.worksheets # => []
|
19
|
+
|
20
|
+
sheet1 = Xmlss::Worksheet.new({
|
21
|
+
:name => 'Sheet 1'
|
22
|
+
})
|
23
|
+
sheet1.table = Xmlss::Table.new
|
24
|
+
sheet1.table.rows # => []
|
25
|
+
|
26
|
+
row1 = Xmlss::Row.new(1, 'some data', 54.54)
|
27
|
+
row1.cells.count = 3
|
28
|
+
row1.cells.first.data # => 1
|
29
|
+
|
30
|
+
sheet1.table.rows << row1
|
31
|
+
workbook.worksheets << sheet1
|
32
|
+
|
33
|
+
workbook.to_xml # => "..." (XML Spreadsheet xml string)
|
34
|
+
|
35
|
+
== Usage
|
36
|
+
see the examples folder for some use case examples.
|
37
|
+
|
38
|
+
Be aware this library only provides the basic, raw API for constructing spreadsheets using this spec and utilities to convert those objects to string xml data representing them. It does not provide any macro logic to aid in constructing the sheets. If you want a more convenient API for your use case, I suggest subclassing the objects and tailoring them to your needs.
|
39
|
+
|
40
|
+
The XML Spreadsheet spec and format are legacy and may have limited support depending on your version of MS Excel. For a more modern spreadsheet generation method, I suggest looking into Office Open XML Workbook format (http://en.wikipedia.org/wiki/Office_Open_XML).
|
41
|
+
|
42
|
+
== API
|
43
|
+
|
44
|
+
These classes define how a spreadsheet is constructed.
|
45
|
+
=== Xmlss::Workbook
|
46
|
+
* *styles*: array, Xmlss:Style objects, default: []
|
47
|
+
* *worksheets*: array, Xmlss::Worksheet objects, default: []
|
48
|
+
|
49
|
+
=== Xmlss::Worksheet
|
50
|
+
* *name*: string
|
51
|
+
* *table*: Xmlss::Table object
|
52
|
+
|
53
|
+
=== Xmlss::Table
|
54
|
+
* *columns*: array, Xmlss::Column objects, default: []
|
55
|
+
* *rows*: array, Xmlss::Row objects, default: []
|
56
|
+
|
57
|
+
=== Xmlss::Column
|
58
|
+
* *style_id*: string
|
59
|
+
* *width*: numeric
|
60
|
+
* *auto_fit_width*: bool, default: false
|
61
|
+
* *hidden*: bool, default: false
|
62
|
+
|
63
|
+
=== Xmlss::Row
|
64
|
+
* *style_id*: string
|
65
|
+
* *height*: numeric
|
66
|
+
* *auto_fit_height*: bool, default: false
|
67
|
+
* *hidden*: bool, default: false
|
68
|
+
* *cells*: array, Xmlss::Cell objects, default: []
|
69
|
+
|
70
|
+
=== Xmlss::Cell
|
71
|
+
* *style_id*: string
|
72
|
+
* *data*: Xmlss::Data object
|
73
|
+
* *formula*: string
|
74
|
+
* *href*: string
|
75
|
+
* *merge_across*: int, default: 0
|
76
|
+
* *merge_down*: int, default: 0
|
77
|
+
* *tool_tip*: string
|
78
|
+
|
79
|
+
=== Xmlss::Data
|
80
|
+
* *type*: :number, :datetime, :boolean, :string, :error, required
|
81
|
+
* *value*: needs to respond to 'to_s'
|
82
|
+
|
83
|
+
|
84
|
+
These classes define how a spreadsheet cells are styled.
|
85
|
+
=== Xmlss::Style
|
86
|
+
* *id*: string, unique identifier for the style
|
87
|
+
* *alignment*: Xmlss::Style::Alignment object
|
88
|
+
* *borders*: array, Xmlss::Style::Border objects, default: []
|
89
|
+
* *font*: Xmlss::Style::Font object
|
90
|
+
* *interior*: Xmlss::Style::Interior object
|
91
|
+
* *number_format*: Xmlss::Style::NumberFormat object
|
92
|
+
* *protection*: Xmlss::Protection object
|
93
|
+
|
94
|
+
=== Xmlss::Style::Alignment
|
95
|
+
* *horizontal*: :automatic, :left, :center, :right, :default, default: :default
|
96
|
+
* *vertical*: :automatic, :top, :center, :bottom, :default, default: :default
|
97
|
+
* *wrap_text*: bool, default: false
|
98
|
+
* *rotate*: int (-90 to 90)
|
99
|
+
|
100
|
+
=== Xmlss::Style::Border
|
101
|
+
* *position*: :left, :top, :right, :bottom
|
102
|
+
* *color*: hex string
|
103
|
+
* *style*: :none, :continuous, :dash, :dot, :dash_dot, :dash_dot_dot, default: :continuous
|
104
|
+
* *weight*: :hairline, :thin, :medium, :thick, default: :thin
|
105
|
+
|
106
|
+
=== Xmlss::Style::Font
|
107
|
+
* *bold*: bool, default: false
|
108
|
+
* *color*: hex string
|
109
|
+
* *name*: string
|
110
|
+
* *italic*: bool, default: false
|
111
|
+
* *size*: int
|
112
|
+
* *strike_through*: bool, default: false
|
113
|
+
* *underline*: :none, :single, :double
|
114
|
+
* *alignment*: :none, :subscript, :superscript
|
115
|
+
|
116
|
+
=== Xmlss::Style::Interior
|
117
|
+
* *color*: hex string
|
118
|
+
* *pattern*: symbol (see code for options), default: :default
|
119
|
+
* *pattern_color*: hex string
|
120
|
+
|
121
|
+
=== Xmlss::Style::NumberFormat
|
122
|
+
* *format*: :symbol (see code for options)
|
123
|
+
|
124
|
+
=== Xmlss::Style::Protection
|
125
|
+
* *protected*: bool, default: false
|
126
|
+
|
127
|
+
|
128
|
+
== For More Info
|
129
|
+
* Full XML Spreadsheet spec: http://msdn.microsoft.com/en-us/library/aa140066(office.10).aspx
|
130
|
+
|
131
|
+
== License
|
132
|
+
|
133
|
+
Copyright (c) 2011 Kelly D. Redding
|
134
|
+
|
135
|
+
Permission is hereby granted, free of charge, to any person
|
136
|
+
obtaining a copy of this software and associated documentation
|
137
|
+
files (the "Software"), to deal in the Software without
|
138
|
+
restriction, including without limitation the rights to use,
|
139
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
140
|
+
copies of the Software, and to permit persons to whom the
|
141
|
+
Software is furnished to do so, subject to the following
|
142
|
+
conditions:
|
143
|
+
|
144
|
+
The above copyright notice and this permission notice shall be
|
145
|
+
included in all copies or substantial portions of the Software.
|
146
|
+
|
147
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
148
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
149
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
150
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
151
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
152
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
153
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
154
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/env'
|
3
|
+
|
4
|
+
class ExampleWorkbook < Xmlss::Workbook
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
puts "Builing #{self.name}.xml..."
|
8
|
+
build
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_file
|
12
|
+
# write this workbooks xml data to a file
|
13
|
+
File.open("examples/#{self.name}.xml", "w") do |file|
|
14
|
+
file.write self.to_xml
|
15
|
+
end
|
16
|
+
puts "... ready - open in Excel or whatever..."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
data/examples/layout.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'examples/example_workbook'
|
2
|
+
|
3
|
+
class Layout < ExampleWorkbook
|
4
|
+
def name; "layout"; end
|
5
|
+
def build
|
6
|
+
wksht = Xmlss::Worksheet.new('first')
|
7
|
+
4.times do
|
8
|
+
wksht.table.columns << Xmlss::Column.new
|
9
|
+
end
|
10
|
+
|
11
|
+
5.times do
|
12
|
+
wksht.table.rows << Xmlss::Row.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# | A | B | C | D |
|
16
|
+
# 1| x | x | x | x |
|
17
|
+
# 2| x | x | x |
|
18
|
+
# 3| x | | x |
|
19
|
+
# 4| x | x | x |
|
20
|
+
# 5| x | | x |
|
21
|
+
|
22
|
+
# row 1: one cell per column
|
23
|
+
4.times do |i|
|
24
|
+
wksht.table.rows[0].cells << Xmlss::Cell.new({
|
25
|
+
:index => i+1,
|
26
|
+
:data => Xmlss::Data.new("x")
|
27
|
+
})
|
28
|
+
end
|
29
|
+
|
30
|
+
# row 2: first cell colspan=2
|
31
|
+
wksht.table.rows[1].cells << Xmlss::Cell.new({
|
32
|
+
:index => 1,
|
33
|
+
:data => Xmlss::Data.new("x"),
|
34
|
+
:merge_across => 1
|
35
|
+
})
|
36
|
+
2.times do |i|
|
37
|
+
wksht.table.rows[1].cells << Xmlss::Cell.new({
|
38
|
+
:index => i+3,
|
39
|
+
:data => Xmlss::Data.new("x")
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
43
|
+
# row 3,4,5: more complex merging
|
44
|
+
# => row 3
|
45
|
+
wksht.table.rows[2].cells << Xmlss::Cell.new({
|
46
|
+
:data => Xmlss::Data.new("x"),
|
47
|
+
:index => 1
|
48
|
+
})
|
49
|
+
wksht.table.rows[2].cells << Xmlss::Cell.new({
|
50
|
+
:data => Xmlss::Data.new("x"),
|
51
|
+
:merge_across => 1,
|
52
|
+
:merge_down => 2,
|
53
|
+
:index => 2
|
54
|
+
})
|
55
|
+
wksht.table.rows[2].cells << Xmlss::Cell.new({
|
56
|
+
:data => Xmlss::Data.new("x"),
|
57
|
+
:index => 4
|
58
|
+
})
|
59
|
+
# => row 4
|
60
|
+
wksht.table.rows[3].cells << Xmlss::Cell.new({
|
61
|
+
:data => Xmlss::Data.new("x"),
|
62
|
+
:index => 1
|
63
|
+
})
|
64
|
+
wksht.table.rows[3].cells << Xmlss::Cell.new({
|
65
|
+
:data => Xmlss::Data.new("x"),
|
66
|
+
:index => 4
|
67
|
+
})
|
68
|
+
# => row 5
|
69
|
+
wksht.table.rows[4].cells << Xmlss::Cell.new({
|
70
|
+
:data => Xmlss::Data.new("x"),
|
71
|
+
:index => 1
|
72
|
+
})
|
73
|
+
wksht.table.rows[4].cells << Xmlss::Cell.new({
|
74
|
+
:data => Xmlss::Data.new("x"),
|
75
|
+
:index => 4
|
76
|
+
})
|
77
|
+
|
78
|
+
self.worksheets << wksht
|
79
|
+
end
|
80
|
+
end
|
81
|
+
Layout.new.to_file
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'examples/example_workbook'
|
2
|
+
|
3
|
+
class Simple < ExampleWorkbook
|
4
|
+
def name; "simple"; end
|
5
|
+
def build
|
6
|
+
|
7
|
+
# add 1 row of simple data across 3 columns
|
8
|
+
wksht = Xmlss::Worksheet.new('1 row, 3 columns')
|
9
|
+
|
10
|
+
wksht.table.columns << Xmlss::Column.new
|
11
|
+
wksht.table.columns << Xmlss::Column.new
|
12
|
+
wksht.table.columns << Xmlss::Column.new
|
13
|
+
wksht.table.columns << Xmlss::Column.new
|
14
|
+
wksht.table.columns << Xmlss::Column.new
|
15
|
+
|
16
|
+
row1 = Xmlss::Row.new
|
17
|
+
|
18
|
+
# put data into the row (infer type)
|
19
|
+
[1, "text", 123.45, "0001267", "$45.23"].each do |data|
|
20
|
+
row1.cells << Xmlss::Cell.new({
|
21
|
+
:data => Xmlss::Data.new(data)
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
wksht.table.rows << row1
|
26
|
+
self.worksheets << wksht
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
Simple.new.to_file
|
data/examples/styles.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'examples/example_workbook'
|
2
|
+
|
3
|
+
class Styles < ExampleWorkbook
|
4
|
+
def name; "styles"; end
|
5
|
+
def build
|
6
|
+
|
7
|
+
wksht = Xmlss::Worksheet.new('styles')
|
8
|
+
wksht.table.columns << Xmlss::Column.new
|
9
|
+
|
10
|
+
self.styles << Xmlss::Style::Base.new('centered') do
|
11
|
+
alignment(
|
12
|
+
:horizontal => :center,
|
13
|
+
:vertical => :center
|
14
|
+
)
|
15
|
+
end
|
16
|
+
wksht.table.rows << Xmlss::Row.new
|
17
|
+
wksht.table.rows[0].cells << Xmlss::Cell.new({
|
18
|
+
:style_id => "centered",
|
19
|
+
:data => Xmlss::Data.new("x")
|
20
|
+
})
|
21
|
+
|
22
|
+
self.styles << Xmlss::Style::Base.new('bordered') do
|
23
|
+
alignment(:wrap_text => true)
|
24
|
+
border(
|
25
|
+
:position => :top,
|
26
|
+
:weight => :hairline,
|
27
|
+
:line_style => :continuous
|
28
|
+
)
|
29
|
+
border(
|
30
|
+
:position => :right,
|
31
|
+
:weight => :medium,
|
32
|
+
:line_style => :continuous
|
33
|
+
)
|
34
|
+
border(
|
35
|
+
:position => :bottom,
|
36
|
+
:weight => :thick,
|
37
|
+
:line_style => :dash_dot,
|
38
|
+
:color => '#00FF00'
|
39
|
+
)
|
40
|
+
border(
|
41
|
+
:position => :left,
|
42
|
+
:weight => :thin,
|
43
|
+
:line_style => :dot
|
44
|
+
)
|
45
|
+
end
|
46
|
+
wksht.table.rows << Xmlss::Row.new
|
47
|
+
wksht.table.rows[1].cells << Xmlss::Cell.new({
|
48
|
+
:style_id => "bordered",
|
49
|
+
:data => Xmlss::Data.new(%{blah blah blah blah blah\nblah blah blah blah\nblah blah blah blah})
|
50
|
+
})
|
51
|
+
|
52
|
+
self.styles << Xmlss::Style::Base.new('fonted') do
|
53
|
+
font(
|
54
|
+
:bold => true,
|
55
|
+
:color => "#FF0000",
|
56
|
+
:italic => true,
|
57
|
+
:size => 18,
|
58
|
+
:strike_through => true,
|
59
|
+
:underline => true
|
60
|
+
)
|
61
|
+
end
|
62
|
+
wksht.table.rows << Xmlss::Row.new
|
63
|
+
wksht.table.rows[2].cells << Xmlss::Cell.new({
|
64
|
+
:style_id => "fonted",
|
65
|
+
:data => Xmlss::Data.new("Cool Font Styles!!")
|
66
|
+
})
|
67
|
+
|
68
|
+
self.styles << Xmlss::Style::Base.new('interior') do
|
69
|
+
interior(
|
70
|
+
:color => "#FF0000",
|
71
|
+
:pattern => :diag_cross,
|
72
|
+
:pattern_color => '#00FFFF'
|
73
|
+
)
|
74
|
+
font(:color => "#FFFFFF")
|
75
|
+
end
|
76
|
+
wksht.table.rows << Xmlss::Row.new
|
77
|
+
wksht.table.rows[3].cells << Xmlss::Cell.new({
|
78
|
+
:style_id => "interior",
|
79
|
+
:data => Xmlss::Data.new("Weird Styles Man...")
|
80
|
+
})
|
81
|
+
|
82
|
+
self.worksheets << wksht
|
83
|
+
end
|
84
|
+
end
|
85
|
+
Styles.new.to_file
|
data/examples/text.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'examples/example_workbook'
|
2
|
+
|
3
|
+
class Text < ExampleWorkbook
|
4
|
+
def name; "text"; end
|
5
|
+
def build
|
6
|
+
|
7
|
+
# add in general text style
|
8
|
+
self.styles << Xmlss::Style::Base.new('general_text') do
|
9
|
+
alignment(
|
10
|
+
:horizontal => :left,
|
11
|
+
:vertical => :top,
|
12
|
+
:wrap_text => true
|
13
|
+
)
|
14
|
+
number_format(
|
15
|
+
:format => "@" # set format to text explicitly
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
# add single cell with text data and specify general text style
|
20
|
+
wksht = Xmlss::Worksheet.new('text')
|
21
|
+
wksht.table.columns << Xmlss::Column.new
|
22
|
+
row1 = Xmlss::Row.new
|
23
|
+
row1.cells << Xmlss::Cell.new({
|
24
|
+
:style_id => "general_text",
|
25
|
+
:data => Xmlss::Data.new(%{
|
26
|
+
A blob of text
|
27
|
+
with line breaks
|
28
|
+
and leading space
|
29
|
+
})
|
30
|
+
})
|
31
|
+
wksht.table.rows << row1
|
32
|
+
self.worksheets << wksht
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
Text.new.to_file
|
data/lib/xmlss/cell.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'xmlss/data'
|
2
|
+
|
3
|
+
module Xmlss
|
4
|
+
class Cell
|
5
|
+
|
6
|
+
include Xmlss::Xml
|
7
|
+
def xml
|
8
|
+
{ :node => :cell,
|
9
|
+
:attributes => [:index, :style_i_d, :formula, :h_ref, :merge_across, :merge_down],
|
10
|
+
:children => [:data] }
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :style_id, :formula, :href, :merge_across, :merge_down
|
14
|
+
attr_accessor :index, :data
|
15
|
+
alias_method :style_i_d, :style_id
|
16
|
+
alias_method :h_ref, :href
|
17
|
+
|
18
|
+
def initialize(attrs={})
|
19
|
+
self.index = attrs[:index]
|
20
|
+
self.style_id = attrs[:style_id]
|
21
|
+
self.formula = attrs[:formula]
|
22
|
+
self.href = attrs[:href]
|
23
|
+
self.merge_across = attrs[:merge_across] || 0
|
24
|
+
self.merge_down = attrs[:merge_down] || 0
|
25
|
+
self.data = attrs[:data]
|
26
|
+
end
|
27
|
+
|
28
|
+
[:index, :merge_across, :merge_down].each do |meth|
|
29
|
+
define_method("#{meth}=") do |value|
|
30
|
+
if value && !value.kind_of?(::Fixnum)
|
31
|
+
raise ArgumentError, "must specify #{meth} as a Fixnum"
|
32
|
+
end
|
33
|
+
instance_variable_set("@#{meth}", value && value <= 0 ? nil : value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/lib/xmlss/column.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Xmlss
|
2
|
+
class Column
|
3
|
+
|
4
|
+
include Xmlss::Xml
|
5
|
+
def xml
|
6
|
+
{ :node => :column,
|
7
|
+
:attributes => [:style_i_d, :width, :auto_fit_width, :hidden] }
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_accessor :style_id, :width, :auto_fit_width, :hidden
|
11
|
+
alias_method :style_i_d, :style_id
|
12
|
+
|
13
|
+
def initialize(attrs={})
|
14
|
+
self.style_id = attrs[:style_id]
|
15
|
+
self.width = attrs[:width]
|
16
|
+
self.auto_fit_width = attrs[:auto_fit_width] || false
|
17
|
+
self.hidden = attrs[:hidden] || false
|
18
|
+
end
|
19
|
+
|
20
|
+
def width=(value)
|
21
|
+
if value && !value.kind_of?(::Numeric)
|
22
|
+
raise ArgumentError, "must specify width as a Numeric"
|
23
|
+
end
|
24
|
+
@width = value && value < 0 ? nil : value
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/xmlss/data.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Xmlss
|
4
|
+
class Data
|
5
|
+
|
6
|
+
LB = " "
|
7
|
+
|
8
|
+
include Xmlss::Xml
|
9
|
+
def xml
|
10
|
+
{ :node => :data,
|
11
|
+
:attributes => [:type],
|
12
|
+
:value => :xml_value }
|
13
|
+
end
|
14
|
+
|
15
|
+
include Xmlss::Enum
|
16
|
+
enum :type, {
|
17
|
+
:number => "Number",
|
18
|
+
:date_time => "DateTime",
|
19
|
+
:boolean => "Boolean",
|
20
|
+
:string => "String",
|
21
|
+
:error => "Error"
|
22
|
+
}
|
23
|
+
|
24
|
+
attr_accessor :value
|
25
|
+
|
26
|
+
def initialize(value="", attrs={})
|
27
|
+
self.value = value
|
28
|
+
self.type = attrs[:type] if attrs[:type]
|
29
|
+
end
|
30
|
+
|
31
|
+
def value=(v)
|
32
|
+
if self.type.nil?
|
33
|
+
self.type = value_type(v)
|
34
|
+
end
|
35
|
+
@value = v
|
36
|
+
end
|
37
|
+
|
38
|
+
def xml_value
|
39
|
+
case value
|
40
|
+
when ::Date, ::Time, ::DateTime
|
41
|
+
value.strftime("%Y-%m-%dT%H:%M:%S")
|
42
|
+
when ::String, ::Symbol
|
43
|
+
value.to_s.gsub(/(\r|\n)+/, LB)
|
44
|
+
else
|
45
|
+
value.to_s
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def value_type(v)
|
52
|
+
case v
|
53
|
+
when ::Numeric
|
54
|
+
:number
|
55
|
+
when ::Date, ::Time
|
56
|
+
:date_time
|
57
|
+
when ::TrueClass, ::FalseClass
|
58
|
+
:boolean
|
59
|
+
when ::String, ::Symbol
|
60
|
+
:string
|
61
|
+
else
|
62
|
+
:string
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/lib/xmlss/enum.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# common methods used for handling enum data
|
2
|
+
module Xmlss
|
3
|
+
module Enum
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def enum(name, map)
|
7
|
+
# TODO: validate name
|
8
|
+
unless map.kind_of?(::Hash)
|
9
|
+
raise ArguementError, "please specify the enum map as a Hash"
|
10
|
+
end
|
11
|
+
|
12
|
+
# define an anonymous Module to extend on
|
13
|
+
# defining a class level map reader
|
14
|
+
class_methods = Module.new do
|
15
|
+
define_method(name) do |key|
|
16
|
+
class_variable_get("@@#{name}")[key]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# set a class variable to store the enum map (used by above reader)
|
21
|
+
# extend the anonymous module to get tne above class
|
22
|
+
# level reader for the map
|
23
|
+
class_eval do
|
24
|
+
class_variable_set("@@#{name}", map)
|
25
|
+
extend class_methods
|
26
|
+
end
|
27
|
+
|
28
|
+
# instance writer for the enum value
|
29
|
+
define_method("#{name}=") do |value|
|
30
|
+
map = self.class.send(:class_variable_get, "@@#{name}")
|
31
|
+
instance_variable_set("@#{name}", if value && map.has_key?(value)
|
32
|
+
# write by key
|
33
|
+
map[value]
|
34
|
+
elsif map.has_value?(value)
|
35
|
+
# write by value
|
36
|
+
value
|
37
|
+
else
|
38
|
+
nil
|
39
|
+
end)
|
40
|
+
end
|
41
|
+
|
42
|
+
# instance reader for the enum value
|
43
|
+
define_method(name) do
|
44
|
+
instance_variable_get("@#{name}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class << self
|
50
|
+
def included(receiver)
|
51
|
+
receiver.send :extend, ClassMethods
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|