From bb2cb303959d76987ec226763b1c3504b5d226e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Bu=CC=88nemann?= Date: Mon, 30 Oct 2017 14:24:11 +0100 Subject: [PATCH] Support customizing font name, size, family This adds support for overriding the default font settings for the whole workbook. The default settings are: { font: { name: 'Calibri', size: 12, family: 'Swiss' } } Example with Arial 10pt: Workbook.new('foo.xlsx', font: { name: 'Arial', size: 10 }) --- lib/xlsxtream/errors.rb | 3 ++ lib/xlsxtream/workbook.rb | 24 ++++++++++++-- test/xlsxtream/workbook_test.rb | 57 +++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 lib/xlsxtream/errors.rb diff --git a/lib/xlsxtream/errors.rb b/lib/xlsxtream/errors.rb new file mode 100644 index 0000000..78d5ab2 --- /dev/null +++ b/lib/xlsxtream/errors.rb @@ -0,0 +1,3 @@ +module Xlsxtream + class Error < StandardError; end +end diff --git a/lib/xlsxtream/workbook.rb b/lib/xlsxtream/workbook.rb index 4e11f04..0c6cd31 100644 --- a/lib/xlsxtream/workbook.rb +++ b/lib/xlsxtream/workbook.rb @@ -1,5 +1,6 @@ # encoding: utf-8 require "stringio" +require "xlsxtream/errors" require "xlsxtream/xml" require "xlsxtream/shared_string_table" require "xlsxtream/workbook" @@ -10,6 +11,15 @@ module Xlsxtream class Workbook + FONT_FAMILY_IDS = { + '' => 0, + 'roman' => 1, + 'swiss' => 2, + 'modern' => 3, + 'script' => 4, + 'decorative' => 5 + }.freeze + class << self def open(data = nil, options = {}) @@ -98,6 +108,14 @@ def write_workbook end def write_styles + font_options = @options.fetch(:font, {}) + font_size = font_options.fetch(:size, 12).to_s + font_name = font_options.fetch(:name, 'Calibri').to_s + font_family = font_options.fetch(:family, 'Swiss').to_s.downcase + font_family_id = FONT_FAMILY_IDS[font_family] or fail Error, + "Invalid font family #{font_family}, must be one of "\ + + FONT_FAMILY_IDS.keys.map(&:inspect).join(', ') + @io.add_file "xl/styles.xml" @io << XML.header @io << XML.strip(<<-XML) @@ -108,9 +126,9 @@ def write_styles - - - + + + diff --git a/test/xlsxtream/workbook_test.rb b/test/xlsxtream/workbook_test.rb index 827aa84..d5ce02a 100644 --- a/test/xlsxtream/workbook_test.rb +++ b/test/xlsxtream/workbook_test.rb @@ -253,6 +253,63 @@ def test_styles_content assert_equal expected, actual end + def test_custom_font_size + iow_spy = io_wrapper_spy + font_options = { :size => 23 } + Workbook.open(nil, :io_wrapper => iow_spy, :font => font_options) {} + expected = '' + actual = iow_spy['xl/styles.xml'][/]+>/] + assert_equal expected, actual + end + + def test_custom_font_name + iow_spy = io_wrapper_spy + font_options = { :name => 'Comic Sans' } + Workbook.open(nil, :io_wrapper => iow_spy, :font => font_options) {} + expected = '' + actual = iow_spy['xl/styles.xml'][/]+>/] + assert_equal expected, actual + end + + def test_custom_font_family + iow_spy = io_wrapper_spy + font_options = { :family => 'Script' } + Workbook.open(nil, :io_wrapper => iow_spy, :font => font_options) {} + expected = '' + actual = iow_spy['xl/styles.xml'][/]+>/] + assert_equal expected, actual + end + + def test_font_family_mapping + tests = { + nil => 0, + '' => 0, + 'ROMAN' => 1, + :roman => 1, + 'Roman' => 1, + :swiss => 2, + :modern => 3, + :script => 4, + :decorative => 5 + } + tests.each do |value, id| + iow_spy = io_wrapper_spy + font_options = { :family => value } + Workbook.open(nil, :io_wrapper => iow_spy, :font => font_options) {} + expected = "" + actual = iow_spy['xl/styles.xml'][/]+>/] + assert_equal expected, actual + end + end + + def test_invalid_font_family + iow_spy = io_wrapper_spy + font_options = { :family => 'Foo' } + assert_raises Xlsxtream::Error do + Workbook.open(nil, :io_wrapper => iow_spy, :font => font_options) {} + end + end + def test_tempfile_is_not_closed tempfile = Tempfile.new('workbook') Workbook.open(tempfile) {}