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

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.
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