2010-06-16 8 views
4

J'ai une grille de données que je veux exporter vers RTF, PDF etc. en utilisant divers convertisseurs/générateurs PHP (et pas parfaits). Ce qui me manque le plus, c'est l'ajustement automatique des largeurs de colonnes en fonction de la longueur des chaînes dans les cellules (les chaînes contiennent des sauts de ligne qui compliquent un peu les choses, car elles doivent être conservées).Calculer des largeurs de colonnes de manière HTML (en fonction du contenu des cellules)

J'ai besoin d'un algorithme qui, étant donné le contenu des cellules (texte brut), une largeur totale de la table et une largeur moyenne d'un caractère, retournerait une largeur pour chaque colonne. Je ne voudrais pas réinventer la roue si quelque chose est déjà disponible.

Bien sûr, il ne peut pas être parfait si la largeur de la police est variable, mais une approximation serait parfaite. Ou peut-être qu'il pourrait avoir une table configurable avec des largeurs pour chaque caractère.

Tout indice serait apprécié.

Répondre

2

Ce n'est pas une tâche facile.

En PHPExcel, lorsqu'une cellule est réglée sur Largeur automatique, nous utilisons la bibliothèque GD imagettfbbox() fonction

// 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; 

Il est bien que très intense, surtout lorsque l'on travaille avec de grandes feuilles de calcul, nous avons donc une alternative (approximation) méthode

// 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

Hi. J'utilise actuellement PHPExcel (ce que j'aime bien) mais cela ne fait pas partie de mon problème, il gère très bien les colonnes autosize (sauf pour les cellules jointes avec du texte enrichi). Je vais commencer avec votre code et peut-être le mettre à jour pour gérer les sauts de ligne (la fonction CountCharacters) et quelques heuristiques pour enrouler le texte afin de garder la largeur totale des colonnes inférieure à la largeur de la page. contrainte). Je vous remercie! – cipak

Questions connexes