Skip to content

Commit f652a94

Browse files
committed
docs: add autofit documentation
1 parent ab8938e commit f652a94

File tree

6 files changed

+61
-13
lines changed

6 files changed

+61
-13
lines changed

Changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1515
- Add border, fill, gradient and pattern formatting options for
1616
chart titles and also chart axis titles.
1717

18+
- Added documentation for the Worksheet `autofit()` method and the Utility
19+
`xl_cell_autofit_width()` function.
20+
1821

1922
### Fixed
2023

MANIFEST

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2188,7 +2188,7 @@ t/utility/xl_parse_time.t
21882188
t/utility/xl_range.t
21892189
t/utility/xl_range_formula.t
21902190
t/utility/xl_rowcol_to_cell.t
2191-
t/utility/xl_string_pixel_width.t
2191+
t/utility/xl_cell_autofit_width.t
21922192
t/workbook/sub_close.t
21932193
t/workbook/sub_get_chart_range.t
21942194
t/workbook/sub_sort_defined_names.t

lib/Excel/Writer/XLSX.pm

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2389,7 +2389,7 @@ Examples:
23892389
23902390
The width corresponds to the column width value that is specified in Excel. It is approximately equal to the length of a string in the default font of Calibri 11. To set the width in pixels use the C<set_column_pixels()> method, see below.
23912391
2392-
Unfortunately, there is no way to specify "AutoFit" for a column in the Excel file format. This feature is only available at runtime from within Excel.
2392+
See also the C<autofit()> method to set the column widths based on the data in the column, approximately.
23932393
23942394
As usual the C<$format> parameter is optional, for additional information, see L</CELL FORMATTING>. If you wish to set the format without changing the width you can pass C<undef> as the width parameter:
23952395
@@ -2459,6 +2459,33 @@ The option to hide unused rows is used by Excel as an optimisation so that the u
24592459
See the C<hide_row_col.pl> example program.
24602460
24612461
2462+
=head2 autofit($max_width)
2463+
2464+
Autofit the worksheet column widths to the widest data in the column, approximately.
2465+
2466+
$worksheet->autofit();
2467+
2468+
Excel autofits columns at runtime when it has access to all of the required worksheet information as well as the Windows functions for calculating display areas based on fonts and formatting. Excel::Writer::XLSX doesn't have access to these Windows functions so it simulates autofit by calculating string widths based on metrics taken from Excel. This isn't perfect but for most cases it should be sufficient and indistinguishable from the output of Excel. However there are some limitations to be aware of when using this method:
2469+
2470+
=over 4
2471+
2472+
=item * It is based on the default Excel font type and size of Calibri 11. It will not give accurate results for other fonts or font sizes.
2473+
2474+
=item * It doesn't take formatting of numbers or dates account, although this may be addressed in a later version.
2475+
2476+
=item * Autofit is a relatively expensive operation since it performs a calculation for all the populated cells in a worksheet. See the note on performance below.
2477+
2478+
=back
2479+
2480+
For cases that don't match your desired output you can set explicit column widths via C<set_column()> or C<set_column_pixels()> method ignores columns that have already been explicitly set if the width is greater than the calculated autofit width. Alternatively, setting the column width explicitly after calling C<autofit()> will override the autofit value. You can also set an upper limit using the optional C<$max_width> parameter as explained below.
2481+
2482+
Excel autofits very long strings up to limit of 1790 pixels/255 characters. This is often too wide to display on a single screen at normal zoom. As such the optional C<$max_width> parameter is provided to enable a smaller upper pixel limit for autofitting long strings. A value of 300 pixels is recommended as a good compromise between column width and readability:
2483+
2484+
$worksheet->autofit(300);
2485+
2486+
If you need more control over the autofit effect you can use the L<Excel::Writer::XLSX::Utility> C<xl_cell_autofit_width()> function to calculate the autofit width for a cell value. This is the same calculation used internally by C<autofit()>.
2487+
2488+
24622489
24632490
24642491
=head2 outline_settings( $visible, $symbols_below, $symbols_right, $auto_style )

lib/Excel/Writer/XLSX/Utility.pm

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ my @rowcol = qw(
4040
xl_dec_row
4141
xl_inc_col
4242
xl_dec_col
43-
xl_string_pixel_width
43+
xl_cell_autofit_width
4444
);
4545

4646
# Date and Time functions
@@ -529,14 +529,14 @@ sub xl_date_1904 {
529529

530530
###############################################################################
531531
#
532-
# xl_string_pixel_width($string)
532+
# xl_cell_autofit_width($string)
533533
#
534534
# Get the pixel width of a string based on individual character widths taken
535535
# from Excel. UTF8 characters are given a default width of 8.
536536
#
537537
# Note, Excel adds an additional 7 pixels padding to a cell.
538538
#
539-
sub xl_string_pixel_width {
539+
sub xl_cell_autofit_width {
540540
my $length = 0;
541541

542542
for my $char (split //, shift) {
@@ -1092,6 +1092,24 @@ This functions takes a cell reference string in A1 notation and decrements the c
10921092
my $str = xl_dec_col( '$C1' ); # $B1
10931093
my $str = xl_dec_col( '$E$5' ); # $D$5
10941094
1095+
1096+
=head2 xl_cell_autofit_width($string)
1097+
1098+
Parameters: $string, The string to calculate the cell width for.
1099+
1100+
Returns: The string autofit width in pixels. Returns 0 if the string is empty.
1101+
1102+
This function calculates the width required to auto-fit a string in a cell:
1103+
1104+
my $width = xl_cell_autofit_width($string);
1105+
1106+
The Worksheet C<autofit()> method can be used to auto-fit cell data to the optimal column width. However, in some cases you may wish to handle auto-fitting yourself and apply additional logic to limit the maximum and minimum ranges.
1107+
1108+
The C<xl_cell_autofit_width()> function can be used to perform the required calculation. It works by estimating the pixel width of a string based on the width of each character. It also adds a 7 pixel padding for the cell boundary in the same way that Excel does.
1109+
1110+
You can use the calculated width in conjunction with Worksheet C<set_column_pixels()> method.
1111+
1112+
10951113
=head1 TIME AND DATE FUNCTIONS
10961114
10971115
Dates and times in Excel are represented by real numbers, for example "Jan 1 2001 12:30:14 PM" is represented by the number 36892.521.

lib/Excel/Writer/XLSX/Worksheet.pm

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use Excel::Writer::XLSX::Utility qw(xl_cell_to_rowcol
2929
xl_rowcol_to_cell
3030
xl_col_to_name
3131
xl_range
32-
xl_string_pixel_width
32+
xl_cell_autofit_width
3333
quote_sheetname
3434
get_image_properties);
3535

@@ -832,14 +832,14 @@ sub autofit {
832832
}
833833

834834
if ( $string !~ /\n/ ) {
835-
$length = xl_string_pixel_width( $string );
835+
$length = xl_cell_autofit_width( $string );
836836
}
837837
else {
838838
# Handle multiline strings.
839839
my @segments = split "\n", $string;
840840
for my $string ( @segments ) {
841841
my $seg_length =
842-
xl_string_pixel_width( $string );
842+
xl_cell_autofit_width( $string );
843843

844844
if ( $seg_length > $length ) {
845845
$length = $seg_length;
@@ -887,15 +887,15 @@ sub autofit {
887887
# non-zero value.
888888
my $value = $cell->[3];
889889
if ( $value ) {
890-
$length = xl_string_pixel_width( $value );
890+
$length = xl_cell_autofit_width( $value );
891891
}
892892
}
893893
elsif ( $type eq 'a' || $type eq 'd' ) {
894894

895895
# Handle array and dynamic formulas.
896896
my $value = $cell->[4];
897897
if ( $value ) {
898-
$length = xl_string_pixel_width( $value );
898+
$length = xl_cell_autofit_width( $value );
899899
}
900900
}
901901

t/utility/xl_string_pixel_width.t

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99

1010
use strict;
1111
use warnings;
12-
use Excel::Writer::XLSX::Utility qw(xl_string_pixel_width);
12+
use Excel::Writer::XLSX::Utility qw(xl_cell_autofit_width);
1313

1414
use utf8;
1515
use Test::More tests => 100;
1616

1717

1818
###############################################################################
1919
#
20-
# Test the xl_string_pixel_width() function.
20+
# Test the xl_cell_autofit_width() function.
2121
#
2222
my @tests = (
2323

@@ -129,7 +129,7 @@ my @tests = (
129129
for my $test ( @tests ) {
130130
my $string = $test->[0];
131131
my $expected = $test->[1];
132-
my $got = xl_string_pixel_width( $string );
132+
my $got = xl_cell_autofit_width( $string );
133133
is( $got, $expected, "String = " . $string );
134134
}
135135

0 commit comments

Comments
 (0)