Calculating height/width and ySplit/xSplit for Open XML spreadsheets
Setup: Open Excel 2007, set the width of the first column to 15.0 (110 px), the height of the first row to 30.0 (40 px), split the widow pane in four at the first cell, and save the file.
When you open the file with the Open XML SDK 2.0 Productivity Tool the column width is "15.7109375" and the height is "30", yet the xSplit value is "2040" and the ySplit value is "795".
Can someone please explain how can I convert "15.0" to "110 px" to "15.7109375 width" to "2040 xSplit" for 开发者_开发百科columns, and "30.0" to "40 px" to "30 ht" to "795 ySplit" for rows?
How can I calculate these numbers and convert from one to the other?
I recently had to work this out on an open source project so I thought that I'd post an answer here to help anyone else who encounters the same problem.
The calculation for the internal column width is documented in the ECMA-376 Part 1 and elsewhere.
The internal row height is the same as the height shown in the Excel interface.
The split pane xSplit and ySplit dimensions are the tricky ones. I didn't find any specific documentation on how they are calculated apart from the fact that they are in units of 1/20 of a point. The calculations for these I deduced from interpolated data extracted from xlsx files and from similar calculations used in the xls file format.
Here is an example in Perl that demonstrates the calculations:
#!/usr/bin/perl -l
use warnings;
use strict;
my $width = 15;
my $height = 30;
print "Column width in characters = ", calculate_column_width( $width );
print "Column width for xSplit = ", calculate_x_split_width( $width ), "\n";
print "Row height in characters = ", $height;
print "Row height for ySplit = ", calculate_y_split_height( $height );
#
# Convert column width from user units to character width.
#
sub calculate_column_width {
my $width = shift;
my $max_digit_width = 7; # For Calabri 11.
my $padding = 5;
$width = ( $width * $max_digit_width + $padding ) / $max_digit_width;
$width = int( $width * 256 ) / 256;
return $width;
}
#
# Convert column width from user units to pane split width.
#
sub calculate_x_split_width {
my $width = shift;
my $max_digit_width = 7; # For Calabri 11.
my $padding = 5;
my $pixels;
# Convert to pixels.
if ( $width < 1 ) {
$pixels = int( $width * 12 + 0.5 );
}
else {
$pixels = int( $width * $max_digit_width + 0.5 ) + $padding;
}
# Convert to points.
my $points = $pixels * 3 / 4;
# Convert to twips (twentieths of a point).
my $twips = $points * 20;
# Add offset/padding.
$width = $twips + 390;
return $width;
}
#
# Convert row height from user units to pane split height.
#
sub calculate_y_split_height {
my $height = shift;
$height = int( 20 * $height + 300 );
return $height;
}
__END__
The output from this is:
Column width in characters = 15.7109375
Column width for xSplit = 2040
Row height in characters = 30
Row height for ySplit = 900
Note, the ySplit value isn't the same as the value in your question. However it does correlate with values extracted from several sample xlsx files that I tried. Perhaps, your sample file was using a different default font height.
精彩评论