Faktor soll umso kleiner werden, desto größer ein anderer Wert ist, aber nicht linear (Excel-Spaltenbreite bestimmen)

  • PHP

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von Marcus Gräfe.

    Faktor soll umso kleiner werden, desto größer ein anderer Wert ist, aber nicht linear (Excel-Spaltenbreite bestimmen)

    Meine Frage lässt sich sicher allgemein beantworten, ist aber im konkreten Fall für PHP.

    Zum Hintergrund: Ich erstelle mit einer Library eine Excel-Datei und möchte im Anschluss die Spaltenbreiten auf das Optimum setzen (ein echtes Autosize gibt es dort nicht). Zunächst ermittle ich dafür mittels mb_strwidth die maximale Wortlänge. Das ist schon recht gut im Ergebnis. Nun ist mir aber aufgefallen, dass je länger ein Wort ist, desto mehr Freiraum habe ich am Ende einer Tabellenzelle.

    Beispiel:
    Wortlänge 10: Wort passt so gerade eben rein, evtl. leicht angeschnitten
    Wortlänge: 100: Die Zelle ist etwas größer, aber völlig OK, sieht gut aus
    Wortlänge 300: Die Zelle ist viel zu groß

    Ich bräuchte nun also eine Art Formel, mit welcher ich dafür sorge, dass die Spaltenbreite bei wenigen Zeichen mind. mb_strwidth ist (bzw. eigentlich leicht größer), aber bei mehr Zeichen kleiner wird. Ich habe schon vieles versucht, alles war linear und führt nicht um richtigen Ergebnis. Ein Beispiel, was nicht richtig klappt (weil linear): $width *= 1 + (1 / $width);.

    Hat jemand einen Ansatz für mich?

    EDIT: Im Titel stand, der Faktor soll mind. 1 sein. War Quatsch.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Wenn Du ein paar Optimalwerte für gewisse Spaltenbreiten hast, könntest Du Dir in Excel ein Diagramm erstellen und dazu Formelvorschläge unterbreiten lassen.
    Warum ist Deine Vorschlagsformel linear? bei width = 1 wird die Breite verdoppelt, bei 2 ist der Faktor 1,5, bei width = 100 ist es nur Faktor 1,01.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed
    Evtl. habe ich das falsche Wort benutzt, aber für mich ist das linear:

    PHP-Quellcode

    1. for ($i=10; $i <= 100; $i += 10) {
    2. $width = $i;
    3. $width *= 1 + (1 / $width);
    4. echo "\n" . $width;
    5. }

    Ergibt:

    Quellcode

    1. 11
    2. 21
    3. 31
    4. 41
    5. 51
    6. 61
    7. 71
    8. 81
    9. 91
    10. 101

    Statt der 101 sollte da aber eher sowas wie 80 stehen. Die Kurve sollte also abflachen.

    EDIT: D. h. der Faktor soll, wie ich nun feststelle, gar nicht immer mind. 1 sein. Habe das im Titel weggemacht. Vielleicht ist "linear" gar nicht mein Problem. Ich habe diesen Post nun schon so oft editiert, weil ich mittlerweile selbst verwirrt bin, was nun eigentlich mein Problem ist ...

    @Takafusa
    Die Funktion hatte ich gesehen. Ich befürchte nur, dass diese meine Excel-Generierung zu langsam machen wird (kann ich aber mal probieren). Es handelt sich teilweise um zehntausende Zellen.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Ich hab's jetzt mal mit dem Excelweg gemacht und komm auf:

    Quellcode

    1. 10 -> 21,44
    2. 20 -> 34,76
    3. 30 -> 46,96
    4. 40 -> 58,04
    5. 50 -> 68
    6. 60 -> 76,84
    7. 70 -> 84,56
    8. 80 -> 91,16
    9. 90 -> 96,64
    10. 100 -> 101

    bei der Formel width = -0.0056 * i * i + 1.5 * i + 7
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Also der sinnvollste Weg (wenn du nicht ne komplette korrekte Berechnung machen willst) wär vermutlich, einige (möglichst viele) Paare von (Anzahl Buchstaben, Gewünschte Breite) zu sammeln, und darauf ne Regression zu machen. Damit kriegst du dann ne Funktion, die dein gewünschtes Verhalten möglichst gut annähert. Ne quadratische Annäherung wie von VaporiZed vorgeschlagen bringt da vermutlich nicht wirklich dein Verhalten, weil die bei ganz langen Zeilen dann wieder gegen 0 geht (und sogar negativ wird) - du willst da eher etwas, das "langsamer" als linear ist, also z.B. ne Annäherung mit Logarithmen oder Wurzelfunktionen. Die Regression selbst kannste gut mit Excel und co. machen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nafets“ ()

    Danke euch für die Tipps. Ich werde in der kommenden Woche mal schauen, wie ich es letztendlich mache. Ich denke, jetzt müsste ich hinbekommen, was ich vorhabe.

    Ich habe meine Zahlen und die von @VaporiZed mal visualisiert (siehe Anhang). Da sieht man dann auch, warum ich von "linear" schrieb.

    nafets schrieb:

    weil die bei ganz langen Zeilen dann wieder gegen 0 geht

    Es gibt allerdings in meinem Fall ein Maximum von 243 Zeichen und ein Minimum von 3 Zeichen. Daher könnte das evtl. doch klappen. Aber mal sehen ...
    Bilder
    • diagramm.jpg

      47 kB, 1.035×526, 105 mal angesehen
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Soweit mich meine mathematischen Kenntnisse nicht täuschen, ist eine abflachende Kurve immer eine Logarithmische oder Exponentielle-Funktion. Mir schwebt dort gerade wieder aus der Physik die Gleichung für das Aufladen eines Kondensators vor:
    schule-bw.de/faecher-und-schul…ung/kondensatorladung.htm

    schau hier mal 4.

    Dort ist die Kurve zu sehen und zeigt zumindest den Ansatz deiner Funktion:

    ​O + k * e^(-p * t)
    wobei O den Offset beschreibt, k die Stärke und e eben als exponentielle Funktion steht. (wichtig: k und p können durchaus negativ werden. Je nachdem, welche Endwerte gewünscht werden)
    FPDF hat eine Funktion mit der sich Textlängen berechnen lassen, eventuell könnte das dein Problem lösen. Hier wird jedem Buchstaben ein Fixwert zugwiesen.
    Ich hab zuhause kein Excel zur Hand hab daher das ganze mal mit nem HTML Div versucht und bekomme dabei folgendes Ergebniss:


    Wirklich wichtig wären hier nur die Funktion StringHelper::getStringWidth(string, FontBase) und die Klasse Helvetica.

    Spoiler anzeigen

    index.php

    PHP-Quellcode

    1. <?php
    2. use MeasureString\Font\Helvetica;
    3. use MeasureString\StringHelper;
    4. require_once __DIR__.'/font/FontBase.php';
    5. require_once __DIR__.'/font/helvetica.php';
    6. require_once __DIR__.'/StringHelper.php';
    7. $font = new Helvetica(16);
    8. $divs = [];
    9. for($i = 10; $i < 300; $i += 10)
    10. {
    11. $str = StringHelper::createString($i);
    12. $width = StringHelper::getStringWidth($str, $font);
    13. $divs[] = "<div style='width:{$width}px; border: 1px solid black;'>{$str}</div>";
    14. }
    15. die(StringHelper::createHTML($divs));



    StringHelper.php

    PHP-Quellcode

    1. <?php
    2. namespace MeasureString;
    3. use MeasureString\Font\FontBase;
    4. class StringHelper
    5. {
    6. public static function createHTML(array $divs) : string
    7. {
    8. $content = implode("\r\n", $divs);
    9. return "
    10. <html lang='de'>
    11. <body style='font-size:16px;font-family: Arial, monospace;'>{$content}</body>
    12. </html>
    13. ";
    14. }
    15. public static function createString(int $length) : string
    16. {
    17. if ($length < 4)
    18. return '';
    19. $length /= 2;
    20. $bytes = openssl_random_pseudo_bytes($length);
    21. return bin2hex($bytes);
    22. }
    23. public static function getStringWidth(string $s, FontBase $font): float
    24. {
    25. $width = 0;
    26. $len = strlen($s);
    27. for($i = 0; $i < $len; $i++)
    28. $width += $font->cw[$s[$i]];
    29. return $width * $font->size/1000;
    30. }
    31. }



    FontBase.php

    PHP-Quellcode

    1. <?php
    2. namespace MeasureString\Font;
    3. class FontBase
    4. {
    5. public string $name;
    6. public int $size;
    7. public array $cw;
    8. public function __construct(string $name, int $size)
    9. {
    10. $this->name = $name;
    11. $this->size = $size;
    12. }
    13. }



    helvetica.php

    PHP-Quellcode

    1. <?php
    2. namespace MeasureString\Font;
    3. class Helvetica extends FontBase
    4. {
    5. public function __construct(int $size)
    6. {
    7. parent::__construct('Helvetica', $size);
    8. $this->cw = [
    9. chr(0) => 278,
    10. chr(1) => 278,
    11. chr(2) => 278,
    12. chr(3) => 278,
    13. chr(4) => 278,
    14. chr(5) => 278,
    15. chr(6) => 278,
    16. chr(7) => 278,
    17. chr(8) => 278,
    18. chr(9) => 278,
    19. chr(10) => 278,
    20. chr(11) => 278,
    21. chr(12) => 278,
    22. chr(13) => 278,
    23. chr(14) => 278,
    24. chr(15) => 278,
    25. chr(16) => 278,
    26. chr(17) => 278,
    27. chr(18) => 278,
    28. chr(19) => 278,
    29. chr(20) => 278,
    30. chr(21) => 278,
    31. chr(22) => 278,
    32. chr(23) => 278,
    33. chr(24) => 278,
    34. chr(25) => 278,
    35. chr(26) => 278,
    36. chr(27) => 278,
    37. chr(28) => 278,
    38. chr(29) => 278,
    39. chr(30) => 278,
    40. chr(31) => 278,
    41. ' ' => 278,
    42. '!' => 278,
    43. '"' => 355,
    44. '#' => 556,
    45. '$' => 556,
    46. '%' => 889,
    47. '&' => 667,
    48. '\'' => 191,
    49. '(' => 333,
    50. ')' => 333,
    51. '*' => 389,
    52. '+' => 584,
    53. ',' => 278,
    54. '-' => 333,
    55. '.' => 278,
    56. '/' => 278,
    57. '0' => 556,
    58. '1' => 556,
    59. '2' => 556,
    60. '3' => 556,
    61. '4' => 556,
    62. '5' => 556,
    63. '6' => 556,
    64. '7' => 556,
    65. '8' => 556,
    66. '9' => 556,
    67. ':' => 278,
    68. ';' => 278,
    69. '<' => 584,
    70. '=' => 584,
    71. '>' => 584,
    72. '?' => 556,
    73. '@' => 1015,
    74. 'A' => 667,
    75. 'B' => 667,
    76. 'C' => 722,
    77. 'D' => 722,
    78. 'E' => 667,
    79. 'F' => 611,
    80. 'G' => 778,
    81. 'H' => 722,
    82. 'I' => 278,
    83. 'J' => 500,
    84. 'K' => 667,
    85. 'L' => 556,
    86. 'M' => 833,
    87. 'N' => 722,
    88. 'O' => 778,
    89. 'P' => 667,
    90. 'Q' => 778,
    91. 'R' => 722,
    92. 'S' => 667,
    93. 'T' => 611,
    94. 'U' => 722,
    95. 'V' => 667,
    96. 'W' => 944,
    97. 'X' => 667,
    98. 'Y' => 667,
    99. 'Z' => 611,
    100. '[' => 278,
    101. '\\' => 278,
    102. ']' => 278,
    103. '^' => 469,
    104. '_' => 556,
    105. '`' => 333,
    106. 'a' => 556,
    107. 'b' => 556,
    108. 'c' => 500,
    109. 'd' => 556,
    110. 'e' => 556,
    111. 'f' => 278,
    112. 'g' => 556,
    113. 'h' => 556,
    114. 'i' => 222,
    115. 'j' => 222,
    116. 'k' => 500,
    117. 'l' => 222,
    118. 'm' => 833,
    119. 'n' => 556,
    120. 'o' => 556,
    121. 'p' => 556,
    122. 'q' => 556,
    123. 'r' => 333,
    124. 's' => 500,
    125. 't' => 278,
    126. 'u' => 556,
    127. 'v' => 500,
    128. 'w' => 722,
    129. 'x' => 500,
    130. 'y' => 500,
    131. 'z' => 500,
    132. '{' => 334,
    133. '|' => 260,
    134. '}' => 334,
    135. '~' => 584,
    136. chr(127) => 350,
    137. chr(128) => 556,
    138. chr(129) => 350,
    139. chr(130) => 222,
    140. chr(131) => 556,
    141. chr(132) => 333,
    142. chr(133) => 1000,
    143. chr(134) => 556,
    144. chr(135) => 556,
    145. chr(136) => 333,
    146. chr(137) => 1000,
    147. chr(138) => 667,
    148. chr(139) => 333,
    149. chr(140) => 1000,
    150. chr(141) => 350,
    151. chr(142) => 611,
    152. chr(143) => 350,
    153. chr(144) => 350,
    154. chr(145) => 222,
    155. chr(146) => 222,
    156. chr(147) => 333,
    157. chr(148) => 333,
    158. chr(149) => 350,
    159. chr(150) => 556,
    160. chr(151) => 1000,
    161. chr(152) => 333,
    162. chr(153) => 1000,
    163. chr(154) => 500,
    164. chr(155) => 333,
    165. chr(156) => 944,
    166. chr(157) => 350,
    167. chr(158) => 500,
    168. chr(159) => 667,
    169. chr(160) => 278,
    170. chr(161) => 333,
    171. chr(162) => 556,
    172. chr(163) => 556,
    173. chr(164) => 556,
    174. chr(165) => 556,
    175. chr(166) => 260,
    176. chr(167) => 556,
    177. chr(168) => 333,
    178. chr(169) => 737,
    179. chr(170) => 370,
    180. chr(171) => 556,
    181. chr(172) => 584,
    182. chr(173) => 333,
    183. chr(174) => 737,
    184. chr(175) => 333,
    185. chr(176) => 400,
    186. chr(177) => 584,
    187. chr(178) => 333,
    188. chr(179) => 333,
    189. chr(180) => 333,
    190. chr(181) => 556,
    191. chr(182) => 537,
    192. chr(183) => 278,
    193. chr(184) => 333,
    194. chr(185) => 333,
    195. chr(186) => 365,
    196. chr(187) => 556,
    197. chr(188) => 834,
    198. chr(189) => 834,
    199. chr(190) => 834,
    200. chr(191) => 611,
    201. chr(192) => 667,
    202. chr(193) => 667,
    203. chr(194) => 667,
    204. chr(195) => 667,
    205. chr(196) => 667,
    206. chr(197) => 667,
    207. chr(198) => 1000,
    208. chr(199) => 722,
    209. chr(200) => 667,
    210. chr(201) => 667,
    211. chr(202) => 667,
    212. chr(203) => 667,
    213. chr(204) => 278,
    214. chr(205) => 278,
    215. chr(206) => 278,
    216. chr(207) => 278,
    217. chr(208) => 722,
    218. chr(209) => 722,
    219. chr(210) => 778,
    220. chr(211) => 778,
    221. chr(212) => 778,
    222. chr(213) => 778,
    223. chr(214) => 778,
    224. chr(215) => 584,
    225. chr(216) => 778,
    226. chr(217) => 722,
    227. chr(218) => 722,
    228. chr(219) => 722,
    229. chr(220) => 722,
    230. chr(221) => 667,
    231. chr(222) => 667,
    232. chr(223) => 611,
    233. chr(224) => 556,
    234. chr(225) => 556,
    235. chr(226) => 556,
    236. chr(227) => 556,
    237. chr(228) => 556,
    238. chr(229) => 556,
    239. chr(230) => 889,
    240. chr(231) => 500,
    241. chr(232) => 556,
    242. chr(233) => 556,
    243. chr(234) => 556,
    244. chr(235) => 556,
    245. chr(236) => 278,
    246. chr(237) => 278,
    247. chr(238) => 278,
    248. chr(239) => 278,
    249. chr(240) => 556,
    250. chr(241) => 556,
    251. chr(242) => 556,
    252. chr(243) => 556,
    253. chr(244) => 556,
    254. chr(245) => 556,
    255. chr(246) => 556,
    256. chr(247) => 584,
    257. chr(248) => 611,
    258. chr(249) => 556,
    259. chr(250) => 556,
    260. chr(251) => 556,
    261. chr(252) => 556,
    262. chr(253) => 500,
    263. chr(254) => 556,
    264. chr(255) => 500
    265. ];
    266. }
    267. }




    PS: Hab die GetStringWidth Funktion aus FPDF einfach mal in Testprojekt gepackt.
    @PadreSperanza
    Danke, schaue ich mir an.

    @Fakiz
    Vmtl. macht die Funktion nicht viel mehr als die in PHP eingebaute Funktion imagettfbbox (siehe Post #3).
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Kann ich mir fast nicht vorstellen, hab dazu mal fogende Schleife erstellt:

    PHP-Quellcode

    1. for($j = 0; $j < 500; $j++) {
    2. for ($i = 10; $i < 300; $i += 10) {
    3. $str = StringHelper::createString($i);
    4. $width = StringHelper::getStringWidth($str, $font);
    5. //$width = StringHelper::getStringWidthByGd($str, $fontSize, $fontFile);
    6. $divs[] = "<div style='width:{$width}px; border: 1px solid black;'>{$str}</div>";
    7. }
    8. }


    Die neu Funktion getStringWidthByGd ermittelt die breite des Textes über imagettfbbox aus der gd lib.

    PHP-Quellcode

    1. public static function getStringWidthByGd(string $s, int $size, string $font): int
    2. {
    3. $box = imagettfbbox($size, 45, $font, $s);
    4. if (is_array($box))
    5. return $box[4];
    6. return 0;
    7. }


    Die GD also imagettfbbox benötigt hierfür 17 Sekunden, die FPDF Variante 3 Sekunden. Da würde ich davon ausgehen das imagettfbbox anders arbeitet.

    Edit: Ohne Debug Connection benötigt imagettfbbox 10,24 sek. und die FPDF Variante 160 ms.

    PPS: Als Font -Datei für imagettfbbox hab ich die Arial.ttf von Windows verwendet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Fakiz“ ()

    Fakiz schrieb:

    Ohne Debug Connection benötigt imagettfbbox 10,24 sek. und die FPDF Variante 160 ms.

    Das klingt in der Tat nicht schlecht. Werde das in der kommenden Woche auf jeden Fall testen! Wenn's in meinem Fall auch schnell arbeitet, dann wäre das die bessere Alternative zu irgendwelchen Kurvenformeln. ;)
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Die ganze Geschichte ist wirklich recht kompliziert. Ich glaube, egal was man macht, man kommt nicht an das ran, was Excel macht, wenn man dort die automatische Breite bestimmen lässt.

    Es ist so, dass Excel die Breite 10 (es gibt keine Einheit) als die Breite von 5x "0" (Null) mit der Schriftart Calibri, Größe 11 definiert. Daher ist es schwierig, bei beliebigen Strings den exakten Excel-Wert zu bestimmen. Ich denke, man kann sich maximal annähern.

    Mit dem von @Fakiz geposteten Code komme ich anscheinend schon am nächsten dran, das hier ist mein Code:

    PHP-Quellcode

    1. function getStringWidth(string $s, int $fontSize): float {
    2. // Die echte Breite eines Strings in Excel-Breiteneinheit zurückgeben, Schriftart: Calibri, $fontSize pt
    3. // Quelle: FPDF (http://www.fpdf.org/), fpdf.php
    4. // Lizenz: "FPDF is released under a permissive license: there is no usage restriction. You may embed it freely in your application (commercial or not), with or without modifications."
    5. // Variable "$cw" wurde wie folgt generiert (gemäß Anleitung unter http://www.fpdf.org/en/tutorial/tuto7.htm): MakeFont('C:\\Windows\\Fonts\\calibri.ttf','cp1252');
    6. $cw = array( /* hier weggelassen, da zu lang */ );
    7. $w = 0;
    8. $l = mb_strlen($s);
    9. for ($i=0; $i < $l; $i++) $w += $cw[$s[$i]];
    10. return (($w * $fontSize / 1000) / 4.5) + (($cw['n'] * $fontSize / 1000) / 4.5 * 1.1); // Erst sind es Pixel, dann /4,5, um sich der korrekten Excel-Breiteneinheit anzunähern, dann plus Padding
    11. }

    Leider gibt es auch hier wieder das Problem, dass je länger ein String ist, desto mehr Freiraum entsteht. Die kleinen Strings hingegen passen knapp in die ermittelte Breite rein. Allerdings: ein String mittlerer Länge, der nur aus Großbuchstaben besteht, braucht natürlich mehr Platz als der entsprechende String mit gemischten Zeichen. Also die anfangs von mir gewünschte Kurve wird mir hier gar nicht helfen.

    Ich habe aber noch drei weitere Ideen, was ich tun kann (auch wenn ich in dieses Problem eigentlich schon viel zu viel Zeit investiert habe).

    1.) Ich ermittelte derzeit erst den längsten String (anhand der Zeichen) und führe dann die Funktion getStringWidth aus. Ich denke, ich müsste es für jeden String ausführen, um dann die maximale Länge zu haben. Eventuelles Problem: die Laufzeit.

    2.) Basierend auf der Information 5x "0" = Breite 10 die jeweilige Zahl ermitteln. Also quasi anhand der Infos aus der FPDF-Fontdatei ermitteln, wie weit die Größe des tatsächlichen Strings von einem String mit Nullen abweicht (oder so ähnlich).

    3.) In der Library "PhpSpreadsheet" den Autosize-Code extrahieren. Dort gibt's das, leider kann ich die Library nicht nutzen, da die viel zu langsam und viel zu speicherhungrig ist (ich verwende PHP_XLSXWriter und bei einer Zeilenanzahl von 35.000 ist der Unterschied 1000 MB/100s zu 80 MB/20s). Wobei ich nicht das Gefühl habe, dass die Funktion dort besser arbeitet als mein jetziger Code.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Breite von 5x "0" (Null)

    Das hört sich für mich nach der ch Unit an die wird relativ zur Breite "0" gemessen.

    Edit: So wie es aussieht verwendet Excel wohl pt als Font Size Unit, nachzulesen hier: Excel.Font.Size

    Leider gibt es auch hier wieder das Problem, dass je länger ein String ist, desto mehr Freiraum entsteht.

    Das Beispiel war bzw. ist für die Font Arial und Helvetica, für Calibri benötigst du andere Gewichtungen, veruschs mal damit.
    Calibri Font

    PHP-Quellcode

    1. <?php
    2. namespace MeasureString\Font;
    3. class Calibri extends FontBase
    4. {
    5. public function __construct(int $size)
    6. {
    7. parent::__construct('Calibri', $size);
    8. $this->cw = [
    9. chr(0)=>507,
    10. chr(1)=>507,
    11. chr(2)=>507,
    12. chr(3)=>507,
    13. chr(4)=>507,
    14. chr(5)=>507,
    15. chr(6)=>507,
    16. chr(7)=>507,
    17. chr(8)=>507,
    18. chr(9)=>507,
    19. chr(10)=>507,
    20. chr(11)=>507,
    21. chr(12)=>507,
    22. chr(13)=>507,
    23. chr(14)=>507,
    24. chr(15)=>507,
    25. chr(16)=>507,
    26. chr(17)=>507,
    27. chr(18)=>507,
    28. chr(19)=>507,
    29. chr(20)=>507,
    30. chr(21)=>507,
    31. chr(22)=>507,
    32. chr(23)=>507,
    33. chr(24)=>507,
    34. chr(25)=>507,
    35. chr(26)=>507,
    36. chr(27)=>507,
    37. chr(28)=>507,
    38. chr(29)=>507,
    39. chr(30)=>507,
    40. chr(31)=>507,
    41. ' '=>226,
    42. '!'=>326,
    43. '"'=>401,
    44. '#'=>498,
    45. '$'=>507,
    46. '%'=>715,
    47. '&'=>682,
    48. '\''=>221,
    49. '('=>303,
    50. ')'=>303,
    51. '*'=>498,
    52. '+'=>498,
    53. ','=>250,
    54. '-'=>306,
    55. '.'=>252,
    56. '/'=>386,
    57. '0'=>507,
    58. '1'=>507,
    59. '2'=>507,
    60. '3'=>507,
    61. '4'=>507,
    62. '5'=>507,
    63. '6'=>507,
    64. '7'=>507,
    65. '8'=>507,
    66. '9'=>507,
    67. ':'=>268,
    68. ';'=>268,
    69. '<'=>498,
    70. '='=>498,
    71. '>'=>498,
    72. '?'=>463,
    73. '@'=>894,
    74. 'A'=>579,
    75. 'B'=>544,
    76. 'C'=>533,
    77. 'D'=>615,
    78. 'E'=>488,
    79. 'F'=>459,
    80. 'G'=>631,
    81. 'H'=>623,
    82. 'I'=>252,
    83. 'J'=>319,
    84. 'K'=>520,
    85. 'L'=>420,
    86. 'M'=>855,
    87. 'N'=>646,
    88. 'O'=>662,
    89. 'P'=>517,
    90. 'Q'=>673,
    91. 'R'=>543,
    92. 'S'=>459,
    93. 'T'=>487,
    94. 'U'=>642,
    95. 'V'=>567,
    96. 'W'=>890,
    97. 'X'=>519,
    98. 'Y'=>487,
    99. 'Z'=>468,
    100. '['=>307,
    101. '\\'=>386,
    102. ']'=>307,
    103. '^'=>498,
    104. '_'=>498,
    105. '`'=>291,
    106. 'a'=>479,
    107. 'b'=>525,
    108. 'c'=>423,
    109. 'd'=>525,
    110. 'e'=>498,
    111. 'f'=>305,
    112. 'g'=>471,
    113. 'h'=>525,
    114. 'i'=>229,
    115. 'j'=>239,
    116. 'k'=>455,
    117. 'l'=>229,
    118. 'm'=>799,
    119. 'n'=>525,
    120. 'o'=>527,
    121. 'p'=>525,
    122. 'q'=>525,
    123. 'r'=>349,
    124. 's'=>391,
    125. 't'=>335,
    126. 'u'=>525,
    127. 'v'=>452,
    128. 'w'=>715,
    129. 'x'=>433,
    130. 'y'=>453,
    131. 'z'=>395,
    132. '{'=>314,
    133. '|'=>460,
    134. '}'=>314,
    135. '~'=>498,
    136. chr(127)=>507,
    137. chr(128)=>507,
    138. chr(129)=>507,
    139. chr(130)=>250,
    140. chr(131)=>305,
    141. chr(132)=>418,
    142. chr(133)=>690,
    143. chr(134)=>498,
    144. chr(135)=>498,
    145. chr(136)=>395,
    146. chr(137)=>1038,
    147. chr(138)=>459,
    148. chr(139)=>339,
    149. chr(140)=>867,
    150. chr(141)=>507,
    151. chr(142)=>468,
    152. chr(143)=>507,
    153. chr(144)=>507,
    154. chr(145)=>250,
    155. chr(146)=>250,
    156. chr(147)=>418,
    157. chr(148)=>418,
    158. chr(149)=>498,
    159. chr(150)=>498,
    160. chr(151)=>905,
    161. chr(152)=>450,
    162. chr(153)=>705,
    163. chr(154)=>391,
    164. chr(155)=>339,
    165. chr(156)=>850,
    166. chr(157)=>507,
    167. chr(158)=>395,
    168. chr(159)=>487,
    169. chr(160)=>226,
    170. chr(161)=>326,
    171. chr(162)=>498,
    172. chr(163)=>507,
    173. chr(164)=>498,
    174. chr(165)=>507,
    175. chr(166)=>498,
    176. chr(167)=>498,
    177. chr(168)=>393,
    178. chr(169)=>834,
    179. chr(170)=>402,
    180. chr(171)=>512,
    181. chr(172)=>498,
    182. chr(173)=>306,
    183. chr(174)=>507,
    184. chr(175)=>394,
    185. chr(176)=>339,
    186. chr(177)=>498,
    187. chr(178)=>336,
    188. chr(179)=>334,
    189. chr(180)=>292,
    190. chr(181)=>550,
    191. chr(182)=>586,
    192. chr(183)=>252,
    193. chr(184)=>307,
    194. chr(185)=>246,
    195. chr(186)=>422,
    196. chr(187)=>512,
    197. chr(188)=>636,
    198. chr(189)=>671,
    199. chr(190)=>675,
    200. chr(191)=>463,
    201. chr(192)=>579,
    202. chr(193)=>579,
    203. chr(194)=>579,
    204. chr(195)=>579,
    205. chr(196)=>579,
    206. chr(197)=>579,
    207. chr(198)=>763,
    208. chr(199)=>533,
    209. chr(200)=>488,
    210. chr(201)=>488,
    211. chr(202)=>488,
    212. chr(203)=>488,
    213. chr(204)=>252,
    214. chr(205)=>252,
    215. chr(206)=>252,
    216. chr(207)=>252,
    217. chr(208)=>625,
    218. chr(209)=>646,
    219. chr(210)=>662,
    220. chr(211)=>662,
    221. chr(212)=>662,
    222. chr(213)=>662,
    223. chr(214)=>662,
    224. chr(215)=>498,
    225. chr(216)=>664,
    226. chr(217)=>642,
    227. chr(218)=>642,
    228. chr(219)=>642,
    229. chr(220)=>642,
    230. chr(221)=>487,
    231. chr(222)=>517,
    232. chr(223)=>527,
    233. chr(224)=>479,
    234. chr(225)=>479,
    235. chr(226)=>479,
    236. chr(227)=>479,
    237. chr(228)=>479,
    238. chr(229)=>479,
    239. chr(230)=>773,
    240. chr(231)=>423,
    241. chr(232)=>498,
    242. chr(233)=>498,
    243. chr(234)=>498,
    244. chr(235)=>498,
    245. chr(236)=>229,
    246. chr(237)=>229,
    247. chr(238)=>229,
    248. chr(239)=>229,
    249. chr(240)=>525,
    250. chr(241)=>525,
    251. chr(242)=>527,
    252. chr(243)=>527,
    253. chr(244)=>527,
    254. chr(245)=>527,
    255. chr(246)=>527,
    256. chr(247)=>498,
    257. chr(248)=>529,
    258. chr(249)=>525,
    259. chr(250)=>525,
    260. chr(251)=>525,
    261. chr(252)=>525,
    262. chr(253)=>453,
    263. chr(254)=>525,
    264. chr(255)=>453
    265. ];
    266. }
    267. }



    PS: Die Font -Dateien für FPDF kann man sich selbst mittels der makefont.php erstellen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Fakiz“ ()

    Hallo,
    Microsoft stellt auch Informationen zur Verfügung, wie Excel Spaltenbreiten ermittelt. Vielleicht hilft der Artikel noch bei der Ermittlung der Breite. Ich würde außerdem versuchen, die Funktion imagettfbbox (wenn verwendet) nur einmal mit dem längsten String je Spalte aufzurufen. Mit der Funktion hatte ich beim Test ganz gute Ergebnisse erzielt, habe aber natürlich keine Exceldateien mit mehreren tausend Zeilen generiert.
    @Fakiz
    Das mit Calibri war klar, habe ich ja auch so gemacht, siehe meinen Code-Kommentar weiter oben: MakeFont('C:\\Windows\\Fonts\\calibri.ttf','cp1252');.

    @ISliceUrPanties
    imagettfbbox mit dem längsten String geht nicht, weil der längste String nicht der längste String ist. ;) "iiiiiiiiii" (10 Zeichen) ist kürzer als "OOOOOO" (6 Zeichen).
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Uha, das Snippet hab ich mir gestern nicht angesehen, dafür jetzt dabei ist mir aufgefallen $fontSize pt $fontSize ist aber vom Typ Integer. Wenn ich jetzt die Excel Schrifgröße 11pt in px umrechene $fontSize = (96/72)*11; und das Ergebniss (14.666666666667) in einem Integer packe lässt sich das von dir beschriebene verhalten reproduzieren.

    Marcus Gräfe schrieb:



    imagettfbbox mit dem längsten String geht nicht, weil der längste String nicht der längste String ist. ;) "iiiiiiiiii" (10 Zeichen) ist kürzer als "OOOOOO" (6 Zeichen).


    Vielleicht liege ich ja falsch, aber meiner Meinung nach geht das doch. Zumindest, wenn du den String in eine Schriftart umwandelst, die monospaced ist. Dann müsste iiiiiiiiii länger sein als OOOOOO
    @Fakiz
    Ich kann deinen Post leider nicht so ganz deuten. Klar ist $fontsize ein Integer. Und die Größe des Fonts ist in "pt" (also Points). Die Rechnung $w * $fontSize / 1000 stammt 1:1 von FPDF. Meiner Meinung nach ist das die Breite des Strings in Pixeln. Und den muss ich natürlich in die Excel-Breite umrechnen, was ich derzeit durch das / 4.5 mache.

    @PadreSperanza
    Das bringt mir ja nichts, denn ich brauche doch die Breite bei der gewählten Schriftart. Ich muss allerdings für jeden String die Breite ermitteln, um den breitesten String zu haben. Würde ich das immer mit imagettfbbox machen, so wäre das zu langsam. Daher die Idee mit der Routine aus der FPDF-Library. Im Moment ist es aber noch so (das muss ich umstellen), dass erst der längste String ermittelt wird und erst danach die Pixelbreite dieses Strings. Nur ist das eben falsch, weil die Anzahl Zeichen nichts mit der Breite zu tun hat.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Ich glaube zum Faktor Text kommen noch weitere Indikatoren hinzu, die sich auf die "optimale" Spaltenbreite auswirken.
    Die Länge eines Textes herzunehmen, ist nur bei monospace-Schriftarten sinnvoll. Hinzu kommen Schriftgröße und Schriftart, die sich wiederum durch letter-spacing auf deine optische Spaltenbreite auswirken.

    Ich würde es, wenn es die Lib nicht möglich macht, auch in zwei Steps gliedern:

    1. EXCEL-Datei erstellen mit der PHP_XLSXWriter-Library um die Performance aufrecht zu erhalten.
    2. Diese erstelle Excel-Datei dann mithilfe von bspw. PhpSpreadsheet autosizen.

    VG,
    Acr0most
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup: