axlsx 1.1.3 → 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 +60 -0
- data/LICENSE +1 -1
- data/README.md +115 -415
- data/Rakefile +11 -3
- data/examples/basic_charts.rb +54 -0
- data/examples/chart_colors.rb +88 -0
- data/examples/data_validation.rb +50 -0
- data/examples/example.rb +299 -155
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/extractive.pdf +0 -0
- data/examples/extractive.rb +45 -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 +26 -0
- data/lib/axlsx/drawing/axis.rb +92 -37
- data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
- data/lib/axlsx/drawing/bar_series.rb +25 -7
- data/lib/axlsx/drawing/cat_axis.rb +50 -22
- data/lib/axlsx/drawing/chart.rb +69 -56
- data/lib/axlsx/drawing/d_lbls.rb +100 -0
- data/lib/axlsx/drawing/drawing.rb +28 -12
- data/lib/axlsx/drawing/graphic_frame.rb +2 -1
- data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
- data/lib/axlsx/drawing/line_series.rb +20 -4
- data/lib/axlsx/drawing/num_data.rb +52 -0
- data/lib/axlsx/drawing/num_data_source.rb +61 -0
- data/lib/axlsx/drawing/num_val.rb +32 -0
- data/lib/axlsx/drawing/pic.rb +44 -4
- data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
- data/lib/axlsx/drawing/pie_series.rb +18 -4
- data/lib/axlsx/drawing/scatter_chart.rb +2 -8
- data/lib/axlsx/drawing/scatter_series.rb +28 -2
- data/lib/axlsx/drawing/ser_axis.rb +1 -1
- data/lib/axlsx/drawing/series.rb +1 -1
- data/lib/axlsx/drawing/str_data.rb +42 -0
- data/lib/axlsx/drawing/str_val.rb +33 -0
- 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 +44 -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 +81 -8
- 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 +17 -1
- 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 +67 -12
- 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 +3 -3
- 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 +17 -13
- data/test/drawing/tc_cat_axis.rb +3 -3
- data/test/drawing/tc_cat_axis_data.rb +23 -13
- data/test/drawing/tc_chart.rb +29 -11
- data/test/drawing/tc_d_lbls.rb +47 -0
- data/test/drawing/tc_data_source.rb +17 -0
- data/test/drawing/tc_drawing.rb +11 -5
- data/test/drawing/tc_hyperlink.rb +4 -5
- data/test/drawing/tc_line_series.rb +9 -11
- data/test/drawing/tc_named_axis_data.rb +27 -0
- data/test/drawing/tc_num_data.rb +31 -0
- data/test/drawing/tc_num_val.rb +29 -0
- 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 +11 -13
- data/test/drawing/tc_scatter_chart.rb +6 -1
- data/test/drawing/tc_scatter_series.rb +6 -5
- data/test/drawing/tc_series.rb +1 -1
- data/test/drawing/tc_str_data.rb +18 -0
- data/test/drawing/tc_str_val.rb +21 -0
- data/test/drawing/tc_title.rb +16 -0
- data/test/drawing/tc_two_cell_anchor.rb +2 -3
- 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 +36 -12
- 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 +164 -52
- data/examples/example.csv +0 -1000
- data/lib/axlsx/drawing/cat_axis_data.rb +0 -34
- data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
- data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
- data/lib/axlsx/drawing/named_axis_data.rb +0 -36
- data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
- data/lib/axlsx/drawing/val_axis_data.rb +0 -27
- 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_val_axis_data.rb +0 -17
- 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
|
@@ -1,71 +1,141 @@
|
|
|
1
1
|
#!/usr/bin/env ruby -w -s
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
|
3
|
+
# $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
|
4
|
+
|
|
5
|
+
#```ruby
|
|
4
6
|
require 'axlsx'
|
|
5
7
|
|
|
6
8
|
p = Axlsx::Package.new
|
|
7
9
|
wb = p.workbook
|
|
10
|
+
#```
|
|
8
11
|
|
|
9
12
|
#A Simple Workbook
|
|
10
13
|
|
|
14
|
+
#```ruby
|
|
11
15
|
wb.add_worksheet(:name => "Basic Worksheet") do |sheet|
|
|
12
16
|
sheet.add_row ["First Column", "Second", "Third"]
|
|
13
17
|
sheet.add_row [1, 2, 3]
|
|
14
18
|
end
|
|
19
|
+
#```
|
|
15
20
|
|
|
16
21
|
#Using Custom Styles
|
|
17
22
|
|
|
23
|
+
#```ruby
|
|
24
|
+
# Each cell allows a single, predified style.
|
|
25
|
+
# When using add_row, the value in the :style array at the same index as the cell's column will be applied to that cell.
|
|
26
|
+
# Alternatively, you can apply a style to an entire row by using an integer value for :style.
|
|
27
|
+
|
|
18
28
|
wb.styles do |s|
|
|
19
29
|
black_cell = s.add_style :bg_color => "00", :fg_color => "FF", :sz => 14, :alignment => { :horizontal=> :center }
|
|
20
30
|
blue_cell = s.add_style :bg_color => "0000FF", :fg_color => "FF", :sz => 20, :alignment => { :horizontal=> :center }
|
|
21
31
|
wb.add_worksheet(:name => "Custom Styles") do |sheet|
|
|
32
|
+
|
|
33
|
+
# Applies the black_cell style to the first and third cell, and the blue_cell style to the second.
|
|
22
34
|
sheet.add_row ["Text Autowidth", "Second", "Third"], :style => [black_cell, blue_cell, black_cell]
|
|
35
|
+
|
|
36
|
+
# Applies the thin border to all three cells
|
|
23
37
|
sheet.add_row [1, 2, 3], :style => Axlsx::STYLE_THIN_BORDER
|
|
24
38
|
end
|
|
25
39
|
end
|
|
40
|
+
#```
|
|
41
|
+
|
|
42
|
+
##Styling Cell Overrides
|
|
26
43
|
|
|
27
|
-
|
|
44
|
+
#```ruby
|
|
45
|
+
#Some of the style attributes can also be set at the cell level. Cell level styles take precedence over Custom Styles shown in the previous example.
|
|
46
|
+
|
|
47
|
+
wb.add_worksheet(:name => "Cell Level Style Overrides") do |sheet|
|
|
48
|
+
|
|
49
|
+
# this will set the font size for each cell.
|
|
50
|
+
sheet.add_row ['col 1', 'col 2', 'col 3', 'col 4'], :sz => 16
|
|
51
|
+
|
|
52
|
+
sheet.add_row [1, 2, 3, "=SUM(A2:C2)"]
|
|
28
53
|
|
|
54
|
+
# You can also apply cell style overrides to a range of cells
|
|
55
|
+
sheet["A1:D1"].each { |c| c.color = "FF0000" }
|
|
56
|
+
sheet['A1:D2'].each { |c| c.style = Axlsx::STYLE_THIN_BORDER }
|
|
57
|
+
end
|
|
58
|
+
#```
|
|
59
|
+
|
|
60
|
+
##Using Custom Border Styles
|
|
61
|
+
|
|
62
|
+
#```ruby
|
|
63
|
+
#Axlsx defines a thin border style, but you can easily create and use your own.
|
|
29
64
|
wb.styles do |s|
|
|
30
|
-
red_border = s.add_style :border => {:style
|
|
31
|
-
blue_border = s.add_style :border => {:style
|
|
65
|
+
red_border = s.add_style :border => { :style => :thick, :color =>"FFFF0000" }
|
|
66
|
+
blue_border = s.add_style :border => { :style => :thick, :color =>"FF0000FF" }
|
|
32
67
|
|
|
33
68
|
wb.add_worksheet(:name => "Custom Borders") do |sheet|
|
|
34
69
|
sheet.add_row ["wrap", "me", "Up in Red"], :style => red_border
|
|
35
70
|
sheet.add_row [1, 2, 3], :style => blue_border
|
|
36
71
|
end
|
|
37
72
|
end
|
|
73
|
+
#```
|
|
38
74
|
|
|
39
75
|
|
|
40
|
-
##
|
|
41
|
-
|
|
76
|
+
##Styling Rows and Columns
|
|
77
|
+
|
|
78
|
+
#```ruby
|
|
42
79
|
wb.styles do |s|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
sheet.add_row [
|
|
49
|
-
sheet.add_row [
|
|
80
|
+
head = s.add_style :bg_color => "00", :fg_color => "FF"
|
|
81
|
+
percent = s.add_style :num_fmt => 9
|
|
82
|
+
wb.add_worksheet(:name => "Columns and Rows") do |sheet|
|
|
83
|
+
sheet.add_row ['col 1', 'col 2', 'col 3', 'col 4', 'col5']
|
|
84
|
+
sheet.add_row [1, 2, 0.3, 4, 5.0]
|
|
85
|
+
sheet.add_row [1, 2, 0.2, 4, 5.0]
|
|
86
|
+
sheet.add_row [1, 2, 0.1, 4, 5.0]
|
|
87
|
+
|
|
88
|
+
#apply the percent style to the column at index 2 skipping the first row.
|
|
89
|
+
sheet.col_style 2, percent, :row_offset => 1
|
|
90
|
+
|
|
91
|
+
# apply the head style to the first row.
|
|
92
|
+
sheet.row_style 0, head
|
|
93
|
+
|
|
94
|
+
#Hide the 5th column
|
|
95
|
+
sheet.column_info[4].hidden = true
|
|
96
|
+
|
|
97
|
+
#Set the second column outline level
|
|
98
|
+
sheet.column_info[1].outlineLevel = 2
|
|
99
|
+
|
|
100
|
+
sheet.rows[3].hidden = true
|
|
101
|
+
sheet.rows[1].outlineLevel = 2
|
|
50
102
|
end
|
|
51
103
|
end
|
|
104
|
+
#```
|
|
52
105
|
|
|
53
106
|
|
|
54
|
-
##
|
|
107
|
+
##Specifying Column Widths
|
|
55
108
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
sheet.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
109
|
+
#```ruby
|
|
110
|
+
wb.add_worksheet(:name => "custom column widths") do |sheet|
|
|
111
|
+
sheet.add_row ["I use autowidth and am very wide", "I use a custom width and am narrow"]
|
|
112
|
+
sheet.add_row ['abcdefg', 'This is a very long text and should flow into the right cell', nil, 'xxx' ]
|
|
113
|
+
sheet.column_widths nil, 3, 5, nil
|
|
114
|
+
end
|
|
115
|
+
#```
|
|
116
|
+
|
|
117
|
+
##Merging Cells.
|
|
118
|
+
|
|
119
|
+
#```ruby
|
|
120
|
+
wb.add_worksheet(:name => 'Merging Cells') do |sheet|
|
|
121
|
+
# cell level style overides when adding cells
|
|
122
|
+
sheet.add_row ["col 1", "col 2", "col 3", "col 4"], :sz => 16
|
|
123
|
+
sheet.add_row [1, 2, 3, "=SUM(A2:C2)"]
|
|
124
|
+
sheet.add_row [2, 3, 4, "=SUM(A3:C3)"]
|
|
125
|
+
sheet.add_row ["total", "", "", "=SUM(D2:D3)"]
|
|
126
|
+
sheet.merge_cells("A4:C4")
|
|
127
|
+
sheet["A1:D1"].each { |c| c.color = "FF0000"}
|
|
128
|
+
sheet["A1:D4"].each { |c| c.style = Axlsx::STYLE_THIN_BORDER }
|
|
63
129
|
end
|
|
130
|
+
#```
|
|
64
131
|
|
|
65
132
|
##Add an Image with a hyperlink
|
|
66
133
|
|
|
134
|
+
#```ruby
|
|
67
135
|
wb.add_worksheet(:name => "Image with Hyperlink") do |sheet|
|
|
68
136
|
img = File.expand_path('../image1.jpeg', __FILE__)
|
|
137
|
+
# specifying the :hyperlink option will add a hyper link to your image.
|
|
138
|
+
# @note - Numbers does not support this part of the specification.
|
|
69
139
|
sheet.add_image(:image_src => img, :noSelect => true, :noMove => true, :hyperlink=>"http://axlsx.blogspot.com") do |image|
|
|
70
140
|
image.width=720
|
|
71
141
|
image.height=666
|
|
@@ -73,163 +143,129 @@ wb.add_worksheet(:name => "Image with Hyperlink") do |sheet|
|
|
|
73
143
|
image.start_at 2, 2
|
|
74
144
|
end
|
|
75
145
|
end
|
|
146
|
+
#```
|
|
76
147
|
|
|
77
|
-
##
|
|
78
|
-
|
|
79
|
-
wb.add_worksheet(:name => "日本語でのシート名") do |sheet|
|
|
80
|
-
sheet.add_row ["日本語"]
|
|
81
|
-
sheet.add_row ["华语/華語"]
|
|
82
|
-
sheet.add_row ["한국어/조선말"]
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
##Styling Columns
|
|
86
|
-
|
|
87
|
-
wb.styles do |s|
|
|
88
|
-
percent = s.add_style :num_fmt => 9
|
|
89
|
-
wb.add_worksheet(:name => "Styling Columns") do |sheet|
|
|
90
|
-
sheet.add_row ['col 1', 'col 2', 'col 3', 'col 4']
|
|
91
|
-
sheet.add_row [1, 2, 0.3, 4]
|
|
92
|
-
sheet.add_row [1, 2, 0.2, 4]
|
|
93
|
-
sheet.add_row [1, 2, 0.1, 4]
|
|
94
|
-
sheet.col_style 2, percent, :row_offset => 1
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
##Hiding Columns
|
|
99
|
-
|
|
100
|
-
wb.styles do |s|
|
|
101
|
-
percent = s.add_style :num_fmt => 9
|
|
102
|
-
wb.add_worksheet(:name => "Hidden Column") do |sheet|
|
|
103
|
-
sheet.add_row ['col 1', 'col 2', 'col 3', 'col 4']
|
|
104
|
-
sheet.add_row [1, 2, 0.3, 4]
|
|
105
|
-
sheet.add_row [1, 2, 0.2, 4]
|
|
106
|
-
sheet.add_row [1, 2, 0.1, 4]
|
|
107
|
-
sheet.col_style 2, percent, :row_offset => 1
|
|
108
|
-
sheet.column_info[1].hidden = true
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
##Styling Rows
|
|
148
|
+
##Using Custom Formatting and date1904
|
|
113
149
|
|
|
150
|
+
#```ruby
|
|
151
|
+
require 'date'
|
|
114
152
|
wb.styles do |s|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
sheet.add_row [
|
|
121
|
-
sheet.add_row [
|
|
122
|
-
sheet.col_style 2, percent, :row_offset => 1
|
|
123
|
-
sheet.row_style 0, head
|
|
153
|
+
date = s.add_style(:format_code => "yyyy-mm-dd", :border => Axlsx::STYLE_THIN_BORDER)
|
|
154
|
+
padded = s.add_style(:format_code => "00#", :border => Axlsx::STYLE_THIN_BORDER)
|
|
155
|
+
percent = s.add_style(:format_code => "0000%", :border => Axlsx::STYLE_THIN_BORDER)
|
|
156
|
+
# wb.date1904 = true # Use the 1904 date system (Used by Excel for Mac < 2011)
|
|
157
|
+
wb.add_worksheet(:name => "Formatting Data") do |sheet|
|
|
158
|
+
sheet.add_row ["Custom Formatted Date", "Percent Formatted Float", "Padded Numbers"], :style => Axlsx::STYLE_THIN_BORDER
|
|
159
|
+
sheet.add_row [Date::strptime('2012-01-19','%Y-%m-%d'), 0.2, 32], :style => [date, percent, padded]
|
|
124
160
|
end
|
|
125
161
|
end
|
|
162
|
+
#```
|
|
126
163
|
|
|
127
|
-
##
|
|
164
|
+
##Asian Language Support
|
|
128
165
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
sheet.add_row [
|
|
132
|
-
sheet.add_row [
|
|
133
|
-
|
|
134
|
-
sheet["A1:D1"].each { |c| c.color = "FF0000"}
|
|
135
|
-
sheet['A1:D2'].each { |c| c.style = Axlsx::STYLE_THIN_BORDER }
|
|
166
|
+
#```ruby
|
|
167
|
+
wb.add_worksheet(:name => "日本語でのシート名") do |sheet|
|
|
168
|
+
sheet.add_row ["日本語"]
|
|
169
|
+
sheet.add_row ["华语/華語"]
|
|
170
|
+
sheet.add_row ["한국어/조선말"]
|
|
136
171
|
end
|
|
172
|
+
#```
|
|
137
173
|
|
|
138
174
|
##Using formula
|
|
139
175
|
|
|
176
|
+
#```ruby
|
|
140
177
|
wb.add_worksheet(:name => "Using Formulas") do |sheet|
|
|
141
178
|
sheet.add_row ['col 1', 'col 2', 'col 3', 'col 4']
|
|
142
179
|
sheet.add_row [1, 2, 3, "=SUM(A2:C2)"]
|
|
143
180
|
end
|
|
181
|
+
#```
|
|
182
|
+
|
|
183
|
+
##Auto Filter
|
|
184
|
+
|
|
185
|
+
#```ruby
|
|
186
|
+
wb.add_worksheet(:name => "Auto Filter") do |sheet|
|
|
187
|
+
sheet.add_row ["Build Matrix"]
|
|
188
|
+
sheet.add_row ["Build", "Duration", "Finished", "Rvm"]
|
|
189
|
+
sheet.add_row ["19.1", "1 min 32 sec", "about 10 hours ago", "1.8.7"]
|
|
190
|
+
sheet.add_row ["19.2", "1 min 28 sec", "about 10 hours ago", "1.9.2"]
|
|
191
|
+
sheet.add_row ["19.3", "1 min 35 sec", "about 10 hours ago", "1.9.3"]
|
|
192
|
+
sheet.auto_filter = "A2:D5"
|
|
193
|
+
end
|
|
194
|
+
#```
|
|
144
195
|
|
|
145
196
|
##Automatic cell types
|
|
146
197
|
|
|
198
|
+
#```ruby
|
|
147
199
|
wb.add_worksheet(:name => "Automatic cell types") do |sheet|
|
|
200
|
+
date_format = wb.styles.add_style :format_code => 'YYYY-MM-DD'
|
|
201
|
+
time_format = wb.styles.add_style :format_code => 'hh:mm:ss'
|
|
148
202
|
sheet.add_row ["Date", "Time", "String", "Boolean", "Float", "Integer"]
|
|
149
|
-
date_format = wb.styles.add_style :format_code => 'YYYY-MMM-DD'
|
|
150
|
-
time_format = wb.styles.add_style :format_code => 'HH:MM:SS'
|
|
151
203
|
sheet.add_row [Date.today, Time.now, "value", true, 0.1, 1], :style => [date_format, time_format]
|
|
152
204
|
end
|
|
205
|
+
#```
|
|
153
206
|
|
|
154
|
-
##Merging Cells.
|
|
155
|
-
|
|
156
|
-
wb.add_worksheet(:name => 'Merging Cells') do |sheet|
|
|
157
|
-
# cell level style overides when adding cells
|
|
158
|
-
sheet.add_row ["col 1", "col 2", "col 3", "col 4"], :sz => 16
|
|
159
|
-
sheet.add_row [1, 2, 3, "=SUM(A2:C2)"]
|
|
160
|
-
sheet.add_row [2, 3, 4, "=SUM(A3:C3)"]
|
|
161
|
-
sheet.add_row ["total", "", "", "=SUM(D2:D3)"]
|
|
162
|
-
sheet.merge_cells("A4:C4")
|
|
163
|
-
sheet["A1:D1"].each { |c| c.color = "FF0000"}
|
|
164
|
-
sheet["A1:D4"].each { |c| c.style = Axlsx::STYLE_THIN_BORDER }
|
|
165
|
-
end
|
|
166
207
|
|
|
167
208
|
##Generating A Bar Chart
|
|
168
209
|
|
|
210
|
+
#```ruby
|
|
169
211
|
wb.add_worksheet(:name => "Bar Chart") do |sheet|
|
|
170
212
|
sheet.add_row ["A Simple Bar Chart"]
|
|
171
|
-
sheet.add_row [
|
|
172
|
-
sheet.
|
|
173
|
-
|
|
174
|
-
chart.add_series :data => sheet["A3:C3"], :labels => sheet["A2:C2"], :title => sheet["A1"]
|
|
175
|
-
chart.valAxis.label_rotation = -45
|
|
176
|
-
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"]
|
|
177
216
|
end
|
|
178
217
|
end
|
|
218
|
+
#```
|
|
179
219
|
|
|
180
220
|
##Hide Gridlines in chart
|
|
221
|
+
|
|
222
|
+
#```ruby
|
|
181
223
|
wb.add_worksheet(:name => "Chart With No Gridlines") do |sheet|
|
|
182
|
-
sheet.add_row ["
|
|
183
|
-
sheet.add_row [
|
|
184
|
-
sheet.
|
|
185
|
-
|
|
186
|
-
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"]
|
|
187
228
|
chart.valAxis.gridlines = false
|
|
188
229
|
chart.catAxis.gridlines = false
|
|
189
230
|
end
|
|
190
231
|
end
|
|
232
|
+
#```
|
|
191
233
|
|
|
192
234
|
##Generating A Pie Chart
|
|
193
235
|
|
|
236
|
+
#```ruby
|
|
194
237
|
wb.add_worksheet(:name => "Pie Chart") do |sheet|
|
|
195
|
-
sheet.add_row ["
|
|
196
|
-
sheet.add_row [
|
|
197
|
-
sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,
|
|
198
|
-
chart.add_series :data => sheet["
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
##Data over time
|
|
203
|
-
|
|
204
|
-
wb.add_worksheet(:name=>'Charting Dates') do |sheet|
|
|
205
|
-
# cell level style overides when adding cells
|
|
206
|
-
sheet.add_row ['Date', 'Value'], :sz => 16
|
|
207
|
-
sheet.add_row [Time.now - (7*60*60*24), 3]
|
|
208
|
-
sheet.add_row [Time.now - (6*60*60*24), 7]
|
|
209
|
-
sheet.add_row [Time.now - (5*60*60*24), 18]
|
|
210
|
-
sheet.add_row [Time.now - (4*60*60*24), 1]
|
|
211
|
-
sheet.add_chart(Axlsx::Bar3DChart) do |chart|
|
|
212
|
-
chart.start_at "B7"
|
|
213
|
-
chart.end_at "H27"
|
|
214
|
-
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']
|
|
215
242
|
end
|
|
216
243
|
end
|
|
244
|
+
#```
|
|
217
245
|
|
|
218
246
|
##Generating A Line Chart
|
|
219
247
|
|
|
248
|
+
#```ruby
|
|
220
249
|
wb.add_worksheet(:name => "Line Chart") do |sheet|
|
|
221
|
-
sheet.add_row ["
|
|
222
|
-
sheet.add_row
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
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'
|
|
228
262
|
end
|
|
229
263
|
end
|
|
264
|
+
#```
|
|
230
265
|
|
|
231
266
|
##Generating A Scatter Chart
|
|
232
267
|
|
|
268
|
+
#```ruby
|
|
233
269
|
wb.add_worksheet(:name => "Scatter Chart") do |sheet|
|
|
234
270
|
sheet.add_row ["First", 1, 5, 7, 9]
|
|
235
271
|
sheet.add_row ["", 1, 25, 49, 81]
|
|
@@ -242,81 +278,189 @@ wb.add_worksheet(:name => "Scatter Chart") do |sheet|
|
|
|
242
278
|
chart.add_series :xData => sheet["B3:E3"], :yData => sheet["B4:E4"], :title => sheet["A3"]
|
|
243
279
|
end
|
|
244
280
|
end
|
|
281
|
+
#```
|
|
245
282
|
|
|
246
|
-
##Auto Filter
|
|
247
283
|
|
|
248
|
-
|
|
284
|
+
##Tables
|
|
285
|
+
|
|
286
|
+
#```ruby
|
|
287
|
+
wb.add_worksheet(:name => "Table") do |sheet|
|
|
249
288
|
sheet.add_row ["Build Matrix"]
|
|
250
289
|
sheet.add_row ["Build", "Duration", "Finished", "Rvm"]
|
|
251
290
|
sheet.add_row ["19.1", "1 min 32 sec", "about 10 hours ago", "1.8.7"]
|
|
252
291
|
sheet.add_row ["19.2", "1 min 28 sec", "about 10 hours ago", "1.9.2"]
|
|
253
292
|
sheet.add_row ["19.3", "1 min 35 sec", "about 10 hours ago", "1.9.3"]
|
|
254
|
-
sheet.
|
|
293
|
+
sheet.add_table "A2:D5", :name => 'Build Matrix'
|
|
255
294
|
end
|
|
295
|
+
#```
|
|
256
296
|
|
|
257
|
-
##Tables
|
|
258
|
-
|
|
259
|
-
wb.add_worksheet(:name => "Table") do |sheet|
|
|
260
|
-
sheet.add_row ["Build Matrix"]
|
|
261
|
-
sheet.add_row ["Build", "Duration", "Finished", "Rvm"]
|
|
262
|
-
sheet.add_row ["19.1", "1 min 32 sec", "about 10 hours ago", "1.8.7"]
|
|
263
|
-
sheet.add_row ["19.2", "1 min 28 sec", "about 10 hours ago", "1.9.2"]
|
|
264
|
-
sheet.add_row ["19.3", "1 min 35 sec", "about 10 hours ago", "1.9.3"]
|
|
265
|
-
sheet.add_table "A2:D5", :name => 'Build Matrix'
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
##Specifying Column Widths
|
|
270
|
-
|
|
271
|
-
wb.add_worksheet(:name => "custom column widths") do |sheet|
|
|
272
|
-
sheet.add_row ["I use autowidth and am very wide", "I use a custom width and am narrow"]
|
|
273
|
-
sheet.add_row ['abcdefg', 'This is a very long text and should flow into the right cell', nil, 'xxx' ]
|
|
274
|
-
sheet.column_widths nil, 3, 5, nil
|
|
275
|
-
end
|
|
276
297
|
|
|
277
298
|
##Fit to page printing
|
|
278
299
|
|
|
300
|
+
#```ruby
|
|
279
301
|
wb.add_worksheet(:name => "fit to page") do |sheet|
|
|
280
302
|
sheet.add_row ['this all goes on one page']
|
|
281
303
|
sheet.fit_to_page = true
|
|
282
304
|
end
|
|
305
|
+
##```
|
|
283
306
|
|
|
284
307
|
|
|
285
308
|
##Hide Gridlines in worksheet
|
|
309
|
+
|
|
310
|
+
#```ruby
|
|
286
311
|
wb.add_worksheet(:name => "No Gridlines") do |sheet|
|
|
287
312
|
sheet.add_row ["This", "Sheet", "Hides", "Gridlines"]
|
|
288
313
|
sheet.show_gridlines = false
|
|
289
314
|
end
|
|
315
|
+
##```
|
|
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
|
|
323
|
+
|
|
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
|
+
|
|
290
332
|
|
|
291
|
-
##Specify
|
|
333
|
+
##Specify page margins and other options for printing
|
|
334
|
+
|
|
335
|
+
#```ruby
|
|
292
336
|
margins = {:left => 3, :right => 3, :top => 1.2, :bottom => 1.2, :header => 0.7, :footer => 0.7}
|
|
293
|
-
|
|
294
|
-
|
|
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"]
|
|
341
|
+
end
|
|
342
|
+
#```
|
|
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 })
|
|
295
427
|
end
|
|
296
428
|
|
|
297
429
|
##Validate and Serialize
|
|
298
430
|
|
|
299
|
-
|
|
431
|
+
#```ruby
|
|
432
|
+
# Serialize directly to file
|
|
300
433
|
p.serialize("example.xlsx")
|
|
301
434
|
|
|
435
|
+
# or
|
|
436
|
+
|
|
437
|
+
#Serialize to a stream
|
|
302
438
|
s = p.to_stream()
|
|
303
439
|
File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) }
|
|
304
|
-
|
|
440
|
+
#```
|
|
305
441
|
|
|
306
442
|
##Using Shared Strings
|
|
443
|
+
|
|
444
|
+
#```ruby
|
|
445
|
+
# This is required by Numbers
|
|
307
446
|
p.use_shared_strings = true
|
|
308
447
|
p.serialize("shared_strings_example.xlsx")
|
|
448
|
+
#```
|
|
309
449
|
|
|
310
450
|
|
|
311
451
|
##Disabling Autowidth
|
|
452
|
+
|
|
453
|
+
#```ruby
|
|
312
454
|
p = Axlsx::Package.new
|
|
313
455
|
p.use_autowidth = false
|
|
314
456
|
wb = p.workbook
|
|
315
|
-
wb.add_worksheet(:name => "
|
|
316
|
-
sheet.add_row ['oh look! no autowidth
|
|
457
|
+
wb.add_worksheet(:name => "Manual Widths") do | sheet |
|
|
458
|
+
sheet.add_row ['oh look! no autowidth']
|
|
317
459
|
end
|
|
318
460
|
p.validate.each { |e| puts e.message }
|
|
319
461
|
p.serialize("no-use_autowidth.xlsx")
|
|
462
|
+
#```
|
|
463
|
+
|
|
320
464
|
|
|
321
465
|
|
|
322
466
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|