to-spreadsheet 1.0.0 → 1.1.1

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
@@ -1,10 +1,40 @@
1
1
  # to-spreadsheet
2
- npm to package to create spreadsheet in node environment
2
+ npm package to create spreadsheet in node environment
3
3
 
4
4
 
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)
8
+
9
+ [![GitHub stars](https://img.shields.io/github/stars/maifeeulasad/to-spreadsheet)](https://github.com/maifeeulasad/to-spreadsheet/stargazers)
10
+ [![GitHub watchers](https://img.shields.io/github/watchers/maifeeulasad/to-spreadsheet)](https://github.com/maifeeulasad/to-spreadsheet/watchers)
11
+
5
12
  # NPM
6
13
  ```
7
14
  npm i to-spreadsheet
8
15
  ```
9
16
 
10
- https://www.npmjs.com/package/to-spreadsheet
17
+
18
+ # Usage
19
+ [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/s/to-spreadsheet-example-hdmrvc?file=/src/App.tsx)
20
+
21
+ ```ts
22
+ import { generateExcel , EnvironmentType, skipCell } from 'to-spreadsheet/lib/index';
23
+
24
+ const sampleData = [
25
+ {
26
+ title: 'Maifee1', content: [
27
+ ['meaw', 'grrr'],
28
+ ['woof', 'smack'],
29
+ [1],
30
+ [1, 2],
31
+ [1, 2, 3],
32
+ ]
33
+ },
34
+ { title: 'Maifee2', content: [[1], [1, skipCell(3), 2]] },
35
+ { title: 'Maifee3', content: [['meaw', undefined, "meaw"], ["woof", 'woof']] }
36
+ ]
37
+
38
+ generateExcel(sampleData); // <-- by default generate XLSX for node
39
+ generateExcel(sampleData, EnvironmentType.BROWSER); // <-- for browser
40
+ ```
@@ -1,4 +1,7 @@
1
- import { IPage, IWorkbook } from "./index";
2
- declare const generateExcel: (dump: IPage[]) => void;
3
- declare const generateExcelWorkbook: (workbook: IWorkbook) => void;
4
- export { generateExcel, generateExcelWorkbook };
1
+ import { IPage } from "./index";
2
+ declare enum EnvironmentType {
3
+ NODE = 0,
4
+ BROWSER = 1
5
+ }
6
+ declare const generateExcel: (dump: IPage[], environmentType?: EnvironmentType) => Promise<void>;
7
+ export { generateExcel, EnvironmentType };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateExcelWorkbook = exports.generateExcel = void 0;
3
+ exports.EnvironmentType = exports.generateExcel = void 0;
4
4
  const content_types_xml_1 = require("./content-types.xml");
5
5
  const _rels_1 = require("./_rels/.rels");
6
6
  const app_xml_1 = require("./docProps/app.xml");
@@ -12,24 +12,39 @@ const theme1_xml_1 = require("./xl/theme/theme1.xml");
12
12
  const workbook_xml_1 = require("./xl/workbook.xml");
13
13
  const sheet_xml_1 = require("./xl/worksheets/sheet.xml");
14
14
  const index_1 = require("./index");
15
- const fs = require("fs");
16
- const archiver = require("archiver");
15
+ const util_1 = require("./util");
17
16
  const generateTree = (workbook) => {
18
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) })), {}));
19
18
  };
20
- const generateExcel = (dump) => {
19
+ var EnvironmentType;
20
+ (function (EnvironmentType) {
21
+ EnvironmentType[EnvironmentType["NODE"] = 0] = "NODE";
22
+ EnvironmentType[EnvironmentType["BROWSER"] = 1] = "BROWSER";
23
+ })(EnvironmentType || (EnvironmentType = {}));
24
+ exports.EnvironmentType = EnvironmentType;
25
+ const generateExcel = (dump, environmentType = EnvironmentType.NODE) => {
21
26
  const strings = [];
22
27
  const sheets = dump.map(({ title, content }) => {
23
28
  const rows = content.map(row => {
24
- const cells = row.map(content => {
25
- const isString = typeof content === 'string';
26
- const type = isString ? index_1.ICellType.string : index_1.ICellType.number;
27
- let value = isString ? strings.indexOf(content) : content;
28
- if (isString && value === -1) {
29
- strings.push(content);
30
- value = strings.length - 1;
29
+ const cells = row.flatMap(content => {
30
+ if (typeof content === 'number') {
31
+ return { type: index_1.ICellType.number, value: content };
32
+ }
33
+ else if (typeof content === 'string') {
34
+ const type = index_1.ICellType.string;
35
+ let value = strings.indexOf(content);
36
+ if (value === -1) {
37
+ strings.push(content);
38
+ value = strings.length - 1;
39
+ }
40
+ return { type: index_1.ICellType.string, value };
41
+ }
42
+ else if (content instanceof util_1.SkipCell) {
43
+ return new Array(content.getSkipCell()).fill({ type: index_1.ICellType.skip, value: undefined });
44
+ }
45
+ else {
46
+ return { type: index_1.ICellType.skip, value: undefined };
31
47
  }
32
- return { type, value };
33
48
  });
34
49
  return { cells };
35
50
  });
@@ -40,35 +55,64 @@ const generateExcel = (dump) => {
40
55
  strings,
41
56
  filename: "tem.xlsx"
42
57
  };
43
- generateExcelWorkbook(workbook);
58
+ if (environmentType === EnvironmentType.BROWSER) {
59
+ return generateExcelWorkbookBrowser(workbook);
60
+ }
61
+ else {
62
+ return generateExcelWorkbookNode(workbook);
63
+ }
44
64
  };
45
65
  exports.generateExcel = generateExcel;
46
- const generateExcelWorkbook = (workbook) => {
47
- const output = fs.createWriteStream(`${__dirname}/${workbook.filename}.xlsx`);
48
- const archive = archiver("zip", {
49
- zlib: { level: 9 },
50
- });
51
- output.on("close", function () {
52
- console.debug(archive.pointer() + " total bytes");
53
- console.debug("archiver has been finalized and the output file descriptor has closed.");
54
- });
55
- output.on("end", function () {
56
- console.debug("Data has been drained");
66
+ const generateExcelWorkbookNode = (workbook) => {
67
+ return new Promise((resolve, reject) => {
68
+ const fs = require('fs');
69
+ const archiver = require('archiver');
70
+ const output = fs.createWriteStream(`${__dirname}/${workbook.filename}.xlsx`);
71
+ const archive = archiver("zip", {
72
+ zlib: { level: 9 },
73
+ });
74
+ output.on("close", () => {
75
+ console.debug(archive.pointer() + " total bytes");
76
+ console.debug("archiver has been finalized and the output file descriptor has closed.");
77
+ resolve();
78
+ });
79
+ output.on("end", () => {
80
+ console.debug("Data has been drained");
81
+ });
82
+ archive.on("warning", (err) => {
83
+ if (err.code === "ENOENT") {
84
+ }
85
+ else {
86
+ reject(err);
87
+ }
88
+ });
89
+ archive.on("error", (err) => {
90
+ reject(err);
91
+ });
92
+ archive.pipe(output);
93
+ Object.entries(generateTree(workbook)).map(([filename, fileContent]) => {
94
+ archive.append(fileContent, { name: filename });
95
+ });
96
+ archive.finalize();
57
97
  });
58
- archive.on("warning", function (err) {
59
- if (err.code === "ENOENT") {
98
+ };
99
+ const generateExcelWorkbookBrowser = (workbook) => {
100
+ return new Promise((resolve, reject) => {
101
+ try {
102
+ const JSZip = require('jszip');
103
+ const { saveAs } = require('file-saver');
104
+ const zip = new JSZip();
105
+ const tree = generateTree(workbook);
106
+ Object.entries(tree).forEach(([filename, fileContent]) => {
107
+ zip.file(filename, fileContent);
108
+ });
109
+ zip.generateAsync({ type: "blob" }).then((blob) => {
110
+ saveAs(blob, `${workbook.filename}.xlsx`);
111
+ resolve();
112
+ });
60
113
  }
61
- else {
62
- throw err;
114
+ catch (error) {
115
+ reject(error);
63
116
  }
64
117
  });
65
- archive.on("error", function (err) {
66
- throw err;
67
- });
68
- archive.pipe(output);
69
- Object.entries(generateTree(workbook)).map(([filename, fileContent]) => {
70
- archive.append(fileContent, { name: filename });
71
- });
72
- archive.finalize();
73
118
  };
74
- exports.generateExcelWorkbook = generateExcelWorkbook;
package/lib/index.d.ts CHANGED
@@ -1,11 +1,13 @@
1
- import { generateExcel, generateExcelWorkbook } from "./generate-excel";
1
+ import { generateExcel, EnvironmentType } from "./generate-excel";
2
+ import { SkipCell, skipCell } from "./util";
2
3
  declare enum ICellType {
3
4
  string = "s",
4
- number = "n"
5
+ number = "n",
6
+ skip = "skip"
5
7
  }
6
8
  interface ICell {
7
9
  type: ICellType;
8
- value: any;
10
+ value: number | undefined;
9
11
  }
10
12
  interface IRows {
11
13
  cells: ICell[];
@@ -21,11 +23,17 @@ interface IWorkbook {
21
23
  }
22
24
  interface IPage {
23
25
  title: string;
24
- content: (string | number)[][];
26
+ content: (string | number | undefined | SkipCell)[][];
25
27
  }
26
28
  export { ICell, ISheet, IWorkbook, IRows, ICellType, IPage };
27
- declare const sampleData: {
29
+ declare const sampleData: ({
28
30
  title: string;
29
31
  content: (string[] | number[])[];
30
- }[];
31
- export { generateExcel, generateExcelWorkbook, sampleData };
32
+ } | {
33
+ title: string;
34
+ content: (number | SkipCell)[][];
35
+ } | {
36
+ title: string;
37
+ content: (string | undefined)[][];
38
+ })[];
39
+ export { generateExcel, sampleData, EnvironmentType, skipCell };
package/lib/index.js CHANGED
@@ -1,13 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sampleData = exports.generateExcelWorkbook = exports.generateExcel = exports.ICellType = void 0;
3
+ exports.skipCell = exports.EnvironmentType = exports.sampleData = exports.generateExcel = 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
- Object.defineProperty(exports, "generateExcelWorkbook", { enumerable: true, get: function () { return generate_excel_1.generateExcelWorkbook; } });
6
+ Object.defineProperty(exports, "EnvironmentType", { enumerable: true, get: function () { return generate_excel_1.EnvironmentType; } });
7
+ const util_1 = require("./util");
8
+ Object.defineProperty(exports, "skipCell", { enumerable: true, get: function () { return util_1.skipCell; } });
7
9
  var ICellType;
8
10
  (function (ICellType) {
9
11
  ICellType["string"] = "s";
10
12
  ICellType["number"] = "n";
13
+ ICellType["skip"] = "skip";
11
14
  })(ICellType || (ICellType = {}));
12
15
  exports.ICellType = ICellType;
13
16
  const sampleData = [
@@ -20,7 +23,7 @@ const sampleData = [
20
23
  [1, 2, 3],
21
24
  ]
22
25
  },
23
- { title: 'Maifee2', content: [[1], [1, 2]] },
24
- { title: 'Maifee3', content: [['meaw', "meaw"], ["woof", 'woof']] }
26
+ { title: 'Maifee2', content: [[1], [1, (0, util_1.skipCell)(3), 2]] },
27
+ { title: 'Maifee3', content: [['meaw', undefined, "meaw"], ["woof", 'woof']] }
25
28
  ];
26
29
  exports.sampleData = sampleData;
package/lib/util.d.ts CHANGED
@@ -4,4 +4,10 @@ declare const indexToVbRelationIndex: (index: number) => number;
4
4
  declare const indexToRowIndex: (index: number) => string;
5
5
  declare const rowColumnToVbPosition: (row: number, col: number) => string;
6
6
  declare const calculateExtant: (rows: IRows[]) => string;
7
- export { indexToVbIndex, indexToVbRelationIndex, indexToRowIndex, rowColumnToVbPosition, calculateExtant };
7
+ declare class SkipCell {
8
+ private skipCell;
9
+ getSkipCell: () => number;
10
+ constructor(skipCell: number);
11
+ }
12
+ declare const skipCell: (skipCell: number) => SkipCell;
13
+ export { indexToVbIndex, indexToVbRelationIndex, indexToRowIndex, rowColumnToVbPosition, calculateExtant, SkipCell, skipCell };
package/lib/util.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateExtant = exports.rowColumnToVbPosition = exports.indexToRowIndex = exports.indexToVbRelationIndex = exports.indexToVbIndex = void 0;
3
+ exports.skipCell = exports.SkipCell = exports.calculateExtant = exports.rowColumnToVbPosition = exports.indexToRowIndex = exports.indexToVbRelationIndex = exports.indexToVbIndex = void 0;
4
4
  const indexToVbIndex = (index) => index + 1;
5
5
  exports.indexToVbIndex = indexToVbIndex;
6
6
  const indexToVbRelationIndex = (index) => indexToVbIndex(index) + 2;
@@ -20,3 +20,12 @@ const rowColumnToVbPosition = (row, col) => indexToRowIndex(indexToVbIndex(row))
20
20
  exports.rowColumnToVbPosition = rowColumnToVbPosition;
21
21
  const calculateExtant = (rows) => rowColumnToVbPosition(Math.max(...rows.map(row => row.cells.length)) - 1, rows.length - 1);
22
22
  exports.calculateExtant = calculateExtant;
23
+ class SkipCell {
24
+ constructor(skipCell) {
25
+ this.getSkipCell = () => this.skipCell;
26
+ this.skipCell = skipCell;
27
+ }
28
+ }
29
+ exports.SkipCell = SkipCell;
30
+ const skipCell = (skipCell) => new SkipCell(skipCell);
31
+ exports.skipCell = skipCell;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateSheetXml = void 0;
4
+ const __1 = require("../..");
4
5
  const util_1 = require("../../util");
5
6
  const generateSheetXml = (sheet) => {
6
7
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@@ -20,12 +21,16 @@ const generateSheetXml = (sheet) => {
20
21
  </cols>
21
22
  <sheetData>
22
23
  ${(sheet.rows).map((row, indexCol) => `
23
- <row r="${(0, util_1.indexToVbIndex)(indexCol)}">
24
- ${(row.cells).map((cell, indexRow) => `
25
- <c r="${(0, util_1.rowColumnToVbPosition)(indexRow, indexCol)}" t="${cell.type}"><v>${cell.value}</v></c>
24
+ <row r="${(0, util_1.indexToVbIndex)(indexCol)}">
25
+ ${(row.cells).map((cell, indexRow) => cell.type === __1.ICellType.skip
26
+ ? ""
27
+ : `
28
+ <c r="${(0, util_1.rowColumnToVbPosition)(indexRow, indexCol)}" t="${cell.type}">
29
+ <v>${cell.value}</v>
30
+ </c>
31
+ `).join('\n')}
32
+ </row>
26
33
  `).join('\n')}
27
- </row>
28
- `).join('\n')}
29
34
  </sheetData>
30
35
  <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
31
36
  </worksheet>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "to-spreadsheet",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "npm package to create spreadsheet in node environment",
5
5
  "main": "src/index.ts",
6
6
  "scripts": {
@@ -19,11 +19,17 @@
19
19
  },
20
20
  "homepage": "https://github.com/maifeeulasad/to-spreadsheet#readme",
21
21
  "dependencies": {
22
- "archiver": "^5.3.1",
23
- "date-fns": "^2.29.3"
22
+ "archiver": "^6.0.1",
23
+ "date-fns": "^2.30.0",
24
+ "file-saver": "^2.0.5",
25
+ "jszip": "^3.10.1"
24
26
  },
25
- "files": ["lib"],
27
+ "files": [
28
+ "lib"
29
+ ],
26
30
  "devDependencies": {
31
+ "@types/archiver": "^5.3.3",
32
+ "@types/file-saver": "^2.0.5",
27
33
  "@types/node": "^17.0.35",
28
34
  "ts-node": "^10.8.0",
29
35
  "typescript": "^4.7.2"
package/src/index.ts CHANGED
@@ -1,13 +1,15 @@
1
- import { generateExcel, generateExcelWorkbook } from "./generate-excel";
1
+ import { generateExcel, EnvironmentType } from "./generate-excel";
2
+ import { SkipCell, skipCell } from "./util";
2
3
 
3
4
  enum ICellType {
4
5
  string = "s",
5
- number = "n"
6
+ number = "n",
7
+ skip = "skip",
6
8
  }
7
9
 
8
10
  interface ICell {
9
11
  type: ICellType;
10
- value: any;
12
+ value: number | undefined;
11
13
  }
12
14
 
13
15
  interface IRows {
@@ -27,7 +29,7 @@ interface IWorkbook {
27
29
 
28
30
  interface IPage {
29
31
  title: string
30
- content: (string | number)[][]
32
+ content: (string | number | undefined | SkipCell)[][]
31
33
  }
32
34
 
33
35
  export { ICell, ISheet, IWorkbook, IRows, ICellType, IPage }
@@ -43,10 +45,10 @@ const sampleData = [
43
45
  [1, 2, 3],
44
46
  ]
45
47
  },
46
- { title: 'Maifee2', content: [[1], [1, 2]] },
47
- { title: 'Maifee3', content: [['meaw', "meaw"], ["woof", 'woof']] }
48
+ { title: 'Maifee2', content: [[1], [1, skipCell(3), 2]] },
49
+ { title: 'Maifee3', content: [['meaw', undefined, "meaw"], ["woof", 'woof']] }
48
50
  ]
49
51
 
50
- // generateExcel(sampleData);
52
+ // generateExcel(sampleData) // <- check before releasing with `yarn test:compile`
51
53
 
52
- export { generateExcel, generateExcelWorkbook, sampleData };
54
+ export { generateExcel, sampleData, EnvironmentType, skipCell };