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.
- data/.yardopts +5 -2
- data/CHANGELOG.md +39 -0
- data/README.md +108 -31
- data/Rakefile +11 -3
- data/examples/basic_charts.rb +54 -0
- data/examples/chart_colors.rb +17 -2
- data/examples/data_validation.rb +50 -0
- data/examples/example.rb +130 -47
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/extractive.pdf +0 -0
- data/examples/extractive.rb +3 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/scraping_html.rb +91 -0
- data/examples/shared_strings_example.xlsx +0 -0
- data/examples/sheet_protection.rb +10 -0
- data/examples/sheet_view.rb +34 -0
- data/examples/two_cell_anchor_image.rb +11 -0
- data/lib/axlsx/content_type/content_type.rb +2 -0
- data/lib/axlsx/content_type/default.rb +30 -15
- data/lib/axlsx/content_type/override.rb +29 -14
- data/lib/axlsx/doc_props/app.rb +161 -104
- data/lib/axlsx/doc_props/core.rb +9 -5
- data/lib/axlsx/drawing/ax_data_source.rb +7 -6
- data/lib/axlsx/drawing/axis.rb +82 -36
- data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
- data/lib/axlsx/drawing/bar_series.rb +2 -1
- data/lib/axlsx/drawing/cat_axis.rb +43 -39
- data/lib/axlsx/drawing/chart.rb +65 -54
- data/lib/axlsx/drawing/d_lbls.rb +100 -0
- data/lib/axlsx/drawing/drawing.rb +20 -8
- data/lib/axlsx/drawing/graphic_frame.rb +2 -1
- data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
- data/lib/axlsx/drawing/num_data.rb +2 -2
- data/lib/axlsx/drawing/num_data_source.rb +4 -1
- data/lib/axlsx/drawing/pic.rb +44 -4
- data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
- data/lib/axlsx/drawing/scatter_chart.rb +2 -8
- data/lib/axlsx/drawing/title.rb +21 -9
- data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
- data/lib/axlsx/drawing/view_3D.rb +41 -31
- data/lib/axlsx/drawing/vml_drawing.rb +42 -0
- data/lib/axlsx/drawing/vml_shape.rb +125 -0
- data/lib/axlsx/package.rb +44 -16
- data/lib/axlsx/rels/relationship.rb +3 -3
- data/lib/axlsx/rels/relationships.rb +1 -11
- data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +1 -1
- data/lib/axlsx/stylesheet/table_style.rb +3 -3
- data/lib/axlsx/util/constants.rb +28 -0
- data/lib/axlsx/util/simple_typed_list.rb +15 -21
- data/lib/axlsx/util/validators.rb +80 -7
- data/lib/axlsx/version.rb +2 -7
- data/lib/axlsx/workbook/defined_name.rb +174 -0
- data/lib/axlsx/workbook/defined_names.rb +21 -0
- data/lib/axlsx/workbook/workbook.rb +65 -13
- data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +35 -7
- data/lib/axlsx/workbook/worksheet/col.rb +15 -0
- data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
- data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
- data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
- data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
- data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
- data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
- data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
- data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
- data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
- data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
- data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
- data/lib/axlsx/workbook/worksheet/row.rb +36 -20
- data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
- data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
- data/lib/axlsx/workbook/worksheet/table.rb +2 -2
- data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +377 -255
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
- data/lib/axlsx.rb +30 -15
- data/test/content_type/tc_content_type.rb +1 -6
- data/test/doc_props/tc_app.rb +31 -1
- data/test/doc_props/tc_core.rb +3 -1
- data/test/drawing/tc_axis.rb +38 -3
- data/test/drawing/tc_bar_3D_chart.rb +12 -12
- data/test/drawing/tc_bar_series.rb +1 -2
- data/test/drawing/tc_cat_axis.rb +3 -3
- data/test/drawing/tc_chart.rb +29 -9
- data/test/drawing/tc_d_lbls.rb +47 -0
- data/test/drawing/tc_drawing.rb +11 -5
- data/test/drawing/tc_hyperlink.rb +4 -5
- data/test/drawing/tc_line_series.rb +7 -3
- data/test/drawing/tc_num_data.rb +5 -1
- data/test/drawing/tc_pic.rb +22 -2
- data/test/drawing/tc_pie_3D_chart.rb +4 -8
- data/test/drawing/tc_pie_series.rb +7 -2
- data/test/drawing/tc_scatter_chart.rb +6 -1
- data/test/drawing/tc_scatter_series.rb +1 -1
- data/test/drawing/tc_series.rb +1 -1
- data/test/drawing/tc_title.rb +16 -0
- data/test/drawing/tc_two_cell_anchor.rb +1 -2
- data/test/drawing/tc_view_3D.rb +18 -18
- data/test/drawing/tc_vml_drawing.rb +25 -0
- data/test/drawing/tc_vml_shape.rb +100 -0
- data/test/rels/tc_relationship.rb +1 -0
- data/test/stylesheet/tc_gradient_fill.rb +8 -0
- data/test/stylesheet/tc_pattern_fill.rb +7 -1
- data/test/stylesheet/tc_styles.rb +3 -4
- data/test/stylesheet/tc_table_style.rb +8 -0
- data/test/stylesheet/tc_table_style_element.rb +10 -1
- data/test/tc_helper.rb +1 -0
- data/test/tc_package.rb +93 -17
- data/test/util/tc_simple_typed_list.rb +13 -0
- data/test/util/tc_validators.rb +95 -9
- data/test/workbook/tc_defined_name.rb +41 -0
- data/test/workbook/tc_workbook.rb +5 -3
- data/test/workbook/worksheet/table/tc_table.rb +3 -11
- data/test/workbook/worksheet/tc_cell.rb +30 -6
- data/test/workbook/worksheet/tc_col.rb +9 -0
- data/test/workbook/worksheet/tc_comment.rb +57 -0
- data/test/workbook/worksheet/tc_comments.rb +57 -0
- data/test/workbook/worksheet/tc_conditional_formatting.rb +44 -0
- data/test/workbook/worksheet/tc_data_bar.rb +1 -1
- data/test/workbook/worksheet/tc_data_validation.rb +265 -0
- data/test/workbook/worksheet/tc_page_setup.rb +138 -0
- data/test/workbook/worksheet/tc_pane.rb +94 -0
- data/test/workbook/worksheet/tc_print_options.rb +72 -0
- data/test/workbook/worksheet/tc_protected_range.rb +17 -0
- data/test/workbook/worksheet/tc_row.rb +32 -14
- data/test/workbook/worksheet/tc_selection.rb +94 -0
- data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
- data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
- data/test/workbook/worksheet/tc_worksheet.rb +138 -48
- metadata +140 -80
- data/examples/#extractive.csv# +0 -0
- data/examples/#extractive.rb# +0 -45
- data/examples/chart_colors.rb~ +0 -0
- data/examples/chart_colors.xlsx +0 -0
- data/examples/colored_series_data.xlsx +0 -0
- data/examples/conditional_formatting/getting_barred.xlsx +0 -0
- data/examples/example.csv +0 -1000
- data/examples/extractive.csv +0 -1
- data/examples/extractive.csv~ +0 -1
- data/examples/extractive.rb~ +0 -3
- data/examples/extractive.xlsx +0 -0
- data/examples/stack.rb +0 -21
- data/examples/stack.rb~ +0 -27
- data/examples/stack.xlsx +0 -0
- data/examples/~$chart_colors.xlsx +0 -0
- data/examples/~$extractive.xlsx +0 -0
- data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
- data/lib/axlsx/drawing/data_source.rb~ +0 -51
- data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
- data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
- data/lib/axlsx/drawing/num_data.rb~ +0 -51
- data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
- data/lib/axlsx/drawing/num_val.rb~ +0 -40
- data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
- data/lib/axlsx/drawing/ref.rb~ +0 -41
- data/lib/axlsx/drawing/str_data.rb~ +0 -58
- data/lib/axlsx/drawing/str_val.rb~ +0 -35
- data/lib/axlsx/util/cbf.rb +0 -333
- data/lib/axlsx/util/cfb.rb~ +0 -201
- data/lib/axlsx/util/font_tables.rb~ +0 -0
- data/lib/axlsx/util/ms_off_crypto.rb +0 -189
- data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
- data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
- data/lib/axlsx/util/parser.rb~ +0 -6
- data/lib/axlsx/util/storage.rb~ +0 -0
- data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
- data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
- data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
- data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
- data/lib/schema/dc.xsd~ +0 -118
- data/lib/schema/dcterms.xsd~ +0 -331
- data/lib/schema/opc-coreProperties.xsd~ +0 -50
- data/test/drawing/tc_data_source.rb~ +0 -30
- data/test/drawing/tc_num_data.rb~ +0 -35
- data/test/drawing/tc_num_val.rb~ +0 -29
- data/test/drawing/tc_str_data.rb~ +0 -30
- data/test/drawing/tc_str_val.rb~ +0 -26
- data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
- data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
- data/test/workbook/worksheet/tc_col.rb~ +0 -10
- data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
- data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
- 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
|
-
|
|
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 [
|
|
215
|
-
sheet.
|
|
216
|
-
|
|
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 ["
|
|
229
|
-
sheet.add_row [
|
|
230
|
-
sheet.
|
|
231
|
-
|
|
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 ["
|
|
244
|
-
sheet.add_row [
|
|
245
|
-
sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,
|
|
246
|
-
chart.add_series :data => sheet["
|
|
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 ["
|
|
274
|
-
sheet.add_row
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
chart.
|
|
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
|
-
|
|
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
|
-
|
|
341
|
-
|
|
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
|
|
data/examples/example.xlsx
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/examples/extractive.rb
CHANGED
|
@@ -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,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 :
|
|
23
|
+
attr_reader :extension
|
|
24
|
+
alias :Extension :extension
|
|
9
25
|
|
|
10
26
|
# The type of content.
|
|
11
27
|
# @return [String]
|
|
12
|
-
attr_reader :
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
20
|
-
options.each do |
|
|
21
|
-
self.send("#{
|
|
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
|
|
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
|
|
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
|
|
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
|