write_xlsx 0.89.0 → 1.01.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 (340) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Changes +98 -0
  4. data/LICENSE.txt +1 -1
  5. data/README.md +2 -2
  6. data/examples/a_simple.rb +2 -7
  7. data/examples/add_vba_project.rb +1 -1
  8. data/examples/array_formula.rb +1 -1
  9. data/examples/chart_area.rb +5 -2
  10. data/examples/chart_bar.rb +5 -2
  11. data/examples/chart_clustered.rb +1 -1
  12. data/examples/chart_column.rb +5 -2
  13. data/examples/chart_combined.rb +1 -1
  14. data/examples/chart_data_table.rb +9 -3
  15. data/examples/chart_data_tools.rb +25 -7
  16. data/examples/chart_doughnut.rb +17 -5
  17. data/examples/chart_gauge.rb +73 -0
  18. data/examples/chart_line.rb +5 -2
  19. data/examples/chart_pareto.rb +1 -1
  20. data/examples/chart_pie.rb +9 -3
  21. data/examples/chart_radar.rb +13 -4
  22. data/examples/chart_scatter.rb +5 -2
  23. data/examples/chart_secondary_axis.rb +5 -2
  24. data/examples/chart_stock.rb +1 -1
  25. data/examples/chart_styles.rb +1 -1
  26. data/examples/colors.rb +1 -1
  27. data/examples/conditional_format.rb +73 -46
  28. data/examples/data_validate.rb +1 -1
  29. data/examples/date_time.rb +1 -1
  30. data/examples/demo.rb +5 -8
  31. data/examples/formats.rb +1 -1
  32. data/examples/headers.rb +1 -1
  33. data/examples/hide_row_col.rb +1 -1
  34. data/examples/hide_sheet.rb +1 -1
  35. data/examples/hyperlink1.rb +5 -12
  36. data/examples/indent.rb +1 -1
  37. data/examples/macros.rb +1 -1
  38. data/examples/merge1.rb +1 -1
  39. data/examples/merge2.rb +1 -1
  40. data/examples/merge3.rb +1 -1
  41. data/examples/merge4.rb +1 -1
  42. data/examples/merge5.rb +1 -1
  43. data/examples/merge6.rb +1 -1
  44. data/examples/outline.rb +1 -1
  45. data/examples/outline_collapsed.rb +1 -1
  46. data/examples/panes.rb +1 -1
  47. data/examples/properties.rb +1 -1
  48. data/examples/regions.rb +1 -1
  49. data/examples/rich_strings.rb +1 -1
  50. data/examples/right_to_left.rb +1 -1
  51. data/examples/shape1.rb +1 -1
  52. data/examples/shape2.rb +1 -1
  53. data/examples/shape3.rb +1 -1
  54. data/examples/shape4.rb +1 -1
  55. data/examples/shape5.rb +1 -1
  56. data/examples/shape6.rb +1 -1
  57. data/examples/shape7.rb +1 -1
  58. data/examples/shape8.rb +1 -1
  59. data/examples/shape_all.rb +1 -1
  60. data/examples/sparklines1.rb +1 -1
  61. data/examples/sparklines2.rb +1 -1
  62. data/examples/stats.rb +1 -1
  63. data/examples/stats_ext.rb +1 -1
  64. data/examples/stocks.rb +1 -1
  65. data/examples/tab_colors.rb +1 -1
  66. data/examples/tables.rb +1 -1
  67. data/lib/write_xlsx/chart.rb +124 -240
  68. data/lib/write_xlsx/chart/area.rb +1 -1
  69. data/lib/write_xlsx/chart/axis.rb +4 -4
  70. data/lib/write_xlsx/chart/bar.rb +1 -1
  71. data/lib/write_xlsx/chart/caption.rb +3 -1
  72. data/lib/write_xlsx/chart/column.rb +1 -1
  73. data/lib/write_xlsx/chart/doughnut.rb +1 -1
  74. data/lib/write_xlsx/chart/legend.rb +14 -0
  75. data/lib/write_xlsx/chart/line.rb +1 -1
  76. data/lib/write_xlsx/chart/pie.rb +32 -15
  77. data/lib/write_xlsx/chart/radar.rb +1 -1
  78. data/lib/write_xlsx/chart/scatter.rb +1 -1
  79. data/lib/write_xlsx/chart/series.rb +11 -7
  80. data/lib/write_xlsx/chart/stock.rb +1 -1
  81. data/lib/write_xlsx/chartsheet.rb +35 -7
  82. data/lib/write_xlsx/drawing.rb +28 -8
  83. data/lib/write_xlsx/format.rb +19 -15
  84. data/lib/write_xlsx/package/comments.rb +57 -54
  85. data/lib/write_xlsx/package/conditional_format.rb +360 -39
  86. data/lib/write_xlsx/package/content_types.rb +10 -0
  87. data/lib/write_xlsx/package/core.rb +8 -6
  88. data/lib/write_xlsx/package/custom.rb +125 -0
  89. data/lib/write_xlsx/package/packager.rb +26 -0
  90. data/lib/write_xlsx/package/styles.rb +53 -21
  91. data/lib/write_xlsx/package/table.rb +16 -4
  92. data/lib/write_xlsx/shape.rb +4 -3
  93. data/lib/write_xlsx/sheets.rb +11 -1
  94. data/lib/write_xlsx/sparkline.rb +1 -1
  95. data/lib/write_xlsx/utility.rb +305 -35
  96. data/lib/write_xlsx/version.rb +1 -1
  97. data/lib/write_xlsx/workbook.rb +132 -12
  98. data/lib/write_xlsx/worksheet.rb +397 -163
  99. data/lib/write_xlsx/worksheet/data_validation.rb +10 -14
  100. data/lib/write_xlsx/worksheet/hyperlink.rb +4 -13
  101. data/test/chart/test_write_legend_pos.rb +9 -1
  102. data/test/chartsheet/test_write_sheet_protection.rb +91 -0
  103. data/test/drawing/test_drawing_chart_01.rb +6 -2
  104. data/test/drawing/test_drawing_image_01.rb +12 -3
  105. data/test/drawing/test_drawing_shape_01.rb +8 -5
  106. data/test/drawing/test_drawing_shape_02.rb +12 -5
  107. data/test/drawing/test_drawing_shape_03.rb +8 -5
  108. data/test/drawing/test_drawing_shape_04.rb +8 -24
  109. data/test/drawing/test_drawing_shape_05.rb +8 -5
  110. data/test/drawing/test_drawing_shape_06.rb +11 -6
  111. data/test/drawing/test_drawing_shape_07.rb +11 -6
  112. data/test/drawing/test_write_a_graphic_frame_locks.rb +1 -1
  113. data/test/drawing/test_write_c_chart.rb +1 -1
  114. data/test/drawing/test_write_c_nv_graphic_frame_pr.rb +1 -1
  115. data/test/drawing/test_write_c_nv_pr.rb +1 -1
  116. data/test/drawing/test_write_col.rb +1 -1
  117. data/test/drawing/test_write_col_off.rb +1 -1
  118. data/test/drawing/test_write_ext.rb +1 -1
  119. data/test/drawing/test_write_pos.rb +1 -1
  120. data/test/drawing/test_write_row.rb +1 -1
  121. data/test/drawing/test_write_row_off.rb +1 -1
  122. data/test/drawing/test_write_xfrm_extension.rb +1 -1
  123. data/test/drawing/test_write_xfrm_offset.rb +1 -1
  124. data/test/helper.rb +6 -1
  125. data/test/package/comments/test_comments_01.rb +54 -0
  126. data/test/package/comments/test_comments_02.rb +54 -0
  127. data/test/perl_output/chart_gauge.xlsx +0 -0
  128. data/test/perl_output/formats.xlsx +0 -0
  129. data/test/regression/_test_hyperlink31.rb +26 -0
  130. data/test/regression/images/happy.jpg +0 -0
  131. data/test/regression/images/zero_dpi.jpg +0 -0
  132. data/test/regression/test_array_formula03.rb +36 -0
  133. data/test/regression/test_autofilter08.rb +110 -0
  134. data/test/regression/test_autofilter09.rb +110 -0
  135. data/test/regression/test_autofilter10.rb +110 -0
  136. data/test/regression/test_chart_axis26.rb +10 -8
  137. data/test/regression/test_chart_axis27.rb +1 -1
  138. data/test/regression/test_chart_axis28.rb +1 -1
  139. data/test/regression/test_chart_axis29.rb +1 -1
  140. data/test/regression/test_chart_axis33.rb +1 -1
  141. data/test/regression/test_chart_axis42.rb +44 -0
  142. data/test/regression/test_chart_axis43.rb +44 -0
  143. data/test/regression/test_chart_axis44.rb +54 -0
  144. data/test/regression/test_chart_axis45.rb +54 -0
  145. data/test/regression/test_chart_axis46.rb +54 -0
  146. data/test/regression/test_chart_bar08.rb +3 -0
  147. data/test/regression/test_chart_bar11.rb +3 -0
  148. data/test/regression/test_chart_bar14.rb +3 -0
  149. data/test/regression/test_chart_chartarea05.rb +16 -17
  150. data/test/regression/test_chart_chartarea06.rb +49 -0
  151. data/test/regression/test_chart_combined10.rb +43 -0
  152. data/test/regression/test_chart_combined11.rb +63 -0
  153. data/test/regression/test_chart_data_labels25.rb +61 -0
  154. data/test/regression/test_chart_doughnut07.rb +37 -0
  155. data/test/regression/test_chart_font09.rb +1 -1
  156. data/test/regression/test_chart_format26.rb +48 -0
  157. data/test/regression/test_chart_format27.rb +58 -0
  158. data/test/regression/test_chart_format28.rb +52 -0
  159. data/test/regression/test_chart_format29.rb +59 -0
  160. data/test/regression/test_chart_format30.rb +53 -0
  161. data/test/regression/test_chart_format31.rb +60 -0
  162. data/test/regression/test_chart_legend03.rb +41 -0
  163. data/test/regression/test_chart_legend04.rb +41 -0
  164. data/test/regression/test_chart_legend05.rb +41 -0
  165. data/test/regression/test_chart_legend06.rb +41 -0
  166. data/test/regression/test_chart_legend07.rb +38 -0
  167. data/test/regression/test_chart_size03.rb +4 -1
  168. data/test/regression/test_chart_table03.rb +56 -0
  169. data/test/regression/test_comment13.rb +36 -0
  170. data/test/regression/test_comment14.rb +29 -0
  171. data/test/regression/test_cond_format14.rb +42 -0
  172. data/test/regression/test_cond_format15.rb +53 -0
  173. data/test/regression/test_cond_format16.rb +53 -0
  174. data/test/regression/test_cond_format17.rb +37 -0
  175. data/test/regression/test_cond_format18.rb +136 -0
  176. data/test/regression/test_cond_format19.rb +64 -0
  177. data/test/regression/test_cond_format20.rb +43 -0
  178. data/test/regression/test_date_1904_01.rb +1 -1
  179. data/test/regression/test_escapes04.rb +3 -0
  180. data/test/regression/test_escapes05.rb +3 -0
  181. data/test/regression/test_escapes07.rb +3 -0
  182. data/test/regression/test_escapes08.rb +3 -0
  183. data/test/regression/test_format15.rb +26 -0
  184. data/test/regression/test_hyperlink01.rb +3 -0
  185. data/test/regression/test_hyperlink02.rb +3 -0
  186. data/test/regression/test_hyperlink03.rb +4 -0
  187. data/test/regression/test_hyperlink04.rb +3 -0
  188. data/test/regression/test_hyperlink05.rb +3 -0
  189. data/test/regression/test_hyperlink06.rb +3 -0
  190. data/test/regression/test_hyperlink07.rb +3 -0
  191. data/test/regression/test_hyperlink08.rb +3 -0
  192. data/test/regression/test_hyperlink09.rb +3 -0
  193. data/test/regression/test_hyperlink10.rb +3 -0
  194. data/test/regression/test_hyperlink11.rb +3 -0
  195. data/test/regression/test_hyperlink12.rb +3 -0
  196. data/test/regression/test_hyperlink13.rb +3 -0
  197. data/test/regression/test_hyperlink14.rb +3 -0
  198. data/test/regression/test_hyperlink15.rb +3 -0
  199. data/test/regression/test_hyperlink16.rb +3 -0
  200. data/test/regression/test_hyperlink17.rb +3 -0
  201. data/test/regression/test_hyperlink18.rb +3 -0
  202. data/test/regression/test_hyperlink20.rb +3 -0
  203. data/test/regression/test_hyperlink21.rb +3 -0
  204. data/test/regression/test_hyperlink22.rb +3 -0
  205. data/test/regression/test_hyperlink23.rb +3 -0
  206. data/test/regression/test_hyperlink24.rb +3 -0
  207. data/test/regression/test_hyperlink25.rb +3 -0
  208. data/test/regression/test_hyperlink26.rb +3 -0
  209. data/test/regression/test_hyperlink27.rb +27 -0
  210. data/test/regression/test_hyperlink28.rb +50 -0
  211. data/test/regression/test_hyperlink29.rb +27 -0
  212. data/test/regression/test_hyperlink30.rb +36 -0
  213. data/test/regression/test_image08.rb +5 -4
  214. data/test/regression/test_image15.rb +4 -2
  215. data/test/regression/test_image28.rb +1 -1
  216. data/test/regression/test_image35.rb +26 -0
  217. data/test/regression/test_image36.rb +26 -0
  218. data/test/regression/test_image44.rb +28 -0
  219. data/test/regression/test_image45.rb +28 -0
  220. data/test/regression/test_image46.rb +29 -0
  221. data/test/regression/test_image47.rb +28 -0
  222. data/test/regression/test_object_position01.rb +26 -0
  223. data/test/regression/test_object_position02.rb +26 -0
  224. data/test/regression/test_object_position03.rb +26 -0
  225. data/test/regression/test_object_position04.rb +44 -0
  226. data/test/regression/test_object_position06.rb +28 -0
  227. data/test/regression/test_object_position07.rb +28 -0
  228. data/test/regression/test_object_position08.rb +47 -0
  229. data/test/regression/test_object_position09.rb +50 -0
  230. data/test/regression/test_object_position10.rb +28 -0
  231. data/test/regression/test_properties01.rb +1 -4
  232. data/test/regression/test_properties02.rb +1 -4
  233. data/test/regression/test_properties03.rb +26 -0
  234. data/test/regression/test_properties04.rb +61 -0
  235. data/test/regression/test_properties05.rb +30 -0
  236. data/test/regression/test_shape_connect01.rb +4 -2
  237. data/test/regression/test_table03.rb +3 -0
  238. data/test/regression/test_table04.rb +3 -0
  239. data/test/regression/test_table05.rb +3 -0
  240. data/test/regression/test_table06.rb +3 -0
  241. data/test/regression/test_table20.rb +34 -0
  242. data/test/regression/test_table21.rb +36 -0
  243. data/test/regression/test_table22.rb +32 -0
  244. data/test/regression/test_table23.rb +56 -0
  245. data/test/regression/test_utf8_11.rb +23 -0
  246. data/test/regression/xlsx_files/array_formula03.xlsx +0 -0
  247. data/test/regression/xlsx_files/autofilter08.xlsx +0 -0
  248. data/test/regression/xlsx_files/autofilter09.xlsx +0 -0
  249. data/test/regression/xlsx_files/autofilter10.xlsx +0 -0
  250. data/test/regression/xlsx_files/chart_axis26.xlsx +0 -0
  251. data/test/regression/xlsx_files/chart_axis27.xlsx +0 -0
  252. data/test/regression/xlsx_files/chart_axis28.xlsx +0 -0
  253. data/test/regression/xlsx_files/chart_axis29.xlsx +0 -0
  254. data/test/regression/xlsx_files/chart_axis33.xlsx +0 -0
  255. data/test/regression/xlsx_files/chart_axis42.xlsx +0 -0
  256. data/test/regression/xlsx_files/chart_axis43.xlsx +0 -0
  257. data/test/regression/xlsx_files/chart_axis44.xlsx +0 -0
  258. data/test/regression/xlsx_files/chart_axis45.xlsx +0 -0
  259. data/test/regression/xlsx_files/chart_axis46.xlsx +0 -0
  260. data/test/regression/xlsx_files/chart_chartarea05.xlsx +0 -0
  261. data/test/regression/xlsx_files/chart_chartarea06.xlsx +0 -0
  262. data/test/regression/xlsx_files/chart_combined10.xlsx +0 -0
  263. data/test/regression/xlsx_files/chart_combined11.xlsx +0 -0
  264. data/test/regression/xlsx_files/chart_data_labels25.xlsx +0 -0
  265. data/test/regression/xlsx_files/chart_doughnut07.xlsx +0 -0
  266. data/test/regression/xlsx_files/chart_font09.xlsx +0 -0
  267. data/test/regression/xlsx_files/chart_format26.xlsx +0 -0
  268. data/test/regression/xlsx_files/chart_format27.xlsx +0 -0
  269. data/test/regression/xlsx_files/chart_format28.xlsx +0 -0
  270. data/test/regression/xlsx_files/chart_format29.xlsx +0 -0
  271. data/test/regression/xlsx_files/chart_format30.xlsx +0 -0
  272. data/test/regression/xlsx_files/chart_format31.xlsx +0 -0
  273. data/test/regression/xlsx_files/chart_legend03.xlsx +0 -0
  274. data/test/regression/xlsx_files/chart_legend04.xlsx +0 -0
  275. data/test/regression/xlsx_files/chart_legend05.xlsx +0 -0
  276. data/test/regression/xlsx_files/chart_legend06.xlsx +0 -0
  277. data/test/regression/xlsx_files/chart_legend07.xlsx +0 -0
  278. data/test/regression/xlsx_files/chart_table03.xlsx +0 -0
  279. data/test/regression/xlsx_files/comment13.xlsx +0 -0
  280. data/test/regression/xlsx_files/comment14.xlsx +0 -0
  281. data/test/regression/xlsx_files/cond_format14.xlsx +0 -0
  282. data/test/regression/xlsx_files/cond_format15.xlsx +0 -0
  283. data/test/regression/xlsx_files/cond_format16.xlsx +0 -0
  284. data/test/regression/xlsx_files/cond_format17.xlsx +0 -0
  285. data/test/regression/xlsx_files/cond_format18.xlsx +0 -0
  286. data/test/regression/xlsx_files/cond_format19.xlsx +0 -0
  287. data/test/regression/xlsx_files/cond_format20.xlsx +0 -0
  288. data/test/regression/xlsx_files/date_1904_01.xlsx +0 -0
  289. data/test/regression/xlsx_files/format15.xlsx +0 -0
  290. data/test/regression/xlsx_files/hyperlink27.xlsx +0 -0
  291. data/test/regression/xlsx_files/hyperlink28.xlsx +0 -0
  292. data/test/regression/xlsx_files/hyperlink29.xlsx +0 -0
  293. data/test/regression/xlsx_files/hyperlink30.xlsx +0 -0
  294. data/test/regression/xlsx_files/hyperlink31.xlsx +0 -0
  295. data/test/regression/xlsx_files/image35.xlsx +0 -0
  296. data/test/regression/xlsx_files/image36.xlsx +0 -0
  297. data/test/regression/xlsx_files/image44.xlsx +0 -0
  298. data/test/regression/xlsx_files/image45.xlsx +0 -0
  299. data/test/regression/xlsx_files/image46.xlsx +0 -0
  300. data/test/regression/xlsx_files/image47.xlsx +0 -0
  301. data/test/regression/xlsx_files/object_position01.xlsx +0 -0
  302. data/test/regression/xlsx_files/object_position02.xlsx +0 -0
  303. data/test/regression/xlsx_files/object_position03.xlsx +0 -0
  304. data/test/regression/xlsx_files/object_position04.xlsx +0 -0
  305. data/test/regression/xlsx_files/object_position06.xlsx +0 -0
  306. data/test/regression/xlsx_files/object_position07.xlsx +0 -0
  307. data/test/regression/xlsx_files/object_position08.xlsx +0 -0
  308. data/test/regression/xlsx_files/object_position09.xlsx +0 -0
  309. data/test/regression/xlsx_files/object_position10.xlsx +0 -0
  310. data/test/regression/xlsx_files/properties03.xlsx +0 -0
  311. data/test/regression/xlsx_files/properties04.xlsx +0 -0
  312. data/test/regression/xlsx_files/properties05.xlsx +0 -0
  313. data/test/regression/xlsx_files/table21.xlsx +0 -0
  314. data/test/regression/xlsx_files/table22.xlsx +0 -0
  315. data/test/regression/xlsx_files/table23.xlsx +0 -0
  316. data/test/regression/xlsx_files/utf8_11.xlsx +0 -0
  317. data/test/test_example_match.rb +836 -771
  318. data/test/workbook/test_check_sheetname.rb +61 -0
  319. data/test/workbook/test_worksheet_by_name.rb +35 -0
  320. data/test/workbook/test_write_workbook_view.rb +117 -0
  321. data/test/worksheet/test_cond_format_22.rb +266 -0
  322. data/test/worksheet/test_cond_format_23.rb +242 -0
  323. data/test/worksheet/test_cond_format_24.rb +303 -0
  324. data/test/worksheet/test_data_bar_01.rb +53 -0
  325. data/test/worksheet/test_data_bar_02.rb +79 -0
  326. data/test/worksheet/test_data_bar_03.rb +147 -0
  327. data/test/worksheet/test_data_bar_04.rb +145 -0
  328. data/test/worksheet/test_data_bar_05.rb +147 -0
  329. data/test/worksheet/test_data_bar_06.rb +145 -0
  330. data/test/worksheet/test_data_bar_07.rb +146 -0
  331. data/test/worksheet/test_data_bar_08.rb +54 -0
  332. data/test/worksheet/test_data_bar_09.rb +80 -0
  333. data/test/worksheet/test_data_bar_10.rb +165 -0
  334. data/test/worksheet/test_data_bar_11.rb +167 -0
  335. data/test/worksheet/test_data_bar_12.rb +104 -0
  336. data/test/worksheet/test_write_data_validation_02.rb +44 -0
  337. data/test/worksheet/test_write_hyperlink.rb +0 -7
  338. data/test/worksheet/test_write_sheet_view.rb +19 -1
  339. metadata +308 -5
  340. data/test/package/comments/test_write_text_t.rb +0 -44
@@ -285,7 +285,7 @@ class Worksheet
285
285
  PADDING = 5 # :nodoc:
286
286
 
287
287
  attr_reader :index # :nodoc:
288
- attr_reader :charts, :images, :tables, :shapes, :drawing # :nodoc:
288
+ attr_reader :charts, :images, :tables, :shapes, :drawings # :nodoc:
289
289
  attr_reader :header_images, :footer_images # :nodoc:
290
290
  attr_reader :vml_drawing_links # :nodoc:
291
291
  attr_reader :vml_data_id # :nodoc:
@@ -294,7 +294,7 @@ class Worksheet
294
294
  attr_reader :writer, :set_rows, :col_formats # :nodoc:
295
295
  attr_reader :vml_shape_id # :nodoc:
296
296
  attr_reader :comments, :comments_author # :nodoc:
297
- attr_accessor :dxf_priority # :nodoc:
297
+ attr_accessor :data_bars_2010, :dxf_priority # :nodoc:
298
298
  attr_reader :vba_codename # :nodoc:
299
299
  attr_writer :excel_version
300
300
 
@@ -308,17 +308,19 @@ def initialize(workbook, index, name) #:nodoc:
308
308
  @cell_data_table = {}
309
309
  @excel_version = 2007
310
310
  @palette = workbook.palette
311
+ @default_url_format = workbook.default_url_format
311
312
 
312
313
  @page_setup = PageSetup.new
313
314
 
314
- @screen_gridlines = true
315
- @show_zeros = true
316
- @dim_rowmin = nil
317
- @dim_rowmax = nil
318
- @dim_colmin = nil
319
- @dim_colmax = nil
320
- @selections = []
321
- @panes = []
315
+ @screen_gridlines = true
316
+ @show_zeros = true
317
+ @dim_rowmin = nil
318
+ @dim_rowmax = nil
319
+ @dim_colmin = nil
320
+ @dim_colmax = nil
321
+ @selections = []
322
+ @panes = []
323
+ @hide_row_col_headers = 0
322
324
 
323
325
  @tab_color = 0
324
326
 
@@ -363,6 +365,7 @@ def initialize(workbook, index, name) #:nodoc:
363
365
  @original_row_height = 15
364
366
  @default_row_height = 15
365
367
  @default_row_pixels = 20
368
+ @default_col_width = 8.43
366
369
  @default_col_pixels = 64
367
370
  @default_row_rezoed = 0
368
371
 
@@ -376,8 +379,9 @@ def initialize(workbook, index, name) #:nodoc:
376
379
 
377
380
  @validations = []
378
381
 
379
- @cond_formats = {}
380
- @dxf_priority = 1
382
+ @cond_formats = {}
383
+ @data_bars_2010 = []
384
+ @dxf_priority = 1
381
385
 
382
386
  if excel2003_style?
383
387
  @original_row_height = 12.75
@@ -422,7 +426,7 @@ def assemble_xml_file #:nodoc:
422
426
  write_legacy_drawing
423
427
  write_legacy_drawing_hf
424
428
  write_table_parts
425
- write_ext_sparklines
429
+ write_ext_list
426
430
  end
427
431
  end
428
432
  end
@@ -765,10 +769,10 @@ def set_column(*args)
765
769
 
766
770
  # Store the col sizes for use when calculating image vertices taking
767
771
  # hidden columns into account. Also store the column formats.
768
- width = 0 if ptrue?(hidden) # Set width to zero if hidden
772
+ width = @default_col_width unless width
769
773
 
770
774
  (firstcol .. lastcol).each do |col|
771
- @col_sizes[col] = width
775
+ @col_sizes[col] = [width, hidden]
772
776
  @col_formats[col] = format if format
773
777
  end
774
778
  end
@@ -2166,7 +2170,7 @@ def write_comment(*args)
2166
2170
  @has_vml = true
2167
2171
 
2168
2172
  # Process the properties of the cell comment.
2169
- @comments.add(Package::Comment.new(@workbook, self, row, col, string, options))
2173
+ @comments.add(@workbook, self, row, col, string, options)
2170
2174
  end
2171
2175
 
2172
2176
  #
@@ -2778,9 +2782,12 @@ def write_url(*args)
2778
2782
  store_hyperlink(row, col, hyperlink)
2779
2783
 
2780
2784
  if hyperlinks_count > 65_530
2781
- raise "URL '#{url}' added but number of URLS is over Excel's limit of 65,530 URLS per worksheet."
2785
+ raise "URL '#{url}' added but URL exceeds Excel's limit of 65,530 URLs per worksheet."
2782
2786
  end
2783
2787
 
2788
+ # Add the default URL format.
2789
+ xf = @default_url_format unless xf
2790
+
2784
2791
  # Write the hyperlink string.
2785
2792
  write_string(row, col, hyperlink.str, xf)
2786
2793
  end
@@ -2984,13 +2991,25 @@ def write_date_time(*args)
2984
2991
  #
2985
2992
  def insert_chart(*args)
2986
2993
  # Check for a cell reference in A1 notation and substitute row and column.
2987
- row, col, chart, x_offset, y_offset, x_scale, y_scale = row_col_notation(args)
2994
+ row, col, chart, *options = row_col_notation(args)
2988
2995
  raise WriteXLSXInsufficientArgumentError if [row, col, chart].include?(nil)
2989
2996
 
2997
+ if options.first.class == Hash
2998
+ params = options.first
2999
+ x_offset = params[:x_offset]
3000
+ y_offset = params[:y_offset]
3001
+ x_scale = params[:x_scale]
3002
+ y_scale = params[:y_scale]
3003
+ anchor = params[:object_position]
3004
+
3005
+ else
3006
+ x_offset, y_offset, x_scale, y_scale, anchor = options
3007
+ end
2990
3008
  x_offset ||= 0
2991
3009
  y_offset ||= 0
2992
3010
  x_scale ||= 1
2993
3011
  y_scale ||= 1
3012
+ anchor ||= 1
2994
3013
 
2995
3014
  raise "Not a Chart object in insert_chart()" unless chart.is_a?(Chart) || chart.is_a?(Chartsheet)
2996
3015
  raise "Not a embedded style Chart object in insert_chart()" if chart.respond_to?(:embedded) && chart.embedded == 0
@@ -3008,61 +3027,36 @@ def insert_chart(*args)
3008
3027
  x_offset = chart.x_offset if ptrue?(chart.x_offset)
3009
3028
  y_offset = chart.y_offset if ptrue?(chart.y_offset)
3010
3029
 
3011
- @charts << [row, col, chart, x_offset, y_offset, x_scale, y_scale]
3030
+ @charts << [row, col, chart, x_offset, y_offset, x_scale, y_scale, anchor]
3012
3031
  end
3013
3032
 
3014
3033
  #
3015
3034
  # :call-seq:
3016
- # insert_image(row, column, filename, x=0, y=0, x_scale=1, y_scale=1)
3017
- #
3018
- # Partially supported. Currently only works for 96 dpi images.
3019
- #
3020
- # This method can be used to insert a image into a worksheet. The image
3021
- # can be in PNG, JPEG or BMP format. The x, y, x_scale and y_scale
3022
- # parameters are optional.
3023
- #
3024
- # worksheet1.insert_image('A1', 'ruby.bmp')
3025
- # worksheet2.insert_image('A1', '../images/ruby.bmp')
3026
- # worksheet3.insert_image('A1', '.c:\images\ruby.bmp')
3027
- #
3028
- # The parameters +x+ and +y+ can be used to specify an offset from the top
3029
- # left hand corner of the cell specified by +row+ and +column+. The offset
3030
- # values are in pixels.
3031
- #
3032
- # worksheet1.insert_image('A1', 'ruby.bmp', 32, 10)
3033
- #
3034
- # The offsets can be greater than the width or height of the underlying
3035
- # cell. This can be occasionally useful if you wish to align two or more
3036
- # images relative to the same cell.
3037
- #
3038
- # The parameters +x_scale+ and +y_scale+ can be used to scale the inserted
3039
- # image horizontally and vertically:
3040
- #
3041
- # # Scale the inserted image: width x 2.0, height x 0.8
3042
- # worksheet.insert_image('A1', 'perl.bmp', 0, 0, 2, 0.8)
3043
- #
3044
- # Note: you must call set_row() or set_column() before insert_image()
3045
- # if you wish to change the default dimensions of any of the rows or
3046
- # columns that the image occupies. The height of a row can also change
3047
- # if you use a font that is larger than the default. This in turn will
3048
- # affect the scaling of your image. To avoid this you should explicitly
3049
- # set the height of the row using set_row() if it contains a font size
3050
- # that will change the row height.
3051
- #
3052
- # BMP images must be 24 bit, true colour, bitmaps. In general it is
3053
- # best to avoid BMP images since they aren't compressed.
3035
+ # insert_image(row, column, filename, options)
3054
3036
  #
3055
3037
  def insert_image(*args)
3056
3038
  # Check for a cell reference in A1 notation and substitute row and column.
3057
- row, col, image, x_offset, y_offset, x_scale, y_scale = row_col_notation(args)
3039
+ row, col, image, *options = row_col_notation(args)
3058
3040
  raise WriteXLSXInsufficientArgumentError if [row, col, image].include?(nil)
3059
3041
 
3042
+ if options.first.class == Hash
3043
+ # Newer hash bashed options
3044
+ params = options.first
3045
+ x_offset = params[:x_offset]
3046
+ y_offset = params[:y_offset]
3047
+ x_scale = params[:x_scale]
3048
+ y_scale = params[:y_scale]
3049
+ anchor = params[:object_position]
3050
+ else
3051
+ x_offset, y_offset, x_scale, y_scale, anchor = options
3052
+ end
3060
3053
  x_offset ||= 0
3061
3054
  y_offset ||= 0
3062
3055
  x_scale ||= 1
3063
3056
  y_scale ||= 1
3057
+ anchor ||= 2
3064
3058
 
3065
- @images << [row, col, image, x_offset, y_offset, x_scale, y_scale]
3059
+ @images << [row, col, image, x_offset, y_offset, x_scale, y_scale, anchor]
3066
3060
  end
3067
3061
 
3068
3062
  #
@@ -3300,10 +3294,8 @@ def set_row(*args)
3300
3294
  # Store the row change to allow optimisations.
3301
3295
  @row_size_changed = true
3302
3296
 
3303
- height = 0 if ptrue?(hidden)
3304
-
3305
3297
  # Store the row sizes for use when calculating image vertices.
3306
- @row_sizes[row] = height
3298
+ @row_sizes[row] = [height, hidden]
3307
3299
  end
3308
3300
 
3309
3301
  #
@@ -5339,6 +5331,13 @@ def print_row_col_headers(headers = true)
5339
5331
  # end
5340
5332
  end
5341
5333
 
5334
+ #
5335
+ # Set the option to hide the row and column headers in Excel.
5336
+ #
5337
+ def hide_row_col_headers
5338
+ @hide_row_col_headers = 1
5339
+ end
5340
+
5342
5341
  #
5343
5342
  # The fit_to_pages() method is used to fit the printed area to a specific
5344
5343
  # number of pages both vertically and horizontally. If the printed area
@@ -5711,7 +5710,7 @@ def set_external_comment_links(comment_id) # :nodoc:
5711
5710
  def prepare_chart(index, chart_id, drawing_id) # :nodoc:
5712
5711
  drawing_type = 1
5713
5712
 
5714
- row, col, chart, x_offset, y_offset, x_scale, y_scale = @charts[index]
5713
+ row, col, chart, x_offset, y_offset, x_scale, y_scale, anchor = @charts[index]
5715
5714
  chart.id = chart_id - 1
5716
5715
  x_scale ||= 0
5717
5716
  y_scale ||= 0
@@ -5723,22 +5722,21 @@ def prepare_chart(index, chart_id, drawing_id) # :nodoc:
5723
5722
  width = (0.5 + (width * x_scale)).to_i
5724
5723
  height = (0.5 + (height * y_scale)).to_i
5725
5724
 
5726
- dimensions = position_object_emus(col, row, x_offset, y_offset, width, height)
5725
+ dimensions = position_object_emus(col, row, x_offset, y_offset, width, height, anchor)
5727
5726
 
5728
5727
  # Set the chart name for the embedded object if it has been specified.
5729
5728
  name = chart.name
5730
5729
 
5731
5730
  # Create a Drawing object to use with worksheet unless one already exists.
5732
- if !drawing?
5733
- drawing = Drawing.new
5734
- drawing.add_drawing_object(drawing_type, dimensions, 0, 0, name)
5735
- drawing.embedded = 1
5736
-
5737
- @drawing = drawing
5731
+ drawing = Drawing.new(drawing_type, dimensions, 0, 0, name, nil, anchor)
5732
+ if !drawings?
5733
+ @drawings = Drawings.new
5734
+ @drawings.add_drawing_object(drawing)
5735
+ @drawings.embedded = 1
5738
5736
 
5739
5737
  @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml" ]
5740
5738
  else
5741
- @drawing.add_drawing_object(drawing_type, dimensions, 0, 0, name)
5739
+ @drawings.add_drawing_object(drawing)
5742
5740
  end
5743
5741
  @drawing_links << ['/chart', "../charts/chart#{chart_id}.xml"]
5744
5742
  end
@@ -5809,6 +5807,10 @@ def get_range_data(row_start, col_start, row_end, col_end) # :nodoc:
5809
5807
  # The values of col_start and row_start are passed in from the calling
5810
5808
  # function. The values of col_end and row_end are calculated by subtracting
5811
5809
  # the width and height of the object from the width and height of the
5810
+ # The anchor/object position defines how images are scaled for hidden rows and
5811
+ # columns. For option 1 "Move and size with cells" the size of the hidden
5812
+ # row/column is subtracted from the image.
5813
+ #
5812
5814
  # underlying cells.
5813
5815
  #
5814
5816
  # col_start # Col containing upper left corner of object.
@@ -5821,7 +5823,7 @@ def get_range_data(row_start, col_start, row_end, col_end) # :nodoc:
5821
5823
  # y2 # Distance to bottom of object.
5822
5824
  # width # Width of object frame.
5823
5825
  # height # Height of object frame.
5824
- def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
5826
+ def position_object_pixels(col_start, row_start, x1, y1, width, height, anchor = nil) #:nodoc:
5825
5827
  # Adjust start column for negative offsets.
5826
5828
  while x1 < 0 && col_start > 0
5827
5829
  x1 += size_col(col_start - 1)
@@ -5840,7 +5842,7 @@ def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
5840
5842
 
5841
5843
  # Calculate the absolute x offset of the top-left vertex.
5842
5844
  if @col_size_changed
5843
- x_abs = (0 .. col_start-1).inject(0) {|sum, col| sum += size_col(col)}
5845
+ x_abs = (0 .. col_start-1).inject(0) {|sum, col| sum += size_col(col, anchor)}
5844
5846
  else
5845
5847
  # Optimisation for when the column widths haven't changed.
5846
5848
  x_abs = @default_col_pixels * col_start
@@ -5850,7 +5852,7 @@ def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
5850
5852
  # Calculate the absolute y offset of the top-left vertex.
5851
5853
  # Store the column change to allow optimisations.
5852
5854
  if @row_size_changed
5853
- y_abs = (0 .. row_start-1).inject(0) {|sum, row| sum += size_row(row)}
5855
+ y_abs = (0 .. row_start-1).inject(0) {|sum, row| sum += size_row(row, anchor)}
5854
5856
  else
5855
5857
  # Optimisation for when the row heights haven't changed.
5856
5858
  y_abs = @default_row_pixels * row_start
@@ -5858,23 +5860,39 @@ def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
5858
5860
  y_abs += y1
5859
5861
 
5860
5862
  # Adjust start column for offsets that are greater than the col width.
5861
- x1, col_start = adjust_column_offset(x1, col_start)
5863
+ if size_col(col_start) > 0
5864
+ while x1 >= size_col(col_start)
5865
+ x1 -= size_col(col_start)
5866
+ col_start += 1
5867
+ end
5868
+ end
5862
5869
 
5863
5870
  # Adjust start row for offsets that are greater than the row height.
5864
- y1, row_start = adjust_row_offset(y1, row_start)
5871
+ if size_row(row_start) > 0
5872
+ while y1 >= size_row(row_start)
5873
+ y1 -= size_row(row_start)
5874
+ row_start += 1
5875
+ end
5876
+ end
5865
5877
 
5866
5878
  # Initialise end cell to the same as the start cell.
5867
5879
  col_end = col_start
5868
5880
  row_end = row_start
5869
5881
 
5870
- width += x1
5871
- height += y1
5882
+ width += x1 if size_col(col_start) > 0
5883
+ height += y1 if size_row(row_start) > 0
5872
5884
 
5873
5885
  # Subtract the underlying cell widths to find the end cell of the object.
5874
- width, col_end = adjust_column_offset(width, col_end)
5886
+ while width >= size_col(col_end, anchor)
5887
+ width -= size_col(col_end, anchor)
5888
+ col_end += 1
5889
+ end
5875
5890
 
5876
5891
  # Subtract the underlying cell heights to find the end cell of the object.
5877
- height, row_end = adjust_row_offset(height, row_end)
5892
+ while height >= size_row(row_end, anchor)
5893
+ height -= size_row(row_end, anchor)
5894
+ row_end += 1
5895
+ end
5878
5896
 
5879
5897
  # The end vertices are whatever is left from the width and height.
5880
5898
  x2 = width
@@ -6037,6 +6055,26 @@ def set_vba_name(vba_codename = nil)
6037
6055
  end
6038
6056
  end
6039
6057
 
6058
+ def write_ext(url)
6059
+ attributes = [
6060
+ ['xmlns:x14', "#{OFFICE_URL}spreadsheetml/2009/9/main"],
6061
+ ['uri', url]
6062
+ ]
6063
+ @writer.tag_elements('ext', attributes) do
6064
+ yield
6065
+ end
6066
+ end
6067
+
6068
+ def write_sparkline_groups
6069
+ # Write the x14:sparklineGroups element.
6070
+ @writer.tag_elements('x14:sparklineGroups', sparkline_groups_attributes) do
6071
+ # Write the sparkline elements.
6072
+ @sparklines.reverse.each do |sparkline|
6073
+ sparkline.write_sparkline_group(@writer)
6074
+ end
6075
+ end
6076
+ end
6077
+
6040
6078
  private
6041
6079
 
6042
6080
  def hyperlinks_count
@@ -6314,32 +6352,16 @@ def sort_pagebreaks(*args) #:nodoc:
6314
6352
  end
6315
6353
  end
6316
6354
 
6317
- def adjust_column_offset(x, column)
6318
- while x >= size_col(column)
6319
- x -= size_col(column)
6320
- column += 1
6321
- end
6322
- [x, column]
6323
- end
6324
-
6325
- def adjust_row_offset(y, row)
6326
- while y >= size_row(row)
6327
- y -= size_row(row)
6328
- row += 1
6329
- end
6330
- [y, row]
6331
- end
6332
-
6333
6355
  #
6334
6356
  # Calculate the vertices that define the position of a graphical object within
6335
6357
  # the worksheet in EMUs.
6336
6358
  #
6337
6359
  # The vertices are expressed as English Metric Units (EMUs). There are 12,700
6338
- # EMUs per point. Therefore, 12,700 * 3 /4 = 9,525 EMUs per pixel.
6360
+ # EMUs per point. Therefore, 12,700 * 3 /4 = 9,525 EMUs per el.
6339
6361
  #
6340
- def position_object_emus(col_start, row_start, x1, y1, width, height, x_dpi = 96, y_dpi = 96) #:nodoc:
6362
+ def position_object_emus(col_start, row_start, x1, y1, width, height, anchor = nil) #:nodoc:
6341
6363
  col_start, row_start, x1, y1, col_end, row_end, x2, y2, x_abs, y_abs =
6342
- position_object_pixels(col_start, row_start, x1, y1, width, height)
6364
+ position_object_pixels(col_start, row_start, x1, y1, width, height, anchor)
6343
6365
 
6344
6366
  # Convert the pixel values to EMUs. See above.
6345
6367
  x1 = (0.5 + 9_525 * x1).to_i
@@ -6355,15 +6377,16 @@ def position_object_emus(col_start, row_start, x1, y1, width, height, x_dpi = 96
6355
6377
  #
6356
6378
  # Convert the width of a cell from user's units to pixels. Excel rounds the
6357
6379
  # column width to the nearest pixel. If the width hasn't been set by the user
6358
- # we use the default value. If the column is hidden it has a value of zero.
6380
+ # we use the default value. A hidden column is treated as having a width of
6381
+ # zero unless it has the special "object_position" of 4 (size with cells).
6359
6382
  #
6360
- def size_col(col) #:nodoc:
6383
+ def size_col(col, anchor = 0) #:nodoc:
6361
6384
  # Look up the cell value to see if it has been changed.
6362
6385
  if @col_sizes[col]
6363
- width = @col_sizes[col]
6386
+ width, hidden = @col_sizes[col]
6364
6387
 
6365
6388
  # Convert to pixels.
6366
- if width == 0
6389
+ if hidden == 1 && anchor != 4
6367
6390
  pixels = 0
6368
6391
  elsif width < 1
6369
6392
  pixels = (width * (MAX_DIGIT_WIDTH + PADDING) + 0.5).to_i
@@ -6378,15 +6401,16 @@ def size_col(col) #:nodoc:
6378
6401
 
6379
6402
  #
6380
6403
  # Convert the height of a cell from user's units to pixels. If the height
6381
- # hasn't been set by the user we use the default value. If the row is hidden
6382
- # it has a value of zero.
6404
+ # hasn't been set by the user we use the default value. A hidden row is
6405
+ # treated as having a height of zero unless it has the special
6406
+ # "object_position" of 4 (size with cells).
6383
6407
  #
6384
- def size_row(row) #:nodoc:
6408
+ def size_row(row, anchor = 0) #:nodoc:
6385
6409
  # Look up the cell value to see if it has been changed
6386
6410
  if @row_sizes[row]
6387
- height = @row_sizes[row]
6411
+ height, hidden = @row_sizes[row]
6388
6412
 
6389
- if height == 0
6413
+ if hidden == 1 && anchor != 4
6390
6414
  pixels = 0
6391
6415
  else
6392
6416
  pixels = (4 / 3.0 * height).to_i
@@ -6404,9 +6428,8 @@ def prepare_image(index, image_id, drawing_id, width, height, name, image_type,
6404
6428
  x_dpi ||= 96
6405
6429
  y_dpi ||= 96
6406
6430
  drawing_type = 2
6407
- drawing
6408
6431
 
6409
- row, col, image, x_offset, y_offset, x_scale, y_scale = @images[index]
6432
+ row, col, image, x_offset, y_offset, x_scale, y_scale, anchor = @images[index]
6410
6433
 
6411
6434
  width *= x_scale
6412
6435
  height *= y_scale
@@ -6414,24 +6437,25 @@ def prepare_image(index, image_id, drawing_id, width, height, name, image_type,
6414
6437
  width *= 96.0 / x_dpi
6415
6438
  height *= 96.0 / y_dpi
6416
6439
 
6417
- dimensions = position_object_emus(col, row, x_offset, y_offset, width, height)
6440
+ dimensions = position_object_emus(col, row, x_offset, y_offset, width, height, anchor)
6418
6441
 
6419
6442
  # Convert from pixels to emus.
6420
6443
  width = (0.5 + (width * 9_525)).to_i
6421
6444
  height = (0.5 + (height * 9_525)).to_i
6422
6445
 
6423
6446
  # Create a Drawing object to use with worksheet unless one already exists.
6424
- if !drawing?
6425
- drawing = Drawing.new
6426
- drawing.embedded = 1
6447
+ drawing = Drawing.new(drawing_type, dimensions, width, height, name, nil, anchor)
6448
+ if !drawings?
6449
+ drawings = Drawings.new
6450
+ drawings.embedded = 1
6427
6451
 
6428
- @drawing = drawing
6452
+ @drawings = drawings
6429
6453
 
6430
6454
  @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml"]
6431
6455
  else
6432
- drawing = @drawing
6456
+ drawings = @drawings
6433
6457
  end
6434
- drawing.add_drawing_object(drawing_type, dimensions, width, height, name)
6458
+ drawings.add_drawing_object(drawing)
6435
6459
 
6436
6460
  @drawing_links << ['/image', "../media/image#{image_id}.#{image_type}"]
6437
6461
  end
@@ -6486,16 +6510,16 @@ def prepare_header_image(image_id, width, height, name, image_type, position, x_
6486
6510
  #
6487
6511
  def insert_shape(*args)
6488
6512
  # Check for a cell reference in A1 notation and substitute row and column.
6489
- row_start, column_start, shape, x_offset, y_offset, x_scale, y_scale =
6513
+ row_start, column_start, shape, x_offset, y_offset, x_scale, y_scale, anchor =
6490
6514
  row_col_notation(args)
6491
6515
  if [row_start, column_start, shape].include?(nil)
6492
6516
  raise "Insufficient arguments in insert_shape()"
6493
6517
  end
6494
6518
 
6495
6519
  shape.set_position(
6496
- row_start, column_start, x_offset, y_offset,
6497
- x_scale, y_scale
6498
- )
6520
+ row_start, column_start, x_offset, y_offset,
6521
+ x_scale, y_scale, anchor
6522
+ )
6499
6523
  # Assign a shape ID.
6500
6524
  while true
6501
6525
  id = shape.id || 0
@@ -6539,9 +6563,9 @@ def prepare_shape(index, drawing_id)
6539
6563
  shape = @shapes[index]
6540
6564
 
6541
6565
  # Create a Drawing object to use with worksheet unless one already exists.
6542
- unless drawing?
6543
- @drawing = Drawing.new
6544
- @drawing.embedded = 1
6566
+ unless drawings?
6567
+ @drawings = Drawings.new
6568
+ @drawings.embedded = 1
6545
6569
  @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml"]
6546
6570
  @has_shapes = true
6547
6571
  end
@@ -6551,13 +6575,14 @@ def prepare_shape(index, drawing_id)
6551
6575
  shape.calc_position_emus(self)
6552
6576
 
6553
6577
  drawing_type = 3
6554
- drawing.add_drawing_object(drawing_type, shape.dimensions, shape.name, shape)
6578
+ drawing = Drawing.new(drawing_type, shape.dimensions, shape.width_emu, shape.height_emu, shape.name, shape, shape.anchor)
6579
+ drawings.add_drawing_object(drawing)
6555
6580
  end
6556
6581
  public :prepare_shape
6557
6582
 
6558
6583
  #
6559
6584
  # This method handles the parameters passed to insert_button as well as
6560
- # calculating the comment object position and vertices.
6585
+ # calculating the button object position and vertices.
6561
6586
  #
6562
6587
  def button_params(row, col, params)
6563
6588
  button = Writexlsx::Package::Button.new
@@ -6586,7 +6611,7 @@ def button_params(row, col, params)
6586
6611
  params[:x_offset] = 0 if !params[:x_offset]
6587
6612
  params[:y_offset] = 0 if !params[:y_offset]
6588
6613
 
6589
- # Scale the size of the comment box if required.
6614
+ # Scale the size of the button box if required.
6590
6615
  if params[:x_scale]
6591
6616
  params[:width] = params[:width] * params[:x_scale]
6592
6617
  end
@@ -6601,15 +6626,15 @@ def button_params(row, col, params)
6601
6626
  params[:start_row] = row
6602
6627
  params[:start_col] = col
6603
6628
 
6604
- # Calculate the positions of comment object.
6629
+ # Calculate the positions of button object.
6605
6630
  vertices = position_object_pixels(
6606
- params[:start_col],
6607
- params[:start_row],
6608
- params[:x_offset],
6609
- params[:y_offset],
6610
- params[:width],
6611
- params[:height]
6612
- )
6631
+ params[:start_col],
6632
+ params[:start_row],
6633
+ params[:x_offset],
6634
+ params[:y_offset],
6635
+ params[:width],
6636
+ params[:height]
6637
+ )
6613
6638
 
6614
6639
  # Add the width and height for VML.
6615
6640
  vertices << [params[:width], params[:height]]
@@ -6648,9 +6673,10 @@ def encode_password(password) #:nodoc:
6648
6673
  def write_worksheet_attributes #:nodoc:
6649
6674
  schema = 'http://schemas.openxmlformats.org/'
6650
6675
  attributes = [
6651
- ['xmlns', "#{schema}spreadsheetml/2006/main"],
6652
- ['xmlns:r', "#{schema}officeDocument/2006/relationships"]
6653
- ]
6676
+ ['xmlns', "#{schema}spreadsheetml/2006/main"],
6677
+ ['xmlns:r', "#{schema}officeDocument/2006/relationships"]
6678
+ ]
6679
+
6654
6680
  if @excel_version == 2010
6655
6681
  attributes << ['xmlns:mc', "#{schema}markup-compatibility/2006"]
6656
6682
  attributes << ['xmlns:x14ac', "#{OFFICE_URL}spreadsheetml/2009/9/ac"]
@@ -6731,9 +6757,12 @@ def write_sheet_views #:nodoc:
6731
6757
 
6732
6758
  def write_sheet_view #:nodoc:
6733
6759
  attributes = []
6734
- # Hide screen gridlines if required
6760
+ # Hide screen gridlines if required.
6735
6761
  attributes << ['showGridLines', 0] unless @screen_gridlines
6736
6762
 
6763
+ # Hide the row/column headers.
6764
+ attributes << ['showRowColHeaders', 0] if ptrue?(@hide_row_col_headers)
6765
+
6737
6766
  # Hide zeroes in cells.
6738
6767
  attributes << ['showZeros', 0] unless show_zeros?
6739
6768
 
@@ -6845,7 +6874,7 @@ def col_info_attributes(args)
6845
6874
  custom_width = false if width.nil? && hidden == 0
6846
6875
  custom_width = false if width == 8.43
6847
6876
 
6848
- width = hidden == 0 ? 8.43 : 0 unless width
6877
+ width = hidden == 0 ? @default_col_width : 0 unless width
6849
6878
 
6850
6879
  # Convert column width from user units to character width.
6851
6880
  if width && width < 1
@@ -7268,13 +7297,20 @@ def write_filter_column(col_id, type, *filters) #:nodoc:
7268
7297
  # Write the <filters> element.
7269
7298
  #
7270
7299
  def write_filters(*filters) #:nodoc:
7271
- if filters.size == 1 && filters[0] == 'blanks'
7300
+ non_blanks = filters.reject { |filter| filter =~ /^blanks$/i }
7301
+ attributes = []
7302
+
7303
+ if filters != non_blanks
7304
+ attributes = [ ['blank', 1] ]
7305
+ end
7306
+
7307
+ if filters.size == 1 && non_blanks.empty?
7272
7308
  # Special case for blank cells only.
7273
- @writer.empty_tag('filters', [ ['blank', 1] ])
7309
+ @writer.empty_tag('filters', attributes)
7274
7310
  else
7275
7311
  # General case.
7276
- @writer.tag_elements('filters') do
7277
- filters.each { |filter| write_filter(filter) }
7312
+ @writer.tag_elements('filters', attributes) do
7313
+ non_blanks.sort.each { |filter| write_filter(filter) }
7278
7314
  end
7279
7315
  end
7280
7316
  end
@@ -7448,7 +7484,7 @@ def write_sheet_protection #:nodoc:
7448
7484
  # Write the <drawing> elements.
7449
7485
  #
7450
7486
  def write_drawings #:nodoc:
7451
- increment_rel_id_and_write_r_id('drawing') if drawing?
7487
+ increment_rel_id_and_write_r_id('drawing') if drawings?
7452
7488
  end
7453
7489
 
7454
7490
  #
@@ -7506,31 +7542,229 @@ def write_r_id(tag, id)
7506
7542
  end
7507
7543
 
7508
7544
  #
7509
- # Write the <extLst> element and sparkline subelements.
7545
+ # Write the <extLst> element for data bars and sparklines.
7510
7546
  #
7511
- def write_ext_sparklines # :nodoc:
7512
- @writer.tag_elements('extLst') { write_ext } unless @sparklines.empty?
7547
+ def write_ext_list # :nodoc:
7548
+ return if @data_bars_2010.empty? && @sparklines.empty?
7549
+
7550
+ @writer.tag_elements('extLst') do
7551
+ write_ext_list_data_bars if @data_bars_2010.size > 0
7552
+ write_ext_list_sparklines if @sparklines.size > 0
7553
+ end
7513
7554
  end
7514
7555
 
7515
- def write_ext
7516
- @writer.tag_elements('ext', write_ext_attributes) do
7517
- write_sparkline_groups
7556
+ #
7557
+ # Write the Excel 2010 data_bar subelements.
7558
+ #
7559
+ def write_ext_list_data_bars
7560
+ # Write the ext element.
7561
+ write_ext('{78C0D931-6437-407d-A8EE-F0AAD7539E65}') do
7562
+
7563
+ @writer.tag_elements('x14:conditionalFormattings') do
7564
+ # Write each of the Excel 2010 conditional formatting data bar elements.
7565
+ @data_bars_2010.each do |data_bar|
7566
+ # Write the x14:conditionalFormatting element.
7567
+ write_conditional_formatting_2010(data_bar)
7568
+ end
7569
+ end
7518
7570
  end
7519
7571
  end
7572
+ #
7573
+ # Write the <x14:conditionalFormatting> element.
7574
+ #
7575
+ def write_conditional_formatting_2010(data_bar)
7576
+ xmlns_xm = 'http://schemas.microsoft.com/office/excel/2006/main'
7520
7577
 
7521
- def write_ext_attributes
7522
- [
7523
- ['xmlns:x14', "#{OFFICE_URL}spreadsheetml/2009/9/main"],
7524
- ['uri', '{05C60535-1F16-4fd2-B633-F4F36F0B64E0}']
7578
+ attributes = [ ['xmlns:xm', xmlns_xm] ]
7579
+
7580
+ @writer.tag_elements('x14:conditionalFormatting', attributes) do
7581
+
7582
+ # Write the '<x14:cfRule element.
7583
+ write_x14_cf_rule(data_bar)
7584
+
7585
+ # Write the x14:dataBar element.
7586
+ write_x14_data_bar(data_bar)
7587
+
7588
+ # Write the x14 max and min data bars.
7589
+ write_x14_cfvo(data_bar[:x14_min_type], data_bar[:min_value])
7590
+ write_x14_cfvo(data_bar[:x14_max_type], data_bar[:max_value])
7591
+
7592
+ # Write the x14:borderColor element.
7593
+ if !ptrue?(data_bar[:bar_no_border])
7594
+ write_x14_border_color(data_bar[:bar_border_color])
7595
+ end
7596
+
7597
+ # Write the x14:negativeFillColor element.
7598
+ if !ptrue?(data_bar[:bar_negative_color_same])
7599
+ write_x14_negative_fill_color(data_bar[:bar_negative_color])
7600
+ end
7601
+
7602
+ # Write the x14:negativeBorderColor element.
7603
+ if !ptrue?(data_bar[:bar_no_border]) &&
7604
+ !ptrue?(data_bar[:bar_negative_border_color_same])
7605
+ write_x14_negative_border_color(
7606
+ data_bar[:bar_negative_border_color])
7607
+ end
7608
+
7609
+ # Write the x14:axisColor element.
7610
+ if data_bar[:bar_axis_position] != 'none'
7611
+ write_x14_axis_color(data_bar[:bar_axis_color])
7612
+ end
7613
+
7614
+ # Write closing elements.
7615
+ @writer.end_tag('x14:dataBar')
7616
+ @writer.end_tag('x14:cfRule')
7617
+
7618
+ # Add the conditional format range.
7619
+ @writer.data_element('xm:sqref', data_bar[:range])
7620
+ end
7621
+ end
7622
+
7623
+ #
7624
+ # Write the <cfvo> element.
7625
+ #
7626
+ def write_x14_cfvo(type, value)
7627
+ attributes = [ ['type', type ] ]
7628
+
7629
+ if %w(min max autoMin autoMax).include?(type)
7630
+ @writer.empty_tag('x14:cfvo', attributes)
7631
+ else
7632
+ @writer.tag_elements('x14:cfvo', attributes) do
7633
+ @writer.data_element('xm:f', value)
7634
+ end
7635
+ end
7636
+ end
7637
+
7638
+ #
7639
+ # Write the <'<x14:cfRule> element.
7640
+ #
7641
+ def write_x14_cf_rule(data_bar)
7642
+ type = 'dataBar'
7643
+ id = data_bar[:guid]
7644
+
7645
+ attributes = [
7646
+ ['type', type],
7647
+ ['id', id]
7525
7648
  ]
7649
+
7650
+ @writer.start_tag('x14:cfRule', attributes)
7651
+
7526
7652
  end
7527
7653
 
7528
- def write_sparkline_groups
7529
- # Write the x14:sparklineGroups element.
7530
- @writer.tag_elements('x14:sparklineGroups', sparkline_groups_attributes) do
7531
- # Write the sparkline elements.
7532
- @sparklines.reverse.each do |sparkline|
7533
- sparkline.write_sparkline_group(@writer)
7654
+ #
7655
+ # Write the <x14:dataBar> element.
7656
+ #
7657
+ def write_x14_data_bar(data_bar)
7658
+ min_length = 0
7659
+ max_length = 100
7660
+
7661
+ attributes = [
7662
+ ['minLength', min_length],
7663
+ ['maxLength', max_length]
7664
+ ]
7665
+
7666
+ attributes << ['border', 1] if !ptrue?(data_bar[:bar_no_border])
7667
+ attributes << ['gradient', 0] if ptrue?(data_bar[:bar_solid])
7668
+
7669
+ if data_bar[:bar_direction] == 'left'
7670
+ attributes << ['direction', 'leftToRight']
7671
+ end
7672
+ if data_bar[:bar_direction] == 'right'
7673
+ attributes << ['direction', 'rightToLeft']
7674
+ end
7675
+
7676
+ if ptrue?(data_bar[:bar_negative_color_same])
7677
+ attributes << ['negativeBarColorSameAsPositive', 1]
7678
+ end
7679
+
7680
+ if !ptrue?(data_bar[:bar_no_border]) &&
7681
+ !ptrue?(data_bar[:bar_negative_border_color_same])
7682
+ attributes << ['negativeBarBorderColorSameAsPositive', 0]
7683
+ end
7684
+
7685
+ if data_bar[:bar_axis_position] == 'middle'
7686
+ attributes << ['axisPosition', 'middle']
7687
+ end
7688
+
7689
+ if data_bar[:bar_axis_position] == 'none'
7690
+ attributes << ['axisPosition', 'none']
7691
+ end
7692
+
7693
+ @writer.start_tag('x14:dataBar', attributes)
7694
+ end
7695
+
7696
+ #
7697
+ # Write the <x14:borderColor> element.
7698
+ #
7699
+ def write_x14_border_color(rgb)
7700
+ attributes = [ ['rgb', rgb] ]
7701
+
7702
+ @writer.empty_tag('x14:borderColor', attributes)
7703
+ end
7704
+
7705
+ #
7706
+ # Write the <x14:negativeFillColor> element.
7707
+ #
7708
+ def write_x14_negative_fill_color(rgb)
7709
+ attributes = [ ['rgb', rgb] ]
7710
+
7711
+ @writer.empty_tag('x14:negativeFillColor', attributes)
7712
+ end
7713
+
7714
+ #
7715
+ # Write the <x14:negativeBorderColor> element.
7716
+ #
7717
+ def write_x14_negative_border_color(rgb)
7718
+ attributes = [ ['rgb', rgb] ]
7719
+
7720
+ @writer.empty_tag('x14:negativeBorderColor', attributes)
7721
+ end
7722
+
7723
+ #
7724
+ # Write the <x14:axisColor> element.
7725
+ #
7726
+ def write_x14_axis_color(rgb)
7727
+ attributes = [ ['rgb', rgb] ]
7728
+
7729
+ @writer.empty_tag('x14:axisColor', attributes)
7730
+ end
7731
+
7732
+ #
7733
+ # Write the sparkline subelements.
7734
+ #
7735
+ def write_ext_list_sparklines
7736
+ # Write the ext element.
7737
+ write_ext('{05C60535-1F16-4fd2-B633-F4F36F0B64E0}') do
7738
+
7739
+ # Write the x14:sparklineGroups element.
7740
+ write_sparkline_groups
7741
+
7742
+ # # Write the sparkline elements.
7743
+ # @sparklines.reverse.each do |sparkline|
7744
+ # # Write the x14:sparklineGroup element.
7745
+ # # sparkline.write_sparkline_group(@writer)
7746
+
7747
+ # @writer.end_tag('x14:sparklineGroup')
7748
+ # end
7749
+
7750
+ # @writer.end_tag('x14:sparklineGroups')
7751
+ end
7752
+ end
7753
+
7754
+ #
7755
+ # Write the <x14:sparklines> element and <x14:sparkline> subelements.
7756
+ #
7757
+ def write_sparklines(sparkline)
7758
+ # Write the sparkline elements.
7759
+ @writer.tag_elements('x14:sparklines') do
7760
+ (0..sparkline[:count]-1).each do |i|
7761
+ range = sparkline[:ranges][i]
7762
+ location = sparkline[:locations][i]
7763
+
7764
+ @writer.tag_elements('x14:sparkline') do
7765
+ @writer.data_element('xm:f', range)
7766
+ @writer.data_element('xm:sqref', location)
7767
+ end
7534
7768
  end
7535
7769
  end
7536
7770
  end
@@ -7728,8 +7962,8 @@ def autofilter_ref? #:nodoc:
7728
7962
  !!@autofilter_ref
7729
7963
  end
7730
7964
 
7731
- def drawing? #:nodoc:
7732
- !!@drawing
7965
+ def drawings? #:nodoc:
7966
+ !!@drawings
7733
7967
  end
7734
7968
 
7735
7969
  def remove_white_space(margin) #:nodoc: