write_xlsx 1.12.3 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -0
  3. data/Changes +23 -0
  4. data/README.md +1 -1
  5. data/lib/write_xlsx/chart/area.rb +2 -2
  6. data/lib/write_xlsx/chart/axis.rb +55 -32
  7. data/lib/write_xlsx/chart/axis_writer.rb +528 -0
  8. data/lib/write_xlsx/chart/bar.rb +2 -2
  9. data/lib/write_xlsx/chart/caption.rb +16 -9
  10. data/lib/write_xlsx/chart/chart_area.rb +121 -0
  11. data/lib/write_xlsx/chart/column.rb +2 -2
  12. data/lib/write_xlsx/chart/d_pt_point_writer.rb +14 -0
  13. data/lib/write_xlsx/chart/doughnut.rb +0 -3
  14. data/lib/write_xlsx/chart/formatting_writer.rb +652 -0
  15. data/lib/write_xlsx/chart/initialization.rb +100 -0
  16. data/lib/write_xlsx/chart/line.rb +4 -3
  17. data/lib/write_xlsx/chart/pie.rb +6 -2
  18. data/lib/write_xlsx/chart/radar.rb +2 -2
  19. data/lib/write_xlsx/chart/scatter.rb +4 -3
  20. data/lib/write_xlsx/chart/series.rb +35 -15
  21. data/lib/write_xlsx/chart/series_data.rb +132 -0
  22. data/lib/write_xlsx/chart/series_writer.rb +318 -0
  23. data/lib/write_xlsx/chart/settings.rb +226 -0
  24. data/lib/write_xlsx/chart/stock.rb +2 -2
  25. data/lib/write_xlsx/chart/table.rb +50 -0
  26. data/lib/write_xlsx/chart/xml_writer.rb +305 -0
  27. data/lib/write_xlsx/chart.rb +286 -2477
  28. data/lib/write_xlsx/chartsheet.rb +35 -83
  29. data/lib/write_xlsx/constants.rb +11 -0
  30. data/lib/write_xlsx/drawing.rb +5 -3
  31. data/lib/write_xlsx/format/alignment_state.rb +39 -0
  32. data/lib/write_xlsx/format/alignment_style.rb +92 -0
  33. data/lib/write_xlsx/format/border_state.rb +47 -0
  34. data/lib/write_xlsx/format/border_style.rb +116 -0
  35. data/lib/write_xlsx/format/fill_state.rb +26 -0
  36. data/lib/write_xlsx/format/fill_style.rb +52 -0
  37. data/lib/write_xlsx/format/font_state.rb +74 -0
  38. data/lib/write_xlsx/format/font_style.rb +172 -0
  39. data/lib/write_xlsx/format/format_state.rb +65 -0
  40. data/lib/write_xlsx/format/number_format_state.rb +20 -0
  41. data/lib/write_xlsx/format/number_format_style.rb +28 -0
  42. data/lib/write_xlsx/format/protection_state.rb +20 -0
  43. data/lib/write_xlsx/format/protection_style.rb +28 -0
  44. data/lib/write_xlsx/format.rb +1093 -426
  45. data/lib/write_xlsx/formats.rb +0 -2
  46. data/lib/write_xlsx/image_property.rb +4 -1
  47. data/lib/write_xlsx/inserted_chart.rb +1 -1
  48. data/lib/write_xlsx/object_positioning.rb +203 -0
  49. data/lib/write_xlsx/package/app.rb +3 -3
  50. data/lib/write_xlsx/package/button.rb +6 -2
  51. data/lib/write_xlsx/package/comments.rb +11 -3
  52. data/lib/write_xlsx/package/conditional_format.rb +7 -3
  53. data/lib/write_xlsx/package/content_types.rb +2 -2
  54. data/lib/write_xlsx/package/core.rb +2 -2
  55. data/lib/write_xlsx/package/custom.rb +3 -2
  56. data/lib/write_xlsx/package/metadata.rb +2 -2
  57. data/lib/write_xlsx/package/packager.rb +0 -3
  58. data/lib/write_xlsx/package/relationships.rb +2 -2
  59. data/lib/write_xlsx/package/rich_value.rb +4 -2
  60. data/lib/write_xlsx/package/rich_value_rel.rb +2 -2
  61. data/lib/write_xlsx/package/rich_value_structure.rb +2 -2
  62. data/lib/write_xlsx/package/rich_value_types.rb +3 -3
  63. data/lib/write_xlsx/package/shared_strings.rb +2 -2
  64. data/lib/write_xlsx/package/styles.rb +13 -9
  65. data/lib/write_xlsx/package/table.rb +8 -2
  66. data/lib/write_xlsx/package/theme.rb +0 -3
  67. data/lib/write_xlsx/package/vml.rb +2 -2
  68. data/lib/write_xlsx/page_setup.rb +192 -0
  69. data/lib/write_xlsx/shape.rb +97 -100
  70. data/lib/write_xlsx/sheets.rb +9 -4
  71. data/lib/write_xlsx/sparkline.rb +2 -2
  72. data/lib/write_xlsx/utility/cell_reference.rb +124 -0
  73. data/lib/write_xlsx/utility/chart_formatting.rb +262 -0
  74. data/lib/write_xlsx/utility/common.rb +44 -0
  75. data/lib/write_xlsx/utility/date_time.rb +113 -0
  76. data/lib/write_xlsx/utility/dimensions.rb +40 -0
  77. data/lib/write_xlsx/utility/drawing.rb +136 -0
  78. data/lib/write_xlsx/utility/rich_text.rb +184 -0
  79. data/lib/write_xlsx/utility/sheetname_quoting.rb +73 -0
  80. data/lib/write_xlsx/utility/string_width.rb +45 -0
  81. data/lib/write_xlsx/utility/url.rb +27 -0
  82. data/lib/write_xlsx/utility/xml_primitives.rb +32 -0
  83. data/lib/write_xlsx/version.rb +1 -1
  84. data/lib/write_xlsx/workbook/chart_data.rb +188 -0
  85. data/lib/write_xlsx/workbook/format_preparation.rb +199 -0
  86. data/lib/write_xlsx/workbook/initialization.rb +223 -0
  87. data/lib/write_xlsx/workbook/package_preparation.rb +231 -0
  88. data/lib/write_xlsx/workbook/workbook_writer.rb +164 -0
  89. data/lib/write_xlsx/workbook.rb +143 -981
  90. data/lib/write_xlsx/worksheet/asset_manager.rb +60 -0
  91. data/lib/write_xlsx/worksheet/autofilter.rb +390 -0
  92. data/lib/write_xlsx/worksheet/cell_data.rb +13 -6
  93. data/lib/write_xlsx/worksheet/cell_data_manager.rb +47 -0
  94. data/lib/write_xlsx/worksheet/cell_data_store.rb +61 -0
  95. data/lib/write_xlsx/worksheet/columns.rb +204 -0
  96. data/lib/write_xlsx/worksheet/comments_support.rb +61 -0
  97. data/lib/write_xlsx/worksheet/conditional_formats.rb +30 -0
  98. data/lib/write_xlsx/worksheet/data_validation.rb +9 -1
  99. data/lib/write_xlsx/worksheet/data_writing.rb +1017 -0
  100. data/lib/write_xlsx/worksheet/drawing_methods.rb +308 -0
  101. data/lib/write_xlsx/worksheet/drawing_preparation.rb +290 -0
  102. data/lib/write_xlsx/worksheet/drawing_relations.rb +76 -0
  103. data/lib/write_xlsx/worksheet/drawing_xml_writer.rb +50 -0
  104. data/lib/write_xlsx/worksheet/formatting.rb +418 -0
  105. data/lib/write_xlsx/worksheet/hyperlink.rb +9 -1
  106. data/lib/write_xlsx/worksheet/initialization.rb +146 -0
  107. data/lib/write_xlsx/worksheet/panes.rb +64 -0
  108. data/lib/write_xlsx/worksheet/print_options.rb +72 -0
  109. data/lib/write_xlsx/worksheet/protection.rb +65 -0
  110. data/lib/write_xlsx/worksheet/rich_text_helpers.rb +78 -0
  111. data/lib/write_xlsx/worksheet/row_col_sizing.rb +69 -0
  112. data/lib/write_xlsx/worksheet/rows.rb +84 -0
  113. data/lib/write_xlsx/worksheet/selection.rb +41 -0
  114. data/lib/write_xlsx/worksheet/xml_writer.rb +1246 -0
  115. data/lib/write_xlsx/worksheet.rb +376 -4530
  116. metadata +66 -4
  117. data/lib/write_xlsx/utility.rb +0 -986
  118. data/lib/write_xlsx/worksheet/page_setup.rb +0 -192
@@ -0,0 +1,305 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ ###############################################################################
5
+ #
6
+ # xml_writer.rb - core chart XML assembly flow
7
+ #
8
+ ###############################################################################
9
+
10
+ module Writexlsx
11
+ class Chart
12
+ module XmlWriter
13
+ #
14
+ # Assemble and write the XML file.
15
+ #
16
+ def assemble_xml_file # :nodoc:
17
+ write_xml_declaration do
18
+ # Write the c:chartSpace element.
19
+ write_chart_space do
20
+ # Write the c:lang element.
21
+ write_lang
22
+ # Write the c:style element.
23
+ write_style
24
+ # Write the c:protection element.
25
+ write_protection
26
+ # Write the c:chart element.
27
+ write_chart
28
+ # Write the c:spPr element for the chartarea formatting.
29
+ write_sp_pr(@chartarea)
30
+ # Write the c:printSettings element.
31
+ write_print_settings if @embedded
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ #
39
+ # Write the <c:chartSpace> element.
40
+ #
41
+ def write_chart_space(&block) # :nodoc:
42
+ @writer.tag_elements('c:chartSpace', chart_space_attributes, &block)
43
+ end
44
+
45
+ # for <c:chartSpace> element.
46
+ def chart_space_attributes # :nodoc:
47
+ schema = 'http://schemas.openxmlformats.org/'
48
+ [
49
+ ['xmlns:c', "#{schema}drawingml/2006/chart"],
50
+ ['xmlns:a', "#{schema}drawingml/2006/main"],
51
+ ['xmlns:r', "#{schema}officeDocument/2006/relationships"]
52
+ ]
53
+ end
54
+
55
+ #
56
+ # Write the <c:lang> element.
57
+ #
58
+ def write_lang # :nodoc:
59
+ @writer.empty_tag('c:lang', [%w[val en-US]])
60
+ end
61
+
62
+ #
63
+ # Write the <c:style> element.
64
+ #
65
+ def write_style # :nodoc:
66
+ return if @style_id == 2
67
+
68
+ @writer.empty_tag('c:style', [['val', @style_id]])
69
+ end
70
+
71
+ #
72
+ # Write the <c:chart> element.
73
+ #
74
+ def write_chart # :nodoc:
75
+ @writer.tag_elements('c:chart') do
76
+ # Write the chart title elements.
77
+ write_chart_title(@title, nil, allow_none: true)
78
+ # Write the c:plotArea element.
79
+ write_plot_area
80
+ # Write the c:legend element.
81
+ write_legend
82
+ # Write the c:plotVisOnly element.
83
+ write_plot_vis_only
84
+ # Write the c:dispBlanksAs element.
85
+ write_disp_blanks_as
86
+ # Write the c:extLst element.
87
+ write_ext_lst_display_na if @show_na_as_empty
88
+ end
89
+ end
90
+
91
+ #
92
+ # Write the <c:plotArea> element.
93
+ #
94
+ # This method orchestrates the plot area generation including:
95
+ # - chart type elements
96
+ # - primary and secondary axes
97
+ # - combined chart handling
98
+ # - plot area formatting
99
+ #
100
+ # The logic is intentionally split into small helpers to preserve the
101
+ # complex ordering requirements of Excel chart XML.
102
+ #
103
+ def write_plot_area # :nodoc:
104
+ second_chart = @combined
105
+
106
+ @writer.tag_elements('c:plotArea') do
107
+ write_plot_area_layout
108
+ write_plot_area_chart_types(second_chart)
109
+ write_plot_area_primary_axes
110
+ write_plot_area_secondary_axes(second_chart)
111
+ write_plot_area_formatting
112
+ end
113
+ end
114
+
115
+ def write_plot_area_layout
116
+ write_layout(@plotarea.layout, 'plot')
117
+ end
118
+
119
+ def write_plot_area_chart_types(second_chart)
120
+ write_primary_and_secondary_chart_types
121
+ write_combined_chart_types(second_chart) if second_chart
122
+ end
123
+
124
+ def write_primary_and_secondary_chart_types
125
+ write_chart_type(primary_axes: 1)
126
+ write_chart_type(primary_axes: 0)
127
+ end
128
+
129
+ def write_combined_chart_types(second_chart)
130
+ prepare_combined_chart(second_chart)
131
+ second_chart.write_chart_type(primary_axes: 1)
132
+ second_chart.write_chart_type(primary_axes: 0)
133
+ end
134
+
135
+ def prepare_combined_chart(second_chart)
136
+ second_chart.id = second_chart.is_secondary? ? 1000 + @id : @id
137
+ second_chart.writer = @writer
138
+ second_chart.series_index = @series_index
139
+ end
140
+
141
+ def write_plot_area_primary_axes
142
+ params = {
143
+ x_axis: @x_axis,
144
+ y_axis: @y_axis,
145
+ axis_ids: @axis_ids
146
+ }
147
+
148
+ write_category_axis_for(params)
149
+ write_val_axis(@x_axis, @y_axis, @axis_ids)
150
+ end
151
+
152
+ def write_plot_area_secondary_axes(second_chart)
153
+ params = {
154
+ x_axis: @x2_axis,
155
+ y_axis: @y2_axis,
156
+ axis_ids: @axis2_ids
157
+ }
158
+
159
+ write_val_axis(@x2_axis, @y2_axis, @axis2_ids)
160
+
161
+ if second_chart && second_chart.is_secondary?
162
+ params = {
163
+ x_axis: second_chart.x2_axis,
164
+ y_axis: second_chart.y2_axis,
165
+ axis_ids: second_chart.axis2_ids
166
+ }
167
+
168
+ second_chart.write_val_axis(
169
+ second_chart.x2_axis,
170
+ second_chart.y2_axis,
171
+ second_chart.axis2_ids
172
+ )
173
+ end
174
+
175
+ write_category_axis_for(params)
176
+ end
177
+
178
+ def write_category_axis_for(params)
179
+ if @date_category
180
+ write_date_axis(params)
181
+ else
182
+ write_cat_axis(params)
183
+ end
184
+ end
185
+
186
+ def write_plot_area_formatting
187
+ write_d_table
188
+ write_sp_pr(@plotarea)
189
+ end
190
+
191
+ #
192
+ # Write the <c:dispBlanksAs> element.
193
+ #
194
+ def write_disp_blanks_as
195
+ return if @show_blanks == 'gap'
196
+
197
+ @writer.empty_tag('c:dispBlanksAs', [['val', @show_blanks]])
198
+ end
199
+
200
+ #
201
+ # Write the <c:layout> element.
202
+ #
203
+ def write_layout(layout = nil, type = nil) # :nodoc:
204
+ tag = 'c:layout'
205
+
206
+ if layout
207
+ @writer.tag_elements(tag) { write_manual_layout(layout, type) }
208
+ else
209
+ @writer.empty_tag(tag)
210
+ end
211
+ end
212
+
213
+ #
214
+ # Write the <c:manualLayout> element.
215
+ #
216
+ def write_manual_layout(layout, type)
217
+ @writer.tag_elements('c:manualLayout') do
218
+ # Plotarea has a layoutTarget element.
219
+ @writer.empty_tag('c:layoutTarget', [%w[val inner]]) if type == 'plot'
220
+
221
+ # Set the x, y positions.
222
+ @writer.empty_tag('c:xMode', [%w[val edge]])
223
+ @writer.empty_tag('c:yMode', [%w[val edge]])
224
+ @writer.empty_tag('c:x', [['val', layout[:x]]])
225
+ @writer.empty_tag('c:y', [['val', layout[:y]]])
226
+
227
+ # For plotarea and legend set the width and height.
228
+ if type != 'text'
229
+ @writer.empty_tag('c:w', [['val', layout[:width]]])
230
+ @writer.empty_tag('c:h', [['val', layout[:height]]])
231
+ end
232
+ end
233
+ end
234
+
235
+ #
236
+ # Write the <c:printSettings> element.
237
+ #
238
+ def write_print_settings # :nodoc:
239
+ @writer.tag_elements('c:printSettings') do
240
+ # Write the c:headerFooter element.
241
+ write_header_footer
242
+ # Write the c:pageMargins element.
243
+ write_page_margins
244
+ # Write the c:pageSetup element.
245
+ write_page_setup
246
+ end
247
+ end
248
+
249
+ #
250
+ # Write the <c:headerFooter> element.
251
+ #
252
+ def write_header_footer # :nodoc:
253
+ @writer.empty_tag('c:headerFooter')
254
+ end
255
+
256
+ #
257
+ # Write the <c:pageMargins> element.
258
+ #
259
+ def write_page_margins # :nodoc:
260
+ attributes = [
261
+ ['b', 0.75],
262
+ ['l', 0.7],
263
+ ['r', 0.7],
264
+ ['t', 0.75],
265
+ ['header', 0.3],
266
+ ['footer', 0.3]
267
+ ]
268
+
269
+ @writer.empty_tag('c:pageMargins', attributes)
270
+ end
271
+
272
+ #
273
+ # Write the <c:pageSetup> element.
274
+ #
275
+ def write_page_setup # :nodoc:
276
+ @writer.empty_tag('c:pageSetup')
277
+ end
278
+
279
+ #
280
+ # Write the <c:autoTitleDeleted> element.
281
+ #
282
+ def write_auto_title_deleted
283
+ attributes = [['val', 1]]
284
+
285
+ @writer.empty_tag('c:autoTitleDeleted', attributes)
286
+ end
287
+
288
+ #
289
+ # Write the <c:grouping> element.
290
+ #
291
+ def write_grouping(val) # :nodoc:
292
+ @writer.empty_tag('c:grouping', [['val', val]])
293
+ end
294
+
295
+ #
296
+ # Write the <c:overlap> element.
297
+ #
298
+ def write_overlap(val = nil) # :nodoc:
299
+ return unless val
300
+
301
+ @writer.empty_tag('c:overlap', [['val', val]])
302
+ end
303
+ end
304
+ end
305
+ end