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
@@ -178,6 +178,16 @@ def add_vba_project
178
178
  add_default('bin', 'application/vnd.ms-office.vbaProject')
179
179
  end
180
180
 
181
+ #
182
+ # Add the name of a table to the ContentTypes overrides.
183
+ #
184
+ def add_custom_properties
185
+ custom = "/docProps/custom.xml"
186
+
187
+ add_override(custom, "#{App_document}custom-properties+xml")
188
+ end
189
+
190
+
181
191
  private
182
192
 
183
193
  def change_the_workbook_xml_content_type_from_xlsx_to_xlsm
@@ -14,7 +14,7 @@ class Core
14
14
  def initialize
15
15
  @writer = Package::XMLWriterSimple.new
16
16
  @properties = {}
17
- @localtime = [Time.now]
17
+ @createtime = [Time.now.gmtime]
18
18
  end
19
19
 
20
20
  def set_xml_writer(filename)
@@ -47,12 +47,14 @@ def write_cp_core_properties_base
47
47
  end
48
48
 
49
49
  #
50
- # Convert a localtime() date to a ISO 8601 style "2010-01-01T00:00:00Z" date.
50
+ # Convert a gmtime/localtime() date to a ISO 8601 style
51
+ # "2010-01-01T00:00:00Z" date. Excel always treats this as
52
+ # a utc date/time.
51
53
  #
52
- def localtime_to_iso8601_date(local_time = nil)
53
- local_time ||= Time.now
54
+ def datetime_to_iso8601_date(gm_time = nil)
55
+ gm_time ||= Time.now.gmtime
54
56
 
55
- local_time.strftime('%Y-%m-%dT%H:%M:%SZ')
57
+ gm_time.strftime('%Y-%m-%dT%H:%M:%SZ')
56
58
  end
57
59
 
58
60
  #
@@ -109,7 +111,7 @@ def write_dcterms(tag)
109
111
  end
110
112
 
111
113
  def dcterms_date
112
- localtime_to_iso8601_date(@properties[:created])
114
+ datetime_to_iso8601_date(@properties[:created])
113
115
  end
114
116
 
115
117
  #
@@ -0,0 +1,125 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'write_xlsx/package/xml_writer_simple'
3
+ require 'write_xlsx/utility'
4
+
5
+ module Writexlsx
6
+ module Package
7
+ class Custom
8
+
9
+ include Writexlsx::Utility
10
+
11
+ def initialize
12
+ @writer = Package::XMLWriterSimple.new
13
+ @properties = []
14
+ @pid = 1
15
+ end
16
+
17
+ def set_xml_writer(filename)
18
+ @writer.set_xml_writer(filename)
19
+ end
20
+
21
+ def assemble_xml_file
22
+ write_xml_declaration do
23
+ write_properties
24
+ end
25
+ end
26
+
27
+ #
28
+ # Set the document properties.
29
+ #
30
+ def set_properties(properties)
31
+ @properties = properties
32
+ end
33
+
34
+ private
35
+
36
+ def write_properties
37
+ schema = 'http://schemas.openxmlformats.org/officeDocument/2006/'
38
+ xmlns = "#{schema}custom-properties"
39
+ xmlns_vt = "#{schema}docPropsVTypes"
40
+
41
+ attributes = [
42
+ ['xmlns', xmlns],
43
+ ['xmlns:vt', xmlns_vt]
44
+ ]
45
+
46
+ @writer.tag_elements('Properties', attributes ) do
47
+ @properties.each do |property|
48
+ # Write the property element.
49
+ write_property(property)
50
+ end
51
+ end
52
+ end
53
+
54
+ def write_property(property)
55
+ fmtid = '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'
56
+
57
+ @pid += 1
58
+ name, value, type = property
59
+
60
+ attributes = [
61
+ ['fmtid', fmtid],
62
+ ['pid', @pid],
63
+ ['name', name]
64
+ ]
65
+
66
+ @writer.tag_elements('property', attributes) do
67
+ if type == 'date'
68
+ # Write the vt:filetime element.
69
+ write_vt_filetime(value)
70
+ elsif type == 'number'
71
+ # Write the vt:r8 element.
72
+ write_vt_r8(value)
73
+ elsif type == 'number_int'
74
+ # Write the vt:i4 element.
75
+ write_vt_i4(value)
76
+ elsif type == 'bool'
77
+ # Write the vt:bool element.
78
+ write_vt_bool(value)
79
+ else
80
+ # Write the vt:lpwstr element.
81
+ write_vt_lpwstr(value)
82
+ end
83
+ end
84
+ end
85
+
86
+ def write_vt_lpwstr(data)
87
+ @writer.data_element('vt:lpwstr', data)
88
+ end
89
+
90
+ #
91
+ # Write the <vt:i4> element.
92
+ #
93
+ def write_vt_i4(data)
94
+ @writer.data_element('vt:i4', data)
95
+ end
96
+
97
+ #
98
+ # Write the <vt:r8> element.
99
+ #
100
+ def write_vt_r8(data)
101
+ @writer.data_element('vt:r8', data)
102
+ end
103
+
104
+ #
105
+ # Write the <vt:bool> element.
106
+ #
107
+ def write_vt_bool(data)
108
+ if ptrue?(data)
109
+ data = 'true'
110
+ else
111
+ data = 'false'
112
+ end
113
+
114
+ @writer.data_element('vt:bool', data)
115
+ end
116
+
117
+ #
118
+ # Write the <vt:filetime> element.
119
+ #
120
+ def write_vt_filetime(data)
121
+ @writer.data_element('vt:filetime', data)
122
+ end
123
+ end
124
+ end
125
+ end
@@ -5,6 +5,7 @@
5
5
  require 'write_xlsx/package/comments'
6
6
  require 'write_xlsx/package/content_types'
7
7
  require 'write_xlsx/package/core'
8
+ require 'write_xlsx/package/custom'
8
9
  require 'write_xlsx/package/relationships'
9
10
  require 'write_xlsx/package/shared_strings'
10
11
  require 'write_xlsx/package/styles'
@@ -44,6 +45,7 @@ def create_package
44
45
  write_shared_strings_file
45
46
  write_app_file
46
47
  write_core_file
48
+ write_custom_file
47
49
  write_content_types_file
48
50
  write_styles_file
49
51
  write_theme_file
@@ -172,6 +174,22 @@ def write_core_file
172
174
  core.assemble_xml_file
173
175
  end
174
176
 
177
+ #
178
+ # Write the custom.xml file.
179
+ #
180
+ def write_custom_file
181
+ properties = @workbook.custom_properties
182
+ custom = Package::Custom.new
183
+
184
+ return if properties.empty?
185
+
186
+ FileUtils.mkdir_p("#{@package_dir}/docProps")
187
+
188
+ custom.set_properties(properties)
189
+ custom.set_xml_writer("#{@package_dir}/docProps/custom.xml")
190
+ custom.assemble_xml_file
191
+ end
192
+
175
193
  #
176
194
  # Write the ContentTypes.xml file.
177
195
  #
@@ -190,6 +208,8 @@ def write_content_types_file
190
208
  content.add_shared_strings unless @workbook.shared_strings_empty?
191
209
  # Add vbaProject if present.
192
210
  content.add_vba_project if @workbook.vba_project
211
+ # Add the custom properties if present.
212
+ content.add_custom_properties unless @workbook.custom_properties.empty?
193
213
 
194
214
  content.set_xml_writer("#{@package_dir}/[Content_Types].xml")
195
215
  content.assemble_xml_file
@@ -239,9 +259,15 @@ def write_root_rels_file
239
259
  FileUtils.mkdir_p("#{@package_dir}/_rels")
240
260
 
241
261
  rels.add_document_relationship('/officeDocument', 'xl/workbook.xml')
262
+
242
263
  rels.add_package_relationship('/metadata/core-properties',
243
264
  'docProps/core.xml')
265
+
244
266
  rels.add_document_relationship('/extended-properties', 'docProps/app.xml')
267
+
268
+ unless @workbook.custom_properties.empty?
269
+ rels.add_document_relationship('/custom-properties', 'docProps/custom.xml')
270
+ end
245
271
  rels.set_xml_writer("#{@package_dir}/_rels/.rels" )
246
272
  rels.assemble_xml_file
247
273
  end
@@ -10,14 +10,16 @@ class Styles
10
10
 
11
11
  def initialize
12
12
  @writer = Package::XMLWriterSimple.new
13
- @xf_formats = nil
14
- @palette = []
15
- @font_count = 0
16
- @num_format_count = 0
17
- @border_count = 0
18
- @fill_count = 0
19
- @custom_colors = []
20
- @dxf_formats = []
13
+ @xf_formats = nil
14
+ @palette = []
15
+ @font_count = 0
16
+ @num_format_count = 0
17
+ @border_count = 0
18
+ @fill_count = 0
19
+ @custom_colors = []
20
+ @dxf_formats = []
21
+ @has_hyperlink = 0
22
+ @hyperlink_font_id = 0
21
23
  end
22
24
 
23
25
  def set_xml_writer(filename)
@@ -33,7 +35,10 @@ def assemble_xml_file
33
35
  #
34
36
  # Pass in the Format objects and other properties used to set the styles.
35
37
  #
36
- def set_style_properties(xf_formats, palette, font_count, num_format_count, border_count, fill_count, custom_colors, dxf_formats)
38
+ def set_style_properties(
39
+ xf_formats, palette, font_count, num_format_count, border_count,
40
+ fill_count, custom_colors, dxf_formats
41
+ )
37
42
  @xf_formats = xf_formats
38
43
  @palette = palette
39
44
  @font_count = font_count
@@ -150,7 +155,11 @@ def write_fonts
150
155
 
151
156
  def write_font_base
152
157
  @xf_formats.each do |format|
153
- format.write_font(@writer, self) if format.has_font?
158
+ if format.has_font?
159
+ format.write_font(@writer, self)
160
+ @has_hyperlink = 1 if ptrue?(format.hyperlink)
161
+ @hyperlink_font_id = format.font_index unless ptrue?(@hyperlink_font_id)
162
+ end
154
163
  end
155
164
  end
156
165
 
@@ -365,11 +374,17 @@ def write_sub_border(type, style = 0, color = nil)
365
374
  # Write the <cellStyleXfs> element.
366
375
  #
367
376
  def write_cell_style_xfs
368
- attributes = [ ['count', 1] ]
377
+ count = ptrue?(@has_hyperlink) ? 2 : 1
378
+
379
+ attributes = [ ['count', count] ]
369
380
 
370
381
  @writer.tag_elements('cellStyleXfs', attributes) do
371
382
  # Write the style_xf element.
372
- write_style_xf
383
+ write_style_xf(0, 0)
384
+
385
+ if ptrue?(@has_hyperlink)
386
+ write_style_xf(1, @hyperlink_font_id)
387
+ end
373
388
  end
374
389
  end
375
390
 
@@ -396,15 +411,27 @@ def write_cell_xfs
396
411
  #
397
412
  # Write the style <xf> element.
398
413
  #
399
- def write_style_xf
414
+ def write_style_xf(has_hyperlink, font_id)
400
415
  attributes = [
401
416
  ['numFmtId', 0],
402
- ['fontId', 0],
417
+ ['fontId', font_id],
403
418
  ['fillId', 0],
404
419
  ['borderId', 0]
405
420
  ]
406
421
 
407
- @writer.empty_tag('xf', attributes)
422
+ if ptrue?(has_hyperlink)
423
+ attributes << ['applyNumberFormat', 0]
424
+ attributes << ['applyFill', 0]
425
+ attributes << ['applyBorder', 0]
426
+ attributes << ['applyAlignment', 0]
427
+ attributes << ['applyProtection', 0]
428
+ @writer.tag_elements('xf', attributes) do
429
+ @writer.empty_tag('alignment', [ ['vertical', 'top'] ])
430
+ @writer.empty_tag('protection', [ ['locked', 0] ])
431
+ end
432
+ else
433
+ @writer.empty_tag('xf', attributes)
434
+ end
408
435
  end
409
436
 
410
437
  private
@@ -450,22 +477,27 @@ def write_xf(format)
450
477
  # Write the <cellStyles> element.
451
478
  #
452
479
  def write_cell_styles
453
- attributes = [ ['count', 1] ]
480
+ count = ptrue?(@has_hyperlink) ? 2 : 1
481
+
482
+ attributes = [ ['count', count] ]
454
483
 
455
484
  @writer.tag_elements('cellStyles', attributes) do
456
485
  # Write the cellStyle element.
457
- write_cell_style
486
+ if ptrue?(@has_hyperlink)
487
+ write_cell_style('Hyperlink', 1, 8)
488
+ end
489
+ write_cell_style('Normal', 0, 0)
458
490
  end
459
491
  end
460
492
 
461
493
  #
462
494
  # Write the <cellStyle> element.
463
495
  #
464
- def write_cell_style
496
+ def write_cell_style(name, xf_id, builtin_id)
465
497
  attributes = [
466
- ['name', 'Normal'],
467
- ['xfId', 0],
468
- ['builtinId', 0]
498
+ ['name', name],
499
+ ['xfId', xf_id],
500
+ ['builtinId', builtin_id]
469
501
  ]
470
502
 
471
503
  @writer.empty_tag('cellStyle', attributes)
@@ -32,8 +32,9 @@ def initialize(worksheet, *args)
32
32
  @writer = Package::XMLWriterSimple.new
33
33
 
34
34
  @row1, @row2, @col1, @col2, @param = handle_args(*args)
35
- @columns = []
35
+ @columns = []
36
36
  @col_formats = []
37
+ @seen_name = {}
37
38
 
38
39
  # Set the data range rows (without the header and footer).
39
40
  @first_data_row = @row1
@@ -95,9 +96,15 @@ def overrite_the_defaults_with_any_use_defined_values(col_id, col_data, col_num)
95
96
  col_data.name = user_data[:header]
96
97
  end
97
98
 
99
+ # Excel requires unique case insensitive header names.
100
+ if @seen_name[col_data.name.downcase]
101
+ raise "add_table() contains duplicate name: '#{col_data.name}'"
102
+ else
103
+ @seen_name[col_data.name.downcase] = true
104
+ end
98
105
  # Get the header format if defined.
99
106
  col_data.name_format = user_data[:header_format]
100
-
107
+
101
108
  # Handle the column formula.
102
109
  handle_the_column_formula(
103
110
  col_data, col_num, user_data[:formula], user_data[:format]
@@ -233,6 +240,11 @@ def handle_the_function_for_the_table_row(row2, col_data, col_num, user_data)
233
240
  # Convert a table total function to a worksheet formula.
234
241
  #
235
242
  def table_function_to_formula(function, col_name)
243
+ col_name = col_name.gsub(/'/, "''").
244
+ gsub(/#/, "'#").
245
+ gsub(/\[/, "'[").
246
+ gsub(/\]/, "']")
247
+
236
248
  subtotals = {
237
249
  :average => 101,
238
250
  :countNums => 102,
@@ -291,8 +303,8 @@ def set_the_table_name
291
303
  # Raise if the name looks like a R1C1.
292
304
  if name =~ /^[rcRC]$/ || name =~ /^[rcRC]\d+[rcRC]\d+$/
293
305
  raise "Invalid name '#{name}' like a RC cell ref in add_table()"
294
- end
295
-
306
+ end
307
+
296
308
  @name = @param[:name]
297
309
  end
298
310
  end
@@ -8,14 +8,14 @@ module Writexlsx
8
8
  # Used in conjunction with WriteXLSX.
9
9
  #
10
10
  # Copyright 2000-2012, John McNamara, jmcnamara@cpan.org
11
- # Converted to ruby by Hideo NAKAMURA, cxn03651@msj.biglobe.ne.jp
11
+ # Converted to ruby by Hideo NAKAMURA, nakamura.hideo@gmail.com
12
12
  #
13
13
  class Shape
14
14
  include Writexlsx::Utility
15
15
 
16
16
  attr_reader :edit_as, :type, :drawing
17
17
  attr_reader :tx_box, :fill, :line, :format
18
- attr_reader :align, :valign
18
+ attr_reader :align, :valign, :anchor
19
19
  attr_accessor :name, :connect, :type, :id, :start, :end, :rotation
20
20
  attr_accessor :flip_h, :flip_v, :adjustments, :palette, :text, :stencil
21
21
  attr_accessor :row_start, :row_end, :column_start, :column_end
@@ -183,11 +183,12 @@ def calc_position_emus(worksheet)
183
183
  @y_abs = (y_abslt * 9_525).to_i
184
184
  end
185
185
 
186
- def set_position(row_start, column_start, x_offset, y_offset, x_scale, y_scale)
186
+ def set_position(row_start, column_start, x_offset, y_offset, x_scale, y_scale, anchor)
187
187
  @row_start = row_start
188
188
  @column_start = column_start
189
189
  @x_offset = x_offset || 0
190
190
  @y_offset = y_offset || 0
191
+ @anchor = anchor || 1
191
192
 
192
193
  # Override shape scale if supplied as an argument. Otherwise, use the
193
194
  # existing shape scale factors.