Skip to content

Commit

Permalink
Improve cell autofit calculation
Browse files Browse the repository at this point in the history
papb committed Jul 3, 2020
1 parent 4cb1e52 commit 8973874
Showing 2 changed files with 112 additions and 11 deletions.
11 changes: 9 additions & 2 deletions source/json-to-excel.ts
Original file line number Diff line number Diff line change
@@ -12,6 +12,11 @@ const ALIGNMENT_STYLE: Partial<Excel.Alignment> = {
wrapText: true
};

const FONT_STYLE: Partial<Excel.Font> = {
name: 'Calibri',
size: 11
};

export async function jsonToExcel(jsonSheets: ExpandedJsonSheet[], path: string, options: ExpandedJsonToExcelOptions): Promise<void> {
if (jsonSheets.length === 0) {
throw new TypeError('Expected non-empty list of json sheets, got empty list');
@@ -59,8 +64,10 @@ export async function jsonToExcel(jsonSheets: ExpandedJsonSheet[], path: string,
for (let ri = 0; ri < rowCount; ri++) {
for (let ci = 0; ci < columnCount; ci++) {
assertValidCellContent(data[ri][ci], options.linefeedLimitChecking);
sheet.getCell(ri + 1, ci + 1).value = data[ri][ci];
sheet.getCell(ri + 1, ci + 1).alignment = ALIGNMENT_STYLE;
const cell = sheet.getCell(ri + 1, ci + 1);
cell.value = data[ri][ci];
cell.alignment = ALIGNMENT_STYLE;
cell.font = FONT_STYLE;
}
}

112 changes: 103 additions & 9 deletions source/visual-string-width.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,110 @@
import { getMax } from './numeric-helpers';
import assert = require('assert');

const MAX_CHAR_VISUAL_WIDTH = 1.75;
// Calculations in this file assume 'Calibri 11'

/* eslint-disable quote-props */
const CHAR_WIDTHS_IN_PX: { [key: string]: number } = {
// 'a': 1, // 1 is the default and can be omitted
'b': 8 / 7,
'c': 6 / 7,
'd': 8 / 7,
'e': 8 / 7,
'f': 5 / 7,
// 'g': 1, // 1 is the default and can be omitted
'h': 8 / 7,
'i': 4 / 7,
'j': 4 / 7,
// 'k': 1, // 1 is the default and can be omitted
'l': 4 / 7,
'm': 12 / 7,
'n': 8 / 7,
'o': 8 / 7,
'p': 8 / 7,
'q': 8 / 7,
'r': 5 / 7,
's': 6 / 7,
't': 5 / 7,
'u': 8 / 7,
// 'v': 1, // 1 is the default and can be omitted
'w': 11 / 7,
// 'x': 1, // 1 is the default and can be omitted
// 'y': 1, // 1 is the default and can be omitted
'z': 6 / 7,
'A': 9 / 7,
'B': 8 / 7,
'C': 8 / 7,
'D': 9 / 7,
// 'E': 1, // 1 is the default and can be omitted
// 'F': 1, // 1 is the default and can be omitted
'G': 9 / 7,
'H': 9 / 7,
'I': 4 / 7,
'J': 5 / 7,
'K': 8 / 7,
'L': 6 / 7,
'M': 12 / 7,
'N': 10 / 7,
'O': 10 / 7,
'P': 8 / 7,
'Q': 10 / 7,
'R': 8 / 7,
// 'S': 1, // 1 is the default and can be omitted
// 'T': 1, // 1 is the default and can be omitted
'U': 9 / 7,
'V': 9 / 7,
'W': 13 / 7,
'X': 8 / 7,
// 'Y': 1, // 1 is the default and can be omitted
// 'Z': 1, // 1 is the default and can be omitted
// '0': 1, // 1 is the default and can be omitted
// '1': 1, // 1 is the default and can be omitted
// '2': 1, // 1 is the default and can be omitted
// '3': 1, // 1 is the default and can be omitted
// '4': 1, // 1 is the default and can be omitted
// '5': 1, // 1 is the default and can be omitted
// '6': 1, // 1 is the default and can be omitted
// '7': 1, // 1 is the default and can be omitted
// '8': 1, // 1 is the default and can be omitted
// '9': 1, // 1 is the default and can be omitted
// '_': 1, // 1 is the default and can be omitted
'-': 5 / 7,
' ': 3 / 7,
'\'': 3 / 7,
'"': 6 / 7,
'!': 5 / 7,
'@': 13 / 7,
// '#': 1, // 1 is the default and can be omitted
// '$': 1, // 1 is the default and can be omitted
'%': 11 / 7,
'&': 10 / 7,
// '*': 1, // 1 is the default and can be omitted
'(': 5 / 7,
')': 5 / 7,
// '+': 1, // 1 is the default and can be omitted
// '=': 1, // 1 is the default and can be omitted
'{': 5 / 7,
'}': 5 / 7,
'[': 5 / 7,
']': 5 / 7,
// '|': 1, // 1 is the default and can be omitted
'/': 6 / 7,
'\\': 6 / 7,
'.': 4 / 7,
',': 4 / 7,
';': 4 / 7,
':': 4 / 7
};
/* eslint-enable quote-props */

const MAX_CHAR_VISUAL_WIDTH = Math.max(...Object.values(CHAR_WIDTHS_IN_PX));

function getCharVisualWidth(char: string): number {
const specials: { [key: string]: number } = {
' ': 0.4,
f: 0.7,
m: 1.75
};
const half = ['i', 'j', 'l', '\'', '!'];
return specials[char] ?? (half.includes(char) ? 0.5 : 1);
return CHAR_WIDTHS_IN_PX[char] ?? 1;
}

function roundCents(number: number): number {
return Number.parseFloat(number.toFixed(2));
}

export function getLineVisualWidth(line: string): number {
@@ -22,7 +116,7 @@ export function getLineVisualWidth(line: string): number {
width += getCharVisualWidth(char);
}

return width;
return roundCents(width);
}

export function getStringVisualWidth(string: string): number {

0 comments on commit 8973874

Please sign in to comment.