axlsx 1.1.0 → 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 +78 -0
- data/LICENSE +1 -1
- data/README.md +132 -331
- data/Rakefile +17 -5
- data/examples/basic_charts.rb +54 -0
- data/examples/chart_colors.rb +88 -0
- data/examples/conditional_formatting/example_conditional_formatting.rb +72 -0
- data/examples/conditional_formatting/getting_barred.rb +37 -0
- data/examples/conditional_formatting/hitting_the_high_notes.rb +37 -0
- data/examples/conditional_formatting/scaled_colors.rb +39 -0
- data/examples/conditional_formatting/stop_and_go.rb +37 -0
- data/examples/data_validation.rb +50 -0
- data/examples/example.rb +300 -152
- 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/sample.png +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/skydrive/real_example.rb +63 -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 +106 -35
- 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 +12 -18
- 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/color.rb +0 -1
- data/lib/axlsx/stylesheet/dxf.rb +79 -0
- data/lib/axlsx/stylesheet/font.rb +2 -1
- data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +143 -50
- data/lib/axlsx/stylesheet/table_style.rb +3 -3
- data/lib/axlsx/stylesheet/xf.rb +2 -0
- data/lib/axlsx/util/constants.rb +36 -0
- data/lib/axlsx/util/simple_typed_list.rb +15 -21
- data/lib/axlsx/util/validators.rb +122 -5
- 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/shared_strings_table.rb +12 -13
- data/lib/axlsx/workbook/workbook.rb +71 -13
- data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +45 -36
- data/lib/axlsx/workbook/worksheet/cfvo.rb +62 -0
- data/lib/axlsx/workbook/worksheet/col.rb +17 -1
- data/lib/axlsx/workbook/worksheet/color_scale.rb +76 -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_formatting.rb +82 -0
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +216 -0
- data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
- data/lib/axlsx/workbook/worksheet/data_bar.rb +97 -0
- 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/icon_set.rb +83 -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 +69 -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 +379 -233
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
- data/lib/axlsx.rb +31 -16
- data/test/benchmark.rb +30 -38
- 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 +46 -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/profile.rb +2 -1
- data/test/rels/tc_relationship.rb +1 -0
- data/test/stylesheet/tc_dxf.rb +81 -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 +163 -3
- 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 +52 -18
- data/test/workbook/worksheet/tc_cfvo.rb +31 -0
- data/test/workbook/worksheet/tc_col.rb +9 -0
- data/test/workbook/worksheet/tc_color_scale.rb +29 -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 +217 -0
- data/test/workbook/worksheet/tc_data_bar.rb +39 -0
- data/test/workbook/worksheet/tc_data_validation.rb +265 -0
- data/test/workbook/worksheet/tc_date_time_converter.rb +11 -5
- data/test/workbook/worksheet/tc_icon_set.rb +45 -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 +44 -13
- 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 +147 -50
- metadata +216 -148
- data/examples/example.csv +0 -1000
- data/examples/example.rb~ +0 -112
- 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/stylesheet/#num_fmt.rb# +0 -69
- data/lib/axlsx/util/cbf.rb +0 -333
- data/lib/axlsx/util/cfb.rb~ +0 -201
- 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/col.rb~ +0 -0
- 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/#benchmark.txt# +0 -7
- data/test/#tc_helper.rb# +0 -3
- data/test/benchmark.rb~ +0 -0
- data/test/benchmark.txt +0 -6
- data/test/benchmark.txt~ +0 -6
- data/test/drawing/tc_val_axis_data.rb +0 -17
- data/test/example.csv +0 -1000
- data/test/example.xlsx +0 -0
- data/test/example_streamed.xlsx +0 -0
- data/test/tc_axlsx.rb~ +0 -0
- data/test/tc_helper.rb~ +0 -3
- data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
- data/test/workbook/worksheet/tc_col.rb~ +0 -10
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module Axlsx
|
|
3
|
+
# The Dxf class defines an incremental formatting record for use in Styles. The recommended way to manage styles for your workbook is with Styles#add_style
|
|
4
|
+
# @see Styles#add_style
|
|
5
|
+
class Dxf
|
|
6
|
+
# The order in which the child elements is put in the XML seems to
|
|
7
|
+
# be important for Excel
|
|
8
|
+
CHILD_ELEMENTS = [:font, :numFmt, :fill, :alignment, :border, :protection]
|
|
9
|
+
#does not support extList (ExtensionList)
|
|
10
|
+
|
|
11
|
+
# The cell alignment for this style
|
|
12
|
+
# @return [CellAlignment]
|
|
13
|
+
# @see CellAlignment
|
|
14
|
+
attr_reader :alignment
|
|
15
|
+
|
|
16
|
+
# The cell protection for this style
|
|
17
|
+
# @return [CellProtection]
|
|
18
|
+
# @see CellProtection
|
|
19
|
+
attr_reader :protection
|
|
20
|
+
|
|
21
|
+
# the child NumFmt to be used to this style
|
|
22
|
+
# @return [NumFmt]
|
|
23
|
+
attr_reader :numFmt
|
|
24
|
+
|
|
25
|
+
# the child font to be used for this style
|
|
26
|
+
# @return [Font]
|
|
27
|
+
attr_reader :font
|
|
28
|
+
|
|
29
|
+
# the child fill to be used in this style
|
|
30
|
+
# @return [Fill]
|
|
31
|
+
attr_reader :fill
|
|
32
|
+
|
|
33
|
+
# the border to be used in this style
|
|
34
|
+
# @return [Border]
|
|
35
|
+
attr_reader :border
|
|
36
|
+
|
|
37
|
+
# Creates a new Xf object
|
|
38
|
+
# @option options [Border] border
|
|
39
|
+
# @option options [NumFmt] numFmt
|
|
40
|
+
# @option options [Fill] fill
|
|
41
|
+
# @option options [Font] font
|
|
42
|
+
# @option options [CellAlignment] alignment
|
|
43
|
+
# @option options [CellProtection] protection
|
|
44
|
+
def initialize(options={})
|
|
45
|
+
options.each do |o|
|
|
46
|
+
next if o[1].nil?
|
|
47
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @see Dxf#alignment
|
|
52
|
+
def alignment=(v) DataTypeValidator.validate "Dxf.alignment", CellAlignment, v; @alignment = v end
|
|
53
|
+
# @see protection
|
|
54
|
+
def protection=(v) DataTypeValidator.validate "Dxf.protection", CellProtection, v; @protection = v end
|
|
55
|
+
# @see numFmt
|
|
56
|
+
def numFmt=(v) DataTypeValidator.validate "Dxf.numFmt", NumFmt, v; @numFmt = v end
|
|
57
|
+
# @see font
|
|
58
|
+
def font=(v) DataTypeValidator.validate "Dxf.font", Font, v; @font = v end
|
|
59
|
+
# @see border
|
|
60
|
+
def border=(v) DataTypeValidator.validate "Dxf.border", Border, v; @border = v end
|
|
61
|
+
# @see fill
|
|
62
|
+
def fill=(v) DataTypeValidator.validate "Dxf.fill", Fill, v; @fill = v end
|
|
63
|
+
|
|
64
|
+
# Serializes the object
|
|
65
|
+
# @param [String] str
|
|
66
|
+
# @return [String]
|
|
67
|
+
def to_xml_string(str = '')
|
|
68
|
+
str << '<dxf>'
|
|
69
|
+
# Dxf elements have no attributes. All of the instance variables
|
|
70
|
+
# are child elements.
|
|
71
|
+
CHILD_ELEMENTS.each do |element|
|
|
72
|
+
self.send(element).to_xml_string(str) if self.send(element)
|
|
73
|
+
end
|
|
74
|
+
str << '</dxf>'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
@@ -103,7 +103,8 @@ module Axlsx
|
|
|
103
103
|
# @option options [Integer] sz
|
|
104
104
|
def initialize(options={})
|
|
105
105
|
options.each do |o|
|
|
106
|
-
|
|
106
|
+
next if o[1].nil?
|
|
107
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
107
108
|
end
|
|
108
109
|
end
|
|
109
110
|
# @see name
|
|
@@ -68,7 +68,7 @@ module Axlsx
|
|
|
68
68
|
# @param [String] str
|
|
69
69
|
# @return [String]
|
|
70
70
|
def to_xml_string(str = '')
|
|
71
|
-
str << '<gradientFill'
|
|
71
|
+
str << '<gradientFill '
|
|
72
72
|
h = self.instance_values.reject { |k,v| k.to_sym == :stop }
|
|
73
73
|
str << h.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
|
|
74
74
|
str << '>'
|
|
@@ -14,6 +14,7 @@ module Axlsx
|
|
|
14
14
|
require 'axlsx/stylesheet/table_style.rb'
|
|
15
15
|
require 'axlsx/stylesheet/table_styles.rb'
|
|
16
16
|
require 'axlsx/stylesheet/table_style_element.rb'
|
|
17
|
+
require 'axlsx/stylesheet/dxf.rb'
|
|
17
18
|
require 'axlsx/stylesheet/xf.rb'
|
|
18
19
|
require 'axlsx/stylesheet/cell_protection.rb'
|
|
19
20
|
|
|
@@ -132,11 +133,12 @@ module Axlsx
|
|
|
132
133
|
# @option options [Integer] family The font family to use.
|
|
133
134
|
# @option options [String] font_name The name of the font to use
|
|
134
135
|
# @option options [Integer] num_fmt The number format to apply
|
|
135
|
-
# @option options [String] format_code The formatting to apply.
|
|
136
|
-
# @option options [Integer] border The border style to use.
|
|
136
|
+
# @option options [String] format_code The formatting to apply.
|
|
137
|
+
# @option options [Integer|Hash] border The border style to use.
|
|
137
138
|
# @option options [String] bg_color The background color to apply to the cell
|
|
138
139
|
# @option options [Boolean] hidden Indicates if the cell should be hidden
|
|
139
140
|
# @option options [Boolean] locked Indicates if the cell should be locked
|
|
141
|
+
# @option options [Symbol] type What type of style is this. Options are [:dxf, :xf]. :xf is default
|
|
140
142
|
# @option options [Hash] alignment A hash defining any of the attributes used in CellAlignment
|
|
141
143
|
# @see CellAlignment
|
|
142
144
|
#
|
|
@@ -189,65 +191,156 @@ module Axlsx
|
|
|
189
191
|
# ws.add_row :values => ["Q4", 2000, 20], :style=>[title, currency, percent]
|
|
190
192
|
# f = File.open('example_you_got_style.xlsx', 'w')
|
|
191
193
|
# p.serialize(f)
|
|
194
|
+
#
|
|
195
|
+
# @example Differential styling
|
|
196
|
+
# # Differential styles apply on top of cell styles. Used in Conditional Formatting. Must specify :type => :dxf, and you can't use :num_fmt.
|
|
197
|
+
# require "rubygems" # if that is your preferred way to manage gems!
|
|
198
|
+
# require "axlsx"
|
|
199
|
+
#
|
|
200
|
+
# p = Axlsx::Package.new
|
|
201
|
+
# wb = p.workbook
|
|
202
|
+
# ws = wb.add_worksheet
|
|
203
|
+
#
|
|
204
|
+
# # define your styles
|
|
205
|
+
# profitable = wb.styles.add_style(:bg_color => "FFFF0000",
|
|
206
|
+
# :fg_color=>"#FF000000",
|
|
207
|
+
# :type => :dxf)
|
|
208
|
+
#
|
|
209
|
+
# ws.add_row :values => ["Genreated At:", Time.now], :styles=>[nil, date_time]
|
|
210
|
+
# ws.add_row :values => ["Previous Year Quarterly Profits (JPY)"], :style=>title
|
|
211
|
+
# ws.add_row :values => ["Quarter", "Profit", "% of Total"], :style=>title
|
|
212
|
+
# ws.add_row :values => ["Q1", 4000, 40], :style=>[title, currency, percent]
|
|
213
|
+
# ws.add_row :values => ["Q2", 3000, 30], :style=>[title, currency, percent]
|
|
214
|
+
# ws.add_row :values => ["Q3", 1000, 10], :style=>[title, currency, percent]
|
|
215
|
+
# ws.add_row :values => ["Q4", 2000, 20], :style=>[title, currency, percent]
|
|
216
|
+
#
|
|
217
|
+
# ws.add_conditional_formatting("A1:A7", { :type => :cellIs, :operator => :greaterThan, :formula => "2000", :dxfId => profitable, :priority => 1 })
|
|
218
|
+
# f = File.open('example_differential_styling', 'w')
|
|
219
|
+
# p.serialize(f)
|
|
220
|
+
#
|
|
192
221
|
def add_style(options={})
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
border = Border.new
|
|
210
|
-
[:left, :right, :top, :bottom].each {|pr| border.prs << BorderPr.new(:name => pr, :style=>s, :color => Color.new(:rgb => c))}
|
|
211
|
-
borderId = self.borders << border
|
|
222
|
+
# Default to :xf
|
|
223
|
+
options[:type] ||= :xf
|
|
224
|
+
raise ArgumentError, "Type must be one of [:xf, :dxf]" unless [:xf, :dxf].include?(options[:type] )
|
|
225
|
+
|
|
226
|
+
fill = parse_fill_options options
|
|
227
|
+
font = parse_font_options options
|
|
228
|
+
numFmt = parse_num_fmt_options options
|
|
229
|
+
border = parse_border_options options
|
|
230
|
+
alignment = parse_alignment_options options
|
|
231
|
+
protection = parse_protection_options options
|
|
232
|
+
|
|
233
|
+
case options[:type]
|
|
234
|
+
when :dxf
|
|
235
|
+
style = Dxf.new :fill => fill, :font => font, :numFmt => numFmt, :border => border, :alignment => alignment, :protection => protection
|
|
236
|
+
else
|
|
237
|
+
style = Xf.new :fillId=>fill || 0, :fontId=>font || 0, :numFmtId=>numFmt || 0, :borderId=>border || 0, :alignment => alignment, :protection => protection, :applyFill=>!fill.nil?, :applyFont=>!font.nil?, :applyNumberFormat =>!numFmt.nil?, :applyBorder=>!border.nil?, :applyAlignment => !alignment.nil?, :applyProtection => !protection.nil?
|
|
212
238
|
end
|
|
213
239
|
|
|
214
|
-
|
|
240
|
+
options[:type] == :xf ? cellXfs << style : dxfs << style
|
|
241
|
+
end
|
|
215
242
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
pattern = PatternFill.new(:patternType =>:solid, :fgColor=>color)
|
|
219
|
-
fills << Fill.new(pattern)
|
|
220
|
-
else
|
|
221
|
-
0
|
|
222
|
-
end
|
|
243
|
+
# parses add_style options for protection styles
|
|
244
|
+
# noop if options hash does not include :hide or :locked key
|
|
223
245
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
0
|
|
232
|
-
end
|
|
246
|
+
# @option options [Boolean] hide boolean value defining cell protection attribute for hiding.
|
|
247
|
+
# @option options [Boolean] locked boolean value defining cell protection attribute for locking.
|
|
248
|
+
# @return [CellProtection]
|
|
249
|
+
def parse_protection_options(options={})
|
|
250
|
+
return if (options.keys & [:hidden, :locked]).empty?
|
|
251
|
+
CellProtection.new(options)
|
|
252
|
+
end
|
|
233
253
|
|
|
234
|
-
|
|
254
|
+
# parses add_style options for alignment
|
|
255
|
+
# noop if options hash does not include :alignment key
|
|
256
|
+
# @option options [Hash] alignment A hash of options to prive the CellAlignment intializer
|
|
257
|
+
# @return [CellAlignment]
|
|
258
|
+
# @see CellAlignment
|
|
259
|
+
def parse_alignment_options(options={})
|
|
260
|
+
return unless options[:alignment]
|
|
261
|
+
CellAlignment.new options[:alignment]
|
|
262
|
+
end
|
|
235
263
|
|
|
236
|
-
|
|
264
|
+
# parses add_style options for fonts. If the options hash contains :type => :dxf we return a new Font object.
|
|
265
|
+
# if not, we return the index of the newly created font object in the styles.fonts collection.
|
|
266
|
+
# @note noop if none of the options described here are set on the options parameter.
|
|
267
|
+
# @option options [Symbol] type The type of style object we are working with (dxf or xf)
|
|
268
|
+
# @option options [String] fg_color The text color
|
|
269
|
+
# @option options [Integer] sz The text size
|
|
270
|
+
# @option options [Boolean] b Indicates if the text should be bold
|
|
271
|
+
# @option options [Boolean] i Indicates if the text should be italicised
|
|
272
|
+
# @option options [Boolean] u Indicates if the text should be underlined
|
|
273
|
+
# @option options [Boolean] strike Indicates if the text should be rendered with a strikethrough
|
|
274
|
+
# @option options [Boolean] outline Indicates if the text should be rendered with a shadow
|
|
275
|
+
# @option options [Integer] charset The character set to use.
|
|
276
|
+
# @option options [Integer] family The font family to use.
|
|
277
|
+
# @option options [String] font_name The name of the font to use
|
|
278
|
+
# @return [Font|Integer]
|
|
279
|
+
def parse_font_options(options={})
|
|
280
|
+
return if (options.keys & [:fg_color, :sz, :b, :i, :u, :strike, :outline, :shadow, :charset, :family, :font_name]).empty?
|
|
281
|
+
font = Font.new(options)
|
|
282
|
+
font.color = Color.new(:rgb => options[:fg_color]) if options[:fg_color]
|
|
283
|
+
font.name = options[:font_name] if options[:font_name]
|
|
284
|
+
options[:type] == :dxf ? font : fonts << font
|
|
285
|
+
end
|
|
237
286
|
|
|
238
|
-
|
|
239
|
-
|
|
287
|
+
# parses add_style options for fills. If the options hash contains :type => :dxf we return a Fill object. If not, we return the index of the fill after being added to the fills collection.
|
|
288
|
+
# @note noop if :bg_color is not specified in options
|
|
289
|
+
# @option options [String] bg_color The rgb color to apply to the fill
|
|
290
|
+
# @return [Fill|Integer]
|
|
291
|
+
def parse_fill_options(options={})
|
|
292
|
+
return unless options[:bg_color]
|
|
293
|
+
color = Color.new(:rgb=>options[:bg_color])
|
|
294
|
+
pattern = PatternFill.new(:patternType =>:solid, :fgColor=>color)
|
|
295
|
+
fill = Fill.new(pattern)
|
|
296
|
+
options[:type] == :dxf ? fill : fills << fill
|
|
297
|
+
end
|
|
240
298
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
299
|
+
# parses Style#add_style options for borders.
|
|
300
|
+
# @note noop if :border is not specified in options
|
|
301
|
+
# @option options [Hash|Integer] A border style definition hash or the index of an existing border. Border style definition hashes must include :style and color: key-value entries and may include an :edges entry that references an array of symbols identifying which border edges you wish to apply the style or any other valid Border initializer options. If the :edges entity is not provided the style is applied to all edges of cells that reference this style.
|
|
302
|
+
# @example
|
|
303
|
+
# #apply a thick red border to the top and bottom
|
|
304
|
+
# { :border => { :style => :thick, :color => "FFFF0000", :edges => [:top, :bottom] }
|
|
305
|
+
# @return [Border|Integer]
|
|
306
|
+
def parse_border_options(options={})
|
|
307
|
+
return unless options[:border]
|
|
308
|
+
b_opts = options[:border]
|
|
309
|
+
if b_opts.is_a?(Hash)
|
|
310
|
+
raise ArgumentError, (ERR_INVALID_BORDER_OPTIONS % b_opts) unless b_opts.values_at(:style, :color).size == 2
|
|
311
|
+
border = Border.new b_opts
|
|
312
|
+
(b_opts[:edges] || [:left, :right, :top, :bottom]).each do |edge|
|
|
313
|
+
b_options = { :name => edge, :style => b_opts[:style], :color => Color.new(:rgb => b_opts[:color]) }
|
|
314
|
+
border.prs << BorderPr.new(b_options)
|
|
315
|
+
end
|
|
316
|
+
options[:type] == :dxf ? border : borders << border
|
|
317
|
+
elsif b_opts.is_a? Integer
|
|
318
|
+
raise ArgumentError, (ERR_INVALID_BORDER_ID % b_opts) unless b_opts < borders.size
|
|
319
|
+
if options[:type] == :dxf
|
|
320
|
+
borders[b_opts].clone
|
|
321
|
+
else
|
|
322
|
+
border = b_opts
|
|
323
|
+
end
|
|
244
324
|
end
|
|
325
|
+
end
|
|
245
326
|
|
|
246
|
-
|
|
247
|
-
|
|
327
|
+
# Parses Style#add_style options for number formatting.
|
|
328
|
+
# noop if neither :format_code or :num_format options are set.
|
|
329
|
+
# @option options [Hash] A hash describing the :format_code and/or :num_fmt integer for the style.
|
|
330
|
+
# @return [NumFmt|Integer]
|
|
331
|
+
def parse_num_fmt_options(options={})
|
|
332
|
+
return if (options.keys & [:format_code, :num_fmt]).empty?
|
|
333
|
+
|
|
334
|
+
#When the user provides format_code - we always need to create a new numFmt object
|
|
335
|
+
#When the type is :dxf we always need to create a new numFmt object
|
|
336
|
+
if options[:format_code] || options[:type] == :dxf
|
|
337
|
+
#If this is a standard xf we pull from numFmts the highest current and increment for num_fmt
|
|
338
|
+
options[:num_fmt] ||= (@numFmts.map{ |num_fmt| num_fmt.numFmtId }.max + 1) if options[:type] != :dxf
|
|
339
|
+
numFmt = NumFmt.new(:numFmtId => options[:num_fmt] || 0, :formatCode=> options[:format_code].to_s)
|
|
340
|
+
options[:type] == :dxf ? numFmt : (numFmts << numFmt; numFmt.numFmtId)
|
|
341
|
+
else
|
|
342
|
+
options[:num_fmt]
|
|
248
343
|
end
|
|
249
|
-
|
|
250
|
-
cellXfs << xf
|
|
251
344
|
end
|
|
252
345
|
|
|
253
346
|
# Serializes the object
|
|
@@ -304,7 +397,7 @@ module Axlsx
|
|
|
304
397
|
@cellXfs << Xf.new(:borderId=>0, :xfId=>0, :numFmtId=>14, :fontId=>0, :fillId=>0, :applyNumberFormat=>1)
|
|
305
398
|
@cellXfs.lock
|
|
306
399
|
|
|
307
|
-
@dxfs = SimpleTypedList.new(
|
|
400
|
+
@dxfs = SimpleTypedList.new(Dxf, "dxfs"); @dxfs.lock
|
|
308
401
|
@tableStyles = TableStyles.new(:defaultTableStyle => "TableStyleMedium9", :defaultPivotStyle => "PivotStyleLight16"); @tableStyles.lock
|
|
309
402
|
end
|
|
310
403
|
end
|
|
@@ -40,10 +40,10 @@ module Axlsx
|
|
|
40
40
|
# @param [String] str
|
|
41
41
|
# @return [String]
|
|
42
42
|
def to_xml_string(str = '')
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
attrs = instance_values.reject { |k, v| ![:name, :pivot, :table].include?(k) }
|
|
44
|
+
attrs[:count] = self.size
|
|
45
45
|
str << '<tableStyle '
|
|
46
|
-
str <<
|
|
46
|
+
str << attrs.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
|
|
47
47
|
str << '>'
|
|
48
48
|
each { |table_style_el| table_style_el.to_xml_string(str) }
|
|
49
49
|
str << '</tableStyle>'
|
data/lib/axlsx/stylesheet/xf.rb
CHANGED
|
@@ -85,6 +85,7 @@ module Axlsx
|
|
|
85
85
|
# @option options [CellProtection] protection
|
|
86
86
|
def initialize(options={})
|
|
87
87
|
options.each do |o|
|
|
88
|
+
next if o[1].nil?
|
|
88
89
|
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
89
90
|
end
|
|
90
91
|
end
|
|
@@ -139,5 +140,6 @@ module Axlsx
|
|
|
139
140
|
str << '</xf>'
|
|
140
141
|
end
|
|
141
142
|
|
|
143
|
+
|
|
142
144
|
end
|
|
143
145
|
end
|
data/lib/axlsx/util/constants.rb
CHANGED
|
@@ -79,6 +79,18 @@ module Axlsx
|
|
|
79
79
|
# image rels namespace
|
|
80
80
|
HYPERLINK_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
|
|
81
81
|
|
|
82
|
+
# comment rels namespace
|
|
83
|
+
COMMENT_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
|
|
84
|
+
|
|
85
|
+
# comment relation for nil target
|
|
86
|
+
COMMENT_R_NULL = "http://purl.oclc.org/ooxml/officeDocument/relationships/comments"
|
|
87
|
+
|
|
88
|
+
#vml drawing relation namespace
|
|
89
|
+
VML_DRAWING_R = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing'
|
|
90
|
+
|
|
91
|
+
# VML Drawing content type
|
|
92
|
+
VML_DRAWING_CT = "application/vnd.openxmlformats-officedocument.vmlDrawing"
|
|
93
|
+
|
|
82
94
|
# table content type
|
|
83
95
|
TABLE_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"
|
|
84
96
|
|
|
@@ -109,6 +121,9 @@ module Axlsx
|
|
|
109
121
|
# chart content type
|
|
110
122
|
CHART_CT = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"
|
|
111
123
|
|
|
124
|
+
# comments content type
|
|
125
|
+
COMMENT_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
|
|
126
|
+
|
|
112
127
|
# jpeg content type
|
|
113
128
|
JPEG_CT = "image/jpeg"
|
|
114
129
|
|
|
@@ -172,6 +187,9 @@ module Axlsx
|
|
|
172
187
|
# drawing rels part
|
|
173
188
|
DRAWING_RELS_PN = "drawings/_rels/drawing%d.xml.rels"
|
|
174
189
|
|
|
190
|
+
# vml drawing part
|
|
191
|
+
VML_DRAWING_PN = "drawings/vmlDrawing%d.vml"
|
|
192
|
+
|
|
175
193
|
# drawing part
|
|
176
194
|
TABLE_PN = "tables/table%d.xml"
|
|
177
195
|
|
|
@@ -181,6 +199,9 @@ module Axlsx
|
|
|
181
199
|
# chart part
|
|
182
200
|
IMAGE_PN = "media/image%d.%s"
|
|
183
201
|
|
|
202
|
+
# comment part
|
|
203
|
+
COMMENT_PN = "comments%d.xml"
|
|
204
|
+
|
|
184
205
|
# location of schema files for validation
|
|
185
206
|
SCHEMA_BASE = File.dirname(__FILE__)+'/../../schema/'
|
|
186
207
|
|
|
@@ -228,8 +249,23 @@ module Axlsx
|
|
|
228
249
|
|
|
229
250
|
# error message for sheets that use a name which is longer than 31 bytes
|
|
230
251
|
ERR_SHEET_NAME_TOO_LONG = "Your worksheet name '%s' is too long. Worksheet names must be 31 characters (bytes) or less"
|
|
252
|
+
|
|
253
|
+
# error message for sheets that use a name which includes a colon
|
|
254
|
+
|
|
255
|
+
ERR_SHEET_NAME_COLON_FORBIDDEN = "Your worksheet name '%s' contains a colon, which is not allowed by MS Excel and will cause repair warnings. Please change the name of your sheet."
|
|
231
256
|
|
|
232
257
|
# error message for duplicate sheet names
|
|
233
258
|
ERR_DUPLICATE_SHEET_NAME = "There is already a worksheet in this workbook named '%s'. Please use a unique name"
|
|
234
259
|
|
|
260
|
+
# error message when user does not provide color and or style options for border in Style#add_sytle
|
|
261
|
+
ERR_INVALID_BORDER_OPTIONS = "border hash must include both style and color. e.g. :border => { :color => 'FF000000', :style => :thin }. You provided: %s"
|
|
262
|
+
|
|
263
|
+
# error message for invalid border id reference
|
|
264
|
+
ERR_INVALID_BORDER_ID = "The border id you specified (%s) does not exist. Please add a border with Style#add_style before referencing its index."
|
|
265
|
+
|
|
266
|
+
# error message for invalid angles
|
|
267
|
+
ERR_ANGLE = "Angles must be a value between -90 and 90. You provided: %s"
|
|
268
|
+
|
|
269
|
+
# error message for non 'integerish' value
|
|
270
|
+
ERR_INTEGERISH = "You value must be, or be castable via to_i, an Integer. You provided %s"
|
|
235
271
|
end
|
|
@@ -18,7 +18,7 @@ module Axlsx
|
|
|
18
18
|
|
|
19
19
|
# Creats a new typed list
|
|
20
20
|
# @param [Array, Class] type An array of Class objects or a single Class object
|
|
21
|
-
# @param [String]
|
|
21
|
+
# @param [String] serialize_as The tag name to use in serialization
|
|
22
22
|
# @raise [ArgumentError] if all members of type are not Class objects
|
|
23
23
|
def initialize type, serialize_as=nil
|
|
24
24
|
if type.is_a? Array
|
|
@@ -50,6 +50,18 @@ module Axlsx
|
|
|
50
50
|
@locked_at = nil
|
|
51
51
|
self
|
|
52
52
|
end
|
|
53
|
+
|
|
54
|
+
# join operator
|
|
55
|
+
# @param [Array] v the array to join
|
|
56
|
+
# @raise [ArgumentError] if any of the values being joined are not
|
|
57
|
+
# one of the allowed types
|
|
58
|
+
# @return [SimpleTypedList]
|
|
59
|
+
def +(v)
|
|
60
|
+
v.each do |item|
|
|
61
|
+
DataTypeValidator.validate "SimpleTypedList.+", @allowed_types, item
|
|
62
|
+
@list << item
|
|
63
|
+
end
|
|
64
|
+
end
|
|
53
65
|
|
|
54
66
|
# Concat operator
|
|
55
67
|
# @param [Any] v the data to be added
|
|
@@ -60,12 +72,7 @@ module Axlsx
|
|
|
60
72
|
@list << v
|
|
61
73
|
@list.size - 1
|
|
62
74
|
end
|
|
63
|
-
|
|
64
|
-
# alternate of << method
|
|
65
|
-
# @see <<
|
|
66
|
-
def push(v)
|
|
67
|
-
self.<< v
|
|
68
|
-
end
|
|
75
|
+
alias :push :<<
|
|
69
76
|
|
|
70
77
|
# delete the item from the list
|
|
71
78
|
# @param [Any] v The item to be deleted.
|
|
@@ -149,25 +156,12 @@ module Axlsx
|
|
|
149
156
|
|
|
150
157
|
def to_xml_string(str = '')
|
|
151
158
|
classname = @allowed_types[0].name.split('::').last
|
|
152
|
-
el_name = serialize_as || (classname[0,1].downcase + classname[1..-1])
|
|
159
|
+
el_name = serialize_as.to_s || (classname[0,1].downcase + classname[1..-1])
|
|
153
160
|
str << '<' << el_name << ' count="' << @list.size.to_s << '">'
|
|
154
161
|
@list.each { |item| item.to_xml_string(str) }
|
|
155
162
|
str << '</' << el_name << '>'
|
|
156
163
|
end
|
|
157
164
|
|
|
158
|
-
# Serializes the list
|
|
159
|
-
# If the serialize_as property is set, it is used as the parent node name.
|
|
160
|
-
# If the serialize_as property is nil, the first item in the list of allowed_types will be used, having the first letter of the class changed to lower case.
|
|
161
|
-
# @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
|
|
162
|
-
# @return [String]
|
|
163
|
-
def to_xml(xml)
|
|
164
|
-
classname = @allowed_types[0].name.split('::').last
|
|
165
|
-
el_name = serialize_as || (classname[0,1].downcase + classname[1..-1])
|
|
166
|
-
xml.send(el_name, :count=>@list.size) {
|
|
167
|
-
@list.each { |item| item.to_xml(xml) }
|
|
168
|
-
}
|
|
169
|
-
end
|
|
170
|
-
|
|
171
165
|
end
|
|
172
166
|
|
|
173
167
|
|