axlsx 1.1.4 → 1.2.0

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 (196) hide show
  1. data/.yardopts +5 -2
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +108 -31
  4. data/Rakefile +11 -3
  5. data/examples/basic_charts.rb +54 -0
  6. data/examples/chart_colors.rb +17 -2
  7. data/examples/data_validation.rb +50 -0
  8. data/examples/example.rb +130 -47
  9. data/examples/example.xlsx +0 -0
  10. data/examples/example_streamed.xlsx +0 -0
  11. data/examples/extractive.pdf +0 -0
  12. data/examples/extractive.rb +3 -0
  13. data/examples/no-use_autowidth.xlsx +0 -0
  14. data/examples/scraping_html.rb +91 -0
  15. data/examples/shared_strings_example.xlsx +0 -0
  16. data/examples/sheet_protection.rb +10 -0
  17. data/examples/sheet_view.rb +34 -0
  18. data/examples/two_cell_anchor_image.rb +11 -0
  19. data/lib/axlsx/content_type/content_type.rb +2 -0
  20. data/lib/axlsx/content_type/default.rb +30 -15
  21. data/lib/axlsx/content_type/override.rb +29 -14
  22. data/lib/axlsx/doc_props/app.rb +161 -104
  23. data/lib/axlsx/doc_props/core.rb +9 -5
  24. data/lib/axlsx/drawing/ax_data_source.rb +7 -6
  25. data/lib/axlsx/drawing/axis.rb +82 -36
  26. data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
  27. data/lib/axlsx/drawing/bar_series.rb +2 -1
  28. data/lib/axlsx/drawing/cat_axis.rb +43 -39
  29. data/lib/axlsx/drawing/chart.rb +65 -54
  30. data/lib/axlsx/drawing/d_lbls.rb +100 -0
  31. data/lib/axlsx/drawing/drawing.rb +20 -8
  32. data/lib/axlsx/drawing/graphic_frame.rb +2 -1
  33. data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
  34. data/lib/axlsx/drawing/num_data.rb +2 -2
  35. data/lib/axlsx/drawing/num_data_source.rb +4 -1
  36. data/lib/axlsx/drawing/pic.rb +44 -4
  37. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
  38. data/lib/axlsx/drawing/scatter_chart.rb +2 -8
  39. data/lib/axlsx/drawing/title.rb +21 -9
  40. data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
  41. data/lib/axlsx/drawing/view_3D.rb +41 -31
  42. data/lib/axlsx/drawing/vml_drawing.rb +42 -0
  43. data/lib/axlsx/drawing/vml_shape.rb +125 -0
  44. data/lib/axlsx/package.rb +44 -16
  45. data/lib/axlsx/rels/relationship.rb +3 -3
  46. data/lib/axlsx/rels/relationships.rb +1 -11
  47. data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
  48. data/lib/axlsx/stylesheet/styles.rb +1 -1
  49. data/lib/axlsx/stylesheet/table_style.rb +3 -3
  50. data/lib/axlsx/util/constants.rb +28 -0
  51. data/lib/axlsx/util/simple_typed_list.rb +15 -21
  52. data/lib/axlsx/util/validators.rb +80 -7
  53. data/lib/axlsx/version.rb +2 -7
  54. data/lib/axlsx/workbook/defined_name.rb +174 -0
  55. data/lib/axlsx/workbook/defined_names.rb +21 -0
  56. data/lib/axlsx/workbook/workbook.rb +65 -13
  57. data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
  58. data/lib/axlsx/workbook/worksheet/cell.rb +35 -7
  59. data/lib/axlsx/workbook/worksheet/col.rb +15 -0
  60. data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
  61. data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
  62. data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
  63. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
  64. data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
  65. data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
  66. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
  67. data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
  68. data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
  69. data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
  70. data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
  71. data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
  72. data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
  73. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
  74. data/lib/axlsx/workbook/worksheet/row.rb +36 -20
  75. data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
  76. data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
  77. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
  78. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
  79. data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
  80. data/lib/axlsx/workbook/worksheet/table.rb +2 -2
  81. data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
  82. data/lib/axlsx/workbook/worksheet/worksheet.rb +377 -255
  83. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
  84. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
  85. data/lib/axlsx.rb +30 -15
  86. data/test/content_type/tc_content_type.rb +1 -6
  87. data/test/doc_props/tc_app.rb +31 -1
  88. data/test/doc_props/tc_core.rb +3 -1
  89. data/test/drawing/tc_axis.rb +38 -3
  90. data/test/drawing/tc_bar_3D_chart.rb +12 -12
  91. data/test/drawing/tc_bar_series.rb +1 -2
  92. data/test/drawing/tc_cat_axis.rb +3 -3
  93. data/test/drawing/tc_chart.rb +29 -9
  94. data/test/drawing/tc_d_lbls.rb +47 -0
  95. data/test/drawing/tc_drawing.rb +11 -5
  96. data/test/drawing/tc_hyperlink.rb +4 -5
  97. data/test/drawing/tc_line_series.rb +7 -3
  98. data/test/drawing/tc_num_data.rb +5 -1
  99. data/test/drawing/tc_pic.rb +22 -2
  100. data/test/drawing/tc_pie_3D_chart.rb +4 -8
  101. data/test/drawing/tc_pie_series.rb +7 -2
  102. data/test/drawing/tc_scatter_chart.rb +6 -1
  103. data/test/drawing/tc_scatter_series.rb +1 -1
  104. data/test/drawing/tc_series.rb +1 -1
  105. data/test/drawing/tc_title.rb +16 -0
  106. data/test/drawing/tc_two_cell_anchor.rb +1 -2
  107. data/test/drawing/tc_view_3D.rb +18 -18
  108. data/test/drawing/tc_vml_drawing.rb +25 -0
  109. data/test/drawing/tc_vml_shape.rb +100 -0
  110. data/test/rels/tc_relationship.rb +1 -0
  111. data/test/stylesheet/tc_gradient_fill.rb +8 -0
  112. data/test/stylesheet/tc_pattern_fill.rb +7 -1
  113. data/test/stylesheet/tc_styles.rb +3 -4
  114. data/test/stylesheet/tc_table_style.rb +8 -0
  115. data/test/stylesheet/tc_table_style_element.rb +10 -1
  116. data/test/tc_helper.rb +1 -0
  117. data/test/tc_package.rb +93 -17
  118. data/test/util/tc_simple_typed_list.rb +13 -0
  119. data/test/util/tc_validators.rb +95 -9
  120. data/test/workbook/tc_defined_name.rb +41 -0
  121. data/test/workbook/tc_workbook.rb +5 -3
  122. data/test/workbook/worksheet/table/tc_table.rb +3 -11
  123. data/test/workbook/worksheet/tc_cell.rb +30 -6
  124. data/test/workbook/worksheet/tc_col.rb +9 -0
  125. data/test/workbook/worksheet/tc_comment.rb +57 -0
  126. data/test/workbook/worksheet/tc_comments.rb +57 -0
  127. data/test/workbook/worksheet/tc_conditional_formatting.rb +44 -0
  128. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  129. data/test/workbook/worksheet/tc_data_validation.rb +265 -0
  130. data/test/workbook/worksheet/tc_page_setup.rb +138 -0
  131. data/test/workbook/worksheet/tc_pane.rb +94 -0
  132. data/test/workbook/worksheet/tc_print_options.rb +72 -0
  133. data/test/workbook/worksheet/tc_protected_range.rb +17 -0
  134. data/test/workbook/worksheet/tc_row.rb +32 -14
  135. data/test/workbook/worksheet/tc_selection.rb +94 -0
  136. data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
  137. data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
  138. data/test/workbook/worksheet/tc_worksheet.rb +138 -48
  139. metadata +140 -80
  140. data/examples/#extractive.csv# +0 -0
  141. data/examples/#extractive.rb# +0 -45
  142. data/examples/chart_colors.rb~ +0 -0
  143. data/examples/chart_colors.xlsx +0 -0
  144. data/examples/colored_series_data.xlsx +0 -0
  145. data/examples/conditional_formatting/getting_barred.xlsx +0 -0
  146. data/examples/example.csv +0 -1000
  147. data/examples/extractive.csv +0 -1
  148. data/examples/extractive.csv~ +0 -1
  149. data/examples/extractive.rb~ +0 -3
  150. data/examples/extractive.xlsx +0 -0
  151. data/examples/stack.rb +0 -21
  152. data/examples/stack.rb~ +0 -27
  153. data/examples/stack.xlsx +0 -0
  154. data/examples/~$chart_colors.xlsx +0 -0
  155. data/examples/~$extractive.xlsx +0 -0
  156. data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
  157. data/lib/axlsx/drawing/data_source.rb~ +0 -51
  158. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  159. data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
  160. data/lib/axlsx/drawing/num_data.rb~ +0 -51
  161. data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
  162. data/lib/axlsx/drawing/num_val.rb~ +0 -40
  163. data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
  164. data/lib/axlsx/drawing/ref.rb~ +0 -41
  165. data/lib/axlsx/drawing/str_data.rb~ +0 -58
  166. data/lib/axlsx/drawing/str_val.rb~ +0 -35
  167. data/lib/axlsx/util/cbf.rb +0 -333
  168. data/lib/axlsx/util/cfb.rb~ +0 -201
  169. data/lib/axlsx/util/font_tables.rb~ +0 -0
  170. data/lib/axlsx/util/ms_off_crypto.rb +0 -189
  171. data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
  172. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  173. data/lib/axlsx/util/parser.rb~ +0 -6
  174. data/lib/axlsx/util/storage.rb~ +0 -0
  175. data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
  176. data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
  177. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  178. data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
  179. data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
  180. data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
  181. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  182. data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
  183. data/lib/schema/dc.xsd~ +0 -118
  184. data/lib/schema/dcterms.xsd~ +0 -331
  185. data/lib/schema/opc-coreProperties.xsd~ +0 -50
  186. data/test/drawing/tc_data_source.rb~ +0 -30
  187. data/test/drawing/tc_num_data.rb~ +0 -35
  188. data/test/drawing/tc_num_val.rb~ +0 -29
  189. data/test/drawing/tc_str_data.rb~ +0 -30
  190. data/test/drawing/tc_str_val.rb~ +0 -26
  191. data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
  192. data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
  193. data/test/workbook/worksheet/tc_col.rb~ +0 -10
  194. data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
  195. data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
  196. data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
data/examples/example.rb CHANGED
@@ -57,7 +57,7 @@ wb.add_worksheet(:name => "Cell Level Style Overrides") do |sheet|
57
57
  end
58
58
  #```
59
59
 
60
- #Using Custom Border Styles
60
+ ##Using Custom Border Styles
61
61
 
62
62
  #```ruby
63
63
  #Axlsx defines a thin border style, but you can easily create and use your own.
@@ -97,7 +97,6 @@ wb.styles do |s|
97
97
  #Set the second column outline level
98
98
  sheet.column_info[1].outlineLevel = 2
99
99
 
100
- #TODO rows hidden, outline etc.
101
100
  sheet.rows[3].hidden = true
102
101
  sheet.rows[1].outlineLevel = 2
103
102
  end
@@ -211,12 +210,9 @@ end
211
210
  #```ruby
212
211
  wb.add_worksheet(:name => "Bar Chart") do |sheet|
213
212
  sheet.add_row ["A Simple Bar Chart"]
214
- sheet.add_row ["First", "Second", "Third"]
215
- sheet.add_row [1, 2, 3]
216
- sheet.add_chart(Axlsx::Bar3DChart, :start_at => "A4", :end_at => "F17") do |chart|
217
- chart.add_series :data => sheet["A3:C3"], :labels => sheet["A2:C2"], :title => sheet["A1"]
218
- chart.valAxis.label_rotation = -45
219
- chart.catAxis.label_rotation = 45
213
+ %w(first second third).each { |label| sheet.add_row [label, rand(24)+1] }
214
+ sheet.add_chart(Axlsx::Bar3DChart, :start_at => "A6", :end_at => "F20") do |chart|
215
+ chart.add_series :data => sheet["B2:B4"], :labels => sheet["A2:A4"], :title => sheet["A1"]
220
216
  end
221
217
  end
222
218
  #```
@@ -225,11 +221,10 @@ end
225
221
 
226
222
  #```ruby
227
223
  wb.add_worksheet(:name => "Chart With No Gridlines") do |sheet|
228
- sheet.add_row ["A Simple Bar Chart"]
229
- sheet.add_row ["First", "Second", "Third"]
230
- sheet.add_row [1, 2, 3]
231
- sheet.add_chart(Axlsx::Bar3DChart, :start_at => "A4", :end_at => "F17") do |chart|
232
- chart.add_series :data => sheet["A3:C3"], :labels => sheet["A2:C2"], :title => sheet["A1"]
224
+ sheet.add_row ["Bar Chart without gridlines"]
225
+ %w(first second third).each { |label| sheet.add_row [label, rand(24)+1] }
226
+ sheet.add_chart(Axlsx::Bar3DChart, :start_at => "A6", :end_at => "F20") do |chart|
227
+ chart.add_series :data => sheet["B2:B4"], :labels => sheet["A2:A4"]
233
228
  chart.valAxis.gridlines = false
234
229
  chart.catAxis.gridlines = false
235
230
  end
@@ -240,28 +235,10 @@ end
240
235
 
241
236
  #```ruby
242
237
  wb.add_worksheet(:name => "Pie Chart") do |sheet|
243
- sheet.add_row ["First", "Second", "Third", "Fourth"]
244
- sheet.add_row [1, 2, 3, "=PRODUCT(A2:C2)"]
245
- sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,2], :end_at => [5, 15], :title => "example 3: Pie Chart") do |chart|
246
- chart.add_series :data => sheet["A2:D2"], :labels => sheet["A1:D1"]
247
- end
248
- end
249
- #```
250
-
251
- ##Data over time
252
-
253
- #```ruby
254
- wb.add_worksheet(:name=>'Charting Dates') do |sheet|
255
- # cell level style overides when adding cells
256
- sheet.add_row ['Date', 'Value'], :sz => 16
257
- sheet.add_row [Time.now - (7*60*60*24), 3]
258
- sheet.add_row [Time.now - (6*60*60*24), 7]
259
- sheet.add_row [Time.now - (5*60*60*24), 18]
260
- sheet.add_row [Time.now - (4*60*60*24), 1]
261
- sheet.add_chart(Axlsx::Bar3DChart) do |chart|
262
- chart.start_at "B7"
263
- chart.end_at "H27"
264
- chart.add_series(:data => sheet["B2:B5"], :labels => sheet["A2:A5"], :title => sheet["B1"])
238
+ sheet.add_row ["Simple Pie Chart"]
239
+ %w(first second third).each { |label| sheet.add_row [label, rand(24)+1] }
240
+ sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,5], :end_at => [10, 20], :title => "example 3: Pie Chart") do |chart|
241
+ chart.add_series :data => sheet["B2:B4"], :labels => sheet["A2:A4"], :colors => ['FF0000', '00FF00', '0000FF']
265
242
  end
266
243
  end
267
244
  #```
@@ -270,13 +247,18 @@ end
270
247
 
271
248
  #```ruby
272
249
  wb.add_worksheet(:name => "Line Chart") do |sheet|
273
- sheet.add_row ["First", 1, 5, 7, 9]
274
- sheet.add_row ["Second", 5, 2, 14, 9]
275
- sheet.add_chart(Axlsx::Line3DChart, :title => "example 6: Line Chart", :rotX => 30, :rotY => 20) do |chart|
276
- chart.start_at 0, 2
277
- chart.end_at 10, 15
278
- chart.add_series :data => sheet["B1:E1"], :title => sheet["A1"]
279
- chart.add_series :data => sheet["B2:E2"], :title => sheet["A2"]
250
+ sheet.add_row ["Simple Line Chart"]
251
+ sheet.add_row %w(first second)
252
+ 4.times do
253
+ sheet.add_row [ rand(24)+1, rand(24)+1]
254
+ end
255
+ sheet.add_chart(Axlsx::Line3DChart, :title => "Simple Line Chart", :rotX => 30, :rotY => 20) do |chart|
256
+ chart.start_at 0, 5
257
+ chart.end_at 10, 20
258
+ chart.add_series :data => sheet["A3:A6"], :title => sheet["A2"]
259
+ chart.add_series :data => sheet["B3:B6"], :title => sheet["B2"]
260
+ chart.catAxis.title = 'X Axis'
261
+ chart.valAxis.title = 'Y Axis'
280
262
  end
281
263
  end
282
264
  #```
@@ -320,7 +302,7 @@ wb.add_worksheet(:name => "fit to page") do |sheet|
320
302
  sheet.add_row ['this all goes on one page']
321
303
  sheet.fit_to_page = true
322
304
  end
323
- #```
305
+ ##```
324
306
 
325
307
 
326
308
  ##Hide Gridlines in worksheet
@@ -330,18 +312,119 @@ wb.add_worksheet(:name => "No Gridlines") do |sheet|
330
312
  sheet.add_row ["This", "Sheet", "Hides", "Gridlines"]
331
313
  sheet.show_gridlines = false
332
314
  end
333
- #```
315
+ ##```
334
316
 
317
+ #```ruby
318
+ wb.add_worksheet(:name => "repeated header") do |sheet|
319
+ sheet.add_row %w(These Column Header Will Render On Every Printed Sheet)
320
+ 200.times { sheet.add_row %w(1 2 3 4 5 6 7 8) }
321
+ wb.add_defined_name("'repeated header'!$1:$1", :local_sheet_id => sheet.index, :name => '_xlnm.Print_Titles')
322
+ end
335
323
 
336
- ##Specify Page Margins for printing
324
+ # Sheet Protection and excluding cells from locking.
325
+ unlocked = wb.styles.add_style :locked => false
326
+ wb.add_worksheet(:name => 'Sheet Protection') do |sheet|
327
+ sheet.sheet_protection.password = 'fish'
328
+ sheet.add_row [1, 2 ,3] # These cells will be locked
329
+ sheet.add_row [4, 5, 6], :style => unlocked # these cells will not!
330
+ end
331
+
332
+
333
+ ##Specify page margins and other options for printing
337
334
 
338
335
  #```ruby
339
336
  margins = {:left => 3, :right => 3, :top => 1.2, :bottom => 1.2, :header => 0.7, :footer => 0.7}
340
- wb.add_worksheet(:name => "print margins", :page_margins => margins) do |sheet|
341
- sheet.add_row ["this sheet uses customized page margins for printing"]
337
+ setup = {:fit_to_width => 1, :orientation => :landscape, :paper_width => "297mm", :paper_height => "210mm"}
338
+ options = {:grid_lines => true, :headings => true, :horizontal_centered => true}
339
+ wb.add_worksheet(:name => "print margins", :page_margins => margins, :page_setup => setup, :print_options => options) do |sheet|
340
+ sheet.add_row ["this sheet uses customized print settings"]
342
341
  end
343
342
  #```
344
343
 
344
+ ## Add Comments to your spreadsheet
345
+ #``` ruby
346
+ wb.add_worksheet(:name => 'comments') do |sheet|
347
+ sheet.add_row ['Can we build it?']
348
+ sheet.add_comment :ref => 'A1', :author => 'Bob', :text => 'Yes We Can!'
349
+ end
350
+
351
+ ## Frozen/Split panes
352
+ ## ``` ruby
353
+ wb.add_worksheet(:name => 'fixed headers') do |sheet|
354
+ sheet.add_row(['', (0..99).map { |i| "column header #{i}" }].flatten )
355
+ 100.times.with_index { |index| sheet << ["row header", (0..index).to_a].flatten }
356
+ sheet.sheet_view.pane do |pane|
357
+ pane.top_left_cell = "B2"
358
+ pane.state = :frozen_split
359
+ pane.y_split = 1
360
+ pane.x_split = 1
361
+ pane.active_pane = :bottom_right
362
+ end
363
+ end
364
+
365
+ # conditional formatting
366
+ #
367
+ percent = wb.styles.add_style(:format_code => "0.00%", :border => Axlsx::STYLE_THIN_BORDER)
368
+ money = wb.styles.add_style(:format_code => '0,000', :border => Axlsx::STYLE_THIN_BORDER)
369
+
370
+ # define the style for conditional formatting
371
+ profitable = wb.styles.add_style( :fg_color=>"FF428751",
372
+ :type => :dxf)
373
+
374
+ wb.add_worksheet(:name => "Conditional Cell Is") do |ws|
375
+
376
+ # Generate 20 rows of data
377
+ ws.add_row ["Previous Year Quarterly Profits (JPY)"]
378
+ ws.add_row ["Quarter", "Profit", "% of Total"]
379
+ offset = 3
380
+ rows = 20
381
+ offset.upto(rows + offset) do |i|
382
+ ws.add_row ["Q#{i}", 10000*((rows/2-i) * (rows/2-i)), "=100*B#{i}/SUM(B3:B#{rows+offset})"], :style=>[nil, money, percent]
383
+ end
384
+
385
+ # Apply conditional formatting to range B3:B100 in the worksheet
386
+ ws.add_conditional_formatting("B3:B100", { :type => :cellIs, :operator => :greaterThan, :formula => "100000", :dxfId => profitable, :priority => 1 })
387
+ end
388
+
389
+ wb.add_worksheet(:name => "Conditional Color Scale") do |ws|
390
+ ws.add_row ["Previous Year Quarterly Profits (JPY)"]
391
+ ws.add_row ["Quarter", "Profit", "% of Total"]
392
+ offset = 3
393
+ rows = 20
394
+ offset.upto(rows + offset) do |i|
395
+ ws.add_row ["Q#{i}", 10000*((rows/2-i) * (rows/2-i)), "=100*B#{i}/SUM(B3:B#{rows+offset})"], :style=>[nil, money, percent]
396
+ end
397
+ # Apply conditional formatting to range B3:B100 in the worksheet
398
+ color_scale = Axlsx::ColorScale.new
399
+ ws.add_conditional_formatting("B3:B100", { :type => :colorScale, :operator => :greaterThan, :formula => "100000", :dxfId => profitable, :priority => 1, :color_scale => color_scale })
400
+ end
401
+
402
+
403
+ wb.add_worksheet(:name => "Conditional Data Bar") do |ws|
404
+ ws.add_row ["Previous Year Quarterly Profits (JPY)"]
405
+ ws.add_row ["Quarter", "Profit", "% of Total"]
406
+ offset = 3
407
+ rows = 20
408
+ offset.upto(rows + offset) do |i|
409
+ ws.add_row ["Q#{i}", 10000*((rows/2-i) * (rows/2-i)), "=100*B#{i}/SUM(B3:B#{rows+offset})"], :style=>[nil, money, percent]
410
+ end
411
+ # Apply conditional formatting to range B3:B100 in the worksheet
412
+ data_bar = Axlsx::DataBar.new
413
+ ws.add_conditional_formatting("B3:B100", { :type => :dataBar, :dxfId => profitable, :priority => 1, :data_bar => data_bar })
414
+ end
415
+
416
+ wb.add_worksheet(:name => "Conditional Format Icon Set") do |ws|
417
+ ws.add_row ["Previous Year Quarterly Profits (JPY)"]
418
+ ws.add_row ["Quarter", "Profit", "% of Total"]
419
+ offset = 3
420
+ rows = 20
421
+ offset.upto(rows + offset) do |i|
422
+ ws.add_row ["Q#{i}", 10000*((rows/2-i) * (rows/2-i)), "=100*B#{i}/SUM(B3:B#{rows+offset})"], :style=>[nil, money, percent]
423
+ end
424
+ # Apply conditional formatting to range B3:B100 in the worksheet
425
+ icon_set = Axlsx::IconSet.new
426
+ ws.add_conditional_formatting("B3:B100", { :type => :iconSet, :dxfId => profitable, :priority => 1, :icon_set => icon_set })
427
+ end
345
428
 
346
429
  ##Validate and Serialize
347
430
 
Binary file
Binary file
Binary file
@@ -13,6 +13,7 @@ data = [ ['oil-bbl',9591.411671,8860.714604,8237.936509,7700.523067,7231.831842,
13
13
  p = Axlsx::Package.new
14
14
  wb = p.workbook
15
15
  wb.add_worksheet(:name => 'volumes') do |ws|
16
+
16
17
  # perspective, rotX and rotY flatten the 3D chart
17
18
  # hPercent sets the chart height to 100%
18
19
  chart = ws.add_chart(Axlsx::Line3DChart, :perspective => 0, :hPercent => 100, :rotX => 0, :rotY => 0, :start_at => "A4", :end_at => 'M44', :title => 'Monthly forcast for Type Curve Gas secondary - gross ngl')
@@ -27,12 +28,14 @@ wb.add_worksheet(:name => 'volumes') do |ws|
27
28
 
28
29
  # Knock the catAxis labels down to the forced min.
29
30
  chart.catAxis.crosses = :min
31
+
30
32
  # set up cat labels / markes to show every 12th item
31
33
  chart.catAxis.tickLblSkip = 12
32
34
  chart.catAxis.tickMarkSkip = 12
33
35
 
34
36
  #rgb colors for our data series
35
37
  colors = ['00FF00', 'FF0000', '0000FF']
38
+
36
39
  data.each_with_index do |value, index|
37
40
  ws.add_row value
38
41
  chart.add_series :data => ws.rows.last.cells[(1..value.size-1)], :labels => (0..value.size).map{ |i| i }, :title => ws.rows.last.cells.first, :color => colors[index]
Binary file
@@ -0,0 +1,91 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+ require 'axlsx'
5
+
6
+ class Scraper
7
+
8
+ def initialize(url, selector)
9
+ @url = url
10
+ @selector = selector
11
+ end
12
+
13
+ def hooks
14
+ @hooks ||= {}
15
+ end
16
+
17
+ def add_hook(clue, p_roc)
18
+ hooks[clue] = p_roc
19
+ end
20
+
21
+ def export(file_name)
22
+ Scraper.clues.each do |clue|
23
+ if detail = parse_clue(clue)
24
+ output << [clue, detail.pop]
25
+ detail.each { |datum| output << ['', datum] }
26
+ end
27
+ end
28
+ serialize(file_name)
29
+ end
30
+
31
+ private
32
+
33
+ def self.clues
34
+ @clues ||= ['Operating system', 'Processors', 'Chipset', 'Memory type', 'Hard drive', 'Graphics',
35
+ 'Ports', 'Webcam', 'Pointing device', 'Keyboard', 'Network interface', 'Chipset', 'Wireless',
36
+ 'Power supply type', 'Energy efficiency', 'Weight', 'Minimum dimensions (W x D x H)',
37
+ 'Warranty', 'Software included', 'Product color']
38
+ end
39
+
40
+ def doc
41
+ @doc ||= begin
42
+ Nokogiri::HTML(open(@url))
43
+ rescue
44
+ raise ArgumentError, 'Invalid URL - Nothing to parse'
45
+ end
46
+ end
47
+
48
+ def output
49
+ @output ||= []
50
+ end
51
+
52
+ def selector_for_clue(clue)
53
+ @selector % clue
54
+ end
55
+
56
+ def parse_clue(clue)
57
+ if element = doc.at(selector_for_clue(clue))
58
+ call_hook(clue, element) || element.inner_html.split('<br>').each(&:strip)
59
+ end
60
+ end
61
+
62
+ def call_hook(clue, element)
63
+ if hooks[clue].is_a? Proc
64
+ value = hooks[clue].call(element)
65
+ value.is_a?(Array) ? value : [value]
66
+ end
67
+ end
68
+
69
+ def package
70
+ @package ||= Axlsx::Package.new
71
+ end
72
+
73
+ def serialize(file_name)
74
+ package.workbook.add_worksheet do |sheet|
75
+ output.each { |datum| sheet.add_row datum }
76
+ end
77
+ package.serialize(file_name)
78
+ end
79
+ end
80
+
81
+ scraper = Scraper.new("http://h10010.www1.hp.com/wwpc/ie/en/ho/WF06b/321957-321957-3329742-89318-89318-5186820-5231694.html?dnr=1", "//td[text()='%s']/following-sibling::td")
82
+
83
+ # define a custom action to take against any elements found.
84
+ os_parse = Proc.new do |element|
85
+ element.inner_html.split('<br>').each(&:strip!).each(&:upcase!)
86
+ end
87
+
88
+ scraper.add_hook('Operating system', os_parse)
89
+
90
+ scraper.export('foo.xlsx')
91
+
Binary file
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby -w -s
2
+ # -*- coding: utf-8 -*-
3
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
4
+ require 'axlsx'
5
+
6
+ p = Axlsx::Package.new
7
+ p.workbook.add_worksheet(:name => 'Open Office') { |ws| ws.sheet_protection.password = 'fish' }
8
+ p.serialize 'sheet_protection.xlsx'
9
+
10
+
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby -w -s
2
+ # -*- coding: utf-8 -*-
3
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
4
+ require 'axlsx'
5
+
6
+ p = Axlsx::Package.new
7
+ ws = p.workbook.add_worksheet :name => "Sheetview - Split"
8
+ ws.sheet_view do |vs|
9
+ vs.pane do |p|
10
+ p.active_pane = :top_right
11
+ p.state = :split
12
+ p.x_split = 11080
13
+ p.y_split = 5000
14
+ p.top_left_cell = 'C44'
15
+ end
16
+
17
+ vs.add_selection(:top_left, { :active_cell => 'A2', :sqref => 'A2' })
18
+ vs.add_selection(:top_right, { :active_cell => 'I10', :sqref => 'I10' })
19
+ vs.add_selection(:bottom_left, { :active_cell => 'E55', :sqref => 'E55' })
20
+ vs.add_selection(:bottom_right, { :active_cell => 'I57', :sqref => 'I57' })
21
+ end
22
+
23
+
24
+ ws = p.workbook.add_worksheet :name => "Sheetview - Frozen"
25
+ ws.sheet_view do |vs|
26
+ vs.pane do |p|
27
+ p.state = :frozen
28
+ p.x_split = 3
29
+ p.y_split = 4
30
+ end
31
+ end
32
+
33
+
34
+ p.serialize 'sheet_view.xlsx'
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby -w -s
2
+ # -*- coding: utf-8 -*-
3
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
4
+ require 'axlsx'
5
+
6
+ p = Axlsx::Package.new
7
+ src = "#{File.dirname(__FILE__)}/image1.png"
8
+ p.workbook.add_worksheet(:name => 'double_anchor') do |ws|
9
+ ws.add_image(:image_src => src, :start_at => [0,0], :end_at => [2,4])
10
+ end
11
+ p.serialize('two_cell_anchor_image.xlsx')
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
+
3
4
  require 'axlsx/content_type/default.rb'
4
5
  require 'axlsx/content_type/override.rb'
5
6
 
@@ -21,4 +22,5 @@ module Axlsx
21
22
  end
22
23
 
23
24
  end
25
+
24
26
  end
@@ -1,41 +1,56 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
+
3
4
  # An default content part. These parts are automatically created by for you based on the content of your package.
4
5
  class Default
5
6
 
7
+ #Creates a new Default object
8
+ # @option options [String] extension
9
+ # @option options [String] content_type
10
+ # @raise [ArgumentError] An argument error is raised if both extension and content_type are not specified.
11
+ def initialize(options={})
12
+ raise ArgumentError, INVALID_ARGUMENTS unless validate_options(options)
13
+ options.each do |name, value|
14
+ self.send("#{name}=", value) if self.respond_to? "#{name}="
15
+ end
16
+ end
17
+
18
+ # Error string for option validation
19
+ INVALID_ARGUMENTS = "extension and content_type are required"
20
+
6
21
  # The extension of the content type.
7
22
  # @return [String]
8
- attr_reader :Extension
23
+ attr_reader :extension
24
+ alias :Extension :extension
9
25
 
10
26
  # The type of content.
11
27
  # @return [String]
12
- attr_reader :ContentType
28
+ attr_reader :content_type
29
+ alias :ContentType :content_type
13
30
 
14
- #Creates a new Default object
15
- # @option options [String] Extension
16
- # @option options [String] ContentType
17
- # @raise [ArgumentError] An argument error is raised if both Extension and ContentType are not specified.
18
- def initialize(options={})
19
- raise ArgumentError, "Extension and ContentType are required" unless options[:Extension] && options[:ContentType]
20
- options.each do |o|
21
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
22
- end
23
- end
24
31
  # Sets the file extension for this content type.
25
- def Extension=(v) Axlsx::validate_string v; @Extension = v end
32
+ def extension=(v) Axlsx::validate_string v; @extension = v end
33
+ alias :Extension= :extension=
26
34
 
27
35
  # Sets the content type
28
36
  # @see Axlsx#validate_content_type
29
- def ContentType=(v) Axlsx::validate_content_type v; @ContentType = v end
37
+ def content_type=(v) Axlsx::validate_content_type v; @content_type = v end
38
+ alias :ContentType= :content_type=
30
39
 
31
40
  # Serializes the object
32
41
  # @param [String] str
33
42
  # @return [String]
34
43
  def to_xml_string(str = '')
35
44
  str << '<Default '
36
- str << instance_values.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
45
+ str << instance_values.map { |key, value| '' << Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ')
37
46
  str << '/>'
38
47
  end
39
48
 
49
+ private
50
+ def validate_options(options)
51
+ (options[:Extension] || options[:extension]) && (options[:content_type] || options[:ContentType])
52
+ end
53
+
40
54
  end
55
+
41
56
  end
@@ -1,42 +1,57 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
+
3
4
  # An override content part. These parts are automatically created by for you based on the content of your package.
4
5
  class Override
5
6
 
6
- # The type of content.
7
- # @return [String]
8
- attr_reader :ContentType
9
-
10
- # The name and location of the part.
11
- # @return [String]
12
- attr_reader :PartName
13
-
14
7
  #Creates a new Override object
15
8
  # @option options [String] PartName
16
9
  # @option options [String] ContentType
17
10
  # @raise [ArgumentError] An argument error is raised if both PartName and ContentType are not specified.
18
11
  def initialize(options={})
19
- raise ArgumentError, "PartName and ContentType are required" unless options[:PartName] && options[:ContentType]
20
- options.each do |o|
21
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
12
+ raise ArgumentError, INVALID_ARGUMENTS unless validate_options(options)
13
+ options.each do |name, value|
14
+ self.send("#{name}=", value) if self.respond_to? "#{name}="
22
15
  end
23
16
  end
24
17
 
18
+ # Error message for invalid options
19
+ INVALID_ARGUMENTS = 'part_name and content_type are required'
20
+
21
+ # The type of content.
22
+ # @return [String]
23
+ attr_reader :content_type
24
+ alias :ContentType :content_type
25
+
26
+ # The name and location of the part.
27
+ # @return [String]
28
+ attr_reader :part_name
29
+ alias :PartName :part_name
30
+
25
31
  # The name and location of the part.
26
- def PartName=(v) Axlsx::validate_string v; @PartName = v end
32
+ def part_name=(v) Axlsx::validate_string v; @part_name = v end
33
+ alias :PartName= :part_name=
27
34
 
28
35
  # The content type.
29
36
  # @see Axlsx#validate_content_type
30
- def ContentType=(v) Axlsx::validate_content_type v; @ContentType = v end
37
+ def content_type=(v) Axlsx::validate_content_type v; @content_type = v end
38
+ alias :ContentType= :content_type=
31
39
 
32
40
  # Serializes the object
33
41
  # @param [String] str
34
42
  # @return [String]
35
43
  def to_xml_string(str = '')
36
44
  str << '<Override '
37
- str << instance_values.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
45
+ str << instance_values.map { |key, value| '' << Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ')
38
46
  str << '/>'
39
47
  end
40
48
 
49
+ private
50
+
51
+ def validate_options(options)
52
+ (options[:PartName] || options[:part_name]) && (options[:ContentType] || options[:content_type])
53
+ end
54
+
41
55
  end
56
+
42
57
  end