Visual Examples Gallery

This gallery showcases xlsxrb DSL usage side-by-side with the visual rendering in LibreOffice Calc.

◄ Back to README

Capability Overview

Feature Visual Preview Link to Detail
Align Horizontal Align Horizontal View Code & Detail
Align Horizontal Fill Align Horizontal Fill View Code & Detail
Align Horizontal Justify Align Horizontal Justify View Code & Detail
Align Indent Align Indent View Code & Detail
Align Text Rotation Align Text Rotation View Code & Detail
Align Text Wrap Align Text Wrap View Code & Detail
Align Vertical Align Vertical View Code & Detail
Basic Data Basic Data View Code & Detail
Borders Borders View Code & Detail
Cell Booleans Cell Booleans View Code & Detail
Cell Dates Cell Dates View Code & Detail
Cell Formulas Cell Formulas View Code & Detail
Cell Num Currency Jpy Cell Num Currency Jpy View Code & Detail
Cell Num Custom Colors Cell Num Custom Colors View Code & Detail
Cell Num Fractions Cell Num Fractions View Code & Detail
Cell Num Percent Decimals Cell Num Percent Decimals View Code & Detail
Cell Num Scientific Cell Num Scientific View Code & Detail
Cell Numbers Cell Numbers View Code & Detail
Cell Rich Text Cell Rich Text View Code & Detail
Cell Times Cell Times View Code & Detail
Cf Begins With Cf Begins With View Code & Detail
Cf Cell Between Cf Cell Between View Code & Detail
Cf Cell Equal To Cf Cell Equal To View Code & Detail
Cf Cell Greater Equal Cf Cell Greater Equal View Code & Detail
Cf Cell Greater Than Cf Cell Greater Than View Code & Detail
Cf Cell Less Than Cf Cell Less Than View Code & Detail
Cf Color Scale Cf Color Scale View Code & Detail
Cf Contains Text Cf Contains Text View Code & Detail
Cf Data Bar Cf Data Bar View Code & Detail
Cf Ends With Cf Ends With View Code & Detail
Cf Expression Formula Cf Expression Formula View Code & Detail
Cf Icon Set Cf Icon Set View Code & Detail
Chart Area Chart Area View Code & Detail
Chart Area Stacked Chart Area Stacked View Code & Detail
Chart Bar Chart Bar View Code & Detail
Chart Bar Percent Stacked Chart Bar Percent Stacked View Code & Detail
Chart Bar Stacked Chart Bar Stacked View Code & Detail
Chart Doughnut Chart Doughnut View Code & Detail
Chart Line Chart Line View Code & Detail
Chart Line Stacked Chart Line Stacked View Code & Detail
Chart Pie Chart Pie View Code & Detail
Chart Radar Chart Radar View Code & Detail
Chart Scatter Chart Scatter View Code & Detail
Col Grouping Col Grouping View Code & Detail
Col Width Tall Col Width Tall View Code & Detail
Col Widths Col Widths View Code & Detail
Conditional Formatting Conditional Formatting View Code & Detail
Drawing Shapes Drawing Shapes View Code & Detail
Embedded Images Embedded Images View Code & Detail
Fill Gradients Fill Gradients View Code & Detail
Fill Patterns Fill Patterns View Code & Detail
Fill Solid Colors Fill Solid Colors View Code & Detail
Fonts Fonts View Code & Detail
Interactive Autofilter Interactive Autofilter View Code & Detail
Interactive Comments Interactive Comments View Code & Detail
Interactive Validation Custom Interactive Validation Custom View Code & Detail
Interactive Validation Date Interactive Validation Date View Code & Detail
Interactive Validation List Interactive Validation List View Code & Detail
Interactive Validation Range Interactive Validation Range View Code & Detail
Interactive Validation Text Length Interactive Validation Text Length View Code & Detail
Interactive Validation Time Interactive Validation Time View Code & Detail
Japanese Text Japanese Text View Code & Detail
Merge Freeze Merge Freeze View Code & Detail
Page Grid Lines Print Page Grid Lines Print View Code & Detail
Page Header Footer Page Header Footer View Code & Detail
Page Headings Print Page Headings Print View Code & Detail
Page Margins Narrow Page Margins Narrow View Code & Detail
Page Margins Wide Page Margins Wide View Code & Detail
Page Orientation Landscape Page Orientation Landscape View Code & Detail
Page Paper Size A3 Page Paper Size A3 View Code & Detail
Pivot Table Pivot Table View Code & Detail
Row Grouping Row Grouping View Code & Detail
Row Height Tall Row Height Tall View Code & Detail
Row Heights Row Heights View Code & Detail
Sheet Tab Colors Sheet Tab Colors View Code & Detail
Sparkline Column Sparkline Column View Code & Detail
Sparkline Line Sparkline Line View Code & Detail
Styles Fonts Fills Styles Fonts Fills View Code & Detail
Table Styles Table Styles View Code & Detail
View Show Grid Lines View Show Grid Lines View Code & Detail
View Zoom Scale View Zoom Scale View Code & Detail
Workbook Three Sheets Workbook Three Sheets View Code & Detail

Align Horizontal

Demonstrates horizontal text alignment (left, center, right).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "align_horizontal.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("left") { |s| s.align_horizontal("left") }
  wb.style("center") { |s| s.align_horizontal("center") }
  wb.style("right") { |s| s.align_horizontal("right") }
  wb.sheet("Alignment") do |s|
    s.print_options(:grid_lines, true)
    s.column(0, width: 20)
    s.column(1, width: 20)
    s.column(2, width: 20)
    s.row(%w[Left Center Right], styles: { 0 => "left", 1 => "center", 2 => "right" })
  end
end

# 2. Read the generated sheet and print the parsed alignments
puts "=== Read Alignment (Xlsxrb.read) ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first

row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  align_h = xf&.dig(:alignment, :horizontal)
  puts "Cell #{c.ref} ('#{c.value}'): align_horizontal = #{align_h.inspect}"
end

Console Output

=== Read Alignment (Xlsxrb.read) ===
Cell A1 ('Left'): align_horizontal = "left"
Cell B1 ('Center'): align_horizontal = "center"
Cell C1 ('Right'): align_horizontal = "right"

Align Horizontal Fill

Demonstrates horizontal fill alignment (repeats value to fill cell width).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "align_horizontal_fill.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("fill_align") { |s| s.align_horizontal("fill") }
  wb.sheet("Alignment") do |s|
    s.column(0, width: 30)
    s.row(["X "], styles: { 0 => "fill_align" })
  end
end

# 2. Read the generated sheet and print the parsed alignments
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  align_h = xf&.dig(:alignment, :horizontal)
  align_v = xf&.dig(:alignment, :vertical)
  wrap = xf&.dig(:alignment, :wrap_text)
  indent = xf&.dig(:alignment, :indent)
  rot = xf&.dig(:alignment, :text_rotation)
  shrink = xf&.dig(:alignment, :shrink_to_fit)
  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}"
end

Console Output

=== Read Validation ===
Cell A1 ('X '): align_h="fill", align_v=nil, wrap=nil, indent=nil, rotation=nil, shrink=nil

Align Horizontal Justify

Demonstrates horizontal justify text alignment.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "align_horizontal_justify.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("justify_align") do |s|
    s.align_horizontal("justify")
    s.wrap_text(true)
  end
  wb.sheet("Alignment") do |s|
    s.column(0, width: 25)
    s.row(["Justified alignment wraps and distributes text evenly."], styles: { 0 => "justify_align" })
  end
end

# 2. Read the generated sheet and print the parsed alignments
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  align_h = xf&.dig(:alignment, :horizontal)
  align_v = xf&.dig(:alignment, :vertical)
  wrap = xf&.dig(:alignment, :wrap_text)
  indent = xf&.dig(:alignment, :indent)
  rot = xf&.dig(:alignment, :text_rotation)
  shrink = xf&.dig(:alignment, :shrink_to_fit)
  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}"
end

Console Output

=== Read Validation ===
Cell A1 ('Justified alignment wraps and distributes text evenly.'): align_h="justify", align_v=nil, wrap=true, indent=nil, rotation=nil, shrink=nil

Align Indent

Demonstrates text indentation inside cells.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "align_indent.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("indent_1") { |s| s.align_horizontal("left").indent(1) }
  wb.style("indent_3") { |s| s.align_horizontal("left").indent(3) }
  wb.sheet("Indent") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.print_options(:grid_lines, true)
    s.row(["No Indent"])
    s.row(["Indent 1"], styles: { 0 => "indent_1" })
    s.row(["Indent 3"], styles: { 0 => "indent_3" })
  end
end

# 2. Read the generated sheet and print the parsed alignments
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  align_h = xf&.dig(:alignment, :horizontal)
  align_v = xf&.dig(:alignment, :vertical)
  wrap = xf&.dig(:alignment, :wrap_text)
  indent = xf&.dig(:alignment, :indent)
  rot = xf&.dig(:alignment, :text_rotation)
  shrink = xf&.dig(:alignment, :shrink_to_fit)
  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}"
end

Console Output

=== Read Validation ===
Cell A1 ('No Indent'): align_h=nil, align_v=nil, wrap=nil, indent=nil, rotation=nil, shrink=nil

Align Text Rotation

Demonstrates text rotated by specific angles (45, 90 degrees).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "align_text_rotation.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("rot_45") { |s| s.text_rotation(45) }
  wb.style("rot_90") { |s| s.text_rotation(90) }
  wb.sheet("Rotation") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.print_options(:grid_lines, true)
    s.row(["Rotated 45", "Rotated 90"], styles: { 0 => "rot_45", 1 => "rot_90" }, height: 50)
  end
end

# 2. Read the generated sheet and print the parsed alignments
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  align_h = xf&.dig(:alignment, :horizontal)
  align_v = xf&.dig(:alignment, :vertical)
  wrap = xf&.dig(:alignment, :wrap_text)
  indent = xf&.dig(:alignment, :indent)
  rot = xf&.dig(:alignment, :text_rotation)
  shrink = xf&.dig(:alignment, :shrink_to_fit)
  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}"
end

Console Output

=== Read Validation ===
Cell A1 ('Rotated 45'): align_h=nil, align_v=nil, wrap=nil, indent=nil, rotation=45, shrink=nil
Cell B1 ('Rotated 90'): align_h=nil, align_v=nil, wrap=nil, indent=nil, rotation=90, shrink=nil

Align Text Wrap

Demonstrates auto-wrapping multi-line text inside narrow cells.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "align_text_wrap.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("wrap", &:wrap_text)
  wb.sheet("Text Wrap") do |s|
    s.print_options(:grid_lines, true)
    s.column(0, width: 15)
    s.row(["This is a long sentence that wraps inside the cell."], styles: { 0 => "wrap" })
  end
end

# 2. Read the generated sheet and print the parsed alignments
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  align_h = xf&.dig(:alignment, :horizontal)
  align_v = xf&.dig(:alignment, :vertical)
  wrap = xf&.dig(:alignment, :wrap_text)
  indent = xf&.dig(:alignment, :indent)
  rot = xf&.dig(:alignment, :text_rotation)
  shrink = xf&.dig(:alignment, :shrink_to_fit)
  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}"
end

Console Output

=== Read Validation ===
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

Align Vertical

Demonstrates vertical text alignment (top, center, bottom).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "align_vertical.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("top") { |s| s.align_vertical("top") }
  wb.style("center") { |s| s.align_vertical("center") }
  wb.style("bottom") { |s| s.align_vertical("bottom") }
  wb.sheet("Vertical Alignment") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.print_options(:grid_lines, true)
    s.row(%w[Top Center Bottom], styles: { 0 => "top", 1 => "center", 2 => "bottom" }, height: 40)
  end
end

# 2. Read the generated sheet and print the parsed alignments
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  align_h = xf&.dig(:alignment, :horizontal)
  align_v = xf&.dig(:alignment, :vertical)
  wrap = xf&.dig(:alignment, :wrap_text)
  indent = xf&.dig(:alignment, :indent)
  rot = xf&.dig(:alignment, :text_rotation)
  shrink = xf&.dig(:alignment, :shrink_to_fit)
  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}"
end

Console Output

=== Read Validation ===
Cell A1 ('Top'): align_h=nil, align_v="top", wrap=nil, indent=nil, rotation=nil, shrink=nil
Cell B1 ('Center'): align_h=nil, align_v="center", wrap=nil, indent=nil, rotation=nil, shrink=nil
Cell C1 ('Bottom'): align_h=nil, align_v="bottom", wrap=nil, indent=nil, rotation=nil, shrink=nil

Basic Data

Demonstrates simple tabular data writing with basic Ruby types (Strings, Numbers, Dates, Booleans).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
require "date"

output_path = ARGV[0] || "basic_data.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.style("currency") { |style| style.number_format("$#,##0.00") }
  wb.style("date") { |style| style.number_format("yyyy-mm-dd") }
  wb.sheet("Basic Data") do |sheet|
    sheet.sheet_properties(:fit_to_page, true)
    sheet.page_setup(fit_to_width: 1, fit_to_height: 1)
    sheet.column(0, width: 25)
    sheet.column(1, width: 25)
    sheet.row(%w[Product Qty Price Date Active])
    sheet.row(["Gadget A", 10, 99.99, Date.new(2026, 1, 15), true], styles: { 2 => "currency", 3 => "date" })
    sheet.row(["Widget B", 5, 49.50, Date.new(2026, 2, 20), false], styles: { 2 => "currency", 3 => "date" })
  end
end

# 2. Read the generated sheet and print parsed cell values and Ruby classes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Product" (String), B1: "Qty" (String), C1: "Price" (String), D1: "Date" (String), E1: "Active" (String)
Row 1: A2: "Gadget A" (String), B2: 10 (Integer), C2: 99.99 (Float), D2: 46037 (Integer), E2: true (TrueClass)
Row 2: A3: "Widget B" (String), B3: 5 (Integer), C3: 49.5 (Float), D3: 46073 (Integer), E3: false (FalseClass)

Borders

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.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "borders.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.style("thin") { |s| s.border_all(style: "thin", color: "FF000000") }
  wb.style("medium") { |s| s.border_all(style: "medium", color: "FF000000") }
  wb.style("thick") { |s| s.border_all(style: "thick", color: "FF000000") }
  wb.style("hair") { |s| s.border_all(style: "hair", color: "FF000000") }
  wb.style("dashed") { |s| s.border_all(style: "dashed", color: "FF000000") }
  wb.style("medium_dashed") { |s| s.border_all(style: "mediumDashed", color: "FF000000") }
  wb.style("dotted") { |s| s.border_all(style: "dotted", color: "FF000000") }
  wb.style("double") { |s| s.border_all(style: "double", color: "FF000000") }
  wb.style("dash_dot") { |s| s.border_all(style: "dashDot", color: "FF000000") }
  wb.style("medium_dash_dot") { |s| s.border_all(style: "mediumDashDot", color: "FF000000") }
  wb.style("dash_dot_dot") { |s| s.border_all(style: "dashDotDot", color: "FF000000") }
  wb.style("slanted") { |s| s.border_all(style: "slantedDashDot", color: "FF000000") }
  wb.style("diagonal") { |s| s.border_diagonal(style: "thin", color: "FF000000", up: true, down: true) }

  wb.sheet("Borders") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.print_options(:grid_lines, true)

    s.row(["Border Style", "Cell Preview"])
    s.row(["Thin", "Thin Border"], styles: { 1 => "thin" })
    s.row(["Medium", "Medium Border"], styles: { 1 => "medium" })
    s.row(["Thick", "Thick Border"], styles: { 1 => "thick" })
    s.row(["Hair", "Hair Border"], styles: { 1 => "hair" })
    s.row(["Dashed", "Dashed Border"], styles: { 1 => "dashed" })
    s.row(["Medium Dashed", "Medium Dashed"], styles: { 1 => "medium_dashed" })
    s.row(["Dotted", "Dotted Border"], styles: { 1 => "dotted" })
    s.row(["Double", "Double Border"], styles: { 1 => "double" })
    s.row(["Dash-Dot", "Dash-Dot Border"], styles: { 1 => "dash_dot" })
    s.row(["Medium Dash-Dot", "Medium Dash-Dot"], styles: { 1 => "medium_dash_dot" })
    s.row(%w[Dash-Dot-Dot Dash-Dot-Dot], styles: { 1 => "dash_dot_dot" })
    s.row(["Slanted Dash-Dot", "Slanted Border"], styles: { 1 => "slanted" })
    s.row(["Diagonal (Cross)", "Diagonal Border"], styles: { 1 => "diagonal" })
  end
end

# Read check
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
    border_id = xf ? xf[:border_id] : 0
    "#{c.ref}: #{c.value.inspect} (border_id: #{border_id})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Border Style" (border_id: 0), B1: "Cell Preview" (border_id: 0)
Row 1: A2: "Thin" (border_id: 0), B2: "Thin Border" (border_id: 1)
Row 2: A3: "Medium" (border_id: 0), B3: "Medium Border" (border_id: 2)
Row 3: A4: "Thick" (border_id: 0), B4: "Thick Border" (border_id: 3)
Row 4: A5: "Hair" (border_id: 0), B5: "Hair Border" (border_id: 4)
Row 5: A6: "Dashed" (border_id: 0), B6: "Dashed Border" (border_id: 5)
Row 6: A7: "Medium Dashed" (border_id: 0), B7: "Medium Dashed" (border_id: 6)
Row 7: A8: "Dotted" (border_id: 0), B8: "Dotted Border" (border_id: 7)
Row 8: A9: "Double" (border_id: 0), B9: "Double Border" (border_id: 8)
Row 9: A10: "Dash-Dot" (border_id: 0), B10: "Dash-Dot Border" (border_id: 9)
Row 10: A11: "Medium Dash-Dot" (border_id: 0), B11: "Medium Dash-Dot" (border_id: 10)
Row 11: A12: "Dash-Dot-Dot" (border_id: 0), B12: "Dash-Dot-Dot" (border_id: 11)
Row 12: A13: "Slanted Dash-Dot" (border_id: 0), B13: "Slanted Border" (border_id: 12)
Row 13: A14: "Diagonal (Cross)" (border_id: 0), B14: "Diagonal Border" (border_id: 13)

Cell Booleans

Demonstrates boolean values serialized and rendered.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_booleans.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Booleans") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Label", "Boolean Value"])
    s.row(["Is Active", true])
    s.row(["Is Pending", false])
  end
end

# 2. Read the generated sheet and print parsed cell values and Ruby classes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Label" (String), B1: "Boolean Value" (String)
Row 1: A2: "Is Active" (String), B2: true (TrueClass)
Row 2: A3: "Is Pending" (String), B3: false (FalseClass)

Cell Dates

Demonstrates dates serialized natively and formatted with standard or custom format strings.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
require "date"
output_path = ARGV[0] || "cell_dates.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("custom_date") { |s| s.num_fmt("yyyy-mm-dd") }
  wb.sheet("Dates") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Format", "Date Value"])
    s.row(["Default Date", Date.new(2026, 7, 1)])
    s.row(["Formatted Date", Date.new(2026, 12, 25)], styles: { 1 => "custom_date" })
  end
end

# 2. Read the generated sheet and print parsed cell values and Ruby classes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (String), B1: "Date Value" (String)
Row 1: A2: "Default Date" (String), B2: 46204 (Integer)
Row 2: A3: "Formatted Date" (String), B3: 46381 (Integer)

Cell Formulas

Demonstrates standard spreadsheet calculations and formulas (SUM, AVERAGE).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_formulas.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Formulas") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Item Value])
    s.row(["A", 10])
    s.row(["B", 20])
    s.row(["SUM", Xlsxrb::Elements::Formula.new(expression: "SUM(B2:B3)", cached_value: 30)])
    s.row(["AVERAGE", Xlsxrb::Elements::Formula.new(expression: "AVERAGE(B2:B3)", cached_value: 15)])
  end
end

# 2. Read the generated sheet and print parsed cell values and Ruby classes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Item" (String), B1: "Value" (String)
Row 1: A2: "A" (String), B2: 10 (Integer)
Row 2: A3: "B" (String), B3: 20 (Integer)
Row 3: A4: "SUM" (String), B4: 30 (Integer)
Row 4: A5: "AVERAGE" (String), B5: 15 (Integer)

Cell Num Currency Jpy

Demonstrates Yen Currency format code formatting.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_num_currency_jpy.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("jpy") { |s| s.num_fmt("¥#,##0;[Red]¥-#,##0") }
  wb.sheet("JPY Currency") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Format Value])
    s.row(["Positive Yen", 12_500], styles: { 1 => "jpy" })
    s.row(["Negative Yen", -8000], styles: { 1 => "jpy" })
  end
end

# 2. Read the generated sheet and print parsed cell numbers and format codes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
    num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
    "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
Row 1: A2: "Positive Yen" (Format ID: , Code: nil), B2: 12500 (Format ID: 164, Code: "¥#,##0;[Red]¥-#,##0")
Row 2: A3: "Negative Yen" (Format ID: , Code: nil), B3: -8000 (Format ID: 164, Code: "¥#,##0;[Red]¥-#,##0")

Cell Num Custom Colors

Demonstrates custom colored formats for positive and negative numbers.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_num_custom_colors.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("custom_color") { |s| s.num_fmt("[Green]#,##0;[Red]-#,##0") }
  wb.sheet("Custom Colors") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Format Value])
    s.row(["Positive (Green)", 5000], styles: { 1 => "custom_color" })
    s.row(["Negative (Red)", -2500], styles: { 1 => "custom_color" })
  end
end

# 2. Read the generated sheet and print parsed cell numbers and format codes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
    num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
    "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
Row 1: A2: "Positive (Green)" (Format ID: , Code: nil), B2: 5000 (Format ID: 164, Code: "[Green]#,##0;[Red]-#,##0")
Row 2: A3: "Negative (Red)" (Format ID: , Code: nil), B3: -2500 (Format ID: 164, Code: "[Green]#,##0;[Red]-#,##0")

Cell Num Fractions

Demonstrates fraction number formats (# ?/?).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_num_fractions.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("frac") { |s| s.num_fmt("# ?/?") }
  wb.sheet("Fractions") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Format Value])
    s.row(["Half", 0.5], styles: { 1 => "frac" })
    s.row(["Third", 0.3333], styles: { 1 => "frac" })
    s.row(["Quarter", 0.75], styles: { 1 => "frac" })
  end
end

# 2. Read the generated sheet and print parsed cell numbers and format codes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
    num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
    "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
Row 1: A2: "Half" (Format ID: , Code: nil), B2: 0.5 (Format ID: 164, Code: "# ?/?")
Row 2: A3: "Third" (Format ID: , Code: nil), B3: 0.3333 (Format ID: 164, Code: "# ?/?")
Row 3: A4: "Quarter" (Format ID: , Code: nil), B4: 0.75 (Format ID: 164, Code: "# ?/?")

Cell Num Percent Decimals

Demonstrates percentages with two decimal places (0.00%).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_num_percent_decimals.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("pct2") { |s| s.num_fmt("0.00%") }
  wb.sheet("Percents") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Format Value])
    s.row(["Percent with 2 Decimals", 0.12345], styles: { 1 => "pct2" })
  end
end

# 2. Read the generated sheet and print parsed cell numbers and format codes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
    num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
    "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
Row 1: A2: "Percent with 2 Decimals" (Format ID: , Code: nil), B2: 0.12345 (Format ID: 164, Code: "0.00%")

Cell Num Scientific

Demonstrates scientific number formats (0.00E+00).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_num_scientific.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("sci") { |s| s.num_fmt("0.00E+00") }
  wb.sheet("Scientific") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Format Value])
    s.row(["Scientific", 123_456_789.0], styles: { 1 => "sci" })
    s.row(["Small Scientific", 0.00001234], styles: { 1 => "sci" })
  end
end

# 2. Read the generated sheet and print parsed cell numbers and format codes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
    num_fmt = xf ? workbook.styles[:num_fmts][xf[:num_fmt_id]] : nil
    "#{c.ref}: #{c.value.inspect} (Format ID: #{xf&.[](:num_fmt_id)}, Code: #{num_fmt.inspect})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (Format ID: , Code: nil), B1: "Value" (Format ID: , Code: nil)
Row 1: A2: "Scientific" (Format ID: , Code: nil), B2: 123456789.0 (Format ID: 164, Code: "0.00E+00")
Row 2: A3: "Small Scientific" (Format ID: , Code: nil), B3: 1.234e-05 (Format ID: 164, Code: "0.00E+00")

Cell Numbers

Demonstrates custom formatting for integers, floating point numbers, currencies, and percentages.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_numbers.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("currency") { |s| s.num_fmt("$#,##0.00") }
  wb.style("percent") { |s| s.num_fmt("0.0%") }
  wb.sheet("Numbers") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Format Value])
    s.row(["Integer", 12_345])
    s.row(["Float", 123.456])
    s.row(["Currency", 1234.5], styles: { 1 => "currency" })
    s.row(["Percentage", 0.85], styles: { 1 => "percent" })
  end
end

# 2. Read the generated sheet and print parsed cell values and Ruby classes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (String), B1: "Value" (String)
Row 1: A2: "Integer" (String), B2: 12345 (Integer)
Row 2: A3: "Float" (String), B3: 123.456 (Float)
Row 3: A4: "Currency" (String), B4: 1234.5 (Float)
Row 4: A5: "Percentage" (String), B5: 0.85 (Float)

Cell Rich Text

Demonstrates Rich Text cells with multiple font weights, styles, and colors in a single cell.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cell_rich_text.xlsx"
Xlsxrb.write(output_path) do |wb|
  rt = Xlsxrb.rich_text(
    { text: "Normal " },
    { text: "BOLD RED ", font: { bold: true, color: "FFC00000", sz: 16 } },
    { text: "ITALIC BLUE", font: { italic: true, color: :blue, sz: 20 } }
  )
  wb.sheet("Rich Text") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Format Value])
    s.row(["Rich Text Cell", rt])
  end
end

# 2. Read the generated sheet and print parsed cell values and Ruby classes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (String), B1: "Value" (String)
Row 1: A2: "Rich Text Cell" (String), B2: "Normal BOLD RED ITALIC BLUE" (String)

Cell Times

Demonstrates timestamp values serialized natively and formatted showing hours, minutes, and seconds.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
require "time"
output_path = ARGV[0] || "cell_times.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("time_fmt") { |s| s.num_fmt("hh:mm:ss") }
  wb.sheet("Times") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Format", "Time Value"])
    s.row(["DateTime", Time.new(2026, 7, 1, 12, 34, 56)])
    s.row(["Time Only", Time.new(2026, 7, 1, 9, 15, 0)], styles: { 1 => "time_fmt" })
  end
end

# 2. Read the generated sheet and print parsed cell values and Ruby classes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Format" (String), B1: "Time Value" (String)
Row 1: A2: "DateTime" (String), B2: 46204.52425925926 (Float)
Row 2: A3: "Time Only" (String), B3: 46204.385416666664 (Float)

Cf Begins With

Demonstrates conditional formatting highlighting cells starting with specific text.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_begins_with.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("CF Begins") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Code"])
    s.row(["A-100"])
    s.row(["B-200"])
    s.row(["A-300"])
    s.conditional_format("A2:A4", type: "beginsWith", operator: "beginsWith", text: "A", formula: 'LEFT(A2,1)="A"', fill_color: "FFFFC7CE")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Code"
Row 1: A2: "A-100"
Row 2: A3: "B-200"
Row 3: A4: "A-300"

Cf Cell Between

Demonstrates conditional formatting highlighting cells within a range.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_cell_between.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("CF Between") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Values"])
    s.row([15], styles: "center")
    s.row([25], styles: "center")
    s.row([5], styles: "center")
    s.conditional_format("A2:A4", type: "cellIs", operator: "between", formulas: %w[10 20], fill_color: :green)
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Values"
Row 1: A2: 15
Row 2: A3: 25
Row 3: A4: 5

Cf Cell Equal To

Demonstrates conditional formatting highlighting cells equal to a target value.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_cell_equal_to.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("CF Equal") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Values"])
    s.row([10], styles: "center")
    s.row([20], styles: "center")
    s.row([10], styles: "center")
    s.conditional_format("A2:A4", type: "cellIs", operator: "equal", formula: "10", fill_color: "FFFFC7CE")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Values"
Row 1: A2: 10
Row 2: A3: 20
Row 3: A4: 10

Cf Cell Greater Equal

Demonstrates conditional formatting highlighting cells greater than or equal to a threshold.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_cell_greater_equal.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("CF Greater Equal") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Values"])
    s.row([10], styles: "center")
    s.row([50], styles: "center")
    s.row([100], styles: "center")
    s.conditional_format("A2:A4", type: "cellIs", operator: "greaterThanOrEqual", formula: "50", fill_color: "FFFFC7CE")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Values"
Row 1: A2: 10
Row 2: A3: 50
Row 3: A4: 100

Cf Cell Greater Than

Demonstrates conditional formatting highlighting cells greater than a threshold.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_cell_greater_than.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("CF Greater") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Values"])
    s.row([25], styles: "center")
    s.row([75], styles: "center")
    s.row([10], styles: "center")
    s.conditional_format("A2:A4", type: "cellIs", operator: "greaterThan", formula: "50", fill_color: "FFFFC7CE")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Values"
Row 1: A2: 25
Row 2: A3: 75
Row 3: A4: 10

Cf Cell Less Than

Demonstrates conditional formatting highlighting cells less than a threshold.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_cell_less_than.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("CF Less") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Values"])
    s.row([25], styles: "center")
    s.row([75], styles: "center")
    s.row([10], styles: "center")
    s.conditional_format("A2:A4", type: "cellIs", operator: "lessThan", formula: "20", fill_color: "FFFFC7CE")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Values"
Row 1: A2: 25
Row 2: A3: 75
Row 3: A4: 10

Cf Color Scale

Demonstrates color scale/heatmap conditional formatting.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_color_scale.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("Colors") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row([10], styles: "center")
    s.row([50], styles: "center")
    s.row([90], styles: "center")
    s.conditional_format("A1:A3", type: :colorScale, priority: 1)
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: 10
Row 1: A2: 50
Row 2: A3: 90

Cf Contains Text

Demonstrates conditional formatting highlighting cells containing specific text.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_contains_text.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("CF Contains") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Status"])
    s.row(["Error"])
    s.row(["Success"])
    s.row(["Pending"])
    s.conditional_format("A2:A4", type: "containsText", operator: "containsText", text: "Error", formula: 'NOT(ISERROR(SEARCH("Error",A2)))', fill_color: :red)
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Status"
Row 1: A2: "Error"
Row 2: A3: "Success"
Row 3: A4: "Pending"

Cf Data Bar

Demonstrates data bar visual conditional formatting indicators.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_data_bar.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("Data Bars") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row([20], styles: "center")
    s.row([60], styles: "center")
    s.row([100], styles: "center")
    s.conditional_format("A1:A3", type: :dataBar, priority: 1, color: "FF0070C0")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: 20
Row 1: A2: 60
Row 2: A3: 100

Cf Ends With

Demonstrates conditional formatting highlighting cells ending with specific text.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_ends_with.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("CF Ends") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Code"])
    s.row(["100-Z"])
    s.row(["200-Y"])
    s.row(["300-Z"])
    s.conditional_format("A2:A4", type: "endsWith", operator: "endsWith", text: "Z", formula: 'RIGHT(A2,1)="Z"', fill_color: "FFFFC7CE")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Code"
Row 1: A2: "100-Z"
Row 2: A3: "200-Y"
Row 3: A4: "300-Z"

Cf Expression Formula

Demonstrates conditional formatting using a custom formula expression.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_expression_formula.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("CF Expression") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Values"])
    s.row([10], styles: "center")
    s.row([20], styles: "center")
    s.row([30], styles: "center")
    s.row([100], styles: "center") # Average is 40. 100 is above average.
    s.conditional_format("A2:A5", type: "expression", formula: "A2>AVERAGE($A$2:$A$5)", fill_color: "FFFFC7CE")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Values"
Row 1: A2: 10
Row 2: A3: 20
Row 3: A4: 30
Row 4: A5: 100

Cf Icon Set

Demonstrates icon set indicators (red/yellow/green arrows).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "cf_icon_set.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("Icons") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row([25], styles: "center")
    s.row([50], styles: "center")
    s.row([75], styles: "center")
    s.conditional_format("A1:A3", type: :iconSet, icon_style: "3Arrows", priority: 1)
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: 25
Row 1: A2: 50
Row 2: A3: 75

Chart Area

Demonstrates embedding a standard 2D Area Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_area.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Day Value])
    s.row(["Mon", 10])
    s.row(["Tue", 15])
    s.chart(
      type: :area,
      title: "Daily Area",
      from_col: 3, from_row: 0, to_col: 8, to_row: 12,
      series: [{ cat_ref: "Data!$A$2:$A$3", val_ref: "Data!$B$2:$B$3", fill_color: "4F81BD" }]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Area Stacked

Demonstrates embedding a stacked 2D Area Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_area_stacked.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Year", "Sales A", "Sales B"])
    s.row([2024, 100, 150])
    s.row([2025, 120, 180])
    s.row([2026, 140, 210])
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.chart(
      type: :area,
      grouping: :stacked,
      title: "Stacked Area Chart",
      from_col: 0, from_row: 5, to_col: 6, to_row: 17,
      series: [
        { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$B$2:$B$4", name: "'Data'!$B$1", fill_color: "4F81BD" },
        { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$C$2:$C$4", name: "'Data'!$C$1", fill_color: "C0504D" }
      ]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Bar

Demonstrates embedding a standard 2D Bar Chart referencing worksheet cell ranges.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "chart_bar.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.sheet("Sales Data") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Month Value])
    s.row(["Jan", 100])
    s.row(["Feb", 200])

    s.chart(
      type: :bar,
      title: "Monthly Sales",
      from_col: 3,
      from_row: 0,
      to_col: 8,
      to_row: 12,
      series: [
        { cat_ref: "'Sales Data'!$A$2:$A$3", val_ref: "'Sales Data'!$B$2:$B$3", fill_color: "4F81BD" }
      ]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Sales Data' has 0 chart(s)

Chart Bar Percent Stacked

Demonstrates embedding a 100% stacked 2D Bar Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_bar_percent_stacked.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Year", "Sales A", "Sales B"])
    s.row([2024, 100, 150])
    s.row([2025, 120, 180])
    s.row([2026, 140, 210])
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.chart(
      type: :bar,
      grouping: :percentStacked,
      title: "100% Stacked Bar Chart",
      from_col: 0, from_row: 5, to_col: 6, to_row: 17,
      series: [
        { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$B$2:$B$4", name: "'Data'!$B$1", fill_color: "4F81BD" },
        { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$C$2:$C$4", name: "'Data'!$C$1", fill_color: "C0504D" }
      ]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Bar Stacked

Demonstrates embedding a stacked 2D Bar Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_bar_stacked.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Year", "Sales A", "Sales B"])
    s.row([2024, 100, 150])
    s.row([2025, 120, 180])
    s.row([2026, 140, 210])
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.chart(
      type: :bar,
      grouping: :stacked,
      title: "Stacked Bar Chart",
      from_col: 0, from_row: 5, to_col: 6, to_row: 17,
      series: [
        { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$B$2:$B$4", name: "'Data'!$B$1", fill_color: "4F81BD" },
        { cat_ref: "'Data'!$A$2:$A$4", val_ref: "'Data'!$C$2:$C$4", name: "'Data'!$C$1", fill_color: "C0504D" }
      ]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Doughnut

Demonstrates embedding a standard 2D Doughnut Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_doughnut.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Label Percent])
    s.row(["A", 40])
    s.row(["B", 60])
    s.chart(
      type: :doughnut,
      title: "Ratio",
      from_col: 3, from_row: 0, to_col: 8, to_row: 12,
      series: [{
        cat_ref: "Data!$A$2:$A$3",
        val_ref: "Data!$B$2:$B$3",
        data_points: [
          { idx: 0, fill_color: "4F81BD" },
          { idx: 1, fill_color: "C0504D" }
        ]
      }]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Line

Demonstrates embedding a standard 2D Line Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_line.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Day Value])
    s.row(["Mon", 10])
    s.row(["Tue", 15])
    s.row(["Wed", 12])
    s.chart(
      type: :line,
      title: "Daily Value",
      from_col: 3, from_row: 0, to_col: 8, to_row: 12,
      series: [{ cat_ref: "Data!$A$2:$A$4", val_ref: "Data!$B$2:$B$4", line_color: "4F81BD", line_width: 2.0 }]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Line Stacked

Demonstrates embedding a stacked 2D Line Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_line_stacked.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Year", "Sales A", "Sales B"])
    s.row([2024, 100, 150])
    s.row([2025, 120, 180])
    s.row([2026, 140, 210])
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.chart(
      type: :line,
      grouping: :stacked,
      title: "Stacked Line Chart",
      from_col: 0, from_row: 5, to_col: 6, to_row: 17,
      series: [
        { 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 },
        { 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 }
      ]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Pie

Demonstrates embedding a standard 2D Pie Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_pie.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Label Percent])
    s.row(["Yes", 70])
    s.row(["No", 30])
    s.chart(
      type: :pie,
      title: "Responses",
      from_col: 3, from_row: 0, to_col: 8, to_row: 12,
      series: [{
        cat_ref: "Data!$A$2:$A$3",
        val_ref: "Data!$B$2:$B$3",
        data_points: [
          { idx: 0, fill_color: "4F81BD" },
          { idx: 1, fill_color: "C0504D" }
        ]
      }]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Radar

Demonstrates embedding a standard 2D Radar Chart.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_radar.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Stat Value])
    s.row(["Atk", 80])
    s.row(["Def", 60])
    s.chart(
      type: :radar,
      title: "Stats",
      from_col: 3, from_row: 0, to_col: 8, to_row: 12,
      series: [{ cat_ref: "Data!$A$2:$A$3", val_ref: "Data!$B$2:$B$3", line_color: "4F81BD", line_width: 2.0 }]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Chart Scatter

Demonstrates embedding a standard 2D Scatter Plot.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "chart_scatter.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Data") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[X Y])
    s.row([1, 10])
    s.row([2, 15])
    s.chart(
      type: :scatter,
      title: "Scatter Plot",
      from_col: 3, from_row: 0, to_col: 8, to_row: 12,
      series: [{ cat_ref: "Data!$A$2:$A$3", val_ref: "Data!$B$2:$B$3", line_color: "4F81BD", line_width: 2.0 }]
    )
  end
end

# 2. Read the generated sheet and print the chart count
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
puts "Sheet '#{sheet.name}' has #{sheet.charts.size} chart(s)"

Console Output

=== Read Validation ===
Sheet 'Data' has 0 chart(s)

Col Grouping

Demonstrates outline grouping for columns.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "col_grouping.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
  wb.sheet("Col Grouping") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25, outline_level: 0)
    s.column(1, width: 25, outline_level: 1)
    s.column(2, width: 25, outline_level: 1)
    s.row(["Col A", "Col B (Grouped)", "Col C (Grouped)"], styles: %w[border border border])
  end
end

# 2. Read the generated sheet and print column dimensions
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.columns.each do |col|
  puts "Column #{col.index}: width=#{col.width}, hidden=#{col.hidden}, outline_level=#{col.outline_level}"
end

Console Output

=== Read Validation ===
Column 0: width=25.0, hidden=false, outline_level=0
Column 1: width=25.0, hidden=false, outline_level=1
Column 2: width=25.0, hidden=false, outline_level=1

Col Width Tall

Demonstrates setting very wide column widths.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "col_width_tall.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
  wb.sheet("Col Width") do |s|
    s.column(0, width: 50)
    s.column(1, width: 10)
    s.row(["Very Wide Column (Width 50)", "Normal (10)"], styles: %w[border border])
  end
end

# 2. Read the generated sheet and print column dimensions
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.columns.each do |col|
  puts "Column #{col.index}: width=#{col.width}, hidden=#{col.hidden}, outline_level=#{col.outline_level}"
end

Console Output

=== Read Validation ===
Column 0: width=50.0, hidden=false, outline_level=
Column 1: width=10.0, hidden=false, outline_level=

Col Widths

Demonstrates setting custom column widths.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "col_widths.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
  wb.sheet("Widths") do |s|
    s.column(0, width: 30)
    s.column(1, width: 10)
    s.row(["Wide Column A", "Narrow B"], styles: %w[border border])
  end
end

# 2. Read the generated sheet and print column dimensions
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.columns.each do |col|
  puts "Column #{col.index}: width=#{col.width}, hidden=#{col.hidden}, outline_level=#{col.outline_level}"
end

Console Output

=== Read Validation ===
Column 0: width=30.0, hidden=false, outline_level=
Column 1: width=10.0, hidden=false, outline_level=

Conditional Formatting

Demonstrates adding conditional formatting rules that style cells automatically based on value ranges.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "conditional_formatting.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |style| style.align_horizontal("center") }
  wb.sheet("Scores") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row([90, 45, 72, 88], styles: %w[center center center center])

    s.conditional_format("A1:D1",
                         type: :cell_is, operator: :greaterThan,
                         formula: "80", priority: 1,
                         fill_color: "FFFFC7CE")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: 90, B1: 45, C1: 72, D1: 88

Drawing Shapes

Visual demonstration for Drawing Shapes.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "drawing_shapes.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.sheet("Shapes") do |sheet|
    sheet.column(0..7, width: 15)
    sheet.row(["Diagram with shapes and annotations"])
    sheet.row([])
    sheet.shape(preset: "rect", text: "Process Start", from_col: 1, from_row: 2, to_col: 3, to_row: 4)
    sheet.shape(preset: "rightArrow", text: "Next", from_col: 4, from_row: 3, to_col: 5, to_row: 4)
    sheet.shape(preset: "roundRect", text: "Processing", from_col: 6, from_row: 2, to_col: 8, to_row: 4)
  end
end

puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Diagram with shapes and annotations"
Row 1:

Embedded Images

Demonstrates embedding raster PNG images in cell ranges.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "embedded_images.xlsx"

require "zlib"

def make_png(width, height, red, green, blue)
  png = "\x89PNG\r\n\x1a\n".dup.force_encoding("BINARY")
  ihdr_data = [width, height, 8, 2, 0, 0, 0].pack("N2C5")
  ihdr_chunk = "IHDR".dup.force_encoding("BINARY") + ihdr_data
  ihdr_crc = Zlib.crc32(ihdr_chunk)
  png << [ihdr_data.bytesize].pack("N") << ihdr_chunk << [ihdr_crc].pack("N")
  raw_data = Array.new(height) { "\x00".dup.force_encoding("BINARY") + ([red, green, blue].pack("C3") * width) }.join
  compressed = Zlib.deflate(raw_data)
  idat_chunk = "IDAT".dup.force_encoding("BINARY") + compressed
  idat_crc = Zlib.crc32(idat_chunk)
  png << [compressed.bytesize].pack("N") << idat_chunk << [idat_crc].pack("N")
  iend_chunk = "IEND".dup.force_encoding("BINARY")
  iend_crc = Zlib.crc32(iend_chunk)
  png << [0].pack("N") << iend_chunk << [iend_crc].pack("N")
  png
end

dummy_png = make_png(100, 100, 255, 0, 0)

Xlsxrb.write(output_path) do |wb|
  wb.style("center") { |st| st.align_horizontal(:center) }
  wb.sheet("Images") do |s|
    s.row(["Logo Target cell:", "", "", "Boundary"], styles: %w[left center center center])
    s.row(["", "", "", ""])
    s.row(["", "", "", ""])
    s.row(["", "", "", ""])
    s.row(["", "", "", "Boundary End"], styles: %w[left center center center])
    s.image(dummy_png, ext: "png", from_col: 1, from_row: 1, to_col: 3, to_row: 5)
    s.column(0, width: 20)
    s.column(1, width: 15)
    s.column(2, width: 15)
    s.column(3, width: 15)
  end
end

# 2. Read the generated sheet and print cell values + parsed embedded images details
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end
images = reader.images(sheet: sheet.name)
images.each_with_index do |img, idx|
  zip_path = File.expand_path(img[:target], "/xl/drawings").sub(%r{^/}, "")
  img_data = reader.send(:extract_zip_entry, zip_path)
  is_png = img_data && img_data[0..3] == "\x89PNG".b
  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]}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Logo Target cell:", B1: "", C1: "", D1: "Boundary"
Row 1: A2: "", B2: "", C2: "", D2: ""
Row 2: A3: "", B3: "", C3: "", D3: ""
Row 3: A4: "", B4: "", C4: "", D4: ""
Row 4: A5: "", B5: "", C5: "", D5: "Boundary End"
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

Fill Gradients

Demonstrates linear gradients inside cell backgrounds.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "fill_gradients.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("gradient") do |style|
    style.fill_gradient(type: "linear", degree: 45, stops: [
                          { position: 0, color: "FFFFFFFF" },
                          { position: 1, color: "FF4F81BD" }
                        ])
  end
  wb.sheet("Gradients") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Normal Cell", "Gradient Cell"], styles: { 1 => "gradient" })
  end
end

# 2. Read the generated sheet and print cell fill properties
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  fill = xf ? workbook.styles[:fills][xf[:fill_id]] : nil
  puts "Cell #{c.ref} ('#{c.value}'): fill pattern = #{fill&.[](:pattern).inspect}, fg_color = #{fill&.[](:fg_color).inspect}"
end

Console Output

=== Read Validation ===
Cell A1 ('Normal Cell'): fill pattern = nil, fg_color = nil
Cell B1 ('Gradient Cell'): fill pattern = nil, fg_color = nil

Fill Patterns

Demonstrates standard pattern fills (darkGray, darkGrid) in cell backgrounds.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "fill_patterns.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("dark_gray") { |s| s.fill(pattern: "darkGray", fg_color: "FFC0C0C0", bg_color: "FFFFFFFF") }
  wb.style("grid_fill") { |s| s.fill(pattern: "darkGrid", fg_color: "FFC0C0C0", bg_color: "FFFFFFFF") }
  wb.sheet("Patterns") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Pattern Preview])
    s.row(["Dark Gray", "Pattern Fill"], styles: { 1 => "dark_gray" })
    s.row(["Dark Grid", "Grid Fill"], styles: { 1 => "grid_fill" })
  end
end

# 2. Read the generated sheet and print cell fill properties
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  fill = xf ? workbook.styles[:fills][xf[:fill_id]] : nil
  puts "Cell #{c.ref} ('#{c.value}'): fill pattern = #{fill&.[](:pattern).inspect}, fg_color = #{fill&.[](:fg_color).inspect}"
end

Console Output

=== Read Validation ===
Cell A1 ('Pattern'): fill pattern = nil, fg_color = nil
Cell B1 ('Preview'): fill pattern = nil, fg_color = nil

Fill Solid Colors

Demonstrates solid cell background fill colors.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "fill_solid_colors.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("red_fill") { |s| s.fill_color("FFFFC7CE") }
  wb.style("green_fill") { |s| s.fill_color("FFC6EFCE") }
  wb.sheet("Fills") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Color Preview])
    s.row(["Red", "Red Fill"], styles: { 1 => "red_fill" })
    s.row(["Green", "Green Fill"], styles: { 1 => "green_fill" })
  end
end

# 2. Read the generated sheet and print cell fill properties
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
row = sheet.rows.first
row.cells.each do |c|
  xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
  fill = xf ? workbook.styles[:fills][xf[:fill_id]] : nil
  puts "Cell #{c.ref} ('#{c.value}'): fill pattern = #{fill&.[](:pattern).inspect}, fg_color = #{fill&.[](:fg_color).inspect}"
end

Console Output

=== Read Validation ===
Cell A1 ('Color'): fill pattern = nil, fg_color = nil
Cell B1 ('Preview'): fill pattern = nil, fg_color = nil

Fonts

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).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "fonts.xlsx"

Xlsxrb.write(output_path) do |wb|
  # Font Families (using nested hash options)
  wb.style("f_arial", font: { name: "Arial" })
  wb.style("f_times", font: { name: "Times New Roman" })
  wb.style("f_courier", font: { name: "Courier New" })
  wb.style("f_georgia", font: { name: "Georgia" })
  wb.style("f_tahoma", font: { name: "Tahoma" })

  # Font Sizes
  wb.style("sz_10", font: { size: 10 })
  wb.style("sz_16", font: { size: 16 })
  wb.style("sz_24", font: { size: 24 })

  # Font Colors
  wb.style("c_red", font: { color: "FFC00000" })
  wb.style("c_green", font: { color: "FF008000" })
  wb.style("c_blue", font: { color: :blue })

  # Font Styles
  wb.style("bold", font: { bold: true })
  wb.style("italic", font: { italic: true })
  wb.style("underline", font: { underline: true })
  wb.style("double_underline", font: { underline: "double" })
  wb.style("strike", font: { strike: true })

  # Vertical Alignment (Subscript / Superscript)
  wb.style("superscript", font: { vert_align: "superscript" })
  wb.style("subscript", font: { vert_align: "subscript" })

  wb.style("header", font: { bold: true, color: :white }, fill: { color: "FF4F81BD" })
  wb.style("bg_light", fill: { color: "FFDCE6F1" })

  wb.sheet("Fonts") do |s|
    s.column(0, width: 25)
    s.column(1, width: 35)

    s.row(["Font Feature", "Text Preview"], styles: "header")

    s.row(["Family: Arial", "Arial Text"], styles: %w[bg_light f_arial])
    s.row(["Family: Times New Roman", "Times New Roman"], styles: [nil, "f_times"])
    s.row(["Family: Courier New", "Courier New Text"], styles: %w[bg_light f_courier])
    s.row(["Family: Georgia", "Georgia Text"], styles: [nil, "f_georgia"])
    s.row(["Family: Tahoma", "Tahoma Text"], styles: %w[bg_light f_tahoma])

    s.row(["Size: 10pt", "10pt Font Size"], styles: [nil, "sz_10"])
    s.row(["Size: 16pt", "16pt Font Size"], styles: %w[bg_light sz_16])
    s.row(["Size: 24pt", "24pt Font Size"], styles: [nil, "sz_24"])

    s.row(["Color: Red", "Red Text"], styles: %w[bg_light c_red])
    s.row(["Color: Green", "Green Text"], styles: [nil, "c_green"])
    s.row(["Color: Blue", "Blue Text"], styles: %w[bg_light c_blue])

    s.row(["Style: Bold", "Bold Text"], styles: [nil, "bold"])
    s.row(["Style: Italic", "Italic Text"], styles: %w[bg_light italic])
    s.row(["Style: Underline", "Underline Text"], styles: [nil, "underline"])
    s.row(["Style: Double Underline", "Double Underline"], styles: %w[bg_light double_underline])
    s.row(["Style: Strike-through", "Strike-through Text"], styles: [nil, "strike"])

    s.row(["Align: Superscript", "x2 (2 is super)"], styles: %w[bg_light superscript])
    s.row(["Align: Subscript", "H2O (2 is sub)"], styles: [nil, "subscript"])
  end
end
puts "Created #{output_path}"

Console Output

Created /workspaces/xlsxrb/docs/visual/files/fonts.xlsx

Interactive Autofilter

[!TIP] 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!

Demonstrates enabling auto-filter sorting headers on tables. Download the sheet to interactively filter and sort columns.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "interactive_autofilter.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Filter") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[Name Department])
    s.row(%w[Alice HR])
    s.row(%w[Bob Eng])
    s.auto_filter("A1:B3")
  end
  wb.defined_name("_xlnm._FilterDatabase", "Filter!$A$1:$B$3", sheet: "Filter", hidden: true)
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Name", B1: "Department"
Row 1: A2: "Alice", B2: "HR"
Row 2: A3: "Bob", B3: "Eng"

Interactive Comments

[!TIP] 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!

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.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "interactive_comments.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Comments") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Item A", "Item B"])
    s.comment("A1", "This is an important comment.", author: "System")
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Item A", B1: "Item B"

Interactive Validation Custom

[!TIP] 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!

Demonstrates interactive custom formula validation rules.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "interactive_validation_custom.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Custom Rule") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Number A", "Number B (Must be larger A)"])
    s.row([10, ""])
    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")
  end
end

# 2. Read the generated sheet and print data validations
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
validations = reader.data_validations(sheet: sheet.name)
validations.each do |v|
  puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
end

Console Output

=== Read Validation ===
Validation range B2: type=custom, formula1=B2>A2, formula2=

Interactive Validation Date

[!TIP] 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!

Demonstrates interactive date range constraints validation rules.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "interactive_validation_date.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Date Validation") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Date Range", "Enter Date (2026):"])
    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")
  end
end

# 2. Read the generated sheet and print data validations
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
validations = reader.data_validations(sheet: sheet.name)
validations.each do |v|
  puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
end

Console Output

=== Read Validation ===
Validation range B2: type=date, formula1=Date(2026,1,1), formula2=Date(2026,12,31)

Interactive Validation List

[!TIP] 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!

Demonstrates dropdown list data validations. Open the sheet in Excel and select cell A1/A2 to see the dropdown list in action.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "interactive_validation_list.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("List Validation") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Department", "Select:"])
    s.validate_data("B2", in: %w[HR Sales Engineering])
  end
end

# 2. Read the generated sheet and print data validations
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
validations = reader.data_validations(sheet: sheet.name)
validations.each do |v|
  puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
end

Console Output

=== Read Validation ===
Validation range B2: type=list, formula1="HR,Sales,Engineering", formula2=

Interactive Validation Range

[!TIP] 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!

Demonstrates range constraints for whole number validations. Open the sheet in Excel and try entering a value outside 10-100 to trigger the warning.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "interactive_validation_range.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Range Validation") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Age", "Enter (18-99):"])
    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!")
  end
end

# 2. Read the generated sheet and print data validations
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
validations = reader.data_validations(sheet: sheet.name)
validations.each do |v|
  puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
end

Console Output

=== Read Validation ===
Validation range B2: type=whole, formula1=18, formula2=99

Interactive Validation Text Length

[!TIP] 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!

Demonstrates interactive text length validation rules.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "interactive_validation_text_length.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Text Length") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Username", "Enter (< 10 chars):"])
    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")
  end
end

# 2. Read the generated sheet and print data validations
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
validations = reader.data_validations(sheet: sheet.name)
validations.each do |v|
  puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
end

Console Output

=== Read Validation ===
Validation range B2: type=textLength, formula1=10, formula2=

Interactive Validation Time

[!TIP] 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!

Demonstrates interactive time validation rules.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "interactive_validation_time.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Time Validation") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Schedule", "Enter Time (after 08:00):"])
    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")
  end
end

# 2. Read the generated sheet and print data validations
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
validations = reader.data_validations(sheet: sheet.name)
validations.each do |v|
  puts "Validation range #{v[:sqref]}: type=#{v[:type]}, formula1=#{v[:formula1]}, formula2=#{v[:formula2]}"
end

Console Output

=== Read Validation ===
Validation range B2: type=time, formula1=0.33333, formula2=

Japanese Text

Demonstrates writing multi-byte Japanese text and setting appropriate Japanese font names (e.g., Noto Sans CJK JP).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "japanese_text.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.style("ja_font") do |style|
    style.font_name("Noto Sans CJK JP").size(12)
  end

  wb.sheet("Japanese") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(%w[日本語ラベル ], styles: { 0 => "ja_font", 1 => "ja_font" })
    s.row(["売上", 12_500], styles: { 0 => "ja_font" })
  end
end

# 2. Read the generated sheet and print parsed cell values and Ruby classes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map do |c|
    "#{c.ref}: #{c.value.inspect} (#{c.value.class})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "日本語ラベル" (String), B1: "値" (String)
Row 1: A2: "売上" (String), B2: 12500 (Integer)

Merge Freeze

Demonstrates merging a cell range into a single cell, and freezing the top rows of a sheet.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "merge_freeze.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.style("title") { |style| style.border_all(style: "thin", color: "FF000000").align_horizontal("center") }
  wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
  wb.sheet("Merge & Freeze") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.column(2, width: 25)
    s.row(["Merged Title Row", nil, nil], styles: %w[title title title])
    s.row(["Header A", "Header B", "Header C"], styles: %w[border border border])
    s.row(["Row 1 Col A", "Row 1 Col B", "Row 1 Col C"], styles: %w[border border border])
    s.row(["Row 2 Col A", "Row 2 Col B", "Row 2 Col C"], styles: %w[border border border])

    s.merge(row: 0, col_start: 0, col_end: 2)
    s.freeze_pane(row: 2, col: 0)
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(5).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Merged Title Row", B1: nil, C1: nil
Row 1: A2: "Header A", B2: "Header B", C2: "Header C"
Row 2: A3: "Row 1 Col A", B3: "Row 1 Col B", C3: "Row 1 Col C"
Row 3: A4: "Row 2 Col A", B4: "Row 2 Col B", C4: "Row 2 Col C"

Page Grid Lines Print

Demonstrates enabling printing of grid lines.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "page_grid_lines_print.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Print Grid Lines") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.print_options(:grid_lines, true)
    s.row(["Grid Lines Printed sheet"])
  end
end

# 2. Read the generated sheet and print page setup properties
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
margins = reader.page_margins(sheet: sheet.name)
setup = reader.page_setup(sheet: sheet.name)
opts = reader.print_options(sheet: sheet.name)
puts "Page Margins: #{margins.inspect}"
puts "Page Setup: #{setup.inspect}"
puts "Print Options: #{opts.inspect}"

Console Output

=== Read Validation ===
Page Margins: nil
Page Setup: {}
Print Options: {grid_lines: true}

Demonstrates setting odd page headers and footers.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "page_header_footer.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Header Footer") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.header_footer(odd_header: "&LMy Company&RPage &P", odd_footer: "&CConfidential")
    s.row(["Header Footer sheet"])
  end
end

# 2. Read the generated sheet and print page setup properties
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
margins = reader.page_margins(sheet: sheet.name)
setup = reader.page_setup(sheet: sheet.name)
opts = reader.print_options(sheet: sheet.name)
puts "Page Margins: #{margins.inspect}"
puts "Page Setup: #{setup.inspect}"
puts "Print Options: #{opts.inspect}"

Console Output

=== Read Validation ===
Page Margins: nil
Page Setup: {}
Print Options: {}

Page Headings Print

Demonstrates enabling printing of row and column headings.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "page_headings_print.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Print Headings") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.print_options(:headings, true)
    s.row(["Row/Col Headings Printed sheet"])
  end
end

# 2. Read the generated sheet and print page setup properties
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
margins = reader.page_margins(sheet: sheet.name)
setup = reader.page_setup(sheet: sheet.name)
opts = reader.print_options(sheet: sheet.name)
puts "Page Margins: #{margins.inspect}"
puts "Page Setup: #{setup.inspect}"
puts "Print Options: #{opts.inspect}"

Console Output

=== Read Validation ===
Page Margins: nil
Page Setup: {}
Print Options: {headings: true}

Page Margins Narrow

Demonstrates setting narrow page margins.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "page_margins_narrow.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Narrow Margins") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.page_margins(top: 0.25, bottom: 0.25, left: 0.25, right: 0.25, header: 0.1, footer: 0.1)
    s.row(["Narrow Margins sheet"])
  end
end

# 2. Read the generated sheet and print page setup properties
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
margins = reader.page_margins(sheet: sheet.name)
setup = reader.page_setup(sheet: sheet.name)
opts = reader.print_options(sheet: sheet.name)
puts "Page Margins: #{margins.inspect}"
puts "Page Setup: #{setup.inspect}"
puts "Print Options: #{opts.inspect}"

Console Output

=== Read Validation ===
Page Margins: {left: 0.25, right: 0.25, top: 0.25, bottom: 0.25, header: 0.1, footer: 0.1}
Page Setup: {}
Print Options: {}

Page Margins Wide

Demonstrates setting wide page margins.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "page_margins_wide.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Wide Margins") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.page_margins(top: 1.0, bottom: 1.0, left: 1.0, right: 1.0, header: 0.5, footer: 0.5)
    s.row(["Wide Margins sheet"])
  end
end

# 2. Read the generated sheet and print page setup properties
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
margins = reader.page_margins(sheet: sheet.name)
setup = reader.page_setup(sheet: sheet.name)
opts = reader.print_options(sheet: sheet.name)
puts "Page Margins: #{margins.inspect}"
puts "Page Setup: #{setup.inspect}"
puts "Print Options: #{opts.inspect}"

Console Output

=== Read Validation ===
Page Margins: {left: 1.0, right: 1.0, top: 1.0, bottom: 1.0, header: 0.5, footer: 0.5}
Page Setup: {}
Print Options: {}

Page Orientation Landscape

Demonstrates landscape page setup for printing.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "page_orientation_landscape.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Landscape") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.page_setup(orientation: :landscape)
    s.row(["Landscape Orientation sheet"])
  end
end

# 2. Read the generated sheet and print page setup properties
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
margins = reader.page_margins(sheet: sheet.name)
setup = reader.page_setup(sheet: sheet.name)
opts = reader.print_options(sheet: sheet.name)
puts "Page Margins: #{margins.inspect}"
puts "Page Setup: #{setup.inspect}"
puts "Print Options: #{opts.inspect}"

Console Output

=== Read Validation ===
Page Margins: nil
Page Setup: {orientation: "landscape"}
Print Options: {}

Page Paper Size A3

Demonstrates setting paper size to A3 (paper size 8).

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "page_paper_size_a3.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("A3 Sheet") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.page_setup(paper_size: 8) # ISO A3 is paperSize="8"
    s.row(["ISO A3 Paper Size sheet"])
  end
end

# 2. Read the generated sheet and print page setup properties
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
margins = reader.page_margins(sheet: sheet.name)
setup = reader.page_setup(sheet: sheet.name)
opts = reader.print_options(sheet: sheet.name)
puts "Page Margins: #{margins.inspect}"
puts "Page Setup: #{setup.inspect}"
puts "Print Options: #{opts.inspect}"

Console Output

=== Read Validation ===
Page Margins: nil
Page Setup: {paper_size: 8}
Print Options: {}

Pivot Table

Visual demonstration for Pivot Table.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "pivot_table.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.sheet("SalesData") do |sheet|
    sheet.column(0..3, width: 18)
    sheet.row(%w[Region Quarter Sales Rep])
    sheet.row(["East", "Q1", 1000, "Alice"])
    sheet.row(["West", "Q1", 1500, "Bob"])
    sheet.row(["East", "Q2", 1200, "Alice"])
    sheet.row(["West", "Q2", 1800, "Bob"])
    sheet.row(["North", "Q1", 800, "Charlie"])
    sheet.row(["North", "Q2", 950, "Charlie"])

    sheet.pivot_table(
      "SalesData!A1:D7",
      row_fields: ["Region"],
      data_fields: [{ name: "Sales", subtotal: "sum" }],
      col_fields: ["Quarter"],
      dest_ref: "F1",
      name: "RegionalSalesSummary"
    )
  end
end

puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Region", B1: "Quarter", C1: "Sales", D1: "Rep"
Row 1: A2: "East", B2: "Q1", C2: 1000, D2: "Alice"
Row 2: A3: "West", B3: "Q1", C3: 1500, D3: "Bob"
Row 3: A4: "East", B4: "Q2", C4: 1200, D4: "Alice"
Row 4: A5: "West", B5: "Q2", C5: 1800, D5: "Bob"
Row 5: A6: "North", B6: "Q1", C6: 800, D6: "Charlie"
Row 6: A7: "North", B7: "Q2", C7: 950, D7: "Charlie"

Row Grouping

Demonstrates outline grouping for rows.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "row_grouping.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("parent") { |style| style.border_all(style: "thin", color: "FF000000").bold }
  wb.style("child") { |style| style.border_all(style: "thin", color: "FF000000").align_horizontal("left").indent(2) }
  wb.sheet("Row Grouping") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Parent Row 1", ""], styles: %w[parent parent])
    s.row(["Child Row 1.1", ""], outline_level: 1, styles: %w[child child])
    s.row(["Child Row 1.2", ""], outline_level: 1, styles: %w[child child])
  end
end

# 2. Read the generated sheet and print row attributes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  puts "Row #{row.index}: height=#{row.height}, hidden=#{row.hidden}, outline_level=#{row.outline_level}"
end

Console Output

=== Read Validation ===
Row 0: height=, hidden=false, outline_level=
Row 1: height=, hidden=false, outline_level=1
Row 2: height=, hidden=false, outline_level=1

Row Height Tall

Demonstrates setting very tall row heights.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "row_height_tall.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
  wb.sheet("Row Height") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Very Tall Row (Height 60)", ""], height: 60, styles: %w[border border])
    s.row(["Normal Row", ""], styles: %w[border border])
  end
end

# 2. Read the generated sheet and print row attributes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  puts "Row #{row.index}: height=#{row.height}, hidden=#{row.hidden}, outline_level=#{row.outline_level}"
end

Console Output

=== Read Validation ===
Row 0: height=60.0, hidden=false, outline_level=
Row 1: height=, hidden=false, outline_level=

Row Heights

Demonstrates setting custom row heights.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "row_heights.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.style("border") { |style| style.border_all(style: "thin", color: "FF000000") }
  wb.sheet("Heights") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row(["Normal Row", ""], styles: %w[border border])
    s.row(["Tall Row", ""], height: 40, styles: %w[border border])
  end
end

# 2. Read the generated sheet and print row attributes
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  puts "Row #{row.index}: height=#{row.height}, hidden=#{row.hidden}, outline_level=#{row.outline_level}"
end

Console Output

=== Read Validation ===
Row 0: height=, hidden=false, outline_level=
Row 1: height=40.0, hidden=false, outline_level=

Sheet Tab Colors

Demonstrates customizing tab colors of individual worksheets.

Rendered Output (LibreOffice Calc)

Preview
Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "sheet_tab_colors.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Red Tab") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.sheet_properties(:tab_color, :red)
    s.row(["Red tab sheet"])
  end
  wb.sheet("Green Tab") do |s|
    s.sheet_properties(:tab_color, :green)
    s.row(["Green tab sheet"])
  end
end

# 2. Read the generated sheet and print sheet properties
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
workbook.sheet_names.each do |s_name|
  props = reader.sheet_properties(sheet: s_name)
  puts "Sheet: #{s_name}, tab color: #{props[:tab_color].inspect}"
end

Console Output

=== Read Validation ===
Sheet: Red Tab, tab color: "red"
Sheet: Green Tab, tab color: "green"

Sparkline Column

Demonstrates embedded column sparklines in cell ranges.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "sparkline_column.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Sparkline") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row([5, 12, 8, 15, nil])
    s.sparkline_group(
      type: :column,
      sparklines: [{ location_ref: "E1", data_ref: "Sparkline!A1:D1" }]
    )
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(3).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: 5, B1: 12, C1: 8, D1: 15

Sparkline Line

Demonstrates embedded line sparklines in cell ranges.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "sparkline_line.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Sparkline") do |s|
    s.sheet_properties(:fit_to_page, true)
    s.page_setup(fit_to_width: 1, fit_to_height: 1)
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.row([10, 20, 15, 30, nil])
    s.sparkline_group(
      type: :line,
      markers: true,
      color_series: "FF000000",
      color_markers: :red,
      sparklines: [{ location_ref: "E1", data_ref: "Sparkline!A1:D1" }]
    )
  end
end

# 2. Read the generated sheet and print cell values
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(3).each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: 10, B1: 20, C1: 15, D1: 30

Styles Fonts Fills

Demonstrates cell formatting, including custom font sizing, bold/italic text, custom text colors, and background fill colors.

Rendered Output (LibreOffice Calc)

Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "styles_fonts_fills.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.style("header") do |style|
    style.bold.size(14).font_color("FFFFFFFF").fill_color("FF4F81BD")
  end

  wb.style("highlight") do |style|
    style.italic.font_color("FFC00000").fill_color("FFFFFF00")
  end

  wb.sheet("Styles") do |sheet|
    sheet.column(0, width: 25)
    sheet.column(1, width: 25)
    sheet.row(["Header 1", "Header 2"], styles: { 0 => "header", 1 => "header" })
    sheet.row(["Normal Text", "Highlighted Text"], styles: { 1 => "highlight" })
  end
end

# 2. Read the generated sheet and print styling details
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.first(4).each do |row|
  row_cells = row.cells.map do |c|
    xf = workbook.styles[:cell_xfs][c.style_index] if c.style_index
    font = xf ? workbook.styles[:fonts][xf[:font_id]] : nil
    fill = xf ? workbook.styles[:fills][xf[:fill_id]] : nil
    "#{c.ref}: #{c.value.inspect} (font=#{font&.[](:name)}, fill=#{fill&.[](:fg_color)&.[](:rgb)})"
  end
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "Header 1" (font=Calibri, fill=FF4F81BD), B1: "Header 2" (font=Calibri, fill=FF4F81BD)
Row 1: A2: "Normal Text" (font=, fill=), B2: "Highlighted Text" (font=Calibri, fill=FFFFFF00)

Table Styles

Visual demonstration for Table Styles.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"

output_path = ARGV[0] || "table_styles.xlsx"

Xlsxrb.write(output_path) do |wb|
  wb.sheet("Table Example") do |sheet|
    sheet.column(0..3, width: 20)
    sheet.row(%w[ID Name Department Salary])
    sheet.row([101, "Alice Smith", "Engineering", 120_000])
    sheet.row([102, "Bob Jones", "Marketing", 95_000])
    sheet.row([103, "Carol White", "Sales", 110_000])
    sheet.row([104, "David Brown", "Engineering", 130_000])

    sheet.table("A1:D5", columns: %w[ID Name Department Salary], name: "EmployeeTable", style: "TableStyleMedium9", total_row: false)
  end
end

puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
sheet = workbook.sheets.first
sheet.rows.each do |row|
  row_cells = row.cells.map { |c| "#{c.ref}: #{c.value.inspect}" }
  puts "Row #{row.index}: #{row_cells.join(", ")}"
end

Console Output

=== Read Validation ===
Row 0: A1: "ID", B1: "Name", C1: "Department", D1: "Salary"
Row 1: A2: 101, B2: "Alice Smith", C2: "Engineering", D2: 120000
Row 2: A3: 102, B3: "Bob Jones", C3: "Marketing", D3: 95000
Row 3: A4: 103, B4: "Carol White", C4: "Sales", D4: 110000
Row 4: A5: 104, B5: "David Brown", C5: "Engineering", D5: 130000

View Show Grid Lines

Demonstrates disabling visible grid lines in spreadsheet view.

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "view_show_grid_lines.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Hide Grid Lines") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.sheet_view(:show_grid_lines, false)
    s.row(["No Grid Lines displayed"])
  end
end

# 2. Read the generated sheet and print view configurations
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
workbook.sheet_names.each do |s_name|
  view = reader.sheet_view(sheet: s_name)
  puts "Sheet '#{s_name}' views zoom scale: #{view[:zoom_scale]}%, show grid lines: #{view[:show_grid_lines]}"
end

Console Output

=== Read Validation ===
Sheet 'Hide Grid Lines' views zoom scale: %, show grid lines: false

View Zoom Scale

Demonstrates setting custom zoom scale in sheet view (e.g. 150%).

Rendered Output (LibreOffice Calc)

Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "view_zoom_scale.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("Zoom 150") do |s|
    s.column(0, width: 25)
    s.column(1, width: 25)
    s.sheet_view(:zoom_scale, 150)
    s.row(["Zoom scale is set to 150%"])
  end
end

# 2. Read the generated sheet and print view configurations
puts "=== Read Validation ==="
reader = Xlsxrb::Ooxml::Reader.new(output_path)
workbook = Xlsxrb.read(output_path).load
workbook.sheet_names.each do |s_name|
  view = reader.sheet_view(sheet: s_name)
  puts "Sheet '#{s_name}' views zoom scale: #{view[:zoom_scale]}%, show grid lines: #{view[:show_grid_lines]}"
end

Console Output

=== Read Validation ===
Sheet 'Zoom 150' views zoom scale: 150%, show grid lines:

Workbook Three Sheets

Demonstrates creating workbooks with multiple worksheets.

Rendered Output (LibreOffice Calc)

Preview
Preview
Preview

DSL Code

# frozen_string_literal: true

require "xlsxrb"
output_path = ARGV[0] || "workbook_three_sheets.xlsx"
Xlsxrb.write(output_path) do |wb|
  wb.sheet("First Sheet") { |s| s.row(["First Sheet Data"]) }
  wb.sheet("Second Sheet") { |s| s.row(["Second Sheet Data"]) }
  wb.sheet("Third Sheet") { |s| s.row(["Third Sheet Data"]) }
end

# 2. Read the generated sheet and print the sheets structure
puts "=== Read Validation ==="
workbook = Xlsxrb.read(output_path).load
puts "Workbook sheets: #{workbook.sheet_names.join(", ")}"

Console Output

=== Read Validation ===
Workbook sheets: First Sheet, Second Sheet, Third Sheet