osheet 1.0.0.rc.1 → 1.0.0.rc.2

Sign up to get free protection for your applications and to get access to all the features.
data/examples/trivial.xls DELETED
@@ -1,18 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
3
- <Styles>
4
- <Style ss:ID="..currency_dollar_2_comma_black">
5
- <NumberFormat ss:Format="&quot;$&quot;#,##0.00" />
6
- </Style>
7
- </Styles>
8
- <Worksheet ss:Name="one dollar">
9
- <Table>
10
- <Column />
11
- <Row>
12
- <Cell ss:StyleID="..currency_dollar_2_comma_black">
13
- <Data ss:Type="Number">1</Data>
14
- </Cell>
15
- </Row>
16
- </Table>
17
- </Worksheet>
18
- </Workbook>
@@ -1,64 +0,0 @@
1
- require 'osheet/style'
2
- require 'osheet/xmlss_writer'
3
- require 'osheet/xmlss_writer/style_settings'
4
-
5
- class Osheet::XmlssWriter
6
- class StyleCache
7
-
8
- attr_reader :styles
9
-
10
- def initialize(osheet_workbook, xmlss_workbook)
11
- @osheet_workbook = osheet_workbook
12
- @xmlss_workbook = xmlss_workbook
13
- @styles = {}
14
- end
15
-
16
- def [](key); @styles[key]; end
17
- def empty?; @styles.empty?; end
18
- def size; @styles.keys.size; end
19
-
20
- def keys
21
- @styles.keys
22
- end
23
-
24
- def get(style_class, format)
25
- # generate the style key and get the get the cached style or
26
- # build and cache and return a style for the key
27
- return nil if (key = self.key(style_class, format.key)).empty?
28
- @styles[key] ||
29
- build_and_cache(key, @osheet_workbook.styles.for(style_class), format)
30
- end
31
-
32
- protected
33
-
34
- # build a unique key for styling based off the style and format keys
35
- def key(class_value, format_key)
36
- (class_value || '').strip.split(/\s+/).collect do |c|
37
- ".#{c}"
38
- end.join('') + (format_key.nil? || format_key.empty? ? '' : "..#{format_key}")
39
- end
40
-
41
- # build and cache an xmlss style
42
- def build_and_cache(key, styles, format)
43
- settings = StyleSettings.new(styles)
44
- @styles[key] = @xmlss_workbook.style(key) {
45
- settings.setting(:align) { @xmlss_workbook.alignment(settings[:align]) }
46
- settings.setting(:font) { @xmlss_workbook.font(settings[:font]) }
47
- settings.setting(:bg) { @xmlss_workbook.interior(settings[:bg]) }
48
-
49
- border_set = ::Osheet::Style::BORDERS.inject([]) do |set, bp|
50
- settings.setting(bp) { set << settings[bp] }
51
- set
52
- end
53
- if !border_set.empty?
54
- @xmlss_workbook.borders {
55
- border_set.each { |setting| @xmlss_workbook.border(setting) }
56
- }
57
- end
58
-
59
- @xmlss_workbook.number_format(format.style)
60
- }
61
- end
62
-
63
- end
64
- end
@@ -1,148 +0,0 @@
1
- require 'osheet/style'
2
- require 'osheet/xmlss_writer'
3
-
4
- class Osheet::XmlssWriter
5
- class StyleSettings
6
-
7
- attr_reader :styles, :value
8
-
9
- def initialize(styles)
10
- @styles = styles
11
- @value = @styles.inject({}) do |value, style|
12
- merged_settings(value, style_settings(style))
13
- end
14
- end
15
-
16
- def [](setting); @value[setting]; end
17
-
18
- # call the given block passing it the setting if that setting
19
- # exists and is not empty
20
- def setting(s, &block)
21
- block.call if self.value[s] && !self.value[s].empty?
22
- end
23
-
24
- protected
25
-
26
- def merged_settings(current, add)
27
- # concat values for keys in both sets
28
- current.keys.each do |k|
29
- current[k].merge!(add.delete(k) || {})
30
- end
31
- # merge keys for anything not in the current
32
- current.merge(add)
33
- end
34
-
35
- def style_settings(osheet_style_obj)
36
- settings = {}
37
- Osheet::Style::SETTINGS.each do |setting|
38
- if !(v = osheet_style_obj.send(setting)).empty?
39
- settings[setting] = self.send("#{setting}_settings", v)
40
- end
41
- end
42
- settings
43
- end
44
-
45
- def align_settings(osheet_align_directives)
46
- osheet_align_directives.inject({}) do |settings, directive|
47
- case directive
48
- when :left, :center, :right
49
- settings[:horizontal] = directive
50
- when :top, :bottom
51
- settings[:vertical] = directive
52
- when :middle
53
- settings[:vertical] = :center
54
- when :wrap
55
- settings[:wrap_text] = true
56
- when ::Fixnum
57
- settings[:rotate] = directive
58
- end
59
- settings
60
- end
61
- end
62
-
63
- def font_settings(osheet_font_directives)
64
- osheet_font_directives.inject({}) do |settings, directive|
65
- case directive
66
- when ::Fixnum
67
- settings[:size] = directive
68
- when ::String
69
- if directive =~ /^#/
70
- settings[:color] = directive
71
- else
72
- settings[:name] = directive
73
- end
74
- when :bold, :italic, :shadow
75
- settings[directive] = true
76
- when :subscript, :superscript
77
- settings[:alignment] = directive
78
- when :strikethrough
79
- settings[:strike_through] = true
80
- when :underline
81
- settings[:underline] = :single
82
- when :double_underline
83
- settings[:underline] = :double
84
- when :accounting_underline
85
- settings[:underline] = :single_accounting
86
- when :double_accounting_underline
87
- settings[:underline] = :double_accounting
88
- end
89
- settings
90
- end
91
- end
92
-
93
- def bg_settings(osheet_bg_directives)
94
- osheet_bg_directives.inject({}) do |settings, directive|
95
- case directive
96
- when ::String
97
- if directive =~ /^#/
98
- settings[:color] = directive
99
- end
100
- when ::Symbol
101
- if ::Xmlss::Style::Interior.pattern_set.include?(directive)
102
- settings[:pattern] = directive
103
- end
104
- when ::Hash
105
- directive.each do |pattern, color|
106
- if ::Xmlss::Style::Interior.pattern_set.include?(pattern) && color =~ /^#/
107
- settings[:pattern] = pattern
108
- settings[:pattern_color] = color
109
- end
110
- end
111
- end
112
-
113
- if !settings[:color].nil? && settings[:pattern].nil?
114
- settings[:pattern] = :solid
115
- end
116
-
117
- settings
118
- end
119
- end
120
-
121
- def border_settings(osheet_border_directives)
122
- osheet_border_directives.inject({}) do |settings, directive|
123
- case directive
124
- when ::String
125
- if directive =~ /^#/
126
- settings[:color] = directive
127
- end
128
- when ::Symbol
129
- if ::Xmlss::Style::Border.position_set.include?(directive)
130
- settings[:position] = directive
131
- elsif ::Xmlss::Style::Border.weight_set.include?(directive)
132
- settings[:weight] = directive
133
- elsif ::Xmlss::Style::Border.line_style_set.include?(directive)
134
- settings[:line_style] = directive
135
- end
136
- end
137
- settings
138
- end
139
- end
140
-
141
- ::Osheet::Style::BORDER_POSITIONS.each do |p|
142
- define_method("border_#{p}_settings") do |cmds|
143
- border_settings(cmds+[p])
144
- end
145
- end
146
-
147
- end
148
- end
@@ -1,143 +0,0 @@
1
- require 'osheet'
2
- require 'xmlss'
3
-
4
- require 'osheet/xmlss_writer/style_cache'
5
-
6
- module Osheet
7
- class XmlssWriter
8
-
9
- # The Osheet::XmlssWriter provides the logic/translation needed to drive
10
- # an xmlss workbook using the Osheet API. The writer creates an xmlss
11
- # workbook and uses the builder approach to drive the workbook creation.
12
-
13
- # The writer maintains a set of used xmlss styles and handles creating
14
- # xmlss style objects as needed and manages style keys
15
-
16
- attr_reader :style_cache, :xmlss_workbook
17
-
18
- def initialize(*args, &block)
19
- @xmlss_workbook = Xmlss::Workbook.new(Xmlss::Writer.new(*args, &block))
20
- @osheet_workbook = nil
21
- @osheet_worksheet_names = []
22
- @style_cache = nil
23
- end
24
-
25
- def bind(osheet_workbook)
26
- @osheet_workbook = osheet_workbook
27
- @style_cache = StyleCache.new(@osheet_workbook, @xmlss_workbook)
28
- end
29
-
30
- def to_s
31
- @xmlss_workbook.to_s
32
- end
33
- alias_method :to_data, :to_s
34
-
35
- def to_file(file_path)
36
- @xmlss_workbook.to_file(file_path)
37
- end
38
-
39
- # Element writers
40
-
41
- def worksheet(worksheet, &build)
42
- if @osheet_workbook && @osheet_worksheet_names.include?(worksheet.name.to_s)
43
- raise ArgumentError, "you can't write two worksheets with the same name ('#{worksheet.name}')"
44
- end
45
- @osheet_worksheet_names << worksheet.name.to_s
46
- @xmlss_workbook.worksheet(worksheet.name, &build)
47
- end
48
-
49
- def column(column, &build)
50
- attrs = {
51
- :width => column.width,
52
- :auto_fit_width => column.autofit,
53
- :hidden => column.hidden
54
- }
55
- if s = @style_cache.get(column.style_class, column.format)
56
- attrs[:style_id] = s.id
57
- end
58
- @xmlss_workbook.column(attrs, &build)
59
- end
60
-
61
- def row(row, &build)
62
- attrs = {
63
- :height => row.height,
64
- :auto_fit_height => row.autofit,
65
- :hidden => row.hidden
66
- }
67
- if s = @style_cache.get(row.style_class, row.format)
68
- attrs[:style_id] = s.id
69
- end
70
- @xmlss_workbook.row(attrs, &build)
71
- end
72
-
73
- def cell(cell, &build)
74
- attrs = {
75
- :href => cell.href,
76
- :index => cell.index,
77
- :merge_across => cell_merge(cell.colspan),
78
- :merge_down => cell_merge(cell.rowspan),
79
- :formula => cell.formula
80
- }
81
- if s = @style_cache.get(cell.style_class, cell.format)
82
- attrs[:style_id] = s.id
83
- end
84
- @xmlss_workbook.cell(cell.data, attrs, &build)
85
- end
86
-
87
- # Element style writers
88
-
89
- # given an elements style_class or format attributes:
90
- # 1) write a new xmlss style object and
91
- # 2) set the current element's style_id attribute
92
-
93
- def style(style_class, format=nil)
94
- @style_cache.get(
95
- style_class,
96
- format || Osheet::Format.new(:general)
97
- ).tap do |xmlss_style|
98
- @xmlss_workbook.style_id(xmlss_style.id)
99
- end
100
- end
101
-
102
- def colspan(count)
103
- @xmlss_workbook.merge_across(cell_merge(count))
104
- end
105
-
106
- def rowspan(count)
107
- @xmlss_workbook.merge_down(cell_merge(count))
108
- end
109
-
110
- def name(value)
111
- @osheet_worksheet_names.pop
112
- @osheet_worksheet_names << value
113
- @xmlss_workbook.name(value)
114
- end
115
-
116
- # Element attribute writers
117
-
118
- [ :width, # column
119
- :height, # row
120
- :autofit, # column, row
121
- :autofit?, # column, row
122
- :hidden, # column, row
123
- :hidden?, # column, row
124
- :data, # cell
125
- :format, # cell
126
- :href, # cell
127
- :formula, # cell
128
- :index # cell
129
- ].each do |meth|
130
- define_method(meth) do |*args, &block|
131
- @xmlss_workbook.send(meth, *args, &block)
132
- end
133
- end
134
-
135
- protected
136
-
137
- # convert osheet col/row span value to xmlss merge value
138
- def cell_merge(span)
139
- span.kind_of?(::Fixnum) && span > 1 ? span-1 : 0
140
- end
141
-
142
- end
143
- end
@@ -1,139 +0,0 @@
1
- require "assert"
2
-
3
- require 'osheet/xmlss_writer'
4
-
5
- module Osheet
6
-
7
- class XmlssWriter::ApiTest < Assert::Context
8
- before do
9
- @writer = XmlssWriter.new
10
- @workbook = Workbook.new(@writer)
11
- end
12
- subject { @writer }
13
-
14
- end
15
-
16
- class XmlssWriter::CellTests < XmlssWriter::ApiTest
17
- desc "when writing a cell"
18
- before do
19
- @cell = Osheet::Cell.new(100)
20
- @cell.style_class "awesome thing"
21
- @cell.format :number
22
- @cell.href 'http://example.com'
23
- @cell.rowspan 2
24
- @cell.colspan 5
25
- @cell.index 3
26
- @cell.formula "=R1C1"
27
- @xmlss_cell = subject.cell(@cell)
28
- end
29
-
30
- should "create an Xmlss::Cell with correct attributes" do
31
- assert_kind_of ::Xmlss::Element::Cell, @xmlss_cell
32
- assert_equal 100, @xmlss_cell.data
33
- assert_equal 'http://example.com', @xmlss_cell.href
34
- assert_equal 3, @xmlss_cell.index
35
- assert_equal "=R1C1", @xmlss_cell.formula
36
- assert_equal 1, @xmlss_cell.merge_down
37
- assert_equal 4, @xmlss_cell.merge_across
38
- end
39
-
40
- should "style the cell" do
41
- assert_equal ".awesome.thing..number_none_0_nocomma_black", @xmlss_cell.style_id
42
- assert_equal 1, subject.style_cache.size
43
- end
44
-
45
- should "write cell element markup" do
46
- assert_equal(
47
- "<Cell ss:Formula=\"=R1C1\" ss:HRef=\"http://example.com\" ss:Index=\"3\" ss:MergeAcross=\"4\" ss:MergeDown=\"1\" ss:StyleID=\".awesome.thing..number_none_0_nocomma_black\"><Data ss:Type=\"Number\">100</Data></Cell>",
48
- xmlss_element_markup(subject)
49
- )
50
- end
51
-
52
- end
53
-
54
- class XmlssWriter::RowTests < XmlssWriter::ApiTest
55
- desc "when writing a row"
56
- before do
57
- @row = Osheet::Row.new
58
- @row.style_class "awesome thing"
59
- @row.height 100
60
- @row.autofit true
61
- @row.hidden true
62
- @xmlss_row = subject.row(@row)
63
- end
64
-
65
- should "create an Xmlss::Row with correct attributes" do
66
- assert_kind_of ::Xmlss::Element::Row, @xmlss_row
67
- assert_equal 100, @xmlss_row.height
68
- assert_equal true, @xmlss_row.auto_fit_height
69
- assert_equal true, @xmlss_row.hidden
70
- end
71
-
72
- should "style the row" do
73
- assert_equal ".awesome.thing", @xmlss_row.style_id
74
- assert_equal 1, subject.style_cache.size
75
- end
76
-
77
- should "write row element markup" do
78
- assert_equal(
79
- "<Row ss:AutoFitHeight=\"1\" ss:Height=\"100\" ss:Hidden=\"1\" ss:StyleID=\".awesome.thing\" />",
80
- xmlss_element_markup(subject)
81
- )
82
- end
83
-
84
- end
85
-
86
- class XmlssWriter::ColumnTests < XmlssWriter::ApiTest
87
- desc "when writing a column"
88
- before do
89
- @column = Osheet::Column.new
90
- @column.style_class "awesome"
91
- @column.width 100
92
- @column.autofit true
93
- @column.hidden true
94
- @xmlss_column = subject.column(@column)
95
- end
96
-
97
- should "create an Xmlss::Column with correct attributes" do
98
- assert_kind_of ::Xmlss::Element::Column, @xmlss_column
99
- assert_equal 100, @xmlss_column.width
100
- assert_equal true, @xmlss_column.auto_fit_width
101
- assert_equal true, @xmlss_column.hidden
102
- end
103
-
104
- should "style an Xmlss column" do
105
- assert_equal ".awesome", @xmlss_column.style_id
106
- assert_equal 1, subject.style_cache.size
107
- end
108
-
109
- should "write column element markup" do
110
- assert_equal(
111
- "<Column ss:AutoFitWidth=\"1\" ss:Hidden=\"1\" ss:StyleID=\".awesome\" ss:Width=\"100\" />",
112
- xmlss_element_markup(subject)
113
- )
114
- end
115
-
116
- end
117
-
118
- class XmlssWriter::WorksheetTests < XmlssWriter::ApiTest
119
- desc "when writing a worksheet"
120
- before do
121
- @worksheet = Worksheet.new("testsheet2")
122
- @xmlss_worksheet = subject.worksheet(@worksheet)
123
- end
124
-
125
- should "create an Xmlss::Worksheet with correct attributes" do
126
- assert_kind_of ::Xmlss::Element::Worksheet, @xmlss_worksheet
127
- assert_equal "testsheet2", @xmlss_worksheet.name
128
- end
129
-
130
- should "write worksheet element markup" do
131
- assert_equal(
132
- "<Worksheet ss:Name=\"testsheet2\"><Table /></Worksheet>",
133
- xmlss_element_markup(subject)
134
- )
135
- end
136
-
137
- end
138
-
139
- end
@@ -1,65 +0,0 @@
1
- require "assert"
2
-
3
- require 'osheet/xmlss_writer/style_cache'
4
-
5
- module Osheet
6
-
7
- class XmlssWriterStyleCacheTests < Assert::Context
8
- desc "the style cache"
9
- before do
10
- @workbook = Workbook.new
11
- @workbook.style('.align.center') { @workbook.align :center }
12
- @workbook.style('.font.size') { @workbook.font 14 }
13
- @workbook.style('.font.weight') { @workbook.font :bold }
14
- @workbook.style('.font.style') { @workbook.font :italic }
15
- @workbook.style('.bg.color') { @workbook.bg '#FF0000' }
16
- @workbook.style('.border.color') { @workbook.border '#FF0000', :thin }
17
- @xmlss_workbook = Xmlss::Workbook.new(Xmlss::Writer.new)
18
-
19
- @cache = XmlssWriter::StyleCache.new(@workbook, @xmlss_workbook)
20
- end
21
- subject { @cache }
22
-
23
- should have_reader :styles
24
- should have_instance_method :get, :keys, :empty?, :size, :[]
25
-
26
- should "have no cached styles by default" do
27
- assert_empty subject
28
- end
29
-
30
- should "key based off class value and format key" do
31
- assert_equal '', subject.send(:key, '', nil)
32
- assert_equal '.awesome', subject.send(:key, 'awesome', nil)
33
- assert_equal '.awesome.thing', subject.send(:key, 'awesome thing', nil)
34
- assert_equal '.awesome..something', subject.send(:key, 'awesome', 'something')
35
- assert_equal '..something', subject.send(:key, '', 'something')
36
- end
37
-
38
- should "return nil if trying to get the style for an empty class and general format" do
39
- assert_not_nil subject.get('font', Osheet::Format.new(:general))
40
- assert_nil subject.get('', Osheet::Format.new(:general))
41
- end
42
-
43
- should "build and cache styles if not already cached" do
44
- assert_equal 0, subject.size
45
- subject.get('font', Osheet::Format.new(:currency))
46
- assert_equal 1, subject.size
47
- end
48
-
49
- should "return cached style if requesting an already cached style" do
50
- assert_equal 0, subject.size
51
- subject.get('font', Osheet::Format.new(:currency))
52
- subject.get('font', Osheet::Format.new(:currency))
53
- assert_equal 1, subject.size
54
- end
55
-
56
- should "build styles with ids matching the cache key" do
57
- key = subject.send(:key, 'font', Osheet::Format.new(:currency).key)
58
- assert_equal key, subject.get('font', Osheet::Format.new(:currency)).id
59
- end
60
-
61
- end
62
-
63
-
64
-
65
- end