axlsx 1.0.12 → 1.0.14

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.
Files changed (77) hide show
  1. data/README.md +165 -134
  2. data/examples/example.rb +133 -153
  3. data/lib/axlsx/#cfb.xlsx# +0 -0
  4. data/lib/axlsx/content_type/content_type.rb +23 -0
  5. data/lib/axlsx/content_type/default.rb +37 -0
  6. data/lib/axlsx/content_type/override.rb +37 -0
  7. data/lib/axlsx/doc_props/app.rb +178 -0
  8. data/lib/axlsx/doc_props/core.rb +34 -0
  9. data/lib/axlsx/drawing/axis.rb +93 -0
  10. data/lib/axlsx/drawing/bar_3D_chart.rb +136 -0
  11. data/lib/axlsx/drawing/bar_series.rb +64 -0
  12. data/lib/axlsx/drawing/cat_axis.rb +63 -0
  13. data/lib/axlsx/drawing/cat_axis_data.rb +35 -0
  14. data/lib/axlsx/drawing/chart.rb +193 -0
  15. data/lib/axlsx/drawing/drawing.rb +137 -0
  16. data/lib/axlsx/drawing/graphic_frame.rb +52 -0
  17. data/lib/axlsx/drawing/line_3D_chart.rb +114 -0
  18. data/lib/axlsx/drawing/line_series.rb +46 -0
  19. data/lib/axlsx/drawing/marker.rb +61 -0
  20. data/lib/axlsx/drawing/one_cell_anchor.rb +89 -0
  21. data/lib/axlsx/drawing/pic.rb +153 -0
  22. data/lib/axlsx/drawing/picture_locking.rb +72 -0
  23. data/lib/axlsx/drawing/picture_locking.rb~ +36 -0
  24. data/lib/axlsx/drawing/pie_3D_chart.rb +41 -0
  25. data/lib/axlsx/drawing/pie_series.rb +56 -0
  26. data/lib/axlsx/drawing/scaling.rb +59 -0
  27. data/lib/axlsx/drawing/ser_axis.rb +45 -0
  28. data/lib/axlsx/drawing/series.rb +71 -0
  29. data/lib/axlsx/drawing/series_title.rb +22 -0
  30. data/lib/axlsx/drawing/title.rb +65 -0
  31. data/lib/axlsx/drawing/two_cell_anchor.rb +76 -0
  32. data/lib/axlsx/drawing/val_axis.rb +34 -0
  33. data/lib/axlsx/drawing/val_axis_data.rb +26 -0
  34. data/lib/axlsx/drawing/view_3D.rb +85 -0
  35. data/lib/axlsx/package.rb +223 -0
  36. data/lib/axlsx/rels/relationship.rb +44 -0
  37. data/lib/axlsx/rels/relationships.rb +25 -0
  38. data/lib/axlsx/stylesheet/border.rb +57 -0
  39. data/lib/axlsx/stylesheet/border_pr.rb +68 -0
  40. data/lib/axlsx/stylesheet/cell_alignment.rb +105 -0
  41. data/lib/axlsx/stylesheet/cell_protection.rb +36 -0
  42. data/lib/axlsx/stylesheet/cell_style.rb +65 -0
  43. data/lib/axlsx/stylesheet/color.rb +69 -0
  44. data/lib/axlsx/stylesheet/fill.rb +32 -0
  45. data/lib/axlsx/stylesheet/font.rb +139 -0
  46. data/lib/axlsx/stylesheet/gradient_fill.rb +76 -0
  47. data/lib/axlsx/stylesheet/gradient_stop.rb +33 -0
  48. data/lib/axlsx/stylesheet/num_fmt.rb +63 -0
  49. data/lib/axlsx/stylesheet/pattern_fill.rb +66 -0
  50. data/lib/axlsx/stylesheet/styles.rb +298 -0
  51. data/lib/axlsx/stylesheet/table_style.rb +47 -0
  52. data/lib/axlsx/stylesheet/table_style_element.rb +71 -0
  53. data/lib/axlsx/stylesheet/table_styles.rb +39 -0
  54. data/lib/axlsx/stylesheet/xf.rb +138 -0
  55. data/lib/axlsx/util/constants.rb +216 -0
  56. data/lib/axlsx/util/ms_off_crypto.rb +88 -0
  57. data/lib/axlsx/util/ms_off_crypto.rb~ +3 -0
  58. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  59. data/lib/axlsx/util/parser.rb +43 -0
  60. data/lib/axlsx/util/parser.rb~ +6 -0
  61. data/lib/axlsx/util/simple_typed_list.rb +160 -0
  62. data/lib/axlsx/util/validators.rb +132 -0
  63. data/lib/axlsx/version.rb +4 -0
  64. data/lib/axlsx/workbook/workbook.rb +161 -0
  65. data/lib/axlsx/workbook/worksheet/cell.rb +350 -0
  66. data/lib/axlsx/workbook/worksheet/row.rb +107 -0
  67. data/lib/axlsx/workbook/worksheet/worksheet.rb +335 -0
  68. data/lib/axlsx.rb +59 -0
  69. data/test/drawing/tc_axis.rb +1 -1
  70. data/test/drawing/tc_cat_axis.rb +1 -1
  71. data/test/drawing/tc_line_series.tc~ +34 -0
  72. data/test/drawing/tc_picture_locking.rb~ +77 -0
  73. data/test/tc_package.rb +10 -0
  74. data/test/workbook/worksheet/tc_cell.rb +15 -0
  75. data/test/workbook/worksheet/tc_worksheet.rb +22 -1
  76. metadata +117 -5
  77. data/examples/follow_20111202.xlsx +0 -0
@@ -0,0 +1,335 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Axlsx
3
+
4
+ # The Worksheet class represents a worksheet in the workbook.
5
+ class Worksheet
6
+
7
+ # The name of the worksheet
8
+ # @return [String]
9
+ attr_reader :name
10
+
11
+ # The workbook that owns this worksheet
12
+ # @return [Workbook]
13
+ attr_reader :workbook
14
+
15
+
16
+ # The rows in this worksheet
17
+ # @note The recommended way to manage rows is Worksheet#add_row
18
+ # @return [SimpleTypedList]
19
+ # @see Worksheet#add_row
20
+ attr_reader :rows
21
+
22
+ # An array of content based calculated column widths.
23
+ # @note a single auto fit data item is a hash with :longest => [String] and :sz=> [Integer] members.
24
+ # @return [Array] of Hash
25
+ attr_reader :auto_fit_data
26
+
27
+ # An array of merged cell ranges e.d "A1:B3"
28
+ # Content and formatting is read from the first cell.
29
+ # @return Array
30
+ attr_reader :merged_cells
31
+
32
+ # An range that excel will apply an autfilter to "A1:B3"
33
+ # This will turn filtering on for the cells in the range.
34
+ # The first row is considered the header, while subsequent rows are considerd to be data.
35
+ # @return Array
36
+ attr_reader :auto_filter
37
+
38
+ # Creates a new worksheet.
39
+ # @note the recommended way to manage worksheets is Workbook#add_worksheet
40
+ # @see Workbook#add_worksheet
41
+ # @option options [String] name The name of this sheet.
42
+ def initialize(wb, options={})
43
+ @drawing = nil
44
+ @rows = SimpleTypedList.new Row
45
+ self.workbook = wb
46
+ @workbook.worksheets << self
47
+ @auto_fit_data = []
48
+ self.name = options[:name] || "Sheet" + (index+1).to_s
49
+ @magick_draw = Magick::Draw.new
50
+ @cols = SimpleTypedList.new Cell
51
+ @merged_cells = []
52
+ end
53
+
54
+ # Creates merge information for this worksheet.
55
+ # Cells can be merged by calling the merge_cells method on a worksheet.
56
+ # @example This would merge the three cells C1..E1 #
57
+ # worksheet.merge_cells "C1:E1"
58
+ # # you can also provide an array of cells to be merged
59
+ # worksheet.merge_cells worksheet.rows.first.cells[(2..4)]
60
+ # #alternatively you can do it from a single cell
61
+ # worksheet["C1"].merge worksheet["E1"]
62
+ # @param [Array, string]
63
+ def merge_cells(cells)
64
+ @merged_cells << if cells.is_a?(String)
65
+ cells
66
+ elsif cells.is_a?(Array)
67
+ cells = cells.sort { |x, y| x.r <=> y.r }
68
+ "#{cells.first.r}:#{cells.last.r}"
69
+ end
70
+ end
71
+
72
+
73
+ # Returns the cell or cells defined using excel style A1:B3 references.
74
+ # @param [String] cell_def the string defining the cell or range of cells
75
+ # @return [Cell, Array]
76
+ def [](cell_def)
77
+ parts = cell_def.split(':')
78
+ first = name_to_cell parts[0]
79
+
80
+ if parts.size == 1
81
+ first
82
+ else
83
+ cells = []
84
+ last = name_to_cell(parts[1])
85
+ rows[(first.row.index..last.row.index)].each do |r|
86
+ r.cells[(first.index..last.index)].each do |c|
87
+ cells << c
88
+ end
89
+ end
90
+ cells
91
+ end
92
+ end
93
+
94
+ # returns the column and row index for a named based cell
95
+ # @param [String] name The cell or cell range to return. "A1" will return the first cell of the first row.
96
+ # @return [Cell]
97
+ def name_to_cell(name)
98
+ col_index, row_index = *Axlsx::name_to_indices(name)
99
+ r = rows[row_index]
100
+ r.cells[col_index] if r
101
+ end
102
+
103
+ # The name of the worksheet
104
+ # @param [String] v
105
+ def name=(v)
106
+ DataTypeValidator.validate "Worksheet.name", String, v
107
+ sheet_names = @workbook.worksheets.map { |s| s.name }
108
+ raise ArgumentError, (ERR_DUPLICATE_SHEET_NAME % v) if sheet_names.include?(v)
109
+ @name=v
110
+ end
111
+
112
+ # The auto filter range for the worksheet
113
+ # @param [String] v
114
+ # @see auto_filter
115
+ def auto_filter=(v)
116
+ DataTypeValidator.validate "Worksheet.auto_filter", String, v
117
+ @auto_filter = v
118
+ end
119
+
120
+ # The part name of this worksheet
121
+ # @return [String]
122
+ def pn
123
+ "#{WORKSHEET_PN % (index+1)}"
124
+ end
125
+
126
+ # The relationship part name of this worksheet
127
+ # @return [String]
128
+ def rels_pn
129
+ "#{WORKSHEET_RELS_PN % (index+1)}"
130
+ end
131
+
132
+ # The relationship Id of thiw worksheet
133
+ # @return [String]
134
+ def rId
135
+ "rId#{index+1}"
136
+ end
137
+
138
+ # The index of this worksheet in the owning Workbook's worksheets list.
139
+ # @return [Integer]
140
+ def index
141
+ @workbook.worksheets.index(self)
142
+ end
143
+
144
+ # The drawing associated with this worksheet.
145
+ # @note the recommended way to work with drawings and charts is Worksheet#add_chart
146
+ # @return [Drawing]
147
+ # @see Worksheet#add_chart
148
+ def drawing
149
+ @drawing || @drawing = Axlsx::Drawing.new(self)
150
+ end
151
+
152
+ # Adds a row to the worksheet and updates auto fit data
153
+ # @return [Row]
154
+ # @option options [Array] values
155
+ # @option options [Array, Symbol] types
156
+ # @option options [Array, Integer] style
157
+ def add_row(values=[], options={})
158
+ Row.new(self, values, options)
159
+ update_auto_fit_data @rows.last.cells
160
+ yield @rows.last if block_given?
161
+ @rows.last
162
+ end
163
+
164
+ # Set the style for cells in a specific row
165
+ # @param [Integer] index or range of indexes in the table
166
+ # @param [Integer] the cellXfs index
167
+ # @option options [Integer] col_offset only cells after this column will be updated.
168
+ # @note You can also specify the style in the add_row call
169
+ # @see Worksheet#add_row
170
+ # @see README.md for an example
171
+ def row_style(index, style, options={})
172
+ offset = options.delete(:col_offset) || 0
173
+ rs = @rows[index]
174
+ if rs.is_a?(Array)
175
+ rs.each { |r| r.cells[(offset..-1)].each { |c| c.style = style } }
176
+ else
177
+ rs.cells[(offset..-1)].each { |c| c.style = style }
178
+ end
179
+ end
180
+
181
+ # returns the sheet data as columnw
182
+ def cols
183
+ @rows.transpose
184
+ end
185
+
186
+
187
+ # Set the style for cells in a specific column
188
+ # @param [Integer] index the index of the column
189
+ # @param [Integer] the cellXfs index
190
+ # @option options [Integer] row_offset only cells after this column will be updated.
191
+ # @note You can also specify the style for specific columns in the call to add_row by using an array for the :styles option
192
+ # @see Worksheet#add_row
193
+ # @see README.md for an example
194
+ def col_style(index, style, options={})
195
+ offset = options.delete(:row_offset) || 0
196
+ @rows[(offset..-1)].each do |r|
197
+ cells = r.cells[index]
198
+ if cells.is_a?(Array)
199
+ cells.each { |c| c.style = style }
200
+ else
201
+ cells.style = style
202
+ end
203
+ end
204
+ end
205
+
206
+ # Adds a chart to this worksheets drawing. This is the recommended way to create charts for your worksheet. This method wraps the complexity of dealing with ooxml drawing, anchors, markers graphic frames chart objects and all the other dirty details.
207
+ # @param [Class] chart_type
208
+ # @option options [Array] start_at
209
+ # @option options [Array] end_at
210
+ # @option options [Cell, String] title
211
+ # @option options [Boolean] show_legend
212
+ # @option options [Integer] style
213
+ # @note each chart type also specifies additional options
214
+ # @see Chart
215
+ # @see Pie3DChart
216
+ # @see Bar3DChart
217
+ # @see Line3DChart
218
+ # @see README for examples
219
+ def add_chart(chart_type, options={})
220
+ chart = drawing.add_chart(chart_type, options)
221
+ yield chart if block_given?
222
+ chart
223
+ end
224
+
225
+ # Adds a media item to the worksheets drawing
226
+ # @param [Class] media_type
227
+ # @option options [] unknown
228
+ def add_image(options={})
229
+ image = drawing.add_image(options)
230
+ yield image if block_given?
231
+ image
232
+ end
233
+
234
+ # Serializes the worksheet document
235
+ # @return [String]
236
+ def to_xml
237
+ builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
238
+ xml.worksheet(:xmlns => XML_NS,
239
+ :'xmlns:r' => XML_NS_R) {
240
+ if @auto_fit_data.size > 0
241
+ xml.cols {
242
+ @auto_fit_data.each_with_index do |col, index|
243
+ min_max = index+1
244
+ xml.col(:min=>min_max, :max=>min_max, :width => auto_width(col), :customWidth=>1)
245
+ end
246
+ }
247
+ end
248
+ xml.sheetData {
249
+ @rows.each do |row|
250
+ row.to_xml(xml)
251
+ end
252
+ }
253
+ xml.autoFilter :ref=>@auto_filter if @auto_filter
254
+ xml.mergeCells(:count=>@merged_cells.size) { @merged_cells.each { | mc | xml.mergeCell(:ref=>mc) } } unless @merged_cells.empty?
255
+ xml.drawing :"r:id"=>"rId1" if @drawing
256
+ }
257
+ end
258
+ builder.to_xml
259
+ end
260
+
261
+ # The worksheet relationships. This is managed automatically by the worksheet
262
+ # @return [Relationships]
263
+ def relationships
264
+ r = Relationships.new
265
+ r << Relationship.new(DRAWING_R, "../#{@drawing.pn}") if @drawing
266
+ r
267
+ end
268
+
269
+ private
270
+
271
+ # assigns the owner workbook for this worksheet
272
+ def workbook=(v) DataTypeValidator.validate "Worksheet.workbook", Workbook, v; @workbook = v; end
273
+
274
+ # Updates auto fit data.
275
+ # We store an auto_fit_data item for each column. when a row is added we multiple the font size by the length of the text to
276
+ # attempt to identify the longest cell in the column. This is not 100% accurate as it needs to take into account
277
+ # any formatting that will be applied to the data, as well as the actual rendering size when the length and size is equal
278
+ # for two cells.
279
+ # @return [Array] of Cell objects
280
+ # @param [Array] cells an array of cells
281
+ def update_auto_fit_data(cells)
282
+ # TODO delay this until rendering. too much work when we dont know what they are going to do to the sheet.
283
+ styles = self.workbook.styles
284
+ cellXfs, fonts = styles.cellXfs, styles.fonts
285
+ sz = 11
286
+ cells.each_with_index do |item, index|
287
+ # ignore formula - there is no way for us to know the result
288
+ next if item.value.is_a?(String) && item.value.start_with?('=')
289
+
290
+ col = @auto_fit_data[index] || {:longest=>"", :sz=>sz}
291
+ cell_xf = cellXfs[item.style]
292
+ font = fonts[cell_xf.fontId || 0]
293
+ sz = item.sz || font.sz || fonts[0].sz
294
+ if (col[:longest].scan(/./mu).size * col[:sz]) < (item.value.to_s.scan(/./mu).size * sz)
295
+ col[:sz] = sz
296
+ col[:longest] = item.value.to_s
297
+ end
298
+ @auto_fit_data[index] = col
299
+ end
300
+ cells
301
+ end
302
+
303
+ # Determines the proper width for a column based on content.
304
+ # @note
305
+ # width = Truncate([!{Number of Characters} * !{Maximum Digit Width} + !{5 pixel padding}]/!{Maximum Digit Width}*256)/256
306
+ # @return [Float]
307
+ # @param [Hash] A hash of auto_fit_data
308
+ def auto_width(col)
309
+ mdw_count, font_scale, mdw = 0, col[:sz]/11.0, 6.0
310
+ mdw_count = col[:longest].scan(/./mu).reduce(0) do | count, char |
311
+ count +=1 if @magick_draw.get_type_metrics(char).max_advance >= mdw
312
+ count
313
+ end
314
+ ((mdw_count * mdw + 5) / mdw * 256) / 256.0 * font_scale
315
+ end
316
+
317
+ # Something to look into:
318
+ # width calculation actually needs to be done agains the formatted value for items that apply a
319
+ # format
320
+ # def excel_format(cell)
321
+ # # The most common case.
322
+ # return time.value.to_s if cell.style == 0
323
+ #
324
+ # # The second most common case
325
+ # num_fmt = workbook.styles.cellXfs[items.style].numFmtId
326
+ # return value.to_s if num_fmt == 0
327
+ #
328
+ # format_code = workbook.styles.numFmts[num_fmt]
329
+ # # need to find some exceptionally fast way of parsing value according to
330
+ # # an excel format_code
331
+ # item.value.to_s
332
+ # end
333
+
334
+ end
335
+ end
data/lib/axlsx.rb ADDED
@@ -0,0 +1,59 @@
1
+ Encoding::default_internal = 'UTF-8' unless RUBY_VERSION < '1.9'
2
+ Encoding::default_external = 'UTF-8' unless RUBY_VERSION < '1.9'
3
+
4
+ require 'axlsx/version.rb'
5
+
6
+ require 'axlsx/util/simple_typed_list.rb'
7
+ require 'axlsx/util/constants.rb'
8
+ require 'axlsx/util/validators.rb'
9
+
10
+ require 'axlsx/util/ms_off_crypto.rb'
11
+
12
+
13
+ # to be included with parsable intitites.
14
+ #require 'axlsx/util/parser.rb'
15
+
16
+ require 'axlsx/stylesheet/styles.rb'
17
+
18
+ require 'axlsx/doc_props/app.rb'
19
+ require 'axlsx/doc_props/core.rb'
20
+ require 'axlsx/content_type/content_type.rb'
21
+ require 'axlsx/rels/relationships.rb'
22
+
23
+ require 'axlsx/drawing/drawing.rb'
24
+ require 'axlsx/workbook/workbook.rb'
25
+ require 'axlsx/package.rb'
26
+
27
+ #required gems
28
+ require 'nokogiri'
29
+ require 'active_support/core_ext/object/instance_variables'
30
+ require 'active_support/inflector'
31
+ require 'RMagick'
32
+ require 'zip/zip'
33
+
34
+ #core dependencies
35
+ require 'bigdecimal'
36
+ require 'time'
37
+
38
+
39
+ # xlsx generation with charts, images, automated column width, customizable styles and full schema validation. Axlsx excels at helping you generate beautiful Office Open XML Spreadsheet documents without having to understand the entire ECMA specification. Check out the README for some examples of how easy it is. Best of all, you can validate your xlsx file before serialization so you know for sure that anything generated is going to load on your client's machine.
40
+ module Axlsx
41
+ # determines the cell range for the items provided
42
+ def self.cell_range(items)
43
+ return "" unless items.first.is_a? Cell
44
+ ref = "'#{items.first.row.worksheet.name}'!" +
45
+ "#{items.first.r_abs}"
46
+ ref += ":#{items.last.r_abs}" if items.size > 1
47
+ ref
48
+ end
49
+
50
+ def self.name_to_indices(name)
51
+ raise ArgumentError, 'invalid cell name' unless name.size > 1
52
+ v = name[/[A-Z]+/].reverse.chars.reduce({:base=>1, :i=>0}) do |v, c|
53
+ v[:i] += ((c.bytes.first - 65) + v[:base]); v[:base] *= 26; v
54
+ end
55
+
56
+ [v[:i]-1, ((name[/[1-9]+/]).to_i)-1]
57
+
58
+ end
59
+ end
@@ -9,7 +9,7 @@ class TestAxis < Test::Unit::TestCase
9
9
  end
10
10
 
11
11
  def test_initialization
12
- assert_equal(@axis.axPos, :l, "axis position default incorrect")
12
+ assert_equal(@axis.axPos, :b, "axis position default incorrect")
13
13
  assert_equal(@axis.tickLblPos, :nextTo, "tick label position default incorrect")
14
14
  assert_equal(@axis.tickLblPos, :nextTo, "tick label position default incorrect")
15
15
  assert_equal(@axis.crosses, :autoZero, "tick label position default incorrect")
@@ -9,7 +9,7 @@ class TestCatAxis < Test::Unit::TestCase
9
9
  end
10
10
 
11
11
  def test_initialization
12
- assert_equal(@axis.auto, true, "axis auto default incorrect")
12
+ assert_equal(@axis.auto, 1, "axis auto default incorrect")
13
13
  assert_equal(@axis.lblAlgn, :ctr, "label align default incorrect")
14
14
  assert_equal(@axis.lblOffset, "100%", "label offset default incorrect")
15
15
  end
@@ -0,0 +1,34 @@
1
+ require 'test/unit'
2
+ require 'axlsx.rb'
3
+
4
+ class TestLineSeries < Test::Unit::TestCase
5
+
6
+ def setup
7
+ p = Axlsx::Package.new
8
+ @ws = p.workbook.add_worksheet :name=>"hmmm"
9
+ chart = @ws.drawing.add_chart Axlsx::Bar3DChart, :title => "fishery"
10
+ @series = chart.add_series :data=>[0,1,2], :labels=>["zero", "one", "two"], :title=>"bob"
11
+ end
12
+
13
+ def test_initialize
14
+ assert_equal(@series.title, "bob", "series title has been applied")
15
+ assert_equal(@series.data, [0,1,2], "data option applied")
16
+ assert_equal(@series.labels, ["zero", "one","two"], "labels option applied")
17
+ assert_equal(@series.shape, :box, "series shape has been applied")
18
+ end
19
+
20
+ def test_data
21
+ assert_equal(@series.data, [0,1,2])
22
+ end
23
+
24
+ def test_labels
25
+ assert_equal(@series.labels, ["zero", "one", "two"])
26
+ end
27
+
28
+ def test_shape
29
+ assert_raise(ArgumentError, "require valid shape") { @series.shape = :teardropt }
30
+ assert_nothing_raised("allow valid shape") { @series.shape = :cone }
31
+ assert(@series.shape == :cone)
32
+ end
33
+
34
+ end
@@ -0,0 +1,77 @@
1
+ require 'test/unit'
2
+ require 'axlsx.rb'
3
+
4
+ class TestPictureLocking < Test::Unit::TestCase
5
+ def setup
6
+ @item = Axlsx::CellAlignment.new
7
+ end
8
+ def teardown
9
+ end
10
+ def test_initialiation
11
+ assert_equal(@item.horizontal, nil)
12
+ assert_equal(@item.vertical, nil)
13
+ assert_equal(@item.textRotation, nil)
14
+ assert_equal(@item.wrapText, nil)
15
+ assert_equal(@item.indent, nil)
16
+ assert_equal(@item.relativeIndent, nil)
17
+ assert_equal(@item.justifyLastLine, nil)
18
+ assert_equal(@item.shrinkToFit, nil)
19
+ assert_equal(@item.readingOrder, nil)
20
+
21
+ end
22
+
23
+ def test_horizontal
24
+ assert_raise(ArgumentError) { @item.horizontal = :red }
25
+ assert_nothing_raised { @item.horizontal = :left }
26
+ assert_equal(@item.horizontal, :left )
27
+ end
28
+
29
+ def test_vertical
30
+ assert_raise(ArgumentError) { @item.vertical = :red }
31
+ assert_nothing_raised { @item.vertical = :top }
32
+ assert_equal(@item.vertical, :top )
33
+ end
34
+
35
+ def test_textRotation
36
+ assert_raise(ArgumentError) { @item.textRotation = -1 }
37
+ assert_nothing_raised { @item.textRotation = 5 }
38
+ assert_equal(@item.textRotation, 5 )
39
+ end
40
+
41
+ def test_wrapText
42
+ assert_raise(ArgumentError) { @item.wrapText = -1 }
43
+ assert_nothing_raised { @item.wrapText = false }
44
+ assert_equal(@item.wrapText, false )
45
+ end
46
+
47
+ def test_indent
48
+ assert_raise(ArgumentError) { @item.indent = -1 }
49
+ assert_nothing_raised { @item.indent = 5 }
50
+ assert_equal(@item.indent, 5 )
51
+ end
52
+
53
+ def test_relativeIndent
54
+ assert_raise(ArgumentError) { @item.relativeIndent = :symbol }
55
+ assert_nothing_raised { @item.relativeIndent = 5 }
56
+ assert_equal(@item.relativeIndent, 5 )
57
+ end
58
+
59
+ def test_justifyLastLine
60
+ assert_raise(ArgumentError) { @item.justifyLastLine = -1 }
61
+ assert_nothing_raised { @item.justifyLastLine = true }
62
+ assert_equal(@item.justifyLastLine, true )
63
+ end
64
+
65
+ def test_shrinkToFit
66
+ assert_raise(ArgumentError) { @item.shrinkToFit = -1 }
67
+ assert_nothing_raised { @item.shrinkToFit = true }
68
+ assert_equal(@item.shrinkToFit, true )
69
+ end
70
+
71
+ def test_readingOrder
72
+ assert_raise(ArgumentError) { @item.readingOrder = -1 }
73
+ assert_nothing_raised { @item.readingOrder = 2 }
74
+ assert_equal(@item.readingOrder, 2 )
75
+ end
76
+
77
+ end
data/test/tc_package.rb CHANGED
@@ -11,6 +11,16 @@ class TestPackage < Test::Unit::TestCase
11
11
 
12
12
  end
13
13
 
14
+ def test_core_accessor
15
+ assert_equal(@package.core, @package.instance_values["core"])
16
+ assert_raise(NoMethodError) {@package.core = nil }
17
+ end
18
+
19
+ def test_app_accessor
20
+ assert_equal(@package.app, @package.instance_values["app"])
21
+ assert_raise(NoMethodError) {@package.app = nil }
22
+ end
23
+
14
24
  def test_default_objects_are_created
15
25
  assert(@package.instance_values["app"].is_a?(Axlsx::App), 'App object not created')
16
26
  assert(@package.instance_values["core"].is_a?(Axlsx::Core), 'Core object not created')
@@ -175,5 +175,20 @@ class TestCell < Test::Unit::TestCase
175
175
  assert_equal(@c.b, false)
176
176
  end
177
177
 
178
+ def test_merge_with_string
179
+ assert_equal(@c.row.worksheet.merged_cells.size, 0)
180
+ @c.row.add_cell 2
181
+ @c.row.add_cell 3
182
+ @c.merge "A2"
183
+ assert_equal(@c.row.worksheet.merged_cells.last, "A1:A2")
184
+ end
185
+
186
+ def test_merge_with_cell
187
+ assert_equal(@c.row.worksheet.merged_cells.size, 0)
188
+ @c.row.add_cell 2
189
+ @c.row.add_cell 3
190
+ @c.merge @row.cells.last
191
+ assert_equal(@c.row.worksheet.merged_cells.last, "A1:C1")
192
+ end
178
193
 
179
194
  end
@@ -132,7 +132,28 @@ class TestWorksheet < Test::Unit::TestCase
132
132
 
133
133
  def test_auto_width
134
134
  assert(@ws.send(:auto_width, {:sz=>11, :longest=>"fisheries"}) > @ws.send(:auto_width, {:sz=>11, :longest=>"fish"}), "longer strings get a longer auto_width at the same font size")
135
- assert(@ws.send(:auto_width, {:sz=>12, :longest=>"fish"}) > @ws.send(:auto_width, {:sz=>11, :longest=>"fish"}), "larger font size gets a longer auto_width using the same text")
135
+
136
+ assert(@ws.send(:auto_width, {:sz=>11, :longest=>"fish"}) < @ws.send(:auto_width, {:sz=>12, :longest=>"fish"}), "larger fonts produce longer with with same string")
137
+
136
138
  end
137
139
 
140
+ def test_merge_cells
141
+ assert(@ws.merged_cells.is_a?(Array))
142
+ assert_equal(@ws.merged_cells.size, 0)
143
+ @ws.add_row [1,2,3]
144
+ @ws.add_row [4,5,6]
145
+ @ws.add_row [7,8,9]
146
+ @ws.merge_cells "A1:A2"
147
+ @ws.merge_cells "B2:C3"
148
+ @ws.merge_cells @ws.rows.last.cells[(0..1)]
149
+ assert_equal(@ws.merged_cells.size, 3)
150
+ assert_equal(@ws.merged_cells.last, "A3:B3")
151
+ end
152
+
153
+ def test_auto_filter
154
+ assert(@ws.auto_filter.nil?)
155
+ assert_raise(ArgumentError) { @ws.auto_filter = 123 }
156
+ @ws.auto_filter = "A1:D9"
157
+ assert_equal(@ws.auto_filter, "A1:D9")
158
+ end
138
159
  end