caxlsx 2.0.2 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +125 -30
- data/README.md +65 -151
- data/Rakefile +9 -11
- data/examples/{image1.jpeg → assets/image1.jpeg} +0 -0
- data/examples/generate.rb +15 -0
- data/lib/axlsx.rb +35 -17
- data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
- data/lib/axlsx/content_type/content_type.rb +1 -1
- data/lib/axlsx/doc_props/app.rb +1 -1
- data/lib/axlsx/doc_props/core.rb +5 -5
- data/lib/axlsx/drawing/area_chart.rb +99 -0
- data/lib/axlsx/drawing/area_series.rb +110 -0
- data/lib/axlsx/drawing/axes.rb +1 -1
- data/lib/axlsx/drawing/axis.rb +12 -9
- data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
- data/lib/axlsx/drawing/bar_chart.rb +143 -0
- data/lib/axlsx/drawing/bar_series.rb +12 -14
- data/lib/axlsx/drawing/bubble_chart.rb +59 -0
- data/lib/axlsx/drawing/bubble_series.rb +63 -0
- data/lib/axlsx/drawing/cat_axis.rb +5 -5
- data/lib/axlsx/drawing/chart.rb +52 -8
- data/lib/axlsx/drawing/d_lbls.rb +4 -4
- data/lib/axlsx/drawing/drawing.rb +6 -1
- data/lib/axlsx/drawing/graphic_frame.rb +3 -3
- data/lib/axlsx/drawing/hyperlink.rb +1 -3
- data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
- data/lib/axlsx/drawing/line_chart.rb +10 -10
- data/lib/axlsx/drawing/line_series.rb +32 -3
- data/lib/axlsx/drawing/marker.rb +1 -1
- data/lib/axlsx/drawing/num_data.rb +4 -4
- data/lib/axlsx/drawing/num_data_source.rb +6 -6
- data/lib/axlsx/drawing/num_val.rb +3 -1
- data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
- data/lib/axlsx/drawing/pic.rb +25 -19
- data/lib/axlsx/drawing/picture_locking.rb +1 -3
- data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
- data/lib/axlsx/drawing/pie_series.rb +6 -6
- data/lib/axlsx/drawing/scaling.rb +6 -6
- data/lib/axlsx/drawing/scatter_chart.rb +10 -10
- data/lib/axlsx/drawing/scatter_series.rb +40 -7
- data/lib/axlsx/drawing/ser_axis.rb +2 -2
- data/lib/axlsx/drawing/series.rb +3 -3
- data/lib/axlsx/drawing/series_title.rb +4 -2
- data/lib/axlsx/drawing/str_data.rb +3 -3
- data/lib/axlsx/drawing/str_val.rb +3 -1
- data/lib/axlsx/drawing/title.rb +23 -4
- data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
- data/lib/axlsx/drawing/val_axis.rb +1 -1
- data/lib/axlsx/drawing/view_3D.rb +2 -2
- data/lib/axlsx/drawing/vml_drawing.rb +1 -1
- data/lib/axlsx/package.rb +58 -47
- data/lib/axlsx/rels/relationship.rb +27 -26
- data/lib/axlsx/rels/relationships.rb +7 -4
- data/lib/axlsx/stylesheet/border_pr.rb +2 -2
- data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
- data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
- data/lib/axlsx/stylesheet/cell_style.rb +1 -3
- data/lib/axlsx/stylesheet/color.rb +1 -3
- data/lib/axlsx/stylesheet/font.rb +11 -3
- data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
- data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
- data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +7 -7
- data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
- data/lib/axlsx/util/accessors.rb +6 -6
- data/lib/axlsx/util/constants.rb +108 -99
- data/lib/axlsx/util/mime_type_utils.rb +11 -0
- data/lib/axlsx/util/options_parser.rb +2 -1
- data/lib/axlsx/util/serialized_attributes.rb +16 -6
- data/lib/axlsx/util/simple_typed_list.rb +28 -52
- data/lib/axlsx/util/storage.rb +4 -4
- data/lib/axlsx/util/validators.rb +31 -19
- data/lib/axlsx/util/zip_command.rb +73 -0
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/defined_name.rb +11 -12
- data/lib/axlsx/workbook/defined_names.rb +2 -2
- data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
- data/lib/axlsx/workbook/workbook.rb +36 -20
- data/lib/axlsx/workbook/workbook_view.rb +80 -0
- data/lib/axlsx/workbook/workbook_views.rb +22 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
- data/lib/axlsx/workbook/worksheet/break.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cell.rb +164 -75
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
- data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
- data/lib/axlsx/workbook/worksheet/col.rb +14 -13
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
- data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
- data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
- data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
- data/lib/axlsx/workbook/worksheet/data_validation.rb +8 -6
- data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
- data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
- data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
- data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
- data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
- data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
- data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
- data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
- data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
- data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
- data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
- data/lib/axlsx/workbook/worksheet/row.rb +42 -52
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
- data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
- data/lib/axlsx/workbook/worksheet/table.rb +6 -6
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
- data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +76 -81
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
- data/lib/caxlsx.rb +2 -0
- data/test/drawing/tc_area_chart.rb +39 -0
- data/test/drawing/tc_area_series.rb +71 -0
- data/test/drawing/tc_axis.rb +27 -0
- data/test/drawing/tc_bar_chart.rb +71 -0
- data/test/drawing/tc_bubble_chart.rb +44 -0
- data/test/drawing/tc_bubble_series.rb +21 -0
- data/test/drawing/tc_chart.rb +23 -10
- data/test/drawing/tc_data_source.rb +6 -0
- data/test/drawing/tc_drawing.rb +4 -4
- data/test/drawing/tc_hyperlink.rb +1 -1
- data/test/drawing/tc_line_chart.rb +5 -5
- data/test/drawing/tc_line_series.rb +47 -6
- data/test/drawing/tc_one_cell_anchor.rb +1 -1
- data/test/drawing/tc_pic.rb +11 -15
- data/test/drawing/tc_pie_series.rb +2 -1
- data/test/drawing/tc_scatter_series.rb +36 -1
- data/test/drawing/tc_series_title.rb +21 -0
- data/test/drawing/tc_str_val.rb +9 -0
- data/test/drawing/tc_title.rb +21 -0
- data/test/fixtures/image1.gif +0 -0
- data/test/fixtures/image1.jpeg +0 -0
- data/test/fixtures/image1.jpg +0 -0
- data/test/fixtures/image1.png +0 -0
- data/test/fixtures/image1_fake.jpg +0 -0
- data/test/rels/tc_relationship.rb +8 -0
- data/test/stylesheet/tc_font.rb +14 -2
- data/test/stylesheet/tc_styles.rb +29 -3
- data/test/tc_axlsx.rb +37 -0
- data/test/tc_helper.rb +2 -0
- data/test/tc_package.rb +50 -13
- data/test/util/tc_mime_type_utils.rb +13 -0
- data/test/util/tc_simple_typed_list.rb +2 -3
- data/test/util/tc_validators.rb +35 -11
- data/test/workbook/tc_defined_name.rb +12 -4
- data/test/workbook/tc_shared_strings_table.rb +16 -1
- data/test/workbook/tc_workbook.rb +38 -3
- data/test/workbook/tc_workbook_view.rb +50 -0
- data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
- data/test/workbook/worksheet/tc_break.rb +1 -1
- data/test/workbook/worksheet/tc_cell.rb +143 -9
- data/test/workbook/worksheet/tc_col.rb +18 -3
- data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
- data/test/workbook/worksheet/tc_data_bar.rb +1 -1
- data/test/workbook/worksheet/tc_data_validation.rb +11 -11
- data/test/workbook/worksheet/tc_header_footer.rb +2 -2
- data/test/workbook/worksheet/tc_icon_set.rb +1 -1
- data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
- data/test/workbook/worksheet/tc_page_setup.rb +3 -3
- data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
- data/test/workbook/worksheet/tc_print_options.rb +1 -1
- data/test/workbook/worksheet/tc_rich_text.rb +44 -0
- data/test/workbook/worksheet/tc_rich_text_run.rb +173 -0
- data/test/workbook/worksheet/tc_row.rb +24 -2
- data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
- data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
- data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
- data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
- data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
- data/test/workbook/worksheet/tc_table.rb +2 -3
- data/test/workbook/worksheet/tc_worksheet.rb +123 -60
- metadata +180 -128
- data/examples/2010_comments.rb +0 -17
- data/examples/anchor_swapping.rb +0 -28
- data/examples/auto_filter.rb +0 -16
- data/examples/basic_charts.rb +0 -58
- data/examples/chart_colors.rb +0 -88
- data/examples/colored_links.rb +0 -59
- data/examples/conditional_formatting/example_conditional_formatting.rb +0 -74
- data/examples/conditional_formatting/getting_barred.rb +0 -37
- data/examples/conditional_formatting/hitting_the_high_notes.rb +0 -37
- data/examples/conditional_formatting/scaled_colors.rb +0 -39
- data/examples/conditional_formatting/stop_and_go.rb +0 -37
- data/examples/data_validation.rb +0 -50
- data/examples/example.rb +0 -777
- data/examples/extractive.rb +0 -45
- data/examples/ios_preview.rb +0 -14
- data/examples/page_setup.rb +0 -11
- data/examples/pivot_table.rb +0 -39
- data/examples/sheet_protection.rb +0 -10
- data/examples/skydrive/real_example.rb +0 -63
- data/examples/styles.rb +0 -66
- data/examples/underline.rb +0 -13
- data/examples/wrap_text.rb +0 -21
- data/lib/axlsx/util/parser.rb +0 -44
@@ -6,7 +6,7 @@ module Axlsx
|
|
6
6
|
include Axlsx::OptionsParser
|
7
7
|
|
8
8
|
# creates a new Scaling object
|
9
|
-
# @option options [Integer
|
9
|
+
# @option options [Integer] logBase
|
10
10
|
# @option options [Symbol] orientation
|
11
11
|
# @option options [Float] max
|
12
12
|
# @option options [Float] min
|
@@ -35,7 +35,7 @@ module Axlsx
|
|
35
35
|
attr_reader :min
|
36
36
|
|
37
37
|
# @see logBase
|
38
|
-
def logBase=(v) DataTypeValidator.validate "Scaling.logBase", [Integer
|
38
|
+
def logBase=(v) DataTypeValidator.validate "Scaling.logBase", [Integer], v, lambda { |arg| arg >= 2 && arg <= 1000}; @logBase = v; end
|
39
39
|
# @see orientation
|
40
40
|
def orientation=(v) RestrictionValidator.validate "Scaling.orientation", [:minMax, :maxMin], v; @orientation = v; end
|
41
41
|
# @see max
|
@@ -49,10 +49,10 @@ module Axlsx
|
|
49
49
|
# @return [String]
|
50
50
|
def to_xml_string(str = '')
|
51
51
|
str << '<c:scaling>'
|
52
|
-
str << '<c:logBase val="' << @logBase.to_s << '"/>' unless @logBase.nil?
|
53
|
-
str << '<c:orientation val="' << @orientation.to_s << '"/>' unless @orientation.nil?
|
54
|
-
str << '<c:min val="' << @min.to_s << '"/>' unless @min.nil?
|
55
|
-
str << '<c:max val="' << @max.to_s << '"/>' unless @max.nil?
|
52
|
+
str << ('<c:logBase val="' << @logBase.to_s << '"/>') unless @logBase.nil?
|
53
|
+
str << ('<c:orientation val="' << @orientation.to_s << '"/>') unless @orientation.nil?
|
54
|
+
str << ('<c:min val="' << @min.to_s << '"/>') unless @min.nil?
|
55
|
+
str << ('<c:max val="' << @max.to_s << '"/>') unless @max.nil?
|
56
56
|
str << '</c:scaling>'
|
57
57
|
end
|
58
58
|
|
@@ -25,7 +25,7 @@ module Axlsx
|
|
25
25
|
# the y value axis
|
26
26
|
# @return [ValAxis]
|
27
27
|
def y_val_axis
|
28
|
-
axes[:
|
28
|
+
axes[:y_val_axis]
|
29
29
|
end
|
30
30
|
alias :yValAxis :y_val_axis
|
31
31
|
|
@@ -51,15 +51,15 @@ module Axlsx
|
|
51
51
|
# @param [String] str
|
52
52
|
# @return [String]
|
53
53
|
def to_xml_string(str = '')
|
54
|
-
super(str) do
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
@series.each { |ser| ser.to_xml_string(
|
59
|
-
d_lbls.to_xml_string(
|
60
|
-
axes.to_xml_string(
|
61
|
-
|
62
|
-
axes.to_xml_string(
|
54
|
+
super(str) do
|
55
|
+
str << '<c:scatterChart>'
|
56
|
+
str << ('<c:scatterStyle val="' << scatter_style.to_s << '"/>')
|
57
|
+
str << ('<c:varyColors val="' << vary_colors.to_s << '"/>')
|
58
|
+
@series.each { |ser| ser.to_xml_string(str) }
|
59
|
+
d_lbls.to_xml_string(str) if @d_lbls
|
60
|
+
axes.to_xml_string(str, :ids => true)
|
61
|
+
str << '</c:scatterChart>'
|
62
|
+
axes.to_xml_string(str)
|
63
63
|
end
|
64
64
|
str
|
65
65
|
end
|
@@ -21,9 +21,25 @@ module Axlsx
|
|
21
21
|
# @return [String]
|
22
22
|
attr_reader :color
|
23
23
|
|
24
|
+
# @return [String]
|
25
|
+
attr_reader :ln_width
|
26
|
+
|
27
|
+
# Line smoothing between data points
|
28
|
+
# @return [Boolean]
|
29
|
+
attr_reader :smooth
|
30
|
+
|
24
31
|
# Creates a new ScatterSeries
|
25
32
|
def initialize(chart, options={})
|
26
33
|
@xData, @yData = nil
|
34
|
+
if options[:smooth].nil?
|
35
|
+
# If caller hasn't specified smoothing or not, turn smoothing on or off based on scatter style
|
36
|
+
@smooth = [:smooth, :smoothMarker].include?(chart.scatter_style)
|
37
|
+
else
|
38
|
+
# Set smoothing according to the option provided
|
39
|
+
Axlsx::validate_boolean(options[:smooth])
|
40
|
+
@smooth = options[:smooth]
|
41
|
+
end
|
42
|
+
@ln_width = options[:ln_width] unless options[:ln_width].nil?
|
27
43
|
super(chart, options)
|
28
44
|
@xData = AxDataSource.new(:tag_name => :xVal, :data => options[:xData]) unless options[:xData].nil?
|
29
45
|
@yData = NumDataSource.new({:tag_name => :yVal, :data => options[:yData]}) unless options[:yData].nil?
|
@@ -34,30 +50,47 @@ module Axlsx
|
|
34
50
|
@color = v
|
35
51
|
end
|
36
52
|
|
53
|
+
# @see smooth
|
54
|
+
def smooth=(v)
|
55
|
+
Axlsx::validate_boolean(v)
|
56
|
+
@smooth = v
|
57
|
+
end
|
58
|
+
|
59
|
+
# @see ln_width
|
60
|
+
def ln_width=(v)
|
61
|
+
@ln_width = v
|
62
|
+
end
|
63
|
+
|
37
64
|
# Serializes the object
|
38
65
|
# @param [String] str
|
39
66
|
# @return [String]
|
40
67
|
def to_xml_string(str = '')
|
41
|
-
super(str) do
|
68
|
+
super(str) do
|
42
69
|
# needs to override the super color here to push in ln/and something else!
|
43
70
|
if color
|
44
71
|
str << '<c:spPr><a:solidFill>'
|
45
|
-
str << '<a:srgbClr val="' << color << '"/>'
|
72
|
+
str << ('<a:srgbClr val="' << color << '"/>')
|
46
73
|
str << '</a:solidFill>'
|
47
74
|
str << '<a:ln><a:solidFill>'
|
48
|
-
str << '<a:srgbClr val="' << color << '"/></a:solidFill></a:ln>'
|
75
|
+
str << ('<a:srgbClr val="' << color << '"/></a:solidFill></a:ln>')
|
49
76
|
str << '</c:spPr>'
|
50
77
|
str << '<c:marker>'
|
51
78
|
str << '<c:spPr><a:solidFill>'
|
52
|
-
str << '<a:srgbClr val="' << color << '"/>'
|
79
|
+
str << ('<a:srgbClr val="' << color << '"/>')
|
53
80
|
str << '</a:solidFill>'
|
54
81
|
str << '<a:ln><a:solidFill>'
|
55
|
-
str << '<a:srgbClr val="' << color << '"/></a:solidFill></a:ln>'
|
82
|
+
str << ('<a:srgbClr val="' << color << '"/></a:solidFill></a:ln>')
|
56
83
|
str << '</c:spPr>'
|
57
84
|
str << '</c:marker>'
|
58
85
|
end
|
59
|
-
|
60
|
-
|
86
|
+
if ln_width
|
87
|
+
str << '<c:spPr>'
|
88
|
+
str << '<a:ln w="' << ln_width.to_s << '"/>'
|
89
|
+
str << '</c:spPr>'
|
90
|
+
end
|
91
|
+
@xData.to_xml_string(str) unless @xData.nil?
|
92
|
+
@yData.to_xml_string(str) unless @yData.nil?
|
93
|
+
str << ('<c:smooth val="' << ((smooth) ? '1' : '0') << '"/>')
|
61
94
|
end
|
62
95
|
str
|
63
96
|
end
|
@@ -35,8 +35,8 @@ module Axlsx
|
|
35
35
|
def to_xml_string(str = '')
|
36
36
|
str << '<c:serAx>'
|
37
37
|
super(str)
|
38
|
-
str << '<c:tickLblSkip val="' << @tick_lbl_skip.to_s << '"/>' unless @tick_lbl_skip.nil?
|
39
|
-
str << '<c:tickMarkSkip val="' << @tick_mark_skip.to_s << '"/>' unless @tick_mark_skip.nil?
|
38
|
+
str << ('<c:tickLblSkip val="' << @tick_lbl_skip.to_s << '"/>') unless @tick_lbl_skip.nil?
|
39
|
+
str << ('<c:tickMarkSkip val="' << @tick_mark_skip.to_s << '"/>') unless @tick_mark_skip.nil?
|
40
40
|
str << '</c:serAx>'
|
41
41
|
end
|
42
42
|
end
|
data/lib/axlsx/drawing/series.rb
CHANGED
@@ -59,10 +59,10 @@ module Axlsx
|
|
59
59
|
# @return [String]
|
60
60
|
def to_xml_string(str = '')
|
61
61
|
str << '<c:ser>'
|
62
|
-
str << '<c:idx val="' << index.to_s << '"/>'
|
63
|
-
str << '<c:order val="' << (order || index).to_s << '"/>'
|
62
|
+
str << ('<c:idx val="' << index.to_s << '"/>')
|
63
|
+
str << ('<c:order val="' << (order || index).to_s << '"/>')
|
64
64
|
title.to_xml_string(str) unless title.nil?
|
65
|
-
yield
|
65
|
+
yield if block_given?
|
66
66
|
str << '</c:ser>'
|
67
67
|
end
|
68
68
|
end
|
@@ -7,13 +7,15 @@ module Axlsx
|
|
7
7
|
# @param [String] str
|
8
8
|
# @return [String]
|
9
9
|
def to_xml_string(str = '')
|
10
|
+
clean_value = Axlsx::trust_input ? @text.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@text.to_s))
|
11
|
+
|
10
12
|
str << '<c:tx>'
|
11
13
|
str << '<c:strRef>'
|
12
|
-
str << '<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>'
|
14
|
+
str << ('<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>')
|
13
15
|
str << '<c:strCache>'
|
14
16
|
str << '<c:ptCount val="1"/>'
|
15
17
|
str << '<c:pt idx="0">'
|
16
|
-
str << '<c:v>' <<
|
18
|
+
str << ('<c:v>' << clean_value << '</c:v>')
|
17
19
|
str << '</c:pt>'
|
18
20
|
str << '</c:strCache>'
|
19
21
|
str << '</c:strRef>'
|
@@ -29,12 +29,12 @@ module Axlsx
|
|
29
29
|
|
30
30
|
# serialize the object
|
31
31
|
def to_xml_string(str = "")
|
32
|
-
str << '<c:' << @tag_name.to_s << '>'
|
33
|
-
str << '<c:ptCount val="' << @pt.size.to_s << '"/>'
|
32
|
+
str << ('<c:' << @tag_name.to_s << '>')
|
33
|
+
str << ('<c:ptCount val="' << @pt.size.to_s << '"/>')
|
34
34
|
@pt.each_with_index do |value, index|
|
35
35
|
value.to_xml_string index, str
|
36
36
|
end
|
37
|
-
str << '</c:' << @tag_name.to_s << '>'
|
37
|
+
str << ('</c:' << @tag_name.to_s << '>')
|
38
38
|
end
|
39
39
|
|
40
40
|
end
|
@@ -26,7 +26,9 @@ module Axlsx
|
|
26
26
|
# serialize the object
|
27
27
|
def to_xml_string(idx, str = "")
|
28
28
|
Axlsx::validate_unsigned_int(idx)
|
29
|
-
|
29
|
+
if !v.to_s.empty?
|
30
|
+
str << ('<c:pt idx="' << idx.to_s << '"><c:v>' << ::CGI.escapeHTML(v.to_s) << '</c:v></c:pt>')
|
31
|
+
end
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
data/lib/axlsx/drawing/title.rb
CHANGED
@@ -7,15 +7,24 @@ module Axlsx
|
|
7
7
|
# @return [String]
|
8
8
|
attr_reader :text
|
9
9
|
|
10
|
+
# Text size property
|
11
|
+
# @return [String]
|
12
|
+
attr_reader :text_size
|
13
|
+
|
10
14
|
# The cell that holds the text for the title. Setting this property will automatically update the text attribute.
|
11
15
|
# @return [Cell]
|
12
16
|
attr_reader :cell
|
13
17
|
|
14
18
|
# Creates a new Title object
|
15
19
|
# @param [String, Cell] title The cell or string to be used for the chart's title
|
16
|
-
def initialize(title="")
|
20
|
+
def initialize(title="", title_size="")
|
17
21
|
self.cell = title if title.is_a?(Cell)
|
18
22
|
self.text = title.to_s unless title.is_a?(Cell)
|
23
|
+
if title_size.to_s.empty?
|
24
|
+
self.text_size = "1600"
|
25
|
+
else
|
26
|
+
self.text_size = title_size.to_s
|
27
|
+
end
|
19
28
|
end
|
20
29
|
|
21
30
|
# @see text
|
@@ -26,6 +35,14 @@ module Axlsx
|
|
26
35
|
v
|
27
36
|
end
|
28
37
|
|
38
|
+
# @see text_size
|
39
|
+
def text_size=(v)
|
40
|
+
DataTypeValidator.validate 'Title.text_size', String, v
|
41
|
+
@text_size = v
|
42
|
+
@cell = nil
|
43
|
+
v
|
44
|
+
end
|
45
|
+
|
29
46
|
# @see cell
|
30
47
|
def cell=(v)
|
31
48
|
DataTypeValidator.validate 'Title.text', Cell, v
|
@@ -45,14 +62,15 @@ module Axlsx
|
|
45
62
|
def to_xml_string(str = '')
|
46
63
|
str << '<c:title>'
|
47
64
|
unless @text.empty?
|
65
|
+
clean_value = Axlsx::trust_input ? @text.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@text.to_s))
|
48
66
|
str << '<c:tx>'
|
49
67
|
if @cell.is_a?(Cell)
|
50
68
|
str << '<c:strRef>'
|
51
|
-
str << '<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>'
|
69
|
+
str << ('<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>')
|
52
70
|
str << '<c:strCache>'
|
53
71
|
str << '<c:ptCount val="1"/>'
|
54
72
|
str << '<c:pt idx="0">'
|
55
|
-
str << '<c:v>' <<
|
73
|
+
str << ('<c:v>' << clean_value << '</c:v>')
|
56
74
|
str << '</c:pt>'
|
57
75
|
str << '</c:strCache>'
|
58
76
|
str << '</c:strRef>'
|
@@ -62,7 +80,8 @@ module Axlsx
|
|
62
80
|
str << '<a:lstStyle/>'
|
63
81
|
str << '<a:p>'
|
64
82
|
str << '<a:r>'
|
65
|
-
str << '<a:
|
83
|
+
str << ('<a:rPr sz="' << @text_size.to_s << '"/>')
|
84
|
+
str << ('<a:t>' << clean_value << '</a:t>')
|
66
85
|
str << '</a:r>'
|
67
86
|
str << '</a:p>'
|
68
87
|
str << '</c:rich>'
|
@@ -37,11 +37,16 @@ module Axlsx
|
|
37
37
|
drawing.anchors << self
|
38
38
|
@from, @to = Marker.new, Marker.new(:col => 5, :row=>10)
|
39
39
|
parse_options options
|
40
|
+
|
41
|
+
# bit of a hack to work around the fact that the coords for start at and end at
|
42
|
+
# are passed in as an array when specified in intialization options - however
|
43
|
+
start_at(*options[:start_at]) if options[:start_at]
|
44
|
+
end_at(*options[:end_at]) if options[:end_at]
|
40
45
|
end
|
41
46
|
|
42
47
|
# sets the col, row attributes for the from marker.
|
43
48
|
# @note The recommended way to set the start position for graphical
|
44
|
-
# objects is directly thru the object.
|
49
|
+
# objects is directly thru the object.
|
45
50
|
# @see Chart#start_at
|
46
51
|
def start_at(x, y=nil)
|
47
52
|
from.coord x, y
|
@@ -86,12 +86,12 @@ module Axlsx
|
|
86
86
|
alias :rAngAx= :r_ang_ax=
|
87
87
|
|
88
88
|
# @see perspective
|
89
|
-
def perspective=(v)
|
89
|
+
def perspective=(v)
|
90
90
|
RangeValidator.validate "View3D.perspective", 0, 240, v
|
91
91
|
@perspective = v
|
92
92
|
end
|
93
93
|
|
94
|
-
# DataTypeValidator.validate "#{self.class}.perspective", [Integer
|
94
|
+
# DataTypeValidator.validate "#{self.class}.perspective", [Integer], v, lambda {|arg| arg >= 0 && arg <= 240 }; @perspective = v; end
|
95
95
|
|
96
96
|
# Serializes the object
|
97
97
|
# @param [String] str
|
@@ -20,7 +20,7 @@ module Axlsx
|
|
20
20
|
# @param [String] str
|
21
21
|
# @return [String]
|
22
22
|
def to_xml_string(str = '')
|
23
|
-
str
|
23
|
+
str << <<BAD_PROGRAMMER
|
24
24
|
<xml xmlns:v="urn:schemas-microsoft-com:vml"
|
25
25
|
xmlns:o="urn:schemas-microsoft-com:office:office"
|
26
26
|
xmlns:x="urn:schemas-microsoft-com:office:excel">
|
data/lib/axlsx/package.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# encoding:
|
1
|
+
# encoding: utf-8
|
2
2
|
module Axlsx
|
3
3
|
# Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
|
4
|
-
# xlsx document including
|
4
|
+
# xlsx document including validation and serialization.
|
5
5
|
class Package
|
6
6
|
include Axlsx::OptionsParser
|
7
7
|
|
@@ -22,7 +22,7 @@ module Axlsx
|
|
22
22
|
# @example Package.new :author => 'you!', :workbook => Workbook.new
|
23
23
|
def initialize(options={})
|
24
24
|
@workbook = nil
|
25
|
-
@core, @app
|
25
|
+
@core, @app = Core.new, App.new
|
26
26
|
@core.creator = options[:author] || @core.creator
|
27
27
|
@core.created = options[:created_at]
|
28
28
|
parse_options options
|
@@ -68,20 +68,16 @@ module Axlsx
|
|
68
68
|
@workbook
|
69
69
|
end
|
70
70
|
|
71
|
-
#def self.parse(input, confirm_valid = false)
|
72
|
-
# p = Package.new
|
73
|
-
# z = Zip::File.open(input)
|
74
|
-
# p.workbook = Workbook.parse z.get_entry(WORKBOOK_PN)
|
75
|
-
# p
|
76
|
-
#end
|
77
|
-
|
78
71
|
# @see workbook
|
79
|
-
def workbook=(workbook) DataTypeValidator.validate
|
72
|
+
def workbook=(workbook) DataTypeValidator.validate :Package_workbook, Workbook, workbook; @workbook = workbook; end
|
80
73
|
|
81
74
|
# Serialize your workbook to disk as an xlsx document.
|
82
75
|
#
|
83
76
|
# @param [String] output The name of the file you want to serialize your package to
|
84
77
|
# @param [Boolean] confirm_valid Validate the package prior to serialization.
|
78
|
+
# @param [String, nil] zip_command When `nil`, `#serialize` with RubyZip to
|
79
|
+
# zip the XLSX file contents. When a String, the provided zip command (e.g.,
|
80
|
+
# "zip") is used to zip the file contents (may be faster for large files)
|
85
81
|
# @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
|
86
82
|
# @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
|
87
83
|
# confirm_valid should be used in the rare case that you cannot open the serialized file.
|
@@ -95,16 +91,28 @@ module Axlsx
|
|
95
91
|
# # ......add cool stuff to your workbook......
|
96
92
|
# p.serialize("example.xlsx")
|
97
93
|
#
|
94
|
+
# # Serialize to a file, using a system zip binary
|
95
|
+
# p.serialize("example.xlsx", false, zip_command: "zip")
|
96
|
+
# p.serialize("example.xlsx", false, zip_command: "/path/to/zip")
|
97
|
+
# p.serialize("example.xlsx", false, zip_command: "zip -1")
|
98
|
+
#
|
98
99
|
# # Serialize to a stream
|
99
100
|
# s = p.to_stream()
|
100
101
|
# File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) }
|
101
|
-
def serialize(output, confirm_valid=false)
|
102
|
+
def serialize(output, confirm_valid=false, zip_command: nil)
|
102
103
|
return false unless !confirm_valid || self.validate.empty?
|
103
|
-
|
104
|
-
|
104
|
+
zip_provider = if zip_command
|
105
|
+
ZipCommand.new(zip_command)
|
106
|
+
else
|
107
|
+
Zip::OutputStream
|
108
|
+
end
|
109
|
+
Relationship.initialize_ids_cache
|
110
|
+
zip_provider.open(output) do |zip|
|
105
111
|
write_parts(zip)
|
106
112
|
end
|
107
113
|
true
|
114
|
+
ensure
|
115
|
+
Relationship.clear_ids_cache
|
108
116
|
end
|
109
117
|
|
110
118
|
|
@@ -113,11 +121,13 @@ module Axlsx
|
|
113
121
|
# @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not.
|
114
122
|
def to_stream(confirm_valid=false)
|
115
123
|
return false unless !confirm_valid || self.validate.empty?
|
116
|
-
Relationship.
|
124
|
+
Relationship.initialize_ids_cache
|
117
125
|
zip = write_parts(Zip::OutputStream.new(StringIO.new, true))
|
118
126
|
stream = zip.close_buffer
|
119
127
|
stream.rewind
|
120
128
|
stream
|
129
|
+
ensure
|
130
|
+
Relationship.clear_ids_cache
|
121
131
|
end
|
122
132
|
|
123
133
|
# Encrypt the package into a CFB using the password provided
|
@@ -135,7 +145,7 @@ module Axlsx
|
|
135
145
|
# dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
|
136
146
|
# refer to the local versions.
|
137
147
|
#
|
138
|
-
# If by chance you are able to
|
148
|
+
# If by chance you are able to create a package that does not validate it indicates that the internal
|
139
149
|
# validation is not robust enough and needs to be improved. Please report your errors to the gem author.
|
140
150
|
# @see http://www.ecma-international.org/publications/standards/Ecma-376.htm
|
141
151
|
# @example
|
@@ -146,7 +156,9 @@ module Axlsx
|
|
146
156
|
def validate
|
147
157
|
errors = []
|
148
158
|
parts.each do |part|
|
149
|
-
|
159
|
+
unless part[:schema].nil?
|
160
|
+
errors.concat validate_single_doc(part[:schema], part[:doc].to_xml_string)
|
161
|
+
end
|
150
162
|
end
|
151
163
|
errors
|
152
164
|
end
|
@@ -154,20 +166,18 @@ module Axlsx
|
|
154
166
|
private
|
155
167
|
|
156
168
|
# Writes the package parts to a zip archive.
|
157
|
-
# @param [Zip::OutputStream] zip
|
158
|
-
# @return [Zip::OutputStream]
|
169
|
+
# @param [Zip::OutputStream, ZipCommand] zip
|
170
|
+
# @return [Zip::OutputStream, ZipCommand]
|
159
171
|
def write_parts(zip)
|
160
172
|
p = parts
|
161
173
|
p.each do |part|
|
162
174
|
unless part[:doc].nil?
|
163
175
|
zip.put_next_entry(zip_entry_for_part(part))
|
164
|
-
|
165
|
-
zip.puts(entry)
|
176
|
+
part[:doc].to_xml_string(zip)
|
166
177
|
end
|
167
178
|
unless part[:path].nil?
|
168
179
|
zip.put_next_entry(zip_entry_for_part(part))
|
169
|
-
|
170
|
-
zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
|
180
|
+
zip.write IO.read(part[:path], mode: "rb")
|
171
181
|
end
|
172
182
|
end
|
173
183
|
zip
|
@@ -194,40 +204,40 @@ module Axlsx
|
|
194
204
|
# @private
|
195
205
|
def parts
|
196
206
|
parts = [
|
197
|
-
{:entry => RELS_PN, :doc => relationships
|
198
|
-
{:entry => "xl/#{STYLES_PN}", :doc => workbook.styles
|
199
|
-
{:entry => CORE_PN, :doc => @core
|
200
|
-
{:entry => APP_PN, :doc => @app
|
201
|
-
{:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships
|
202
|
-
{:entry => CONTENT_TYPES_PN, :doc => content_types
|
203
|
-
{:entry => WORKBOOK_PN, :doc => workbook
|
207
|
+
{:entry => RELS_PN, :doc => relationships, :schema => RELS_XSD},
|
208
|
+
{:entry => "xl/#{STYLES_PN}", :doc => workbook.styles, :schema => SML_XSD},
|
209
|
+
{:entry => CORE_PN, :doc => @core, :schema => CORE_XSD},
|
210
|
+
{:entry => APP_PN, :doc => @app, :schema => APP_XSD},
|
211
|
+
{:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships, :schema => RELS_XSD},
|
212
|
+
{:entry => CONTENT_TYPES_PN, :doc => content_types, :schema => CONTENT_TYPES_XSD},
|
213
|
+
{:entry => WORKBOOK_PN, :doc => workbook, :schema => SML_XSD}
|
204
214
|
]
|
205
215
|
|
206
216
|
workbook.drawings.each do |drawing|
|
207
|
-
parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships
|
208
|
-
parts << {:entry => "xl/#{drawing.pn}", :doc => drawing
|
217
|
+
parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships, :schema => RELS_XSD}
|
218
|
+
parts << {:entry => "xl/#{drawing.pn}", :doc => drawing, :schema => DRAWING_XSD}
|
209
219
|
end
|
210
220
|
|
211
221
|
|
212
222
|
workbook.tables.each do |table|
|
213
|
-
parts << {:entry => "xl/#{table.pn}", :doc => table
|
223
|
+
parts << {:entry => "xl/#{table.pn}", :doc => table, :schema => SML_XSD}
|
214
224
|
end
|
215
225
|
workbook.pivot_tables.each do |pivot_table|
|
216
226
|
cache_definition = pivot_table.cache_definition
|
217
|
-
parts << {:entry => "xl/#{pivot_table.rels_pn}", :doc => pivot_table.relationships
|
218
|
-
parts << {:entry => "xl/#{pivot_table.pn}", :doc => pivot_table
|
219
|
-
parts << {:entry => "xl/#{cache_definition.pn}", :doc => cache_definition
|
227
|
+
parts << {:entry => "xl/#{pivot_table.rels_pn}", :doc => pivot_table.relationships, :schema => RELS_XSD}
|
228
|
+
parts << {:entry => "xl/#{pivot_table.pn}", :doc => pivot_table} #, :schema => SML_XSD}
|
229
|
+
parts << {:entry => "xl/#{cache_definition.pn}", :doc => cache_definition} #, :schema => SML_XSD}
|
220
230
|
end
|
221
231
|
|
222
232
|
workbook.comments.each do|comment|
|
223
233
|
if comment.size > 0
|
224
|
-
parts << { :entry => "xl/#{comment.pn}", :doc => comment
|
225
|
-
parts << { :entry => "xl/#{comment.vml_drawing.pn}", :doc => comment.vml_drawing
|
234
|
+
parts << { :entry => "xl/#{comment.pn}", :doc => comment, :schema => SML_XSD }
|
235
|
+
parts << { :entry => "xl/#{comment.vml_drawing.pn}", :doc => comment.vml_drawing, :schema => nil }
|
226
236
|
end
|
227
237
|
end
|
228
238
|
|
229
239
|
workbook.charts.each do |chart|
|
230
|
-
parts << {:entry => "xl/#{chart.pn}", :doc => chart
|
240
|
+
parts << {:entry => "xl/#{chart.pn}", :doc => chart, :schema => DRAWING_XSD}
|
231
241
|
end
|
232
242
|
|
233
243
|
workbook.images.each do |image|
|
@@ -235,14 +245,16 @@ module Axlsx
|
|
235
245
|
end
|
236
246
|
|
237
247
|
if use_shared_strings
|
238
|
-
parts << {:entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings
|
248
|
+
parts << {:entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings, :schema => SML_XSD}
|
239
249
|
end
|
240
250
|
|
241
251
|
workbook.worksheets.each do |sheet|
|
242
|
-
parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships
|
243
|
-
parts << {:entry => "xl/#{sheet.pn}", :doc => sheet
|
252
|
+
parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships, :schema => RELS_XSD}
|
253
|
+
parts << {:entry => "xl/#{sheet.pn}", :doc => sheet, :schema => SML_XSD}
|
244
254
|
end
|
245
|
-
|
255
|
+
|
256
|
+
# Sort parts for correct MIME detection
|
257
|
+
parts.sort_by { |part| part[:entry] }
|
246
258
|
end
|
247
259
|
|
248
260
|
# Performs xsd validation for a signle document
|
@@ -303,7 +315,7 @@ module Axlsx
|
|
303
315
|
c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
|
304
316
|
:ContentType => WORKSHEET_CT)
|
305
317
|
end
|
306
|
-
exts = workbook.images.map { |image| image.extname }
|
318
|
+
exts = workbook.images.map { |image| image.extname.downcase }
|
307
319
|
exts.uniq.each do |ext|
|
308
320
|
ct = if ['jpeg', 'jpg'].include?(ext)
|
309
321
|
JPEG_CT
|
@@ -326,8 +338,8 @@ module Axlsx
|
|
326
338
|
# @private
|
327
339
|
def base_content_types
|
328
340
|
c_types = ContentType.new()
|
329
|
-
c_types <<
|
330
|
-
c_types <<
|
341
|
+
c_types << Default.new(:ContentType => RELS_CT, :Extension => RELS_EX)
|
342
|
+
c_types << Default.new(:Extension => XML_EX, :ContentType => XML_CT)
|
331
343
|
c_types << Override.new(:PartName => "/#{APP_PN}", :ContentType => APP_CT)
|
332
344
|
c_types << Override.new(:PartName => "/#{CORE_PN}", :ContentType => CORE_CT)
|
333
345
|
c_types << Override.new(:PartName => "/xl/#{STYLES_PN}", :ContentType => STYLES_CT)
|
@@ -349,4 +361,3 @@ module Axlsx
|
|
349
361
|
end
|
350
362
|
end
|
351
363
|
end
|
352
|
-
|