write_xlsx 0.89.0 → 1.01.0

Sign up to get free protection for your applications and to get access to all the features.
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: