write_xlsx 0.97.0 → 1.04.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 (313) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Changes +78 -0
  4. data/LICENSE.txt +1 -1
  5. data/README.md +2 -2
  6. data/examples/a_simple.rb +1 -1
  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 +90 -12
  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/data_validate.rb +1 -1
  28. data/examples/date_time.rb +1 -1
  29. data/examples/demo.rb +4 -1
  30. data/examples/formats.rb +1 -1
  31. data/examples/headers.rb +1 -1
  32. data/examples/hide_row_col.rb +1 -1
  33. data/examples/hide_sheet.rb +1 -1
  34. data/examples/hyperlink1.rb +1 -1
  35. data/examples/indent.rb +1 -1
  36. data/examples/macros.rb +1 -1
  37. data/examples/merge1.rb +1 -1
  38. data/examples/merge2.rb +1 -1
  39. data/examples/merge3.rb +1 -1
  40. data/examples/merge4.rb +1 -1
  41. data/examples/merge5.rb +1 -1
  42. data/examples/merge6.rb +1 -1
  43. data/examples/outline.rb +1 -1
  44. data/examples/outline_collapsed.rb +1 -1
  45. data/examples/panes.rb +1 -1
  46. data/examples/properties.rb +1 -1
  47. data/examples/regions.rb +1 -1
  48. data/examples/rich_strings.rb +1 -1
  49. data/examples/right_to_left.rb +1 -1
  50. data/examples/shape1.rb +1 -1
  51. data/examples/shape2.rb +1 -1
  52. data/examples/shape3.rb +1 -1
  53. data/examples/shape4.rb +1 -1
  54. data/examples/shape5.rb +1 -1
  55. data/examples/shape6.rb +1 -1
  56. data/examples/shape7.rb +1 -1
  57. data/examples/shape8.rb +1 -1
  58. data/examples/shape_all.rb +1 -1
  59. data/examples/sparklines1.rb +1 -1
  60. data/examples/sparklines2.rb +1 -1
  61. data/examples/stats.rb +1 -1
  62. data/examples/stats_ext.rb +1 -1
  63. data/examples/stocks.rb +1 -1
  64. data/examples/tab_colors.rb +1 -1
  65. data/examples/tables.rb +78 -43
  66. data/lib/write_xlsx/chart.rb +43 -35
  67. data/lib/write_xlsx/chart/area.rb +1 -1
  68. data/lib/write_xlsx/chart/axis.rb +2 -2
  69. data/lib/write_xlsx/chart/bar.rb +1 -1
  70. data/lib/write_xlsx/chart/column.rb +1 -1
  71. data/lib/write_xlsx/chart/doughnut.rb +1 -1
  72. data/lib/write_xlsx/chart/legend.rb +14 -0
  73. data/lib/write_xlsx/chart/line.rb +16 -2
  74. data/lib/write_xlsx/chart/pie.rb +30 -15
  75. data/lib/write_xlsx/chart/radar.rb +1 -1
  76. data/lib/write_xlsx/chart/scatter.rb +1 -1
  77. data/lib/write_xlsx/chart/stock.rb +1 -1
  78. data/lib/write_xlsx/chartsheet.rb +35 -7
  79. data/lib/write_xlsx/drawing.rb +86 -30
  80. data/lib/write_xlsx/format.rb +9 -9
  81. data/lib/write_xlsx/package/comments.rb +61 -58
  82. data/lib/write_xlsx/package/conditional_format.rb +9 -1
  83. data/lib/write_xlsx/package/relationships.rb +4 -4
  84. data/lib/write_xlsx/package/styles.rb +26 -8
  85. data/lib/write_xlsx/package/table.rb +13 -7
  86. data/lib/write_xlsx/package/vml.rb +20 -19
  87. data/lib/write_xlsx/shape.rb +4 -3
  88. data/lib/write_xlsx/sheets.rb +18 -16
  89. data/lib/write_xlsx/sparkline.rb +1 -1
  90. data/lib/write_xlsx/utility.rb +96 -7
  91. data/lib/write_xlsx/version.rb +1 -1
  92. data/lib/write_xlsx/workbook.rb +99 -49
  93. data/lib/write_xlsx/worksheet.rb +225 -145
  94. data/lib/write_xlsx/worksheet/data_validation.rb +10 -14
  95. data/lib/write_xlsx/worksheet/hyperlink.rb +16 -37
  96. data/test/chart/test_write_legend_pos.rb +9 -1
  97. data/test/chartsheet/test_write_sheet_protection.rb +91 -0
  98. data/test/drawing/test_drawing_chart_01.rb +6 -2
  99. data/test/drawing/test_drawing_image_01.rb +12 -3
  100. data/test/drawing/test_drawing_shape_01.rb +8 -5
  101. data/test/drawing/test_drawing_shape_02.rb +12 -5
  102. data/test/drawing/test_drawing_shape_03.rb +8 -5
  103. data/test/drawing/test_drawing_shape_04.rb +8 -24
  104. data/test/drawing/test_drawing_shape_05.rb +8 -5
  105. data/test/drawing/test_drawing_shape_06.rb +11 -6
  106. data/test/drawing/test_drawing_shape_07.rb +11 -6
  107. data/test/drawing/test_write_a_graphic_frame_locks.rb +1 -1
  108. data/test/drawing/test_write_c_chart.rb +1 -1
  109. data/test/drawing/test_write_c_nv_graphic_frame_pr.rb +1 -1
  110. data/test/drawing/test_write_c_nv_pr.rb +1 -1
  111. data/test/drawing/test_write_col.rb +1 -1
  112. data/test/drawing/test_write_col_off.rb +1 -1
  113. data/test/drawing/test_write_ext.rb +1 -1
  114. data/test/drawing/test_write_pos.rb +1 -1
  115. data/test/drawing/test_write_row.rb +1 -1
  116. data/test/drawing/test_write_row_off.rb +1 -1
  117. data/test/drawing/test_write_xfrm_extension.rb +1 -1
  118. data/test/drawing/test_write_xfrm_offset.rb +1 -1
  119. data/test/package/comments/test_comments_01.rb +54 -0
  120. data/test/package/comments/test_comments_02.rb +54 -0
  121. data/test/perl_output/chart_gauge.xlsx +0 -0
  122. data/test/perl_output/chart_line.xlsx +0 -0
  123. data/test/perl_output/comments2.xlsx +0 -0
  124. data/test/perl_output/formats.xlsx +0 -0
  125. data/test/perl_output/tables.xlsx +0 -0
  126. data/test/regression/images/happy.jpg +0 -0
  127. data/test/regression/images/red2.png +0 -0
  128. data/test/regression/test_array_formula03.rb +36 -0
  129. data/test/regression/test_autofilter08.rb +110 -0
  130. data/test/regression/test_autofilter09.rb +110 -0
  131. data/test/regression/test_autofilter10.rb +110 -0
  132. data/test/regression/test_chart_axis26.rb +10 -8
  133. data/test/regression/test_chart_axis27.rb +1 -1
  134. data/test/regression/test_chart_axis28.rb +1 -1
  135. data/test/regression/test_chart_axis29.rb +1 -1
  136. data/test/regression/test_chart_axis33.rb +1 -1
  137. data/test/regression/test_chart_axis42.rb +44 -0
  138. data/test/regression/test_chart_axis43.rb +44 -0
  139. data/test/regression/test_chart_axis44.rb +54 -0
  140. data/test/regression/test_chart_axis45.rb +54 -0
  141. data/test/regression/test_chart_axis46.rb +54 -0
  142. data/test/regression/test_chart_combined10.rb +43 -0
  143. data/test/regression/test_chart_combined11.rb +63 -0
  144. data/test/regression/test_chart_data_labels25.rb +1 -1
  145. data/test/regression/test_chart_doughnut07.rb +37 -0
  146. data/test/regression/test_chart_font09.rb +1 -1
  147. data/test/regression/test_chart_legend03.rb +41 -0
  148. data/test/regression/test_chart_legend04.rb +41 -0
  149. data/test/regression/test_chart_legend05.rb +41 -0
  150. data/test/regression/test_chart_legend06.rb +41 -0
  151. data/test/regression/test_chart_legend07.rb +38 -0
  152. data/test/regression/test_chart_line05.rb +43 -0
  153. data/test/regression/test_chart_line06.rb +43 -0
  154. data/test/regression/test_chart_size03.rb +4 -1
  155. data/test/regression/test_comment13.rb +36 -0
  156. data/test/regression/test_comment14.rb +29 -0
  157. data/test/regression/test_comment15.rb +28 -0
  158. data/test/regression/test_comment16.rb +34 -0
  159. data/test/regression/test_cond_format19.rb +64 -0
  160. data/test/regression/test_cond_format20.rb +43 -0
  161. data/test/regression/test_format15.rb +26 -0
  162. data/test/regression/test_header_image15.rb +36 -0
  163. data/test/regression/test_header_image16.rb +42 -0
  164. data/test/regression/test_header_image17.rb +46 -0
  165. data/test/regression/test_header_image18.rb +48 -0
  166. data/test/regression/test_header_image19.rb +36 -0
  167. data/test/regression/test_hyperlink32.rb +27 -0
  168. data/test/regression/test_hyperlink33.rb +28 -0
  169. data/test/regression/test_hyperlink34.rb +33 -0
  170. data/test/regression/test_hyperlink35.rb +39 -0
  171. data/test/regression/test_hyperlink36.rb +34 -0
  172. data/test/regression/test_hyperlink37.rb +33 -0
  173. data/test/regression/test_hyperlink38.rb +27 -0
  174. data/test/regression/test_hyperlink39.rb +27 -0
  175. data/test/regression/test_hyperlink40.rb +27 -0
  176. data/test/regression/test_hyperlink41.rb +27 -0
  177. data/test/regression/test_hyperlink42.rb +27 -0
  178. data/test/regression/test_hyperlink43.rb +27 -0
  179. data/test/regression/test_hyperlink44.rb +27 -0
  180. data/test/regression/test_hyperlink45.rb +27 -0
  181. data/test/regression/test_hyperlink47.rb +27 -0
  182. data/test/regression/test_hyperlink48.rb +31 -0
  183. data/test/regression/test_hyperlink49.rb +29 -0
  184. data/test/regression/test_image06.rb +5 -5
  185. data/test/regression/test_image08.rb +5 -4
  186. data/test/regression/test_image15.rb +4 -2
  187. data/test/regression/test_image28.rb +1 -1
  188. data/test/regression/test_image36.rb +26 -0
  189. data/test/regression/test_image44.rb +28 -0
  190. data/test/regression/test_image45.rb +29 -0
  191. data/test/regression/test_image46.rb +29 -0
  192. data/test/regression/test_image47.rb +28 -0
  193. data/test/regression/test_image48.rb +32 -0
  194. data/test/regression/test_image49.rb +38 -0
  195. data/test/regression/test_image50.rb +24 -0
  196. data/test/regression/test_image51.rb +30 -0
  197. data/test/regression/test_object_position01.rb +26 -0
  198. data/test/regression/test_object_position02.rb +26 -0
  199. data/test/regression/test_object_position03.rb +26 -0
  200. data/test/regression/test_object_position04.rb +44 -0
  201. data/test/regression/test_object_position06.rb +28 -0
  202. data/test/regression/test_object_position07.rb +28 -0
  203. data/test/regression/test_object_position08.rb +47 -0
  204. data/test/regression/test_object_position09.rb +50 -0
  205. data/test/regression/test_object_position10.rb +28 -0
  206. data/test/regression/test_object_position12.rb +25 -0
  207. data/test/regression/test_object_position13.rb +25 -0
  208. data/test/regression/test_object_position14.rb +25 -0
  209. data/test/regression/test_object_position15.rb +29 -0
  210. data/test/regression/test_object_position16.rb +29 -0
  211. data/test/regression/test_object_position17.rb +29 -0
  212. data/test/regression/test_object_position18.rb +29 -0
  213. data/test/regression/test_object_position19.rb +29 -0
  214. data/test/regression/test_object_position20.rb +29 -0
  215. data/test/regression/test_shape_connect01.rb +4 -2
  216. data/test/regression/test_table23.rb +56 -0
  217. data/test/regression/test_table24.rb +27 -0
  218. data/test/regression/test_table25.rb +27 -0
  219. data/test/regression/xlsx_files/array_formula03.xlsx +0 -0
  220. data/test/regression/xlsx_files/autofilter08.xlsx +0 -0
  221. data/test/regression/xlsx_files/autofilter09.xlsx +0 -0
  222. data/test/regression/xlsx_files/autofilter10.xlsx +0 -0
  223. data/test/regression/xlsx_files/chart_axis26.xlsx +0 -0
  224. data/test/regression/xlsx_files/chart_axis27.xlsx +0 -0
  225. data/test/regression/xlsx_files/chart_axis28.xlsx +0 -0
  226. data/test/regression/xlsx_files/chart_axis29.xlsx +0 -0
  227. data/test/regression/xlsx_files/chart_axis33.xlsx +0 -0
  228. data/test/regression/xlsx_files/chart_axis42.xlsx +0 -0
  229. data/test/regression/xlsx_files/chart_axis43.xlsx +0 -0
  230. data/test/regression/xlsx_files/chart_axis44.xlsx +0 -0
  231. data/test/regression/xlsx_files/chart_axis45.xlsx +0 -0
  232. data/test/regression/xlsx_files/chart_axis46.xlsx +0 -0
  233. data/test/regression/xlsx_files/chart_combined10.xlsx +0 -0
  234. data/test/regression/xlsx_files/chart_combined11.xlsx +0 -0
  235. data/test/regression/xlsx_files/chart_data_labels25.xlsx +0 -0
  236. data/test/regression/xlsx_files/chart_doughnut07.xlsx +0 -0
  237. data/test/regression/xlsx_files/chart_font09.xlsx +0 -0
  238. data/test/regression/xlsx_files/chart_legend03.xlsx +0 -0
  239. data/test/regression/xlsx_files/chart_legend04.xlsx +0 -0
  240. data/test/regression/xlsx_files/chart_legend05.xlsx +0 -0
  241. data/test/regression/xlsx_files/chart_legend06.xlsx +0 -0
  242. data/test/regression/xlsx_files/chart_legend07.xlsx +0 -0
  243. data/test/regression/xlsx_files/chart_line05.xlsx +0 -0
  244. data/test/regression/xlsx_files/chart_line06.xlsx +0 -0
  245. data/test/regression/xlsx_files/comment13.xlsx +0 -0
  246. data/test/regression/xlsx_files/comment14.xlsx +0 -0
  247. data/test/regression/xlsx_files/comment15.xlsx +0 -0
  248. data/test/regression/xlsx_files/comment16.xlsx +0 -0
  249. data/test/regression/xlsx_files/cond_format19.xlsx +0 -0
  250. data/test/regression/xlsx_files/cond_format20.xlsx +0 -0
  251. data/test/regression/xlsx_files/format15.xlsx +0 -0
  252. data/test/regression/xlsx_files/header_image15.xlsx +0 -0
  253. data/test/regression/xlsx_files/header_image16.xlsx +0 -0
  254. data/test/regression/xlsx_files/header_image17.xlsx +0 -0
  255. data/test/regression/xlsx_files/header_image18.xlsx +0 -0
  256. data/test/regression/xlsx_files/header_image19.xlsx +0 -0
  257. data/test/regression/xlsx_files/hyperlink32.xlsx +0 -0
  258. data/test/regression/xlsx_files/hyperlink33.xlsx +0 -0
  259. data/test/regression/xlsx_files/hyperlink34.xlsx +0 -0
  260. data/test/regression/xlsx_files/hyperlink35.xlsx +0 -0
  261. data/test/regression/xlsx_files/hyperlink36.xlsx +0 -0
  262. data/test/regression/xlsx_files/hyperlink37.xlsx +0 -0
  263. data/test/regression/xlsx_files/hyperlink38.xlsx +0 -0
  264. data/test/regression/xlsx_files/hyperlink39.xlsx +0 -0
  265. data/test/regression/xlsx_files/hyperlink40.xlsx +0 -0
  266. data/test/regression/xlsx_files/hyperlink41.xlsx +0 -0
  267. data/test/regression/xlsx_files/hyperlink42.xlsx +0 -0
  268. data/test/regression/xlsx_files/hyperlink43.xlsx +0 -0
  269. data/test/regression/xlsx_files/hyperlink44.xlsx +0 -0
  270. data/test/regression/xlsx_files/hyperlink45.xlsx +0 -0
  271. data/test/regression/xlsx_files/hyperlink46.xlsx +0 -0
  272. data/test/regression/xlsx_files/hyperlink47.xlsx +0 -0
  273. data/test/regression/xlsx_files/hyperlink48.xlsx +0 -0
  274. data/test/regression/xlsx_files/hyperlink49.xlsx +0 -0
  275. data/test/regression/xlsx_files/image06.xlsx +0 -0
  276. data/test/regression/xlsx_files/image36.xlsx +0 -0
  277. data/test/regression/xlsx_files/image44.xlsx +0 -0
  278. data/test/regression/xlsx_files/image45.xlsx +0 -0
  279. data/test/regression/xlsx_files/image46.xlsx +0 -0
  280. data/test/regression/xlsx_files/image47.xlsx +0 -0
  281. data/test/regression/xlsx_files/image48.xlsx +0 -0
  282. data/test/regression/xlsx_files/image49.xlsx +0 -0
  283. data/test/regression/xlsx_files/image50.xlsx +0 -0
  284. data/test/regression/xlsx_files/image51.xlsx +0 -0
  285. data/test/regression/xlsx_files/object_position01.xlsx +0 -0
  286. data/test/regression/xlsx_files/object_position02.xlsx +0 -0
  287. data/test/regression/xlsx_files/object_position03.xlsx +0 -0
  288. data/test/regression/xlsx_files/object_position04.xlsx +0 -0
  289. data/test/regression/xlsx_files/object_position06.xlsx +0 -0
  290. data/test/regression/xlsx_files/object_position07.xlsx +0 -0
  291. data/test/regression/xlsx_files/object_position08.xlsx +0 -0
  292. data/test/regression/xlsx_files/object_position09.xlsx +0 -0
  293. data/test/regression/xlsx_files/object_position10.xlsx +0 -0
  294. data/test/regression/xlsx_files/object_position12.xlsx +0 -0
  295. data/test/regression/xlsx_files/object_position13.xlsx +0 -0
  296. data/test/regression/xlsx_files/object_position14.xlsx +0 -0
  297. data/test/regression/xlsx_files/object_position15.xlsx +0 -0
  298. data/test/regression/xlsx_files/object_position16.xlsx +0 -0
  299. data/test/regression/xlsx_files/object_position17.xlsx +0 -0
  300. data/test/regression/xlsx_files/object_position18.xlsx +0 -0
  301. data/test/regression/xlsx_files/object_position19.xlsx +0 -0
  302. data/test/regression/xlsx_files/object_position20.xlsx +0 -0
  303. data/test/regression/xlsx_files/table23.xlsx +0 -0
  304. data/test/regression/xlsx_files/table24.xlsx +0 -0
  305. data/test/regression/xlsx_files/table25.xlsx +0 -0
  306. data/test/test_example_match.rb +955 -780
  307. data/test/workbook/test_check_sheetname.rb +51 -0
  308. data/test/workbook/test_write_workbook_view.rb +36 -0
  309. data/test/worksheet/test_write_data_validation_02.rb +17 -0
  310. data/test/worksheet/test_write_sheet_view.rb +19 -1
  311. data/write_xlsx.gemspec +1 -0
  312. metadata +349 -7
  313. 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:
@@ -309,17 +309,19 @@ def initialize(workbook, index, name) #:nodoc:
309
309
  @excel_version = 2007
310
310
  @palette = workbook.palette
311
311
  @default_url_format = workbook.default_url_format
312
+ @max_url_length = workbook.max_url_length
312
313
 
313
314
  @page_setup = PageSetup.new
314
315
 
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 = []
316
+ @screen_gridlines = true
317
+ @show_zeros = true
318
+ @dim_rowmin = nil
319
+ @dim_rowmax = nil
320
+ @dim_colmin = nil
321
+ @dim_colmax = nil
322
+ @selections = []
323
+ @panes = []
324
+ @hide_row_col_headers = 0
323
325
 
324
326
  @tab_color = 0
325
327
 
@@ -355,6 +357,10 @@ def initialize(workbook, index, name) #:nodoc:
355
357
  @sparklines = []
356
358
  @shapes = []
357
359
  @shape_hash = {}
360
+ @drawing_rels = {}
361
+ @drawing_rels_id = 0
362
+ @vml_drawing_rels = {}
363
+ @vml_drawing_rels_id = 0
358
364
  @header_images = []
359
365
  @footer_images = []
360
366
 
@@ -364,6 +370,7 @@ def initialize(workbook, index, name) #:nodoc:
364
370
  @original_row_height = 15
365
371
  @default_row_height = 15
366
372
  @default_row_pixels = 20
373
+ @default_col_width = 8.43
367
374
  @default_col_pixels = 64
368
375
  @default_row_rezoed = 0
369
376
 
@@ -767,10 +774,10 @@ def set_column(*args)
767
774
 
768
775
  # Store the col sizes for use when calculating image vertices taking
769
776
  # hidden columns into account. Also store the column formats.
770
- width = 0 if ptrue?(hidden) # Set width to zero if hidden
777
+ width = @default_col_width unless width
771
778
 
772
779
  (firstcol .. lastcol).each do |col|
773
- @col_sizes[col] = width
780
+ @col_sizes[col] = [width, hidden]
774
781
  @col_formats[col] = format if format
775
782
  end
776
783
  end
@@ -2168,7 +2175,7 @@ def write_comment(*args)
2168
2175
  @has_vml = true
2169
2176
 
2170
2177
  # Process the properties of the cell comment.
2171
- @comments.add(Package::Comment.new(@workbook, self, row, col, string, options))
2178
+ @comments.add(@workbook, self, row, col, string, options)
2172
2179
  end
2173
2180
 
2174
2181
  #
@@ -2780,7 +2787,7 @@ def write_url(*args)
2780
2787
  store_hyperlink(row, col, hyperlink)
2781
2788
 
2782
2789
  if hyperlinks_count > 65_530
2783
- raise "URL '#{url}' added but number of URLS is over Excel's limit of 65,530 URLS per worksheet."
2790
+ raise "URL '#{url}' added but URL exceeds Excel's limit of 65,530 URLs per worksheet."
2784
2791
  end
2785
2792
 
2786
2793
  # Add the default URL format.
@@ -2989,13 +2996,25 @@ def write_date_time(*args)
2989
2996
  #
2990
2997
  def insert_chart(*args)
2991
2998
  # Check for a cell reference in A1 notation and substitute row and column.
2992
- row, col, chart, x_offset, y_offset, x_scale, y_scale = row_col_notation(args)
2999
+ row, col, chart, *options = row_col_notation(args)
2993
3000
  raise WriteXLSXInsufficientArgumentError if [row, col, chart].include?(nil)
2994
3001
 
3002
+ if options.first.class == Hash
3003
+ params = options.first
3004
+ x_offset = params[:x_offset]
3005
+ y_offset = params[:y_offset]
3006
+ x_scale = params[:x_scale]
3007
+ y_scale = params[:y_scale]
3008
+ anchor = params[:object_position]
3009
+
3010
+ else
3011
+ x_offset, y_offset, x_scale, y_scale, anchor = options
3012
+ end
2995
3013
  x_offset ||= 0
2996
3014
  y_offset ||= 0
2997
3015
  x_scale ||= 1
2998
3016
  y_scale ||= 1
3017
+ anchor ||= 1
2999
3018
 
3000
3019
  raise "Not a Chart object in insert_chart()" unless chart.is_a?(Chart) || chart.is_a?(Chartsheet)
3001
3020
  raise "Not a embedded style Chart object in insert_chart()" if chart.respond_to?(:embedded) && chart.embedded == 0
@@ -3013,61 +3032,41 @@ def insert_chart(*args)
3013
3032
  x_offset = chart.x_offset if ptrue?(chart.x_offset)
3014
3033
  y_offset = chart.y_offset if ptrue?(chart.y_offset)
3015
3034
 
3016
- @charts << [row, col, chart, x_offset, y_offset, x_scale, y_scale]
3035
+ @charts << [row, col, chart, x_offset, y_offset, x_scale, y_scale, anchor]
3017
3036
  end
3018
3037
 
3019
3038
  #
3020
3039
  # :call-seq:
3021
- # insert_image(row, column, filename, x=0, y=0, x_scale=1, y_scale=1)
3022
- #
3023
- # Partially supported. Currently only works for 96 dpi images.
3024
- #
3025
- # This method can be used to insert a image into a worksheet. The image
3026
- # can be in PNG, JPEG or BMP format. The x, y, x_scale and y_scale
3027
- # parameters are optional.
3028
- #
3029
- # worksheet1.insert_image('A1', 'ruby.bmp')
3030
- # worksheet2.insert_image('A1', '../images/ruby.bmp')
3031
- # worksheet3.insert_image('A1', '.c:\images\ruby.bmp')
3032
- #
3033
- # The parameters +x+ and +y+ can be used to specify an offset from the top
3034
- # left hand corner of the cell specified by +row+ and +column+. The offset
3035
- # values are in pixels.
3036
- #
3037
- # worksheet1.insert_image('A1', 'ruby.bmp', 32, 10)
3038
- #
3039
- # The offsets can be greater than the width or height of the underlying
3040
- # cell. This can be occasionally useful if you wish to align two or more
3041
- # images relative to the same cell.
3042
- #
3043
- # The parameters +x_scale+ and +y_scale+ can be used to scale the inserted
3044
- # image horizontally and vertically:
3045
- #
3046
- # # Scale the inserted image: width x 2.0, height x 0.8
3047
- # worksheet.insert_image('A1', 'perl.bmp', 0, 0, 2, 0.8)
3048
- #
3049
- # Note: you must call set_row() or set_column() before insert_image()
3050
- # if you wish to change the default dimensions of any of the rows or
3051
- # columns that the image occupies. The height of a row can also change
3052
- # if you use a font that is larger than the default. This in turn will
3053
- # affect the scaling of your image. To avoid this you should explicitly
3054
- # set the height of the row using set_row() if it contains a font size
3055
- # that will change the row height.
3056
- #
3057
- # BMP images must be 24 bit, true colour, bitmaps. In general it is
3058
- # best to avoid BMP images since they aren't compressed.
3040
+ # insert_image(row, column, filename, options)
3059
3041
  #
3060
3042
  def insert_image(*args)
3061
3043
  # Check for a cell reference in A1 notation and substitute row and column.
3062
- row, col, image, x_offset, y_offset, x_scale, y_scale = row_col_notation(args)
3044
+ row, col, image, *options = row_col_notation(args)
3063
3045
  raise WriteXLSXInsufficientArgumentError if [row, col, image].include?(nil)
3064
3046
 
3047
+ if options.first.class == Hash
3048
+ # Newer hash bashed options
3049
+ params = options.first
3050
+ x_offset = params[:x_offset]
3051
+ y_offset = params[:y_offset]
3052
+ x_scale = params[:x_scale]
3053
+ y_scale = params[:y_scale]
3054
+ anchor = params[:object_position]
3055
+ url = params[:url]
3056
+ tip = params[:tip]
3057
+ else
3058
+ x_offset, y_offset, x_scale, y_scale, anchor = options
3059
+ end
3065
3060
  x_offset ||= 0
3066
3061
  y_offset ||= 0
3067
3062
  x_scale ||= 1
3068
3063
  y_scale ||= 1
3064
+ anchor ||= 2
3069
3065
 
3070
- @images << [row, col, image, x_offset, y_offset, x_scale, y_scale]
3066
+ @images << [
3067
+ row, col, image, x_offset, y_offset,
3068
+ x_scale, y_scale, url, tip, anchor
3069
+ ]
3071
3070
  end
3072
3071
 
3073
3072
  #
@@ -3305,10 +3304,8 @@ def set_row(*args)
3305
3304
  # Store the row change to allow optimisations.
3306
3305
  @row_size_changed = true
3307
3306
 
3308
- height = 0 if ptrue?(hidden)
3309
-
3310
3307
  # Store the row sizes for use when calculating image vertices.
3311
- @row_sizes[row] = height
3308
+ @row_sizes[row] = [height, hidden]
3312
3309
  end
3313
3310
 
3314
3311
  #
@@ -5344,6 +5341,13 @@ def print_row_col_headers(headers = true)
5344
5341
  # end
5345
5342
  end
5346
5343
 
5344
+ #
5345
+ # Set the option to hide the row and column headers in Excel.
5346
+ #
5347
+ def hide_row_col_headers
5348
+ @hide_row_col_headers = 1
5349
+ end
5350
+
5347
5351
  #
5348
5352
  # The fit_to_pages() method is used to fit the printed area to a specific
5349
5353
  # number of pages both vertically and horizontally. If the printed area
@@ -5716,7 +5720,7 @@ def set_external_comment_links(comment_id) # :nodoc:
5716
5720
  def prepare_chart(index, chart_id, drawing_id) # :nodoc:
5717
5721
  drawing_type = 1
5718
5722
 
5719
- row, col, chart, x_offset, y_offset, x_scale, y_scale = @charts[index]
5723
+ row, col, chart, x_offset, y_offset, x_scale, y_scale, anchor = @charts[index]
5720
5724
  chart.id = chart_id - 1
5721
5725
  x_scale ||= 0
5722
5726
  y_scale ||= 0
@@ -5728,22 +5732,21 @@ def prepare_chart(index, chart_id, drawing_id) # :nodoc:
5728
5732
  width = (0.5 + (width * x_scale)).to_i
5729
5733
  height = (0.5 + (height * y_scale)).to_i
5730
5734
 
5731
- dimensions = position_object_emus(col, row, x_offset, y_offset, width, height)
5735
+ dimensions = position_object_emus(col, row, x_offset, y_offset, width, height, anchor)
5732
5736
 
5733
5737
  # Set the chart name for the embedded object if it has been specified.
5734
5738
  name = chart.name
5735
5739
 
5736
5740
  # Create a Drawing object to use with worksheet unless one already exists.
5737
- if !drawing?
5738
- drawing = Drawing.new
5739
- drawing.add_drawing_object(drawing_type, dimensions, 0, 0, name)
5740
- drawing.embedded = 1
5741
-
5742
- @drawing = drawing
5741
+ drawing = Drawing.new(drawing_type, dimensions, 0, 0, name, nil, anchor, drawing_rel_index, 0, nil)
5742
+ if !drawings?
5743
+ @drawings = Drawings.new
5744
+ @drawings.add_drawing_object(drawing)
5745
+ @drawings.embedded = 1
5743
5746
 
5744
5747
  @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml" ]
5745
5748
  else
5746
- @drawing.add_drawing_object(drawing_type, dimensions, 0, 0, name)
5749
+ @drawings.add_drawing_object(drawing)
5747
5750
  end
5748
5751
  @drawing_links << ['/chart', "../charts/chart#{chart_id}.xml"]
5749
5752
  end
@@ -5814,6 +5817,10 @@ def get_range_data(row_start, col_start, row_end, col_end) # :nodoc:
5814
5817
  # The values of col_start and row_start are passed in from the calling
5815
5818
  # function. The values of col_end and row_end are calculated by subtracting
5816
5819
  # the width and height of the object from the width and height of the
5820
+ # The anchor/object position defines how images are scaled for hidden rows and
5821
+ # columns. For option 1 "Move and size with cells" the size of the hidden
5822
+ # row/column is subtracted from the image.
5823
+ #
5817
5824
  # underlying cells.
5818
5825
  #
5819
5826
  # col_start # Col containing upper left corner of object.
@@ -5826,7 +5833,7 @@ def get_range_data(row_start, col_start, row_end, col_end) # :nodoc:
5826
5833
  # y2 # Distance to bottom of object.
5827
5834
  # width # Width of object frame.
5828
5835
  # height # Height of object frame.
5829
- def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
5836
+ def position_object_pixels(col_start, row_start, x1, y1, width, height, anchor = nil) #:nodoc:
5830
5837
  # Adjust start column for negative offsets.
5831
5838
  while x1 < 0 && col_start > 0
5832
5839
  x1 += size_col(col_start - 1)
@@ -5845,7 +5852,7 @@ def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
5845
5852
 
5846
5853
  # Calculate the absolute x offset of the top-left vertex.
5847
5854
  if @col_size_changed
5848
- x_abs = (0 .. col_start-1).inject(0) {|sum, col| sum += size_col(col)}
5855
+ x_abs = (0 .. col_start-1).inject(0) {|sum, col| sum += size_col(col, anchor)}
5849
5856
  else
5850
5857
  # Optimisation for when the column widths haven't changed.
5851
5858
  x_abs = @default_col_pixels * col_start
@@ -5855,7 +5862,7 @@ def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
5855
5862
  # Calculate the absolute y offset of the top-left vertex.
5856
5863
  # Store the column change to allow optimisations.
5857
5864
  if @row_size_changed
5858
- y_abs = (0 .. row_start-1).inject(0) {|sum, row| sum += size_row(row)}
5865
+ y_abs = (0 .. row_start-1).inject(0) {|sum, row| sum += size_row(row, anchor)}
5859
5866
  else
5860
5867
  # Optimisation for when the row heights haven't changed.
5861
5868
  y_abs = @default_row_pixels * row_start
@@ -5863,23 +5870,36 @@ def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
5863
5870
  y_abs += y1
5864
5871
 
5865
5872
  # Adjust start column for offsets that are greater than the col width.
5866
- x1, col_start = adjust_column_offset(x1, col_start)
5873
+ while x1 >= size_col(col_start, anchor)
5874
+ x1 -= size_col(col_start)
5875
+ col_start += 1
5876
+ end
5867
5877
 
5868
5878
  # Adjust start row for offsets that are greater than the row height.
5869
- y1, row_start = adjust_row_offset(y1, row_start)
5879
+ while y1 >= size_row(row_start, anchor)
5880
+ y1 -= size_row(row_start)
5881
+ row_start += 1
5882
+ end
5870
5883
 
5871
5884
  # Initialise end cell to the same as the start cell.
5872
5885
  col_end = col_start
5873
5886
  row_end = row_start
5874
5887
 
5875
- width += x1
5876
- height += y1
5888
+ # Only offset the image in the cell if the row/col isn't hidden.
5889
+ width += x1 if size_col(col_start, anchor) > 0
5890
+ height += y1 if size_row(row_start, anchor) > 0
5877
5891
 
5878
5892
  # Subtract the underlying cell widths to find the end cell of the object.
5879
- width, col_end = adjust_column_offset(width, col_end)
5893
+ while width >= size_col(col_end, anchor)
5894
+ width -= size_col(col_end, anchor)
5895
+ col_end += 1
5896
+ end
5880
5897
 
5881
5898
  # Subtract the underlying cell heights to find the end cell of the object.
5882
- height, row_end = adjust_row_offset(height, row_end)
5899
+ while height >= size_row(row_end, anchor)
5900
+ height -= size_row(row_end, anchor)
5901
+ row_end += 1
5902
+ end
5883
5903
 
5884
5904
  # The end vertices are whatever is left from the width and height.
5885
5905
  x2 = width
@@ -6064,6 +6084,33 @@ def write_sparkline_groups
6064
6084
 
6065
6085
  private
6066
6086
 
6087
+ #
6088
+ # Get the index used to address a drawing rel link.
6089
+ #
6090
+ def drawing_rel_index(target = nil)
6091
+ if !target
6092
+ # Undefined values for drawings like charts will always be unique.
6093
+ @drawing_rels_id += 1
6094
+ elsif ptrue?(@drawing_rels[target])
6095
+ @drawing_rels[target]
6096
+ else
6097
+ @drawing_rels_id += 1
6098
+ @drawing_rels[target] = @drawing_rels_id
6099
+ end
6100
+ end
6101
+
6102
+ #
6103
+ # Get the index used to address a vml_drawing rel link.
6104
+ #
6105
+ def get_vml_drawing_rel_index(target)
6106
+ if @vml_drawing_rels[target]
6107
+ @vml_drawing_rels[target]
6108
+ else
6109
+ @vml_drawing_rels_id += 1
6110
+ @vml_drawing_rels[target] = @vml_drawing_rels_id
6111
+ end
6112
+ end
6113
+
6067
6114
  def hyperlinks_count
6068
6115
  @hyperlinks.keys.inject(0) { |s, n| s += @hyperlinks[n].keys.size }
6069
6116
  end
@@ -6339,32 +6386,16 @@ def sort_pagebreaks(*args) #:nodoc:
6339
6386
  end
6340
6387
  end
6341
6388
 
6342
- def adjust_column_offset(x, column)
6343
- while x >= size_col(column)
6344
- x -= size_col(column)
6345
- column += 1
6346
- end
6347
- [x, column]
6348
- end
6349
-
6350
- def adjust_row_offset(y, row)
6351
- while y >= size_row(row)
6352
- y -= size_row(row)
6353
- row += 1
6354
- end
6355
- [y, row]
6356
- end
6357
-
6358
6389
  #
6359
6390
  # Calculate the vertices that define the position of a graphical object within
6360
6391
  # the worksheet in EMUs.
6361
6392
  #
6362
6393
  # The vertices are expressed as English Metric Units (EMUs). There are 12,700
6363
- # EMUs per point. Therefore, 12,700 * 3 /4 = 9,525 EMUs per pixel.
6394
+ # EMUs per point. Therefore, 12,700 * 3 /4 = 9,525 EMUs per el.
6364
6395
  #
6365
- def position_object_emus(col_start, row_start, x1, y1, width, height, x_dpi = 96, y_dpi = 96) #:nodoc:
6396
+ def position_object_emus(col_start, row_start, x1, y1, width, height, anchor = nil) #:nodoc:
6366
6397
  col_start, row_start, x1, y1, col_end, row_end, x2, y2, x_abs, y_abs =
6367
- position_object_pixels(col_start, row_start, x1, y1, width, height)
6398
+ position_object_pixels(col_start, row_start, x1, y1, width, height, anchor)
6368
6399
 
6369
6400
  # Convert the pixel values to EMUs. See above.
6370
6401
  x1 = (0.5 + 9_525 * x1).to_i
@@ -6380,15 +6411,16 @@ def position_object_emus(col_start, row_start, x1, y1, width, height, x_dpi = 96
6380
6411
  #
6381
6412
  # Convert the width of a cell from user's units to pixels. Excel rounds the
6382
6413
  # column width to the nearest pixel. If the width hasn't been set by the user
6383
- # we use the default value. If the column is hidden it has a value of zero.
6414
+ # we use the default value. A hidden column is treated as having a width of
6415
+ # zero unless it has the special "object_position" of 4 (size with cells).
6384
6416
  #
6385
- def size_col(col) #:nodoc:
6417
+ def size_col(col, anchor = 0) #:nodoc:
6386
6418
  # Look up the cell value to see if it has been changed.
6387
6419
  if @col_sizes[col]
6388
- width = @col_sizes[col]
6420
+ width, hidden = @col_sizes[col]
6389
6421
 
6390
6422
  # Convert to pixels.
6391
- if width == 0
6423
+ if hidden == 1 && anchor != 4
6392
6424
  pixels = 0
6393
6425
  elsif width < 1
6394
6426
  pixels = (width * (MAX_DIGIT_WIDTH + PADDING) + 0.5).to_i
@@ -6403,15 +6435,16 @@ def size_col(col) #:nodoc:
6403
6435
 
6404
6436
  #
6405
6437
  # Convert the height of a cell from user's units to pixels. If the height
6406
- # hasn't been set by the user we use the default value. If the row is hidden
6407
- # it has a value of zero.
6438
+ # hasn't been set by the user we use the default value. A hidden row is
6439
+ # treated as having a height of zero unless it has the special
6440
+ # "object_position" of 4 (size with cells).
6408
6441
  #
6409
- def size_row(row) #:nodoc:
6442
+ def size_row(row, anchor = 0) #:nodoc:
6410
6443
  # Look up the cell value to see if it has been changed
6411
6444
  if @row_sizes[row]
6412
- height = @row_sizes[row]
6445
+ height, hidden = @row_sizes[row]
6413
6446
 
6414
- if height == 0
6447
+ if hidden == 1 && anchor != 4
6415
6448
  pixels = 0
6416
6449
  else
6417
6450
  pixels = (4 / 3.0 * height).to_i
@@ -6425,13 +6458,13 @@ def size_row(row) #:nodoc:
6425
6458
  #
6426
6459
  # Set up image/drawings.
6427
6460
  #
6428
- def prepare_image(index, image_id, drawing_id, width, height, name, image_type, x_dpi = 96, y_dpi = 96) #:nodoc:
6461
+ def prepare_image(index, image_id, drawing_id, width, height, name, image_type, x_dpi = 96, y_dpi = 96, md5 = nil) #:nodoc:
6429
6462
  x_dpi ||= 96
6430
6463
  y_dpi ||= 96
6431
6464
  drawing_type = 2
6432
- drawing
6433
6465
 
6434
- row, col, image, x_offset, y_offset, x_scale, y_scale = @images[index]
6466
+ row, col, image, x_offset, y_offset,
6467
+ x_scale, y_scale, url, tip, anchor = @images[index]
6435
6468
 
6436
6469
  width *= x_scale
6437
6470
  height *= y_scale
@@ -6439,36 +6472,72 @@ def prepare_image(index, image_id, drawing_id, width, height, name, image_type,
6439
6472
  width *= 96.0 / x_dpi
6440
6473
  height *= 96.0 / y_dpi
6441
6474
 
6442
- dimensions = position_object_emus(col, row, x_offset, y_offset, width, height)
6475
+ dimensions = position_object_emus(col, row, x_offset, y_offset, width, height, anchor)
6443
6476
 
6444
6477
  # Convert from pixels to emus.
6445
6478
  width = (0.5 + (width * 9_525)).to_i
6446
6479
  height = (0.5 + (height * 9_525)).to_i
6447
6480
 
6448
6481
  # Create a Drawing object to use with worksheet unless one already exists.
6449
- if !drawing?
6450
- drawing = Drawing.new
6451
- drawing.embedded = 1
6482
+ drawing = Drawing.new(drawing_type, dimensions, width, height, name, nil, anchor, 0, 0, tip)
6483
+ if !drawings?
6484
+ drawings = Drawings.new
6485
+ drawings.embedded = 1
6452
6486
 
6453
- @drawing = drawing
6487
+ @drawings = drawings
6454
6488
 
6455
6489
  @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml"]
6456
6490
  else
6457
- drawing = @drawing
6491
+ drawings = @drawings
6492
+ end
6493
+ drawings.add_drawing_object(drawing)
6494
+
6495
+ if url
6496
+ rel_type = '/hyperlink'
6497
+ target_mode = 'External'
6498
+ if url =~ %r!^[fh]tt?ps?://! || url =~ /^mailto:/
6499
+ target = escape_url(url)
6500
+ end
6501
+ if url =~ /^external:/
6502
+ target = escape_url(url.sub(/^external:/, 'file:///'))
6503
+ # Additional escape not required in worksheet hyperlinks
6504
+ target = target.gsub(/#/, '%23')
6505
+ end
6506
+ if url =~ /^internal:/
6507
+ target = url.sub(/^internal:/, '#')
6508
+ target_mode = nil
6509
+ end
6510
+
6511
+ if target.length > 255
6512
+ raise <<"EOS"
6513
+ Ignoring URL #{target} where link or anchor > 255 characters since it exceeds Excel's limit for URLS. See LIMITATIONS section of the WriteXLSX documentation.
6514
+ EOS
6515
+ end
6516
+
6517
+ if target && !@drawing_rels[url]
6518
+ @drawing_links << [rel_type, target, target_mode]
6519
+ end
6520
+ drawing.url_rel_index = drawing_rel_index(url)
6458
6521
  end
6459
- drawing.add_drawing_object(drawing_type, dimensions, width, height, name)
6460
6522
 
6461
- @drawing_links << ['/image', "../media/image#{image_id}.#{image_type}"]
6523
+ if !@drawing_rels[md5]
6524
+ @drawing_links << ['/image', "../media/image#{image_id}.#{image_type}"]
6525
+ end
6526
+ drawing.rel_index = drawing_rel_index(md5)
6462
6527
  end
6463
6528
  public :prepare_image
6464
6529
 
6465
- def prepare_header_image(image_id, width, height, name, image_type, position, x_dpi, y_dpi)
6530
+ def prepare_header_image(image_id, width, height, name, image_type, position, x_dpi, y_dpi, md5)
6466
6531
  # Strip the extension from the filename.
6467
6532
  body = name.dup
6468
6533
  body[/\.[^\.]+$/, 0] = ''
6469
6534
 
6470
- @header_images_array << [width, height, body, position, x_dpi, y_dpi]
6471
- @vml_drawing_links << ['/image', "../media/image#{image_id}.#{image_type}" ]
6535
+ if !@vml_drawing_rels[md5]
6536
+ @vml_drawing_links << ['/image', "../media/image#{image_id}.#{image_type}" ]
6537
+ end
6538
+
6539
+ ref_id = get_vml_drawing_rel_index(md5)
6540
+ @header_images_array << [width, height, body, position, x_dpi, y_dpi, ref_id]
6472
6541
  end
6473
6542
  public :prepare_header_image
6474
6543
 
@@ -6511,16 +6580,16 @@ def prepare_header_image(image_id, width, height, name, image_type, position, x_
6511
6580
  #
6512
6581
  def insert_shape(*args)
6513
6582
  # Check for a cell reference in A1 notation and substitute row and column.
6514
- row_start, column_start, shape, x_offset, y_offset, x_scale, y_scale =
6583
+ row_start, column_start, shape, x_offset, y_offset, x_scale, y_scale, anchor =
6515
6584
  row_col_notation(args)
6516
6585
  if [row_start, column_start, shape].include?(nil)
6517
6586
  raise "Insufficient arguments in insert_shape()"
6518
6587
  end
6519
6588
 
6520
6589
  shape.set_position(
6521
- row_start, column_start, x_offset, y_offset,
6522
- x_scale, y_scale
6523
- )
6590
+ row_start, column_start, x_offset, y_offset,
6591
+ x_scale, y_scale, anchor
6592
+ )
6524
6593
  # Assign a shape ID.
6525
6594
  while true
6526
6595
  id = shape.id || 0
@@ -6564,9 +6633,9 @@ def prepare_shape(index, drawing_id)
6564
6633
  shape = @shapes[index]
6565
6634
 
6566
6635
  # Create a Drawing object to use with worksheet unless one already exists.
6567
- unless drawing?
6568
- @drawing = Drawing.new
6569
- @drawing.embedded = 1
6636
+ unless drawings?
6637
+ @drawings = Drawings.new
6638
+ @drawings.embedded = 1
6570
6639
  @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml"]
6571
6640
  @has_shapes = true
6572
6641
  end
@@ -6576,13 +6645,14 @@ def prepare_shape(index, drawing_id)
6576
6645
  shape.calc_position_emus(self)
6577
6646
 
6578
6647
  drawing_type = 3
6579
- drawing.add_drawing_object(drawing_type, shape.dimensions, shape.name, shape)
6648
+ drawing = Drawing.new(drawing_type, shape.dimensions, shape.width_emu, shape.height_emu, shape.name, shape, shape.anchor, drawing_rel_index, 0, nil)
6649
+ drawings.add_drawing_object(drawing)
6580
6650
  end
6581
6651
  public :prepare_shape
6582
6652
 
6583
6653
  #
6584
6654
  # This method handles the parameters passed to insert_button as well as
6585
- # calculating the comment object position and vertices.
6655
+ # calculating the button object position and vertices.
6586
6656
  #
6587
6657
  def button_params(row, col, params)
6588
6658
  button = Writexlsx::Package::Button.new
@@ -6611,7 +6681,7 @@ def button_params(row, col, params)
6611
6681
  params[:x_offset] = 0 if !params[:x_offset]
6612
6682
  params[:y_offset] = 0 if !params[:y_offset]
6613
6683
 
6614
- # Scale the size of the comment box if required.
6684
+ # Scale the size of the button box if required.
6615
6685
  if params[:x_scale]
6616
6686
  params[:width] = params[:width] * params[:x_scale]
6617
6687
  end
@@ -6626,15 +6696,15 @@ def button_params(row, col, params)
6626
6696
  params[:start_row] = row
6627
6697
  params[:start_col] = col
6628
6698
 
6629
- # Calculate the positions of comment object.
6699
+ # Calculate the positions of button object.
6630
6700
  vertices = position_object_pixels(
6631
- params[:start_col],
6632
- params[:start_row],
6633
- params[:x_offset],
6634
- params[:y_offset],
6635
- params[:width],
6636
- params[:height]
6637
- )
6701
+ params[:start_col],
6702
+ params[:start_row],
6703
+ params[:x_offset],
6704
+ params[:y_offset],
6705
+ params[:width],
6706
+ params[:height]
6707
+ )
6638
6708
 
6639
6709
  # Add the width and height for VML.
6640
6710
  vertices << [params[:width], params[:height]]
@@ -6757,9 +6827,12 @@ def write_sheet_views #:nodoc:
6757
6827
 
6758
6828
  def write_sheet_view #:nodoc:
6759
6829
  attributes = []
6760
- # Hide screen gridlines if required
6830
+ # Hide screen gridlines if required.
6761
6831
  attributes << ['showGridLines', 0] unless @screen_gridlines
6762
6832
 
6833
+ # Hide the row/column headers.
6834
+ attributes << ['showRowColHeaders', 0] if ptrue?(@hide_row_col_headers)
6835
+
6763
6836
  # Hide zeroes in cells.
6764
6837
  attributes << ['showZeros', 0] unless show_zeros?
6765
6838
 
@@ -6871,7 +6944,7 @@ def col_info_attributes(args)
6871
6944
  custom_width = false if width.nil? && hidden == 0
6872
6945
  custom_width = false if width == 8.43
6873
6946
 
6874
- width = hidden == 0 ? 8.43 : 0 unless width
6947
+ width = hidden == 0 ? @default_col_width : 0 unless width
6875
6948
 
6876
6949
  # Convert column width from user units to character width.
6877
6950
  if width && width < 1
@@ -7294,13 +7367,20 @@ def write_filter_column(col_id, type, *filters) #:nodoc:
7294
7367
  # Write the <filters> element.
7295
7368
  #
7296
7369
  def write_filters(*filters) #:nodoc:
7297
- if filters.size == 1 && filters[0] == 'blanks'
7370
+ non_blanks = filters.reject { |filter| filter =~ /^blanks$/i }
7371
+ attributes = []
7372
+
7373
+ if filters != non_blanks
7374
+ attributes = [ ['blank', 1] ]
7375
+ end
7376
+
7377
+ if filters.size == 1 && non_blanks.empty?
7298
7378
  # Special case for blank cells only.
7299
- @writer.empty_tag('filters', [ ['blank', 1] ])
7379
+ @writer.empty_tag('filters', attributes)
7300
7380
  else
7301
7381
  # General case.
7302
- @writer.tag_elements('filters') do
7303
- filters.each { |filter| write_filter(filter) }
7382
+ @writer.tag_elements('filters', attributes) do
7383
+ non_blanks.sort.each { |filter| write_filter(filter) }
7304
7384
  end
7305
7385
  end
7306
7386
  end
@@ -7474,7 +7554,7 @@ def write_sheet_protection #:nodoc:
7474
7554
  # Write the <drawing> elements.
7475
7555
  #
7476
7556
  def write_drawings #:nodoc:
7477
- increment_rel_id_and_write_r_id('drawing') if drawing?
7557
+ increment_rel_id_and_write_r_id('drawing') if drawings?
7478
7558
  end
7479
7559
 
7480
7560
  #
@@ -7952,8 +8032,8 @@ def autofilter_ref? #:nodoc:
7952
8032
  !!@autofilter_ref
7953
8033
  end
7954
8034
 
7955
- def drawing? #:nodoc:
7956
- !!@drawing
8035
+ def drawings? #:nodoc:
8036
+ !!@drawings
7957
8037
  end
7958
8038
 
7959
8039
  def remove_white_space(margin) #:nodoc: