axlsx 1.0.15 → 1.1.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 (176) hide show
  1. data/.yardopts +1 -0
  2. data/CHANGELOG.md +40 -2
  3. data/README.md +223 -92
  4. data/examples/example.csv +1000 -0
  5. data/examples/example.rb +266 -132
  6. data/examples/example.xlsx +0 -0
  7. data/examples/example_streamed.xlsx +0 -0
  8. data/examples/no-use_autowidth.xlsx +0 -0
  9. data/examples/shared_strings_example.xlsx +0 -0
  10. data/lib/axlsx/content_type/content_type.rb +13 -12
  11. data/lib/axlsx/content_type/default.rb +10 -6
  12. data/lib/axlsx/content_type/override.rb +13 -8
  13. data/lib/axlsx/doc_props/app.rb +38 -41
  14. data/lib/axlsx/doc_props/core.rb +13 -17
  15. data/lib/axlsx/drawing/axis.rb +39 -19
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +34 -32
  17. data/lib/axlsx/drawing/bar_series.rb +14 -14
  18. data/lib/axlsx/drawing/cat_axis.rb +16 -14
  19. data/lib/axlsx/drawing/cat_axis_data.rb +17 -18
  20. data/lib/axlsx/drawing/chart.rb +40 -41
  21. data/lib/axlsx/drawing/drawing.rb +27 -12
  22. data/lib/axlsx/drawing/graphic_frame.rb +22 -21
  23. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  24. data/lib/axlsx/drawing/hyperlink.rb +96 -0
  25. data/lib/axlsx/drawing/hyperlink.rb~ +64 -0
  26. data/lib/axlsx/drawing/line_3D_chart.rb +31 -28
  27. data/lib/axlsx/drawing/line_series.rb +12 -11
  28. data/lib/axlsx/drawing/marker.rb +11 -8
  29. data/lib/axlsx/drawing/named_axis_data.rb +36 -0
  30. data/lib/axlsx/drawing/one_cell_anchor.rb +18 -16
  31. data/lib/axlsx/drawing/pic.rb +47 -33
  32. data/lib/axlsx/drawing/picture_locking.rb +22 -18
  33. data/lib/axlsx/drawing/pie_3D_chart.rb +11 -8
  34. data/lib/axlsx/drawing/pie_series.rb +16 -12
  35. data/lib/axlsx/drawing/scaling.rb +11 -10
  36. data/lib/axlsx/drawing/scatter_chart.rb +69 -0
  37. data/lib/axlsx/drawing/scatter_series.rb +39 -0
  38. data/lib/axlsx/drawing/ser_axis.rb +11 -10
  39. data/lib/axlsx/drawing/series.rb +16 -15
  40. data/lib/axlsx/drawing/series_title.rb +15 -14
  41. data/lib/axlsx/drawing/title.rb +27 -26
  42. data/lib/axlsx/drawing/two_cell_anchor.rb +19 -20
  43. data/lib/axlsx/drawing/val_axis.rb +9 -7
  44. data/lib/axlsx/drawing/val_axis_data.rb +18 -17
  45. data/lib/axlsx/drawing/view_3D.rb +23 -20
  46. data/lib/axlsx/package.rb +117 -52
  47. data/lib/axlsx/rels/relationship.rb +27 -8
  48. data/lib/axlsx/rels/relationships.rb +9 -2
  49. data/lib/axlsx/stylesheet/#num_fmt.rb# +69 -0
  50. data/lib/axlsx/stylesheet/border.rb +28 -23
  51. data/lib/axlsx/stylesheet/border_pr.rb +17 -15
  52. data/lib/axlsx/stylesheet/cell_alignment.rb +24 -21
  53. data/lib/axlsx/stylesheet/cell_protection.rb +11 -7
  54. data/lib/axlsx/stylesheet/cell_style.rb +9 -5
  55. data/lib/axlsx/stylesheet/color.rb +21 -14
  56. data/lib/axlsx/stylesheet/fill.rb +8 -5
  57. data/lib/axlsx/stylesheet/font.rb +22 -14
  58. data/lib/axlsx/stylesheet/gradient_fill.rb +20 -17
  59. data/lib/axlsx/stylesheet/gradient_stop.rb +10 -6
  60. data/lib/axlsx/stylesheet/num_fmt.rb +13 -6
  61. data/lib/axlsx/stylesheet/pattern_fill.rb +26 -10
  62. data/lib/axlsx/stylesheet/styles.rb +53 -41
  63. data/lib/axlsx/stylesheet/table_style.rb +10 -4
  64. data/lib/axlsx/stylesheet/table_style_element.rb +11 -7
  65. data/lib/axlsx/stylesheet/table_styles.rb +12 -8
  66. data/lib/axlsx/stylesheet/xf.rb +30 -25
  67. data/lib/axlsx/util/cbf.rb +69 -33
  68. data/lib/axlsx/util/constants.rb +39 -20
  69. data/lib/axlsx/util/ms_off_crypto.rb +10 -10
  70. data/lib/axlsx/util/parser.rb +1 -0
  71. data/lib/axlsx/util/simple_typed_list.rb +20 -10
  72. data/lib/axlsx/util/storage.rb +1 -1
  73. data/lib/axlsx/util/validators.rb +23 -7
  74. data/lib/axlsx/version.rb +5 -2
  75. data/lib/axlsx/workbook/shared_strings_table.rb +69 -0
  76. data/lib/axlsx/workbook/shared_strings_table.rb~ +69 -0
  77. data/lib/axlsx/workbook/workbook.rb +82 -26
  78. data/lib/axlsx/workbook/worksheet/cell.rb +172 -117
  79. data/lib/axlsx/workbook/worksheet/col.rb +114 -0
  80. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  81. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +29 -0
  82. data/lib/axlsx/workbook/worksheet/page_margins.rb +97 -0
  83. data/lib/axlsx/workbook/worksheet/row.rb +53 -21
  84. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  85. data/lib/axlsx/workbook/worksheet/table.rb +96 -0
  86. data/lib/axlsx/workbook/worksheet/table.rb~ +97 -0
  87. data/lib/axlsx/workbook/worksheet/worksheet.rb +270 -121
  88. data/lib/axlsx.rb +41 -14
  89. data/lib/schema/dc.xsd +5 -5
  90. data/lib/schema/dcmitype.xsd +5 -3
  91. data/lib/schema/dcterms.xsd +15 -15
  92. data/lib/schema/opc-coreProperties.xsd +6 -2
  93. data/lib/schema/xml.xsd +7 -8
  94. data/test/#benchmark.txt# +7 -0
  95. data/test/#tc_helper.rb# +3 -0
  96. data/test/benchmark.rb +81 -0
  97. data/test/benchmark.rb~ +0 -0
  98. data/test/benchmark.txt +6 -0
  99. data/test/benchmark.txt~ +6 -0
  100. data/test/content_type/tc_content_type.rb +31 -31
  101. data/test/content_type/tc_default.rb +9 -22
  102. data/test/content_type/tc_override.rb +8 -21
  103. data/test/doc_props/tc_app.rb +2 -8
  104. data/test/doc_props/tc_core.rb +6 -7
  105. data/test/drawing/tc_axis.rb +7 -3
  106. data/test/drawing/tc_bar_3D_chart.rb +6 -7
  107. data/test/drawing/tc_bar_series.rb +4 -5
  108. data/test/drawing/tc_cat_axis.rb +2 -3
  109. data/test/drawing/tc_cat_axis_data.rb +2 -3
  110. data/test/drawing/tc_chart.rb +13 -14
  111. data/test/drawing/tc_drawing.rb +7 -8
  112. data/test/drawing/tc_graphic_frame.rb +3 -4
  113. data/test/drawing/tc_hyperlink.rb +69 -0
  114. data/test/drawing/tc_line_3d_chart.rb +5 -6
  115. data/test/drawing/tc_line_series.rb +3 -4
  116. data/test/drawing/tc_marker.rb +3 -4
  117. data/test/drawing/tc_one_cell_anchor.rb +6 -7
  118. data/test/drawing/tc_pic.rb +13 -8
  119. data/test/drawing/tc_picture_locking.rb +2 -3
  120. data/test/drawing/tc_pie_3D_chart.rb +5 -6
  121. data/test/drawing/tc_pie_series.rb +4 -5
  122. data/test/drawing/tc_scaling.rb +3 -4
  123. data/test/drawing/tc_scatter_chart.rb +43 -0
  124. data/test/drawing/tc_scatter_series.rb +20 -0
  125. data/test/drawing/tc_ser_axis.rb +2 -3
  126. data/test/drawing/tc_series.rb +4 -5
  127. data/test/drawing/tc_series_title.rb +4 -5
  128. data/test/drawing/tc_title.rb +4 -5
  129. data/test/drawing/tc_two_cell_anchor.rb +4 -5
  130. data/test/drawing/tc_val_axis.rb +2 -3
  131. data/test/drawing/tc_val_axis_data.rb +2 -3
  132. data/test/drawing/tc_view_3D.rb +6 -7
  133. data/test/example.csv +1000 -0
  134. data/test/example.xlsx +0 -0
  135. data/test/example_streamed.xlsx +0 -0
  136. data/test/profile.rb +33 -0
  137. data/test/rels/tc_relationship.rb +10 -6
  138. data/test/rels/tc_relationships.rb +4 -5
  139. data/test/stylesheet/tc_border.rb +3 -4
  140. data/test/stylesheet/tc_border_pr.rb +3 -4
  141. data/test/stylesheet/tc_cell_alignment.rb +10 -6
  142. data/test/stylesheet/tc_cell_protection.rb +2 -3
  143. data/test/stylesheet/tc_cell_style.rb +2 -3
  144. data/test/stylesheet/tc_color.rb +2 -3
  145. data/test/stylesheet/tc_fill.rb +1 -2
  146. data/test/stylesheet/tc_font.rb +12 -5
  147. data/test/stylesheet/tc_gradient_fill.rb +1 -2
  148. data/test/stylesheet/tc_gradient_stop.rb +1 -2
  149. data/test/stylesheet/tc_num_fmt.rb +1 -2
  150. data/test/stylesheet/tc_pattern_fill.rb +3 -4
  151. data/test/stylesheet/tc_styles.rb +16 -6
  152. data/test/stylesheet/tc_table_style.rb +2 -3
  153. data/test/stylesheet/tc_table_style_element.rb +2 -3
  154. data/test/stylesheet/tc_table_styles.rb +3 -4
  155. data/test/stylesheet/tc_xf.rb +16 -17
  156. data/test/tc_axlsx.rb +39 -0
  157. data/test/tc_axlsx.rb~ +0 -0
  158. data/test/tc_helper.rb +3 -0
  159. data/test/tc_helper.rb~ +3 -0
  160. data/test/tc_package.rb +43 -9
  161. data/test/util/tc_simple_typed_list.rb +8 -9
  162. data/test/util/tc_validators.rb +7 -8
  163. data/test/workbook/tc_shared_strings_table.rb +38 -0
  164. data/test/workbook/tc_workbook.rb +32 -6
  165. data/test/workbook/worksheet/table/tc_table.rb +71 -0
  166. data/test/workbook/worksheet/table/tc_table.rb~ +72 -0
  167. data/test/workbook/worksheet/tc_cell.rb +70 -13
  168. data/test/workbook/worksheet/tc_col.rb +59 -0
  169. data/test/workbook/worksheet/tc_col.rb~ +10 -0
  170. data/test/workbook/worksheet/tc_date_time_converter.rb +126 -0
  171. data/test/workbook/worksheet/tc_page_margins.rb +97 -0
  172. data/test/workbook/worksheet/tc_row.rb +54 -4
  173. data/test/workbook/worksheet/tc_worksheet.rb +198 -31
  174. metadata +167 -111
  175. data/test/drawing/tc_line_series.tc~ +0 -34
  176. data/test/drawing/tc_picture_locking.rb~ +0 -77
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module Axlsx
2
3
 
3
4
  # The Cfb class is a MS-OFF-CRYPTOGRAPHY specific OLE (MS-CBF) writer implementation. No attempt is made to re-invent the wheel for read/write of compound binary files.
@@ -10,13 +11,13 @@ module Axlsx
10
11
  VERSION_PACKING = 'l s30 l3'
11
12
 
12
13
  # The serialization for the MS-OFF-CRYPTO dataspace map stream
13
- DATA_SPACE_MAP_PACKING = 'l6 s16 l s25'
14
+ DATA_SPACE_MAP_PACKING = 'l6 s16 l s25 x2'
14
15
 
15
16
  # The serialization for the MS-OFF-CRYPTO strong encrytion data space stream
16
- STRONG_ENCRYPTION_DATA_SPACE_PACKING = 'l3 s25'
17
+ STRONG_ENCRYPTION_DATA_SPACE_PACKING = 'l3 s26'
17
18
 
18
19
  # The serialization for the MS-OFF-CRYPTO primary stream
19
- PRIMARY_PACKING = 'l3 s38 l s39 l3 x12 l x2'
20
+ PRIMARY_PACKING = 'l3 s38 l s40 l3 x12 l'
20
21
 
21
22
  # The cutoff size that determines if a stream should be in the mini-fat or the fat
22
23
  MINI_CUTOFF = 4096
@@ -28,6 +29,7 @@ module Axlsx
28
29
  # @param [MsOffCrypto] ms_off_crypto
29
30
  def initialize(ms_off_crypto)
30
31
  @file_name = ms_off_crypto.file_name
32
+ @ms_off_crypto = ms_off_crypto
31
33
  create_storages
32
34
  mini_fat_stream
33
35
  mini_fat
@@ -95,6 +97,17 @@ module Axlsx
95
97
  @header ||= create_header
96
98
  end
97
99
 
100
+ # returns the encryption info from the ms_off_crypt object provided during intialization
101
+ # @return [String] encryption info
102
+ def encryption_info
103
+ @ms_off_crypto.encryption_info
104
+ end
105
+
106
+ # returns the encrypted package from the ms_off_crypt object provided during initalization
107
+ # @return [String] encrypted package
108
+ def encrypted_package
109
+ @ms_off_crypto.encrypted_package
110
+ end
98
111
 
99
112
  # writes the compound binary file to disk
100
113
  def save
@@ -114,12 +127,11 @@ module Axlsx
114
127
  # Generates the storages required for ms-office-cryptography cfb
115
128
  def create_storages
116
129
  @storages = []
117
- @encryption_info = ms_off_crypto.encryption_info
118
- @encrypted_package = ms_off_crypto.encrypted_package
119
- @storages << Storage.new('R', :type=>Storage::TYPES[:root], :color=>Storage::COLORS[:red], :child=>1, :modified=>129685612742510730)
120
- @storages.last.name_size = 2
121
- @storages << Storage.new('EncryptionInfo', :data=>@encryption_info, :left=>3, :size => @encryption_info.size) # example shows right child. do we need the summary info????
122
- @storages << Storage.new('EncryptedPackage', :data=>@encrypted_package, :color=>Storage::COLORS[:red], :size=>@encrypted_package.size)
130
+ @encryption_info = @ms_off_crypto.encryption_info
131
+ @encrypted_package = @ms_off_crypto.encrypted_package
132
+
133
+ @storages << Storage.new('EncryptionInfo', :data=>encryption_info, :left=>3, :right=>11) # example shows right child. do we need the summary info????
134
+ @storages << Storage.new('EncryptedPackage', :data=>encrypted_package, :color=>Storage::COLORS[:red])
123
135
  @storages << Storage.new([6].pack("c")+"DataSpaces", :child=>5, :modified =>129685612740945580, :created=>129685612740819979)
124
136
  @storages << version
125
137
  @storages << data_space_map
@@ -128,6 +140,12 @@ module Axlsx
128
140
  @storages << Storage.new('TransformInfo', :color => Storage::COLORS[:red], :child=>9, :created=>129685612740834130, :modified=>129685612740943959)
129
141
  @storages << Storage.new('StrongEncryptionTransform', :child=>10, :created=>129685612740834169, :modified=>129685612740942280)
130
142
  @storages << primary
143
+ # @storages << summary_information
144
+ # @storages << document_summary_information
145
+
146
+ # we do this at the end as we need to build the minifat stream to determine the size. #HOWEVER - it looks like the size should not include the padding?
147
+ @storages.unshift Storage.new('Root Entry', :type=>Storage::TYPES[:root], :color=>Storage::COLORS[:red], :child=>1, :data => mini_fat_stream)
148
+
131
149
  end
132
150
 
133
151
  # generates the mini fat stream
@@ -135,10 +153,11 @@ module Axlsx
135
153
  def create_mini_fat_stream
136
154
  mfs = []
137
155
  @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each_with_index do |stream, index|
156
+ puts "#{stream.name.pack('c*')}: #{stream.data.size}"
138
157
  mfs.concat stream.data
139
- mfs.concat Array.new(64 - (mfs.size % 64), 0) if mfs.size % 64
158
+ mfs.concat Array.new(64 - (mfs.size % 64), 0) if mfs.size % 64 > 0
159
+ puts "mini fat stream size: #{mfs.size}"
140
160
  end
141
- @storages[0].size = mfs.size
142
161
  mfs.concat(Array.new(512 - (mfs.size % 512), 0))
143
162
  mfs.pack 'c*'
144
163
  end
@@ -149,7 +168,7 @@ module Axlsx
149
168
  mfs = []
150
169
  @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size >= MINI_CUTOFF}.each_with_index do |stream, index|
151
170
  mfs.concat stream.data
152
- mfs.concat Array.new(512 - (mfs.size % 512), 0) if mfs.size % 512
171
+ mfs.concat Array.new(512 - (mfs.size % 512), 0) if mfs.size % 512 > 0
153
172
  end
154
173
  mfs.pack 'c*'
155
174
  end
@@ -214,7 +233,7 @@ module Axlsx
214
233
  # creates the stron encryption data space storage
215
234
  # @return [Storgae]
216
235
  def create_strong_encryption_data_space
217
- v_stream = [8,1,50,"StrongEncryptionTransform".bytes.to_a].flatten.pack STRONG_ENCRYPTION_DATA_SPACE_PACKING
236
+ v_stream = [8,1,50,"StrongEncryptionTransform".bytes.to_a,0].flatten.pack STRONG_ENCRYPTION_DATA_SPACE_PACKING
218
237
  Storage.new("StrongEncryptionDataSpace", :data=>v_stream, :size => v_stream.size)
219
238
  end
220
239
 
@@ -222,41 +241,58 @@ module Axlsx
222
241
  # @return [Storgae]
223
242
  def create_primary
224
243
  v_stream = [88,1,76,"{FF9A3F03-56EF-4613-BDD5-5A41C1D07246}".bytes.to_a].flatten
225
- v_stream.concat [78, "Microsoft.Container.EncryptionTransform".bytes.to_a,1,1,1,4].flatten
244
+ v_stream.concat [78, "Microsoft.Container.EncryptionTransform".bytes.to_a,0,1,1,1,4].flatten
226
245
  v_stream = v_stream.pack PRIMARY_PACKING
227
246
  Storage.new([6].pack("c")+"Primary", :data=>v_stream)
228
247
  end
229
248
 
230
249
 
231
- SUMMARY_INFORMATION_PACKING = ""
232
250
  # creates the summary information storage
233
251
  # @return [Storage]
234
252
  def create_summary_information
235
- # FEFF 0000 030A 0100 0000 0000 0000 0000
236
- # 0000 0000 0000 0000 0100 0000 E085 9FF2
237
- # F94F 6810 AB91 0800 2B27 B3D9 3000 0000
238
- # AC00 0000 0700 0000 0100 0000 4000 0000
239
- # 0400 0000 4800 0000 0800 0000 5800 0000
240
- # 1200 0000 6800 0000 0C00 0000 8C00 0000
241
- # 0D00 0000 9800 0000 1300 0000 A400 0000
242
- # 0200 0000 E9FD 0000 1E00 0000 0800 0000
243
- # 7261 6E64 796D 0000 1E00 0000 0800 0000
244
- # 7261 6E64 796D 0000 1E00 0000 1C00 0000
245
- # 4D69 6372 6F73 6F66 7420 4D61 6369 6E74
246
- # 6F73 6820 4578 6365 6C00 0000 4000 0000
247
- # 10AC 5396 60BC CC01 4000 0000 40F4 FDAF
248
- # 60BC CC01 0300 0000 0100 0000
249
253
  v_stream = []
250
- v_stream = v_stream.pack SUMMARY_INFORMATION_PACKING
251
- Storage.new([5].pack('c')+"SummaryInformation", :data=>v_stream)
254
+ v_stream.concat [0xFEFF, 0x0000, 0x030A, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000]
255
+ v_stream.concat [0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, 0xE085, 0x9FF2]
256
+ v_stream.concat [0xF94F, 0x6810, 0xAB91, 0x0800, 0x2B27, 0xB3D9, 0x3000, 0x0000]
257
+ v_stream.concat [0xAC00, 0x0000, 0x0700, 0x0000, 0x0100, 0x0000, 0x4000, 0x0000]
258
+ v_stream.concat [0x0400, 0x0000, 0x4800, 0x0000, 0x0800, 0x0000, 0x5800, 0x0000]
259
+ v_stream.concat [0x1200, 0x0000, 0x6800, 0x0000, 0x0C00, 0x0000, 0x8C00, 0x0000]
260
+ v_stream.concat [0x0D00, 0x0000, 0x9800, 0x0000, 0x1300, 0x0000, 0xA400, 0x0000]
261
+ v_stream.concat [0x0200, 0x0000, 0xE9FD, 0x0000, 0x1E00, 0x0000, 0x0800, 0x0000]
262
+ v_stream.concat [0x7261, 0x6E64, 0x796D, 0x0000, 0x1E00, 0x0000, 0x0800, 0x0000]
263
+ v_stream.concat [0x7261, 0x6E64, 0x796D, 0x0000, 0x1E00, 0x0000, 0x1C00, 0x0000]
264
+ v_stream.concat [0x4D69, 0x6372, 0x6F73, 0x6F66, 0x7420, 0x4D61, 0x6369, 0x6E74]
265
+ v_stream.concat [0x6F73, 0x6820, 0x4578, 0x6365, 0x6C00, 0x0000, 0x4000, 0x0000]
266
+ v_stream.concat [0x10AC, 0x5396, 0x60BC, 0xCC01, 0x4000, 0x0000, 0x40F4, 0xFDAF]
267
+ v_stream.concat [0x60BC, 0xCC01, 0x0300, 0x0000, 0x0100, 0x0000]
268
+
269
+ v_stream = v_stream.pack "s*"
270
+
271
+ Storage.new([5].pack('c')+"SummaryInformation", :data=>v_stream, :left => 2)
252
272
  end
253
273
 
254
- DOCUMENT_SUMMARY_INFORMATION_PACKING = ""
274
+
255
275
  # creates the document summary information storage
256
276
  # @return [Storage]
257
277
  def create_document_summary_information
258
278
  v_stream = []
259
- v_stream = v_stream.pack DOCUMENT_SUMMARY_INFORMATION_PACKING
279
+ v_stream.concat [0xFEFF, 0x0000, 0x030A, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000]
280
+ v_stream.concat [0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, 0x02D5, 0xCDD5]
281
+ v_stream.concat [0x9C2E, 0x1B10, 0x9397, 0x0800, 0x2B2C, 0xF9AE, 0x3000, 0x0000]
282
+ v_stream.concat [0xCC00, 0x0000, 0x0900, 0x0000, 0x0100, 0x0000, 0x5000, 0x0000]
283
+ v_stream.concat [0x0F00, 0x0000, 0x5800, 0x0000, 0x1700, 0x0000, 0x6400, 0x0000]
284
+ v_stream.concat [0x0B00, 0x0000, 0x6C00, 0x0000, 0x1000, 0x0000, 0x7400, 0x0000]
285
+ v_stream.concat [0x1300, 0x0000, 0x7C00, 0x0000, 0x1600, 0x0000, 0x8400, 0x0000]
286
+ v_stream.concat [0x0D00, 0x0000, 0x8C00, 0x0000, 0x0C00, 0x0000, 0x9F00, 0x0000]
287
+ v_stream.concat [0x0200, 0x0000, 0xE9FD, 0x0000, 0x1E00, 0x0000, 0x0400, 0x0000]
288
+ v_stream.concat [0x0000, 0x0000, 0x0300, 0x0000, 0x0000, 0x0C00, 0x0B00, 0x0000]
289
+ v_stream.concat [0x0000, 0x0000, 0x0B00, 0x0000, 0x0000, 0x0000, 0x0B00, 0x0000]
290
+ v_stream.concat [0x0000, 0x0000, 0x0B00, 0x0000, 0x0000, 0x0000, 0x1E10, 0x0000]
291
+ v_stream.concat [0x0100, 0x0000, 0x0700, 0x0000, 0x5368, 0x6565, 0x7431, 0x000C]
292
+ v_stream.concat [0x1000, 0x0002, 0x0000, 0x001E, 0x0000, 0x0013, 0x0000, 0x00E3]
293
+ v_stream.concat [0x83AF, 0xE383, 0xBCE3, 0x82AF, 0xE382, 0xB7E3, 0x83BC, 0xE383]
294
+ v_stream.concat [0x8800, 0x0300, 0x0000, 0x0100, 0x0000, 0x0000]
295
+ v_stream = v_stream.pack 'c*'
260
296
  Storage.new([5].pack('c')+"DocumentSummaryInformation", :data=>v_stream)
261
297
  end
262
298
 
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module Axlsx
2
3
 
3
4
  # XML Encoding
@@ -20,7 +21,7 @@ module Axlsx
20
21
 
21
22
  # dc elements (core) namespace
22
23
  CORE_NS_DC = "http://purl.org/dc/elements/1.1/"
23
-
24
+
24
25
  # dcmit (core) namespcace
25
26
  CORE_NS_DCMIT = "http://purl.org/dc/dcmitype/"
26
27
 
@@ -29,10 +30,10 @@ module Axlsx
29
30
 
30
31
  # xml schema namespace
31
32
  CORE_NS_XSI = "http://www.w3.org/2001/XMLSchema-instance"
32
-
33
+
33
34
  # spreadsheet drawing namespace
34
35
  XML_NS_XDR = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
35
-
36
+
36
37
  # drawing namespace
37
38
  XML_NS_A = "http://schemas.openxmlformats.org/drawingml/2006/main"
38
39
 
@@ -42,13 +43,12 @@ module Axlsx
42
43
  # relationships namespace
43
44
  XML_NS_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
44
45
 
45
-
46
46
  # relationships name space
47
47
  RELS_R = "http://schemas.openxmlformats.org/package/2006/relationships"
48
48
 
49
49
  # table rels namespace
50
50
  TABLE_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
51
-
51
+
52
52
  # workbook rels namespace
53
53
  WORKBOOK_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
54
54
 
@@ -64,6 +64,9 @@ module Axlsx
64
64
  # styles rels namespace
65
65
  STYLES_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
66
66
 
67
+ # shared strings namespace
68
+ SHARED_STRINGS_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"
69
+
67
70
  # drawing rels namespace
68
71
  DRAWING_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
69
72
 
@@ -73,7 +76,10 @@ module Axlsx
73
76
  # image rels namespace
74
77
  IMAGE_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
75
78
 
76
- # table content type
79
+ # image rels namespace
80
+ HYPERLINK_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
81
+
82
+ # table content type
77
83
  TABLE_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"
78
84
 
79
85
  # workbook content type
@@ -83,14 +89,14 @@ module Axlsx
83
89
  APP_CT = "application/vnd.openxmlformats-officedocument.extended-properties+xml"
84
90
 
85
91
  # rels content type
86
- RELS_CT = "application/vnd.openxmlformats-package.relationships+xml"
92
+ RELS_CT = "application/vnd.openxmlformats-package.relationships+xml"
87
93
 
88
94
  # styles content type
89
95
  STYLES_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"
90
96
 
91
97
  # xml content type
92
98
  XML_CT = "application/xml"
93
-
99
+
94
100
  # worksheet content type
95
101
  WORKSHEET_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
96
102
 
@@ -120,7 +126,7 @@ module Axlsx
120
126
 
121
127
  # jpeg extension
122
128
  JPEG_EX = "jpeg"
123
-
129
+
124
130
  # gif extension
125
131
  GIF_EX = "gif"
126
132
 
@@ -135,10 +141,13 @@ module Axlsx
135
141
 
136
142
  # styles part
137
143
  STYLES_PN = "styles.xml"
138
-
144
+
145
+ # shared_strings part
146
+ SHARED_STRINGS_PN = "sharedStrings.xml"
147
+
139
148
  # app part
140
149
  APP_PN = "docProps/app.xml"
141
-
150
+
142
151
  # core part
143
152
  CORE_PN = "docProps/core.xml"
144
153
 
@@ -163,32 +172,38 @@ module Axlsx
163
172
  # drawing rels part
164
173
  DRAWING_RELS_PN = "drawings/_rels/drawing%d.xml.rels"
165
174
 
175
+ # drawing part
176
+ TABLE_PN = "tables/table%d.xml"
177
+
166
178
  # chart part
167
179
  CHART_PN = "charts/chart%d.xml"
168
180
 
169
181
  # chart part
170
182
  IMAGE_PN = "media/image%d.%s"
171
183
 
184
+ # location of schema files for validation
185
+ SCHEMA_BASE = File.dirname(__FILE__)+'/../../schema/'
186
+
172
187
  # App validation schema
173
- APP_XSD = "lib/schema/shared-documentPropertiesExtended.xsd"
188
+ APP_XSD = SCHEMA_BASE + "shared-documentPropertiesExtended.xsd"
174
189
 
175
190
  # core validation schema
176
- CORE_XSD = "lib/schema/opc-coreProperties.xsd"
191
+ CORE_XSD = SCHEMA_BASE + "opc-coreProperties.xsd"
177
192
 
178
193
  # content types validation schema
179
- CONTENT_TYPES_XSD = "lib/schema/opc-contentTypes.xsd"
194
+ CONTENT_TYPES_XSD = SCHEMA_BASE + "opc-contentTypes.xsd"
180
195
 
181
196
  # rels validation schema
182
- RELS_XSD = "lib/schema/opc-relationships.xsd"
197
+ RELS_XSD = SCHEMA_BASE + "opc-relationships.xsd"
183
198
 
184
199
  # spreadsheetML validation schema
185
- SML_XSD = "lib/schema/sml.xsd"
186
-
200
+ SML_XSD = SCHEMA_BASE + "sml.xsd"
201
+
187
202
  # drawing validation schema
188
- DRAWING_XSD = "lib/schema/dml-spreadsheetDrawing.xsd"
203
+ DRAWING_XSD = SCHEMA_BASE + "dml-spreadsheetDrawing.xsd"
189
204
 
190
205
  # number format id for pecentage formatting using the default formatting id.
191
- NUM_FMT_PERCENT = 9
206
+ NUM_FMT_PERCENT = 9
192
207
 
193
208
  # number format id for date format like 2011/11/13
194
209
  NUM_FMT_YYYYMMDD = 100
@@ -203,7 +218,7 @@ module Axlsx
203
218
  STYLE_DATE = 2
204
219
 
205
220
  # error messages RestrictionValidor
206
- ERR_RESTRICTION = "Invalid Data: %s. %s must be one of %s."
221
+ ERR_RESTRICTION = "Invalid Data: %s. %s must be one of %s."
207
222
 
208
223
  # error message DataTypeValidator
209
224
  ERR_TYPE = "Invalid Data %s for %s. must be %s."
@@ -211,6 +226,10 @@ module Axlsx
211
226
  # error message for RegexValidator
212
227
  ERR_REGEX = "Invalid Data. %s does not match %s."
213
228
 
229
+ # error message for sheets that use a name which is longer than 31 bytes
230
+ ERR_SHEET_NAME_TOO_LONG = "Your worksheet name '%s' is too long. Worksheet names must be 31 characters (bytes) or less"
231
+
214
232
  # error message for duplicate sheet names
215
233
  ERR_DUPLICATE_SHEET_NAME = "There is already a worksheet in this workbook named '%s'. Please use a unique name"
234
+
216
235
  end
@@ -1,4 +1,4 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: UTF-8
2
2
  require 'digest'
3
3
  require 'base64'
4
4
  require 'openssl'
@@ -48,7 +48,7 @@ module Axlsx
48
48
  # encrypts and returns the package specified by the file name
49
49
  # @return [String]
50
50
  def encrypted_package
51
- @encrypted_package ||= encrypt_package(file_name, password)
51
+ @encrypted_package ||= encrypt_package(file_name)
52
52
  end
53
53
 
54
54
  # returns the encryption info for this instance of ms-off-crypto
@@ -94,10 +94,10 @@ module Axlsx
94
94
  end
95
95
 
96
96
  # size of unencrypted package? concated with encrypted package
97
- def encrypt_package(file_name, password)
97
+ def encrypt_package(file_name)
98
98
  package = File.open(file_name, 'r')
99
- package_text = package.read
100
- [package_text.bytes.to_a.size].pack('q') + encrypt(package_text)
99
+ crypt_pack = encrypt(package.read)
100
+ [crypt_pack.size].pack('q') + crypt_pack
101
101
  end
102
102
 
103
103
  # Generates an encryption info structure
@@ -106,18 +106,18 @@ module Axlsx
106
106
  header = [3, 0, 2, 0] # version
107
107
  # Header flags copy
108
108
  header.concat [0x24, 0, 0, 0] #flags -- VERY UNSURE ABOUT THIS STILL
109
- header.concat [0, 0, 0, 0] #unused
109
+ # header.concat [0, 0, 0, 0] #unused
110
110
  header.concat [0xA4, 0, 0, 0] #length
111
111
  # Header
112
112
  header.concat [0x24, 0, 0, 0] #flags again
113
- header.concat [0, 0, 0, 0] #unused again,
113
+ # header.concat [0, 0, 0, 0] #unused again,
114
114
  header.concat [0x0E, 0x66, 0, 0] #alg id
115
115
  header.concat [0x04, 0x80, 0, 0] #alg hash id
116
116
  header.concat [key.size, 0, 0, 0] #key size
117
117
  header.concat [0x18, 0, 0, 0] #provider type
118
- header.concat [0, 0, 0, 0] #reserved 1
119
- header.concat [0, 0, 0, 0] #reserved 2
120
- #header.concat [0xA0, 0xC7, 0xDC, 0x2, 0, 0, 0, 0]
118
+ # header.concat [0, 0, 0, 0] #reserved 1
119
+ # header.concat [0, 0, 0, 0] #reserved 2
120
+ header.concat [0xA0, 0xC7, 0xDC, 0x2, 0, 0, 0, 0]
121
121
  header.concat "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)".bytes.to_a.pack('s*').bytes.to_a
122
122
  header.concat [0, 0] #null terminator
123
123
 
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module Axlsx
2
3
  # The Parser module mixes in a number of methods to help in generating a model from xml
3
4
  # This module is not included in the axlsx library at this time. It is for future development only,
@@ -1,5 +1,6 @@
1
+ # encoding: UTF-8
1
2
  module Axlsx
2
- # A SimpleTypedList is a type restrictive collection that allows some of the methods from Array and supports basic xml serialization.
3
+ # A SimpleTypedList is a type restrictive collection that allows some of the methods from Array and supports basic xml serialization.
3
4
  # @private
4
5
  class SimpleTypedList
5
6
  # The class constants of allowed types
@@ -11,14 +12,14 @@ module Axlsx
11
12
  attr_reader :locked_at
12
13
 
13
14
  # The tag name to use when serializing this object
14
- # by default the parent node for all items in the list is the classname of the first allowed type with the first letter in lowercase.
15
+ # by default the parent node for all items in the list is the classname of the first allowed type with the first letter in lowercase.
15
16
  # @return [String]
16
17
  attr_reader :serialize_as
17
18
 
18
19
  # Creats a new typed list
19
20
  # @param [Array, Class] type An array of Class objects or a single Class object
20
21
  # @param [String] serialize The tag name to use in serialization
21
- # @raise [ArgumentError] if all members of type are not Class objects
22
+ # @raise [ArgumentError] if all members of type are not Class objects
22
23
  def initialize type, serialize_as=nil
23
24
  if type.is_a? Array
24
25
  type.each { |item| raise ArgumentError, "All members of type must be Class objects" unless item.is_a? Class }
@@ -38,7 +39,7 @@ module Axlsx
38
39
  @locked_at = @list.size
39
40
  self
40
41
  end
41
-
42
+
42
43
  def to_ary
43
44
  @list
44
45
  end
@@ -57,7 +58,7 @@ module Axlsx
57
58
  def <<(v)
58
59
  DataTypeValidator.validate "SimpleTypedList.<<", @allowed_types, v
59
60
  @list << v
60
- @list.size - 1
61
+ @list.size - 1
61
62
  end
62
63
 
63
64
  # alternate of << method
@@ -103,14 +104,14 @@ module Axlsx
103
104
  return false unless @locked_at.is_a? Fixnum
104
105
  index < @locked_at
105
106
  end
106
-
107
+
107
108
  # override the equality method so that this object can be compared to a simple array.
108
109
  # if this object's list is equal to the specifiec array, we return true.
109
110
  def ==(v)
110
111
  v == @list
111
112
  end
112
113
  # method_mission override to pass allowed methods to the list.
113
- # @note
114
+ # @note
114
115
  # the following methods are not allowed
115
116
  # :replace
116
117
  # :insert
@@ -139,25 +140,34 @@ module Axlsx
139
140
  DELEGATES = Array.instance_methods - self.instance_methods - DESTRUCTIVE
140
141
 
141
142
  DELEGATES.each do |method|
142
- class_eval %{
143
+ class_eval %{
143
144
  def #{method}(*args, &block)
144
145
  @list.send(:#{method}, *args, &block)
145
146
  end
146
147
  }
147
148
  end
148
149
 
150
+ def to_xml_string(str = '')
151
+ classname = @allowed_types[0].name.split('::').last
152
+ el_name = serialize_as || (classname[0,1].downcase + classname[1..-1])
153
+ str << '<' << el_name << ' count="' << @list.size.to_s << '">'
154
+ @list.each { |item| item.to_xml_string(str) }
155
+ str << '</' << el_name << '>'
156
+ end
157
+
149
158
  # Serializes the list
150
- # If the serialize_as property is set, it is used as the parent node name.
159
+ # If the serialize_as property is set, it is used as the parent node name.
151
160
  # If the serialize_as property is nil, the first item in the list of allowed_types will be used, having the first letter of the class changed to lower case.
152
161
  # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
153
162
  # @return [String]
154
163
  def to_xml(xml)
155
164
  classname = @allowed_types[0].name.split('::').last
156
- el_name = serialize_as || (classname[0,1].downcase + classname[1..-1]).pluralize
165
+ el_name = serialize_as || (classname[0,1].downcase + classname[1..-1])
157
166
  xml.send(el_name, :count=>@list.size) {
158
167
  @list.each { |item| item.to_xml(xml) }
159
168
  }
160
169
  end
170
+
161
171
  end
162
172
 
163
173
 
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module Axlsx
2
3
 
3
4
  # The Storage class represents a storage object or stream in a compound file.
@@ -28,7 +29,6 @@ module Axlsx
28
29
  @modified,
29
30
  @sector,
30
31
  @size].flatten
31
- puts data.inspect
32
32
  data.pack(PACKING)
33
33
  end
34
34
 
@@ -1,14 +1,15 @@
1
+ # encoding: UTF-8
1
2
  module Axlsx
2
3
  # Validate a value against a specific list of allowed values.
3
4
  class RestrictionValidator
4
5
  # Perform validation
5
6
  # @param [String] name The name of what is being validatied. This is included in the error message
6
7
  # @param [Array] choices The list of choices to validate against
7
- # @param [Any] v The value to be validated
8
+ # @param [Any] v The value to be validated
8
9
  # @raise [ArgumentError] Raised if the value provided is not in the list of choices.
9
10
  # @return [Boolean] true if validation succeeds.
10
11
  def self.validate(name, choices, v)
11
- raise ArgumentError, (ERR_RESTRICTION % [v.to_s, name, choices.inspect]) unless choices.include?(v)
12
+ raise ArgumentError, (ERR_RESTRICTION % [v.to_s, name, choices.inspect]) unless choices.include?(v)
12
13
  true
13
14
  end
14
15
  end
@@ -52,6 +53,14 @@ module Axlsx
52
53
  DataTypeValidator.validate(:unsigned_int, [Fixnum, Integer], v, lambda { |arg| arg.respond_to?(:>=) && arg >= 0 })
53
54
  end
54
55
 
56
+ # Requires that the value is a Fixnum Integer or Float and is greater or equal to 0
57
+ # @param [Any] v The value validated
58
+ # @raise [ArgumentError] raised if the value is not a Fixnun, Integer, Float value greater or equal to 0
59
+ # @return [Boolean] true if the data is valid
60
+ def self.validate_unsigned_numeric(v)
61
+ DataTypeValidator.validate("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg >= 0 })
62
+ end
63
+
55
64
  # Requires that the value is a Fixnum or Integer
56
65
  # @param [Any] v The value validated
57
66
  def self.validate_int(v)
@@ -59,7 +68,7 @@ module Axlsx
59
68
  end
60
69
 
61
70
  # Requires that the value is a form that can be evaluated as a boolean in an xml document.
62
- # The value must be an instance of Fixnum, String, Integer, Symbol, TrueClass or FalseClass and
71
+ # The value must be an instance of Fixnum, String, Integer, Symbol, TrueClass or FalseClass and
63
72
  # it must be one of 0, 1, "true", "false", :true, :false, true, false, "0", or "1"
64
73
  # @param [Any] v The value validated
65
74
  def self.validate_boolean(v)
@@ -70,13 +79,13 @@ module Axlsx
70
79
  # @param [Any] v The value validated
71
80
  def self.validate_string(v)
72
81
  DataTypeValidator.validate :string, String, v
73
- end
82
+ end
74
83
 
75
84
  # Requires that the value is a Float
76
85
  # @param [Any] v The value validated
77
86
  def self.validate_float(v)
78
87
  DataTypeValidator.validate :float, Float, v
79
- end
88
+ end
80
89
 
81
90
  # Requires that the value is valid pattern type.
82
91
  # valid pattern types must be one of :none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown,
@@ -94,6 +103,13 @@ module Axlsx
94
103
  RestrictionValidator.validate :gradient_type, [:linear, :path], v
95
104
  end
96
105
 
106
+ # Requires that the value is a valid scatterStyle
107
+ # must be one of :none | :line | :lineMarker | :marker | :smooth | :smoothMarker
108
+ # must be one of "none" | "line" | "lineMarker" | "marker" | "smooth" | "smoothMarker"
109
+ # @param [Symbol|String] the value to validate
110
+ def self.validate_scatter_style(v)
111
+ Axlsx::RestrictionValidator.validate "ScatterChart.scatterStyle", [:none, :line, :lineMarker, :marker, :smooth, :smoothMarker], v.to_sym
112
+ end
97
113
  # Requires that the value is a valid horizontal_alignment
98
114
  # :general, :left, :center, :right, :fill, :justify, :centerContinuous, :distributed are allowed
99
115
  # @param [Any] v The value validated
@@ -116,10 +132,10 @@ module Axlsx
116
132
  end
117
133
 
118
134
  # Requires that the value is a valid relationship_type
119
- # XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R are allowed
135
+ # XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R are allowed
120
136
  # @param [Any] v The value validated
121
137
  def self.validate_relationship_type(v)
122
- RestrictionValidator.validate :relationship_type, [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R], v
138
+ RestrictionValidator.validate :relationship_type, [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R], v
123
139
  end
124
140
 
125
141
  # Requires that the value is a valid table element type
data/lib/axlsx/version.rb CHANGED
@@ -1,7 +1,10 @@
1
+ # encoding: UTF-8
1
2
  module Axlsx
2
- # version
3
+
4
+ # The version of the gem
3
5
  # When using bunle exec rake and referencing the gem on github or locally
4
6
  # it will use the gemspec, which preloads this constant for the gem's version.
5
7
  # We check to make sure that it has not already been loaded
6
- VERSION="1.0.15" unless Axlsx.const_defined? :VERSION
8
+ VERSION="1.1.0" unless defined? Axlsx::VERSION
9
+
7
10
  end