Skip to content

Commit

Permalink
Add support for boolean values
Browse files Browse the repository at this point in the history
including auto format, which will detect the strings 'true' and
'false' as boolean values.
  • Loading branch information
felixbuenemann committed Oct 22, 2017
1 parent 6427c39 commit 46d61b0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ Or install it yourself as:
# Creates a new workbook and closes it at the end of the block
Xlsxtream::Workbook.open('my_data.xlsx') do |xlsx|
xlsx.write_worksheet 'Sheet1' do |sheet|
# Date, Time, DateTime and Numeric are properly mapped
sheet << [Date.today, 'hello', 'world', 42, 3.14159265359, 42**13]
# Boolean, Date, Time, DateTime and Numeric are properly mapped
sheet << [true, Date.today, 'hello', 'world', 42, 3.14159265359, 42**13]
end
end

Expand Down Expand Up @@ -71,10 +71,11 @@ end
# appropriately. This is a convenient way to avoid an Excel-warning about
# "Number stored as text". Dates and times must be in the ISO-8601 format and
# numeric values must contain only numbers and an optional decimal separator.
# The strings true and false are detected as boolean values.
xlsx.write_worksheet('SheetWithAutoFormat', :auto_format => true) do |sheet|
# these two rows will be identical in the xlsx-output
sheet << [11.85, DateTime.parse('2050-01-01T12:00'), Date.parse('1984-01-01')]
sheet << ['11.85', '2050-01-01T12:00', '1984-01-01']
sheet << [true, 11.85, DateTime.parse('2050-01-01T12:00'), Date.parse('1984-01-01')]
sheet << ['true', '11.85', '2050-01-01T12:00', '1984-01-01']
end

# Writes metadata and ZIP archive central directory
Expand Down
9 changes: 9 additions & 0 deletions lib/xlsxtream/row.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class Row
# ISO 8601 yyyy-mm-ddThh:mm:ss(.s)(Z|+hh:mm|-hh:mm)
TIME_PATTERN = /\A[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}(?::[0-9]{2}(?:\.[0-9]{1,9})?)?(?:Z|[+-][0-9]{2}:[0-9]{2})?\z/.freeze

TRUE_STRING = 'true'.freeze
FALSE_STRING = 'false'.freeze

DATE_STYLE = 1
TIME_STYLE = 2

Expand All @@ -38,6 +41,8 @@ def to_xml
case value
when Numeric
xml << %Q{<c r="#{cid}" t="n"><v>#{value}</v></c>}
when TrueClass, FalseClass
xml << %Q{<c r="#{cid}" t="b"><v>#{value ? 1 : 0}</v></c>}
when Time, DateTime
xml << %Q{<c r="#{cid}" s="#{TIME_STYLE}"><v>#{time_to_oa_date(value)}</v></c>}
when Date
Expand Down Expand Up @@ -65,6 +70,10 @@ def to_xml
# Detects and casts numbers, date, time in text
def auto_format(value)
case value
when TRUE_STRING
true
when FALSE_STRING
false
when NUMBER_PATTERN
value.include?('.') ? value.to_f : value.to_i
when DATE_PATTERN
Expand Down
22 changes: 22 additions & 0 deletions test/xlsxtream/row_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,28 @@ def test_symbol_column
assert_equal expected, actual
end

def test_boolean_column
row = Row.new([true], 1)
actual = row.to_xml
expected = '<row r="1"><c r="A1" t="b"><v>1</v></c></row>'
assert_equal expected, actual
row = Row.new([false], 1)
actual = row.to_xml
expected = '<row r="1"><c r="A1" t="b"><v>0</v></c></row>'
assert_equal expected, actual
end

def test_text_boolean_column
row = Row.new(['true'], 1, :auto_format => true)
actual = row.to_xml
expected = '<row r="1"><c r="A1" t="b"><v>1</v></c></row>'
assert_equal expected, actual
row = Row.new(['false'], 1, :auto_format => true)
actual = row.to_xml
expected = '<row r="1"><c r="A1" t="b"><v>0</v></c></row>'
assert_equal expected, actual
end

def test_integer_column
row = Row.new([1], 1)
actual = row.to_xml
Expand Down

0 comments on commit 46d61b0

Please sign in to comment.