summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorWeston Ganger <[email protected]>2020-02-12 16:07:52 -0800
committerGitHub <[email protected]>2020-02-13 01:07:52 +0100
commit5a5c09132060f1270849c2535d00c456a31fa02a (patch)
tree3a05366e3e9795266f08ce17fa6d0e387eb8747d
parenta58375fa72fac090d6310e2094808e8a477eab82 (diff)
downloadcaxlsx-5a5c09132060f1270849c2535d00c456a31fa02a.tar.gz
caxlsx-5a5c09132060f1270849c2535d00c456a31fa02a.zip
Improve cell string_autowidth calculations (#44)
Previously, cells with autowidth sometimes were too narrow for the content to fit. The original width calculation tried to take the difference between narrow and wide chars into account, but it didn’t work out very well. The new calculation is simpler. Compared to the previous implementation it results in cells being slightly wider in most cases.
-rw-r--r--CHANGELOG.md3
-rw-r--r--lib/axlsx/workbook/worksheet/cell.rb3
-rw-r--r--lib/axlsx/workbook/worksheet/rich_text_run.rb2
-rw-r--r--lib/axlsx/workbook/worksheet/worksheet.rb3
-rw-r--r--test/workbook/worksheet/tc_cell.rb2
-rw-r--r--test/workbook/worksheet/tc_rich_text_run.rb5
6 files changed, 10 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 720fa9d6..b8af4d90 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
CHANGELOG
---------
+- **Unreleased**
+ - [PR #44](https://github.com/caxlsx/caxlsx/pull/44) - Improve cell autowidth calculations. Previously columns with undefined/auto width would tend to be just slightly too small for the content. This is because certain letters were being excluded from the width calculation because they were deemed not wide enough. We now treat all characters as equal width which helps ensure columns auto-widths are actually large enough for the content. This will gain us a very slight performance improvement because of we are no longer searching the string for specific characters.
+
- **October.4.19**: 3.0.1
- Support for ruby versions limited to officially supported version (Ruby v2.3+)
- Updates to dependency gems, especially nokogiri and ruby-zip
diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb
index 53bea28b..5a00a97d 100644
--- a/lib/axlsx/workbook/worksheet/cell.rb
+++ b/lib/axlsx/workbook/worksheet/cell.rb
@@ -373,6 +373,7 @@ module Axlsx
# @return [Float]
def autowidth
return if is_formula? || value.nil?
+
if contains_rich_text?
string_width('', font_size) + value.autowidth
elsif styles.cellXfs[style].alignment && styles.cellXfs[style].alignment.wrap_text
@@ -409,7 +410,7 @@ module Axlsx
# - scaling is not linear as font sizes increase
def string_width(string, font_size)
font_scale = font_size / 10.0
- (string.to_s.count(Worksheet::THIN_CHARS) + 3.0) * font_scale
+ (string.to_s.size + 3) * font_scale
end
# we scale the font size if bold style is applied to either the style font or
diff --git a/lib/axlsx/workbook/worksheet/rich_text_run.rb b/lib/axlsx/workbook/worksheet/rich_text_run.rb
index 40d99bb0..c8668da6 100644
--- a/lib/axlsx/workbook/worksheet/rich_text_run.rb
+++ b/lib/axlsx/workbook/worksheet/rich_text_run.rb
@@ -215,7 +215,7 @@ module Axlsx
# - scaling is not linear as font sizes increase
def string_width(string, font_size)
font_scale = font_size / 10.0
- string.count(Worksheet::THIN_CHARS) * font_scale
+ string.size * font_scale
end
# we scale the font size if bold style is applied to either the style font or
diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb
index 4fb95d4c..aae91947 100644
--- a/lib/axlsx/workbook/worksheet/worksheet.rb
+++ b/lib/axlsx/workbook/worksheet/worksheet.rb
@@ -5,9 +5,6 @@ module Axlsx
class Worksheet
include Axlsx::OptionsParser
include Axlsx::SerializedAttributes
- # definition of characters which are less than the maximum width of 0-9 in the default font for use in String#count.
- # This is used for autowidth calculations
- THIN_CHARS = '^.acfijklrstxzFIJL()-'.freeze
# Creates a new worksheet.
# @note the recommended way to manage worksheets is Workbook#add_worksheet
diff --git a/test/workbook/worksheet/tc_cell.rb b/test/workbook/worksheet/tc_cell.rb
index d3ca9fe8..9e0bdc0e 100644
--- a/test/workbook/worksheet/tc_cell.rb
+++ b/test/workbook/worksheet/tc_cell.rb
@@ -61,7 +61,7 @@ class TestCell < Test::Unit::TestCase
def test_autowidth
style = @c.row.worksheet.workbook.styles.add_style({:alignment => {:horizontal => :center, :vertical => :center, :wrap_text => true}} )
@c.style = style
- assert_equal(@c.autowidth, 5.5)
+ assert_in_delta(6.6, @c.autowidth, 0.01)
end
def test_time
diff --git a/test/workbook/worksheet/tc_rich_text_run.rb b/test/workbook/worksheet/tc_rich_text_run.rb
index e4a5ef80..39919a31 100644
--- a/test/workbook/worksheet/tc_rich_text_run.rb
+++ b/test/workbook/worksheet/tc_rich_text_run.rb
@@ -148,8 +148,9 @@ class RichTextRun < Test::Unit::TestCase
@ws.add_row [rt], :style => wrap
ar = [0]
awtr.autowidth(ar)
- assert_equal(ar.length, 2)
- assert_equal(ar.last, 0)
+ assert_equal(2, ar.length)
+ assert_equal(13.2, ar[0])
+ assert_equal(0, ar[1])
end
def test_to_xml