diff --git a/README.md b/README.md index 8a85c30..d61b6dc 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,10 @@ const fileAsUint8Array = await createXlsx({ }) ``` +Styles accept an `alignment` object, for example +`{ alignment: { vertical: "center", wrapText: true } }`. +Alignment is preserved when a cell also uses a date or datetime format. + ## Contributing Follow [Coding Style Guide](https://github.com/litejs/litejs/wiki/Style-Guide), diff --git a/test/index.js b/test/index.js index 8ab460f..547dd28 100644 --- a/test/index.js +++ b/test/index.js @@ -4,6 +4,26 @@ describe("xlsx", function() { var { createFiles, createXlsx } = require("..") , compressionSuported = typeof CompressionStream !== "undefined" && typeof Response !== "undefined" + test("cell alignment and formatted styles", function(assert) { + var files = createFiles({ + styles: { + Wrapped: { font: { b: true }, alignment: { vertical: 'center', wrapText: true } }, + Unwrapped: { alignment: { horizontal: 'right', wrapText: false } } + }, + sheets: [[[ + { style: 'Wrapped', value: 'line one\nline two' }, + { style: 'Wrapped', format: 'date', value: new Date(1514900750001) }, + { style: 'Unwrapped', value: 10 } + ]]] + }) + , styles = files.find(f => f.name === 'xl/styles.xml').content + assert.equal((styles.match(//g) || []).length, 2, 'alignment survives format merging') + assert.ok(styles.includes('applyAlignment="1"'), 'alignment enabled on cell style') + assert.ok(styles.includes(''), 'false remains explicit') + assert.ok(!styles.includes('alignment="'), 'alignment is a child, never an attribute') + assert.end() + }) + function sheet1(data, sheet) { return createFiles({ sheets: [{ data, ...sheet }] }).find(f => f.name === 'xl/worksheets/sheet1.xml').content } diff --git a/test/types.ts b/test/types.ts index 613a4cf..e8767e4 100644 --- a/test/types.ts +++ b/test/types.ts @@ -2,7 +2,7 @@ import { createFiles, createXlsx, Workbook, XlsxFile } from ".." var workbook: Workbook = { styles: { - bold: { font: { sz: 11, name: "Calibri", b: true } }, + bold: { font: { sz: 11, name: "Calibri", b: true }, alignment: { vertical: "center", wrapText: true } }, border: { border: "thin" }, fill: { fill: "FFFF00" }, }, diff --git a/types/index.d.ts b/types/index.d.ts index 51d7069..614d031 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -36,7 +36,18 @@ export interface FillDef { pattern?: string } +export interface AlignmentDef { + horizontal?: "general" | "left" | "center" | "right" | "fill" | "justify" | "centerContinuous" | "distributed" + vertical?: "top" | "center" | "bottom" | "justify" | "distributed" + wrapText?: boolean + shrinkToFit?: boolean + textRotation?: number + indent?: number + readingOrder?: number +} + export interface StyleDef { + alignment?: AlignmentDef font?: FontDef border?: string | BorderSides fill?: string | FillDef diff --git a/xlsx.js b/xlsx.js index 05ddbe2..46bdef9 100644 --- a/xlsx.js +++ b/xlsx.js @@ -72,6 +72,8 @@ bgColor: normalizeRgb(newFill.bgColor) } a[1] = xf.push({ + alignment: a[1].alignment, + applyAlignment: a[1].alignment ? 1 : UNDEF, fontId: newFont ? font.push(newFont) - 1 : 0, applyFont: newFont ? 1 : UNDEF, borderId: newBorder ? border.push(newBorder) - 1 : UNDEF, @@ -190,7 +192,11 @@ (k, v) => toXml(k, { style: v && v.style || v }, v && v.color ? { color: [toColor(v.color)] } : 0) ) + '' + - toXml('cellXfs', { count: xf.length }, { xf }) + + toXml('cellXfs', { count: xf.length }, xf.map( + f => toXml('xf', assign({}, f, { alignment: UNDEF }), { + alignment: f.alignment ? [f.alignment] : UNDEF + }) + ).join('')) + '' + '' },