php - 以类似 HTML 的方式计算列宽(基于单元格内容)

标签 php algorithm html-table autosize column-width

我有一个数据网格,我想使用各种(并非完美的)PHP 转换器/生成器将其导出为 RTF、PDF 等。

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

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

当然,如果字体是可变宽度的,它就不可能是完美的,但一个近似值就可以了。或者它可能有一个可配置的表格,其中包含每个字符的宽度。

如有任何提示,我们将不胜感激。

最佳答案

这不是一件容易的事。

在PHPExcel中,当单元格设置为自动宽度时,我们使用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;

关于php - 以类似 HTML 的方式计算列宽(基于单元格内容),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3051809/

相关文章:

php - 当一切都已安装但仍然无法正常工作时,如何使用 LAMP 解决 Wordpress

javascript - 将字符串转换为数组以用于 highcharts js

javascript - 如何使用正则表达式将文本样式更改为特定模式?

html - 如何使用类更改我表中第一个 td 的颜色

html - Rowspan 无法正常工作,我该怎么做才能实现这一目标?

html - 添加填充以显示 : table-header-group

php - 具有两种类型标志的表上的 Laravel 关系

单击鼠标时,Javascript获取网页上最近的超链接

c++ - 需要帮助编写一个函数来查找 N 维数组 C++ 中的最大值和最小值

string - 递归删除字符串中所有出现的子字符串的有效方法是什么?