to-spreadsheet 1.1.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,11 +3,12 @@ npm package to create spreadsheet in node environment and in browser
3
3
 
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/to-spreadsheet.svg)](https://www.npmjs.com/package/to-spreadsheet)
6
- [![minified](https://badgen.net/bundlephobia/min/to-spreadsheet)](https://bundlephobia.com/result?p=to-spreadsheet)
7
- [![minified + gzipped](https://badgen.net/bundlephobia/minzip/to-spreadsheet)](https://bundlephobia.com/result?p=to-spreadsheet)
6
+ [![minified](https://badgen.net/bundlephobia/min/to-spreadsheet)](https://badgen.net/bundlephobia/min/to-spreadsheet)
7
+ [![minified + gzipped](https://badgen.net/bundlephobia/minzip/to-spreadsheet)](https://badgen.net/bundlephobia/minzip/to-spreadsheet)
8
8
 
9
9
  [![GitHub stars](https://img.shields.io/github/stars/maifeeulasad/to-spreadsheet)](https://github.com/maifeeulasad/to-spreadsheet/stargazers)
10
10
  [![GitHub watchers](https://img.shields.io/github/watchers/maifeeulasad/to-spreadsheet)](https://github.com/maifeeulasad/to-spreadsheet/watchers)
11
+ [![Commits after release](https://img.shields.io/github/commits-since/maifeeulasad/to-spreadsheet/latest/main?include_prereleases)](https://img.shields.io/github/commits-since/maifeeulasad/to-spreadsheet/latest/main?include_prereleases)
11
12
 
12
13
  # NPM
13
14
  ```
@@ -39,8 +40,371 @@ generateExcel(sampleData); // <-- by default generate XLSX for node
39
40
  generateExcel(sampleData, EnvironmentType.BROWSER); // <-- for browser
40
41
  ```
41
42
 
43
+ # Cell Features
44
+
45
+ ## Dates
46
+
47
+ You can create date cells that are properly formatted in Excel:
48
+
49
+ ### Basic Date Usage
50
+
51
+ ```ts
52
+ import {
53
+ generateExcel,
54
+ createDateCell,
55
+ createBorderedDateCell,
56
+ createBackgroundDateCell
57
+ } from 'to-spreadsheet/lib/index';
58
+
59
+ const data = [
60
+ {
61
+ title: 'DateDemo',
62
+ content: [
63
+ [
64
+ 'Event',
65
+ 'Date',
66
+ 'Styled Date'
67
+ ],
68
+ [
69
+ 'Project Start',
70
+ createDateCell(new Date('2024-01-01')),
71
+ createBorderedDateCell(new Date('2024-01-15'), createAllBorders())
72
+ ],
73
+ [
74
+ 'Milestone',
75
+ createDateCell(new Date()),
76
+ createBackgroundDateCell(new Date('2024-12-25'), '#FFCCCC')
77
+ ]
78
+ ]
79
+ }
80
+ ];
81
+ ```
82
+
83
+ ### Date Helper Functions
84
+
85
+ - `createDateCell(date, style?)` - Creates a date cell with optional styling
86
+ - `createBorderedDateCell(date, border)` - Creates a date cell with borders
87
+ - `createBackgroundDateCell(date, backgroundColor)` - Creates a date cell with background color
88
+
89
+ ## Colors
90
+
91
+ You can add background and foreground colors to cells:
92
+
93
+ ### Basic Color Usage
94
+
95
+ ```ts
96
+ import {
97
+ generateExcel,
98
+ createBackgroundCell,
99
+ createForegroundCell,
100
+ createColoredCell,
101
+ createStyledCell
102
+ } from 'to-spreadsheet/lib/index';
103
+
104
+ const data = [
105
+ {
106
+ title: 'ColorDemo',
107
+ content: [
108
+ [
109
+ 'Feature',
110
+ 'Background Color',
111
+ 'Foreground Color',
112
+ 'Both Colors'
113
+ ],
114
+ [
115
+ 'Yellow Background',
116
+ createBackgroundCell('Highlighted', '#FFFF00'),
117
+ createForegroundCell('Red Text', '#FF0000'),
118
+ createColoredCell('Green BG, Red Text', '#00FF00', '#FF0000')
119
+ ],
120
+ [
121
+ 'Complex Styling',
122
+ createStyledCell('Full Style', {
123
+ backgroundColor: '#FFFFCC',
124
+ foregroundColor: '#0000FF',
125
+ border: createAllBorders(BorderStyle.thick, '#000000')
126
+ }),
127
+ 'Regular cell',
128
+ 42
129
+ ]
130
+ ]
131
+ }
132
+ ];
133
+ ```
134
+
135
+ ### Color Helper Functions
136
+
137
+ - `createBackgroundCell(value, backgroundColor)` - Creates cell with background color
138
+ - `createForegroundCell(value, foregroundColor)` - Creates cell with text color
139
+ - `createColoredCell(value, backgroundColor, foregroundColor)` - Creates cell with both colors
140
+ - `createStyledCell(value, style)` - Creates cell with full styling options
141
+
42
142
  # Features
43
143
  - [x] Multiple sheet support
44
144
  - [x] Equations
45
- - [ ] Cell styling
46
- - [ ] Sheet styling
145
+ - [x] Cell borders
146
+ - [x] Cell styling (background colors, foreground colors, dates)
147
+ - [x] Date cells with proper Excel formatting
148
+ - [x] Cell alignment (horizontal and vertical)
149
+ - [ ] Sheet styling
150
+
151
+ ## Cell Borders
152
+
153
+ You can add borders to cells using the border functionality:
154
+
155
+ ### Basic Border Usage
156
+
157
+ ```ts
158
+ import {
159
+ generateExcel,
160
+ createBorderedCell,
161
+ createAllBorders,
162
+ createTopBorder,
163
+ createBottomBorder,
164
+ createLeftBorder,
165
+ createRightBorder,
166
+ BorderStyle
167
+ } from 'to-spreadsheet/lib/index';
168
+
169
+ const data = [
170
+ {
171
+ title: 'BorderDemo',
172
+ content: [
173
+ [
174
+ // Create cells with all borders
175
+ createBorderedCell('Header 1', createAllBorders(BorderStyle.thick, '#000000')),
176
+ createBorderedCell('Header 2', createAllBorders(BorderStyle.thick, '#000000'))
177
+ ],
178
+ [
179
+ // Create cells with specific borders
180
+ createBorderedCell('Data 1', createTopBorder()),
181
+ createBorderedCell(100, createRightBorder()),
182
+ createBorderedCell('Final', createBottomBorder())
183
+ ]
184
+ ]
185
+ }
186
+ ];
187
+
188
+ generateExcel(data);
189
+ ```
190
+
191
+ ### Border Styles
192
+
193
+ Available border styles:
194
+ - `BorderStyle.none` - No border
195
+ - `BorderStyle.thin` - Thin border (default)
196
+ - `BorderStyle.medium` - Medium border
197
+ - `BorderStyle.thick` - Thick border
198
+ - `BorderStyle.double` - Double border
199
+ - `BorderStyle.dotted` - Dotted border
200
+ - `BorderStyle.dashed` - Dashed border
201
+
202
+ ### Border Helper Functions
203
+
204
+ **Border Creation:**
205
+ - `createAllBorders(style?, color?)` - Creates borders on all sides
206
+ - `createTopBorder(style?, color?)` - Creates only top border
207
+ - `createBottomBorder(style?, color?)` - Creates only bottom border
208
+ - `createLeftBorder(style?, color?)` - Creates only left border
209
+ - `createRightBorder(style?, color?)` - Creates only right border
210
+ - `createBorder(borderConfig)` - Creates custom border configuration
211
+
212
+ **Cell Creation:**
213
+ - `createBorderedCell(value, border)` - Creates a cell with border
214
+ - `createStyledCell(value, style)` - Creates a cell with custom styling
215
+
216
+ ### Advanced Border Usage
217
+
218
+ ```ts
219
+ import { createStyledCell, BorderStyle } from 'to-spreadsheet/lib/index';
220
+
221
+ // Custom border configuration
222
+ const customCell = createStyledCell('Custom', {
223
+ border: {
224
+ left: BorderStyle.double,
225
+ top: BorderStyle.thin,
226
+ right: BorderStyle.dashed,
227
+ bottom: BorderStyle.thick,
228
+ color: '#FF0000' // Red borders
229
+ }
230
+ });
231
+
232
+ // Mix styled and regular cells
233
+ const data = [
234
+ {
235
+ title: 'Mixed',
236
+ content: [
237
+ [customCell, 'Regular Cell', 42]
238
+ ]
239
+ }
240
+ ];
241
+ ```
242
+
243
+ ## Combined Styling
244
+
245
+ All styling features can be combined together:
246
+
247
+ ```ts
248
+ import {
249
+ createStyledCell,
250
+ createAllBorders,
251
+ BorderStyle
252
+ } from 'to-spreadsheet/lib/index';
253
+
254
+ const data = [
255
+ {
256
+ title: 'CombinedDemo',
257
+ content: [
258
+ [
259
+ // Cell with background color, text color, and borders
260
+ createStyledCell('Fully Styled', {
261
+ backgroundColor: '#FFFFCC', // Light yellow background
262
+ foregroundColor: '#0000FF', // Blue text
263
+ border: createAllBorders(BorderStyle.thick, '#FF0000') // Red thick border
264
+ }),
265
+
266
+ // Date with background and border
267
+ createDateCell(new Date(), {
268
+ backgroundColor: '#CCFFCC', // Light green background
269
+ border: createAllBorders(BorderStyle.double, '#008000') // Green double border
270
+ }),
271
+
272
+ // Regular cells for comparison
273
+ 'Plain text',
274
+ 42
275
+ ]
276
+ ]
277
+ }
278
+ ];
279
+ ```
280
+
281
+ ### Color Format
282
+
283
+ Colors should be specified in hex format:
284
+ - `#FF0000` - Red
285
+ - `#00FF00` - Green
286
+ - `#0000FF` - Blue
287
+ - `#FFFF00` - Yellow
288
+ - `#FF00FF` - Magenta
289
+ - `#00FFFF` - Cyan
290
+ - `#000000` - Black
291
+ - `#FFFFFF` - White
292
+ - `#CCCCCC` - Light gray
293
+
294
+ ## Cell Alignment
295
+
296
+ You can align cell content both horizontally and vertically:
297
+
298
+ ### Basic Alignment Usage
299
+
300
+ ```ts
301
+ import {
302
+ generateExcel,
303
+ createHorizontallyAlignedCell,
304
+ createVerticallyAlignedCell,
305
+ createAlignedCell,
306
+ createCenteredCell,
307
+ HorizontalAlignment,
308
+ VerticalAlignment
309
+ } from 'to-spreadsheet/lib/index';
310
+
311
+ const data = [
312
+ {
313
+ title: 'AlignmentDemo',
314
+ content: [
315
+ [
316
+ 'Feature',
317
+ 'Horizontal',
318
+ 'Vertical',
319
+ 'Both'
320
+ ],
321
+ [
322
+ 'Left Align',
323
+ createHorizontallyAlignedCell('Left Text', HorizontalAlignment.left),
324
+ createVerticallyAlignedCell('Top Text', VerticalAlignment.top),
325
+ createAlignedCell('Top-Left', HorizontalAlignment.left, VerticalAlignment.top)
326
+ ],
327
+ [
328
+ 'Center Align',
329
+ createHorizontallyAlignedCell('Center Text', HorizontalAlignment.center),
330
+ createVerticallyAlignedCell('Center Text', VerticalAlignment.center),
331
+ createCenteredCell('Full Center')
332
+ ],
333
+ [
334
+ 'Right Align',
335
+ createHorizontallyAlignedCell('Right Text', HorizontalAlignment.right),
336
+ createVerticallyAlignedCell('Bottom Text', VerticalAlignment.bottom),
337
+ createAlignedCell('Bottom-Right', HorizontalAlignment.right, VerticalAlignment.bottom)
338
+ ]
339
+ ]
340
+ }
341
+ ];
342
+ ```
343
+
344
+ ### Horizontal Alignment Options
345
+
346
+ - `HorizontalAlignment.general` - General alignment (Excel default)
347
+ - `HorizontalAlignment.left` - Left alignment
348
+ - `HorizontalAlignment.center` - Center alignment
349
+ - `HorizontalAlignment.right` - Right alignment
350
+ - `HorizontalAlignment.fill` - Fill alignment
351
+ - `HorizontalAlignment.justify` - Justify alignment
352
+ - `HorizontalAlignment.centerContinuous` - Center across selection
353
+ - `HorizontalAlignment.distributed` - Distributed alignment
354
+
355
+ ### Vertical Alignment Options
356
+
357
+ - `VerticalAlignment.top` - Top alignment
358
+ - `VerticalAlignment.center` - Center alignment
359
+ - `VerticalAlignment.bottom` - Bottom alignment
360
+ - `VerticalAlignment.justify` - Justify alignment
361
+ - `VerticalAlignment.distributed` - Distributed alignment
362
+
363
+ ### Alignment Helper Functions
364
+
365
+ - `createHorizontallyAlignedCell(value, alignment)` - Creates cell with horizontal alignment
366
+ - `createVerticallyAlignedCell(value, alignment)` - Creates cell with vertical alignment
367
+ - `createAlignedCell(value, horizontal, vertical)` - Creates cell with both alignments
368
+ - `createCenteredCell(value)` - Creates center-aligned cell (convenience function)
369
+
370
+ ### Combined with Other Features
371
+
372
+ Alignment works seamlessly with all other styling features:
373
+
374
+ ```ts
375
+ import {
376
+ createStyledCell,
377
+ HorizontalAlignment,
378
+ VerticalAlignment,
379
+ createAllBorders,
380
+ BorderStyle
381
+ } from 'to-spreadsheet/lib/index';
382
+
383
+ const data = [
384
+ {
385
+ title: 'ComplexStyling',
386
+ content: [
387
+ [
388
+ // Full styling with alignment, colors, and borders
389
+ createStyledCell('Complete Style', {
390
+ horizontalAlignment: HorizontalAlignment.center,
391
+ verticalAlignment: VerticalAlignment.center,
392
+ backgroundColor: '#CCFFCC',
393
+ foregroundColor: '#FF0000',
394
+ border: createAllBorders(BorderStyle.thick, '#000000')
395
+ }),
396
+
397
+ // Aligned date cell
398
+ createDateCell(new Date(), {
399
+ horizontalAlignment: HorizontalAlignment.right,
400
+ verticalAlignment: VerticalAlignment.center,
401
+ backgroundColor: '#FFFFCC'
402
+ }),
403
+
404
+ // Simple centered text
405
+ createCenteredCell('Centered')
406
+ ]
407
+ ]
408
+ }
409
+ ];
410
+ ```
@@ -14,7 +14,23 @@ const sheet_xml_1 = require("./xl/worksheets/sheet.xml");
14
14
  const index_1 = require("./index");
15
15
  const util_1 = require("./util");
16
16
  const generateTree = (workbook) => {
17
- return Object.assign({ "[Content_Types].xml": (0, content_types_xml_1.generateContentTypesXml)(workbook), "_rels/.rels": (0, _rels_1.generateRels)(), "docProps/app.xml": (0, app_xml_1.generateAppXml)(workbook), "docProps/core.xml": (0, core_xml_1.generateCoreXml)({}), "xl/_rels/workbook.xml.rels": (0, workbook_xml_rels_1.generateWorkBookXmlRels)(workbook), "xl/sharedStrings.xml": (0, sharedStrings_xml_1.generateSharedStrings)(workbook), "xl/styles.xml": (0, styles_xml_1.generateStyleXml)(), "xl/theme/theme1.xml": (0, theme1_xml_1.generateTheme1)(), "xl/workbook.xml": (0, workbook_xml_1.generateWorkBookXml)(workbook) }, workbook.sheets.reduce((acc, sheet, idx) => (Object.assign(Object.assign({}, acc), { [`xl/worksheets/sheet${idx + 1}.xml`]: (0, sheet_xml_1.generateSheetXml)(sheet) })), {}));
17
+ const styleMap = new Map();
18
+ styleMap.set("default", {});
19
+ let hasDateCells = false;
20
+ workbook.sheets.forEach(sheet => {
21
+ sheet.rows.forEach(row => {
22
+ row.cells.forEach(cell => {
23
+ if (cell.type === index_1.ICellType.date) {
24
+ hasDateCells = true;
25
+ }
26
+ if ('style' in cell && cell.style) {
27
+ const styleKey = (0, util_1.getStyleKey)(cell.style);
28
+ styleMap.set(styleKey, cell.style);
29
+ }
30
+ });
31
+ });
32
+ });
33
+ return Object.assign({ "[Content_Types].xml": (0, content_types_xml_1.generateContentTypesXml)(workbook), "_rels/.rels": (0, _rels_1.generateRels)(), "docProps/app.xml": (0, app_xml_1.generateAppXml)(workbook), "docProps/core.xml": (0, core_xml_1.generateCoreXml)({}), "xl/_rels/workbook.xml.rels": (0, workbook_xml_rels_1.generateWorkBookXmlRels)(workbook), "xl/sharedStrings.xml": (0, sharedStrings_xml_1.generateSharedStrings)(workbook), "xl/styles.xml": (0, styles_xml_1.generateStyleXml)(styleMap, hasDateCells), "xl/theme/theme1.xml": (0, theme1_xml_1.generateTheme1)(), "xl/workbook.xml": (0, workbook_xml_1.generateWorkBookXml)(workbook) }, workbook.sheets.reduce((acc, sheet, idx) => (Object.assign(Object.assign({}, acc), { [`xl/worksheets/sheet${idx + 1}.xml`]: (0, sheet_xml_1.generateSheetXml)(sheet, styleMap, hasDateCells) })), {}));
18
34
  };
19
35
  var EnvironmentType;
20
36
  (function (EnvironmentType) {
@@ -26,9 +42,10 @@ const generateExcel = (dump, environmentType = EnvironmentType.NODE) => {
26
42
  const strings = [];
27
43
  const sheets = dump.map(({ title, content }) => {
28
44
  const rows = content.map(row => {
29
- const cells = row.flatMap(content => {
45
+ const cells = [];
46
+ row.forEach(content => {
30
47
  if (typeof content === 'number') {
31
- return { type: index_1.ICellType.number, value: content };
48
+ cells.push({ type: index_1.ICellType.number, value: content });
32
49
  }
33
50
  else if (typeof content === 'string') {
34
51
  const type = index_1.ICellType.string;
@@ -37,16 +54,32 @@ const generateExcel = (dump, environmentType = EnvironmentType.NODE) => {
37
54
  strings.push(content);
38
55
  value = strings.length - 1;
39
56
  }
40
- return { type: index_1.ICellType.string, value };
57
+ cells.push({ type: index_1.ICellType.string, value });
41
58
  }
42
59
  else if (content instanceof util_1.SkipCell) {
43
- return new Array(content.getSkipCell()).fill({ type: index_1.ICellType.skip, value: undefined });
60
+ for (let i = 0; i < content.getSkipCell(); i++) {
61
+ cells.push({ type: index_1.ICellType.skip, value: undefined });
62
+ }
44
63
  }
45
64
  else if (content instanceof util_1.Equation) {
46
- return { type: index_1.ICellType.equation, value: content };
65
+ cells.push({ type: index_1.ICellType.equation, value: content });
66
+ }
67
+ else if (content && typeof content === 'object' && 'type' in content) {
68
+ const cell = content;
69
+ if (cell.type === index_1.ICellType.string && typeof cell.value === 'string') {
70
+ let stringIndex = strings.indexOf(cell.value);
71
+ if (stringIndex === -1) {
72
+ strings.push(cell.value);
73
+ stringIndex = strings.length - 1;
74
+ }
75
+ cells.push(Object.assign(Object.assign({}, cell), { value: stringIndex }));
76
+ }
77
+ else {
78
+ cells.push(cell);
79
+ }
47
80
  }
48
81
  else {
49
- return { type: index_1.ICellType.skip };
82
+ cells.push({ type: index_1.ICellType.skip });
50
83
  }
51
84
  });
52
85
  return { cells };
package/lib/index.d.ts CHANGED
@@ -1,18 +1,61 @@
1
1
  import { generateExcel, EnvironmentType } from "./generate-excel";
2
- import { SkipCell, skipCell, Equation, writeEquation } from "./util";
2
+ import { SkipCell, skipCell, Equation, writeEquation, createBorder, createAllBorders, createTopBorder, createBottomBorder, createLeftBorder, createRightBorder, createStyledCell, createBorderedCell, createDateCell, createBorderedDateCell, createBackgroundCell, createForegroundCell, createColoredCell, createBackgroundDateCell, createHorizontallyAlignedCell, createVerticallyAlignedCell, createAlignedCell, createCenteredCell } from "./util";
3
3
  declare enum ICellType {
4
4
  string = "s",
5
5
  number = "n",
6
+ date = "d",
6
7
  skip = "skip",
7
8
  equation = "equation"
8
9
  }
10
+ declare enum BorderStyle {
11
+ none = "none",
12
+ thin = "thin",
13
+ medium = "medium",
14
+ thick = "thick",
15
+ double = "double",
16
+ dotted = "dotted",
17
+ dashed = "dashed"
18
+ }
19
+ declare enum HorizontalAlignment {
20
+ general = "general",
21
+ left = "left",
22
+ center = "center",
23
+ right = "right",
24
+ fill = "fill",
25
+ justify = "justify",
26
+ centerContinuous = "centerContinuous",
27
+ distributed = "distributed"
28
+ }
29
+ declare enum VerticalAlignment {
30
+ top = "top",
31
+ center = "center",
32
+ bottom = "bottom",
33
+ justify = "justify",
34
+ distributed = "distributed"
35
+ }
36
+ interface IBorder {
37
+ top?: BorderStyle;
38
+ right?: BorderStyle;
39
+ bottom?: BorderStyle;
40
+ left?: BorderStyle;
41
+ color?: string;
42
+ }
43
+ interface ICellStyle {
44
+ border?: IBorder;
45
+ backgroundColor?: string;
46
+ foregroundColor?: string;
47
+ horizontalAlignment?: HorizontalAlignment;
48
+ verticalAlignment?: VerticalAlignment;
49
+ }
9
50
  interface ICellString {
10
51
  type: ICellType.string;
11
52
  value: number;
53
+ style?: ICellStyle;
12
54
  }
13
55
  interface ICellNumber {
14
56
  type: ICellType.number;
15
57
  value: number;
58
+ style?: ICellStyle;
16
59
  }
17
60
  interface ICellSkip {
18
61
  type: ICellType.skip;
@@ -20,8 +63,14 @@ interface ICellSkip {
20
63
  interface ICellEquation {
21
64
  type: ICellType.equation;
22
65
  value: Equation;
66
+ style?: ICellStyle;
67
+ }
68
+ interface ICellDate {
69
+ type: ICellType.date;
70
+ value: Date;
71
+ style?: ICellStyle;
23
72
  }
24
- declare type ICell = ICellString | ICellNumber | ICellSkip | ICellEquation;
73
+ declare type ICell = ICellString | ICellNumber | ICellDate | ICellSkip | ICellEquation;
25
74
  interface IRows {
26
75
  cells: ICell[];
27
76
  }
@@ -36,9 +85,9 @@ interface IWorkbook {
36
85
  }
37
86
  interface IPage {
38
87
  title: string;
39
- content: (string | number | undefined | SkipCell | Equation)[][];
88
+ content: (string | number | undefined | SkipCell | Equation | ICell)[][];
40
89
  }
41
- export { ICell, ISheet, IWorkbook, IRows, ICellType, IPage };
90
+ export { ICell, ISheet, IWorkbook, IRows, ICellType, IPage, BorderStyle, IBorder, ICellStyle, ICellDate, HorizontalAlignment, VerticalAlignment };
42
91
  declare const sampleData: ({
43
92
  title: string;
44
93
  content: (string[] | (number | Equation)[])[];
@@ -48,5 +97,8 @@ declare const sampleData: ({
48
97
  } | {
49
98
  title: string;
50
99
  content: (string | undefined)[][];
100
+ } | {
101
+ title: string;
102
+ content: (string | number | ICell)[][];
51
103
  })[];
52
- export { generateExcel, sampleData, EnvironmentType, skipCell, writeEquation };
104
+ export { generateExcel, sampleData, EnvironmentType, skipCell, writeEquation, createBorder, createAllBorders, createTopBorder, createBottomBorder, createLeftBorder, createRightBorder, createStyledCell, createBorderedCell, createDateCell, createBorderedDateCell, createBackgroundCell, createForegroundCell, createColoredCell, createBackgroundDateCell, createHorizontallyAlignedCell, createVerticallyAlignedCell, createAlignedCell, createCenteredCell };
package/lib/index.js CHANGED
@@ -1,20 +1,71 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.writeEquation = exports.skipCell = exports.EnvironmentType = exports.sampleData = exports.generateExcel = exports.ICellType = void 0;
3
+ exports.createCenteredCell = exports.createAlignedCell = exports.createVerticallyAlignedCell = exports.createHorizontallyAlignedCell = exports.createBackgroundDateCell = exports.createColoredCell = exports.createForegroundCell = exports.createBackgroundCell = exports.createBorderedDateCell = exports.createDateCell = exports.createBorderedCell = exports.createStyledCell = exports.createRightBorder = exports.createLeftBorder = exports.createBottomBorder = exports.createTopBorder = exports.createAllBorders = exports.createBorder = exports.writeEquation = exports.skipCell = exports.EnvironmentType = exports.sampleData = exports.generateExcel = exports.VerticalAlignment = exports.HorizontalAlignment = exports.BorderStyle = exports.ICellType = void 0;
4
4
  const generate_excel_1 = require("./generate-excel");
5
5
  Object.defineProperty(exports, "generateExcel", { enumerable: true, get: function () { return generate_excel_1.generateExcel; } });
6
6
  Object.defineProperty(exports, "EnvironmentType", { enumerable: true, get: function () { return generate_excel_1.EnvironmentType; } });
7
7
  const util_1 = require("./util");
8
8
  Object.defineProperty(exports, "skipCell", { enumerable: true, get: function () { return util_1.skipCell; } });
9
9
  Object.defineProperty(exports, "writeEquation", { enumerable: true, get: function () { return util_1.writeEquation; } });
10
+ Object.defineProperty(exports, "createBorder", { enumerable: true, get: function () { return util_1.createBorder; } });
11
+ Object.defineProperty(exports, "createAllBorders", { enumerable: true, get: function () { return util_1.createAllBorders; } });
12
+ Object.defineProperty(exports, "createTopBorder", { enumerable: true, get: function () { return util_1.createTopBorder; } });
13
+ Object.defineProperty(exports, "createBottomBorder", { enumerable: true, get: function () { return util_1.createBottomBorder; } });
14
+ Object.defineProperty(exports, "createLeftBorder", { enumerable: true, get: function () { return util_1.createLeftBorder; } });
15
+ Object.defineProperty(exports, "createRightBorder", { enumerable: true, get: function () { return util_1.createRightBorder; } });
16
+ Object.defineProperty(exports, "createStyledCell", { enumerable: true, get: function () { return util_1.createStyledCell; } });
17
+ Object.defineProperty(exports, "createBorderedCell", { enumerable: true, get: function () { return util_1.createBorderedCell; } });
18
+ Object.defineProperty(exports, "createDateCell", { enumerable: true, get: function () { return util_1.createDateCell; } });
19
+ Object.defineProperty(exports, "createBorderedDateCell", { enumerable: true, get: function () { return util_1.createBorderedDateCell; } });
20
+ Object.defineProperty(exports, "createBackgroundCell", { enumerable: true, get: function () { return util_1.createBackgroundCell; } });
21
+ Object.defineProperty(exports, "createForegroundCell", { enumerable: true, get: function () { return util_1.createForegroundCell; } });
22
+ Object.defineProperty(exports, "createColoredCell", { enumerable: true, get: function () { return util_1.createColoredCell; } });
23
+ Object.defineProperty(exports, "createBackgroundDateCell", { enumerable: true, get: function () { return util_1.createBackgroundDateCell; } });
24
+ Object.defineProperty(exports, "createHorizontallyAlignedCell", { enumerable: true, get: function () { return util_1.createHorizontallyAlignedCell; } });
25
+ Object.defineProperty(exports, "createVerticallyAlignedCell", { enumerable: true, get: function () { return util_1.createVerticallyAlignedCell; } });
26
+ Object.defineProperty(exports, "createAlignedCell", { enumerable: true, get: function () { return util_1.createAlignedCell; } });
27
+ Object.defineProperty(exports, "createCenteredCell", { enumerable: true, get: function () { return util_1.createCenteredCell; } });
10
28
  var ICellType;
11
29
  (function (ICellType) {
12
30
  ICellType["string"] = "s";
13
31
  ICellType["number"] = "n";
32
+ ICellType["date"] = "d";
14
33
  ICellType["skip"] = "skip";
15
34
  ICellType["equation"] = "equation";
16
35
  })(ICellType || (ICellType = {}));
17
36
  exports.ICellType = ICellType;
37
+ var BorderStyle;
38
+ (function (BorderStyle) {
39
+ BorderStyle["none"] = "none";
40
+ BorderStyle["thin"] = "thin";
41
+ BorderStyle["medium"] = "medium";
42
+ BorderStyle["thick"] = "thick";
43
+ BorderStyle["double"] = "double";
44
+ BorderStyle["dotted"] = "dotted";
45
+ BorderStyle["dashed"] = "dashed";
46
+ })(BorderStyle || (BorderStyle = {}));
47
+ exports.BorderStyle = BorderStyle;
48
+ var HorizontalAlignment;
49
+ (function (HorizontalAlignment) {
50
+ HorizontalAlignment["general"] = "general";
51
+ HorizontalAlignment["left"] = "left";
52
+ HorizontalAlignment["center"] = "center";
53
+ HorizontalAlignment["right"] = "right";
54
+ HorizontalAlignment["fill"] = "fill";
55
+ HorizontalAlignment["justify"] = "justify";
56
+ HorizontalAlignment["centerContinuous"] = "centerContinuous";
57
+ HorizontalAlignment["distributed"] = "distributed";
58
+ })(HorizontalAlignment || (HorizontalAlignment = {}));
59
+ exports.HorizontalAlignment = HorizontalAlignment;
60
+ var VerticalAlignment;
61
+ (function (VerticalAlignment) {
62
+ VerticalAlignment["top"] = "top";
63
+ VerticalAlignment["center"] = "center";
64
+ VerticalAlignment["bottom"] = "bottom";
65
+ VerticalAlignment["justify"] = "justify";
66
+ VerticalAlignment["distributed"] = "distributed";
67
+ })(VerticalAlignment || (VerticalAlignment = {}));
68
+ exports.VerticalAlignment = VerticalAlignment;
18
69
  const sampleData = [
19
70
  {
20
71
  title: 'Maifee1', content: [
@@ -26,6 +77,146 @@ const sampleData = [
26
77
  ]
27
78
  },
28
79
  { title: 'Maifee2', content: [[1], [1, (0, util_1.skipCell)(3), 2]] },
29
- { title: 'Maifee3', content: [['meaw', undefined, "meaw"], ["woof", 'woof']] }
80
+ { title: 'Maifee3', content: [['meaw', undefined, "meaw"], ["woof", 'woof']] },
81
+ {
82
+ title: 'BorderDemo',
83
+ content: [
84
+ [
85
+ (0, util_1.createBorderedCell)('Product', (0, util_1.createAllBorders)(BorderStyle.thick, '#000000')),
86
+ (0, util_1.createBorderedCell)('Price', (0, util_1.createAllBorders)(BorderStyle.thick, '#000000')),
87
+ (0, util_1.createBorderedCell)('Total', (0, util_1.createAllBorders)(BorderStyle.thick, '#000000'))
88
+ ],
89
+ [
90
+ (0, util_1.createBorderedCell)('Apple', (0, util_1.createLeftBorder)()),
91
+ (0, util_1.createBorderedCell)(10, (0, util_1.createTopBorder)()),
92
+ (0, util_1.createBorderedCell)(100, (0, util_1.createRightBorder)())
93
+ ],
94
+ [
95
+ (0, util_1.createStyledCell)('Custom', {
96
+ border: {
97
+ left: BorderStyle.double,
98
+ bottom: BorderStyle.thin,
99
+ color: '#0000FF'
100
+ }
101
+ }),
102
+ 200,
103
+ 'No Border Cell'
104
+ ]
105
+ ]
106
+ },
107
+ {
108
+ title: 'DateDemo',
109
+ content: [
110
+ [
111
+ 'Event',
112
+ 'Date',
113
+ 'Bordered Date'
114
+ ],
115
+ [
116
+ 'Project Start',
117
+ (0, util_1.createDateCell)(new Date('2024-01-01')),
118
+ (0, util_1.createBorderedDateCell)(new Date('2024-01-15'), (0, util_1.createAllBorders)(BorderStyle.thin, '#000000'))
119
+ ],
120
+ [
121
+ 'Milestone 1',
122
+ (0, util_1.createDateCell)(new Date()),
123
+ (0, util_1.createDateCell)(new Date('2024-12-31'))
124
+ ],
125
+ [
126
+ 'Custom Date Style',
127
+ (0, util_1.createDateCell)(new Date('2024-06-15'), {
128
+ border: {
129
+ top: BorderStyle.thick,
130
+ bottom: BorderStyle.double,
131
+ color: '#FF0000'
132
+ }
133
+ }),
134
+ 'Mixed Content'
135
+ ]
136
+ ]
137
+ },
138
+ {
139
+ title: 'ColorDemo',
140
+ content: [
141
+ [
142
+ 'Feature',
143
+ 'Background Color',
144
+ 'Foreground Color',
145
+ 'Both Colors'
146
+ ],
147
+ [
148
+ 'Yellow Background',
149
+ (0, util_1.createBackgroundCell)('Highlighted', '#FFFF00'),
150
+ (0, util_1.createForegroundCell)('Red Text', '#FF0000'),
151
+ (0, util_1.createColoredCell)('Both', '#00FF00', '#FF0000')
152
+ ],
153
+ [
154
+ 'More Colors',
155
+ (0, util_1.createBackgroundCell)('Blue BG', '#0000FF'),
156
+ (0, util_1.createForegroundCell)('Green Text', '#00FF00'),
157
+ (0, util_1.createColoredCell)('Purple/White', '#800080', '#FFFFFF')
158
+ ],
159
+ [
160
+ 'Date Colors',
161
+ (0, util_1.createBackgroundDateCell)(new Date(), '#FFCCCC'),
162
+ (0, util_1.createDateCell)(new Date('2024-12-25'), {
163
+ backgroundColor: '#00FF00',
164
+ foregroundColor: '#FF0000'
165
+ }),
166
+ 'Mixed with dates'
167
+ ],
168
+ [
169
+ 'With Borders',
170
+ (0, util_1.createStyledCell)('Complex', {
171
+ backgroundColor: '#FFFFCC',
172
+ foregroundColor: '#0000FF',
173
+ border: (0, util_1.createAllBorders)(BorderStyle.thick, '#000000')
174
+ }),
175
+ 'Plain text',
176
+ 42
177
+ ]
178
+ ]
179
+ },
180
+ {
181
+ title: 'AlignmentDemo',
182
+ content: [
183
+ [
184
+ 'Feature',
185
+ 'Horizontal Alignment',
186
+ 'Vertical Alignment',
187
+ 'Both Alignments'
188
+ ],
189
+ [
190
+ 'Left Align',
191
+ (0, util_1.createHorizontallyAlignedCell)('Left Text', HorizontalAlignment.left),
192
+ (0, util_1.createVerticallyAlignedCell)('Top Text', VerticalAlignment.top),
193
+ (0, util_1.createAlignedCell)('Top-Left', HorizontalAlignment.left, VerticalAlignment.top)
194
+ ],
195
+ [
196
+ 'Center Align',
197
+ (0, util_1.createHorizontallyAlignedCell)('Center Text', HorizontalAlignment.center),
198
+ (0, util_1.createVerticallyAlignedCell)('Center Text', VerticalAlignment.center),
199
+ (0, util_1.createCenteredCell)('Full Center')
200
+ ],
201
+ [
202
+ 'Right Align',
203
+ (0, util_1.createHorizontallyAlignedCell)('Right Text', HorizontalAlignment.right),
204
+ (0, util_1.createVerticallyAlignedCell)('Bottom Text', VerticalAlignment.bottom),
205
+ (0, util_1.createAlignedCell)('Bottom-Right', HorizontalAlignment.right, VerticalAlignment.bottom)
206
+ ],
207
+ [
208
+ 'Complex Style',
209
+ (0, util_1.createStyledCell)('All Features', {
210
+ horizontalAlignment: HorizontalAlignment.center,
211
+ verticalAlignment: VerticalAlignment.center,
212
+ backgroundColor: '#CCFFCC',
213
+ foregroundColor: '#FF0000',
214
+ border: (0, util_1.createAllBorders)(BorderStyle.thick, '#000000')
215
+ }),
216
+ (0, util_1.createAlignedCell)(new Date(), HorizontalAlignment.right, VerticalAlignment.center),
217
+ (0, util_1.createCenteredCell)(42)
218
+ ]
219
+ ]
220
+ }
30
221
  ];
31
222
  exports.sampleData = sampleData;
package/lib/util.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { IRows } from ".";
1
+ import { IRows, IBorder, BorderStyle, ICellStyle, ICell, HorizontalAlignment, VerticalAlignment } from ".";
2
2
  declare const indexToVbIndex: (index: number) => number;
3
3
  declare const indexToVbRelationIndex: (index: number) => number;
4
4
  declare const indexToRowIndex: (index: number) => string;
@@ -16,4 +16,25 @@ declare class Equation {
16
16
  constructor(equation: string);
17
17
  }
18
18
  declare const writeEquation: (equation: string) => Equation;
19
- export { indexToVbIndex, indexToVbRelationIndex, indexToRowIndex, rowColumnToVbPosition, calculateExtant, SkipCell, skipCell, Equation, writeEquation };
19
+ declare const createBorder: (border: IBorder) => IBorder;
20
+ declare const createAllBorders: (style?: BorderStyle, color?: string) => IBorder;
21
+ declare const createTopBorder: (style?: BorderStyle, color?: string) => IBorder;
22
+ declare const createBottomBorder: (style?: BorderStyle, color?: string) => IBorder;
23
+ declare const createLeftBorder: (style?: BorderStyle, color?: string) => IBorder;
24
+ declare const createRightBorder: (style?: BorderStyle, color?: string) => IBorder;
25
+ declare const getBorderKey: (border?: IBorder) => string;
26
+ declare const getStyleKey: (style?: ICellStyle) => string;
27
+ declare const createStyledCell: (value: string | number, style?: ICellStyle) => ICell;
28
+ declare const createBorderedCell: (value: string | number, border: IBorder) => ICell;
29
+ declare const dateToExcelSerial: (date: Date) => number;
30
+ declare const createDateCell: (date: Date, style?: ICellStyle) => ICell;
31
+ declare const createBorderedDateCell: (date: Date, border: IBorder) => ICell;
32
+ declare const createBackgroundCell: (value: string | number, backgroundColor: string) => ICell;
33
+ declare const createForegroundCell: (value: string | number, foregroundColor: string) => ICell;
34
+ declare const createColoredCell: (value: string | number, backgroundColor: string, foregroundColor: string) => ICell;
35
+ declare const createBackgroundDateCell: (date: Date, backgroundColor: string) => ICell;
36
+ declare const createHorizontallyAlignedCell: (value: string | number | Date, alignment: HorizontalAlignment) => ICell;
37
+ declare const createVerticallyAlignedCell: (value: string | number | Date, alignment: VerticalAlignment) => ICell;
38
+ declare const createAlignedCell: (value: string | number | Date, horizontal: HorizontalAlignment, vertical: VerticalAlignment) => ICell;
39
+ declare const createCenteredCell: (value: string | number | Date) => ICell;
40
+ export { indexToVbIndex, indexToVbRelationIndex, indexToRowIndex, rowColumnToVbPosition, calculateExtant, SkipCell, skipCell, Equation, writeEquation, createBorder, createAllBorders, createTopBorder, createBottomBorder, createLeftBorder, createRightBorder, getBorderKey, getStyleKey, createStyledCell, createBorderedCell, dateToExcelSerial, createDateCell, createBorderedDateCell, createBackgroundCell, createForegroundCell, createColoredCell, createBackgroundDateCell, createHorizontallyAlignedCell, createVerticallyAlignedCell, createAlignedCell, createCenteredCell };
package/lib/util.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.writeEquation = exports.Equation = exports.skipCell = exports.SkipCell = exports.calculateExtant = exports.rowColumnToVbPosition = exports.indexToRowIndex = exports.indexToVbRelationIndex = exports.indexToVbIndex = void 0;
3
+ exports.createCenteredCell = exports.createAlignedCell = exports.createVerticallyAlignedCell = exports.createHorizontallyAlignedCell = exports.createBackgroundDateCell = exports.createColoredCell = exports.createForegroundCell = exports.createBackgroundCell = exports.createBorderedDateCell = exports.createDateCell = exports.dateToExcelSerial = exports.createBorderedCell = exports.createStyledCell = exports.getStyleKey = exports.getBorderKey = exports.createRightBorder = exports.createLeftBorder = exports.createBottomBorder = exports.createTopBorder = exports.createAllBorders = exports.createBorder = exports.writeEquation = exports.Equation = exports.skipCell = exports.SkipCell = exports.calculateExtant = exports.rowColumnToVbPosition = exports.indexToRowIndex = exports.indexToVbRelationIndex = exports.indexToVbIndex = void 0;
4
+ const _1 = require(".");
4
5
  const indexToVbIndex = (index) => index + 1;
5
6
  exports.indexToVbIndex = indexToVbIndex;
6
7
  const indexToVbRelationIndex = (index) => indexToVbIndex(index) + 2;
@@ -38,3 +39,146 @@ class Equation {
38
39
  exports.Equation = Equation;
39
40
  const writeEquation = (equation) => new Equation(equation);
40
41
  exports.writeEquation = writeEquation;
42
+ const createBorder = (border) => border;
43
+ exports.createBorder = createBorder;
44
+ const createAllBorders = (style = _1.BorderStyle.thin, color = "#000000") => ({
45
+ top: style,
46
+ right: style,
47
+ bottom: style,
48
+ left: style,
49
+ color
50
+ });
51
+ exports.createAllBorders = createAllBorders;
52
+ const createTopBorder = (style = _1.BorderStyle.thin, color = "#000000") => ({
53
+ top: style,
54
+ color
55
+ });
56
+ exports.createTopBorder = createTopBorder;
57
+ const createBottomBorder = (style = _1.BorderStyle.thin, color = "#000000") => ({
58
+ bottom: style,
59
+ color
60
+ });
61
+ exports.createBottomBorder = createBottomBorder;
62
+ const createLeftBorder = (style = _1.BorderStyle.thin, color = "#000000") => ({
63
+ left: style,
64
+ color
65
+ });
66
+ exports.createLeftBorder = createLeftBorder;
67
+ const createRightBorder = (style = _1.BorderStyle.thin, color = "#000000") => ({
68
+ right: style,
69
+ color
70
+ });
71
+ exports.createRightBorder = createRightBorder;
72
+ const getBorderKey = (border) => {
73
+ if (!border)
74
+ return "none";
75
+ const parts = [
76
+ border.top || "none",
77
+ border.right || "none",
78
+ border.bottom || "none",
79
+ border.left || "none",
80
+ border.color || "#000000"
81
+ ];
82
+ return parts.join("-");
83
+ };
84
+ exports.getBorderKey = getBorderKey;
85
+ const getStyleKey = (style) => {
86
+ if (!style)
87
+ return "default";
88
+ const parts = [
89
+ getBorderKey(style.border),
90
+ style.backgroundColor || "no-bg",
91
+ style.foregroundColor || "no-fg",
92
+ style.horizontalAlignment || "no-halign",
93
+ style.verticalAlignment || "no-valign"
94
+ ];
95
+ return parts.join("|");
96
+ };
97
+ exports.getStyleKey = getStyleKey;
98
+ const createStyledCell = (value, style) => {
99
+ if (typeof value === 'string') {
100
+ return {
101
+ type: _1.ICellType.string,
102
+ value: value,
103
+ style
104
+ };
105
+ }
106
+ else {
107
+ return {
108
+ type: _1.ICellType.number,
109
+ value,
110
+ style
111
+ };
112
+ }
113
+ };
114
+ exports.createStyledCell = createStyledCell;
115
+ const createBorderedCell = (value, border) => {
116
+ return createStyledCell(value, { border });
117
+ };
118
+ exports.createBorderedCell = createBorderedCell;
119
+ const dateToExcelSerial = (date) => {
120
+ const excelEpoch = new Date(1900, 0, 1);
121
+ const diffTime = date.getTime() - excelEpoch.getTime();
122
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
123
+ return diffDays + (date >= new Date(1900, 1, 29) ? 2 : 1);
124
+ };
125
+ exports.dateToExcelSerial = dateToExcelSerial;
126
+ const createDateCell = (date, style) => {
127
+ return {
128
+ type: _1.ICellType.date,
129
+ value: date,
130
+ style
131
+ };
132
+ };
133
+ exports.createDateCell = createDateCell;
134
+ const createBorderedDateCell = (date, border) => {
135
+ return createDateCell(date, { border });
136
+ };
137
+ exports.createBorderedDateCell = createBorderedDateCell;
138
+ const createBackgroundCell = (value, backgroundColor) => {
139
+ return createStyledCell(value, { backgroundColor });
140
+ };
141
+ exports.createBackgroundCell = createBackgroundCell;
142
+ const createForegroundCell = (value, foregroundColor) => {
143
+ return createStyledCell(value, { foregroundColor });
144
+ };
145
+ exports.createForegroundCell = createForegroundCell;
146
+ const createColoredCell = (value, backgroundColor, foregroundColor) => {
147
+ return createStyledCell(value, { backgroundColor, foregroundColor });
148
+ };
149
+ exports.createColoredCell = createColoredCell;
150
+ const createBackgroundDateCell = (date, backgroundColor) => {
151
+ return createDateCell(date, { backgroundColor });
152
+ };
153
+ exports.createBackgroundDateCell = createBackgroundDateCell;
154
+ const createHorizontallyAlignedCell = (value, alignment) => {
155
+ if (value instanceof Date) {
156
+ return createDateCell(value, { horizontalAlignment: alignment });
157
+ }
158
+ return createStyledCell(value, { horizontalAlignment: alignment });
159
+ };
160
+ exports.createHorizontallyAlignedCell = createHorizontallyAlignedCell;
161
+ const createVerticallyAlignedCell = (value, alignment) => {
162
+ if (value instanceof Date) {
163
+ return createDateCell(value, { verticalAlignment: alignment });
164
+ }
165
+ return createStyledCell(value, { verticalAlignment: alignment });
166
+ };
167
+ exports.createVerticallyAlignedCell = createVerticallyAlignedCell;
168
+ const createAlignedCell = (value, horizontal, vertical) => {
169
+ if (value instanceof Date) {
170
+ return createDateCell(value, {
171
+ horizontalAlignment: horizontal,
172
+ verticalAlignment: vertical
173
+ });
174
+ }
175
+ return createStyledCell(value, {
176
+ horizontalAlignment: horizontal,
177
+ verticalAlignment: vertical
178
+ });
179
+ };
180
+ exports.createAlignedCell = createAlignedCell;
181
+ const createCenteredCell = (value) => {
182
+ return createAlignedCell(value, _1.HorizontalAlignment.center, _1.VerticalAlignment.center);
183
+ };
184
+ exports.createCenteredCell = createCenteredCell;
@@ -1,2 +1,3 @@
1
- declare const generateStyleXml: () => string;
1
+ import { ICellStyle } from "..";
2
+ declare const generateStyleXml: (styleMap: Map<string, ICellStyle>, hasDateCells?: boolean) => string;
2
3
  export { generateStyleXml };
@@ -1,39 +1,159 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateStyleXml = void 0;
4
- const generateStyleXml = () => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
4
+ const __1 = require("..");
5
+ const generateBorderXml = (border) => {
6
+ const getColorXml = (color) => color ? `<color rgb="${color.replace('#', 'FF')}" />` : '';
7
+ const getBorderSideXml = (side, color) => {
8
+ if (!side || side === __1.BorderStyle.none) {
9
+ return '<left />';
10
+ }
11
+ return `<left style="${side}">${getColorXml(color)}</left>`;
12
+ };
13
+ const leftXml = !border.left || border.left === __1.BorderStyle.none
14
+ ? '<left />'
15
+ : `<left style="${border.left}">${getColorXml(border.color)}</left>`;
16
+ const rightXml = !border.right || border.right === __1.BorderStyle.none
17
+ ? '<right />'
18
+ : `<right style="${border.right}">${getColorXml(border.color)}</right>`;
19
+ const topXml = !border.top || border.top === __1.BorderStyle.none
20
+ ? '<top />'
21
+ : `<top style="${border.top}">${getColorXml(border.color)}</top>`;
22
+ const bottomXml = !border.bottom || border.bottom === __1.BorderStyle.none
23
+ ? '<bottom />'
24
+ : `<bottom style="${border.bottom}">${getColorXml(border.color)}</bottom>`;
25
+ return `
26
+ <border>
27
+ ${leftXml}
28
+ ${rightXml}
29
+ ${topXml}
30
+ ${bottomXml}
31
+ <diagonal />
32
+ </border>`;
33
+ };
34
+ const generateFontXml = (color) => {
35
+ const colorXml = color
36
+ ? `<color rgb="${color.replace('#', 'FF')}" />`
37
+ : '<color theme="1" />';
38
+ return `
39
+ <font>
40
+ <sz val="11" />
41
+ ${colorXml}
42
+ <name val="Calibri" />
43
+ <family val="2" />
44
+ <scheme val="minor" />
45
+ </font>`;
46
+ };
47
+ const generateFillXml = (color) => {
48
+ if (!color) {
49
+ return `
50
+ <fill>
51
+ <patternFill patternType="none" />
52
+ </fill>`;
53
+ }
54
+ return `
55
+ <fill>
56
+ <patternFill patternType="solid">
57
+ <fgColor rgb="${color.replace('#', 'FF')}" />
58
+ <bgColor indexed="64" />
59
+ </patternFill>
60
+ </fill>`;
61
+ };
62
+ const generateAlignmentXml = (style) => {
63
+ const hasAlignment = style.horizontalAlignment || style.verticalAlignment;
64
+ if (!hasAlignment) {
65
+ return '';
66
+ }
67
+ let alignmentAttrs = '';
68
+ if (style.horizontalAlignment) {
69
+ alignmentAttrs += ` horizontal="${style.horizontalAlignment}"`;
70
+ }
71
+ if (style.verticalAlignment) {
72
+ alignmentAttrs += ` vertical="${style.verticalAlignment}"`;
73
+ }
74
+ return `<alignment${alignmentAttrs} />`;
75
+ };
76
+ const generateStyleXml = (styleMap, hasDateCells = false) => {
77
+ const styles = Array.from(styleMap.values());
78
+ const styleCount = styles.length;
79
+ const uniqueBorders = new Map();
80
+ const uniqueFonts = new Map();
81
+ const uniqueFills = new Map();
82
+ uniqueBorders.set("none", {});
83
+ uniqueFonts.set("default", "");
84
+ uniqueFills.set("none", "");
85
+ uniqueFills.set("gray125", "");
86
+ styles.forEach(style => {
87
+ if (style.border) {
88
+ uniqueBorders.set(JSON.stringify(style.border), style.border);
89
+ }
90
+ if (style.foregroundColor) {
91
+ uniqueFonts.set(style.foregroundColor, style.foregroundColor);
92
+ }
93
+ if (style.backgroundColor) {
94
+ uniqueFills.set(style.backgroundColor, style.backgroundColor);
95
+ }
96
+ });
97
+ const borderArray = Array.from(uniqueBorders.values());
98
+ const fontArray = Array.from(uniqueFonts.values());
99
+ const fillArray = Array.from(uniqueFills.values());
100
+ const bordersXml = borderArray.map(border => generateBorderXml(border)).join('');
101
+ const fontsXml = fontArray.map(color => generateFontXml(color || undefined)).join('');
102
+ const fillsXml = fillArray.map(color => generateFillXml(color || undefined)).join('');
103
+ const numFmtsXml = hasDateCells
104
+ ? `<numFmts count="1">
105
+ <numFmt numFmtId="164" formatCode="mm/dd/yyyy" />
106
+ </numFmts>`
107
+ : '';
108
+ let cellXfsXml = '';
109
+ let cellXfsCount = styleCount;
110
+ if (hasDateCells) {
111
+ cellXfsXml += styles.map((style, index) => {
112
+ const borderIndex = Array.from(uniqueBorders.keys()).indexOf(JSON.stringify(style.border || {}));
113
+ const fontIndex = Array.from(uniqueFonts.keys()).indexOf(style.foregroundColor || "default");
114
+ const fillIndex = Array.from(uniqueFills.keys()).indexOf(style.backgroundColor || "none");
115
+ const alignmentXml = generateAlignmentXml(style);
116
+ const applyAlignment = style.horizontalAlignment || style.verticalAlignment ? ' applyAlignment="1"' : '';
117
+ return `<xf numFmtId="0" fontId="${fontIndex}" fillId="${fillIndex}" borderId="${borderIndex}" xfId="0"${applyAlignment}>${alignmentXml}</xf>`;
118
+ }).join('\n ');
119
+ cellXfsXml += '\n ';
120
+ cellXfsXml += styles.map((style, index) => {
121
+ const borderIndex = Array.from(uniqueBorders.keys()).indexOf(JSON.stringify(style.border || {}));
122
+ const fontIndex = Array.from(uniqueFonts.keys()).indexOf(style.foregroundColor || "default");
123
+ const fillIndex = Array.from(uniqueFills.keys()).indexOf(style.backgroundColor || "none");
124
+ const alignmentXml = generateAlignmentXml(style);
125
+ const applyAlignment = style.horizontalAlignment || style.verticalAlignment ? ' applyAlignment="1"' : '';
126
+ return `<xf numFmtId="164" fontId="${fontIndex}" fillId="${fillIndex}" borderId="${borderIndex}" xfId="0"${applyAlignment}>${alignmentXml}</xf>`;
127
+ }).join('\n ');
128
+ cellXfsCount = styleCount * 2;
129
+ }
130
+ else {
131
+ cellXfsXml = styles.map((style, index) => {
132
+ const borderIndex = Array.from(uniqueBorders.keys()).indexOf(JSON.stringify(style.border || {}));
133
+ const fontIndex = Array.from(uniqueFonts.keys()).indexOf(style.foregroundColor || "default");
134
+ const fillIndex = Array.from(uniqueFills.keys()).indexOf(style.backgroundColor || "none");
135
+ const alignmentXml = generateAlignmentXml(style);
136
+ const applyAlignment = style.horizontalAlignment || style.verticalAlignment ? ' applyAlignment="1"' : '';
137
+ return `<xf numFmtId="0" fontId="${fontIndex}" fillId="${fillIndex}" borderId="${borderIndex}" xfId="0"${applyAlignment}>${alignmentXml}</xf>`;
138
+ }).join('\n ');
139
+ }
140
+ return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
5
141
  <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2 xr" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision">
6
- <fonts count="1" x14ac:knownFonts="1">
7
- <font>
8
- <sz val="11" />
9
- <color theme="1" />
10
- <name val="Calibri" />
11
- <family val="2" />
12
- <scheme val="minor" />
13
- </font>
142
+ ${numFmtsXml}
143
+ <fonts count="${fontArray.length}" x14ac:knownFonts="1">
144
+ ${fontsXml}
14
145
  </fonts>
15
- <fills count="2">
16
- <fill>
17
- <patternFill patternType="none" />
18
- </fill>
19
- <fill>
20
- <patternFill patternType="gray125" />
21
- </fill>
146
+ <fills count="${fillArray.length}">
147
+ ${fillsXml}
22
148
  </fills>
23
- <borders count="1">
24
- <border>
25
- <left />
26
- <right />
27
- <top />
28
- <bottom />
29
- <diagonal />
30
- </border>
149
+ <borders count="${borderArray.length}">
150
+ ${bordersXml}
31
151
  </borders>
32
152
  <cellStyleXfs count="1">
33
153
  <xf numFmtId="0" fontId="0" fillId="0" borderId="0" />
34
154
  </cellStyleXfs>
35
- <cellXfs count="1">
36
- <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" />
155
+ <cellXfs count="${cellXfsCount}">
156
+ ${cellXfsXml}
37
157
  </cellXfs>
38
158
  <cellStyles count="1">
39
159
  <cellStyle name="Normal" xfId="0" builtinId="0" />
@@ -50,4 +170,5 @@ const generateStyleXml = () => `<?xml version="1.0" encoding="UTF-8" standalone=
50
170
  </extLst>
51
171
  </styleSheet>
52
172
  `;
173
+ };
53
174
  exports.generateStyleXml = generateStyleXml;
@@ -1,3 +1,3 @@
1
- import { ISheet } from "../..";
2
- declare const generateSheetXml: (sheet: ISheet) => string;
1
+ import { ISheet, ICellStyle } from "../..";
2
+ declare const generateSheetXml: (sheet: ISheet, styleMap: Map<string, ICellStyle>, hasDateCells?: boolean) => string;
3
3
  export { generateSheetXml };
@@ -3,7 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateSheetXml = void 0;
4
4
  const __1 = require("../..");
5
5
  const util_1 = require("../../util");
6
- const generateSheetXml = (sheet) => {
6
+ const generateSheetXml = (sheet, styleMap, hasDateCells = false) => {
7
+ const styleToIndex = new Map();
8
+ Array.from(styleMap.keys()).forEach((key, index) => {
9
+ styleToIndex.set(key, index);
10
+ });
7
11
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
8
12
  <worksheet
9
13
  xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
@@ -28,15 +32,37 @@ const generateSheetXml = (sheet) => {
28
32
  if (cellType !== __1.ICellType.skip) {
29
33
  const cellPosition = (0, util_1.rowColumnToVbPosition)(cellIndex, rowIndex);
30
34
  const cellValue = cell.value || '';
35
+ let styleIndex = 0;
36
+ let isDateCell = cell.type === __1.ICellType.date;
37
+ if ('style' in cell && cell.style) {
38
+ const styleKey = (0, util_1.getStyleKey)(cell.style);
39
+ const baseStyleIndex = styleToIndex.get(styleKey) || 0;
40
+ if (isDateCell && hasDateCells) {
41
+ styleIndex = baseStyleIndex + styleMap.size;
42
+ }
43
+ else {
44
+ styleIndex = baseStyleIndex;
45
+ }
46
+ }
47
+ else if (isDateCell && hasDateCells) {
48
+ styleIndex = styleMap.size;
49
+ }
31
50
  if (cell.type === __1.ICellType.equation) {
32
51
  rowContent += `
33
- <c r="${cellPosition}" t="n">
52
+ <c r="${cellPosition}" t="n" s="${styleIndex}">
34
53
  <f aca="false">${cell.value.getEquation()}</f>
54
+ </c>\n`;
55
+ }
56
+ else if (cell.type === __1.ICellType.date) {
57
+ const excelDateValue = (0, util_1.dateToExcelSerial)(cell.value);
58
+ rowContent += `
59
+ <c r="${cellPosition}" t="n" s="${styleIndex}">
60
+ <v>${excelDateValue}</v>
35
61
  </c>\n`;
36
62
  }
37
63
  else {
38
64
  rowContent += `
39
- <c r="${cellPosition}" t="${cellType}">
65
+ <c r="${cellPosition}" t="${cellType}" s="${styleIndex}">
40
66
  <v>${cellValue}</v>
41
67
  </c>\n`;
42
68
  }
package/package.json CHANGED
@@ -1,8 +1,35 @@
1
1
  {
2
2
  "name": "to-spreadsheet",
3
- "version": "1.1.5",
3
+ "version": "1.3.0",
4
4
  "description": "npm package to create spreadsheet in node environment and in browser",
5
+ "keywords": [
6
+ "excel",
7
+ "xlsx",
8
+ "spreadsheet",
9
+ "workbook",
10
+ "worksheet",
11
+ "cell",
12
+ "border",
13
+ "color",
14
+ "date",
15
+ "formula",
16
+ "equation",
17
+ "export",
18
+ "generate",
19
+ "browser",
20
+ "node",
21
+ "typescript",
22
+ "javascript",
23
+ "office",
24
+ "microsoft",
25
+ "csv",
26
+ "data-export",
27
+ "file-generation",
28
+ "styling",
29
+ "formatting"
30
+ ],
5
31
  "main": "lib/index.js",
32
+ "types": "lib/index.d.ts",
6
33
  "scripts": {
7
34
  "prepare": "npm run build",
8
35
  "build": "tsc",
@@ -14,6 +41,9 @@
14
41
  },
15
42
  "author": "Maifee Ul Asad <maifeeulasad@gmail.com>",
16
43
  "license": "MIT",
44
+ "engines": {
45
+ "node": ">=14.0.0"
46
+ },
17
47
  "bugs": {
18
48
  "url": "https://github.com/maifeeulasad/to-spreadsheet/issues"
19
49
  },
@@ -24,7 +54,9 @@
24
54
  "jszip": "^3.10.1"
25
55
  },
26
56
  "files": [
27
- "lib"
57
+ "lib",
58
+ "README.md",
59
+ "LICENSE"
28
60
  ],
29
61
  "devDependencies": {
30
62
  "@types/archiver": "^5.3.3",