xlsxrb 0.1.11 → 0.1.13

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 (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -34
  3. data/README.md +26 -21
  4. data/lib/xlsxrb/chart_builder.rb +18 -18
  5. data/lib/xlsxrb/dsl_helpers.rb +175 -0
  6. data/lib/xlsxrb/elements/cell.rb +56 -22
  7. data/lib/xlsxrb/elements/column.rb +27 -3
  8. data/lib/xlsxrb/elements/row.rb +27 -8
  9. data/lib/xlsxrb/elements/workbook.rb +27 -14
  10. data/lib/xlsxrb/elements/worksheet.rb +17 -1
  11. data/lib/xlsxrb/ooxml/cfb.rb +9 -6
  12. data/lib/xlsxrb/ooxml/crypto/agile.rb +5 -5
  13. data/lib/xlsxrb/ooxml/reader/listeners/core_listeners.rb +784 -0
  14. data/lib/xlsxrb/ooxml/reader/listeners/drawing_listeners.rb +3478 -0
  15. data/lib/xlsxrb/ooxml/reader/listeners/feature_listeners.rb +1796 -0
  16. data/lib/xlsxrb/ooxml/reader/listeners/style_listeners.rb +428 -0
  17. data/lib/xlsxrb/ooxml/reader/listeners.rb +4 -6446
  18. data/lib/xlsxrb/ooxml/shared_strings_parser.rb +3 -5
  19. data/lib/xlsxrb/ooxml/utils.rb +5 -6
  20. data/lib/xlsxrb/ooxml/workbook_writer.rb +5 -7
  21. data/lib/xlsxrb/ooxml/worksheet_parser.rb +172 -9
  22. data/lib/xlsxrb/ooxml/writer/drawing_xml.rb +1602 -0
  23. data/lib/xlsxrb/ooxml/writer/features_xml.rb +731 -0
  24. data/lib/xlsxrb/ooxml/writer/styles_xml.rb +348 -0
  25. data/lib/xlsxrb/ooxml/writer.rb +9 -2646
  26. data/lib/xlsxrb/ooxml/xml_builder.rb +31 -2
  27. data/lib/xlsxrb/ooxml/zip_generator.rb +26 -5
  28. data/lib/xlsxrb/ooxml/zip_reader.rb +364 -78
  29. data/lib/xlsxrb/ooxml/zip_writer.rb +32 -5
  30. data/lib/xlsxrb/stream_sheet.rb +94 -6
  31. data/lib/xlsxrb/stream_writer.rb +48 -115
  32. data/lib/xlsxrb/style_builder.rb +10 -1
  33. data/lib/xlsxrb/version.rb +1 -1
  34. data/lib/xlsxrb/workbook_builder.rb +1 -1
  35. data/lib/xlsxrb/worksheet_builder.rb +19 -81
  36. data/lib/xlsxrb.rb +449 -171
  37. data/sig/generated/xlsxrb/chart_builder.rbs +36 -36
  38. data/sig/generated/xlsxrb/dsl_helpers.rbs +92 -0
  39. data/sig/generated/xlsxrb/elements/cell.rbs +29 -0
  40. data/sig/generated/xlsxrb/elements/column.rbs +32 -21
  41. data/sig/generated/xlsxrb/elements/row.rbs +94 -14
  42. data/sig/generated/xlsxrb/elements/workbook.rbs +102 -10
  43. data/sig/generated/xlsxrb/elements/worksheet.rbs +9 -0
  44. data/sig/generated/xlsxrb/ooxml/reader/listeners/core_listeners.rbs +173 -0
  45. data/sig/generated/xlsxrb/ooxml/reader/listeners/drawing_listeners.rbs +400 -0
  46. data/sig/generated/xlsxrb/ooxml/reader/listeners/feature_listeners.rbs +442 -0
  47. data/sig/generated/xlsxrb/ooxml/reader/listeners/style_listeners.rbs +80 -0
  48. data/sig/generated/xlsxrb/ooxml/reader/listeners.rbs +0 -1072
  49. data/sig/generated/xlsxrb/ooxml/shared_strings_parser.rbs +0 -2
  50. data/sig/generated/xlsxrb/ooxml/utils.rbs +2 -0
  51. data/sig/generated/xlsxrb/ooxml/worksheet_parser.rbs +5 -4
  52. data/sig/generated/xlsxrb/ooxml/writer/drawing_xml.rbs +79 -0
  53. data/sig/generated/xlsxrb/ooxml/writer/features_xml.rbs +83 -0
  54. data/sig/generated/xlsxrb/ooxml/writer/styles_xml.rbs +53 -0
  55. data/sig/generated/xlsxrb/ooxml/writer.rbs +6 -185
  56. data/sig/generated/xlsxrb/ooxml/xml_builder.rbs +18 -0
  57. data/sig/generated/xlsxrb/ooxml/zip_generator.rbs +15 -0
  58. data/sig/generated/xlsxrb/ooxml/zip_reader.rbs +96 -8
  59. data/sig/generated/xlsxrb/ooxml/zip_writer.rbs +5 -1
  60. data/sig/generated/xlsxrb/stream_sheet.rbs +43 -3
  61. data/sig/generated/xlsxrb/style_builder.rbs +7 -0
  62. data/sig/generated/xlsxrb.rbs +18 -11
  63. metadata +22 -144
  64. data/.devcontainer/Dockerfile +0 -65
  65. data/.devcontainer/devcontainer.json +0 -17
  66. data/.gem_rbs_collection/ast/2.4/.rbs_meta.yaml +0 -9
  67. data/.gem_rbs_collection/ast/2.4/ast.rbs +0 -73
  68. data/.gem_rbs_collection/concurrent-ruby/1.1/.rbs_meta.yaml +0 -9
  69. data/.gem_rbs_collection/concurrent-ruby/1.1/array.rbs +0 -4
  70. data/.gem_rbs_collection/concurrent-ruby/1.1/atomic_reference.rbs +0 -16
  71. data/.gem_rbs_collection/concurrent-ruby/1.1/executor.rbs +0 -96
  72. data/.gem_rbs_collection/concurrent-ruby/1.1/hash.rbs +0 -4
  73. data/.gem_rbs_collection/concurrent-ruby/1.1/map.rbs +0 -68
  74. data/.gem_rbs_collection/concurrent-ruby/1.1/promises.rbs +0 -249
  75. data/.gem_rbs_collection/concurrent-ruby/1.1/set.rbs +0 -4
  76. data/.gem_rbs_collection/concurrent-ruby/1.1/timer_task.rbs +0 -47
  77. data/.gem_rbs_collection/concurrent-ruby/1.1/utility/processor_counter.rbs +0 -5
  78. data/.gem_rbs_collection/csv/3.3/.rbs_meta.yaml +0 -9
  79. data/.gem_rbs_collection/csv/3.3/csv.rbs +0 -3871
  80. data/.gem_rbs_collection/csv/3.3/manifest.yaml +0 -3
  81. data/.gem_rbs_collection/lint_roller/1.1/.rbs_meta.yaml +0 -9
  82. data/.gem_rbs_collection/lint_roller/1.1/lint_roller.rbs +0 -48
  83. data/.gem_rbs_collection/listen/3.9/.rbs_meta.yaml +0 -9
  84. data/.gem_rbs_collection/listen/3.9/listen.rbs +0 -25
  85. data/.gem_rbs_collection/listen/3.9/listener.rbs +0 -24
  86. data/.gem_rbs_collection/logger/1.7/.rbs_meta.yaml +0 -9
  87. data/.gem_rbs_collection/logger/1.7/formatter.rbs +0 -45
  88. data/.gem_rbs_collection/logger/1.7/log_device.rbs +0 -100
  89. data/.gem_rbs_collection/logger/1.7/logger.rbs +0 -796
  90. data/.gem_rbs_collection/logger/1.7/manifest.yaml +0 -2
  91. data/.gem_rbs_collection/logger/1.7/period.rbs +0 -17
  92. data/.gem_rbs_collection/logger/1.7/severity.rbs +0 -34
  93. data/.gem_rbs_collection/nokogiri/1.11/.rbs_meta.yaml +0 -9
  94. data/.gem_rbs_collection/nokogiri/1.11/nokogiri.rbs +0 -2332
  95. data/.gem_rbs_collection/nokogiri/1.11/patch.rbs +0 -4
  96. data/.gem_rbs_collection/parallel/1.20/.rbs_meta.yaml +0 -9
  97. data/.gem_rbs_collection/parallel/1.20/parallel.rbs +0 -86
  98. data/.gem_rbs_collection/parser/3.2/.rbs_meta.yaml +0 -9
  99. data/.gem_rbs_collection/parser/3.2/manifest.yaml +0 -7
  100. data/.gem_rbs_collection/parser/3.2/parser.rbs +0 -194
  101. data/.gem_rbs_collection/parser/3.2/polyfill.rbs +0 -4
  102. data/.gem_rbs_collection/rainbow/3.0/.rbs_meta.yaml +0 -9
  103. data/.gem_rbs_collection/rainbow/3.0/global.rbs +0 -7
  104. data/.gem_rbs_collection/rainbow/3.0/presenter.rbs +0 -209
  105. data/.gem_rbs_collection/rainbow/3.0/rainbow.rbs +0 -5
  106. data/.gem_rbs_collection/rake/13.0/.rbs_meta.yaml +0 -9
  107. data/.gem_rbs_collection/rake/13.0/manifest.yaml +0 -2
  108. data/.gem_rbs_collection/rake/13.0/rake.rbs +0 -39
  109. data/.gem_rbs_collection/regexp_parser/2.8/.rbs_meta.yaml +0 -9
  110. data/.gem_rbs_collection/regexp_parser/2.8/regexp_parser.rbs +0 -17
  111. data/.gem_rbs_collection/rubocop/1.57/.rbs_meta.yaml +0 -9
  112. data/.gem_rbs_collection/rubocop/1.57/rubocop.rbs +0 -208
  113. data/.gem_rbs_collection/rubocop-ast/1.46/.rbs_meta.yaml +0 -9
  114. data/.gem_rbs_collection/rubocop-ast/1.46/rubocop-ast.rbs +0 -903
  115. data/.gem_rbs_collection/rubyzip/3.2/.rbs_meta.yaml +0 -9
  116. data/.gem_rbs_collection/rubyzip/3.2/manifest.yaml +0 -8
  117. data/.gem_rbs_collection/rubyzip/3.2/zip/central_directory.rbs +0 -42
  118. data/.gem_rbs_collection/rubyzip/3.2/zip/compressor.rbs +0 -5
  119. data/.gem_rbs_collection/rubyzip/3.2/zip/constants.rbs +0 -47
  120. data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/aes_encryption.rbs +0 -30
  121. data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/decrypted_io.rbs +0 -9
  122. data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/encryption.rbs +0 -7
  123. data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/null_encryption.rbs +0 -19
  124. data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/traditional_encryption.rbs +0 -31
  125. data/.gem_rbs_collection/rubyzip/3.2/zip/decompressor.rbs +0 -18
  126. data/.gem_rbs_collection/rubyzip/3.2/zip/deflater.rbs +0 -12
  127. data/.gem_rbs_collection/rubyzip/3.2/zip/dirtyable.rbs +0 -11
  128. data/.gem_rbs_collection/rubyzip/3.2/zip/dos_time.rbs +0 -13
  129. data/.gem_rbs_collection/rubyzip/3.2/zip/entry.rbs +0 -95
  130. data/.gem_rbs_collection/rubyzip/3.2/zip/entry_set.rbs +0 -31
  131. data/.gem_rbs_collection/rubyzip/3.2/zip/errors.rbs +0 -58
  132. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/aes.rbs +0 -24
  133. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/generic.rbs +0 -17
  134. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/ntfs.rbs +0 -23
  135. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/old_unix.rbs +0 -22
  136. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/universal_time.rbs +0 -30
  137. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/unix.rbs +0 -20
  138. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/unknown.rbs +0 -15
  139. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/zip64.rbs +0 -26
  140. data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field.rbs +0 -21
  141. data/.gem_rbs_collection/rubyzip/3.2/zip/file.rbs +0 -131
  142. data/.gem_rbs_collection/rubyzip/3.2/zip/file_split.rbs +0 -14
  143. data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/dir.rbs +0 -33
  144. data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/directory_iterator.rbs +0 -21
  145. data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/file.rbs +0 -63
  146. data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/file_stat.rbs +0 -55
  147. data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/zip_file_name_mapper.rbs +0 -35
  148. data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem.rbs +0 -7
  149. data/.gem_rbs_collection/rubyzip/3.2/zip/inflater.rbs +0 -10
  150. data/.gem_rbs_collection/rubyzip/3.2/zip/input_stream.rbs +0 -22
  151. data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras/abstract_input_stream.rbs +0 -29
  152. data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras/abstract_output_stream.rbs +0 -17
  153. data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras.rbs +0 -13
  154. data/.gem_rbs_collection/rubyzip/3.2/zip/null_compressor.rbs +0 -10
  155. data/.gem_rbs_collection/rubyzip/3.2/zip/null_decompressor.rbs +0 -8
  156. data/.gem_rbs_collection/rubyzip/3.2/zip/null_input_stream.rbs +0 -6
  157. data/.gem_rbs_collection/rubyzip/3.2/zip/output_stream.rbs +0 -30
  158. data/.gem_rbs_collection/rubyzip/3.2/zip/pass_thru_compressor.rbs +0 -10
  159. data/.gem_rbs_collection/rubyzip/3.2/zip/pass_thru_decompressor.rbs +0 -10
  160. data/.gem_rbs_collection/rubyzip/3.2/zip/streamable_directory.rbs +0 -5
  161. data/.gem_rbs_collection/rubyzip/3.2/zip/streamable_stream.rbs +0 -15
  162. data/.gem_rbs_collection/rubyzip/3.2/zip/version.rbs +0 -3
  163. data/.gem_rbs_collection/rubyzip/3.2/zip.rbs +0 -40
  164. data/Rakefile +0 -567
  165. data/Steepfile +0 -18
  166. data/benchmark.rb +0 -406
  167. data/docs/ARCHITECTURE.md +0 -514
  168. data/docs/DEVELOPMENT.md +0 -133
  169. data/docs/PEER_LIBRARIES.md +0 -121
  170. data/docs/QUALITY_ASSURANCE.md +0 -25
  171. data/docs/SPEC_SOURCES.md +0 -48
  172. data/docs/assets/benchmark_results.svg +0 -144
  173. data/docs/assets/lsp_autocompletion.png +0 -0
  174. data/docs/assets/playground_preview.png +0 -0
  175. data/docs/coi-serviceworker.js +0 -82
  176. data/docs/office_thread.js +0 -77
  177. data/docs/preview.html +0 -719
  178. data/docs/visual/VisualGallery.md +0 -4672
  179. data/docs/wasm/ruby.wasm +0 -0
  180. data/docs/wasm/wasm_doc_helper.css +0 -351
  181. data/docs/wasm/wasm_doc_helper.js +0 -439
  182. data/docs/zeta.js +0 -1107
  183. data/rbs_collection.lock.yaml +0 -252
  184. data/rbs_collection.yaml +0 -19
  185. data/vendor/sdk_runner/Program.cs +0 -93
  186. data/vendor/sdk_runner/sdk_runner.csproj +0 -13
@@ -1,4672 +0,0 @@
1
- # Visual Examples Gallery
2
-
3
- This gallery showcases `xlsxrb` DSL usage side-by-side with the visual rendering in LibreOffice Calc.
4
-
5
- [◄ Back to README](../../README.md)
6
-
7
- ## Capability Overview
8
-
9
- <table>
10
- <thead>
11
- <tr>
12
- <th align="left">Feature</th>
13
- <th align="center">Visual Preview</th>
14
- <th align="center">Link to Detail</th>
15
- </tr>
16
- </thead>
17
- <tbody>
18
- <tr>
19
- <td><strong>Align Horizontal</strong></td>
20
- <td align="center"><img src="../../test/visual/baselines/align_horizontal/page-1.png" width="160" alt="Align Horizontal"/></td>
21
- <td align="center"><a href="#align-horizontal">View Code &amp; Detail</a></td>
22
- </tr>
23
- <tr>
24
- <td><strong>Align Horizontal Fill</strong></td>
25
- <td align="center"><img src="../../test/visual/baselines/align_horizontal_fill/page-1.png" width="160" alt="Align Horizontal Fill"/></td>
26
- <td align="center"><a href="#align-horizontal-fill">View Code &amp; Detail</a></td>
27
- </tr>
28
- <tr>
29
- <td><strong>Align Horizontal Justify</strong></td>
30
- <td align="center"><img src="../../test/visual/baselines/align_horizontal_justify/page-1.png" width="160" alt="Align Horizontal Justify"/></td>
31
- <td align="center"><a href="#align-horizontal-justify">View Code &amp; Detail</a></td>
32
- </tr>
33
- <tr>
34
- <td><strong>Align Indent</strong></td>
35
- <td align="center"><img src="../../test/visual/baselines/align_indent/page-1.png" width="160" alt="Align Indent"/></td>
36
- <td align="center"><a href="#align-indent">View Code &amp; Detail</a></td>
37
- </tr>
38
- <tr>
39
- <td><strong>Align Text Rotation</strong></td>
40
- <td align="center"><img src="../../test/visual/baselines/align_text_rotation/page-1.png" width="160" alt="Align Text Rotation"/></td>
41
- <td align="center"><a href="#align-text-rotation">View Code &amp; Detail</a></td>
42
- </tr>
43
- <tr>
44
- <td><strong>Align Text Wrap</strong></td>
45
- <td align="center"><img src="../../test/visual/baselines/align_text_wrap/page-1.png" width="160" alt="Align Text Wrap"/></td>
46
- <td align="center"><a href="#align-text-wrap">View Code &amp; Detail</a></td>
47
- </tr>
48
- <tr>
49
- <td><strong>Align Vertical</strong></td>
50
- <td align="center"><img src="../../test/visual/baselines/align_vertical/page-1.png" width="160" alt="Align Vertical"/></td>
51
- <td align="center"><a href="#align-vertical">View Code &amp; Detail</a></td>
52
- </tr>
53
- <tr>
54
- <td><strong>Basic Data</strong></td>
55
- <td align="center"><img src="../../test/visual/baselines/basic_data/page-1.png" width="160" alt="Basic Data"/></td>
56
- <td align="center"><a href="#basic-data">View Code &amp; Detail</a></td>
57
- </tr>
58
- <tr>
59
- <td><strong>Borders</strong></td>
60
- <td align="center"><img src="../../test/visual/baselines/borders/page-1.png" width="160" alt="Borders"/></td>
61
- <td align="center"><a href="#borders">View Code &amp; Detail</a></td>
62
- </tr>
63
- <tr>
64
- <td><strong>Cell Booleans</strong></td>
65
- <td align="center"><img src="../../test/visual/baselines/cell_booleans/page-1.png" width="160" alt="Cell Booleans"/></td>
66
- <td align="center"><a href="#cell-booleans">View Code &amp; Detail</a></td>
67
- </tr>
68
- <tr>
69
- <td><strong>Cell Dates</strong></td>
70
- <td align="center"><img src="../../test/visual/baselines/cell_dates/page-1.png" width="160" alt="Cell Dates"/></td>
71
- <td align="center"><a href="#cell-dates">View Code &amp; Detail</a></td>
72
- </tr>
73
- <tr>
74
- <td><strong>Cell Formulas</strong></td>
75
- <td align="center"><img src="../../test/visual/baselines/cell_formulas/page-1.png" width="160" alt="Cell Formulas"/></td>
76
- <td align="center"><a href="#cell-formulas">View Code &amp; Detail</a></td>
77
- </tr>
78
- <tr>
79
- <td><strong>Cell Num Currency Jpy</strong></td>
80
- <td align="center"><img src="../../test/visual/baselines/cell_num_currency_jpy/page-1.png" width="160" alt="Cell Num Currency Jpy"/></td>
81
- <td align="center"><a href="#cell-num-currency-jpy">View Code &amp; Detail</a></td>
82
- </tr>
83
- <tr>
84
- <td><strong>Cell Num Custom Colors</strong></td>
85
- <td align="center"><img src="../../test/visual/baselines/cell_num_custom_colors/page-1.png" width="160" alt="Cell Num Custom Colors"/></td>
86
- <td align="center"><a href="#cell-num-custom-colors">View Code &amp; Detail</a></td>
87
- </tr>
88
- <tr>
89
- <td><strong>Cell Num Fractions</strong></td>
90
- <td align="center"><img src="../../test/visual/baselines/cell_num_fractions/page-1.png" width="160" alt="Cell Num Fractions"/></td>
91
- <td align="center"><a href="#cell-num-fractions">View Code &amp; Detail</a></td>
92
- </tr>
93
- <tr>
94
- <td><strong>Cell Num Percent Decimals</strong></td>
95
- <td align="center"><img src="../../test/visual/baselines/cell_num_percent_decimals/page-1.png" width="160" alt="Cell Num Percent Decimals"/></td>
96
- <td align="center"><a href="#cell-num-percent-decimals">View Code &amp; Detail</a></td>
97
- </tr>
98
- <tr>
99
- <td><strong>Cell Num Scientific</strong></td>
100
- <td align="center"><img src="../../test/visual/baselines/cell_num_scientific/page-1.png" width="160" alt="Cell Num Scientific"/></td>
101
- <td align="center"><a href="#cell-num-scientific">View Code &amp; Detail</a></td>
102
- </tr>
103
- <tr>
104
- <td><strong>Cell Numbers</strong></td>
105
- <td align="center"><img src="../../test/visual/baselines/cell_numbers/page-1.png" width="160" alt="Cell Numbers"/></td>
106
- <td align="center"><a href="#cell-numbers">View Code &amp; Detail</a></td>
107
- </tr>
108
- <tr>
109
- <td><strong>Cell Rich Text</strong></td>
110
- <td align="center"><img src="../../test/visual/baselines/cell_rich_text/page-1.png" width="160" alt="Cell Rich Text"/></td>
111
- <td align="center"><a href="#cell-rich-text">View Code &amp; Detail</a></td>
112
- </tr>
113
- <tr>
114
- <td><strong>Cell Times</strong></td>
115
- <td align="center"><img src="../../test/visual/baselines/cell_times/page-1.png" width="160" alt="Cell Times"/></td>
116
- <td align="center"><a href="#cell-times">View Code &amp; Detail</a></td>
117
- </tr>
118
- <tr>
119
- <td><strong>Cf Begins With</strong></td>
120
- <td align="center"><img src="../../test/visual/baselines/cf_begins_with/page-1.png" width="160" alt="Cf Begins With"/></td>
121
- <td align="center"><a href="#cf-begins-with">View Code &amp; Detail</a></td>
122
- </tr>
123
- <tr>
124
- <td><strong>Cf Cell Between</strong></td>
125
- <td align="center"><img src="../../test/visual/baselines/cf_cell_between/page-1.png" width="160" alt="Cf Cell Between"/></td>
126
- <td align="center"><a href="#cf-cell-between">View Code &amp; Detail</a></td>
127
- </tr>
128
- <tr>
129
- <td><strong>Cf Cell Equal To</strong></td>
130
- <td align="center"><img src="../../test/visual/baselines/cf_cell_equal_to/page-1.png" width="160" alt="Cf Cell Equal To"/></td>
131
- <td align="center"><a href="#cf-cell-equal-to">View Code &amp; Detail</a></td>
132
- </tr>
133
- <tr>
134
- <td><strong>Cf Cell Greater Equal</strong></td>
135
- <td align="center"><img src="../../test/visual/baselines/cf_cell_greater_equal/page-1.png" width="160" alt="Cf Cell Greater Equal"/></td>
136
- <td align="center"><a href="#cf-cell-greater-equal">View Code &amp; Detail</a></td>
137
- </tr>
138
- <tr>
139
- <td><strong>Cf Cell Greater Than</strong></td>
140
- <td align="center"><img src="../../test/visual/baselines/cf_cell_greater_than/page-1.png" width="160" alt="Cf Cell Greater Than"/></td>
141
- <td align="center"><a href="#cf-cell-greater-than">View Code &amp; Detail</a></td>
142
- </tr>
143
- <tr>
144
- <td><strong>Cf Cell Less Than</strong></td>
145
- <td align="center"><img src="../../test/visual/baselines/cf_cell_less_than/page-1.png" width="160" alt="Cf Cell Less Than"/></td>
146
- <td align="center"><a href="#cf-cell-less-than">View Code &amp; Detail</a></td>
147
- </tr>
148
- <tr>
149
- <td><strong>Cf Color Scale</strong></td>
150
- <td align="center"><img src="../../test/visual/baselines/cf_color_scale/page-1.png" width="160" alt="Cf Color Scale"/></td>
151
- <td align="center"><a href="#cf-color-scale">View Code &amp; Detail</a></td>
152
- </tr>
153
- <tr>
154
- <td><strong>Cf Contains Text</strong></td>
155
- <td align="center"><img src="../../test/visual/baselines/cf_contains_text/page-1.png" width="160" alt="Cf Contains Text"/></td>
156
- <td align="center"><a href="#cf-contains-text">View Code &amp; Detail</a></td>
157
- </tr>
158
- <tr>
159
- <td><strong>Cf Data Bar</strong></td>
160
- <td align="center"><img src="../../test/visual/baselines/cf_data_bar/page-1.png" width="160" alt="Cf Data Bar"/></td>
161
- <td align="center"><a href="#cf-data-bar">View Code &amp; Detail</a></td>
162
- </tr>
163
- <tr>
164
- <td><strong>Cf Ends With</strong></td>
165
- <td align="center"><img src="../../test/visual/baselines/cf_ends_with/page-1.png" width="160" alt="Cf Ends With"/></td>
166
- <td align="center"><a href="#cf-ends-with">View Code &amp; Detail</a></td>
167
- </tr>
168
- <tr>
169
- <td><strong>Cf Expression Formula</strong></td>
170
- <td align="center"><img src="../../test/visual/baselines/cf_expression_formula/page-1.png" width="160" alt="Cf Expression Formula"/></td>
171
- <td align="center"><a href="#cf-expression-formula">View Code &amp; Detail</a></td>
172
- </tr>
173
- <tr>
174
- <td><strong>Cf Icon Set</strong></td>
175
- <td align="center"><img src="../../test/visual/baselines/cf_icon_set/page-1.png" width="160" alt="Cf Icon Set"/></td>
176
- <td align="center"><a href="#cf-icon-set">View Code &amp; Detail</a></td>
177
- </tr>
178
- <tr>
179
- <td><strong>Chart Area</strong></td>
180
- <td align="center"><img src="../../test/visual/baselines/chart_area/page-1.png" width="160" alt="Chart Area"/></td>
181
- <td align="center"><a href="#chart-area">View Code &amp; Detail</a></td>
182
- </tr>
183
- <tr>
184
- <td><strong>Chart Area Stacked</strong></td>
185
- <td align="center"><img src="../../test/visual/baselines/chart_area_stacked/page-1.png" width="160" alt="Chart Area Stacked"/></td>
186
- <td align="center"><a href="#chart-area-stacked">View Code &amp; Detail</a></td>
187
- </tr>
188
- <tr>
189
- <td><strong>Chart Bar</strong></td>
190
- <td align="center"><img src="../../test/visual/baselines/chart_bar/page-1.png" width="160" alt="Chart Bar"/></td>
191
- <td align="center"><a href="#chart-bar">View Code &amp; Detail</a></td>
192
- </tr>
193
- <tr>
194
- <td><strong>Chart Bar Percent Stacked</strong></td>
195
- <td align="center"><img src="../../test/visual/baselines/chart_bar_percent_stacked/page-1.png" width="160" alt="Chart Bar Percent Stacked"/></td>
196
- <td align="center"><a href="#chart-bar-percent-stacked">View Code &amp; Detail</a></td>
197
- </tr>
198
- <tr>
199
- <td><strong>Chart Bar Stacked</strong></td>
200
- <td align="center"><img src="../../test/visual/baselines/chart_bar_stacked/page-1.png" width="160" alt="Chart Bar Stacked"/></td>
201
- <td align="center"><a href="#chart-bar-stacked">View Code &amp; Detail</a></td>
202
- </tr>
203
- <tr>
204
- <td><strong>Chart Doughnut</strong></td>
205
- <td align="center"><img src="../../test/visual/baselines/chart_doughnut/page-1.png" width="160" alt="Chart Doughnut"/></td>
206
- <td align="center"><a href="#chart-doughnut">View Code &amp; Detail</a></td>
207
- </tr>
208
- <tr>
209
- <td><strong>Chart Line</strong></td>
210
- <td align="center"><img src="../../test/visual/baselines/chart_line/page-1.png" width="160" alt="Chart Line"/></td>
211
- <td align="center"><a href="#chart-line">View Code &amp; Detail</a></td>
212
- </tr>
213
- <tr>
214
- <td><strong>Chart Line Stacked</strong></td>
215
- <td align="center"><img src="../../test/visual/baselines/chart_line_stacked/page-1.png" width="160" alt="Chart Line Stacked"/></td>
216
- <td align="center"><a href="#chart-line-stacked">View Code &amp; Detail</a></td>
217
- </tr>
218
- <tr>
219
- <td><strong>Chart Pie</strong></td>
220
- <td align="center"><img src="../../test/visual/baselines/chart_pie/page-1.png" width="160" alt="Chart Pie"/></td>
221
- <td align="center"><a href="#chart-pie">View Code &amp; Detail</a></td>
222
- </tr>
223
- <tr>
224
- <td><strong>Chart Radar</strong></td>
225
- <td align="center"><img src="../../test/visual/baselines/chart_radar/page-1.png" width="160" alt="Chart Radar"/></td>
226
- <td align="center"><a href="#chart-radar">View Code &amp; Detail</a></td>
227
- </tr>
228
- <tr>
229
- <td><strong>Chart Scatter</strong></td>
230
- <td align="center"><img src="../../test/visual/baselines/chart_scatter/page-1.png" width="160" alt="Chart Scatter"/></td>
231
- <td align="center"><a href="#chart-scatter">View Code &amp; Detail</a></td>
232
- </tr>
233
- <tr>
234
- <td><strong>Col Grouping</strong></td>
235
- <td align="center"><img src="../../test/visual/baselines/col_grouping/page-1.png" width="160" alt="Col Grouping"/></td>
236
- <td align="center"><a href="#col-grouping">View Code &amp; Detail</a></td>
237
- </tr>
238
- <tr>
239
- <td><strong>Col Width Tall</strong></td>
240
- <td align="center"><img src="../../test/visual/baselines/col_width_tall/page-1.png" width="160" alt="Col Width Tall"/></td>
241
- <td align="center"><a href="#col-width-tall">View Code &amp; Detail</a></td>
242
- </tr>
243
- <tr>
244
- <td><strong>Col Widths</strong></td>
245
- <td align="center"><img src="../../test/visual/baselines/col_widths/page-1.png" width="160" alt="Col Widths"/></td>
246
- <td align="center"><a href="#col-widths">View Code &amp; Detail</a></td>
247
- </tr>
248
- <tr>
249
- <td><strong>Conditional Formatting</strong></td>
250
- <td align="center"><img src="../../test/visual/baselines/conditional_formatting/page-1.png" width="160" alt="Conditional Formatting"/></td>
251
- <td align="center"><a href="#conditional-formatting">View Code &amp; Detail</a></td>
252
- </tr>
253
- <tr>
254
- <td><strong>Drawing Shapes</strong></td>
255
- <td align="center"><img src="../../test/visual/baselines/drawing_shapes/page-1.png" width="160" alt="Drawing Shapes"/></td>
256
- <td align="center"><a href="#drawing-shapes">View Code &amp; Detail</a></td>
257
- </tr>
258
- <tr>
259
- <td><strong>Embedded Images</strong></td>
260
- <td align="center"><img src="../../test/visual/baselines/embedded_images/page-1.png" width="160" alt="Embedded Images"/></td>
261
- <td align="center"><a href="#embedded-images">View Code &amp; Detail</a></td>
262
- </tr>
263
- <tr>
264
- <td><strong>Fill Gradients</strong></td>
265
- <td align="center"><img src="../../test/visual/baselines/fill_gradients/page-1.png" width="160" alt="Fill Gradients"/></td>
266
- <td align="center"><a href="#fill-gradients">View Code &amp; Detail</a></td>
267
- </tr>
268
- <tr>
269
- <td><strong>Fill Patterns</strong></td>
270
- <td align="center"><img src="../../test/visual/baselines/fill_patterns/page-1.png" width="160" alt="Fill Patterns"/></td>
271
- <td align="center"><a href="#fill-patterns">View Code &amp; Detail</a></td>
272
- </tr>
273
- <tr>
274
- <td><strong>Fill Solid Colors</strong></td>
275
- <td align="center"><img src="../../test/visual/baselines/fill_solid_colors/page-1.png" width="160" alt="Fill Solid Colors"/></td>
276
- <td align="center"><a href="#fill-solid-colors">View Code &amp; Detail</a></td>
277
- </tr>
278
- <tr>
279
- <td><strong>Fonts</strong></td>
280
- <td align="center"><img src="../../test/visual/baselines/fonts/page-1.png" width="160" alt="Fonts"/></td>
281
- <td align="center"><a href="#fonts">View Code &amp; Detail</a></td>
282
- </tr>
283
- <tr>
284
- <td><strong>Interactive Autofilter</strong></td>
285
- <td align="center"><img src="../../test/visual/baselines/interactive_autofilter/page-1.png" width="160" alt="Interactive Autofilter"/></td>
286
- <td align="center"><a href="#interactive-autofilter">View Code &amp; Detail</a></td>
287
- </tr>
288
- <tr>
289
- <td><strong>Interactive Comments</strong></td>
290
- <td align="center"><img src="../../test/visual/baselines/interactive_comments/page-1.png" width="160" alt="Interactive Comments"/></td>
291
- <td align="center"><a href="#interactive-comments">View Code &amp; Detail</a></td>
292
- </tr>
293
- <tr>
294
- <td><strong>Interactive Validation Custom</strong></td>
295
- <td align="center"><img src="../../test/visual/baselines/interactive_validation_custom/page-1.png" width="160" alt="Interactive Validation Custom"/></td>
296
- <td align="center"><a href="#interactive-validation-custom">View Code &amp; Detail</a></td>
297
- </tr>
298
- <tr>
299
- <td><strong>Interactive Validation Date</strong></td>
300
- <td align="center"><img src="../../test/visual/baselines/interactive_validation_date/page-1.png" width="160" alt="Interactive Validation Date"/></td>
301
- <td align="center"><a href="#interactive-validation-date">View Code &amp; Detail</a></td>
302
- </tr>
303
- <tr>
304
- <td><strong>Interactive Validation List</strong></td>
305
- <td align="center"><img src="../../test/visual/baselines/interactive_validation_list/page-1.png" width="160" alt="Interactive Validation List"/></td>
306
- <td align="center"><a href="#interactive-validation-list">View Code &amp; Detail</a></td>
307
- </tr>
308
- <tr>
309
- <td><strong>Interactive Validation Range</strong></td>
310
- <td align="center"><img src="../../test/visual/baselines/interactive_validation_range/page-1.png" width="160" alt="Interactive Validation Range"/></td>
311
- <td align="center"><a href="#interactive-validation-range">View Code &amp; Detail</a></td>
312
- </tr>
313
- <tr>
314
- <td><strong>Interactive Validation Text Length</strong></td>
315
- <td align="center"><img src="../../test/visual/baselines/interactive_validation_text_length/page-1.png" width="160" alt="Interactive Validation Text Length"/></td>
316
- <td align="center"><a href="#interactive-validation-text-length">View Code &amp; Detail</a></td>
317
- </tr>
318
- <tr>
319
- <td><strong>Interactive Validation Time</strong></td>
320
- <td align="center"><img src="../../test/visual/baselines/interactive_validation_time/page-1.png" width="160" alt="Interactive Validation Time"/></td>
321
- <td align="center"><a href="#interactive-validation-time">View Code &amp; Detail</a></td>
322
- </tr>
323
- <tr>
324
- <td><strong>Japanese Text</strong></td>
325
- <td align="center"><img src="../../test/visual/baselines/japanese_text/page-1.png" width="160" alt="Japanese Text"/></td>
326
- <td align="center"><a href="#japanese-text">View Code &amp; Detail</a></td>
327
- </tr>
328
- <tr>
329
- <td><strong>Merge Freeze</strong></td>
330
- <td align="center"><img src="../../test/visual/baselines/merge_freeze/page-1.png" width="160" alt="Merge Freeze"/></td>
331
- <td align="center"><a href="#merge-freeze">View Code &amp; Detail</a></td>
332
- </tr>
333
- <tr>
334
- <td><strong>Page Grid Lines Print</strong></td>
335
- <td align="center"><img src="../../test/visual/baselines/page_grid_lines_print/page-1.png" width="160" alt="Page Grid Lines Print"/></td>
336
- <td align="center"><a href="#page-grid-lines-print">View Code &amp; Detail</a></td>
337
- </tr>
338
- <tr>
339
- <td><strong>Page Header Footer</strong></td>
340
- <td align="center"><img src="../../test/visual/baselines/page_header_footer/page-1.png" width="160" alt="Page Header Footer"/></td>
341
- <td align="center"><a href="#page-header-footer">View Code &amp; Detail</a></td>
342
- </tr>
343
- <tr>
344
- <td><strong>Page Headings Print</strong></td>
345
- <td align="center"><img src="../../test/visual/baselines/page_headings_print/page-1.png" width="160" alt="Page Headings Print"/></td>
346
- <td align="center"><a href="#page-headings-print">View Code &amp; Detail</a></td>
347
- </tr>
348
- <tr>
349
- <td><strong>Page Margins Narrow</strong></td>
350
- <td align="center"><img src="../../test/visual/baselines/page_margins_narrow/page-1.png" width="160" alt="Page Margins Narrow"/></td>
351
- <td align="center"><a href="#page-margins-narrow">View Code &amp; Detail</a></td>
352
- </tr>
353
- <tr>
354
- <td><strong>Page Margins Wide</strong></td>
355
- <td align="center"><img src="../../test/visual/baselines/page_margins_wide/page-1.png" width="160" alt="Page Margins Wide"/></td>
356
- <td align="center"><a href="#page-margins-wide">View Code &amp; Detail</a></td>
357
- </tr>
358
- <tr>
359
- <td><strong>Page Orientation Landscape</strong></td>
360
- <td align="center"><img src="../../test/visual/baselines/page_orientation_landscape/page-1.png" width="160" alt="Page Orientation Landscape"/></td>
361
- <td align="center"><a href="#page-orientation-landscape">View Code &amp; Detail</a></td>
362
- </tr>
363
- <tr>
364
- <td><strong>Page Paper Size A3</strong></td>
365
- <td align="center"><img src="../../test/visual/baselines/page_paper_size_a3/page-1.png" width="160" alt="Page Paper Size A3"/></td>
366
- <td align="center"><a href="#page-paper-size-a3">View Code &amp; Detail</a></td>
367
- </tr>
368
- <tr>
369
- <td><strong>Pivot Table</strong></td>
370
- <td align="center"><img src="../../test/visual/baselines/pivot_table/page-1.png" width="160" alt="Pivot Table"/></td>
371
- <td align="center"><a href="#pivot-table">View Code &amp; Detail</a></td>
372
- </tr>
373
- <tr>
374
- <td><strong>Row Grouping</strong></td>
375
- <td align="center"><img src="../../test/visual/baselines/row_grouping/page-1.png" width="160" alt="Row Grouping"/></td>
376
- <td align="center"><a href="#row-grouping">View Code &amp; Detail</a></td>
377
- </tr>
378
- <tr>
379
- <td><strong>Row Height Tall</strong></td>
380
- <td align="center"><img src="../../test/visual/baselines/row_height_tall/page-1.png" width="160" alt="Row Height Tall"/></td>
381
- <td align="center"><a href="#row-height-tall">View Code &amp; Detail</a></td>
382
- </tr>
383
- <tr>
384
- <td><strong>Row Heights</strong></td>
385
- <td align="center"><img src="../../test/visual/baselines/row_heights/page-1.png" width="160" alt="Row Heights"/></td>
386
- <td align="center"><a href="#row-heights">View Code &amp; Detail</a></td>
387
- </tr>
388
- <tr>
389
- <td><strong>Sheet Tab Colors</strong></td>
390
- <td align="center"><img src="../../test/visual/baselines/sheet_tab_colors/page-1.png" width="160" alt="Sheet Tab Colors"/></td>
391
- <td align="center"><a href="#sheet-tab-colors">View Code &amp; Detail</a></td>
392
- </tr>
393
- <tr>
394
- <td><strong>Sparkline Column</strong></td>
395
- <td align="center"><img src="../../test/visual/baselines/sparkline_column/page-1.png" width="160" alt="Sparkline Column"/></td>
396
- <td align="center"><a href="#sparkline-column">View Code &amp; Detail</a></td>
397
- </tr>
398
- <tr>
399
- <td><strong>Sparkline Line</strong></td>
400
- <td align="center"><img src="../../test/visual/baselines/sparkline_line/page-1.png" width="160" alt="Sparkline Line"/></td>
401
- <td align="center"><a href="#sparkline-line">View Code &amp; Detail</a></td>
402
- </tr>
403
- <tr>
404
- <td><strong>Styles Fonts Fills</strong></td>
405
- <td align="center"><img src="../../test/visual/baselines/styles_fonts_fills/page-1.png" width="160" alt="Styles Fonts Fills"/></td>
406
- <td align="center"><a href="#styles-fonts-fills">View Code &amp; Detail</a></td>
407
- </tr>
408
- <tr>
409
- <td><strong>Table Styles</strong></td>
410
- <td align="center"><img src="../../test/visual/baselines/table_styles/page-1.png" width="160" alt="Table Styles"/></td>
411
- <td align="center"><a href="#table-styles">View Code &amp; Detail</a></td>
412
- </tr>
413
- <tr>
414
- <td><strong>View Show Grid Lines</strong></td>
415
- <td align="center"><img src="../../test/visual/baselines/view_show_grid_lines/page-1.png" width="160" alt="View Show Grid Lines"/></td>
416
- <td align="center"><a href="#view-show-grid-lines">View Code &amp; Detail</a></td>
417
- </tr>
418
- <tr>
419
- <td><strong>View Zoom Scale</strong></td>
420
- <td align="center"><img src="../../test/visual/baselines/view_zoom_scale/page-1.png" width="160" alt="View Zoom Scale"/></td>
421
- <td align="center"><a href="#view-zoom-scale">View Code &amp; Detail</a></td>
422
- </tr>
423
- <tr>
424
- <td><strong>Workbook Three Sheets</strong></td>
425
- <td align="center"><img src="../../test/visual/baselines/workbook_three_sheets/page-1.png" width="160" alt="Workbook Three Sheets"/></td>
426
- <td align="center"><a href="#workbook-three-sheets">View Code &amp; Detail</a></td>
427
- </tr>
428
- </tbody>
429
- </table>
430
-
431
-
432
- ---
433
-
434
- ## Align Horizontal
435
-
436
- Demonstrates horizontal text alignment (left, center, right).
437
-
438
- ### Rendered Output (LibreOffice Calc)
439
-
440
- <div><img src="../../test/visual/baselines/align_horizontal/page-1.png" width="100%" alt="Preview"/></div>
441
-
442
- ### DSL Code
443
-
444
- ```ruby
445
- # frozen_string_literal: true
446
-
447
- require "xlsxrb"
448
- output_path = ARGV[0] || "align_horizontal.xlsx"
449
- Xlsxrb.write(output_path) do |wb|
450
- wb.style("left") { |s| s.align_horizontal("left") }
451
- wb.style("center") { |s| s.align_horizontal("center") }
452
- wb.style("right") { |s| s.align_horizontal("right") }
453
- wb.sheet("Alignment") do |s|
454
- s.print_options(:grid_lines, true)
455
- s.column(0, width: 20)
456
- s.column(1, width: 20)
457
- s.column(2, width: 20)
458
- s.row(%w[Left Center Right], styles: { 0 => "left", 1 => "center", 2 => "right" })
459
- end
460
- end
461
-
462
- # 2. Read the generated sheet and print the parsed alignments
463
- puts "=== Read Alignment (Xlsxrb.read) ==="
464
- workbook = Xlsxrb.read(output_path).load
465
- sheet = workbook.sheets.first
466
- row = sheet.rows.first
467
-
468
- row.cells.each do |c|
469
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
470
- align_h = xf&.dig(:alignment, :horizontal)
471
- puts "Cell #{c.ref} ('#{c.value}'): align_horizontal = #{align_h.inspect}"
472
- end
473
- ```
474
-
475
- ### Console Output
476
-
477
- ```text
478
- === Read Alignment (Xlsxrb.read) ===
479
- Cell A1 ('Left'): align_horizontal = "left"
480
- Cell B1 ('Center'): align_horizontal = "center"
481
- Cell C1 ('Right'): align_horizontal = "right"
482
- ```
483
-
484
- <hr/>
485
-
486
- ## Align Horizontal Fill
487
-
488
- Demonstrates horizontal fill alignment (repeats value to fill cell width).
489
-
490
- ### Rendered Output (LibreOffice Calc)
491
-
492
- <div><img src="../../test/visual/baselines/align_horizontal_fill/page-1.png" width="100%" alt="Preview"/></div>
493
-
494
- ### DSL Code
495
-
496
- ```ruby
497
- # frozen_string_literal: true
498
-
499
- require "xlsxrb"
500
- output_path = ARGV[0] || "align_horizontal_fill.xlsx"
501
- Xlsxrb.write(output_path) do |wb|
502
- wb.style("fill_align") { |s| s.align_horizontal("fill") }
503
- wb.sheet("Alignment") do |s|
504
- s.column(0, width: 30)
505
- s.row(["X "], styles: { 0 => "fill_align" })
506
- end
507
- end
508
-
509
- # 2. Read the generated sheet and print the parsed alignments
510
- puts "=== Read Validation ==="
511
- workbook = Xlsxrb.read(output_path).load
512
- sheet = workbook.sheets.first
513
- row = sheet.rows.first
514
- row.cells.each do |c|
515
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
516
- align_h = xf&.dig(:alignment, :horizontal)
517
- align_v = xf&.dig(:alignment, :vertical)
518
- wrap = xf&.dig(:alignment, :wrap_text)
519
- indent = xf&.dig(:alignment, :indent)
520
- rot = xf&.dig(:alignment, :text_rotation)
521
- shrink = xf&.dig(:alignment, :shrink_to_fit)
522
- puts "Cell #{c.ref} ('#{c.value}'): align_h=#{align_h.inspect}, align_v=#{align_v.inspect}, wrap=#{wrap.inspect}, indent=#{indent.inspect}, rotation=#{rot.inspect}, shrink=#{shrink.inspect}"
523
- end
524
- ```
525
-
526
- ### Console Output
527
-
528
- ```text
529
- === Read Validation ===
530
- Cell A1 ('X '): align_h="fill", align_v=nil, wrap=nil, indent=nil, rotation=nil, shrink=nil
531
- ```
532
-
533
- <hr/>
534
-
535
- ## Align Horizontal Justify
536
-
537
- Demonstrates horizontal justify text alignment.
538
-
539
- ### Rendered Output (LibreOffice Calc)
540
-
541
- <div><img src="../../test/visual/baselines/align_horizontal_justify/page-1.png" width="100%" alt="Preview"/></div>
542
-
543
- ### DSL Code
544
-
545
- ```ruby
546
- # frozen_string_literal: true
547
-
548
- require "xlsxrb"
549
- output_path = ARGV[0] || "align_horizontal_justify.xlsx"
550
- Xlsxrb.write(output_path) do |wb|
551
- wb.style("justify_align") do |s|
552
- s.align_horizontal("justify")
553
- s.wrap_text(true)
554
- end
555
- wb.sheet("Alignment") do |s|
556
- s.column(0, width: 25)
557
- s.row(["Justified alignment wraps and distributes text evenly."], styles: { 0 => "justify_align" })
558
- end
559
- end
560
-
561
- # 2. Read the generated sheet and print the parsed alignments
562
- puts "=== Read Validation ==="
563
- workbook = Xlsxrb.read(output_path).load
564
- sheet = workbook.sheets.first
565
- row = sheet.rows.first
566
- row.cells.each do |c|
567
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
568
- align_h = xf&.dig(:alignment, :horizontal)
569
- align_v = xf&.dig(:alignment, :vertical)
570
- wrap = xf&.dig(:alignment, :wrap_text)
571
- indent = xf&.dig(:alignment, :indent)
572
- rot = xf&.dig(:alignment, :text_rotation)
573
- shrink = xf&.dig(:alignment, :shrink_to_fit)
574
- puts "Cell #{c.ref} ('#{c.value}'): align_h=#{align_h.inspect}, align_v=#{align_v.inspect}, wrap=#{wrap.inspect}, indent=#{indent.inspect}, rotation=#{rot.inspect}, shrink=#{shrink.inspect}"
575
- end
576
- ```
577
-
578
- ### Console Output
579
-
580
- ```text
581
- === Read Validation ===
582
- Cell A1 ('Justified alignment wraps and distributes text evenly.'): align_h="justify", align_v=nil, wrap=true, indent=nil, rotation=nil, shrink=nil
583
- ```
584
-
585
- <hr/>
586
-
587
- ## Align Indent
588
-
589
- Demonstrates text indentation inside cells.
590
-
591
- ### Rendered Output (LibreOffice Calc)
592
-
593
- <div><img src="../../test/visual/baselines/align_indent/page-1.png" width="100%" alt="Preview"/></div>
594
-
595
- ### DSL Code
596
-
597
- ```ruby
598
- # frozen_string_literal: true
599
-
600
- require "xlsxrb"
601
- output_path = ARGV[0] || "align_indent.xlsx"
602
- Xlsxrb.write(output_path) do |wb|
603
- wb.style("indent_1") { |s| s.align_horizontal("left").indent(1) }
604
- wb.style("indent_3") { |s| s.align_horizontal("left").indent(3) }
605
- wb.sheet("Indent") do |s|
606
- s.column(0, width: 25)
607
- s.column(1, width: 25)
608
- s.print_options(:grid_lines, true)
609
- s.row(["No Indent"])
610
- s.row(["Indent 1"], styles: { 0 => "indent_1" })
611
- s.row(["Indent 3"], styles: { 0 => "indent_3" })
612
- end
613
- end
614
-
615
- # 2. Read the generated sheet and print the parsed alignments
616
- puts "=== Read Validation ==="
617
- workbook = Xlsxrb.read(output_path).load
618
- sheet = workbook.sheets.first
619
- row = sheet.rows.first
620
- row.cells.each do |c|
621
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
622
- align_h = xf&.dig(:alignment, :horizontal)
623
- align_v = xf&.dig(:alignment, :vertical)
624
- wrap = xf&.dig(:alignment, :wrap_text)
625
- indent = xf&.dig(:alignment, :indent)
626
- rot = xf&.dig(:alignment, :text_rotation)
627
- shrink = xf&.dig(:alignment, :shrink_to_fit)
628
- puts "Cell #{c.ref} ('#{c.value}'): align_h=#{align_h.inspect}, align_v=#{align_v.inspect}, wrap=#{wrap.inspect}, indent=#{indent.inspect}, rotation=#{rot.inspect}, shrink=#{shrink.inspect}"
629
- end
630
- ```
631
-
632
- ### Console Output
633
-
634
- ```text
635
- === Read Validation ===
636
- Cell A1 ('No Indent'): align_h=nil, align_v=nil, wrap=nil, indent=nil, rotation=nil, shrink=nil
637
- ```
638
-
639
- <hr/>
640
-
641
- ## Align Text Rotation
642
-
643
- Demonstrates text rotated by specific angles (45, 90 degrees).
644
-
645
- ### Rendered Output (LibreOffice Calc)
646
-
647
- <div><img src="../../test/visual/baselines/align_text_rotation/page-1.png" width="100%" alt="Preview"/></div>
648
-
649
- ### DSL Code
650
-
651
- ```ruby
652
- # frozen_string_literal: true
653
-
654
- require "xlsxrb"
655
- output_path = ARGV[0] || "align_text_rotation.xlsx"
656
- Xlsxrb.write(output_path) do |wb|
657
- wb.style("rot_45") { |s| s.text_rotation(45) }
658
- wb.style("rot_90") { |s| s.text_rotation(90) }
659
- wb.sheet("Rotation") do |s|
660
- s.column(0, width: 25)
661
- s.column(1, width: 25)
662
- s.print_options(:grid_lines, true)
663
- s.row(["Rotated 45", "Rotated 90"], styles: { 0 => "rot_45", 1 => "rot_90" }, height: 50)
664
- end
665
- end
666
-
667
- # 2. Read the generated sheet and print the parsed alignments
668
- puts "=== Read Validation ==="
669
- workbook = Xlsxrb.read(output_path).load
670
- sheet = workbook.sheets.first
671
- row = sheet.rows.first
672
- row.cells.each do |c|
673
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
674
- align_h = xf&.dig(:alignment, :horizontal)
675
- align_v = xf&.dig(:alignment, :vertical)
676
- wrap = xf&.dig(:alignment, :wrap_text)
677
- indent = xf&.dig(:alignment, :indent)
678
- rot = xf&.dig(:alignment, :text_rotation)
679
- shrink = xf&.dig(:alignment, :shrink_to_fit)
680
- puts "Cell #{c.ref} ('#{c.value}'): align_h=#{align_h.inspect}, align_v=#{align_v.inspect}, wrap=#{wrap.inspect}, indent=#{indent.inspect}, rotation=#{rot.inspect}, shrink=#{shrink.inspect}"
681
- end
682
- ```
683
-
684
- ### Console Output
685
-
686
- ```text
687
- === Read Validation ===
688
- Cell A1 ('Rotated 45'): align_h=nil, align_v=nil, wrap=nil, indent=nil, rotation=45, shrink=nil
689
- Cell B1 ('Rotated 90'): align_h=nil, align_v=nil, wrap=nil, indent=nil, rotation=90, shrink=nil
690
- ```
691
-
692
- <hr/>
693
-
694
- ## Align Text Wrap
695
-
696
- Demonstrates auto-wrapping multi-line text inside narrow cells.
697
-
698
- ### Rendered Output (LibreOffice Calc)
699
-
700
- <div><img src="../../test/visual/baselines/align_text_wrap/page-1.png" width="100%" alt="Preview"/></div>
701
-
702
- ### DSL Code
703
-
704
- ```ruby
705
- # frozen_string_literal: true
706
-
707
- require "xlsxrb"
708
- output_path = ARGV[0] || "align_text_wrap.xlsx"
709
- Xlsxrb.write(output_path) do |wb|
710
- wb.style("wrap", &:wrap_text)
711
- wb.sheet("Text Wrap") do |s|
712
- s.print_options(:grid_lines, true)
713
- s.column(0, width: 15)
714
- s.row(["This is a long sentence that wraps inside the cell."], styles: { 0 => "wrap" })
715
- end
716
- end
717
-
718
- # 2. Read the generated sheet and print the parsed alignments
719
- puts "=== Read Validation ==="
720
- workbook = Xlsxrb.read(output_path).load
721
- sheet = workbook.sheets.first
722
- row = sheet.rows.first
723
- row.cells.each do |c|
724
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
725
- align_h = xf&.dig(:alignment, :horizontal)
726
- align_v = xf&.dig(:alignment, :vertical)
727
- wrap = xf&.dig(:alignment, :wrap_text)
728
- indent = xf&.dig(:alignment, :indent)
729
- rot = xf&.dig(:alignment, :text_rotation)
730
- shrink = xf&.dig(:alignment, :shrink_to_fit)
731
- puts "Cell #{c.ref} ('#{c.value}'): align_h=#{align_h.inspect}, align_v=#{align_v.inspect}, wrap=#{wrap.inspect}, indent=#{indent.inspect}, rotation=#{rot.inspect}, shrink=#{shrink.inspect}"
732
- end
733
- ```
734
-
735
- ### Console Output
736
-
737
- ```text
738
- === Read Validation ===
739
- Cell A1 ('This is a long sentence that wraps inside the cell.'): align_h=nil, align_v=nil, wrap=true, indent=nil, rotation=nil, shrink=nil
740
- ```
741
-
742
- <hr/>
743
-
744
- ## Align Vertical
745
-
746
- Demonstrates vertical text alignment (top, center, bottom).
747
-
748
- ### Rendered Output (LibreOffice Calc)
749
-
750
- <div><img src="../../test/visual/baselines/align_vertical/page-1.png" width="100%" alt="Preview"/></div>
751
-
752
- ### DSL Code
753
-
754
- ```ruby
755
- # frozen_string_literal: true
756
-
757
- require "xlsxrb"
758
- output_path = ARGV[0] || "align_vertical.xlsx"
759
- Xlsxrb.write(output_path) do |wb|
760
- wb.style("top") { |s| s.align_vertical("top") }
761
- wb.style("center") { |s| s.align_vertical("center") }
762
- wb.style("bottom") { |s| s.align_vertical("bottom") }
763
- wb.sheet("Vertical Alignment") do |s|
764
- s.column(0, width: 25)
765
- s.column(1, width: 25)
766
- s.print_options(:grid_lines, true)
767
- s.row(%w[Top Center Bottom], styles: { 0 => "top", 1 => "center", 2 => "bottom" }, height: 40)
768
- end
769
- end
770
-
771
- # 2. Read the generated sheet and print the parsed alignments
772
- puts "=== Read Validation ==="
773
- workbook = Xlsxrb.read(output_path).load
774
- sheet = workbook.sheets.first
775
- row = sheet.rows.first
776
- row.cells.each do |c|
777
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
778
- align_h = xf&.dig(:alignment, :horizontal)
779
- align_v = xf&.dig(:alignment, :vertical)
780
- wrap = xf&.dig(:alignment, :wrap_text)
781
- indent = xf&.dig(:alignment, :indent)
782
- rot = xf&.dig(:alignment, :text_rotation)
783
- shrink = xf&.dig(:alignment, :shrink_to_fit)
784
- puts "Cell #{c.ref} ('#{c.value}'): align_h=#{align_h.inspect}, align_v=#{align_v.inspect}, wrap=#{wrap.inspect}, indent=#{indent.inspect}, rotation=#{rot.inspect}, shrink=#{shrink.inspect}"
785
- end
786
- ```
787
-
788
- ### Console Output
789
-
790
- ```text
791
- === Read Validation ===
792
- Cell A1 ('Top'): align_h=nil, align_v="top", wrap=nil, indent=nil, rotation=nil, shrink=nil
793
- Cell B1 ('Center'): align_h=nil, align_v="center", wrap=nil, indent=nil, rotation=nil, shrink=nil
794
- Cell C1 ('Bottom'): align_h=nil, align_v="bottom", wrap=nil, indent=nil, rotation=nil, shrink=nil
795
- ```
796
-
797
- <hr/>
798
-
799
- ## Basic Data
800
-
801
- Demonstrates simple tabular data writing with basic Ruby types (Strings, Numbers, Dates, Booleans).
802
-
803
- ### Rendered Output (LibreOffice Calc)
804
-
805
- <div><img src="../../test/visual/baselines/basic_data/page-1.png" width="100%" alt="Preview"/></div>
806
-
807
- ### DSL Code
808
-
809
- ```ruby
810
- # frozen_string_literal: true
811
-
812
- require "xlsxrb"
813
- require "date"
814
-
815
- output_path = ARGV[0] || "basic_data.xlsx"
816
-
817
- Xlsxrb.write(output_path) do |wb|
818
- wb.style("currency") { |style| style.number_format("$#,##0.00") }
819
- wb.style("date") { |style| style.number_format("yyyy-mm-dd") }
820
- wb.sheet("Basic Data") do |sheet|
821
- sheet.sheet_properties(:fit_to_page, true)
822
- sheet.page_setup(fit_to_width: 1, fit_to_height: 1)
823
- sheet.column(0, width: 25)
824
- sheet.column(1, width: 25)
825
- sheet.row(%w[Product Qty Price Date Active])
826
- sheet.row(["Gadget A", 10, 99.99, Date.new(2026, 1, 15), true], styles: { 2 => "currency", 3 => "date" })
827
- sheet.row(["Widget B", 5, 49.50, Date.new(2026, 2, 20), false], styles: { 2 => "currency", 3 => "date" })
828
- end
829
- end
830
-
831
- # 2. Read the generated sheet and print parsed cell values and Ruby classes
832
- puts "=== Read Validation ==="
833
- workbook = Xlsxrb.read(output_path).load
834
- sheet = workbook.sheets.first
835
- sheet.rows.each do |row|
836
- row_cells = row.cells.map do |c|
837
- "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
838
- end
839
- puts "Row #{row.index}: #{row_cells.join(", ")}"
840
- end
841
- ```
842
-
843
- ### Console Output
844
-
845
- ```text
846
- === Read Validation ===
847
- Row 0: A1: "Product" (String), B1: "Qty" (String), C1: "Price" (String), D1: "Date" (String), E1: "Active" (String)
848
- Row 1: A2: "Gadget A" (String), B2: 10 (Integer), C2: 99.99 (Float), D2: 46037 (Integer), E2: true (TrueClass)
849
- Row 2: A3: "Widget B" (String), B3: 5 (Integer), C3: 49.5 (Float), D3: 46073 (Integer), E3: false (FalseClass)
850
- ```
851
-
852
- <hr/>
853
-
854
- ## Borders
855
-
856
- Demonstrates border styles (thin, medium, thick, hair, dashed, medium dashed, dotted, double, dash-dot, medium dash-dot, dash-dot-dot, slanted, and diagonal cross borders) applied to cell ranges.
857
-
858
- ### Rendered Output (LibreOffice Calc)
859
-
860
- <div><img src="../../test/visual/baselines/borders/page-1.png" width="100%" alt="Preview"/></div>
861
-
862
- ### DSL Code
863
-
864
- ```ruby
865
- # frozen_string_literal: true
866
-
867
- require "xlsxrb"
868
-
869
- output_path = ARGV[0] || "borders.xlsx"
870
-
871
- Xlsxrb.write(output_path) do |wb|
872
- wb.style("thin") { |s| s.border_all(style: "thin", color: "FF000000") }
873
- wb.style("medium") { |s| s.border_all(style: "medium", color: "FF000000") }
874
- wb.style("thick") { |s| s.border_all(style: "thick", color: "FF000000") }
875
- wb.style("hair") { |s| s.border_all(style: "hair", color: "FF000000") }
876
- wb.style("dashed") { |s| s.border_all(style: "dashed", color: "FF000000") }
877
- wb.style("medium_dashed") { |s| s.border_all(style: "mediumDashed", color: "FF000000") }
878
- wb.style("dotted") { |s| s.border_all(style: "dotted", color: "FF000000") }
879
- wb.style("double") { |s| s.border_all(style: "double", color: "FF000000") }
880
- wb.style("dash_dot") { |s| s.border_all(style: "dashDot", color: "FF000000") }
881
- wb.style("medium_dash_dot") { |s| s.border_all(style: "mediumDashDot", color: "FF000000") }
882
- wb.style("dash_dot_dot") { |s| s.border_all(style: "dashDotDot", color: "FF000000") }
883
- wb.style("slanted") { |s| s.border_all(style: "slantedDashDot", color: "FF000000") }
884
- wb.style("diagonal") { |s| s.border_diagonal(style: "thin", color: "FF000000", up: true, down: true) }
885
-
886
- wb.sheet("Borders") do |s|
887
- s.column(0, width: 25)
888
- s.column(1, width: 25)
889
- s.print_options(:grid_lines, true)
890
-
891
- s.row(["Border Style", "Cell Preview"])
892
- s.row(["Thin", "Thin Border"], styles: { 1 => "thin" })
893
- s.row(["Medium", "Medium Border"], styles: { 1 => "medium" })
894
- s.row(["Thick", "Thick Border"], styles: { 1 => "thick" })
895
- s.row(["Hair", "Hair Border"], styles: { 1 => "hair" })
896
- s.row(["Dashed", "Dashed Border"], styles: { 1 => "dashed" })
897
- s.row(["Medium Dashed", "Medium Dashed"], styles: { 1 => "medium_dashed" })
898
- s.row(["Dotted", "Dotted Border"], styles: { 1 => "dotted" })
899
- s.row(["Double", "Double Border"], styles: { 1 => "double" })
900
- s.row(["Dash-Dot", "Dash-Dot Border"], styles: { 1 => "dash_dot" })
901
- s.row(["Medium Dash-Dot", "Medium Dash-Dot"], styles: { 1 => "medium_dash_dot" })
902
- s.row(%w[Dash-Dot-Dot Dash-Dot-Dot], styles: { 1 => "dash_dot_dot" })
903
- s.row(["Slanted Dash-Dot", "Slanted Border"], styles: { 1 => "slanted" })
904
- s.row(["Diagonal (Cross)", "Diagonal Border"], styles: { 1 => "diagonal" })
905
- end
906
- end
907
-
908
- # Read check
909
- puts "=== Read Validation ==="
910
- workbook = Xlsxrb.read(output_path).load
911
- sheet = workbook.sheets.first
912
- sheet.rows.each do |row|
913
- row_cells = row.cells.map do |c|
914
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
915
- border_id = xf ? xf[:border_id] : 0
916
- "#{c.ref}: #{c.value.inspect} (border_id: #{border_id})"
917
- end
918
- puts "Row #{row.index}: #{row_cells.join(", ")}"
919
- end
920
- ```
921
-
922
- ### Console Output
923
-
924
- ```text
925
- === Read Validation ===
926
- Row 0: A1: "Border Style" (border_id: 0), B1: "Cell Preview" (border_id: 0)
927
- Row 1: A2: "Thin" (border_id: 0), B2: "Thin Border" (border_id: 1)
928
- Row 2: A3: "Medium" (border_id: 0), B3: "Medium Border" (border_id: 2)
929
- Row 3: A4: "Thick" (border_id: 0), B4: "Thick Border" (border_id: 3)
930
- Row 4: A5: "Hair" (border_id: 0), B5: "Hair Border" (border_id: 4)
931
- Row 5: A6: "Dashed" (border_id: 0), B6: "Dashed Border" (border_id: 5)
932
- Row 6: A7: "Medium Dashed" (border_id: 0), B7: "Medium Dashed" (border_id: 6)
933
- Row 7: A8: "Dotted" (border_id: 0), B8: "Dotted Border" (border_id: 7)
934
- Row 8: A9: "Double" (border_id: 0), B9: "Double Border" (border_id: 8)
935
- Row 9: A10: "Dash-Dot" (border_id: 0), B10: "Dash-Dot Border" (border_id: 9)
936
- Row 10: A11: "Medium Dash-Dot" (border_id: 0), B11: "Medium Dash-Dot" (border_id: 10)
937
- Row 11: A12: "Dash-Dot-Dot" (border_id: 0), B12: "Dash-Dot-Dot" (border_id: 11)
938
- Row 12: A13: "Slanted Dash-Dot" (border_id: 0), B13: "Slanted Border" (border_id: 12)
939
- Row 13: A14: "Diagonal (Cross)" (border_id: 0), B14: "Diagonal Border" (border_id: 13)
940
- ```
941
-
942
- <hr/>
943
-
944
- ## Cell Booleans
945
-
946
- Demonstrates boolean values serialized and rendered.
947
-
948
- ### Rendered Output (LibreOffice Calc)
949
-
950
- <div><img src="../../test/visual/baselines/cell_booleans/page-1.png" width="100%" alt="Preview"/></div>
951
-
952
- ### DSL Code
953
-
954
- ```ruby
955
- # frozen_string_literal: true
956
-
957
- require "xlsxrb"
958
- output_path = ARGV[0] || "cell_booleans.xlsx"
959
- Xlsxrb.write(output_path) do |wb|
960
- wb.sheet("Booleans") do |s|
961
- s.column(0, width: 25)
962
- s.column(1, width: 25)
963
- s.row(["Label", "Boolean Value"])
964
- s.row(["Is Active", true])
965
- s.row(["Is Pending", false])
966
- end
967
- end
968
-
969
- # 2. Read the generated sheet and print parsed cell values and Ruby classes
970
- puts "=== Read Validation ==="
971
- workbook = Xlsxrb.read(output_path).load
972
- sheet = workbook.sheets.first
973
- sheet.rows.each do |row|
974
- row_cells = row.cells.map do |c|
975
- "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
976
- end
977
- puts "Row #{row.index}: #{row_cells.join(", ")}"
978
- end
979
- ```
980
-
981
- ### Console Output
982
-
983
- ```text
984
- === Read Validation ===
985
- Row 0: A1: "Label" (String), B1: "Boolean Value" (String)
986
- Row 1: A2: "Is Active" (String), B2: true (TrueClass)
987
- Row 2: A3: "Is Pending" (String), B3: false (FalseClass)
988
- ```
989
-
990
- <hr/>
991
-
992
- ## Cell Dates
993
-
994
- Demonstrates dates serialized natively and formatted with standard or custom format strings.
995
-
996
- ### Rendered Output (LibreOffice Calc)
997
-
998
- <div><img src="../../test/visual/baselines/cell_dates/page-1.png" width="100%" alt="Preview"/></div>
999
-
1000
- ### DSL Code
1001
-
1002
- ```ruby
1003
- # frozen_string_literal: true
1004
-
1005
- require "xlsxrb"
1006
- require "date"
1007
- output_path = ARGV[0] || "cell_dates.xlsx"
1008
- Xlsxrb.write(output_path) do |wb|
1009
- wb.style("custom_date") { |s| s.num_fmt("yyyy-mm-dd") }
1010
- wb.sheet("Dates") do |s|
1011
- s.column(0, width: 25)
1012
- s.column(1, width: 25)
1013
- s.row(["Format", "Date Value"])
1014
- s.row(["Default Date", Date.new(2026, 7, 1)])
1015
- s.row(["Formatted Date", Date.new(2026, 12, 25)], styles: { 1 => "custom_date" })
1016
- end
1017
- end
1018
-
1019
- # 2. Read the generated sheet and print parsed cell values and Ruby classes
1020
- puts "=== Read Validation ==="
1021
- workbook = Xlsxrb.read(output_path).load
1022
- sheet = workbook.sheets.first
1023
- sheet.rows.each do |row|
1024
- row_cells = row.cells.map do |c|
1025
- "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
1026
- end
1027
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1028
- end
1029
- ```
1030
-
1031
- ### Console Output
1032
-
1033
- ```text
1034
- === Read Validation ===
1035
- Row 0: A1: "Format" (String), B1: "Date Value" (String)
1036
- Row 1: A2: "Default Date" (String), B2: 46204 (Integer)
1037
- Row 2: A3: "Formatted Date" (String), B3: 46381 (Integer)
1038
- ```
1039
-
1040
- <hr/>
1041
-
1042
- ## Cell Formulas
1043
-
1044
- Demonstrates standard spreadsheet calculations and formulas (SUM, AVERAGE).
1045
-
1046
- ### Rendered Output (LibreOffice Calc)
1047
-
1048
- <div><img src="../../test/visual/baselines/cell_formulas/page-1.png" width="100%" alt="Preview"/></div>
1049
-
1050
- ### DSL Code
1051
-
1052
- ```ruby
1053
- # frozen_string_literal: true
1054
-
1055
- require "xlsxrb"
1056
- output_path = ARGV[0] || "cell_formulas.xlsx"
1057
- Xlsxrb.write(output_path) do |wb|
1058
- wb.sheet("Formulas") do |s|
1059
- s.column(0, width: 25)
1060
- s.column(1, width: 25)
1061
- s.row(%w[Item Value])
1062
- s.row(["A", 10])
1063
- s.row(["B", 20])
1064
- s.row(["SUM", Xlsxrb::Elements::Formula.new(expression: "SUM(B2:B3)", cached_value: 30)])
1065
- s.row(["AVERAGE", Xlsxrb::Elements::Formula.new(expression: "AVERAGE(B2:B3)", cached_value: 15)])
1066
- end
1067
- end
1068
-
1069
- # 2. Read the generated sheet and print parsed cell values and Ruby classes
1070
- puts "=== Read Validation ==="
1071
- workbook = Xlsxrb.read(output_path).load
1072
- sheet = workbook.sheets.first
1073
- sheet.rows.each do |row|
1074
- row_cells = row.cells.map do |c|
1075
- "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
1076
- end
1077
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1078
- end
1079
- ```
1080
-
1081
- ### Console Output
1082
-
1083
- ```text
1084
- === Read Validation ===
1085
- Row 0: A1: "Item" (String), B1: "Value" (String)
1086
- Row 1: A2: "A" (String), B2: 10 (Integer)
1087
- Row 2: A3: "B" (String), B3: 20 (Integer)
1088
- Row 3: A4: "SUM" (String), B4: 30 (Integer)
1089
- Row 4: A5: "AVERAGE" (String), B5: 15 (Integer)
1090
- ```
1091
-
1092
- <hr/>
1093
-
1094
- ## Cell Num Currency Jpy
1095
-
1096
- Demonstrates Yen Currency format code formatting.
1097
-
1098
- ### Rendered Output (LibreOffice Calc)
1099
-
1100
- <div><img src="../../test/visual/baselines/cell_num_currency_jpy/page-1.png" width="100%" alt="Preview"/></div>
1101
-
1102
- ### DSL Code
1103
-
1104
- ```ruby
1105
- # frozen_string_literal: true
1106
-
1107
- require "xlsxrb"
1108
- output_path = ARGV[0] || "cell_num_currency_jpy.xlsx"
1109
- Xlsxrb.write(output_path) do |wb|
1110
- wb.style("jpy") { |s| s.num_fmt("¥#,##0;[Red]¥-#,##0") }
1111
- wb.sheet("JPY Currency") do |s|
1112
- s.column(0, width: 25)
1113
- s.column(1, width: 25)
1114
- s.row(%w[Format Value])
1115
- s.row(["Positive Yen", 12_500], styles: { 1 => "jpy" })
1116
- s.row(["Negative Yen", -8000], styles: { 1 => "jpy" })
1117
- end
1118
- end
1119
-
1120
- # 2. Read the generated sheet and print parsed cell numbers and format codes
1121
- puts "=== Read Validation ==="
1122
- workbook = Xlsxrb.read(output_path).load
1123
- sheet = workbook.sheets.first
1124
- sheet.rows.each do |row|
1125
- row_cells = row.cells.map do |c|
1126
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
1127
- num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
1128
- "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
1129
- end
1130
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1131
- end
1132
- ```
1133
-
1134
- ### Console Output
1135
-
1136
- ```text
1137
- === Read Validation ===
1138
- Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
1139
- Row 1: A2: "Positive Yen" (Format ID: , Code: nil), B2: 12500 (Format ID: 164, Code: "¥#,##0;[Red]¥-#,##0")
1140
- Row 2: A3: "Negative Yen" (Format ID: , Code: nil), B3: -8000 (Format ID: 164, Code: "¥#,##0;[Red]¥-#,##0")
1141
- ```
1142
-
1143
- <hr/>
1144
-
1145
- ## Cell Num Custom Colors
1146
-
1147
- Demonstrates custom colored formats for positive and negative numbers.
1148
-
1149
- ### Rendered Output (LibreOffice Calc)
1150
-
1151
- <div><img src="../../test/visual/baselines/cell_num_custom_colors/page-1.png" width="100%" alt="Preview"/></div>
1152
-
1153
- ### DSL Code
1154
-
1155
- ```ruby
1156
- # frozen_string_literal: true
1157
-
1158
- require "xlsxrb"
1159
- output_path = ARGV[0] || "cell_num_custom_colors.xlsx"
1160
- Xlsxrb.write(output_path) do |wb|
1161
- wb.style("custom_color") { |s| s.num_fmt("[Green]#,##0;[Red]-#,##0") }
1162
- wb.sheet("Custom Colors") do |s|
1163
- s.column(0, width: 25)
1164
- s.column(1, width: 25)
1165
- s.row(%w[Format Value])
1166
- s.row(["Positive (Green)", 5000], styles: { 1 => "custom_color" })
1167
- s.row(["Negative (Red)", -2500], styles: { 1 => "custom_color" })
1168
- end
1169
- end
1170
-
1171
- # 2. Read the generated sheet and print parsed cell numbers and format codes
1172
- puts "=== Read Validation ==="
1173
- workbook = Xlsxrb.read(output_path).load
1174
- sheet = workbook.sheets.first
1175
- sheet.rows.each do |row|
1176
- row_cells = row.cells.map do |c|
1177
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
1178
- num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
1179
- "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
1180
- end
1181
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1182
- end
1183
- ```
1184
-
1185
- ### Console Output
1186
-
1187
- ```text
1188
- === Read Validation ===
1189
- Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
1190
- Row 1: A2: "Positive (Green)" (Format ID: , Code: nil), B2: 5000 (Format ID: 164, Code: "[Green]#,##0;[Red]-#,##0")
1191
- Row 2: A3: "Negative (Red)" (Format ID: , Code: nil), B3: -2500 (Format ID: 164, Code: "[Green]#,##0;[Red]-#,##0")
1192
- ```
1193
-
1194
- <hr/>
1195
-
1196
- ## Cell Num Fractions
1197
-
1198
- Demonstrates fraction number formats (# ?/?).
1199
-
1200
- ### Rendered Output (LibreOffice Calc)
1201
-
1202
- <div><img src="../../test/visual/baselines/cell_num_fractions/page-1.png" width="100%" alt="Preview"/></div>
1203
-
1204
- ### DSL Code
1205
-
1206
- ```ruby
1207
- # frozen_string_literal: true
1208
-
1209
- require "xlsxrb"
1210
- output_path = ARGV[0] || "cell_num_fractions.xlsx"
1211
- Xlsxrb.write(output_path) do |wb|
1212
- wb.style("frac") { |s| s.num_fmt("# ?/?") }
1213
- wb.sheet("Fractions") do |s|
1214
- s.column(0, width: 25)
1215
- s.column(1, width: 25)
1216
- s.row(%w[Format Value])
1217
- s.row(["Half", 0.5], styles: { 1 => "frac" })
1218
- s.row(["Third", 0.3333], styles: { 1 => "frac" })
1219
- s.row(["Quarter", 0.75], styles: { 1 => "frac" })
1220
- end
1221
- end
1222
-
1223
- # 2. Read the generated sheet and print parsed cell numbers and format codes
1224
- puts "=== Read Validation ==="
1225
- workbook = Xlsxrb.read(output_path).load
1226
- sheet = workbook.sheets.first
1227
- sheet.rows.each do |row|
1228
- row_cells = row.cells.map do |c|
1229
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
1230
- num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
1231
- "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
1232
- end
1233
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1234
- end
1235
- ```
1236
-
1237
- ### Console Output
1238
-
1239
- ```text
1240
- === Read Validation ===
1241
- Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
1242
- Row 1: A2: "Half" (Format ID: , Code: nil), B2: 0.5 (Format ID: 164, Code: "# ?/?")
1243
- Row 2: A3: "Third" (Format ID: , Code: nil), B3: 0.3333 (Format ID: 164, Code: "# ?/?")
1244
- Row 3: A4: "Quarter" (Format ID: , Code: nil), B4: 0.75 (Format ID: 164, Code: "# ?/?")
1245
- ```
1246
-
1247
- <hr/>
1248
-
1249
- ## Cell Num Percent Decimals
1250
-
1251
- Demonstrates percentages with two decimal places (0.00%).
1252
-
1253
- ### Rendered Output (LibreOffice Calc)
1254
-
1255
- <div><img src="../../test/visual/baselines/cell_num_percent_decimals/page-1.png" width="100%" alt="Preview"/></div>
1256
-
1257
- ### DSL Code
1258
-
1259
- ```ruby
1260
- # frozen_string_literal: true
1261
-
1262
- require "xlsxrb"
1263
- output_path = ARGV[0] || "cell_num_percent_decimals.xlsx"
1264
- Xlsxrb.write(output_path) do |wb|
1265
- wb.style("pct2") { |s| s.num_fmt("0.00%") }
1266
- wb.sheet("Percents") do |s|
1267
- s.column(0, width: 25)
1268
- s.column(1, width: 25)
1269
- s.row(%w[Format Value])
1270
- s.row(["Percent with 2 Decimals", 0.12345], styles: { 1 => "pct2" })
1271
- end
1272
- end
1273
-
1274
- # 2. Read the generated sheet and print parsed cell numbers and format codes
1275
- puts "=== Read Validation ==="
1276
- workbook = Xlsxrb.read(output_path).load
1277
- sheet = workbook.sheets.first
1278
- sheet.rows.each do |row|
1279
- row_cells = row.cells.map do |c|
1280
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
1281
- num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
1282
- "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
1283
- end
1284
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1285
- end
1286
- ```
1287
-
1288
- ### Console Output
1289
-
1290
- ```text
1291
- === Read Validation ===
1292
- Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
1293
- Row 1: A2: "Percent with 2 Decimals" (Format ID: , Code: nil), B2: 0.12345 (Format ID: 164, Code: "0.00%")
1294
- ```
1295
-
1296
- <hr/>
1297
-
1298
- ## Cell Num Scientific
1299
-
1300
- Demonstrates scientific number formats (0.00E+00).
1301
-
1302
- ### Rendered Output (LibreOffice Calc)
1303
-
1304
- <div><img src="../../test/visual/baselines/cell_num_scientific/page-1.png" width="100%" alt="Preview"/></div>
1305
-
1306
- ### DSL Code
1307
-
1308
- ```ruby
1309
- # frozen_string_literal: true
1310
-
1311
- require "xlsxrb"
1312
- output_path = ARGV[0] || "cell_num_scientific.xlsx"
1313
- Xlsxrb.write(output_path) do |wb|
1314
- wb.style("sci") { |s| s.num_fmt("0.00E+00") }
1315
- wb.sheet("Scientific") do |s|
1316
- s.column(0, width: 25)
1317
- s.column(1, width: 25)
1318
- s.row(%w[Format Value])
1319
- s.row(["Scientific", 123_456_789.0], styles: { 1 => "sci" })
1320
- s.row(["Small Scientific", 0.00001234], styles: { 1 => "sci" })
1321
- end
1322
- end
1323
-
1324
- # 2. Read the generated sheet and print parsed cell numbers and format codes
1325
- puts "=== Read Validation ==="
1326
- workbook = Xlsxrb.read(output_path).load
1327
- sheet = workbook.sheets.first
1328
- sheet.rows.each do |row|
1329
- row_cells = row.cells.map do |c|
1330
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
1331
- num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
1332
- "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
1333
- end
1334
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1335
- end
1336
- ```
1337
-
1338
- ### Console Output
1339
-
1340
- ```text
1341
- === Read Validation ===
1342
- Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
1343
- Row 1: A2: "Scientific" (Format ID: , Code: nil), B2: 123456789.0 (Format ID: 164, Code: "0.00E+00")
1344
- Row 2: A3: "Small Scientific" (Format ID: , Code: nil), B3: 1.234e-05 (Format ID: 164, Code: "0.00E+00")
1345
- ```
1346
-
1347
- <hr/>
1348
-
1349
- ## Cell Numbers
1350
-
1351
- Demonstrates custom formatting for integers, floating point numbers, currencies, and percentages.
1352
-
1353
- ### Rendered Output (LibreOffice Calc)
1354
-
1355
- <div><img src="../../test/visual/baselines/cell_numbers/page-1.png" width="100%" alt="Preview"/></div>
1356
-
1357
- ### DSL Code
1358
-
1359
- ```ruby
1360
- # frozen_string_literal: true
1361
-
1362
- require "xlsxrb"
1363
- output_path = ARGV[0] || "cell_numbers.xlsx"
1364
- Xlsxrb.write(output_path) do |wb|
1365
- wb.style("currency") { |s| s.num_fmt("$#,##0.00") }
1366
- wb.style("percent") { |s| s.num_fmt("0.0%") }
1367
- wb.sheet("Numbers") do |s|
1368
- s.column(0, width: 25)
1369
- s.column(1, width: 25)
1370
- s.row(%w[Format Value])
1371
- s.row(["Integer", 12_345])
1372
- s.row(["Float", 123.456])
1373
- s.row(["Currency", 1234.5], styles: { 1 => "currency" })
1374
- s.row(["Percentage", 0.85], styles: { 1 => "percent" })
1375
- end
1376
- end
1377
-
1378
- # 2. Read the generated sheet and print parsed cell values and Ruby classes
1379
- puts "=== Read Validation ==="
1380
- workbook = Xlsxrb.read(output_path).load
1381
- sheet = workbook.sheets.first
1382
- sheet.rows.each do |row|
1383
- row_cells = row.cells.map do |c|
1384
- "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
1385
- end
1386
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1387
- end
1388
- ```
1389
-
1390
- ### Console Output
1391
-
1392
- ```text
1393
- === Read Validation ===
1394
- Row 0: A1: "Format" (String), B1: "Value" (String)
1395
- Row 1: A2: "Integer" (String), B2: 12345 (Integer)
1396
- Row 2: A3: "Float" (String), B3: 123.456 (Float)
1397
- Row 3: A4: "Currency" (String), B4: 1234.5 (Float)
1398
- Row 4: A5: "Percentage" (String), B5: 0.85 (Float)
1399
- ```
1400
-
1401
- <hr/>
1402
-
1403
- ## Cell Rich Text
1404
-
1405
- Demonstrates Rich Text cells with multiple font weights, styles, and colors in a single cell.
1406
-
1407
- ### Rendered Output (LibreOffice Calc)
1408
-
1409
- <div><img src="../../test/visual/baselines/cell_rich_text/page-1.png" width="100%" alt="Preview"/></div>
1410
-
1411
- ### DSL Code
1412
-
1413
- ```ruby
1414
- # frozen_string_literal: true
1415
-
1416
- require "xlsxrb"
1417
- output_path = ARGV[0] || "cell_rich_text.xlsx"
1418
- Xlsxrb.write(output_path) do |wb|
1419
- rt = Xlsxrb.rich_text(
1420
- { text: "Normal " },
1421
- { text: "BOLD RED ", font: { bold: true, color: "FFC00000", sz: 16 } },
1422
- { text: "ITALIC BLUE", font: { italic: true, color: :blue, sz: 20 } }
1423
- )
1424
- wb.sheet("Rich Text") do |s|
1425
- s.column(0, width: 25)
1426
- s.column(1, width: 25)
1427
- s.row(%w[Format Value])
1428
- s.row(["Rich Text Cell", rt])
1429
- end
1430
- end
1431
-
1432
- # 2. Read the generated sheet and print parsed cell values and Ruby classes
1433
- puts "=== Read Validation ==="
1434
- workbook = Xlsxrb.read(output_path).load
1435
- sheet = workbook.sheets.first
1436
- sheet.rows.each do |row|
1437
- row_cells = row.cells.map do |c|
1438
- "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
1439
- end
1440
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1441
- end
1442
- ```
1443
-
1444
- ### Console Output
1445
-
1446
- ```text
1447
- === Read Validation ===
1448
- Row 0: A1: "Format" (String), B1: "Value" (String)
1449
- Row 1: A2: "Rich Text Cell" (String), B2: "Normal BOLD RED ITALIC BLUE" (String)
1450
- ```
1451
-
1452
- <hr/>
1453
-
1454
- ## Cell Times
1455
-
1456
- Demonstrates timestamp values serialized natively and formatted showing hours, minutes, and seconds.
1457
-
1458
- ### Rendered Output (LibreOffice Calc)
1459
-
1460
- <div><img src="../../test/visual/baselines/cell_times/page-1.png" width="100%" alt="Preview"/></div>
1461
-
1462
- ### DSL Code
1463
-
1464
- ```ruby
1465
- # frozen_string_literal: true
1466
-
1467
- require "xlsxrb"
1468
- require "time"
1469
- output_path = ARGV[0] || "cell_times.xlsx"
1470
- Xlsxrb.write(output_path) do |wb|
1471
- wb.style("time_fmt") { |s| s.num_fmt("hh:mm:ss") }
1472
- wb.sheet("Times") do |s|
1473
- s.column(0, width: 25)
1474
- s.column(1, width: 25)
1475
- s.row(["Format", "Time Value"])
1476
- s.row(["DateTime", Time.new(2026, 7, 1, 12, 34, 56)])
1477
- s.row(["Time Only", Time.new(2026, 7, 1, 9, 15, 0)], styles: { 1 => "time_fmt" })
1478
- end
1479
- end
1480
-
1481
- # 2. Read the generated sheet and print parsed cell values and Ruby classes
1482
- puts "=== Read Validation ==="
1483
- workbook = Xlsxrb.read(output_path).load
1484
- sheet = workbook.sheets.first
1485
- sheet.rows.each do |row|
1486
- row_cells = row.cells.map do |c|
1487
- "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
1488
- end
1489
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1490
- end
1491
- ```
1492
-
1493
- ### Console Output
1494
-
1495
- ```text
1496
- === Read Validation ===
1497
- Row 0: A1: "Format" (String), B1: "Time Value" (String)
1498
- Row 1: A2: "DateTime" (String), B2: 46204.52425925926 (Float)
1499
- Row 2: A3: "Time Only" (String), B3: 46204.385416666664 (Float)
1500
- ```
1501
-
1502
- <hr/>
1503
-
1504
- ## Cf Begins With
1505
-
1506
- Demonstrates conditional formatting highlighting cells starting with specific text.
1507
-
1508
- ### Rendered Output (LibreOffice Calc)
1509
-
1510
- <div><img src="../../test/visual/baselines/cf_begins_with/page-1.png" width="100%" alt="Preview"/></div>
1511
-
1512
- ### DSL Code
1513
-
1514
- ```ruby
1515
- # frozen_string_literal: true
1516
-
1517
- require "xlsxrb"
1518
- output_path = ARGV[0] || "cf_begins_with.xlsx"
1519
- Xlsxrb.write(output_path) do |wb|
1520
- wb.sheet("CF Begins") do |s|
1521
- s.column(0, width: 25)
1522
- s.column(1, width: 25)
1523
- s.row(["Code"])
1524
- s.row(["A-100"])
1525
- s.row(["B-200"])
1526
- s.row(["A-300"])
1527
- s.conditional_format("A2:A4", type: "beginsWith", operator: "beginsWith", text: "A", formula: 'LEFT(A2,1)="A"', fill_color: "FFFFC7CE")
1528
- end
1529
- end
1530
-
1531
- # 2. Read the generated sheet and print cell values
1532
- puts "=== Read Validation ==="
1533
- workbook = Xlsxrb.read(output_path).load
1534
- sheet = workbook.sheets.first
1535
- sheet.rows.first(5).each do |row|
1536
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1537
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1538
- end
1539
- ```
1540
-
1541
- ### Console Output
1542
-
1543
- ```text
1544
- === Read Validation ===
1545
- Row 0: A1: "Code"
1546
- Row 1: A2: "A-100"
1547
- Row 2: A3: "B-200"
1548
- Row 3: A4: "A-300"
1549
- ```
1550
-
1551
- <hr/>
1552
-
1553
- ## Cf Cell Between
1554
-
1555
- Demonstrates conditional formatting highlighting cells within a range.
1556
-
1557
- ### Rendered Output (LibreOffice Calc)
1558
-
1559
- <div><img src="../../test/visual/baselines/cf_cell_between/page-1.png" width="100%" alt="Preview"/></div>
1560
-
1561
- ### DSL Code
1562
-
1563
- ```ruby
1564
- # frozen_string_literal: true
1565
-
1566
- require "xlsxrb"
1567
- output_path = ARGV[0] || "cf_cell_between.xlsx"
1568
- Xlsxrb.write(output_path) do |wb|
1569
- wb.style("center") { |style| style.align_horizontal("center") }
1570
- wb.sheet("CF Between") do |s|
1571
- s.column(0, width: 25)
1572
- s.column(1, width: 25)
1573
- s.row(["Values"])
1574
- s.row([15], styles: "center")
1575
- s.row([25], styles: "center")
1576
- s.row([5], styles: "center")
1577
- s.conditional_format("A2:A4", type: "cellIs", operator: "between", formulas: %w[10 20], fill_color: :green)
1578
- end
1579
- end
1580
-
1581
- # 2. Read the generated sheet and print cell values
1582
- puts "=== Read Validation ==="
1583
- workbook = Xlsxrb.read(output_path).load
1584
- sheet = workbook.sheets.first
1585
- sheet.rows.first(5).each do |row|
1586
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1587
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1588
- end
1589
- ```
1590
-
1591
- ### Console Output
1592
-
1593
- ```text
1594
- === Read Validation ===
1595
- Row 0: A1: "Values"
1596
- Row 1: A2: 15
1597
- Row 2: A3: 25
1598
- Row 3: A4: 5
1599
- ```
1600
-
1601
- <hr/>
1602
-
1603
- ## Cf Cell Equal To
1604
-
1605
- Demonstrates conditional formatting highlighting cells equal to a target value.
1606
-
1607
- ### Rendered Output (LibreOffice Calc)
1608
-
1609
- <div><img src="../../test/visual/baselines/cf_cell_equal_to/page-1.png" width="100%" alt="Preview"/></div>
1610
-
1611
- ### DSL Code
1612
-
1613
- ```ruby
1614
- # frozen_string_literal: true
1615
-
1616
- require "xlsxrb"
1617
- output_path = ARGV[0] || "cf_cell_equal_to.xlsx"
1618
- Xlsxrb.write(output_path) do |wb|
1619
- wb.style("center") { |style| style.align_horizontal("center") }
1620
- wb.sheet("CF Equal") do |s|
1621
- s.column(0, width: 25)
1622
- s.column(1, width: 25)
1623
- s.row(["Values"])
1624
- s.row([10], styles: "center")
1625
- s.row([20], styles: "center")
1626
- s.row([10], styles: "center")
1627
- s.conditional_format("A2:A4", type: "cellIs", operator: "equal", formula: "10", fill_color: "FFFFC7CE")
1628
- end
1629
- end
1630
-
1631
- # 2. Read the generated sheet and print cell values
1632
- puts "=== Read Validation ==="
1633
- workbook = Xlsxrb.read(output_path).load
1634
- sheet = workbook.sheets.first
1635
- sheet.rows.first(5).each do |row|
1636
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1637
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1638
- end
1639
- ```
1640
-
1641
- ### Console Output
1642
-
1643
- ```text
1644
- === Read Validation ===
1645
- Row 0: A1: "Values"
1646
- Row 1: A2: 10
1647
- Row 2: A3: 20
1648
- Row 3: A4: 10
1649
- ```
1650
-
1651
- <hr/>
1652
-
1653
- ## Cf Cell Greater Equal
1654
-
1655
- Demonstrates conditional formatting highlighting cells greater than or equal to a threshold.
1656
-
1657
- ### Rendered Output (LibreOffice Calc)
1658
-
1659
- <div><img src="../../test/visual/baselines/cf_cell_greater_equal/page-1.png" width="100%" alt="Preview"/></div>
1660
-
1661
- ### DSL Code
1662
-
1663
- ```ruby
1664
- # frozen_string_literal: true
1665
-
1666
- require "xlsxrb"
1667
- output_path = ARGV[0] || "cf_cell_greater_equal.xlsx"
1668
- Xlsxrb.write(output_path) do |wb|
1669
- wb.style("center") { |style| style.align_horizontal("center") }
1670
- wb.sheet("CF Greater Equal") do |s|
1671
- s.column(0, width: 25)
1672
- s.column(1, width: 25)
1673
- s.row(["Values"])
1674
- s.row([10], styles: "center")
1675
- s.row([50], styles: "center")
1676
- s.row([100], styles: "center")
1677
- s.conditional_format("A2:A4", type: "cellIs", operator: "greaterThanOrEqual", formula: "50", fill_color: "FFFFC7CE")
1678
- end
1679
- end
1680
-
1681
- # 2. Read the generated sheet and print cell values
1682
- puts "=== Read Validation ==="
1683
- workbook = Xlsxrb.read(output_path).load
1684
- sheet = workbook.sheets.first
1685
- sheet.rows.first(5).each do |row|
1686
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1687
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1688
- end
1689
- ```
1690
-
1691
- ### Console Output
1692
-
1693
- ```text
1694
- === Read Validation ===
1695
- Row 0: A1: "Values"
1696
- Row 1: A2: 10
1697
- Row 2: A3: 50
1698
- Row 3: A4: 100
1699
- ```
1700
-
1701
- <hr/>
1702
-
1703
- ## Cf Cell Greater Than
1704
-
1705
- Demonstrates conditional formatting highlighting cells greater than a threshold.
1706
-
1707
- ### Rendered Output (LibreOffice Calc)
1708
-
1709
- <div><img src="../../test/visual/baselines/cf_cell_greater_than/page-1.png" width="100%" alt="Preview"/></div>
1710
-
1711
- ### DSL Code
1712
-
1713
- ```ruby
1714
- # frozen_string_literal: true
1715
-
1716
- require "xlsxrb"
1717
- output_path = ARGV[0] || "cf_cell_greater_than.xlsx"
1718
- Xlsxrb.write(output_path) do |wb|
1719
- wb.style("center") { |style| style.align_horizontal("center") }
1720
- wb.sheet("CF Greater") do |s|
1721
- s.column(0, width: 25)
1722
- s.column(1, width: 25)
1723
- s.row(["Values"])
1724
- s.row([25], styles: "center")
1725
- s.row([75], styles: "center")
1726
- s.row([10], styles: "center")
1727
- s.conditional_format("A2:A4", type: "cellIs", operator: "greaterThan", formula: "50", fill_color: "FFFFC7CE")
1728
- end
1729
- end
1730
-
1731
- # 2. Read the generated sheet and print cell values
1732
- puts "=== Read Validation ==="
1733
- workbook = Xlsxrb.read(output_path).load
1734
- sheet = workbook.sheets.first
1735
- sheet.rows.first(5).each do |row|
1736
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1737
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1738
- end
1739
- ```
1740
-
1741
- ### Console Output
1742
-
1743
- ```text
1744
- === Read Validation ===
1745
- Row 0: A1: "Values"
1746
- Row 1: A2: 25
1747
- Row 2: A3: 75
1748
- Row 3: A4: 10
1749
- ```
1750
-
1751
- <hr/>
1752
-
1753
- ## Cf Cell Less Than
1754
-
1755
- Demonstrates conditional formatting highlighting cells less than a threshold.
1756
-
1757
- ### Rendered Output (LibreOffice Calc)
1758
-
1759
- <div><img src="../../test/visual/baselines/cf_cell_less_than/page-1.png" width="100%" alt="Preview"/></div>
1760
-
1761
- ### DSL Code
1762
-
1763
- ```ruby
1764
- # frozen_string_literal: true
1765
-
1766
- require "xlsxrb"
1767
- output_path = ARGV[0] || "cf_cell_less_than.xlsx"
1768
- Xlsxrb.write(output_path) do |wb|
1769
- wb.style("center") { |style| style.align_horizontal("center") }
1770
- wb.sheet("CF Less") do |s|
1771
- s.column(0, width: 25)
1772
- s.column(1, width: 25)
1773
- s.row(["Values"])
1774
- s.row([25], styles: "center")
1775
- s.row([75], styles: "center")
1776
- s.row([10], styles: "center")
1777
- s.conditional_format("A2:A4", type: "cellIs", operator: "lessThan", formula: "20", fill_color: "FFFFC7CE")
1778
- end
1779
- end
1780
-
1781
- # 2. Read the generated sheet and print cell values
1782
- puts "=== Read Validation ==="
1783
- workbook = Xlsxrb.read(output_path).load
1784
- sheet = workbook.sheets.first
1785
- sheet.rows.first(5).each do |row|
1786
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1787
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1788
- end
1789
- ```
1790
-
1791
- ### Console Output
1792
-
1793
- ```text
1794
- === Read Validation ===
1795
- Row 0: A1: "Values"
1796
- Row 1: A2: 25
1797
- Row 2: A3: 75
1798
- Row 3: A4: 10
1799
- ```
1800
-
1801
- <hr/>
1802
-
1803
- ## Cf Color Scale
1804
-
1805
- Demonstrates color scale/heatmap conditional formatting.
1806
-
1807
- ### Rendered Output (LibreOffice Calc)
1808
-
1809
- <div><img src="../../test/visual/baselines/cf_color_scale/page-1.png" width="100%" alt="Preview"/></div>
1810
-
1811
- ### DSL Code
1812
-
1813
- ```ruby
1814
- # frozen_string_literal: true
1815
-
1816
- require "xlsxrb"
1817
- output_path = ARGV[0] || "cf_color_scale.xlsx"
1818
- Xlsxrb.write(output_path) do |wb|
1819
- wb.style("center") { |style| style.align_horizontal("center") }
1820
- wb.sheet("Colors") do |s|
1821
- s.column(0, width: 25)
1822
- s.column(1, width: 25)
1823
- s.row([10], styles: "center")
1824
- s.row([50], styles: "center")
1825
- s.row([90], styles: "center")
1826
- s.conditional_format("A1:A3", type: :colorScale, priority: 1)
1827
- end
1828
- end
1829
-
1830
- # 2. Read the generated sheet and print cell values
1831
- puts "=== Read Validation ==="
1832
- workbook = Xlsxrb.read(output_path).load
1833
- sheet = workbook.sheets.first
1834
- sheet.rows.first(5).each do |row|
1835
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1836
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1837
- end
1838
- ```
1839
-
1840
- ### Console Output
1841
-
1842
- ```text
1843
- === Read Validation ===
1844
- Row 0: A1: 10
1845
- Row 1: A2: 50
1846
- Row 2: A3: 90
1847
- ```
1848
-
1849
- <hr/>
1850
-
1851
- ## Cf Contains Text
1852
-
1853
- Demonstrates conditional formatting highlighting cells containing specific text.
1854
-
1855
- ### Rendered Output (LibreOffice Calc)
1856
-
1857
- <div><img src="../../test/visual/baselines/cf_contains_text/page-1.png" width="100%" alt="Preview"/></div>
1858
-
1859
- ### DSL Code
1860
-
1861
- ```ruby
1862
- # frozen_string_literal: true
1863
-
1864
- require "xlsxrb"
1865
- output_path = ARGV[0] || "cf_contains_text.xlsx"
1866
- Xlsxrb.write(output_path) do |wb|
1867
- wb.sheet("CF Contains") do |s|
1868
- s.column(0, width: 25)
1869
- s.column(1, width: 25)
1870
- s.row(["Status"])
1871
- s.row(["Error"])
1872
- s.row(["Success"])
1873
- s.row(["Pending"])
1874
- s.conditional_format("A2:A4", type: "containsText", operator: "containsText", text: "Error", formula: 'NOT(ISERROR(SEARCH("Error",A2)))', fill_color: :red)
1875
- end
1876
- end
1877
-
1878
- # 2. Read the generated sheet and print cell values
1879
- puts "=== Read Validation ==="
1880
- workbook = Xlsxrb.read(output_path).load
1881
- sheet = workbook.sheets.first
1882
- sheet.rows.first(5).each do |row|
1883
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1884
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1885
- end
1886
- ```
1887
-
1888
- ### Console Output
1889
-
1890
- ```text
1891
- === Read Validation ===
1892
- Row 0: A1: "Status"
1893
- Row 1: A2: "Error"
1894
- Row 2: A3: "Success"
1895
- Row 3: A4: "Pending"
1896
- ```
1897
-
1898
- <hr/>
1899
-
1900
- ## Cf Data Bar
1901
-
1902
- Demonstrates data bar visual conditional formatting indicators.
1903
-
1904
- ### Rendered Output (LibreOffice Calc)
1905
-
1906
- <div><img src="../../test/visual/baselines/cf_data_bar/page-1.png" width="100%" alt="Preview"/></div>
1907
-
1908
- ### DSL Code
1909
-
1910
- ```ruby
1911
- # frozen_string_literal: true
1912
-
1913
- require "xlsxrb"
1914
- output_path = ARGV[0] || "cf_data_bar.xlsx"
1915
- Xlsxrb.write(output_path) do |wb|
1916
- wb.style("center") { |style| style.align_horizontal("center") }
1917
- wb.sheet("Data Bars") do |s|
1918
- s.column(0, width: 25)
1919
- s.column(1, width: 25)
1920
- s.row([20], styles: "center")
1921
- s.row([60], styles: "center")
1922
- s.row([100], styles: "center")
1923
- s.conditional_format("A1:A3", type: :dataBar, priority: 1, color: "FF0070C0")
1924
- end
1925
- end
1926
-
1927
- # 2. Read the generated sheet and print cell values
1928
- puts "=== Read Validation ==="
1929
- workbook = Xlsxrb.read(output_path).load
1930
- sheet = workbook.sheets.first
1931
- sheet.rows.first(5).each do |row|
1932
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1933
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1934
- end
1935
- ```
1936
-
1937
- ### Console Output
1938
-
1939
- ```text
1940
- === Read Validation ===
1941
- Row 0: A1: 20
1942
- Row 1: A2: 60
1943
- Row 2: A3: 100
1944
- ```
1945
-
1946
- <hr/>
1947
-
1948
- ## Cf Ends With
1949
-
1950
- Demonstrates conditional formatting highlighting cells ending with specific text.
1951
-
1952
- ### Rendered Output (LibreOffice Calc)
1953
-
1954
- <div><img src="../../test/visual/baselines/cf_ends_with/page-1.png" width="100%" alt="Preview"/></div>
1955
-
1956
- ### DSL Code
1957
-
1958
- ```ruby
1959
- # frozen_string_literal: true
1960
-
1961
- require "xlsxrb"
1962
- output_path = ARGV[0] || "cf_ends_with.xlsx"
1963
- Xlsxrb.write(output_path) do |wb|
1964
- wb.sheet("CF Ends") do |s|
1965
- s.column(0, width: 25)
1966
- s.column(1, width: 25)
1967
- s.row(["Code"])
1968
- s.row(["100-Z"])
1969
- s.row(["200-Y"])
1970
- s.row(["300-Z"])
1971
- s.conditional_format("A2:A4", type: "endsWith", operator: "endsWith", text: "Z", formula: 'RIGHT(A2,1)="Z"', fill_color: "FFFFC7CE")
1972
- end
1973
- end
1974
-
1975
- # 2. Read the generated sheet and print cell values
1976
- puts "=== Read Validation ==="
1977
- workbook = Xlsxrb.read(output_path).load
1978
- sheet = workbook.sheets.first
1979
- sheet.rows.first(5).each do |row|
1980
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
1981
- puts "Row #{row.index}: #{row_cells.join(", ")}"
1982
- end
1983
- ```
1984
-
1985
- ### Console Output
1986
-
1987
- ```text
1988
- === Read Validation ===
1989
- Row 0: A1: "Code"
1990
- Row 1: A2: "100-Z"
1991
- Row 2: A3: "200-Y"
1992
- Row 3: A4: "300-Z"
1993
- ```
1994
-
1995
- <hr/>
1996
-
1997
- ## Cf Expression Formula
1998
-
1999
- Demonstrates conditional formatting using a custom formula expression.
2000
-
2001
- ### Rendered Output (LibreOffice Calc)
2002
-
2003
- <div><img src="../../test/visual/baselines/cf_expression_formula/page-1.png" width="100%" alt="Preview"/></div>
2004
-
2005
- ### DSL Code
2006
-
2007
- ```ruby
2008
- # frozen_string_literal: true
2009
-
2010
- require "xlsxrb"
2011
- output_path = ARGV[0] || "cf_expression_formula.xlsx"
2012
- Xlsxrb.write(output_path) do |wb|
2013
- wb.style("center") { |style| style.align_horizontal("center") }
2014
- wb.sheet("CF Expression") do |s|
2015
- s.column(0, width: 25)
2016
- s.column(1, width: 25)
2017
- s.row(["Values"])
2018
- s.row([10], styles: "center")
2019
- s.row([20], styles: "center")
2020
- s.row([30], styles: "center")
2021
- s.row([100], styles: "center") # Average is 40. 100 is above average.
2022
- s.conditional_format("A2:A5", type: "expression", formula: "A2>AVERAGE($A$2:$A$5)", fill_color: "FFFFC7CE")
2023
- end
2024
- end
2025
-
2026
- # 2. Read the generated sheet and print cell values
2027
- puts "=== Read Validation ==="
2028
- workbook = Xlsxrb.read(output_path).load
2029
- sheet = workbook.sheets.first
2030
- sheet.rows.first(5).each do |row|
2031
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
2032
- puts "Row #{row.index}: #{row_cells.join(", ")}"
2033
- end
2034
- ```
2035
-
2036
- ### Console Output
2037
-
2038
- ```text
2039
- === Read Validation ===
2040
- Row 0: A1: "Values"
2041
- Row 1: A2: 10
2042
- Row 2: A3: 20
2043
- Row 3: A4: 30
2044
- Row 4: A5: 100
2045
- ```
2046
-
2047
- <hr/>
2048
-
2049
- ## Cf Icon Set
2050
-
2051
- Demonstrates icon set indicators (red/yellow/green arrows).
2052
-
2053
- ### Rendered Output (LibreOffice Calc)
2054
-
2055
- <div><img src="../../test/visual/baselines/cf_icon_set/page-1.png" width="100%" alt="Preview"/></div>
2056
-
2057
- ### DSL Code
2058
-
2059
- ```ruby
2060
- # frozen_string_literal: true
2061
-
2062
- require "xlsxrb"
2063
- output_path = ARGV[0] || "cf_icon_set.xlsx"
2064
- Xlsxrb.write(output_path) do |wb|
2065
- wb.style("center") { |style| style.align_horizontal("center") }
2066
- wb.sheet("Icons") do |s|
2067
- s.column(0, width: 25)
2068
- s.column(1, width: 25)
2069
- s.row([25], styles: "center")
2070
- s.row([50], styles: "center")
2071
- s.row([75], styles: "center")
2072
- s.conditional_format("A1:A3", type: :iconSet, icon_style: "3Arrows", priority: 1)
2073
- end
2074
- end
2075
-
2076
- # 2. Read the generated sheet and print cell values
2077
- puts "=== Read Validation ==="
2078
- workbook = Xlsxrb.read(output_path).load
2079
- sheet = workbook.sheets.first
2080
- sheet.rows.first(5).each do |row|
2081
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
2082
- puts "Row #{row.index}: #{row_cells.join(", ")}"
2083
- end
2084
- ```
2085
-
2086
- ### Console Output
2087
-
2088
- ```text
2089
- === Read Validation ===
2090
- Row 0: A1: 25
2091
- Row 1: A2: 50
2092
- Row 2: A3: 75
2093
- ```
2094
-
2095
- <hr/>
2096
-
2097
- ## Chart Area
2098
-
2099
- Demonstrates embedding a standard 2D Area Chart.
2100
-
2101
- ### Rendered Output (LibreOffice Calc)
2102
-
2103
- <div><img src="../../test/visual/baselines/chart_area/page-1.png" width="100%" alt="Preview"/></div>
2104
-
2105
- ### DSL Code
2106
-
2107
- ```ruby
2108
- # frozen_string_literal: true
2109
-
2110
- require "xlsxrb"
2111
- output_path = ARGV[0] || "chart_area.xlsx"
2112
- Xlsxrb.write(output_path) do |wb|
2113
- wb.sheet("Data") do |s|
2114
- s.sheet_properties(:fit_to_page, true)
2115
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2116
- s.column(0, width: 25)
2117
- s.column(1, width: 25)
2118
- s.row(%w[Day Value])
2119
- s.row(["Mon", 10])
2120
- s.row(["Tue", 15])
2121
- s.chart(
2122
- type: :area,
2123
- title: "Daily Area",
2124
- from_col: 3, from_row: 0, to_col: 8, to_row: 12,
2125
- series: [{ cat_ref: "Data!$A$2:$A$3", val_ref: "Data!$B$2:$B$3", fill_color: "4F81BD" }]
2126
- )
2127
- end
2128
- end
2129
-
2130
- # 2. Read the generated sheet and print the chart count
2131
- puts "=== Read Validation ==="
2132
- workbook = Xlsxrb.read(output_path).load
2133
- sheet = workbook.sheets.first
2134
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2135
- ```
2136
-
2137
- ### Console Output
2138
-
2139
- ```text
2140
- === Read Validation ===
2141
- Sheet 'Data' has 0 chart(s)
2142
- ```
2143
-
2144
- <hr/>
2145
-
2146
- ## Chart Area Stacked
2147
-
2148
- Demonstrates embedding a stacked 2D Area Chart.
2149
-
2150
- ### Rendered Output (LibreOffice Calc)
2151
-
2152
- <div><img src="../../test/visual/baselines/chart_area_stacked/page-1.png" width="100%" alt="Preview"/></div>
2153
-
2154
- ### DSL Code
2155
-
2156
- ```ruby
2157
- # frozen_string_literal: true
2158
-
2159
- require "xlsxrb"
2160
- output_path = ARGV[0] || "chart_area_stacked.xlsx"
2161
- Xlsxrb.write(output_path) do |wb|
2162
- wb.sheet("Data") do |s|
2163
- s.column(0, width: 25)
2164
- s.column(1, width: 25)
2165
- s.row(["Year", "Sales A", "Sales B"])
2166
- s.row([2024, 100, 150])
2167
- s.row([2025, 120, 180])
2168
- s.row([2026, 140, 210])
2169
- s.sheet_properties(:fit_to_page, true)
2170
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2171
- s.chart(
2172
- type: :area,
2173
- grouping: :stacked,
2174
- title: "Stacked Area Chart",
2175
- from_col: 0, from_row: 5, to_col: 6, to_row: 17,
2176
- series: [
2177
- { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$B$2:$B$4", name: "'Data'!$B$1", fill_color: "4F81BD" },
2178
- { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$C$2:$C$4", name: "'Data'!$C$1", fill_color: "C0504D" }
2179
- ]
2180
- )
2181
- end
2182
- end
2183
-
2184
- # 2. Read the generated sheet and print the chart count
2185
- puts "=== Read Validation ==="
2186
- workbook = Xlsxrb.read(output_path).load
2187
- sheet = workbook.sheets.first
2188
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2189
- ```
2190
-
2191
- ### Console Output
2192
-
2193
- ```text
2194
- === Read Validation ===
2195
- Sheet 'Data' has 0 chart(s)
2196
- ```
2197
-
2198
- <hr/>
2199
-
2200
- ## Chart Bar
2201
-
2202
- Demonstrates embedding a standard 2D Bar Chart referencing worksheet cell ranges.
2203
-
2204
- ### Rendered Output (LibreOffice Calc)
2205
-
2206
- <div><img src="../../test/visual/baselines/chart_bar/page-1.png" width="100%" alt="Preview"/></div>
2207
-
2208
- ### DSL Code
2209
-
2210
- ```ruby
2211
- # frozen_string_literal: true
2212
-
2213
- require "xlsxrb"
2214
-
2215
- output_path = ARGV[0] || "chart_bar.xlsx"
2216
-
2217
- Xlsxrb.write(output_path) do |wb|
2218
- wb.sheet("Sales Data") do |s|
2219
- s.sheet_properties(:fit_to_page, true)
2220
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2221
- s.column(0, width: 25)
2222
- s.column(1, width: 25)
2223
- s.row(%w[Month Value])
2224
- s.row(["Jan", 100])
2225
- s.row(["Feb", 200])
2226
-
2227
- s.chart(
2228
- type: :bar,
2229
- title: "Monthly Sales",
2230
- from_col: 3,
2231
- from_row: 0,
2232
- to_col: 8,
2233
- to_row: 12,
2234
- series: [
2235
- { cat_ref: "'Sales Data'!$A$2:$A$3", val_ref: "'Sales Data'!$B$2:$B$3", fill_color: "4F81BD" }
2236
- ]
2237
- )
2238
- end
2239
- end
2240
-
2241
- # 2. Read the generated sheet and print the chart count
2242
- puts "=== Read Validation ==="
2243
- workbook = Xlsxrb.read(output_path).load
2244
- sheet = workbook.sheets.first
2245
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2246
- ```
2247
-
2248
- ### Console Output
2249
-
2250
- ```text
2251
- === Read Validation ===
2252
- Sheet 'Sales Data' has 0 chart(s)
2253
- ```
2254
-
2255
- <hr/>
2256
-
2257
- ## Chart Bar Percent Stacked
2258
-
2259
- Demonstrates embedding a 100% stacked 2D Bar Chart.
2260
-
2261
- ### Rendered Output (LibreOffice Calc)
2262
-
2263
- <div><img src="../../test/visual/baselines/chart_bar_percent_stacked/page-1.png" width="100%" alt="Preview"/></div>
2264
-
2265
- ### DSL Code
2266
-
2267
- ```ruby
2268
- # frozen_string_literal: true
2269
-
2270
- require "xlsxrb"
2271
- output_path = ARGV[0] || "chart_bar_percent_stacked.xlsx"
2272
- Xlsxrb.write(output_path) do |wb|
2273
- wb.sheet("Data") do |s|
2274
- s.column(0, width: 25)
2275
- s.column(1, width: 25)
2276
- s.row(["Year", "Sales A", "Sales B"])
2277
- s.row([2024, 100, 150])
2278
- s.row([2025, 120, 180])
2279
- s.row([2026, 140, 210])
2280
- s.sheet_properties(:fit_to_page, true)
2281
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2282
- s.chart(
2283
- type: :bar,
2284
- grouping: :percentStacked,
2285
- title: "100% Stacked Bar Chart",
2286
- from_col: 0, from_row: 5, to_col: 6, to_row: 17,
2287
- series: [
2288
- { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$B$2:$B$4", name: "'Data'!$B$1", fill_color: "4F81BD" },
2289
- { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$C$2:$C$4", name: "'Data'!$C$1", fill_color: "C0504D" }
2290
- ]
2291
- )
2292
- end
2293
- end
2294
-
2295
- # 2. Read the generated sheet and print the chart count
2296
- puts "=== Read Validation ==="
2297
- workbook = Xlsxrb.read(output_path).load
2298
- sheet = workbook.sheets.first
2299
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2300
- ```
2301
-
2302
- ### Console Output
2303
-
2304
- ```text
2305
- === Read Validation ===
2306
- Sheet 'Data' has 0 chart(s)
2307
- ```
2308
-
2309
- <hr/>
2310
-
2311
- ## Chart Bar Stacked
2312
-
2313
- Demonstrates embedding a stacked 2D Bar Chart.
2314
-
2315
- ### Rendered Output (LibreOffice Calc)
2316
-
2317
- <div><img src="../../test/visual/baselines/chart_bar_stacked/page-1.png" width="100%" alt="Preview"/></div>
2318
-
2319
- ### DSL Code
2320
-
2321
- ```ruby
2322
- # frozen_string_literal: true
2323
-
2324
- require "xlsxrb"
2325
- output_path = ARGV[0] || "chart_bar_stacked.xlsx"
2326
- Xlsxrb.write(output_path) do |wb|
2327
- wb.sheet("Data") do |s|
2328
- s.column(0, width: 25)
2329
- s.column(1, width: 25)
2330
- s.row(["Year", "Sales A", "Sales B"])
2331
- s.row([2024, 100, 150])
2332
- s.row([2025, 120, 180])
2333
- s.row([2026, 140, 210])
2334
- s.sheet_properties(:fit_to_page, true)
2335
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2336
- s.chart(
2337
- type: :bar,
2338
- grouping: :stacked,
2339
- title: "Stacked Bar Chart",
2340
- from_col: 0, from_row: 5, to_col: 6, to_row: 17,
2341
- series: [
2342
- { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$B$2:$B$4", name: "'Data'!$B$1", fill_color: "4F81BD" },
2343
- { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$C$2:$C$4", name: "'Data'!$C$1", fill_color: "C0504D" }
2344
- ]
2345
- )
2346
- end
2347
- end
2348
-
2349
- # 2. Read the generated sheet and print the chart count
2350
- puts "=== Read Validation ==="
2351
- workbook = Xlsxrb.read(output_path).load
2352
- sheet = workbook.sheets.first
2353
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2354
- ```
2355
-
2356
- ### Console Output
2357
-
2358
- ```text
2359
- === Read Validation ===
2360
- Sheet 'Data' has 0 chart(s)
2361
- ```
2362
-
2363
- <hr/>
2364
-
2365
- ## Chart Doughnut
2366
-
2367
- Demonstrates embedding a standard 2D Doughnut Chart.
2368
-
2369
- ### Rendered Output (LibreOffice Calc)
2370
-
2371
- <div><img src="../../test/visual/baselines/chart_doughnut/page-1.png" width="100%" alt="Preview"/></div>
2372
-
2373
- ### DSL Code
2374
-
2375
- ```ruby
2376
- # frozen_string_literal: true
2377
-
2378
- require "xlsxrb"
2379
- output_path = ARGV[0] || "chart_doughnut.xlsx"
2380
- Xlsxrb.write(output_path) do |wb|
2381
- wb.sheet("Data") do |s|
2382
- s.sheet_properties(:fit_to_page, true)
2383
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2384
- s.column(0, width: 25)
2385
- s.column(1, width: 25)
2386
- s.row(%w[Label Percent])
2387
- s.row(["A", 40])
2388
- s.row(["B", 60])
2389
- s.chart(
2390
- type: :doughnut,
2391
- title: "Ratio",
2392
- from_col: 3, from_row: 0, to_col: 8, to_row: 12,
2393
- series: [{
2394
- cat_ref: "Data!$A$2:$A$3",
2395
- val_ref: "Data!$B$2:$B$3",
2396
- data_points: [
2397
- { idx: 0, fill_color: "4F81BD" },
2398
- { idx: 1, fill_color: "C0504D" }
2399
- ]
2400
- }]
2401
- )
2402
- end
2403
- end
2404
-
2405
- # 2. Read the generated sheet and print the chart count
2406
- puts "=== Read Validation ==="
2407
- workbook = Xlsxrb.read(output_path).load
2408
- sheet = workbook.sheets.first
2409
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2410
- ```
2411
-
2412
- ### Console Output
2413
-
2414
- ```text
2415
- === Read Validation ===
2416
- Sheet 'Data' has 0 chart(s)
2417
- ```
2418
-
2419
- <hr/>
2420
-
2421
- ## Chart Line
2422
-
2423
- Demonstrates embedding a standard 2D Line Chart.
2424
-
2425
- ### Rendered Output (LibreOffice Calc)
2426
-
2427
- <div><img src="../../test/visual/baselines/chart_line/page-1.png" width="100%" alt="Preview"/></div>
2428
-
2429
- ### DSL Code
2430
-
2431
- ```ruby
2432
- # frozen_string_literal: true
2433
-
2434
- require "xlsxrb"
2435
- output_path = ARGV[0] || "chart_line.xlsx"
2436
- Xlsxrb.write(output_path) do |wb|
2437
- wb.sheet("Data") do |s|
2438
- s.sheet_properties(:fit_to_page, true)
2439
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2440
- s.column(0, width: 25)
2441
- s.column(1, width: 25)
2442
- s.row(%w[Day Value])
2443
- s.row(["Mon", 10])
2444
- s.row(["Tue", 15])
2445
- s.row(["Wed", 12])
2446
- s.chart(
2447
- type: :line,
2448
- title: "Daily Value",
2449
- from_col: 3, from_row: 0, to_col: 8, to_row: 12,
2450
- series: [{ cat_ref: "Data!$A$2:$A$4", val_ref: "Data!$B$2:$B$4", line_color: "4F81BD", line_width: 2.0 }]
2451
- )
2452
- end
2453
- end
2454
-
2455
- # 2. Read the generated sheet and print the chart count
2456
- puts "=== Read Validation ==="
2457
- workbook = Xlsxrb.read(output_path).load
2458
- sheet = workbook.sheets.first
2459
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2460
- ```
2461
-
2462
- ### Console Output
2463
-
2464
- ```text
2465
- === Read Validation ===
2466
- Sheet 'Data' has 0 chart(s)
2467
- ```
2468
-
2469
- <hr/>
2470
-
2471
- ## Chart Line Stacked
2472
-
2473
- Demonstrates embedding a stacked 2D Line Chart.
2474
-
2475
- ### Rendered Output (LibreOffice Calc)
2476
-
2477
- <div><img src="../../test/visual/baselines/chart_line_stacked/page-1.png" width="100%" alt="Preview"/></div>
2478
-
2479
- ### DSL Code
2480
-
2481
- ```ruby
2482
- # frozen_string_literal: true
2483
-
2484
- require "xlsxrb"
2485
- output_path = ARGV[0] || "chart_line_stacked.xlsx"
2486
- Xlsxrb.write(output_path) do |wb|
2487
- wb.sheet("Data") do |s|
2488
- s.column(0, width: 25)
2489
- s.column(1, width: 25)
2490
- s.row(["Year", "Sales A", "Sales B"])
2491
- s.row([2024, 100, 150])
2492
- s.row([2025, 120, 180])
2493
- s.row([2026, 140, 210])
2494
- s.sheet_properties(:fit_to_page, true)
2495
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2496
- s.chart(
2497
- type: :line,
2498
- grouping: :stacked,
2499
- title: "Stacked Line Chart",
2500
- from_col: 0, from_row: 5, to_col: 6, to_row: 17,
2501
- series: [
2502
- { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$B$2:$B$4", name: "'Data'!$B$1", line_color: "4F81BD", line_width: 2.0 },
2503
- { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$C$2:$C$4", name: "'Data'!$C$1", line_color: "C0504D", line_width: 2.0 }
2504
- ]
2505
- )
2506
- end
2507
- end
2508
-
2509
- # 2. Read the generated sheet and print the chart count
2510
- puts "=== Read Validation ==="
2511
- workbook = Xlsxrb.read(output_path).load
2512
- sheet = workbook.sheets.first
2513
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2514
- ```
2515
-
2516
- ### Console Output
2517
-
2518
- ```text
2519
- === Read Validation ===
2520
- Sheet 'Data' has 0 chart(s)
2521
- ```
2522
-
2523
- <hr/>
2524
-
2525
- ## Chart Pie
2526
-
2527
- Demonstrates embedding a standard 2D Pie Chart.
2528
-
2529
- ### Rendered Output (LibreOffice Calc)
2530
-
2531
- <div><img src="../../test/visual/baselines/chart_pie/page-1.png" width="100%" alt="Preview"/></div>
2532
-
2533
- ### DSL Code
2534
-
2535
- ```ruby
2536
- # frozen_string_literal: true
2537
-
2538
- require "xlsxrb"
2539
- output_path = ARGV[0] || "chart_pie.xlsx"
2540
- Xlsxrb.write(output_path) do |wb|
2541
- wb.sheet("Data") do |s|
2542
- s.sheet_properties(:fit_to_page, true)
2543
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2544
- s.column(0, width: 25)
2545
- s.column(1, width: 25)
2546
- s.row(%w[Label Percent])
2547
- s.row(["Yes", 70])
2548
- s.row(["No", 30])
2549
- s.chart(
2550
- type: :pie,
2551
- title: "Responses",
2552
- from_col: 3, from_row: 0, to_col: 8, to_row: 12,
2553
- series: [{
2554
- cat_ref: "Data!$A$2:$A$3",
2555
- val_ref: "Data!$B$2:$B$3",
2556
- data_points: [
2557
- { idx: 0, fill_color: "4F81BD" },
2558
- { idx: 1, fill_color: "C0504D" }
2559
- ]
2560
- }]
2561
- )
2562
- end
2563
- end
2564
-
2565
- # 2. Read the generated sheet and print the chart count
2566
- puts "=== Read Validation ==="
2567
- workbook = Xlsxrb.read(output_path).load
2568
- sheet = workbook.sheets.first
2569
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2570
- ```
2571
-
2572
- ### Console Output
2573
-
2574
- ```text
2575
- === Read Validation ===
2576
- Sheet 'Data' has 0 chart(s)
2577
- ```
2578
-
2579
- <hr/>
2580
-
2581
- ## Chart Radar
2582
-
2583
- Demonstrates embedding a standard 2D Radar Chart.
2584
-
2585
- ### Rendered Output (LibreOffice Calc)
2586
-
2587
- <div><img src="../../test/visual/baselines/chart_radar/page-1.png" width="100%" alt="Preview"/></div>
2588
-
2589
- ### DSL Code
2590
-
2591
- ```ruby
2592
- # frozen_string_literal: true
2593
-
2594
- require "xlsxrb"
2595
- output_path = ARGV[0] || "chart_radar.xlsx"
2596
- Xlsxrb.write(output_path) do |wb|
2597
- wb.sheet("Data") do |s|
2598
- s.sheet_properties(:fit_to_page, true)
2599
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2600
- s.column(0, width: 25)
2601
- s.column(1, width: 25)
2602
- s.row(%w[Stat Value])
2603
- s.row(["Atk", 80])
2604
- s.row(["Def", 60])
2605
- s.chart(
2606
- type: :radar,
2607
- title: "Stats",
2608
- from_col: 3, from_row: 0, to_col: 8, to_row: 12,
2609
- series: [{ cat_ref: "Data!$A$2:$A$3", val_ref: "Data!$B$2:$B$3", line_color: "4F81BD", line_width: 2.0 }]
2610
- )
2611
- end
2612
- end
2613
-
2614
- # 2. Read the generated sheet and print the chart count
2615
- puts "=== Read Validation ==="
2616
- workbook = Xlsxrb.read(output_path).load
2617
- sheet = workbook.sheets.first
2618
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2619
- ```
2620
-
2621
- ### Console Output
2622
-
2623
- ```text
2624
- === Read Validation ===
2625
- Sheet 'Data' has 0 chart(s)
2626
- ```
2627
-
2628
- <hr/>
2629
-
2630
- ## Chart Scatter
2631
-
2632
- Demonstrates embedding a standard 2D Scatter Plot.
2633
-
2634
- ### Rendered Output (LibreOffice Calc)
2635
-
2636
- <div><img src="../../test/visual/baselines/chart_scatter/page-1.png" width="100%" alt="Preview"/></div>
2637
-
2638
- ### DSL Code
2639
-
2640
- ```ruby
2641
- # frozen_string_literal: true
2642
-
2643
- require "xlsxrb"
2644
- output_path = ARGV[0] || "chart_scatter.xlsx"
2645
- Xlsxrb.write(output_path) do |wb|
2646
- wb.sheet("Data") do |s|
2647
- s.sheet_properties(:fit_to_page, true)
2648
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2649
- s.column(0, width: 25)
2650
- s.column(1, width: 25)
2651
- s.row(%w[X Y])
2652
- s.row([1, 10])
2653
- s.row([2, 15])
2654
- s.chart(
2655
- type: :scatter,
2656
- title: "Scatter Plot",
2657
- from_col: 3, from_row: 0, to_col: 8, to_row: 12,
2658
- series: [{ cat_ref: "Data!$A$2:$A$3", val_ref: "Data!$B$2:$B$3", line_color: "4F81BD", line_width: 2.0 }]
2659
- )
2660
- end
2661
- end
2662
-
2663
- # 2. Read the generated sheet and print the chart count
2664
- puts "=== Read Validation ==="
2665
- workbook = Xlsxrb.read(output_path).load
2666
- sheet = workbook.sheets.first
2667
- puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"
2668
- ```
2669
-
2670
- ### Console Output
2671
-
2672
- ```text
2673
- === Read Validation ===
2674
- Sheet 'Data' has 0 chart(s)
2675
- ```
2676
-
2677
- <hr/>
2678
-
2679
- ## Col Grouping
2680
-
2681
- Demonstrates outline grouping for columns.
2682
-
2683
- ### Rendered Output (LibreOffice Calc)
2684
-
2685
- <div><img src="../../test/visual/baselines/col_grouping/page-1.png" width="100%" alt="Preview"/></div>
2686
-
2687
- ### DSL Code
2688
-
2689
- ```ruby
2690
- # frozen_string_literal: true
2691
-
2692
- require "xlsxrb"
2693
- output_path = ARGV[0] || "col_grouping.xlsx"
2694
- Xlsxrb.write(output_path) do |wb|
2695
- wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
2696
- wb.sheet("Col Grouping") do |s|
2697
- s.sheet_properties(:fit_to_page, true)
2698
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
2699
- s.column(0, width: 25, outline_level: 0)
2700
- s.column(1, width: 25, outline_level: 1)
2701
- s.column(2, width: 25, outline_level: 1)
2702
- s.row(["Col A", "Col B (Grouped)", "Col C (Grouped)"], styles: %w[border border border])
2703
- end
2704
- end
2705
-
2706
- # 2. Read the generated sheet and print column dimensions
2707
- puts "=== Read Validation ==="
2708
- workbook = Xlsxrb.read(output_path).load
2709
- sheet = workbook.sheets.first
2710
- sheet.columns.each do |col|
2711
- puts "Column #{col.index}: width=#{col.width}, hidden=#{col.hidden}, outline_level=#{col.outline_level}"
2712
- end
2713
- ```
2714
-
2715
- ### Console Output
2716
-
2717
- ```text
2718
- === Read Validation ===
2719
- Column 0: width=25.0, hidden=false, outline_level=0
2720
- Column 1: width=25.0, hidden=false, outline_level=1
2721
- Column 2: width=25.0, hidden=false, outline_level=1
2722
- ```
2723
-
2724
- <hr/>
2725
-
2726
- ## Col Width Tall
2727
-
2728
- Demonstrates setting very wide column widths.
2729
-
2730
- ### Rendered Output (LibreOffice Calc)
2731
-
2732
- <div><img src="../../test/visual/baselines/col_width_tall/page-1.png" width="100%" alt="Preview"/></div>
2733
-
2734
- ### DSL Code
2735
-
2736
- ```ruby
2737
- # frozen_string_literal: true
2738
-
2739
- require "xlsxrb"
2740
- output_path = ARGV[0] || "col_width_tall.xlsx"
2741
- Xlsxrb.write(output_path) do |wb|
2742
- wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
2743
- wb.sheet("Col Width") do |s|
2744
- s.column(0, width: 50)
2745
- s.column(1, width: 10)
2746
- s.row(["Very Wide Column (Width 50)", "Normal (10)"], styles: %w[border border])
2747
- end
2748
- end
2749
-
2750
- # 2. Read the generated sheet and print column dimensions
2751
- puts "=== Read Validation ==="
2752
- workbook = Xlsxrb.read(output_path).load
2753
- sheet = workbook.sheets.first
2754
- sheet.columns.each do |col|
2755
- puts "Column #{col.index}: width=#{col.width}, hidden=#{col.hidden}, outline_level=#{col.outline_level}"
2756
- end
2757
- ```
2758
-
2759
- ### Console Output
2760
-
2761
- ```text
2762
- === Read Validation ===
2763
- Column 0: width=50.0, hidden=false, outline_level=
2764
- Column 1: width=10.0, hidden=false, outline_level=
2765
- ```
2766
-
2767
- <hr/>
2768
-
2769
- ## Col Widths
2770
-
2771
- Demonstrates setting custom column widths.
2772
-
2773
- ### Rendered Output (LibreOffice Calc)
2774
-
2775
- <div><img src="../../test/visual/baselines/col_widths/page-1.png" width="100%" alt="Preview"/></div>
2776
-
2777
- ### DSL Code
2778
-
2779
- ```ruby
2780
- # frozen_string_literal: true
2781
-
2782
- require "xlsxrb"
2783
- output_path = ARGV[0] || "col_widths.xlsx"
2784
- Xlsxrb.write(output_path) do |wb|
2785
- wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
2786
- wb.sheet("Widths") do |s|
2787
- s.column(0, width: 30)
2788
- s.column(1, width: 10)
2789
- s.row(["Wide Column A", "Narrow B"], styles: %w[border border])
2790
- end
2791
- end
2792
-
2793
- # 2. Read the generated sheet and print column dimensions
2794
- puts "=== Read Validation ==="
2795
- workbook = Xlsxrb.read(output_path).load
2796
- sheet = workbook.sheets.first
2797
- sheet.columns.each do |col|
2798
- puts "Column #{col.index}: width=#{col.width}, hidden=#{col.hidden}, outline_level=#{col.outline_level}"
2799
- end
2800
- ```
2801
-
2802
- ### Console Output
2803
-
2804
- ```text
2805
- === Read Validation ===
2806
- Column 0: width=30.0, hidden=false, outline_level=
2807
- Column 1: width=10.0, hidden=false, outline_level=
2808
- ```
2809
-
2810
- <hr/>
2811
-
2812
- ## Conditional Formatting
2813
-
2814
- Demonstrates adding conditional formatting rules that style cells automatically based on value ranges.
2815
-
2816
- ### Rendered Output (LibreOffice Calc)
2817
-
2818
- <div><img src="../../test/visual/baselines/conditional_formatting/page-1.png" width="100%" alt="Preview"/></div>
2819
-
2820
- ### DSL Code
2821
-
2822
- ```ruby
2823
- # frozen_string_literal: true
2824
-
2825
- require "xlsxrb"
2826
-
2827
- output_path = ARGV[0] || "conditional_formatting.xlsx"
2828
-
2829
- Xlsxrb.write(output_path) do |wb|
2830
- wb.style("center") { |style| style.align_horizontal("center") }
2831
- wb.sheet("Scores") do |s|
2832
- s.column(0, width: 25)
2833
- s.column(1, width: 25)
2834
- s.row([90, 45, 72, 88], styles: %w[center center center center])
2835
-
2836
- s.conditional_format("A1:D1",
2837
- type: :cell_is, operator: :greaterThan,
2838
- formula: "80", priority: 1,
2839
- fill_color: "FFFFC7CE")
2840
- end
2841
- end
2842
-
2843
- # 2. Read the generated sheet and print cell values
2844
- puts "=== Read Validation ==="
2845
- workbook = Xlsxrb.read(output_path).load
2846
- sheet = workbook.sheets.first
2847
- sheet.rows.first(5).each do |row|
2848
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
2849
- puts "Row #{row.index}: #{row_cells.join(", ")}"
2850
- end
2851
- ```
2852
-
2853
- ### Console Output
2854
-
2855
- ```text
2856
- === Read Validation ===
2857
- Row 0: A1: 90, B1: 45, C1: 72, D1: 88
2858
- ```
2859
-
2860
- <hr/>
2861
-
2862
- ## Drawing Shapes
2863
-
2864
- Visual demonstration for Drawing Shapes.
2865
-
2866
- ### Rendered Output (LibreOffice Calc)
2867
-
2868
- <div><img src="../../test/visual/baselines/drawing_shapes/page-1.png" width="100%" alt="Preview"/></div>
2869
-
2870
- <div><img src="../../test/visual/baselines/drawing_shapes/page-2.png" width="100%" alt="Preview"/></div>
2871
-
2872
- ### DSL Code
2873
-
2874
- ```ruby
2875
- # frozen_string_literal: true
2876
-
2877
- require "xlsxrb"
2878
-
2879
- output_path = ARGV[0] || "drawing_shapes.xlsx"
2880
-
2881
- Xlsxrb.write(output_path) do |wb|
2882
- wb.sheet("Shapes") do |sheet|
2883
- sheet.column(0..7, width: 15)
2884
- sheet.row(["Diagram with shapes and annotations"])
2885
- sheet.row([])
2886
- sheet.shape(preset: "rect", text: "Process Start", from_col: 1, from_row: 2, to_col: 3, to_row: 4)
2887
- sheet.shape(preset: "rightArrow", text: "Next", from_col: 4, from_row: 3, to_col: 5, to_row: 4)
2888
- sheet.shape(preset: "roundRect", text: "Processing", from_col: 6, from_row: 2, to_col: 8, to_row: 4)
2889
- end
2890
- end
2891
-
2892
- puts "=== Read Validation ==="
2893
- workbook = Xlsxrb.read(output_path).load
2894
- sheet = workbook.sheets.first
2895
- sheet.rows.each do |row|
2896
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
2897
- puts "Row #{row.index}: #{row_cells.join(", ")}"
2898
- end
2899
- ```
2900
-
2901
- ### Console Output
2902
-
2903
- ```text
2904
- === Read Validation ===
2905
- Row 0: A1: "Diagram with shapes and annotations"
2906
- Row 1:
2907
- ```
2908
-
2909
- <hr/>
2910
-
2911
- ## Embedded Images
2912
-
2913
- Demonstrates embedding raster PNG images in cell ranges.
2914
-
2915
- ### Rendered Output (LibreOffice Calc)
2916
-
2917
- <div><img src="../../test/visual/baselines/embedded_images/page-1.png" width="100%" alt="Preview"/></div>
2918
-
2919
- ### DSL Code
2920
-
2921
- ```ruby
2922
- # frozen_string_literal: true
2923
-
2924
- require "xlsxrb"
2925
- output_path = ARGV[0] || "embedded_images.xlsx"
2926
-
2927
- require "zlib"
2928
-
2929
- def make_png(width, height, red, green, blue)
2930
- png = "\x89PNG\r\n\x1a\n".dup.force_encoding("BINARY")
2931
- ihdr_data = [width, height, 8, 2, 0, 0, 0].pack("N2C5")
2932
- ihdr_chunk = "IHDR".dup.force_encoding("BINARY") + ihdr_data
2933
- ihdr_crc = Zlib.crc32(ihdr_chunk)
2934
- png << [ihdr_data.bytesize].pack("N") << ihdr_chunk << [ihdr_crc].pack("N")
2935
- raw_data = Array.new(height) { "\x00".dup.force_encoding("BINARY") + ([red, green, blue].pack("C3") * width) }.join
2936
- compressed = Zlib.deflate(raw_data)
2937
- idat_chunk = "IDAT".dup.force_encoding("BINARY") + compressed
2938
- idat_crc = Zlib.crc32(idat_chunk)
2939
- png << [compressed.bytesize].pack("N") << idat_chunk << [idat_crc].pack("N")
2940
- iend_chunk = "IEND".dup.force_encoding("BINARY")
2941
- iend_crc = Zlib.crc32(iend_chunk)
2942
- png << [0].pack("N") << iend_chunk << [iend_crc].pack("N")
2943
- png
2944
- end
2945
-
2946
- dummy_png = make_png(100, 100, 255, 0, 0)
2947
-
2948
- Xlsxrb.write(output_path) do |wb|
2949
- wb.style("center") { |st| st.align_horizontal(:center) }
2950
- wb.sheet("Images") do |s|
2951
- s.row(["Logo Target cell:", "", "", "Boundary"], styles: %w[left center center center])
2952
- s.row(["", "", "", ""])
2953
- s.row(["", "", "", ""])
2954
- s.row(["", "", "", ""])
2955
- s.row(["", "", "", "Boundary End"], styles: %w[left center center center])
2956
- s.image(dummy_png, ext: "png", from_col: 1, from_row: 1, to_col: 3, to_row: 5)
2957
- s.column(0, width: 20)
2958
- s.column(1, width: 15)
2959
- s.column(2, width: 15)
2960
- s.column(3, width: 15)
2961
- end
2962
- end
2963
-
2964
- # 2. Read the generated sheet and print cell values + parsed embedded images details
2965
- puts "=== Read Validation ==="
2966
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
2967
- workbook = Xlsxrb.read(output_path).load
2968
- sheet = workbook.sheets.first
2969
- sheet.rows.first(5).each do |row|
2970
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
2971
- puts "Row #{row.index}: #{row_cells.join(", ")}"
2972
- end
2973
- images = reader.images(sheet: sheet.name)
2974
- images.each_with_index do |img, idx|
2975
- zip_path = File.expand_path(img[:target], "/xl/drawings").sub(%r{^/}, "")
2976
- img_data = reader.send(:extract_zip_entry, zip_path)
2977
- is_png = img_data && img_data[0..3] == "\x89PNG".b
2978
- puts "Image ##{idx + 1}: name='#{img[:name]}', target='#{img[:target]}' -> ZIP path='#{zip_path}', size=#{img_data&.bytesize} bytes, valid_png=#{is_png}, range=Col #{img[:from_col]} Row #{img[:from_row]} to Col #{img[:to_col]} Row #{img[:to_row]}"
2979
- end
2980
- ```
2981
-
2982
- ### Console Output
2983
-
2984
- ```text
2985
- === Read Validation ===
2986
- Row 0: A1: "Logo Target cell:", B1: "", C1: "", D1: "Boundary"
2987
- Row 1: A2: "", B2: "", C2: "", D2: ""
2988
- Row 2: A3: "", B3: "", C3: "", D3: ""
2989
- Row 3: A4: "", B4: "", C4: "", D4: ""
2990
- Row 4: A5: "", B5: "", C5: "", D5: "Boundary End"
2991
- Image #1: name='', target='../media/image1.png' -> ZIP path='xl/media/image1.png', size=334 bytes, valid_png=true, range=Col 1 Row 1 to Col 3 Row 5
2992
- ```
2993
-
2994
- <hr/>
2995
-
2996
- ## Fill Gradients
2997
-
2998
- Demonstrates linear gradients inside cell backgrounds.
2999
-
3000
- ### Rendered Output (LibreOffice Calc)
3001
-
3002
- <div><img src="../../test/visual/baselines/fill_gradients/page-1.png" width="100%" alt="Preview"/></div>
3003
-
3004
- ### DSL Code
3005
-
3006
- ```ruby
3007
- # frozen_string_literal: true
3008
-
3009
- require "xlsxrb"
3010
- output_path = ARGV[0] || "fill_gradients.xlsx"
3011
- Xlsxrb.write(output_path) do |wb|
3012
- wb.style("gradient") do |style|
3013
- style.fill_gradient(type: "linear", degree: 45, stops: [
3014
- { position: 0, color: "FFFFFFFF" },
3015
- { position: 1, color: "FF4F81BD" }
3016
- ])
3017
- end
3018
- wb.sheet("Gradients") do |s|
3019
- s.column(0, width: 25)
3020
- s.column(1, width: 25)
3021
- s.row(["Normal Cell", "Gradient Cell"], styles: { 1 => "gradient" })
3022
- end
3023
- end
3024
-
3025
- # 2. Read the generated sheet and print cell fill properties
3026
- puts "=== Read Validation ==="
3027
- workbook = Xlsxrb.read(output_path).load
3028
- sheet = workbook.sheets.first
3029
- row = sheet.rows.first
3030
- row.cells.each do |c|
3031
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
3032
- fill = xf ? workbook.styles[:fills][xf[:fill_id]] : nil
3033
- puts "Cell #{c.ref} ('#{c.value}'): fill pattern = #{fill&.[](:pattern).inspect}, fg_color = #{fill&.[](:fg_color).inspect}"
3034
- end
3035
- ```
3036
-
3037
- ### Console Output
3038
-
3039
- ```text
3040
- === Read Validation ===
3041
- Cell A1 ('Normal Cell'): fill pattern = nil, fg_color = nil
3042
- Cell B1 ('Gradient Cell'): fill pattern = nil, fg_color = nil
3043
- ```
3044
-
3045
- <hr/>
3046
-
3047
- ## Fill Patterns
3048
-
3049
- Demonstrates standard pattern fills (darkGray, darkGrid) in cell backgrounds.
3050
-
3051
- ### Rendered Output (LibreOffice Calc)
3052
-
3053
- <div><img src="../../test/visual/baselines/fill_patterns/page-1.png" width="100%" alt="Preview"/></div>
3054
-
3055
- ### DSL Code
3056
-
3057
- ```ruby
3058
- # frozen_string_literal: true
3059
-
3060
- require "xlsxrb"
3061
- output_path = ARGV[0] || "fill_patterns.xlsx"
3062
- Xlsxrb.write(output_path) do |wb|
3063
- wb.style("dark_gray") { |s| s.fill(pattern: "darkGray", fg_color: "FFC0C0C0", bg_color: "FFFFFFFF") }
3064
- wb.style("grid_fill") { |s| s.fill(pattern: "darkGrid", fg_color: "FFC0C0C0", bg_color: "FFFFFFFF") }
3065
- wb.sheet("Patterns") do |s|
3066
- s.column(0, width: 25)
3067
- s.column(1, width: 25)
3068
- s.row(%w[Pattern Preview])
3069
- s.row(["Dark Gray", "Pattern Fill"], styles: { 1 => "dark_gray" })
3070
- s.row(["Dark Grid", "Grid Fill"], styles: { 1 => "grid_fill" })
3071
- end
3072
- end
3073
-
3074
- # 2. Read the generated sheet and print cell fill properties
3075
- puts "=== Read Validation ==="
3076
- workbook = Xlsxrb.read(output_path).load
3077
- sheet = workbook.sheets.first
3078
- row = sheet.rows.first
3079
- row.cells.each do |c|
3080
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
3081
- fill = xf ? workbook.styles[:fills][xf[:fill_id]] : nil
3082
- puts "Cell #{c.ref} ('#{c.value}'): fill pattern = #{fill&.[](:pattern).inspect}, fg_color = #{fill&.[](:fg_color).inspect}"
3083
- end
3084
- ```
3085
-
3086
- ### Console Output
3087
-
3088
- ```text
3089
- === Read Validation ===
3090
- Cell A1 ('Pattern'): fill pattern = nil, fg_color = nil
3091
- Cell B1 ('Preview'): fill pattern = nil, fg_color = nil
3092
- ```
3093
-
3094
- <hr/>
3095
-
3096
- ## Fill Solid Colors
3097
-
3098
- Demonstrates solid cell background fill colors.
3099
-
3100
- ### Rendered Output (LibreOffice Calc)
3101
-
3102
- <div><img src="../../test/visual/baselines/fill_solid_colors/page-1.png" width="100%" alt="Preview"/></div>
3103
-
3104
- ### DSL Code
3105
-
3106
- ```ruby
3107
- # frozen_string_literal: true
3108
-
3109
- require "xlsxrb"
3110
- output_path = ARGV[0] || "fill_solid_colors.xlsx"
3111
- Xlsxrb.write(output_path) do |wb|
3112
- wb.style("red_fill") { |s| s.fill_color("FFFFC7CE") }
3113
- wb.style("green_fill") { |s| s.fill_color("FFC6EFCE") }
3114
- wb.sheet("Fills") do |s|
3115
- s.column(0, width: 25)
3116
- s.column(1, width: 25)
3117
- s.row(%w[Color Preview])
3118
- s.row(["Red", "Red Fill"], styles: { 1 => "red_fill" })
3119
- s.row(["Green", "Green Fill"], styles: { 1 => "green_fill" })
3120
- end
3121
- end
3122
-
3123
- # 2. Read the generated sheet and print cell fill properties
3124
- puts "=== Read Validation ==="
3125
- workbook = Xlsxrb.read(output_path).load
3126
- sheet = workbook.sheets.first
3127
- row = sheet.rows.first
3128
- row.cells.each do |c|
3129
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
3130
- fill = xf ? workbook.styles[:fills][xf[:fill_id]] : nil
3131
- puts "Cell #{c.ref} ('#{c.value}'): fill pattern = #{fill&.[](:pattern).inspect}, fg_color = #{fill&.[](:fg_color).inspect}"
3132
- end
3133
- ```
3134
-
3135
- ### Console Output
3136
-
3137
- ```text
3138
- === Read Validation ===
3139
- Cell A1 ('Color'): fill pattern = nil, fg_color = nil
3140
- Cell B1 ('Preview'): fill pattern = nil, fg_color = nil
3141
- ```
3142
-
3143
- <hr/>
3144
-
3145
- ## Fonts
3146
-
3147
- Demonstrates cell fonts properties (Arial, Georgia, Courier New, Times New Roman, Tahoma, sizes 10pt/16pt/24pt, red/green/blue colors, bold/italic/underline/double underline/strike-through styles, superscript/subscript).
3148
-
3149
- ### Rendered Output (LibreOffice Calc)
3150
-
3151
- <div><img src="../../test/visual/baselines/fonts/page-1.png" width="100%" alt="Preview"/></div>
3152
-
3153
- ### DSL Code
3154
-
3155
- ```ruby
3156
- # frozen_string_literal: true
3157
-
3158
- require "xlsxrb"
3159
-
3160
- output_path = ARGV[0] || "fonts.xlsx"
3161
-
3162
- Xlsxrb.write(output_path) do |wb|
3163
- # Font Families (using nested hash options)
3164
- wb.style("f_arial", font: { name: "Arial" })
3165
- wb.style("f_times", font: { name: "Times New Roman" })
3166
- wb.style("f_courier", font: { name: "Courier New" })
3167
- wb.style("f_georgia", font: { name: "Georgia" })
3168
- wb.style("f_tahoma", font: { name: "Tahoma" })
3169
-
3170
- # Font Sizes
3171
- wb.style("sz_10", font: { size: 10 })
3172
- wb.style("sz_16", font: { size: 16 })
3173
- wb.style("sz_24", font: { size: 24 })
3174
-
3175
- # Font Colors
3176
- wb.style("c_red", font: { color: "FFC00000" })
3177
- wb.style("c_green", font: { color: "FF008000" })
3178
- wb.style("c_blue", font: { color: :blue })
3179
-
3180
- # Font Styles
3181
- wb.style("bold", font: { bold: true })
3182
- wb.style("italic", font: { italic: true })
3183
- wb.style("underline", font: { underline: true })
3184
- wb.style("double_underline", font: { underline: "double" })
3185
- wb.style("strike", font: { strike: true })
3186
-
3187
- # Vertical Alignment (Subscript / Superscript)
3188
- wb.style("superscript", font: { vert_align: "superscript" })
3189
- wb.style("subscript", font: { vert_align: "subscript" })
3190
-
3191
- wb.style("header", font: { bold: true, color: :white }, fill: { color: "FF4F81BD" })
3192
- wb.style("bg_light", fill: { color: "FFDCE6F1" })
3193
-
3194
- wb.sheet("Fonts") do |s|
3195
- s.column(0, width: 25)
3196
- s.column(1, width: 35)
3197
-
3198
- s.row(["Font Feature", "Text Preview"], styles: "header")
3199
-
3200
- s.row(["Family: Arial", "Arial Text"], styles: %w[bg_light f_arial])
3201
- s.row(["Family: Times New Roman", "Times New Roman"], styles: [nil, "f_times"])
3202
- s.row(["Family: Courier New", "Courier New Text"], styles: %w[bg_light f_courier])
3203
- s.row(["Family: Georgia", "Georgia Text"], styles: [nil, "f_georgia"])
3204
- s.row(["Family: Tahoma", "Tahoma Text"], styles: %w[bg_light f_tahoma])
3205
-
3206
- s.row(["Size: 10pt", "10pt Font Size"], styles: [nil, "sz_10"])
3207
- s.row(["Size: 16pt", "16pt Font Size"], styles: %w[bg_light sz_16])
3208
- s.row(["Size: 24pt", "24pt Font Size"], styles: [nil, "sz_24"])
3209
-
3210
- s.row(["Color: Red", "Red Text"], styles: %w[bg_light c_red])
3211
- s.row(["Color: Green", "Green Text"], styles: [nil, "c_green"])
3212
- s.row(["Color: Blue", "Blue Text"], styles: %w[bg_light c_blue])
3213
-
3214
- s.row(["Style: Bold", "Bold Text"], styles: [nil, "bold"])
3215
- s.row(["Style: Italic", "Italic Text"], styles: %w[bg_light italic])
3216
- s.row(["Style: Underline", "Underline Text"], styles: [nil, "underline"])
3217
- s.row(["Style: Double Underline", "Double Underline"], styles: %w[bg_light double_underline])
3218
- s.row(["Style: Strike-through", "Strike-through Text"], styles: [nil, "strike"])
3219
-
3220
- s.row(["Align: Superscript", "x2 (2 is super)"], styles: %w[bg_light superscript])
3221
- s.row(["Align: Subscript", "H2O (2 is sub)"], styles: [nil, "subscript"])
3222
- end
3223
- end
3224
- puts "Created #{output_path}"
3225
- ```
3226
-
3227
- ### Console Output
3228
-
3229
- ```text
3230
- Created /workspaces/xlsxrb/docs/visual/files/fonts.xlsx
3231
- ```
3232
-
3233
- <hr/>
3234
-
3235
- ## Interactive Autofilter
3236
-
3237
- > [!TIP]
3238
- > **Interactive Feature**: This example uses interactive Excel behaviors (such as validation dropdowns, comments, or autofilters). Since the static visual preview below represents a printed page layout, please use the **Live Preview** to interact with it!
3239
-
3240
- Demonstrates enabling auto-filter sorting headers on tables. Download the sheet to interactively filter and sort columns.
3241
-
3242
- ### Rendered Output (LibreOffice Calc)
3243
-
3244
- <div><img src="../../test/visual/baselines/interactive_autofilter/page-1.png" width="100%" alt="Preview"/></div>
3245
-
3246
- <div><img src="../../test/visual/support/illustrations/interactive_autofilter_page-2.png" width="100%" alt="Preview"/></div>
3247
-
3248
- ### DSL Code
3249
-
3250
- ```ruby
3251
- # frozen_string_literal: true
3252
-
3253
- require "xlsxrb"
3254
- output_path = ARGV[0] || "interactive_autofilter.xlsx"
3255
- Xlsxrb.write(output_path) do |wb|
3256
- wb.sheet("Filter") do |s|
3257
- s.column(0, width: 25)
3258
- s.column(1, width: 25)
3259
- s.row(%w[Name Department])
3260
- s.row(%w[Alice HR])
3261
- s.row(%w[Bob Eng])
3262
- s.auto_filter("A1:B3")
3263
- end
3264
- wb.defined_name("_xlnm._FilterDatabase", "Filter!$A$1:$B$3", sheet: "Filter", hidden: true)
3265
- end
3266
-
3267
- # 2. Read the generated sheet and print cell values
3268
- puts "=== Read Validation ==="
3269
- workbook = Xlsxrb.read(output_path).load
3270
- sheet = workbook.sheets.first
3271
- sheet.rows.first(5).each do |row|
3272
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
3273
- puts "Row #{row.index}: #{row_cells.join(", ")}"
3274
- end
3275
- ```
3276
-
3277
- ### Console Output
3278
-
3279
- ```text
3280
- === Read Validation ===
3281
- Row 0: A1: "Name", B1: "Department"
3282
- Row 1: A2: "Alice", B2: "HR"
3283
- Row 2: A3: "Bob", B3: "Eng"
3284
- ```
3285
-
3286
- <hr/>
3287
-
3288
- ## Interactive Comments
3289
-
3290
- > [!TIP]
3291
- > **Interactive Feature**: This example uses interactive Excel behaviors (such as validation dropdowns, comments, or autofilters). Since the static visual preview below represents a printed page layout, please use the **Live Preview** to interact with it!
3292
-
3293
- Demonstrates cell pop-up comments. Open the sheet in Excel and hover your mouse over the cell with the red triangle to view the comment.
3294
-
3295
- ### Rendered Output (LibreOffice Calc)
3296
-
3297
- <div><img src="../../test/visual/baselines/interactive_comments/page-1.png" width="100%" alt="Preview"/></div>
3298
-
3299
- <div><img src="../../test/visual/support/illustrations/interactive_comments_page-2.png" width="100%" alt="Preview"/></div>
3300
-
3301
- ### DSL Code
3302
-
3303
- ```ruby
3304
- # frozen_string_literal: true
3305
-
3306
- require "xlsxrb"
3307
- output_path = ARGV[0] || "interactive_comments.xlsx"
3308
- Xlsxrb.write(output_path) do |wb|
3309
- wb.sheet("Comments") do |s|
3310
- s.column(0, width: 25)
3311
- s.column(1, width: 25)
3312
- s.row(["Item A", "Item B"])
3313
- s.comment("A1", "This is an important comment.", author: "System")
3314
- end
3315
- end
3316
-
3317
- # 2. Read the generated sheet and print cell values
3318
- puts "=== Read Validation ==="
3319
- workbook = Xlsxrb.read(output_path).load
3320
- sheet = workbook.sheets.first
3321
- sheet.rows.first(5).each do |row|
3322
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
3323
- puts "Row #{row.index}: #{row_cells.join(", ")}"
3324
- end
3325
- ```
3326
-
3327
- ### Console Output
3328
-
3329
- ```text
3330
- === Read Validation ===
3331
- Row 0: A1: "Item A", B1: "Item B"
3332
- ```
3333
-
3334
- <hr/>
3335
-
3336
- ## Interactive Validation Custom
3337
-
3338
- > [!TIP]
3339
- > **Interactive Feature**: This example uses interactive Excel behaviors (such as validation dropdowns, comments, or autofilters). Since the static visual preview below represents a printed page layout, please use the **Live Preview** to interact with it!
3340
-
3341
- Demonstrates interactive custom formula validation rules.
3342
-
3343
- ### Rendered Output (LibreOffice Calc)
3344
-
3345
- <div><img src="../../test/visual/baselines/interactive_validation_custom/page-1.png" width="100%" alt="Preview"/></div>
3346
-
3347
- <div><img src="../../test/visual/support/illustrations/interactive_validation_custom_page-2.png" width="100%" alt="Preview"/></div>
3348
-
3349
- ### DSL Code
3350
-
3351
- ```ruby
3352
- # frozen_string_literal: true
3353
-
3354
- require "xlsxrb"
3355
- output_path = ARGV[0] || "interactive_validation_custom.xlsx"
3356
- Xlsxrb.write(output_path) do |wb|
3357
- wb.sheet("Custom Rule") do |s|
3358
- s.column(0, width: 25)
3359
- s.column(1, width: 25)
3360
- s.row(["Number A", "Number B (Must be larger A)"])
3361
- s.row([10, ""])
3362
- s.validate_data("B2", type: "custom", formula1: "B2>A2", show_error_message: true, error_title: "Validation Error", error: "Number B must be greater than Number A")
3363
- end
3364
- end
3365
-
3366
- # 2. Read the generated sheet and print data validations
3367
- puts "=== Read Validation ==="
3368
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3369
- workbook = Xlsxrb.read(output_path).load
3370
- sheet = workbook.sheets.first
3371
- validations = reader.data_validations(sheet: sheet.name)
3372
- validations.each do |v|
3373
- puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
3374
- end
3375
- ```
3376
-
3377
- ### Console Output
3378
-
3379
- ```text
3380
- === Read Validation ===
3381
- Validation range B2: type=custom, formula1=B2>A2, formula2=
3382
- ```
3383
-
3384
- <hr/>
3385
-
3386
- ## Interactive Validation Date
3387
-
3388
- > [!TIP]
3389
- > **Interactive Feature**: This example uses interactive Excel behaviors (such as validation dropdowns, comments, or autofilters). Since the static visual preview below represents a printed page layout, please use the **Live Preview** to interact with it!
3390
-
3391
- Demonstrates interactive date range constraints validation rules.
3392
-
3393
- ### Rendered Output (LibreOffice Calc)
3394
-
3395
- <div><img src="../../test/visual/baselines/interactive_validation_date/page-1.png" width="100%" alt="Preview"/></div>
3396
-
3397
- <div><img src="../../test/visual/support/illustrations/interactive_validation_date_page-2.png" width="100%" alt="Preview"/></div>
3398
-
3399
- ### DSL Code
3400
-
3401
- ```ruby
3402
- # frozen_string_literal: true
3403
-
3404
- require "xlsxrb"
3405
- output_path = ARGV[0] || "interactive_validation_date.xlsx"
3406
- Xlsxrb.write(output_path) do |wb|
3407
- wb.sheet("Date Validation") do |s|
3408
- s.column(0, width: 25)
3409
- s.column(1, width: 25)
3410
- s.row(["Date Range", "Enter Date (2026):"])
3411
- s.validate_data("B2", type: "date", operator: "between", formula1: "Date(2026,1,1)", formula2: "Date(2026,12,31)", show_error_message: true, error_title: "Invalid Date", error: "Must be a date in 2026")
3412
- end
3413
- end
3414
-
3415
- # 2. Read the generated sheet and print data validations
3416
- puts "=== Read Validation ==="
3417
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3418
- workbook = Xlsxrb.read(output_path).load
3419
- sheet = workbook.sheets.first
3420
- validations = reader.data_validations(sheet: sheet.name)
3421
- validations.each do |v|
3422
- puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
3423
- end
3424
- ```
3425
-
3426
- ### Console Output
3427
-
3428
- ```text
3429
- === Read Validation ===
3430
- Validation range B2: type=date, formula1=Date(2026,1,1), formula2=Date(2026,12,31)
3431
- ```
3432
-
3433
- <hr/>
3434
-
3435
- ## Interactive Validation List
3436
-
3437
- > [!TIP]
3438
- > **Interactive Feature**: This example uses interactive Excel behaviors (such as validation dropdowns, comments, or autofilters). Since the static visual preview below represents a printed page layout, please use the **Live Preview** to interact with it!
3439
-
3440
- Demonstrates dropdown list data validations. Open the sheet in Excel and select cell A1/A2 to see the dropdown list in action.
3441
-
3442
- ### Rendered Output (LibreOffice Calc)
3443
-
3444
- <div><img src="../../test/visual/baselines/interactive_validation_list/page-1.png" width="100%" alt="Preview"/></div>
3445
-
3446
- <div><img src="../../test/visual/support/illustrations/interactive_validation_list_page-2.png" width="100%" alt="Preview"/></div>
3447
-
3448
- ### DSL Code
3449
-
3450
- ```ruby
3451
- # frozen_string_literal: true
3452
-
3453
- require "xlsxrb"
3454
- output_path = ARGV[0] || "interactive_validation_list.xlsx"
3455
- Xlsxrb.write(output_path) do |wb|
3456
- wb.sheet("List Validation") do |s|
3457
- s.column(0, width: 25)
3458
- s.column(1, width: 25)
3459
- s.row(["Department", "Select:"])
3460
- s.validate_data("B2", in: %w[HR Sales Engineering])
3461
- end
3462
- end
3463
-
3464
- # 2. Read the generated sheet and print data validations
3465
- puts "=== Read Validation ==="
3466
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3467
- workbook = Xlsxrb.read(output_path).load
3468
- sheet = workbook.sheets.first
3469
- validations = reader.data_validations(sheet: sheet.name)
3470
- validations.each do |v|
3471
- puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
3472
- end
3473
- ```
3474
-
3475
- ### Console Output
3476
-
3477
- ```text
3478
- === Read Validation ===
3479
- Validation range B2: type=list, formula1="HR,Sales,Engineering", formula2=
3480
- ```
3481
-
3482
- <hr/>
3483
-
3484
- ## Interactive Validation Range
3485
-
3486
- > [!TIP]
3487
- > **Interactive Feature**: This example uses interactive Excel behaviors (such as validation dropdowns, comments, or autofilters). Since the static visual preview below represents a printed page layout, please use the **Live Preview** to interact with it!
3488
-
3489
- Demonstrates range constraints for whole number validations. Open the sheet in Excel and try entering a value outside 10-100 to trigger the warning.
3490
-
3491
- ### Rendered Output (LibreOffice Calc)
3492
-
3493
- <div><img src="../../test/visual/baselines/interactive_validation_range/page-1.png" width="100%" alt="Preview"/></div>
3494
-
3495
- <div><img src="../../test/visual/support/illustrations/interactive_validation_range_page-2.png" width="100%" alt="Preview"/></div>
3496
-
3497
- ### DSL Code
3498
-
3499
- ```ruby
3500
- # frozen_string_literal: true
3501
-
3502
- require "xlsxrb"
3503
- output_path = ARGV[0] || "interactive_validation_range.xlsx"
3504
- Xlsxrb.write(output_path) do |wb|
3505
- wb.sheet("Range Validation") do |s|
3506
- s.column(0, width: 25)
3507
- s.column(1, width: 25)
3508
- s.row(["Age", "Enter (18-99):"])
3509
- s.validate_data("B2", type: "whole", operator: "between", formula1: "18", formula2: "99", show_error_message: true, error_title: "Invalid Age", error: "Age must be between 18 and 99!")
3510
- end
3511
- end
3512
-
3513
- # 2. Read the generated sheet and print data validations
3514
- puts "=== Read Validation ==="
3515
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3516
- workbook = Xlsxrb.read(output_path).load
3517
- sheet = workbook.sheets.first
3518
- validations = reader.data_validations(sheet: sheet.name)
3519
- validations.each do |v|
3520
- puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
3521
- end
3522
- ```
3523
-
3524
- ### Console Output
3525
-
3526
- ```text
3527
- === Read Validation ===
3528
- Validation range B2: type=whole, formula1=18, formula2=99
3529
- ```
3530
-
3531
- <hr/>
3532
-
3533
- ## Interactive Validation Text Length
3534
-
3535
- > [!TIP]
3536
- > **Interactive Feature**: This example uses interactive Excel behaviors (such as validation dropdowns, comments, or autofilters). Since the static visual preview below represents a printed page layout, please use the **Live Preview** to interact with it!
3537
-
3538
- Demonstrates interactive text length validation rules.
3539
-
3540
- ### Rendered Output (LibreOffice Calc)
3541
-
3542
- <div><img src="../../test/visual/baselines/interactive_validation_text_length/page-1.png" width="100%" alt="Preview"/></div>
3543
-
3544
- <div><img src="../../test/visual/support/illustrations/interactive_validation_text_length_page-2.png" width="100%" alt="Preview"/></div>
3545
-
3546
- ### DSL Code
3547
-
3548
- ```ruby
3549
- # frozen_string_literal: true
3550
-
3551
- require "xlsxrb"
3552
- output_path = ARGV[0] || "interactive_validation_text_length.xlsx"
3553
- Xlsxrb.write(output_path) do |wb|
3554
- wb.sheet("Text Length") do |s|
3555
- s.column(0, width: 25)
3556
- s.column(1, width: 25)
3557
- s.row(["Username", "Enter (< 10 chars):"])
3558
- s.validate_data("B2", type: "textLength", operator: "lessThan", formula1: "10", show_error_message: true, error_title: "Too Long", error: "Username must be under 10 characters")
3559
- end
3560
- end
3561
-
3562
- # 2. Read the generated sheet and print data validations
3563
- puts "=== Read Validation ==="
3564
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3565
- workbook = Xlsxrb.read(output_path).load
3566
- sheet = workbook.sheets.first
3567
- validations = reader.data_validations(sheet: sheet.name)
3568
- validations.each do |v|
3569
- puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
3570
- end
3571
- ```
3572
-
3573
- ### Console Output
3574
-
3575
- ```text
3576
- === Read Validation ===
3577
- Validation range B2: type=textLength, formula1=10, formula2=
3578
- ```
3579
-
3580
- <hr/>
3581
-
3582
- ## Interactive Validation Time
3583
-
3584
- > [!TIP]
3585
- > **Interactive Feature**: This example uses interactive Excel behaviors (such as validation dropdowns, comments, or autofilters). Since the static visual preview below represents a printed page layout, please use the **Live Preview** to interact with it!
3586
-
3587
- Demonstrates interactive time validation rules.
3588
-
3589
- ### Rendered Output (LibreOffice Calc)
3590
-
3591
- <div><img src="../../test/visual/baselines/interactive_validation_time/page-1.png" width="100%" alt="Preview"/></div>
3592
-
3593
- <div><img src="../../test/visual/support/illustrations/interactive_validation_time_page-2.png" width="100%" alt="Preview"/></div>
3594
-
3595
- ### DSL Code
3596
-
3597
- ```ruby
3598
- # frozen_string_literal: true
3599
-
3600
- require "xlsxrb"
3601
- output_path = ARGV[0] || "interactive_validation_time.xlsx"
3602
- Xlsxrb.write(output_path) do |wb|
3603
- wb.sheet("Time Validation") do |s|
3604
- s.column(0, width: 25)
3605
- s.column(1, width: 25)
3606
- s.row(["Schedule", "Enter Time (after 08:00):"])
3607
- s.validate_data("B2", type: "time", operator: "greaterThan", formula1: "0.33333", show_error_message: true, error_title: "Too Early", error: "Time must be after 08:00 AM")
3608
- end
3609
- end
3610
-
3611
- # 2. Read the generated sheet and print data validations
3612
- puts "=== Read Validation ==="
3613
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3614
- workbook = Xlsxrb.read(output_path).load
3615
- sheet = workbook.sheets.first
3616
- validations = reader.data_validations(sheet: sheet.name)
3617
- validations.each do |v|
3618
- puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
3619
- end
3620
- ```
3621
-
3622
- ### Console Output
3623
-
3624
- ```text
3625
- === Read Validation ===
3626
- Validation range B2: type=time, formula1=0.33333, formula2=
3627
- ```
3628
-
3629
- <hr/>
3630
-
3631
- ## Japanese Text
3632
-
3633
- Demonstrates writing multi-byte Japanese text and setting appropriate Japanese font names (e.g., Noto Sans CJK JP).
3634
-
3635
- ### Rendered Output (LibreOffice Calc)
3636
-
3637
- <div><img src="../../test/visual/baselines/japanese_text/page-1.png" width="100%" alt="Preview"/></div>
3638
-
3639
- ### DSL Code
3640
-
3641
- ```ruby
3642
- # frozen_string_literal: true
3643
-
3644
- require "xlsxrb"
3645
-
3646
- output_path = ARGV[0] || "japanese_text.xlsx"
3647
-
3648
- Xlsxrb.write(output_path) do |wb|
3649
- wb.style("ja_font") do |style|
3650
- style.font_name("Noto Sans CJK JP").size(12)
3651
- end
3652
-
3653
- wb.sheet("Japanese") do |s|
3654
- s.column(0, width: 25)
3655
- s.column(1, width: 25)
3656
- s.row(%w[日本語ラベル 値], styles: { 0 => "ja_font", 1 => "ja_font" })
3657
- s.row(["売上", 12_500], styles: { 0 => "ja_font" })
3658
- end
3659
- end
3660
-
3661
- # 2. Read the generated sheet and print parsed cell values and Ruby classes
3662
- puts "=== Read Validation ==="
3663
- workbook = Xlsxrb.read(output_path).load
3664
- sheet = workbook.sheets.first
3665
- sheet.rows.each do |row|
3666
- row_cells = row.cells.map do |c|
3667
- "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
3668
- end
3669
- puts "Row #{row.index}: #{row_cells.join(", ")}"
3670
- end
3671
- ```
3672
-
3673
- ### Console Output
3674
-
3675
- ```text
3676
- === Read Validation ===
3677
- Row 0: A1: "日本語ラベル" (String), B1: "値" (String)
3678
- Row 1: A2: "売上" (String), B2: 12500 (Integer)
3679
- ```
3680
-
3681
- <hr/>
3682
-
3683
- ## Merge Freeze
3684
-
3685
- Demonstrates merging a cell range into a single cell, and freezing the top rows of a sheet.
3686
-
3687
- ### Rendered Output (LibreOffice Calc)
3688
-
3689
- <div><img src="../../test/visual/baselines/merge_freeze/page-1.png" width="100%" alt="Preview"/></div>
3690
-
3691
- ### DSL Code
3692
-
3693
- ```ruby
3694
- # frozen_string_literal: true
3695
-
3696
- require "xlsxrb"
3697
-
3698
- output_path = ARGV[0] || "merge_freeze.xlsx"
3699
-
3700
- Xlsxrb.write(output_path) do |wb|
3701
- wb.style("title") { |style| style.border_all(style: "thin", color: "FF000000").align_horizontal("center") }
3702
- wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
3703
- wb.sheet("Merge & Freeze") do |s|
3704
- s.sheet_properties(:fit_to_page, true)
3705
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
3706
- s.column(0, width: 25)
3707
- s.column(1, width: 25)
3708
- s.column(2, width: 25)
3709
- s.row(["Merged Title Row", nil, nil], styles: %w[title title title])
3710
- s.row(["Header A", "Header B", "Header C"], styles: %w[border border border])
3711
- s.row(["Row 1 Col A", "Row 1 Col B", "Row 1 Col C"], styles: %w[border border border])
3712
- s.row(["Row 2 Col A", "Row 2 Col B", "Row 2 Col C"], styles: %w[border border border])
3713
-
3714
- s.merge(row: 0, col_start: 0, col_end: 2)
3715
- s.freeze_pane(row: 2, col: 0)
3716
- end
3717
- end
3718
-
3719
- # 2. Read the generated sheet and print cell values
3720
- puts "=== Read Validation ==="
3721
- workbook = Xlsxrb.read(output_path).load
3722
- sheet = workbook.sheets.first
3723
- sheet.rows.first(5).each do |row|
3724
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
3725
- puts "Row #{row.index}: #{row_cells.join(", ")}"
3726
- end
3727
- ```
3728
-
3729
- ### Console Output
3730
-
3731
- ```text
3732
- === Read Validation ===
3733
- Row 0: A1: "Merged Title Row", B1: nil, C1: nil
3734
- Row 1: A2: "Header A", B2: "Header B", C2: "Header C"
3735
- Row 2: A3: "Row 1 Col A", B3: "Row 1 Col B", C3: "Row 1 Col C"
3736
- Row 3: A4: "Row 2 Col A", B4: "Row 2 Col B", C4: "Row 2 Col C"
3737
- ```
3738
-
3739
- <hr/>
3740
-
3741
- ## Page Grid Lines Print
3742
-
3743
- Demonstrates enabling printing of grid lines.
3744
-
3745
- ### Rendered Output (LibreOffice Calc)
3746
-
3747
- <div><img src="../../test/visual/baselines/page_grid_lines_print/page-1.png" width="100%" alt="Preview"/></div>
3748
-
3749
- ### DSL Code
3750
-
3751
- ```ruby
3752
- # frozen_string_literal: true
3753
-
3754
- require "xlsxrb"
3755
- output_path = ARGV[0] || "page_grid_lines_print.xlsx"
3756
- Xlsxrb.write(output_path) do |wb|
3757
- wb.sheet("Print Grid Lines") do |s|
3758
- s.column(0, width: 25)
3759
- s.column(1, width: 25)
3760
- s.print_options(:grid_lines, true)
3761
- s.row(["Grid Lines Printed sheet"])
3762
- end
3763
- end
3764
-
3765
- # 2. Read the generated sheet and print page setup properties
3766
- puts "=== Read Validation ==="
3767
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3768
- workbook = Xlsxrb.read(output_path).load
3769
- sheet = workbook.sheets.first
3770
- margins = reader.page_margins(sheet: sheet.name)
3771
- setup = reader.page_setup(sheet: sheet.name)
3772
- opts = reader.print_options(sheet: sheet.name)
3773
- puts "Page Margins: #{margins.inspect}"
3774
- puts "Page Setup: #{setup.inspect}"
3775
- puts "Print Options: #{opts.inspect}"
3776
- ```
3777
-
3778
- ### Console Output
3779
-
3780
- ```text
3781
- === Read Validation ===
3782
- Page Margins: nil
3783
- Page Setup: {}
3784
- Print Options: {grid_lines: true}
3785
- ```
3786
-
3787
- <hr/>
3788
-
3789
- ## Page Header Footer
3790
-
3791
- Demonstrates setting odd page headers and footers.
3792
-
3793
- ### Rendered Output (LibreOffice Calc)
3794
-
3795
- <div><img src="../../test/visual/baselines/page_header_footer/page-1.png" width="100%" alt="Preview"/></div>
3796
-
3797
- ### DSL Code
3798
-
3799
- ```ruby
3800
- # frozen_string_literal: true
3801
-
3802
- require "xlsxrb"
3803
- output_path = ARGV[0] || "page_header_footer.xlsx"
3804
- Xlsxrb.write(output_path) do |wb|
3805
- wb.sheet("Header Footer") do |s|
3806
- s.column(0, width: 25)
3807
- s.column(1, width: 25)
3808
- s.header_footer(odd_header: "&LMy Company&RPage &P", odd_footer: "&CConfidential")
3809
- s.row(["Header Footer sheet"])
3810
- end
3811
- end
3812
-
3813
- # 2. Read the generated sheet and print page setup properties
3814
- puts "=== Read Validation ==="
3815
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3816
- workbook = Xlsxrb.read(output_path).load
3817
- sheet = workbook.sheets.first
3818
- margins = reader.page_margins(sheet: sheet.name)
3819
- setup = reader.page_setup(sheet: sheet.name)
3820
- opts = reader.print_options(sheet: sheet.name)
3821
- puts "Page Margins: #{margins.inspect}"
3822
- puts "Page Setup: #{setup.inspect}"
3823
- puts "Print Options: #{opts.inspect}"
3824
- ```
3825
-
3826
- ### Console Output
3827
-
3828
- ```text
3829
- === Read Validation ===
3830
- Page Margins: nil
3831
- Page Setup: {}
3832
- Print Options: {}
3833
- ```
3834
-
3835
- <hr/>
3836
-
3837
- ## Page Headings Print
3838
-
3839
- Demonstrates enabling printing of row and column headings.
3840
-
3841
- ### Rendered Output (LibreOffice Calc)
3842
-
3843
- <div><img src="../../test/visual/baselines/page_headings_print/page-1.png" width="100%" alt="Preview"/></div>
3844
-
3845
- ### DSL Code
3846
-
3847
- ```ruby
3848
- # frozen_string_literal: true
3849
-
3850
- require "xlsxrb"
3851
- output_path = ARGV[0] || "page_headings_print.xlsx"
3852
- Xlsxrb.write(output_path) do |wb|
3853
- wb.sheet("Print Headings") do |s|
3854
- s.column(0, width: 25)
3855
- s.column(1, width: 25)
3856
- s.print_options(:headings, true)
3857
- s.row(["Row/Col Headings Printed sheet"])
3858
- end
3859
- end
3860
-
3861
- # 2. Read the generated sheet and print page setup properties
3862
- puts "=== Read Validation ==="
3863
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3864
- workbook = Xlsxrb.read(output_path).load
3865
- sheet = workbook.sheets.first
3866
- margins = reader.page_margins(sheet: sheet.name)
3867
- setup = reader.page_setup(sheet: sheet.name)
3868
- opts = reader.print_options(sheet: sheet.name)
3869
- puts "Page Margins: #{margins.inspect}"
3870
- puts "Page Setup: #{setup.inspect}"
3871
- puts "Print Options: #{opts.inspect}"
3872
- ```
3873
-
3874
- ### Console Output
3875
-
3876
- ```text
3877
- === Read Validation ===
3878
- Page Margins: nil
3879
- Page Setup: {}
3880
- Print Options: {headings: true}
3881
- ```
3882
-
3883
- <hr/>
3884
-
3885
- ## Page Margins Narrow
3886
-
3887
- Demonstrates setting narrow page margins.
3888
-
3889
- ### Rendered Output (LibreOffice Calc)
3890
-
3891
- <div><img src="../../test/visual/baselines/page_margins_narrow/page-1.png" width="100%" alt="Preview"/></div>
3892
-
3893
- ### DSL Code
3894
-
3895
- ```ruby
3896
- # frozen_string_literal: true
3897
-
3898
- require "xlsxrb"
3899
- output_path = ARGV[0] || "page_margins_narrow.xlsx"
3900
- Xlsxrb.write(output_path) do |wb|
3901
- wb.sheet("Narrow Margins") do |s|
3902
- s.column(0, width: 25)
3903
- s.column(1, width: 25)
3904
- s.page_margins(top: 0.25, bottom: 0.25, left: 0.25, right: 0.25, header: 0.1, footer: 0.1)
3905
- s.row(["Narrow Margins sheet"])
3906
- end
3907
- end
3908
-
3909
- # 2. Read the generated sheet and print page setup properties
3910
- puts "=== Read Validation ==="
3911
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3912
- workbook = Xlsxrb.read(output_path).load
3913
- sheet = workbook.sheets.first
3914
- margins = reader.page_margins(sheet: sheet.name)
3915
- setup = reader.page_setup(sheet: sheet.name)
3916
- opts = reader.print_options(sheet: sheet.name)
3917
- puts "Page Margins: #{margins.inspect}"
3918
- puts "Page Setup: #{setup.inspect}"
3919
- puts "Print Options: #{opts.inspect}"
3920
- ```
3921
-
3922
- ### Console Output
3923
-
3924
- ```text
3925
- === Read Validation ===
3926
- Page Margins: {left: 0.25, right: 0.25, top: 0.25, bottom: 0.25, header: 0.1, footer: 0.1}
3927
- Page Setup: {}
3928
- Print Options: {}
3929
- ```
3930
-
3931
- <hr/>
3932
-
3933
- ## Page Margins Wide
3934
-
3935
- Demonstrates setting wide page margins.
3936
-
3937
- ### Rendered Output (LibreOffice Calc)
3938
-
3939
- <div><img src="../../test/visual/baselines/page_margins_wide/page-1.png" width="100%" alt="Preview"/></div>
3940
-
3941
- ### DSL Code
3942
-
3943
- ```ruby
3944
- # frozen_string_literal: true
3945
-
3946
- require "xlsxrb"
3947
- output_path = ARGV[0] || "page_margins_wide.xlsx"
3948
- Xlsxrb.write(output_path) do |wb|
3949
- wb.sheet("Wide Margins") do |s|
3950
- s.column(0, width: 25)
3951
- s.column(1, width: 25)
3952
- s.page_margins(top: 1.0, bottom: 1.0, left: 1.0, right: 1.0, header: 0.5, footer: 0.5)
3953
- s.row(["Wide Margins sheet"])
3954
- end
3955
- end
3956
-
3957
- # 2. Read the generated sheet and print page setup properties
3958
- puts "=== Read Validation ==="
3959
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
3960
- workbook = Xlsxrb.read(output_path).load
3961
- sheet = workbook.sheets.first
3962
- margins = reader.page_margins(sheet: sheet.name)
3963
- setup = reader.page_setup(sheet: sheet.name)
3964
- opts = reader.print_options(sheet: sheet.name)
3965
- puts "Page Margins: #{margins.inspect}"
3966
- puts "Page Setup: #{setup.inspect}"
3967
- puts "Print Options: #{opts.inspect}"
3968
- ```
3969
-
3970
- ### Console Output
3971
-
3972
- ```text
3973
- === Read Validation ===
3974
- Page Margins: {left: 1.0, right: 1.0, top: 1.0, bottom: 1.0, header: 0.5, footer: 0.5}
3975
- Page Setup: {}
3976
- Print Options: {}
3977
- ```
3978
-
3979
- <hr/>
3980
-
3981
- ## Page Orientation Landscape
3982
-
3983
- Demonstrates landscape page setup for printing.
3984
-
3985
- ### Rendered Output (LibreOffice Calc)
3986
-
3987
- <div><img src="../../test/visual/baselines/page_orientation_landscape/page-1.png" width="100%" alt="Preview"/></div>
3988
-
3989
- ### DSL Code
3990
-
3991
- ```ruby
3992
- # frozen_string_literal: true
3993
-
3994
- require "xlsxrb"
3995
- output_path = ARGV[0] || "page_orientation_landscape.xlsx"
3996
- Xlsxrb.write(output_path) do |wb|
3997
- wb.sheet("Landscape") do |s|
3998
- s.column(0, width: 25)
3999
- s.column(1, width: 25)
4000
- s.page_setup(orientation: :landscape)
4001
- s.row(["Landscape Orientation sheet"])
4002
- end
4003
- end
4004
-
4005
- # 2. Read the generated sheet and print page setup properties
4006
- puts "=== Read Validation ==="
4007
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
4008
- workbook = Xlsxrb.read(output_path).load
4009
- sheet = workbook.sheets.first
4010
- margins = reader.page_margins(sheet: sheet.name)
4011
- setup = reader.page_setup(sheet: sheet.name)
4012
- opts = reader.print_options(sheet: sheet.name)
4013
- puts "Page Margins: #{margins.inspect}"
4014
- puts "Page Setup: #{setup.inspect}"
4015
- puts "Print Options: #{opts.inspect}"
4016
- ```
4017
-
4018
- ### Console Output
4019
-
4020
- ```text
4021
- === Read Validation ===
4022
- Page Margins: nil
4023
- Page Setup: {orientation: "landscape"}
4024
- Print Options: {}
4025
- ```
4026
-
4027
- <hr/>
4028
-
4029
- ## Page Paper Size A3
4030
-
4031
- Demonstrates setting paper size to A3 (paper size 8).
4032
-
4033
- ### Rendered Output (LibreOffice Calc)
4034
-
4035
- <div><img src="../../test/visual/baselines/page_paper_size_a3/page-1.png" width="100%" alt="Preview"/></div>
4036
-
4037
- ### DSL Code
4038
-
4039
- ```ruby
4040
- # frozen_string_literal: true
4041
-
4042
- require "xlsxrb"
4043
- output_path = ARGV[0] || "page_paper_size_a3.xlsx"
4044
- Xlsxrb.write(output_path) do |wb|
4045
- wb.sheet("A3 Sheet") do |s|
4046
- s.column(0, width: 25)
4047
- s.column(1, width: 25)
4048
- s.page_setup(paper_size: 8) # ISO A3 is paperSize="8"
4049
- s.row(["ISO A3 Paper Size sheet"])
4050
- end
4051
- end
4052
-
4053
- # 2. Read the generated sheet and print page setup properties
4054
- puts "=== Read Validation ==="
4055
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
4056
- workbook = Xlsxrb.read(output_path).load
4057
- sheet = workbook.sheets.first
4058
- margins = reader.page_margins(sheet: sheet.name)
4059
- setup = reader.page_setup(sheet: sheet.name)
4060
- opts = reader.print_options(sheet: sheet.name)
4061
- puts "Page Margins: #{margins.inspect}"
4062
- puts "Page Setup: #{setup.inspect}"
4063
- puts "Print Options: #{opts.inspect}"
4064
- ```
4065
-
4066
- ### Console Output
4067
-
4068
- ```text
4069
- === Read Validation ===
4070
- Page Margins: nil
4071
- Page Setup: {paper_size: 8}
4072
- Print Options: {}
4073
- ```
4074
-
4075
- <hr/>
4076
-
4077
- ## Pivot Table
4078
-
4079
- Visual demonstration for Pivot Table.
4080
-
4081
- ### Rendered Output (LibreOffice Calc)
4082
-
4083
- <div><img src="../../test/visual/baselines/pivot_table/page-1.png" width="100%" alt="Preview"/></div>
4084
-
4085
- <div><img src="../../test/visual/baselines/pivot_table/page-2.png" width="100%" alt="Preview"/></div>
4086
-
4087
- ### DSL Code
4088
-
4089
- ```ruby
4090
- # frozen_string_literal: true
4091
-
4092
- require "xlsxrb"
4093
-
4094
- output_path = ARGV[0] || "pivot_table.xlsx"
4095
-
4096
- Xlsxrb.write(output_path) do |wb|
4097
- wb.sheet("SalesData") do |sheet|
4098
- sheet.column(0..3, width: 18)
4099
- sheet.row(%w[Region Quarter Sales Rep])
4100
- sheet.row(["East", "Q1", 1000, "Alice"])
4101
- sheet.row(["West", "Q1", 1500, "Bob"])
4102
- sheet.row(["East", "Q2", 1200, "Alice"])
4103
- sheet.row(["West", "Q2", 1800, "Bob"])
4104
- sheet.row(["North", "Q1", 800, "Charlie"])
4105
- sheet.row(["North", "Q2", 950, "Charlie"])
4106
-
4107
- sheet.pivot_table(
4108
- "SalesData!A1:D7",
4109
- row_fields: ["Region"],
4110
- data_fields: [{ name: "Sales", subtotal: "sum" }],
4111
- col_fields: ["Quarter"],
4112
- dest_ref: "F1",
4113
- name: "RegionalSalesSummary"
4114
- )
4115
- end
4116
- end
4117
-
4118
- puts "=== Read Validation ==="
4119
- workbook = Xlsxrb.read(output_path).load
4120
- sheet = workbook.sheets.first
4121
- sheet.rows.each do |row|
4122
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
4123
- puts "Row #{row.index}: #{row_cells.join(", ")}"
4124
- end
4125
- ```
4126
-
4127
- ### Console Output
4128
-
4129
- ```text
4130
- === Read Validation ===
4131
- Row 0: A1: "Region", B1: "Quarter", C1: "Sales", D1: "Rep"
4132
- Row 1: A2: "East", B2: "Q1", C2: 1000, D2: "Alice"
4133
- Row 2: A3: "West", B3: "Q1", C3: 1500, D3: "Bob"
4134
- Row 3: A4: "East", B4: "Q2", C4: 1200, D4: "Alice"
4135
- Row 4: A5: "West", B5: "Q2", C5: 1800, D5: "Bob"
4136
- Row 5: A6: "North", B6: "Q1", C6: 800, D6: "Charlie"
4137
- Row 6: A7: "North", B7: "Q2", C7: 950, D7: "Charlie"
4138
- ```
4139
-
4140
- <hr/>
4141
-
4142
- ## Row Grouping
4143
-
4144
- Demonstrates outline grouping for rows.
4145
-
4146
- ### Rendered Output (LibreOffice Calc)
4147
-
4148
- <div><img src="../../test/visual/baselines/row_grouping/page-1.png" width="100%" alt="Preview"/></div>
4149
-
4150
- ### DSL Code
4151
-
4152
- ```ruby
4153
- # frozen_string_literal: true
4154
-
4155
- require "xlsxrb"
4156
- output_path = ARGV[0] || "row_grouping.xlsx"
4157
- Xlsxrb.write(output_path) do |wb|
4158
- wb.style("parent") { |style| style.border_all(style: "thin", color: "FF000000").bold }
4159
- wb.style("child") { |style| style.border_all(style: "thin", color: "FF000000").align_horizontal("left").indent(2) }
4160
- wb.sheet("Row Grouping") do |s|
4161
- s.column(0, width: 25)
4162
- s.column(1, width: 25)
4163
- s.row(["Parent Row 1", ""], styles: %w[parent parent])
4164
- s.row(["Child Row 1.1", ""], outline_level: 1, styles: %w[child child])
4165
- s.row(["Child Row 1.2", ""], outline_level: 1, styles: %w[child child])
4166
- end
4167
- end
4168
-
4169
- # 2. Read the generated sheet and print row attributes
4170
- puts "=== Read Validation ==="
4171
- workbook = Xlsxrb.read(output_path).load
4172
- sheet = workbook.sheets.first
4173
- sheet.rows.each do |row|
4174
- puts "Row #{row.index}: height=#{row.height}, hidden=#{row.hidden}, outline_level=#{row.outline_level}"
4175
- end
4176
- ```
4177
-
4178
- ### Console Output
4179
-
4180
- ```text
4181
- === Read Validation ===
4182
- Row 0: height=, hidden=false, outline_level=
4183
- Row 1: height=, hidden=false, outline_level=1
4184
- Row 2: height=, hidden=false, outline_level=1
4185
- ```
4186
-
4187
- <hr/>
4188
-
4189
- ## Row Height Tall
4190
-
4191
- Demonstrates setting very tall row heights.
4192
-
4193
- ### Rendered Output (LibreOffice Calc)
4194
-
4195
- <div><img src="../../test/visual/baselines/row_height_tall/page-1.png" width="100%" alt="Preview"/></div>
4196
-
4197
- ### DSL Code
4198
-
4199
- ```ruby
4200
- # frozen_string_literal: true
4201
-
4202
- require "xlsxrb"
4203
- output_path = ARGV[0] || "row_height_tall.xlsx"
4204
- Xlsxrb.write(output_path) do |wb|
4205
- wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
4206
- wb.sheet("Row Height") do |s|
4207
- s.column(0, width: 25)
4208
- s.column(1, width: 25)
4209
- s.row(["Very Tall Row (Height 60)", ""], height: 60, styles: %w[border border])
4210
- s.row(["Normal Row", ""], styles: %w[border border])
4211
- end
4212
- end
4213
-
4214
- # 2. Read the generated sheet and print row attributes
4215
- puts "=== Read Validation ==="
4216
- workbook = Xlsxrb.read(output_path).load
4217
- sheet = workbook.sheets.first
4218
- sheet.rows.each do |row|
4219
- puts "Row #{row.index}: height=#{row.height}, hidden=#{row.hidden}, outline_level=#{row.outline_level}"
4220
- end
4221
- ```
4222
-
4223
- ### Console Output
4224
-
4225
- ```text
4226
- === Read Validation ===
4227
- Row 0: height=60.0, hidden=false, outline_level=
4228
- Row 1: height=, hidden=false, outline_level=
4229
- ```
4230
-
4231
- <hr/>
4232
-
4233
- ## Row Heights
4234
-
4235
- Demonstrates setting custom row heights.
4236
-
4237
- ### Rendered Output (LibreOffice Calc)
4238
-
4239
- <div><img src="../../test/visual/baselines/row_heights/page-1.png" width="100%" alt="Preview"/></div>
4240
-
4241
- ### DSL Code
4242
-
4243
- ```ruby
4244
- # frozen_string_literal: true
4245
-
4246
- require "xlsxrb"
4247
- output_path = ARGV[0] || "row_heights.xlsx"
4248
- Xlsxrb.write(output_path) do |wb|
4249
- wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
4250
- wb.sheet("Heights") do |s|
4251
- s.column(0, width: 25)
4252
- s.column(1, width: 25)
4253
- s.row(["Normal Row", ""], styles: %w[border border])
4254
- s.row(["Tall Row", ""], height: 40, styles: %w[border border])
4255
- end
4256
- end
4257
-
4258
- # 2. Read the generated sheet and print row attributes
4259
- puts "=== Read Validation ==="
4260
- workbook = Xlsxrb.read(output_path).load
4261
- sheet = workbook.sheets.first
4262
- sheet.rows.each do |row|
4263
- puts "Row #{row.index}: height=#{row.height}, hidden=#{row.hidden}, outline_level=#{row.outline_level}"
4264
- end
4265
- ```
4266
-
4267
- ### Console Output
4268
-
4269
- ```text
4270
- === Read Validation ===
4271
- Row 0: height=, hidden=false, outline_level=
4272
- Row 1: height=40.0, hidden=false, outline_level=
4273
- ```
4274
-
4275
- <hr/>
4276
-
4277
- ## Sheet Tab Colors
4278
-
4279
- Demonstrates customizing tab colors of individual worksheets.
4280
-
4281
- ### Rendered Output (LibreOffice Calc)
4282
-
4283
- <div><img src="../../test/visual/baselines/sheet_tab_colors/page-1.png" width="100%" alt="Preview"/></div>
4284
-
4285
- <div><img src="../../test/visual/baselines/sheet_tab_colors/page-2.png" width="100%" alt="Preview"/></div>
4286
-
4287
- <div><img src="../../test/visual/support/illustrations/sheet_tab_colors_page-2.png" width="100%" alt="Preview"/></div>
4288
-
4289
- ### DSL Code
4290
-
4291
- ```ruby
4292
- # frozen_string_literal: true
4293
-
4294
- require "xlsxrb"
4295
- output_path = ARGV[0] || "sheet_tab_colors.xlsx"
4296
- Xlsxrb.write(output_path) do |wb|
4297
- wb.sheet("Red Tab") do |s|
4298
- s.column(0, width: 25)
4299
- s.column(1, width: 25)
4300
- s.sheet_properties(:tab_color, :red)
4301
- s.row(["Red tab sheet"])
4302
- end
4303
- wb.sheet("Green Tab") do |s|
4304
- s.sheet_properties(:tab_color, :green)
4305
- s.row(["Green tab sheet"])
4306
- end
4307
- end
4308
-
4309
- # 2. Read the generated sheet and print sheet properties
4310
- puts "=== Read Validation ==="
4311
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
4312
- workbook = Xlsxrb.read(output_path).load
4313
- workbook.sheet_names.each do |s_name|
4314
- props = reader.sheet_properties(sheet: s_name)
4315
- puts "Sheet: #{s_name}, tab color: #{props[:tab_color].inspect}"
4316
- end
4317
- ```
4318
-
4319
- ### Console Output
4320
-
4321
- ```text
4322
- === Read Validation ===
4323
- Sheet: Red Tab, tab color: "red"
4324
- Sheet: Green Tab, tab color: "green"
4325
- ```
4326
-
4327
- <hr/>
4328
-
4329
- ## Sparkline Column
4330
-
4331
- Demonstrates embedded column sparklines in cell ranges.
4332
-
4333
- ### Rendered Output (LibreOffice Calc)
4334
-
4335
- <div><img src="../../test/visual/baselines/sparkline_column/page-1.png" width="100%" alt="Preview"/></div>
4336
-
4337
- ### DSL Code
4338
-
4339
- ```ruby
4340
- # frozen_string_literal: true
4341
-
4342
- require "xlsxrb"
4343
- output_path = ARGV[0] || "sparkline_column.xlsx"
4344
- Xlsxrb.write(output_path) do |wb|
4345
- wb.sheet("Sparkline") do |s|
4346
- s.sheet_properties(:fit_to_page, true)
4347
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
4348
- s.column(0, width: 25)
4349
- s.column(1, width: 25)
4350
- s.row([5, 12, 8, 15, nil])
4351
- s.sparkline_group(
4352
- type: :column,
4353
- sparklines: [{ location_ref: "E1", data_ref: "Sparkline!A1:D1" }]
4354
- )
4355
- end
4356
- end
4357
-
4358
- # 2. Read the generated sheet and print cell values
4359
- puts "=== Read Validation ==="
4360
- workbook = Xlsxrb.read(output_path).load
4361
- sheet = workbook.sheets.first
4362
- sheet.rows.first(3).each do |row|
4363
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
4364
- puts "Row #{row.index}: #{row_cells.join(", ")}"
4365
- end
4366
- ```
4367
-
4368
- ### Console Output
4369
-
4370
- ```text
4371
- === Read Validation ===
4372
- Row 0: A1: 5, B1: 12, C1: 8, D1: 15
4373
- ```
4374
-
4375
- <hr/>
4376
-
4377
- ## Sparkline Line
4378
-
4379
- Demonstrates embedded line sparklines in cell ranges.
4380
-
4381
- ### Rendered Output (LibreOffice Calc)
4382
-
4383
- <div><img src="../../test/visual/baselines/sparkline_line/page-1.png" width="100%" alt="Preview"/></div>
4384
-
4385
- <div><img src="../../test/visual/support/illustrations/sparkline_line_page-2.png" width="100%" alt="Preview"/></div>
4386
-
4387
- ### DSL Code
4388
-
4389
- ```ruby
4390
- # frozen_string_literal: true
4391
-
4392
- require "xlsxrb"
4393
- output_path = ARGV[0] || "sparkline_line.xlsx"
4394
- Xlsxrb.write(output_path) do |wb|
4395
- wb.sheet("Sparkline") do |s|
4396
- s.sheet_properties(:fit_to_page, true)
4397
- s.page_setup(fit_to_width: 1, fit_to_height: 1)
4398
- s.column(0, width: 25)
4399
- s.column(1, width: 25)
4400
- s.row([10, 20, 15, 30, nil])
4401
- s.sparkline_group(
4402
- type: :line,
4403
- markers: true,
4404
- color_series: "FF000000",
4405
- color_markers: :red,
4406
- sparklines: [{ location_ref: "E1", data_ref: "Sparkline!A1:D1" }]
4407
- )
4408
- end
4409
- end
4410
-
4411
- # 2. Read the generated sheet and print cell values
4412
- puts "=== Read Validation ==="
4413
- workbook = Xlsxrb.read(output_path).load
4414
- sheet = workbook.sheets.first
4415
- sheet.rows.first(3).each do |row|
4416
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
4417
- puts "Row #{row.index}: #{row_cells.join(", ")}"
4418
- end
4419
- ```
4420
-
4421
- ### Console Output
4422
-
4423
- ```text
4424
- === Read Validation ===
4425
- Row 0: A1: 10, B1: 20, C1: 15, D1: 30
4426
- ```
4427
-
4428
- <hr/>
4429
-
4430
- ## Styles Fonts Fills
4431
-
4432
- Demonstrates cell formatting, including custom font sizing, bold/italic text, custom text colors, and background fill colors.
4433
-
4434
- ### Rendered Output (LibreOffice Calc)
4435
-
4436
- <div><img src="../../test/visual/baselines/styles_fonts_fills/page-1.png" width="100%" alt="Preview"/></div>
4437
-
4438
- ### DSL Code
4439
-
4440
- ```ruby
4441
- # frozen_string_literal: true
4442
-
4443
- require "xlsxrb"
4444
-
4445
- output_path = ARGV[0] || "styles_fonts_fills.xlsx"
4446
-
4447
- Xlsxrb.write(output_path) do |wb|
4448
- wb.style("header") do |style|
4449
- style.bold.size(14).font_color("FFFFFFFF").fill_color("FF4F81BD")
4450
- end
4451
-
4452
- wb.style("highlight") do |style|
4453
- style.italic.font_color("FFC00000").fill_color("FFFFFF00")
4454
- end
4455
-
4456
- wb.sheet("Styles") do |sheet|
4457
- sheet.column(0, width: 25)
4458
- sheet.column(1, width: 25)
4459
- sheet.row(["Header 1", "Header 2"], styles: { 0 => "header", 1 => "header" })
4460
- sheet.row(["Normal Text", "Highlighted Text"], styles: { 1 => "highlight" })
4461
- end
4462
- end
4463
-
4464
- # 2. Read the generated sheet and print styling details
4465
- puts "=== Read Validation ==="
4466
- workbook = Xlsxrb.read(output_path).load
4467
- sheet = workbook.sheets.first
4468
- sheet.rows.first(4).each do |row|
4469
- row_cells = row.cells.map do |c|
4470
- xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
4471
- font = xf ? workbook.styles[:fonts][xf[:font_id]] : nil
4472
- fill = xf ? workbook.styles[:fills][xf[:fill_id]] : nil
4473
- "#{c.ref}: #{c.value.inspect} (font=#{font&.[](:name)}, fill=#{fill&.[](:fg_color)&.[](:rgb)})"
4474
- end
4475
- puts "Row #{row.index}: #{row_cells.join(", ")}"
4476
- end
4477
- ```
4478
-
4479
- ### Console Output
4480
-
4481
- ```text
4482
- === Read Validation ===
4483
- Row 0: A1: "Header 1" (font=Calibri, fill=FF4F81BD), B1: "Header 2" (font=Calibri, fill=FF4F81BD)
4484
- Row 1: A2: "Normal Text" (font=, fill=), B2: "Highlighted Text" (font=Calibri, fill=FFFFFF00)
4485
- ```
4486
-
4487
- <hr/>
4488
-
4489
- ## Table Styles
4490
-
4491
- Visual demonstration for Table Styles.
4492
-
4493
- ### Rendered Output (LibreOffice Calc)
4494
-
4495
- <div><img src="../../test/visual/baselines/table_styles/page-1.png" width="100%" alt="Preview"/></div>
4496
-
4497
- <div><img src="../../test/visual/baselines/table_styles/page-2.png" width="100%" alt="Preview"/></div>
4498
-
4499
- ### DSL Code
4500
-
4501
- ```ruby
4502
- # frozen_string_literal: true
4503
-
4504
- require "xlsxrb"
4505
-
4506
- output_path = ARGV[0] || "table_styles.xlsx"
4507
-
4508
- Xlsxrb.write(output_path) do |wb|
4509
- wb.sheet("Table Example") do |sheet|
4510
- sheet.column(0..3, width: 20)
4511
- sheet.row(%w[ID Name Department Salary])
4512
- sheet.row([101, "Alice Smith", "Engineering", 120_000])
4513
- sheet.row([102, "Bob Jones", "Marketing", 95_000])
4514
- sheet.row([103, "Carol White", "Sales", 110_000])
4515
- sheet.row([104, "David Brown", "Engineering", 130_000])
4516
-
4517
- sheet.table("A1:D5", columns: %w[ID Name Department Salary], name: "EmployeeTable", style: "TableStyleMedium9", total_row: false)
4518
- end
4519
- end
4520
-
4521
- puts "=== Read Validation ==="
4522
- workbook = Xlsxrb.read(output_path).load
4523
- sheet = workbook.sheets.first
4524
- sheet.rows.each do |row|
4525
- row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
4526
- puts "Row #{row.index}: #{row_cells.join(", ")}"
4527
- end
4528
- ```
4529
-
4530
- ### Console Output
4531
-
4532
- ```text
4533
- === Read Validation ===
4534
- Row 0: A1: "ID", B1: "Name", C1: "Department", D1: "Salary"
4535
- Row 1: A2: 101, B2: "Alice Smith", C2: "Engineering", D2: 120000
4536
- Row 2: A3: 102, B3: "Bob Jones", C3: "Marketing", D3: 95000
4537
- Row 3: A4: 103, B4: "Carol White", C4: "Sales", D4: 110000
4538
- Row 4: A5: 104, B5: "David Brown", C5: "Engineering", D5: 130000
4539
- ```
4540
-
4541
- <hr/>
4542
-
4543
- ## View Show Grid Lines
4544
-
4545
- Demonstrates disabling visible grid lines in spreadsheet view.
4546
-
4547
- ### Rendered Output (LibreOffice Calc)
4548
-
4549
- <div><img src="../../test/visual/baselines/view_show_grid_lines/page-1.png" width="100%" alt="Preview"/></div>
4550
-
4551
- <div><img src="../../test/visual/support/illustrations/view_show_grid_lines_page-2.png" width="100%" alt="Preview"/></div>
4552
-
4553
- ### DSL Code
4554
-
4555
- ```ruby
4556
- # frozen_string_literal: true
4557
-
4558
- require "xlsxrb"
4559
- output_path = ARGV[0] || "view_show_grid_lines.xlsx"
4560
- Xlsxrb.write(output_path) do |wb|
4561
- wb.sheet("Hide Grid Lines") do |s|
4562
- s.column(0, width: 25)
4563
- s.column(1, width: 25)
4564
- s.sheet_view(:show_grid_lines, false)
4565
- s.row(["No Grid Lines displayed"])
4566
- end
4567
- end
4568
-
4569
- # 2. Read the generated sheet and print view configurations
4570
- puts "=== Read Validation ==="
4571
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
4572
- workbook = Xlsxrb.read(output_path).load
4573
- workbook.sheet_names.each do |s_name|
4574
- view = reader.sheet_view(sheet: s_name)
4575
- puts "Sheet '#{s_name}' views zoom scale: #{view[:zoom_scale]}%, show grid lines: #{view[:show_grid_lines]}"
4576
- end
4577
- ```
4578
-
4579
- ### Console Output
4580
-
4581
- ```text
4582
- === Read Validation ===
4583
- Sheet 'Hide Grid Lines' views zoom scale: %, show grid lines: false
4584
- ```
4585
-
4586
- <hr/>
4587
-
4588
- ## View Zoom Scale
4589
-
4590
- Demonstrates setting custom zoom scale in sheet view (e.g. 150%).
4591
-
4592
- ### Rendered Output (LibreOffice Calc)
4593
-
4594
- <div><img src="../../test/visual/baselines/view_zoom_scale/page-1.png" width="100%" alt="Preview"/></div>
4595
-
4596
- <div><img src="../../test/visual/support/illustrations/view_zoom_scale_page-2.png" width="100%" alt="Preview"/></div>
4597
-
4598
- ### DSL Code
4599
-
4600
- ```ruby
4601
- # frozen_string_literal: true
4602
-
4603
- require "xlsxrb"
4604
- output_path = ARGV[0] || "view_zoom_scale.xlsx"
4605
- Xlsxrb.write(output_path) do |wb|
4606
- wb.sheet("Zoom 150") do |s|
4607
- s.column(0, width: 25)
4608
- s.column(1, width: 25)
4609
- s.sheet_view(:zoom_scale, 150)
4610
- s.row(["Zoom scale is set to 150%"])
4611
- end
4612
- end
4613
-
4614
- # 2. Read the generated sheet and print view configurations
4615
- puts "=== Read Validation ==="
4616
- reader = Xlsxrb::Ooxml::Reader.new(output_path)
4617
- workbook = Xlsxrb.read(output_path).load
4618
- workbook.sheet_names.each do |s_name|
4619
- view = reader.sheet_view(sheet: s_name)
4620
- puts "Sheet '#{s_name}' views zoom scale: #{view[:zoom_scale]}%, show grid lines: #{view[:show_grid_lines]}"
4621
- end
4622
- ```
4623
-
4624
- ### Console Output
4625
-
4626
- ```text
4627
- === Read Validation ===
4628
- Sheet 'Zoom 150' views zoom scale: 150%, show grid lines:
4629
- ```
4630
-
4631
- <hr/>
4632
-
4633
- ## Workbook Three Sheets
4634
-
4635
- Demonstrates creating workbooks with multiple worksheets.
4636
-
4637
- ### Rendered Output (LibreOffice Calc)
4638
-
4639
- <div><img src="../../test/visual/baselines/workbook_three_sheets/page-1.png" width="100%" alt="Preview"/></div>
4640
-
4641
- <div><img src="../../test/visual/baselines/workbook_three_sheets/page-2.png" width="100%" alt="Preview"/></div>
4642
-
4643
- <div><img src="../../test/visual/baselines/workbook_three_sheets/page-3.png" width="100%" alt="Preview"/></div>
4644
-
4645
- ### DSL Code
4646
-
4647
- ```ruby
4648
- # frozen_string_literal: true
4649
-
4650
- require "xlsxrb"
4651
- output_path = ARGV[0] || "workbook_three_sheets.xlsx"
4652
- Xlsxrb.write(output_path) do |wb|
4653
- wb.sheet("First Sheet") { |s| s.row(["First Sheet Data"]) }
4654
- wb.sheet("Second Sheet") { |s| s.row(["Second Sheet Data"]) }
4655
- wb.sheet("Third Sheet") { |s| s.row(["Third Sheet Data"]) }
4656
- end
4657
-
4658
- # 2. Read the generated sheet and print the sheets structure
4659
- puts "=== Read Validation ==="
4660
- workbook = Xlsxrb.read(output_path).load
4661
- puts "Workbook sheets: #{workbook.sheet_names.join(", ")}"
4662
- ```
4663
-
4664
- ### Console Output
4665
-
4666
- ```text
4667
- === Read Validation ===
4668
- Workbook sheets: First Sheet, Second Sheet, Third Sheet
4669
- ```
4670
-
4671
- <hr/>
4672
-