json-as-xlsx 2.3.9 → 2.4.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2019 - present, LuisEnMarroquin <luis@marroquin.dev>
3
+ Copyright (c) 2022, LuisEnMarroquin <xlsx@marroquin.dev>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -4,53 +4,98 @@ This is a tool that helps to build an excel from a json and it depends only on `
4
4
 
5
5
  You can see a live example of it working on any of this sites (there are many just in case):
6
6
 
7
- * [xlsx.pages.dev](https://xlsx.pages.dev)
8
- * [xlsx.marroquin.dev](https://xlsx.marroquin.dev)
9
- * [xlsx.luismarroquin.com](https://xlsx.luismarroquin.com)
7
+ - [xlsx.pages.dev](https://xlsx.pages.dev)
8
+ - [xlsx.marroquin.dev](https://xlsx.marroquin.dev)
9
+ - [xlsx.luismarroquin.com](https://xlsx.luismarroquin.com)
10
10
 
11
11
  ## Usage
12
12
 
13
13
  ```js
14
- let xlsx = require('json-as-xlsx')
14
+ let xlsx = require("json-as-xlsx")
15
15
 
16
16
  let data = [
17
17
  {
18
- sheet: 'Adults',
18
+ sheet: "Adults",
19
19
  columns: [
20
- { label: 'User', value: 'user' }, // Top level data
21
- { label: 'Age', value: row => (row.age + ' years') }, // Run functions
22
- { label: 'Phone', value: row => (row.more ? row.more.phone || '' : '') }, // Deep props
20
+ { label: "User", value: "user" }, // Top level data
21
+ { label: "Age", value: (row) => row.age + " years" }, // Custom format
22
+ { label: "Phone", value: (row) => (row.more ? row.more.phone || "" : "") }, // Run functions
23
23
  ],
24
24
  content: [
25
- { user: 'Andrea', age: 20, more: { phone: '11111111' } },
26
- { user: 'Luis', age: 21, more: { phone: '12345678' } }
27
- ]
28
- }, {
29
- sheet: 'Children',
25
+ { user: "Andrea", age: 20, more: { phone: "11111111" } },
26
+ { user: "Luis", age: 21, more: { phone: "12345678" } },
27
+ ],
28
+ },
29
+ {
30
+ sheet: "Children",
30
31
  columns: [
31
- { label: 'User', value: 'user' }, // Top level data
32
- { label: 'Age', value: row => (row.age + ' years') }, // Run functions
33
- { label: 'Phone', value: 'user.more.phone' }, // Deep props
32
+ { label: "User", value: "user" }, // Top level data
33
+ { label: "Age", value: "age", format: '# "years"' }, // Column format
34
+ { label: "Phone", value: "user.more.phone", format: "(###) ###-####" }, // Deep props and column format
34
35
  ],
35
36
  content: [
36
- { user: 'Manuel', age: 16, more: { phone: '99999999' } },
37
- { user: 'Ana', age: 17, more: { phone: '87654321' } }
38
- ]
39
- }
37
+ { user: "Manuel", age: 16, more: { phone: 9999999900 } },
38
+ { user: "Ana", age: 17, more: { phone: 8765432135 } },
39
+ ],
40
+ },
40
41
  ]
41
42
 
42
43
  let settings = {
43
- fileName: 'MySpreadsheet', // Name of the resulting spreadsheet
44
+ fileName: "MySpreadsheet", // Name of the resulting spreadsheet
44
45
  extraLength: 3, // A bigger number means that columns will be wider
45
- writeOptions: {} // Style options from https://github.com/SheetJS/sheetjs#writing-options
46
+ writeOptions: {}, // Style options from https://github.com/SheetJS/sheetjs#writing-options
46
47
  }
47
48
 
48
49
  xlsx(data, settings) // Will download the excel file
49
50
  ```
50
51
 
52
+ If you want to trigger something after the file is downloaded, you can use the `callback` parameter:
53
+
54
+ ```js
55
+ let callback = function (sheet) {
56
+ console.log("Download complete:", sheet)
57
+ }
58
+
59
+ xlsx(data, settings, callback) // Will download the excel file
60
+ ```
61
+
62
+ ### Column formatting
63
+
64
+ > **Note:** Cell formatting is type based, i.e. the format type and value type must match.
65
+ >
66
+ > If you want to use a Date format, the value must be of type Date; if you want a number format, the value must be a Number.
67
+
68
+ Column formatting can be provided in the column object, i.e.
69
+
70
+ ```js
71
+ columns: [{ label: "Income", value: "income", format: "€#,##0.00" }]
72
+ ```
73
+
74
+ - A list of SheetJS format examples can be found
75
+ here: [SSF library](https://github.com/SheetJS/sheetjs/blob/f443aa8475ebf051fc4e888cf0a6c3e5b751813c/bits/10_ssf.js#L42)
76
+ - ECMA-376 number formatting
77
+ specification: [Number formats](https://c-rex.net/projects/samples/ooxml/e1/Part4/OOXML_P4_DOCX_numFmts_topic_ID0E6KK6.html)
78
+
79
+ Examples
80
+
81
+ ```js
82
+ // Number formats
83
+
84
+ "$0.00" // Basic
85
+ "\£#,##0.00" // Pound
86
+ "0%" // Percentage
87
+ '#.# "ft"' // Number and text
88
+
89
+ // Date formats
90
+ "d-mmm-yy" // 12-Mar-22
91
+ "ddd" // (eg. Sat)
92
+ "dddd" // (eg. Saturday)
93
+ "h:mm AM/PM" // 1:10 PM
94
+ ```
95
+
51
96
  ## Examples
52
97
 
53
98
  This are files used for development, please change imports from `../../src/index.js` to `json-as-xlsx`
54
99
 
55
- * [VueJS with JavaScript](https://github.com/LuisEnMarroquin/json-as-xlsx/blob/main/examples/vue-app/App.vue)
56
- * [Express with TypeScript](https://github.com/LuisEnMarroquin/json-as-xlsx/blob/main/examples/express/server.ts)
100
+ - [VueJS with JavaScript](https://github.com/LuisEnMarroquin/json-as-xlsx/blob/main/examples/vue-app/App.vue)
101
+ - [Express with TypeScript](https://github.com/LuisEnMarroquin/json-as-xlsx/blob/main/examples/express/server.ts)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "json-as-xlsx",
3
- "version": "2.3.9",
4
- "main": "src/index.ts",
3
+ "version": "2.4.1",
4
+ "main": "src/index.js",
5
5
  "license": "MIT",
6
6
  "types": "types/index.d.ts",
7
7
  "description": "Create excel xlsx file from json",
@@ -13,7 +13,6 @@
13
13
  "start-client": "vue-cli-service serve",
14
14
  "build-client": "vue-cli-service build",
15
15
  "start-server": "npx nodemon --exec npx ts-node --skip-project examples/express/server.ts",
16
- "lint": "ts-standard --fix",
17
16
  "test": "jest"
18
17
  },
19
18
  "dependencies": {
@@ -27,7 +26,6 @@
27
26
  "express": "^4.17.1",
28
27
  "jest": "^27.3.1",
29
28
  "ts-jest": "^27.0.7",
30
- "ts-standard": "^11.0.0",
31
29
  "typescript": "^4.4.3",
32
30
  "uglify-js": "^3.14.2",
33
31
  "vue": "^2.6.14",
@@ -64,8 +62,8 @@
64
62
  "microsoft-excel"
65
63
  ],
66
64
  "browserslist": [
67
- "> 1%",
68
- "last 2 versions",
69
- "not dead"
65
+ ">0.2%",
66
+ "not dead",
67
+ "not op_mini all"
70
68
  ]
71
69
  }
package/src/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";exports.__esModule=true;exports.getWorksheetColumnWidths=exports.getJsonSheetRow=exports.getContentProperty=void 0;var xlsx_mini_min_1=require("xlsx/dist/xlsx.mini.min");var getContentProperty=function(content,property){var accessContentProperties=function(content,properties){var value=content[properties[0]];if(properties.length===1){return value!==null&&value!==void 0?value:""}if(value===undefined||typeof value==="string"||typeof value==="boolean"||typeof value==="number"||value instanceof Date){return""}return accessContentProperties(value,properties.slice(1))};var properties=property.split(".");return accessContentProperties(content,properties)};exports.getContentProperty=getContentProperty;var getJsonSheetRow=function(content,columns){var jsonSheetRow={};columns.forEach(function(column){if(typeof column.value==="function"){jsonSheetRow[column.label]=column.value(content)}else{jsonSheetRow[column.label]=getContentProperty(content,column.value)}});return jsonSheetRow};exports.getJsonSheetRow=getJsonSheetRow;var getWorksheetColumnWidths=function(worksheet,extraLength){var _a;if(extraLength===void 0){extraLength=1}var columnRange=xlsx_mini_min_1.utils.decode_range((_a=worksheet["!ref"])!==null&&_a!==void 0?_a:"");var columnLetters=[];for(var C=columnRange.s.c;C<=columnRange.e.c;C++){var address=xlsx_mini_min_1.utils.encode_col(C);columnLetters.push(address)}return columnLetters.map(function(column){var columnCells=Object.keys(worksheet).filter(function(cell){return cell.charAt(0)===column||cell.slice(0,2)===column});var maxWidthCell=columnCells.reduce(function(previousCell,currentCell){return worksheet[previousCell].v.length>worksheet[currentCell].v.length?previousCell:currentCell});return{width:worksheet[maxWidthCell].v.length+extraLength}})};exports.getWorksheetColumnWidths=getWorksheetColumnWidths;var getWorksheet=function(jsonSheet,settings){var jsonSheetRows;if(jsonSheet.content.length>0){jsonSheetRows=jsonSheet.content.map(function(contentItem){return getJsonSheetRow(contentItem,jsonSheet.columns)})}else{jsonSheetRows=jsonSheet.columns.map(function(column){var _a;return _a={},_a[column.label]="",_a})}var worksheet=xlsx_mini_min_1.utils.json_to_sheet(jsonSheetRows);worksheet["!cols"]=getWorksheetColumnWidths(worksheet,settings.extraLength);return worksheet};var writeWorkbook=function(workbook,settings){var _a,_b;if(settings===void 0){settings={}}var filename="".concat((_a=settings.fileName)!==null&&_a!==void 0?_a:"Spreadsheet",".xlsx");var writeOptions=(_b=settings.writeOptions)!==null&&_b!==void 0?_b:{};return writeOptions.type==="buffer"?(0,xlsx_mini_min_1.write)(workbook,writeOptions):(0,xlsx_mini_min_1.writeFile)(workbook,filename,writeOptions)};var xlsx=function(jsonSheets,settings,workbookCallback){if(settings===void 0){settings={}}if(workbookCallback===void 0){workbookCallback=function(){}}if(jsonSheets.length===0)return;var workbook=xlsx_mini_min_1.utils.book_new();jsonSheets.forEach(function(actualSheet,actualIndex){var _a;var worksheet=getWorksheet(actualSheet,settings);var worksheetName=(_a=actualSheet.sheet)!==null&&_a!==void 0?_a:"Sheet ".concat(actualIndex+1);xlsx_mini_min_1.utils.book_append_sheet(workbook,worksheet,worksheetName)});workbookCallback(workbook);return writeWorkbook(workbook,settings)};exports["default"]=xlsx;module.exports=xlsx;module.exports.getContentProperty=getContentProperty;module.exports.getJsonSheetRow=getJsonSheetRow;module.exports.getWorksheetColumnWidths=getWorksheetColumnWidths;
1
+ "use strict";exports.__esModule=true;exports.getWorksheetColumnWidths=exports.getJsonSheetRow=exports.getContentProperty=void 0;var xlsx_mini_min_1=require("xlsx/dist/xlsx.mini.min");var getContentProperty=function(content,property){var accessContentProperties=function(content,properties){var value=content[properties[0]];if(properties.length===1){return value!==null&&value!==void 0?value:""}if(value===undefined||typeof value==="string"||typeof value==="boolean"||typeof value==="number"||value instanceof Date){return""}return accessContentProperties(value,properties.slice(1))};var properties=property.split(".");return accessContentProperties(content,properties)};exports.getContentProperty=getContentProperty;var getJsonSheetRow=function(content,columns){var jsonSheetRow={};columns.forEach(function(column){if(typeof column.value==="function"){jsonSheetRow[column.label]=column.value(content)}else{jsonSheetRow[column.label]=getContentProperty(content,column.value)}});return jsonSheetRow};exports.getJsonSheetRow=getJsonSheetRow;var applyColumnFormat=function(worksheet,columnIds,columnFormats){var _a;for(var i=0;i<columnIds.length;i+=1){var columnFormat=columnFormats[i];if(!columnFormat){continue}var column=xlsx_mini_min_1.utils.decode_col(columnIds[i]);var range=xlsx_mini_min_1.utils.decode_range((_a=worksheet["!ref"])!==null&&_a!==void 0?_a:"");for(var row=range.s.r+1;row<=range.e.r;++row){var ref=xlsx_mini_min_1.utils.encode_cell({r:row,c:column});if(worksheet[ref]){worksheet[ref].z=columnFormat}}}};var getWorksheetColumnIds=function(worksheet){var _a;var columnRange=xlsx_mini_min_1.utils.decode_range((_a=worksheet["!ref"])!==null&&_a!==void 0?_a:"");var columnIds=[];for(var C=columnRange.s.c;C<=columnRange.e.c;C++){var address=xlsx_mini_min_1.utils.encode_col(C);columnIds.push(address)}return columnIds};var getObjectLength=function(object){if(typeof object==="string"){return object.length}if(typeof object==="number"){return object.toString().length}if(typeof object==="boolean"){return object?"true".length:"false".length}if(object instanceof Date){return object.toString().length}return 0};var getWorksheetColumnWidths=function(worksheet,extraLength){if(extraLength===void 0){extraLength=1}var columnLetters=getWorksheetColumnIds(worksheet);return columnLetters.map(function(column){var columnCells=Object.keys(worksheet).filter(function(cell){return cell.replace(/[0-9]/g,"")===column});var maxWidthCell=columnCells.reduce(function(maxWidth,cellId){var cell=worksheet[cellId];var cellContentLength=getObjectLength(cell.v);if(!cell.z){return Math.max(maxWidth,cellContentLength)}var cellFormatLength=cell.z.length;var largestWidth=Math.max(cellContentLength,cellFormatLength);return Math.max(maxWidth,largestWidth)},0);return{width:maxWidthCell+extraLength}})};exports.getWorksheetColumnWidths=getWorksheetColumnWidths;var getWorksheet=function(jsonSheet,settings){var jsonSheetRows;if(jsonSheet.content.length>0){jsonSheetRows=jsonSheet.content.map(function(contentItem){return getJsonSheetRow(contentItem,jsonSheet.columns)})}else{jsonSheetRows=jsonSheet.columns.map(function(column){var _a;return _a={},_a[column.label]="",_a})}var worksheet=xlsx_mini_min_1.utils.json_to_sheet(jsonSheetRows);var worksheetColumnIds=getWorksheetColumnIds(worksheet);var worksheetColumnFormats=jsonSheet.columns.map(function(jsonSheetColumn){var _a;return(_a=jsonSheetColumn.format)!==null&&_a!==void 0?_a:null});applyColumnFormat(worksheet,worksheetColumnIds,worksheetColumnFormats);worksheet["!cols"]=getWorksheetColumnWidths(worksheet,settings.extraLength);return worksheet};var writeWorkbook=function(workbook,settings){var _a,_b;if(settings===void 0){settings={}}var filename="".concat((_a=settings.fileName)!==null&&_a!==void 0?_a:"Spreadsheet",".xlsx");var writeOptions=(_b=settings.writeOptions)!==null&&_b!==void 0?_b:{};return writeOptions.type==="buffer"?(0,xlsx_mini_min_1.write)(workbook,writeOptions):(0,xlsx_mini_min_1.writeFile)(workbook,filename,writeOptions)};var xlsx=function(jsonSheets,settings,workbookCallback){if(settings===void 0){settings={}}if(workbookCallback===void 0){workbookCallback=function(){}}if(jsonSheets.length===0)return;var workbook=xlsx_mini_min_1.utils.book_new();jsonSheets.forEach(function(actualSheet,actualIndex){var _a;var worksheet=getWorksheet(actualSheet,settings);var worksheetName=(_a=actualSheet.sheet)!==null&&_a!==void 0?_a:"Sheet ".concat(actualIndex+1);xlsx_mini_min_1.utils.book_append_sheet(workbook,worksheet,worksheetName)});workbookCallback(workbook);return writeWorkbook(workbook,settings)};exports["default"]=xlsx;module.exports=xlsx;module.exports.getContentProperty=getContentProperty;module.exports.getJsonSheetRow=getJsonSheetRow;module.exports.getWorksheetColumnWidths=getWorksheetColumnWidths;
package/types/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { WritingOptions } from 'xlsx'
1
+ import { WritingOptions } from "xlsx"
2
2
 
3
3
  export interface IColumn {
4
4
  label: string
5
5
  value: string | ((value: IContent) => string | number | boolean | Date | IContent)
6
+ format?: string
6
7
  }
7
8
 
8
9
  export interface IContent {
@@ -29,6 +30,6 @@ export interface IWorksheetColumnWidth {
29
30
  width: number
30
31
  }
31
32
 
32
- export function xlsx (jsonSheets: IJsonSheet[], settings?: ISettings): Buffer | undefined
33
+ export function xlsx(jsonSheets: IJsonSheet[], settings?: ISettings): Buffer | undefined
33
34
 
34
35
  export default xlsx
package/src/index.ts DELETED
@@ -1,110 +0,0 @@
1
- import { utils, WorkBook, WorkSheet, write, writeFile } from 'xlsx/dist/xlsx.mini.min'
2
- import { IColumn, IContent, IJsonSheet, IJsonSheetRow, ISettings, IWorksheetColumnWidth } from '../types/index'
3
-
4
- const getContentProperty = (content: IContent, property: string): string | number | boolean | Date | IContent => {
5
- const accessContentProperties = (content: IContent, properties: string[]): string | number | boolean | Date | IContent => {
6
- const value = content[properties[0]]
7
-
8
- if (properties.length === 1) {
9
- return value ?? ''
10
- }
11
-
12
- if (value === undefined || typeof value === 'string' || typeof value === 'boolean' ||
13
- typeof value === 'number' || value instanceof Date) {
14
- return ''
15
- }
16
-
17
- return accessContentProperties(value, properties.slice(1))
18
- }
19
-
20
- const properties = property.split('.')
21
- return accessContentProperties(content, properties)
22
- }
23
-
24
- const getJsonSheetRow = (content: IContent, columns: IColumn[]): IJsonSheetRow => {
25
- const jsonSheetRow: IJsonSheetRow = {}
26
- columns.forEach((column) => {
27
- if (typeof column.value === 'function') {
28
- jsonSheetRow[column.label] = column.value(content)
29
- } else {
30
- jsonSheetRow[column.label] = getContentProperty(content, column.value)
31
- }
32
- })
33
- return jsonSheetRow
34
- }
35
-
36
- const getWorksheetColumnWidths = (worksheet: WorkSheet, extraLength: number = 1): IWorksheetColumnWidth[] => {
37
- const columnRange = utils.decode_range(worksheet['!ref'] ?? '')
38
-
39
- // Column letters present in the workbook, e.g. A, B, C
40
- const columnLetters: string[] = []
41
- for (let C = columnRange.s.c; C <= columnRange.e.c; C++) {
42
- const address = utils.encode_col(C)
43
- columnLetters.push(address)
44
- }
45
-
46
- return columnLetters.map((column) => {
47
- // Cells that belong to this column
48
- const columnCells: string[] = Object.keys(worksheet).filter((cell) => {
49
- return cell.charAt(0) === column || cell.slice(0, 2) === column
50
- })
51
-
52
- const maxWidthCell = columnCells.reduce((previousCell, currentCell) => {
53
- return worksheet[previousCell].v.length > worksheet[currentCell].v.length
54
- ? previousCell
55
- : currentCell
56
- })
57
-
58
- return { width: worksheet[maxWidthCell].v.length as number + extraLength }
59
- })
60
- }
61
-
62
- const getWorksheet = (jsonSheet: IJsonSheet, settings: ISettings): WorkSheet => {
63
- let jsonSheetRows: IJsonSheetRow[]
64
-
65
- if (jsonSheet.content.length > 0) {
66
- jsonSheetRows = jsonSheet.content.map((contentItem) => {
67
- return getJsonSheetRow(contentItem, jsonSheet.columns)
68
- })
69
- } else {
70
- // If there's no content, show only column labels
71
- jsonSheetRows = jsonSheet.columns.map((column) => ({ [column.label]: '' }))
72
- }
73
-
74
- const worksheet = utils.json_to_sheet(jsonSheetRows)
75
- worksheet['!cols'] = getWorksheetColumnWidths(worksheet, settings.extraLength)
76
-
77
- return worksheet
78
- }
79
-
80
- const writeWorkbook = (workbook: WorkBook, settings: ISettings = {}): Buffer | undefined => {
81
- const filename = `${settings.fileName ?? 'Spreadsheet'}.xlsx`
82
- const writeOptions = settings.writeOptions ?? {}
83
-
84
- return writeOptions.type === 'buffer'
85
- ? write(workbook, writeOptions)
86
- : writeFile(workbook, filename, writeOptions)
87
- }
88
-
89
- type IWorkbookCallback = (workbook: WorkBook) => void
90
-
91
- const xlsx = (jsonSheets: IJsonSheet[], settings: ISettings = {}, workbookCallback: IWorkbookCallback = () => { }): Buffer | undefined => {
92
- if (jsonSheets.length === 0) return
93
-
94
- const workbook = utils.book_new() // Creating a workbook, this is the name given to an Excel file
95
- jsonSheets.forEach((actualSheet, actualIndex) => {
96
- const worksheet = getWorksheet(actualSheet, settings)
97
- const worksheetName = actualSheet.sheet ?? `Sheet ${actualIndex + 1}`
98
- utils.book_append_sheet(workbook, worksheet, worksheetName) // Add Worksheet to Workbook
99
- })
100
-
101
- workbookCallback(workbook)
102
- return writeWorkbook(workbook, settings)
103
- }
104
-
105
- export default xlsx
106
- export { getContentProperty, getJsonSheetRow, getWorksheetColumnWidths }
107
- module.exports = xlsx
108
- module.exports.getContentProperty = getContentProperty
109
- module.exports.getJsonSheetRow = getJsonSheetRow
110
- module.exports.getWorksheetColumnWidths = getWorksheetColumnWidths