Excel-Writer-XLSX
view release on metacpan or search on metacpan
lib/Excel/Writer/XLSX/Worksheet.pm view on Meta::CPAN
if ($pixels) {
$width = _pixels_to_width( $pixels );
}
return $self->set_column( $first_col, $last_col, $width, $format,
$hidden, $level );
}
###############################################################################
#
# autofit()
#
# Simulate autofit based on the data, and datatypes in each column. We do this
# by estimating a pixel width for each cell data.
#
sub autofit {
my $self = shift;
my $max_width = shift || 255.0;
my %col_width = ();
# Convert the autofit maximum pixel width to a column/character width, but
# limit it to the Excel max limit.
$max_width = _pixels_to_width($max_width);
if ( $max_width > 255.0 ) {
$max_width = 255.0;
}
# Create a reverse lookup for the share strings table so we can convert
# the string id back to the original string.
my @strings;
while ( my $key = each %{ ${ $self->{_str_table} } } ) {
$strings[ ${ $self->{_str_table} }->{$key} ] = $key;
}
# Iterate through all the data in the worksheet.
for my $row_num ( $self->{_dim_rowmin} .. $self->{_dim_rowmax} ) {
# Skip row if it doesn't contain cell data.
if ( !$self->{_table}->{$row_num} ) {
next;
}
if ( my $row_ref = $self->{_table}->{$row_num} ) {
for my $col_num ( $self->{_dim_colmin} .. $self->{_dim_colmax} ) {
if ( my $cell = $self->{_table}->{$row_num}->{$col_num} ) {
# Get the cell type and data.
my $type = $cell->[0];
my $token = $cell->[1];
my $length = 0;
if ( $type eq 's' || $type eq 'r' ) {
# Handle strings and rich strings.
#
# For standard shared strings we do a reverse lookup
# from the shared string id to the actual string. For
# rich strings we use the unformatted string. We also
# split multiline strings and handle each part
# separately.
my $string;
if ( $type eq 's' ) {
# Handle standard shared strings.
$string = $strings[$token];
}
else {
# Handle rich strings without html formatting.
$string = $cell->[3];
}
if ( $string !~ /\n/ ) {
$length = xl_cell_autofit_width( $string );
}
else {
# Handle multiline strings.
my @segments = split "\n", $string;
for my $string ( @segments ) {
my $seg_length =
xl_cell_autofit_width( $string );
if ( $seg_length > $length ) {
$length = $seg_length;
}
}
}
}
elsif ( $type eq 'n' ) {
# Handle numbers.
#
# We use a workaround/optimization for numbers since
# digits all have a pixel width of 7. This gives a
# slightly greater width for the decimal place and
# minus sign but only by a few pixels and
# over-estimation is okay.
$length = 7 * length $token;
}
elsif ( $type eq 't' ) {
# Handle dates.
#
# The following uses the default width for mm/dd/yyyy
# dates. It isn't feasible to parse the number format
# to get the actual string width for all format types.
$length = $self->{_default_date_pixels};
}
elsif ( $type eq 'l' ) {
# Handle boolean values.
#
# Use the Excel standard widths for TRUE and FALSE.
if ( $token ) {
$length = 31;
}
else {
$length = 36;
}
( run in 3.362 seconds using v1.01-cache-2.11-cpan-71847e10f99 )