axlsx 1.1.0 → 1.2.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 (214) hide show
  1. data/.yardopts +5 -2
  2. data/CHANGELOG.md +78 -0
  3. data/LICENSE +1 -1
  4. data/README.md +132 -331
  5. data/Rakefile +17 -5
  6. data/examples/basic_charts.rb +54 -0
  7. data/examples/chart_colors.rb +88 -0
  8. data/examples/conditional_formatting/example_conditional_formatting.rb +72 -0
  9. data/examples/conditional_formatting/getting_barred.rb +37 -0
  10. data/examples/conditional_formatting/hitting_the_high_notes.rb +37 -0
  11. data/examples/conditional_formatting/scaled_colors.rb +39 -0
  12. data/examples/conditional_formatting/stop_and_go.rb +37 -0
  13. data/examples/data_validation.rb +50 -0
  14. data/examples/example.rb +300 -152
  15. data/examples/example.xlsx +0 -0
  16. data/examples/example_streamed.xlsx +0 -0
  17. data/examples/extractive.pdf +0 -0
  18. data/examples/extractive.rb +45 -0
  19. data/examples/no-use_autowidth.xlsx +0 -0
  20. data/examples/sample.png +0 -0
  21. data/examples/scraping_html.rb +91 -0
  22. data/examples/shared_strings_example.xlsx +0 -0
  23. data/examples/sheet_protection.rb +10 -0
  24. data/examples/sheet_view.rb +34 -0
  25. data/examples/skydrive/real_example.rb +63 -0
  26. data/examples/two_cell_anchor_image.rb +11 -0
  27. data/lib/axlsx/content_type/content_type.rb +2 -0
  28. data/lib/axlsx/content_type/default.rb +30 -15
  29. data/lib/axlsx/content_type/override.rb +29 -14
  30. data/lib/axlsx/doc_props/app.rb +161 -104
  31. data/lib/axlsx/doc_props/core.rb +9 -5
  32. data/lib/axlsx/drawing/ax_data_source.rb +26 -0
  33. data/lib/axlsx/drawing/axis.rb +106 -35
  34. data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
  35. data/lib/axlsx/drawing/bar_series.rb +25 -7
  36. data/lib/axlsx/drawing/cat_axis.rb +50 -22
  37. data/lib/axlsx/drawing/chart.rb +69 -56
  38. data/lib/axlsx/drawing/d_lbls.rb +100 -0
  39. data/lib/axlsx/drawing/drawing.rb +28 -12
  40. data/lib/axlsx/drawing/graphic_frame.rb +2 -1
  41. data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
  42. data/lib/axlsx/drawing/line_series.rb +20 -4
  43. data/lib/axlsx/drawing/num_data.rb +52 -0
  44. data/lib/axlsx/drawing/num_data_source.rb +61 -0
  45. data/lib/axlsx/drawing/num_val.rb +32 -0
  46. data/lib/axlsx/drawing/pic.rb +44 -4
  47. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
  48. data/lib/axlsx/drawing/pie_series.rb +18 -4
  49. data/lib/axlsx/drawing/scatter_chart.rb +12 -18
  50. data/lib/axlsx/drawing/scatter_series.rb +28 -2
  51. data/lib/axlsx/drawing/ser_axis.rb +1 -1
  52. data/lib/axlsx/drawing/series.rb +1 -1
  53. data/lib/axlsx/drawing/str_data.rb +42 -0
  54. data/lib/axlsx/drawing/str_val.rb +33 -0
  55. data/lib/axlsx/drawing/title.rb +21 -9
  56. data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
  57. data/lib/axlsx/drawing/view_3D.rb +44 -31
  58. data/lib/axlsx/drawing/vml_drawing.rb +42 -0
  59. data/lib/axlsx/drawing/vml_shape.rb +125 -0
  60. data/lib/axlsx/package.rb +44 -16
  61. data/lib/axlsx/rels/relationship.rb +3 -3
  62. data/lib/axlsx/rels/relationships.rb +1 -11
  63. data/lib/axlsx/stylesheet/color.rb +0 -1
  64. data/lib/axlsx/stylesheet/dxf.rb +79 -0
  65. data/lib/axlsx/stylesheet/font.rb +2 -1
  66. data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
  67. data/lib/axlsx/stylesheet/styles.rb +143 -50
  68. data/lib/axlsx/stylesheet/table_style.rb +3 -3
  69. data/lib/axlsx/stylesheet/xf.rb +2 -0
  70. data/lib/axlsx/util/constants.rb +36 -0
  71. data/lib/axlsx/util/simple_typed_list.rb +15 -21
  72. data/lib/axlsx/util/validators.rb +122 -5
  73. data/lib/axlsx/version.rb +2 -7
  74. data/lib/axlsx/workbook/defined_name.rb +174 -0
  75. data/lib/axlsx/workbook/defined_names.rb +21 -0
  76. data/lib/axlsx/workbook/shared_strings_table.rb +12 -13
  77. data/lib/axlsx/workbook/workbook.rb +71 -13
  78. data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
  79. data/lib/axlsx/workbook/worksheet/cell.rb +45 -36
  80. data/lib/axlsx/workbook/worksheet/cfvo.rb +62 -0
  81. data/lib/axlsx/workbook/worksheet/col.rb +17 -1
  82. data/lib/axlsx/workbook/worksheet/color_scale.rb +76 -0
  83. data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
  84. data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
  85. data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
  86. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +82 -0
  87. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +216 -0
  88. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
  89. data/lib/axlsx/workbook/worksheet/data_bar.rb +97 -0
  90. data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
  91. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
  92. data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
  93. data/lib/axlsx/workbook/worksheet/icon_set.rb +83 -0
  94. data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
  95. data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
  96. data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
  97. data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
  98. data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
  99. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
  100. data/lib/axlsx/workbook/worksheet/row.rb +69 -12
  101. data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
  102. data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
  103. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
  104. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
  105. data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
  106. data/lib/axlsx/workbook/worksheet/table.rb +3 -3
  107. data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
  108. data/lib/axlsx/workbook/worksheet/worksheet.rb +379 -233
  109. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
  110. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
  111. data/lib/axlsx.rb +31 -16
  112. data/test/benchmark.rb +30 -38
  113. data/test/content_type/tc_content_type.rb +1 -6
  114. data/test/doc_props/tc_app.rb +31 -1
  115. data/test/doc_props/tc_core.rb +3 -1
  116. data/test/drawing/tc_axis.rb +46 -3
  117. data/test/drawing/tc_bar_3D_chart.rb +12 -12
  118. data/test/drawing/tc_bar_series.rb +17 -13
  119. data/test/drawing/tc_cat_axis.rb +3 -3
  120. data/test/drawing/tc_cat_axis_data.rb +23 -13
  121. data/test/drawing/tc_chart.rb +29 -11
  122. data/test/drawing/tc_d_lbls.rb +47 -0
  123. data/test/drawing/tc_data_source.rb +17 -0
  124. data/test/drawing/tc_drawing.rb +11 -5
  125. data/test/drawing/tc_hyperlink.rb +4 -5
  126. data/test/drawing/tc_line_series.rb +9 -11
  127. data/test/drawing/tc_named_axis_data.rb +27 -0
  128. data/test/drawing/tc_num_data.rb +31 -0
  129. data/test/drawing/tc_num_val.rb +29 -0
  130. data/test/drawing/tc_pic.rb +22 -2
  131. data/test/drawing/tc_pie_3D_chart.rb +4 -8
  132. data/test/drawing/tc_pie_series.rb +11 -13
  133. data/test/drawing/tc_scatter_chart.rb +6 -1
  134. data/test/drawing/tc_scatter_series.rb +6 -5
  135. data/test/drawing/tc_series.rb +1 -1
  136. data/test/drawing/tc_str_data.rb +18 -0
  137. data/test/drawing/tc_str_val.rb +21 -0
  138. data/test/drawing/tc_title.rb +16 -0
  139. data/test/drawing/tc_two_cell_anchor.rb +2 -3
  140. data/test/drawing/tc_view_3D.rb +18 -18
  141. data/test/drawing/tc_vml_drawing.rb +25 -0
  142. data/test/drawing/tc_vml_shape.rb +100 -0
  143. data/test/profile.rb +2 -1
  144. data/test/rels/tc_relationship.rb +1 -0
  145. data/test/stylesheet/tc_dxf.rb +81 -0
  146. data/test/stylesheet/tc_gradient_fill.rb +8 -0
  147. data/test/stylesheet/tc_pattern_fill.rb +7 -1
  148. data/test/stylesheet/tc_styles.rb +163 -3
  149. data/test/stylesheet/tc_table_style.rb +8 -0
  150. data/test/stylesheet/tc_table_style_element.rb +10 -1
  151. data/test/tc_helper.rb +1 -0
  152. data/test/tc_package.rb +93 -17
  153. data/test/util/tc_simple_typed_list.rb +13 -0
  154. data/test/util/tc_validators.rb +95 -9
  155. data/test/workbook/tc_defined_name.rb +41 -0
  156. data/test/workbook/tc_workbook.rb +5 -3
  157. data/test/workbook/worksheet/table/tc_table.rb +3 -11
  158. data/test/workbook/worksheet/tc_cell.rb +52 -18
  159. data/test/workbook/worksheet/tc_cfvo.rb +31 -0
  160. data/test/workbook/worksheet/tc_col.rb +9 -0
  161. data/test/workbook/worksheet/tc_color_scale.rb +29 -0
  162. data/test/workbook/worksheet/tc_comment.rb +57 -0
  163. data/test/workbook/worksheet/tc_comments.rb +57 -0
  164. data/test/workbook/worksheet/tc_conditional_formatting.rb +217 -0
  165. data/test/workbook/worksheet/tc_data_bar.rb +39 -0
  166. data/test/workbook/worksheet/tc_data_validation.rb +265 -0
  167. data/test/workbook/worksheet/tc_date_time_converter.rb +11 -5
  168. data/test/workbook/worksheet/tc_icon_set.rb +45 -0
  169. data/test/workbook/worksheet/tc_page_setup.rb +138 -0
  170. data/test/workbook/worksheet/tc_pane.rb +94 -0
  171. data/test/workbook/worksheet/tc_print_options.rb +72 -0
  172. data/test/workbook/worksheet/tc_protected_range.rb +17 -0
  173. data/test/workbook/worksheet/tc_row.rb +44 -13
  174. data/test/workbook/worksheet/tc_selection.rb +94 -0
  175. data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
  176. data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
  177. data/test/workbook/worksheet/tc_worksheet.rb +147 -50
  178. metadata +216 -148
  179. data/examples/example.csv +0 -1000
  180. data/examples/example.rb~ +0 -112
  181. data/lib/axlsx/drawing/cat_axis_data.rb +0 -34
  182. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  183. data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
  184. data/lib/axlsx/drawing/named_axis_data.rb +0 -36
  185. data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
  186. data/lib/axlsx/drawing/val_axis_data.rb +0 -27
  187. data/lib/axlsx/stylesheet/#num_fmt.rb# +0 -69
  188. data/lib/axlsx/util/cbf.rb +0 -333
  189. data/lib/axlsx/util/cfb.rb~ +0 -201
  190. data/lib/axlsx/util/ms_off_crypto.rb +0 -189
  191. data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
  192. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  193. data/lib/axlsx/util/parser.rb~ +0 -6
  194. data/lib/axlsx/util/storage.rb~ +0 -0
  195. data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
  196. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  197. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  198. data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
  199. data/lib/schema/dc.xsd~ +0 -118
  200. data/lib/schema/dcterms.xsd~ +0 -331
  201. data/lib/schema/opc-coreProperties.xsd~ +0 -50
  202. data/test/#benchmark.txt# +0 -7
  203. data/test/#tc_helper.rb# +0 -3
  204. data/test/benchmark.rb~ +0 -0
  205. data/test/benchmark.txt +0 -6
  206. data/test/benchmark.txt~ +0 -6
  207. data/test/drawing/tc_val_axis_data.rb +0 -17
  208. data/test/example.csv +0 -1000
  209. data/test/example.xlsx +0 -0
  210. data/test/example_streamed.xlsx +0 -0
  211. data/test/tc_axlsx.rb~ +0 -0
  212. data/test/tc_helper.rb~ +0 -3
  213. data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
  214. data/test/workbook/worksheet/tc_col.rb~ +0 -10
@@ -0,0 +1,25 @@
1
+ require 'tc_helper.rb'
2
+
3
+ class TestVmlDrawing < Test::Unit::TestCase
4
+
5
+ def setup
6
+ p = Axlsx::Package.new
7
+ wb = p.workbook
8
+ @ws = wb.add_worksheet
9
+ @ws.add_comment :ref => 'A1', :text => 'penut machine', :author => 'crank'
10
+ @ws.add_comment :ref => 'C3', :text => 'rust bucket', :author => 'PO'
11
+ @vml_drawing = @ws.comments.vml_drawing
12
+ end
13
+
14
+ def test_initialize
15
+ assert_raise(ArgumentError) { Axlsx::VmlDrawing.new }
16
+ end
17
+
18
+ def test_to_xml_string
19
+ str = @vml_drawing.to_xml_string()
20
+ doc = Nokogiri::XML(str)
21
+ assert_equal(doc.xpath("//v:shape").size, 2)
22
+ assert(doc.xpath("//o:idmap[@o:data='#{@ws.index+1}']"))
23
+ end
24
+
25
+ end
@@ -0,0 +1,100 @@
1
+ require 'tc_helper.rb'
2
+
3
+ class TestVmlShape < Test::Unit::TestCase
4
+
5
+ def setup
6
+ p = Axlsx::Package.new
7
+ wb = p.workbook
8
+ @ws = wb.add_worksheet
9
+ @ws.add_comment :ref => 'A1', :text => 'penut machine', :author => 'crank'
10
+ @ws.add_comment :ref => 'C3', :text => 'rust bucket', :author => 'PO'
11
+ @comments = @ws.comments
12
+ end
13
+
14
+ def test_initialize
15
+ assert_raise(ArgumentError) { Axlsx::VmlDrawing.new }
16
+ end
17
+
18
+ def test_row
19
+ shape = @comments.first.vml_shape
20
+ assert_equal(shape.row, 0)
21
+ shape = @comments.last.vml_shape
22
+ assert_equal(shape.row, 2)
23
+ end
24
+
25
+ def test_column
26
+ shape = @comments.first.vml_shape
27
+ assert_equal(shape.column, 0)
28
+ shape = @comments.last.vml_shape
29
+ assert_equal(shape.column, 2)
30
+ end
31
+
32
+ def test_left_column
33
+ shape = @comments.first.vml_shape
34
+ shape.left_column = 3
35
+ assert(shape.left_column == 3)
36
+ assert_raise(ArgumentError) { shape.left_column = [] }
37
+ end
38
+
39
+ def test_left_offset
40
+ shape = @comments.first.vml_shape
41
+ shape.left_offset = 3
42
+ assert(shape.left_offset == 3)
43
+ assert_raise(ArgumentError) { shape.left_offset = [] }
44
+ end
45
+
46
+ def test_right_column
47
+ shape = @comments.first.vml_shape
48
+ shape.right_column = 3
49
+ assert(shape.right_column == 3)
50
+ assert_raise(ArgumentError) { shape.right_column = [] }
51
+ end
52
+
53
+ def test_right_offset
54
+ shape = @comments.first.vml_shape
55
+ shape.right_offset = 3
56
+ assert(shape.right_offset == 3)
57
+ assert_raise(ArgumentError) { shape.right_offset = [] }
58
+ end
59
+
60
+ def test_top_offset
61
+ shape = @comments.first.vml_shape
62
+ shape.top_offset = 3
63
+ assert(shape.top_offset == 3)
64
+ assert_raise(ArgumentError) { shape.top_offset = [] }
65
+ end
66
+
67
+ def test_bottom_offset
68
+ shape = @comments.first.vml_shape
69
+ shape.bottom_offset = 3
70
+ assert(shape.bottom_offset == 3)
71
+ assert_raise(ArgumentError) { shape.bottom_offset = [] }
72
+ end
73
+
74
+ def test_bottom_row
75
+ shape = @comments.first.vml_shape
76
+ shape.bottom_row = 3
77
+ assert(shape.bottom_row == 3)
78
+ assert_raise(ArgumentError) { shape.bottom_row = [] }
79
+ end
80
+
81
+ def test_top_row
82
+ shape = @comments.first.vml_shape
83
+ shape.top_row = 3
84
+ assert(shape.top_row == 3)
85
+ assert_raise(ArgumentError) { shape.top_row = [] }
86
+ end
87
+
88
+ def test_to_xml_string
89
+ str = @comments.vml_drawing.to_xml_string()
90
+ doc = Nokogiri::XML(str)
91
+ assert_equal(doc.xpath("//v:shape").size, 2)
92
+ @comments.each do |comment|
93
+ shape = comment.vml_shape
94
+ assert(doc.xpath("//v:shape/x:ClientData/x:Row[text()='#{shape.row}']").size == 1)
95
+ assert(doc.xpath("//v:shape/x:ClientData/x:Column[text()='#{shape.column}']").size == 1)
96
+ assert(doc.xpath("//v:shape/x:ClientData/x:Anchor[text()='#{shape.left_column}, #{shape.left_offset}, #{shape.top_row}, #{shape.top_offset}, #{shape.right_column}, #{shape.right_offset}, #{shape.bottom_row}, #{shape.bottom_offset}']").size == 1)
97
+ end
98
+ end
99
+
100
+ end
data/test/profile.rb CHANGED
@@ -15,11 +15,12 @@ require 'perftools'
15
15
  row = []
16
16
  input = (32..126).to_a.pack('U*').chars.to_a
17
17
  20.times { row << input.shuffle.join}
18
- times = 1000
18
+ times = 3000
19
19
 
20
20
  PerfTools::CpuProfiler.start("/tmp/axlsx_noautowidth") do
21
21
  p = Axlsx::Package.new
22
22
  p.use_autowidth = false
23
+ p.use_shared_strings = true
23
24
  wb = p.workbook
24
25
 
25
26
  #A Simple Workbook
@@ -10,6 +10,7 @@ class TestRelationships < Test::Unit::TestCase
10
10
  def test_type
11
11
  assert_raise(ArgumentError) { Axlsx::Relationship.new 'type', 'target' }
12
12
  assert_nothing_raised { Axlsx::Relationship.new Axlsx::WORKSHEET_R, 'target' }
13
+ assert_nothing_raised { Axlsx::Relationship.new Axlsx::COMMENT_R, 'target' }
13
14
  end
14
15
 
15
16
  def test_target_mode
@@ -0,0 +1,81 @@
1
+ require 'tc_helper.rb'
2
+
3
+ class TestDxf < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @item = Axlsx::Dxf.new
7
+ @styles = Axlsx::Styles.new
8
+ end
9
+
10
+ def teardown
11
+ end
12
+
13
+ def test_initialiation
14
+ assert_equal(@item.alignment, nil)
15
+ assert_equal(@item.protection, nil)
16
+ assert_equal(@item.numFmt, nil)
17
+ assert_equal(@item.font, nil)
18
+ assert_equal(@item.fill, nil)
19
+ assert_equal(@item.border, nil)
20
+ end
21
+
22
+ def test_alignment
23
+ assert_raise(ArgumentError) { @item.alignment = -1.1 }
24
+ assert_nothing_raised { @item.alignment = Axlsx::CellAlignment.new }
25
+ assert(@item.alignment.is_a?(Axlsx::CellAlignment))
26
+ end
27
+
28
+ def test_protection
29
+ assert_raise(ArgumentError) { @item.protection = -1.1 }
30
+ assert_nothing_raised { @item.protection = Axlsx::CellProtection.new }
31
+ assert(@item.protection.is_a?(Axlsx::CellProtection))
32
+ end
33
+
34
+ def test_numFmt
35
+ assert_raise(ArgumentError) { @item.numFmt = 1 }
36
+ assert_nothing_raised { @item.numFmt = Axlsx::NumFmt.new }
37
+ assert @item.numFmt.is_a? Axlsx::NumFmt
38
+ end
39
+
40
+ def test_fill
41
+ assert_raise(ArgumentError) { @item.fill = 1 }
42
+ assert_nothing_raised { @item.fill = Axlsx::Fill.new(Axlsx::PatternFill.new(:patternType =>:solid, :fgColor=> Axlsx::Color.new(:rgb => "FF000000"))) }
43
+ assert @item.fill.is_a? Axlsx::Fill
44
+ end
45
+
46
+ def test_font
47
+ assert_raise(ArgumentError) { @item.font = 1 }
48
+ assert_nothing_raised { @item.font = Axlsx::Font.new }
49
+ assert @item.font.is_a? Axlsx::Font
50
+ end
51
+
52
+ def test_border
53
+ assert_raise(ArgumentError) { @item.border = 1 }
54
+ assert_nothing_raised { @item.border = Axlsx::Border.new }
55
+ assert @item.border.is_a? Axlsx::Border
56
+ end
57
+
58
+ def test_to_xml
59
+ @item.border = Axlsx::Border.new
60
+ doc = Nokogiri::XML.parse(@item.to_xml_string)
61
+ assert_equal(1, doc.xpath(".//dxf//border").size)
62
+ assert_equal(0, doc.xpath(".//dxf//font").size)
63
+ end
64
+
65
+ def test_many_options_xml
66
+ @item.border = Axlsx::Border.new
67
+ @item.alignment = Axlsx::CellAlignment.new
68
+ @item.fill = Axlsx::Fill.new(Axlsx::PatternFill.new(:patternType =>:solid, :fgColor=> Axlsx::Color.new(:rgb => "FF000000")))
69
+ @item.font = Axlsx::Font.new
70
+ @item.protection = Axlsx::CellProtection.new
71
+ @item.numFmt = Axlsx::NumFmt.new
72
+
73
+ doc = Nokogiri::XML.parse(@item.to_xml_string)
74
+ assert_equal(1, doc.xpath(".//dxf//fill//patternFill[@patternType='solid']//fgColor[@rgb='FF000000']").size)
75
+ assert_equal(1, doc.xpath(".//dxf//font").size)
76
+ assert_equal(1, doc.xpath(".//dxf//protection").size)
77
+ assert_equal(1, doc.xpath(".//dxf//numFmt[@numFmtId='0'][@formatCode='']").size)
78
+ assert_equal(1, doc.xpath(".//dxf//alignment").size)
79
+ assert_equal(1, doc.xpath(".//dxf//border").size)
80
+ end
81
+ end
@@ -61,4 +61,12 @@ class TestGradientFill < Test::Unit::TestCase
61
61
  assert(@item.stop.size == 1)
62
62
  assert(@item.stop.last.is_a?(Axlsx::GradientStop))
63
63
  end
64
+
65
+ def test_to_xml_string
66
+ @item.stop << Axlsx::GradientStop.new(Axlsx::Color.new(:rgb => "000000"), 0.5)
67
+ @item.stop << Axlsx::GradientStop.new(Axlsx::Color.new(:rgb => "FFFFFF"), 0.5)
68
+ @item.type = :path
69
+ doc = Nokogiri::XML(@item.to_xml_string)
70
+ assert(doc.xpath("//color[@rgb='FF000000']"))
71
+ end
64
72
  end
@@ -33,5 +33,11 @@ class TestPatternFill < Test::Unit::TestCase
33
33
  assert_nothing_raised { @item.patternType = :lightUp }
34
34
  assert_equal(@item.patternType, :lightUp)
35
35
  end
36
-
36
+
37
+ def test_to_xml_string
38
+ @item = Axlsx::PatternFill.new :bgColor => Axlsx::Color.new(:rgb => "FF0000"), :fgColor => Axlsx::Color.new(:rgb=>"00FF00")
39
+ doc = Nokogiri::XML(@item.to_xml_string)
40
+ assert(doc.xpath('//color[@rgb="FFFF0000"]'))
41
+ assert(doc.xpath('//color[@rgb="FF00FF00"]'))
42
+ end
37
43
  end
@@ -19,11 +19,130 @@ class TestStyles < Test::Unit::TestCase
19
19
  end
20
20
  def test_add_style_border_hash
21
21
  border_count = @styles.borders.size
22
- s = @styles.add_style :border => {:style=>:thin, :color => "FFFF0000"}
22
+ @styles.add_style :border => {:style => :thin, :color => "FFFF0000"}
23
23
  assert_equal(@styles.borders.size, border_count + 1)
24
24
  assert_equal(@styles.borders.last.prs.last.color.rgb, "FFFF0000")
25
25
  assert_raise(ArgumentError) { @styles.add_style :border => {:color => "FFFF0000"} }
26
+ assert_equal @styles.borders.last.prs.size, 4
27
+ end
28
+
29
+ def test_add_style_border_edges
30
+ @styles.add_style :border => { :style => :thin, :color => "0000FFFF", :edges => [:top, :bottom] }
31
+ parts = @styles.borders.last.prs
32
+ parts.each { |pr| assert_equal(pr.color.rgb, "0000FFFF", "Style is applied to #{pr.name} properly") }
33
+ assert((parts.map { |pr| pr.name.to_s }.sort && ['bottom', 'top']).size == 2, "specify two edges, and you get two border prs")
34
+ end
35
+
36
+ def test_do_not_alter_options_in_add_style
37
+ #This should test all options, but for now - just the bits that we know caused some pain
38
+ options = { :border => { :style => :thin, :color =>"FF000000" } }
39
+ @styles.add_style options
40
+ assert_equal options[:border][:style], :thin, 'thin style is stil in option'
41
+ assert_equal options[:border][:color], "FF000000", 'color is stil in option'
42
+ end
43
+
44
+ def test_parse_num_fmt
45
+ f_code = {:format_code => "YYYY/MM"}
46
+ num_fmt = {:num_fmt => 5}
47
+ assert_equal(@styles.parse_num_fmt_options, nil, 'noop if neither :format_code or :num_fmt exist')
48
+ max = @styles.numFmts.map{ |nf| nf.numFmtId }.max
49
+ @styles.parse_num_fmt_options(f_code)
50
+ assert_equal(@styles.numFmts.last.numFmtId, max + 1, "new numfmts gets next available id")
51
+ assert(@styles.parse_num_fmt_options(num_fmt).is_a?(Integer), "Should return the provided num_fmt if not dxf")
52
+ assert(@styles.parse_num_fmt_options(num_fmt.merge({:type => :dxf})).is_a?(Axlsx::NumFmt), "Makes a new NumFmt if dxf")
53
+ end
54
+
55
+ def test_parse_border_options_hash_required_keys
56
+ assert_raise(ArgumentError, "Require color key") { @styles.parse_border_options(:border => { :style => :thin }) }
57
+ assert_raise(ArgumentError, "Require style key") { @styles.parse_border_options(:border => { :color => "FF0d0d0d" }) }
58
+ assert_nothing_raised { @styles.parse_border_options(:border => { :style => :thin, :color => "FF000000"} ) }
59
+ end
60
+
61
+ def test_parse_border_basic_options
62
+ b_opts = {:border => { :diagonalUp => 1, :edges => [:left, :right], :color => "FFDADADA", :style => :thick } }
63
+ b = @styles.parse_border_options b_opts
64
+ assert(b.is_a? Integer)
65
+ assert_equal(@styles.parse_border_options(b_opts.merge({:type => :dxf})).class,Axlsx::Border)
66
+ assert(@styles.borders.last.diagonalUp == 1, "border options are passed in to the initializer")
67
+ end
68
+
69
+ def test_parse_border_options_edges
70
+ b_opts = {:border => { :diagonalUp => 1, :edges => [:left, :right], :color => "FFDADADA", :style => :thick } }
71
+ @styles.parse_border_options b_opts
72
+ b = @styles.borders.last
73
+ left = b.prs.select { |bpr| bpr.name == :left }[0]
74
+ right = b.prs.select { |bpr| bpr.name == :right }[0]
75
+ top = b.prs.select { |bpr| bpr.name == :top }[0]
76
+ bottom = b.prs.select { |bpr| bpr.name == :bottom }[0]
77
+ assert_equal(top, nil, "unspecified top edge should not be created")
78
+ assert_equal(bottom, nil, "unspecified bottom edge should not be created")
79
+ assert(left.is_a?(Axlsx::BorderPr), "specified left edge is set")
80
+ assert(right.is_a?(Axlsx::BorderPr), "specified right edge is set")
81
+ assert_equal(left.style,right.style, "edge parts have the same style")
82
+ assert_equal(left.style, :thick, "the style is THICK")
83
+ assert_equal(right.color.rgb,left.color.rgb, "edge parts are colors are the same")
84
+ assert_equal(right.color.rgb,"FFDADADA", "edge color rgb is correct")
85
+ end
86
+
87
+ def test_parse_border_options_noop
88
+ assert_equal(@styles.parse_border_options({}), nil, "noop if the border key is not in options")
89
+ end
90
+
91
+ def test_parse_border_options_integer_xf
92
+ assert_equal(@styles.parse_border_options(:border => 1), 1)
93
+ assert_raise(ArgumentError, "unknown border index") {@styles.parse_border_options(:border => 100) }
94
+ end
95
+
96
+ def test_parse_border_options_integer_dxf
97
+ b_opts = { :border => { :edges => [:left, :right], :color => "FFFFFFFF", :style=> :thick } }
98
+ b = @styles.parse_border_options(b_opts)
99
+ b2 = @styles.parse_border_options(:border => b, :type => :dxf)
100
+ assert(b2.is_a?(Axlsx::Border), "Cloned existing border object")
101
+ end
102
+
103
+ def test_parse_alignment_options
104
+ assert_equal(@styles.parse_alignment_options {}, nil, "noop if :alignment is not set")
105
+ assert(@styles.parse_alignment_options(:alignment => {}).is_a?(Axlsx::CellAlignment))
106
+ end
107
+
108
+ def test_parse_font_options
109
+ options = {
110
+ :fg_color => "FF050505",
111
+ :sz => 20,
112
+ :b => 1,
113
+ :i => 1,
114
+ :u => 1,
115
+ :strike => 1,
116
+ :outline => 1,
117
+ :shadow => 1,
118
+ :charset => 9,
119
+ :family => 1,
120
+ :font_name => "woot font"
121
+ }
122
+ assert_equal(@styles.parse_font_options {}, nil, "noop if no font keys are set")
123
+ assert_equal(@styles.parse_font_options(:b=>1).class, Fixnum, "return index of font if not :dxf type")
124
+ assert_equal(@styles.parse_font_options(:b=>1, :type => :dxf).class, Axlsx::Font, "return font object if :dxf type")
125
+
126
+ f = @styles.parse_font_options(options.merge(:type => :dxf))
127
+ color = options.delete(:fg_color)
128
+ options[:name] = options.delete(:font_name)
129
+ options.each do |key, value|
130
+ assert_equal(f.send(key), value, "assert that #{key} was parsed")
131
+ end
132
+ assert_equal(f.color.rgb, color)
133
+ end
26
134
 
135
+ def test_parse_fill_options
136
+ assert_equal(@styles.parse_fill_options {}, nil, "noop if no fill keys are set")
137
+ assert_equal(@styles.parse_fill_options(:bg_color => "DE").class, Fixnum, "return index of fill if not :dxf type")
138
+ assert_equal(@styles.parse_fill_options(:bg_color => "DE", :type => :dxf).class, Axlsx::Fill, "return fill object if :dxf type")
139
+ f = @styles.parse_fill_options(:bg_color => "DE", :type => :dxf)
140
+ assert(f.fill_type.fgColor.rgb == "FFDEDEDE")
141
+ end
142
+
143
+ def test_parse_protection_options
144
+ assert_equal(@styles.parse_protection_options {}, nil, "noop if no protection keys are set")
145
+ assert_equal(@styles.parse_protection_options(:hidden => 1).class, Axlsx::CellProtection, "creates a new cell protection object")
27
146
  end
28
147
 
29
148
  def test_add_style
@@ -53,10 +172,51 @@ class TestStyles < Test::Unit::TestCase
53
172
  assert_raise(ArgumentError, "should reject invalid borderId") { @styles.add_style :border => 2 }
54
173
 
55
174
 
56
- assert_equal(xf.applyProtection, 1, "protection applied")
175
+ assert_equal(xf.applyProtection, true, "protection applied")
57
176
  assert_equal(xf.applyBorder, true, "border applied")
58
- assert_equal(xf.applyNumberFormat, true, "number format applied")
177
+ assert_equal(xf.applyNumberFormat,true, "number format applied")
59
178
  assert_equal(xf.applyAlignment, true, "alignment applied")
60
179
  end
61
180
 
181
+ def test_basic_add_style_dxf
182
+ border_count = @styles.borders.size
183
+ @styles.add_style :border => {:style => :thin, :color => "FFFF0000"}, :type => :dxf
184
+ assert_equal(@styles.borders.size, border_count, "styles borders not affected")
185
+ assert_equal(@styles.dxfs.last.border.prs.last.color.rgb, "FFFF0000")
186
+ assert_raise(ArgumentError) { @styles.add_style :border => {:color => "FFFF0000"}, :type => :dxf }
187
+ assert_equal @styles.borders.last.prs.size, 4
188
+ end
189
+
190
+ def test_add_style_dxf
191
+ fill_count = @styles.fills.size
192
+ font_count = @styles.fonts.size
193
+ dxf_count = @styles.dxfs.size
194
+
195
+ style = @styles.add_style :bg_color=>"FF000000", :fg_color=>"FFFFFFFF", :sz=>13, :alignment=>{:horizontal=>:left}, :border=>{:style => :thin, :color => "FFFF0000"}, :hidden=>true, :locked=>true, :type => :dxf
196
+ assert_equal(@styles.dxfs.size, dxf_count+1)
197
+ assert_equal(0, style, "returns the zero-based dxfId")
198
+
199
+ dxf = @styles.dxfs.last
200
+ assert_equal(@styles.dxfs.last.fill.fill_type.fgColor.rgb, "FF000000", "fill created with color")
201
+
202
+ assert_equal(font_count, (@styles.fonts.size), "font not created under styles")
203
+ assert_equal(fill_count, (@styles.fills.size), "fill not created under styles")
204
+
205
+ assert(dxf.border.is_a?(Axlsx::Border), "border is set")
206
+ assert_equal(nil, dxf.numFmt, "number format is not set")
207
+
208
+ assert(dxf.alignment.is_a?(Axlsx::CellAlignment), "alignment was created")
209
+ assert_equal(dxf.alignment.horizontal, :left, "horizontal alignment applied")
210
+ assert_equal(dxf.protection.hidden, true, "hidden protection set")
211
+ assert_equal(dxf.protection.locked, true, "cell locking set")
212
+ assert_raise(ArgumentError, "should reject invalid borderId") { @styles.add_style :border => 3 }
213
+ end
214
+
215
+ def test_multiple_dxf
216
+ # add a second style
217
+ style = @styles.add_style :bg_color=>"00000000", :fg_color=>"FFFFFFFF", :sz=>13, :alignment=>{:horizontal=>:left}, :border=>{:style => :thin, :color => "FFFF0000"}, :hidden=>true, :locked=>true, :type => :dxf
218
+ assert_equal(0, style, "returns the first dxfId")
219
+ style = @styles.add_style :bg_color=>"FF000000", :fg_color=>"FFFFFFFF", :sz=>13, :alignment=>{:horizontal=>:left}, :border=>{:style => :thin, :color => "FFFF0000"}, :hidden=>true, :locked=>true, :type => :dxf
220
+ assert_equal(1, style, "returns the second dxfId")
221
+ end
62
222
  end
@@ -13,6 +13,10 @@ class TestTableStyle < Test::Unit::TestCase
13
13
  assert_equal(@item.name, "fisher")
14
14
  assert_equal(@item.pivot, nil)
15
15
  assert_equal(@item.table, nil)
16
+ ts = Axlsx::TableStyle.new 'price', :pivot => true, :table => true
17
+ assert_equal(ts.name, 'price')
18
+ assert_equal(ts.pivot, true)
19
+ assert_equal(ts.table, true)
16
20
  end
17
21
 
18
22
  def test_name
@@ -33,4 +37,8 @@ class TestTableStyle < Test::Unit::TestCase
33
37
  assert_equal(@item.table, true)
34
38
  end
35
39
 
40
+ def test_to_xml_string
41
+ doc = Nokogiri::XML(@item.to_xml_string)
42
+ assert(doc.xpath("//tableStyle[@name='#{@item.name}']"))
43
+ end
36
44
  end
@@ -13,6 +13,10 @@ class TestTableStyleElement < Test::Unit::TestCase
13
13
  assert_equal(@item.type, nil)
14
14
  assert_equal(@item.size, nil)
15
15
  assert_equal(@item.dxfId, nil)
16
+ options = { :type => :headerRow, :size => 10, :dxfId => 1 }
17
+
18
+ tse = Axlsx::TableStyleElement.new options
19
+ options.each { |key, value| assert_equal(tse.send(key.to_sym), value) }
16
20
  end
17
21
 
18
22
  def test_type
@@ -32,5 +36,10 @@ class TestTableStyleElement < Test::Unit::TestCase
32
36
  assert_nothing_raised { @item.dxfId = 7 }
33
37
  assert_equal(@item.dxfId, 7)
34
38
  end
35
-
39
+
40
+ def test_to_xml_string
41
+ doc = Nokogiri::XML(@item.to_xml_string)
42
+ @item.type = :headerRow
43
+ assert(doc.xpath("//tableStyleElement[@type='#{@item.type.to_s}']"))
44
+ end
36
45
  end
data/test/tc_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
2
+ require 'cover_me' unless RUBY_VERSION == '1.8.7'
2
3
  require 'test/unit'
3
4
  require "axlsx.rb"
data/test/tc_package.rb CHANGED
@@ -1,13 +1,78 @@
1
+ # encoding: UTF-8
1
2
  require 'tc_helper.rb'
2
3
 
3
4
  class TestPackage < Test::Unit::TestCase
4
5
  def setup
5
6
  @package = Axlsx::Package.new
6
7
  ws = @package.workbook.add_worksheet
7
- chart = ws.add_chart Axlsx::Pie3DChart
8
- chart.add_series :data=>[1,2,3], :labels=>["a", "b", "c"]
8
+ ws.add_row ['Can', 'we', 'build it?']
9
+ ws.add_row ['Yes!', 'We', 'can!']
10
+ ws.workbook.add_defined_name("#{ws.name}!A1:C2", :name => '_xlnm.Print_Titles', :hidden => true)
11
+ ws.protect_range('A1:C1')
12
+ ws.protect_range(ws.rows.last.cells)
13
+ ws.add_comment :author => 'alice', :text => 'Hi Bob', :ref => 'A12'
14
+ ws.add_comment :author => 'bob', :text => 'Hi Alice', :ref => 'F19'
15
+ ws.sheet_view do |vs|
16
+ vs.pane do |p|
17
+ p.active_pane = :top_right
18
+ p.state = :split
19
+ p.x_split = 11080
20
+ p.y_split = 5000
21
+ p.top_left_cell = 'C44'
22
+ end
23
+
24
+ vs.add_selection(:top_left, { :active_cell => 'A2', :sqref => 'A2' })
25
+ vs.add_selection(:top_right, { :active_cell => 'I10', :sqref => 'I10' })
26
+ vs.add_selection(:bottom_left, { :active_cell => 'E55', :sqref => 'E55' })
27
+ vs.add_selection(:bottom_right, { :active_cell => 'I57', :sqref => 'I57' })
28
+ end
29
+
30
+ ws.add_chart(Axlsx::Pie3DChart, :title => "これは?", :start_at => [0,3]) do |chart|
31
+ chart.add_series :data=>[1,2,3], :labels=>["a", "b", "c"]
32
+ chart.d_lbls.show_val = true
33
+ chart.d_lbls.d_lbl_pos = :outEnd
34
+ chart.d_lbls.show_percent = true
35
+ end
36
+
37
+ ws.add_chart(Axlsx::Line3DChart, :title => "axis labels") do |chart|
38
+ chart.valAxis.title = 'bob'
39
+ chart.d_lbls.show_val = true
40
+ end
41
+
42
+ ws.add_chart(Axlsx::Bar3DChart, :title => 'bar chart') do |chart|
43
+ chart.add_series :data => [1,4,5], :labels => %w(A B C)
44
+ chart.d_lbls.show_percent = true
45
+ end
46
+
47
+ ws.add_chart(Axlsx::ScatterChart, :title => 'scat man') do |chart|
48
+ chart.add_series :xData => [1,2,3,4], :yData => [4,3,2,1]
49
+ chart.d_lbls.show_val = true
50
+ end
51
+
9
52
  @fname = 'axlsx_test_serialization.xlsx'
53
+ img = File.expand_path('../../examples/image1.jpeg', __FILE__)
54
+ ws.add_image(:image_src => img, :noSelect => true, :noMove => true, :hyperlink=>"http://axlsx.blogspot.com") do |image|
55
+ image.width=720
56
+ image.height=666
57
+ image.hyperlink.tooltip = "Labeled Link"
58
+ image.start_at 5, 5
59
+ end
60
+ ws.add_image :image_src => File.expand_path('../../examples/image1.gif', __FILE__) do |image|
61
+ image.start_at 0, 20
62
+ image.width=360
63
+ image.height=333
64
+ end
65
+ ws.add_image :image_src => File.expand_path('../../examples/image1.png', __FILE__) do |image|
66
+ image.start_at 9, 20
67
+ image.width = 180
68
+ image.height = 167
69
+ end
70
+ ws.add_table 'A1:C1'
71
+ end
10
72
 
73
+ def test_use_autowidth
74
+ @package.use_autowidth = false
75
+ assert(@package.workbook.use_autowidth == false)
11
76
  end
12
77
 
13
78
  def test_core_accessor
@@ -35,30 +100,26 @@ class TestPackage < Test::Unit::TestCase
35
100
  end
36
101
 
37
102
  def test_serialization
38
- fname = 'axlsx_test_serialization.xlsx'
39
103
  assert_nothing_raised do
40
104
  begin
41
- z= @package.serialize(@fname)
42
- zf = Zip::ZipFile.open(@fname)
43
- @package.send(:parts).each{ |part| zf.get_entry(part[:entry]) }
44
- File.delete(@fname)
105
+ @package.serialize(@fname)
106
+ zf = Zip::ZipFile.open(@fname)
107
+ @package.send(:parts).each{ |part| zf.get_entry(part[:entry]) }
108
+ File.delete(@fname)
45
109
  rescue Errno::EACCES
46
- puts "WARNING:: test_serialization requires write access."
110
+ puts "WARNING:: test_serialization requires write access."
47
111
  end
48
- end
49
- end
112
+ end
113
+ end
50
114
 
51
115
  def test_validation
52
116
  assert_equal(@package.validate.size, 0, @package.validate)
53
- #how to test for failure? the internal validations on the models are so strict I cant break anthing.....
117
+ Axlsx::Workbook.send(:class_variable_set, :@@date1904, 9900)
118
+ assert(@package.validate.size > 0)
54
119
  end
55
120
 
56
121
  def test_parts
57
122
  p = @package.send(:parts)
58
- p.each do |part|
59
- #all parts must have :doc, :entry, :schema
60
- assert(part.keys.size == 3 && part.keys.reject{ |k| [:doc, :entry, :schema].include? k}.empty?)
61
- end
62
123
  #all parts have an entry
63
124
  assert_equal(p.select{ |part| part[:entry] =~ /_rels\/\.rels/ }.size, 1, "rels missing")
64
125
  assert_equal(p.select{ |part| part[:entry] =~ /docProps\/core\.xml/ }.size, 1, "core missing")
@@ -72,9 +133,11 @@ class TestPackage < Test::Unit::TestCase
72
133
  assert_equal(p.select{ |part| part[:entry] =~ /xl\/charts\/chart\d\.xml/ }.size, @package.workbook.charts.size, "one or more charts missing")
73
134
  assert_equal(p.select{ |part| part[:entry] =~ /xl\/worksheets\/sheet\d\.xml/ }.size, @package.workbook.worksheets.size, "one or more sheet missing")
74
135
  assert_equal(p.select{ |part| part[:entry] =~ /xl\/worksheets\/_rels\/sheet\d\.xml\.rels/ }.size, @package.workbook.worksheets.size, "one or more sheet rels missing")
136
+ assert_equal(p.select{ |part| part[:entry] =~ /xl\/comments\d\.xml/ }.size, @package.workbook.worksheets.size, "one or more sheet rels missing")
137
+
75
138
 
76
139
  #no mystery parts
77
- assert_equal(p.size, 12)
140
+ assert_equal(p.size, 21)
78
141
 
79
142
  end
80
143
 
@@ -102,11 +165,24 @@ class TestPackage < Test::Unit::TestCase
102
165
  def test_content_type_added_with_shared_strings
103
166
  @package.use_shared_strings = true
104
167
  ct = @package.send(:content_types)
105
- assert(ct.select { |ct| ct.ContentType == Axlsx::SHARED_STRINGS_CT }.size == 1)
168
+ assert(ct.select { |type| type.ContentType == Axlsx::SHARED_STRINGS_CT }.size == 1)
106
169
  end
107
170
 
108
171
  def test_name_to_indices
109
172
  assert(Axlsx::name_to_indices('A1') == [0,0])
110
173
  assert(Axlsx::name_to_indices('A100') == [0,99], 'needs to axcept rows that contain 0')
111
174
  end
175
+
176
+ def test_to_stream
177
+ stream = @package.to_stream
178
+ assert(stream.is_a?(StringIO))
179
+ # this is just a roundabout guess for a package as it is build now
180
+ # in testing.
181
+ assert(stream.size > 80000)
182
+ end
183
+
184
+ def test_encrypt
185
+ # this is no where near close to ready yet
186
+ assert(@package.encrypt('your_mom.xlsxl', 'has a password') == false)
187
+ end
112
188
  end
@@ -61,5 +61,18 @@ class TestSimpleTypedList < Test::Unit::TestCase
61
61
  assert_nothing_raised { @list.delete 0 }
62
62
  assert_nothing_raised { @list.delete 9 }
63
63
  end
64
+
65
+ def test_delete
66
+ @list.push 1
67
+ assert(@list.size == 1)
68
+ @list.delete 1
69
+ assert(@list.empty?)
70
+ end
64
71
 
72
+ def test_equality
73
+ @list.push 1
74
+ @list.push 2
75
+ assert_equal(@list, [1,2])
76
+
77
+ end
65
78
  end