/* * This file is part of TREB. * * TREB is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. * * TREB is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with TREB. If not, see . * * Copyright 2022-2026 trebco, llc. * info@treb.app * */ /** * So here is how Excel column widths work: * * Column width, as used in the elements, is * * " * ...measured as the number of characters of the maximum digit width of the * numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. There are * 4 pixels of margin padding (two on each side), plus 1 pixel padding for the * gridlines. * " * * https://c-rex.net/projects/samples/ooxml/e1/Part4/OOXML_P4_DOCX_col_topic_ID0ELFQ4.html * * (good resource, btw) * * * ==== THIS IS COMPLETELY FUCKING INSANE ====================================== * * Using the Calibri font as an example, the maximum digit width of 11 point * font size is 7 pixels (at 96 dpi). In fact, each digit is the same width for * this font. Therefore if the cell width is 8 characters wide, the value of * this attribute shall be Truncate([8*7+5]/7*256)/256 = 8.7109375. * * To translate the value of width in the file into the column width value at * runtime (expressed in terms of pixels), use this calculation: * * =Truncate(((256 * {width} + Truncate(128/{Maximum Digit Width}))/256)*{Maximum Digit Width}) * * Using the same example as above, the calculation would be * Truncate(((256*8.7109375+Truncate(128/7))/256)*7) = 61 pixels * * To translate from pixels to character width, use this calculation: * * =Truncate(({pixels}-5)/{Maximum Digit Width} * 100+0.5)/100 * * Using the example above, the calculation would be * Truncate((61-5)/7*100+0.5)/100 = 8 characters. * * ============================================================================= * * Reading the above, if you want the cell to be *8 characters wide* the value * of the attribute shall be *8.7109375*. * * Step 3: Profit! * */ const MaximumDigitWidth = 7; // @ calibri 11 export const PixelsToColumnWidth = (pixels: number): number => { const characters = Math.floor((pixels - 5) / MaximumDigitWidth * 100 + 0.5) / 100; const column_width = Math.floor((characters * MaximumDigitWidth + 5) / MaximumDigitWidth * 256) / 256; // console.info('pixels', pixels, 'characters', characters, 'width', column_width); return column_width; }; export const ColumnWidthToPixels = (width: number): number => { const pixels = Math.floor(((256 * width + Math.floor(128 / MaximumDigitWidth)) / 256) * MaximumDigitWidth); // console.info('width', width, 'pixels', pixels); return pixels; };