2010-06-16 34 views
4

我使用各种(而不是完美的)PHP转换器/生成器将数据网格导出为RTF,PDF等。以类似于HTML的方式计算列宽(基于单元格内容)

我最缺少的是根据单元格中字符串的长度(字符串包含换行符使得事情有点复杂,因为它们应该被保留)而自动调整列宽。

我需要一个算法,给定的单元格内容(纯文本),表的总宽度和字符的平均宽度,将返回每列的宽度。如果有东西可用,我不想重新发明轮子。

当然,如果字体的宽度是可变的,它不可能是完美的,但是近似值就可以。或者也许它可以为每个字符配置一个宽度可配置的表格。

任何提示,将不胜感激。

回答

2

这不是一件容易的事。

在PHPExcel,当一个小区被设置为autowidth,我们使用GD库imagettfbbox()函数

// font size should really be supplied in pixels in GD2, 
// but since GD2 seems to assume 72dpi, pixels and points are the same 
$fontFile = self::getTrueTypeFontFileFromFont($font); 
$textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text); 

// Get corners positions 
$lowerLeftCornerX = $textBox[0]; 
$lowerLeftCornerY = $textBox[1]; 
$lowerRightCornerX = $textBox[2]; 
$lowerRightCornerY = $textBox[3]; 
$upperRightCornerX = $textBox[4]; 
$upperRightCornerY = $textBox[5]; 
$upperLeftCornerX = $textBox[6]; 
$upperLeftCornerY = $textBox[7]; 

// Consider the rotation when calculating the width 
$textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX); 

return $textWidth; 

这是非常密集的,虽然,特别是在处理大型工作表时,所以我们也有一个替代(近似)方法

// Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size. 
switch ($fontName) { 
    case 'Calibri': 
     // value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font. 
     $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); 
     $columnWidth = $columnWidth * $fontSize/11; // extrapolate from font size 
     break; 

    case 'Arial': 
     // value 7 was found via interpolation by inspecting real Excel files with Arial 10 font. 
     $columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText)); 
     $columnWidth = $columnWidth * $fontSize/10; // extrapolate from font size 
     break; 

    case 'Verdana': 
     // value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font. 
     $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText)); 
     $columnWidth = $columnWidth * $fontSize/10; // extrapolate from font size 
     break; 

    default: 
     // just assume Calibri 
     $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); 
     $columnWidth = $columnWidth * $fontSize/11; // extrapolate from font size 
     break; 
} 

// Calculate approximate rotated column width 
if ($rotation !== 0) { 
    if ($rotation == -165) { 
     // stacked text 
     $columnWidth = 4; // approximation 
    } else { 
     // rotated text 
     $columnWidth = $columnWidth * cos(deg2rad($rotation)) 
         + $fontSize * abs(sin(deg2rad($rotation)))/5; // approximation 
    } 
} 

// pixel width is an integer 
$columnWidth = (int) $columnWidth; 
return $columnWidth; 
+0

嗨。我实际上使用的PHPExcel(我很喜欢),但它不是我的问题的一部分,它处理自动大小列很好(除了与富文本连接的单元格)。我将从你的代码开始,也许更新它来处理换行符(CountCharacters函数)和一些启发式来包装文本,以保持列的总宽度小于页面的宽度(电子表格通常不会有这个约束)。谢谢! – cipak 2010-06-17 13:09:58

相关问题