Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xlsx Column Autosize Approximate for CJK #3416

Merged
merged 2 commits into from
Mar 4, 2023

Conversation

oleibman
Copy link
Collaborator

@oleibman oleibman commented Mar 1, 2023

Fix #3405. Autosize is definitely not working well with CJK characters (column is not wide enough). User reports a workaround using mb_strwidth to calculate and set the column width. PhpSpreadsheet uses mb_strlen for width calculations. Change it to use mb_strwidth instead. For non-CJK strings, the results will be identical (and there are already unit tests on such strings which assert the expected results, and these tests did not need to change). For CJK strings, the results will be wider. The string I'm using to test comes from the issue. It currently results in a column width of 30.564. When I open the resulting sheet in Excel and auto-fit the column width, the width winds up as 43.00. So, as long as the computed width exceeds 43.00, the spreadsheet will show the full cell. With the new calculation, the computed width is 55.2722, satisfying our condition. This is wider than expected, but that is generally true for this type of computation. For example, for 'abcdefghijklmnopqrstuvwxyz', the computed width (before and after this change) is 31.7065, but Excel auto-fit actually uses 24.73.

"Exact width calculation" works well for fonts that support CJK, even without this PR. Since none of the fonts included in Shared/Font support CJK, this requires the use of the Shared/Font::setTrueTypeFontPath and Shard/Font::setExtraFontArray methods.

This is:

  • a bugfix
  • a new feature
  • refactoring
  • additional unit tests

Checklist:

  • Changes are covered by unit tests
    • Changes are covered by existing unit tests
    • New unit tests have been added
  • Code style is respected
  • Commit message explains why the change is made (see https://github.com/erlang/otp/wiki/Writing-good-commit-messages)
  • CHANGELOG.md contains a short summary of the change and a link to the pull request if applicable
  • Documentation is updated as necessary

Why this change is needed?

Provide an explanation of why this change is needed, with links to any Issues (if appropriate).
If this is a bugfix or a new feature, and there are no existing Issues, then please also create an issue that will make it easier to track progress with this PR.

Fix PHPOffice#3405. Autosize is definitely not working well with CJK characters (column is not wide enough). User reports a workaround using `mb_strwidth` to calculate and set the column width. PhpSpreadsheet uses `mb_strlen` for width calculations. Change it to use mb_strwidth instead. For non-CJK strings, the results will be identical (and there are already unit tests on such strings which assert the expected results, and these tests did not need to change). For CJK strings, the results will be wider. The string I'm using to test comes from the issue. It currently results in a column width of 30.564. When I open the resulting sheet in Excel and auto-fit the column width, the width winds up as 43.00. So, as long as the computed width exceeds 43.00, the spreadsheet will show the full cell. With the new calculation, the computed width is 55.2722, satisfying our condition. This is wider than expected, but that is generally true for this type of computation. For example, for 'abcdefghijklmnopqrstuvwxyz', the computed width (before and after this change) is 31.7065, but Excel auto-fit actually uses 24.73.

Disappointingly, "exact width calculation" does not solve this problem. It does seem to do a little better than "approximate" for non-CJK, but its CJK calculation is not wide enough. This might or might not indicate a bug in Php function `imagegetttfbbox`; I do not know enough about it to report a bug. Anyhow, since we're dependent on that result, there is no equivalent in this case for swapping mb_strlen out for mb_strwidth.
@oleibman
Copy link
Collaborator Author

oleibman commented Mar 3, 2023

I was wrong to suggest a problem with exact width calculation" - I thought the font I was using supported the CJK characters, but it doesn't - testing with a font with verified support for the characters worked just fine. Description has been updated.

@oleibman oleibman merged commit bb54c89 into PHPOffice:master Mar 4, 2023
@oleibman oleibman deleted the issue3405 branch March 24, 2023 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

中文自动列宽设置后无效
1 participant