excellentexport 3.7.3 → 3.8.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.
@@ -1,3 +1,3 @@
1
- /*! cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
1
+ /*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
2
2
 
3
- /*! cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
3
+ /*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
package/dist/utils.d.ts CHANGED
@@ -17,6 +17,11 @@ export declare const getTable: (element: (HTMLTableElement | string)) => HTMLTab
17
17
  * @param {*} element
18
18
  */
19
19
  export declare const getAnchor: (element: (HTMLAnchorElement | string)) => HTMLAnchorElement;
20
+ /**
21
+ * Encode a value for CSV.
22
+ * @param {*} value
23
+ */
24
+ export declare const fixCSVField: (value: string, csvDelimiter: string) => string;
20
25
  export declare const tableToArray: (table: HTMLTableElement) => any[][];
21
26
  export declare const tableToCSV: (table: HTMLTableElement, csvDelimiter?: string, csvNewLine?: string) => string;
22
27
  export declare const createDownloadLink: (anchor: HTMLAnchorElement, base64data: string, exporttype: string, filename: string) => boolean;
@@ -2,63 +2,38 @@
2
2
  <head>
3
3
  <meta charset="utf-8">
4
4
  <title>Export to excel test</title>
5
- <script src="excellentexport.js"></script>
5
+ <script src="dist/excellentexport.js"></script>
6
6
  <style>
7
7
  table, tr, td {
8
8
  border: 1px black solid;
9
9
  }
10
10
  </style>
11
+ <script>
12
+ function action(format) {
13
+ return ExcellentExport.convert({
14
+ anchor: 'bigdata-' + format,
15
+ filename: 'big_table.' + format,
16
+ format: format
17
+ }, [{
18
+ name: 'Big Table',
19
+ from: {
20
+ table: 'bigtable'
21
+ }
22
+ }]);
23
+ }
24
+ </script>
11
25
  </head>
12
26
  <body>
13
27
  <h1>ExcellentExport.js</h1>
14
28
 
15
29
  Check on <a href="http://jordiburgos.com">jordiburgos.com</a> and <a href="https://github.com/jmaister/excellentexport">GitHub</a>.
16
30
 
17
- <h3>Test page</h3>
18
-
19
- <br/>
20
-
21
- <a download="somedata.xls" href="#" onclick="return ExcellentExport.excel(this, 'datatable', 'Sheet Name Here');">Export to Excel</a>
22
- <br/>
23
-
24
- <a download="somedata.csv" href="#" onclick="return ExcellentExport.csv(this, 'datatable');">Export to CSV - UTF8</a>
25
- <br/>
26
- <a download="somedata.csv" href="#" onclick="return ExcellentExport.csv(this, 'datatable', ';');">Export to CSV - Using semicolon ";" separator - UTF8</a>
27
- <br/>
31
+ <h3>Big Table Test page</h3>
28
32
 
29
- <table id="datatable">
30
- <tr>
31
- <th>Column 1</th>
32
- <th>Column "cool" 2</th>
33
- <th>Column 3</th>
34
- <th>Column 4</th>
35
- </tr>
36
- <tr>
37
- <td>100,111</td>
38
- <td>200</td>
39
- <td>300</td>
40
- <td>áéíóú</td>
41
- </tr>
42
- <tr>
43
- <td>400</td>
44
- <td>500</td>
45
- <td>Chinese chars: 解决导出csv中文乱码问题</td>
46
- <td>àèìòù</td>
47
- </tr>
48
- <tr>
49
- <td>Text</td>
50
- <td>More text</td>
51
- <td>Text with
52
- new line</td>
53
- <td>ç ñ ÄËÏÖÜ äëïöü</td>
54
- </tr>
55
- </table>
56
33
 
57
-
58
- <br/>
59
- <br/>
60
- <a download="bigdata.xls" href="#" onclick="return ExcellentExport.excel(this, 'bigtable', 'Big Data Sheet');">Export to Excel very big table</a><br/>
61
- <a download="bigdata.csv" href="#" onclick="return ExcellentExport.csv(this, 'bigtable');">Export to CSV very big table</a>
34
+ <a id="bigdata-xlsx" download="bigdata.xlsx" href="#" onclick="return action('xlsx')">Export to XLSX very big table</a><br/>
35
+ <a id="bigdata-xls" download="bigdata.xls" href="#" onclick="return action('xls')">Export to XLS very big table</a><br/>
36
+ <a id="bigdata-csv" download="bigdata.csv" href="#" onclick="return action('csv')">Export to CSV very big table</a>
62
37
  <table id="bigtable">
63
38
  <br/>
64
39
  </table>
package/index.rtl.html ADDED
@@ -0,0 +1,69 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="utf-8">
4
+ <title>Export to excel test</title>
5
+ <script src="dist/excellentexport.js"></script>
6
+ <style>
7
+ table, tr, td {
8
+ border: 1px black solid;
9
+ }
10
+ </style>
11
+ <script>
12
+ function openFile(format) {
13
+ return ExcellentExport.convert({
14
+ anchor: 'anchorNewApi-' + format,
15
+ filename: 'data_123.' + format,
16
+ format: format,
17
+ rtl: true,
18
+ }, [{
19
+ name: 'Sheet Name Here 1',
20
+ from: {
21
+ table: 'datatable'
22
+ }
23
+ }]);
24
+ }
25
+ </script>
26
+ </head>
27
+ <body>
28
+ <h1>ExcellentExport.js RTL text</h1>
29
+
30
+ Check on <a href="http://jordiburgos.com">jordiburgos.com</a> and <a href="https://github.com/jmaister/excellentexport">GitHub</a>.
31
+
32
+ <h3>Test page</h3>
33
+
34
+ Test table
35
+ <table id="datatable">
36
+ <thead>
37
+ <tr>
38
+ <th>االلغة</th>
39
+ <th>عدد الأحرف</th>
40
+ <th>Country</th>
41
+ <th>miص-ص</th>
42
+ </tr>
43
+ </thead>
44
+ <tbody>
45
+ <tr>
46
+ <td>العربية</td>
47
+ <td>٢٨</td>
48
+ <td>Earth</td>
49
+ <td>ن0ن</td>
50
+ </tr>
51
+ <tr>
52
+ <td>العبرية</td>
53
+ <td>٢٢</td>
54
+ <td>Isreal</td>
55
+ <td>ضSض</td>
56
+ </tr>
57
+ </tbody>
58
+ </table>
59
+
60
+ <br/>
61
+
62
+ <a download="data_123.xls" href="#" id="anchorNewApi-xls" onclick="return openFile('xls');">Export to Excel: XLS format</a>
63
+ <br/>
64
+ <a download="data_123.xlsx" href="#" id="anchorNewApi-xlsx" onclick="return openFile('xlsx');">Export to Excel: XLSX format</a>
65
+ <br/>
66
+ <a download="data_123.csv" href="#" id="anchorNewApi-csv" onclick="return openFile('csv');">Export to CSV</a>
67
+
68
+ </body>
69
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "excellentexport",
3
- "version": "3.7.3",
3
+ "version": "3.8.1",
4
4
  "description": "Client side JavaScript export to Excel or CSV",
5
5
  "license": "MIT",
6
6
  "homepage": "http://jordiburgos.com",
@@ -27,31 +27,34 @@
27
27
  },
28
28
  "main": "dist/excellentexport.js",
29
29
  "devDependencies": {
30
- "@babel/core": "7.15.8",
31
- "@babel/plugin-proposal-class-properties": "7.14.5",
32
- "@babel/plugin-transform-flow-strip-types": "7.14.5",
33
- "@babel/preset-env": "7.15.8",
34
- "@types/jest": "27.0.2",
35
- "@types/jest-environment-puppeteer": "4.4.1",
36
- "@types/node": "16.11.6",
37
- "@types/puppeteer": "5.4.4",
38
- "babel-loader": "8.2.3",
39
- "blob-polyfill": "6.0.20211015",
30
+ "@babel/core": "7.20.12",
31
+ "@babel/plugin-proposal-class-properties": "7.18.6",
32
+ "@babel/plugin-transform-flow-strip-types": "7.19.0",
33
+ "@babel/preset-env": "7.20.2",
34
+ "@types/jest": "29.4.0",
35
+ "@types/jest-environment-puppeteer": "5.0.3",
36
+ "@types/node": "18.13.0",
37
+ "babel-loader": "9.1.2",
38
+ "blob-polyfill": "7.0.20220408",
40
39
  "coveralls": "3.1.1",
41
40
  "cross-env": "7.0.3",
42
- "html-loader": "3.0.0",
43
- "jest": "27.3.1",
44
- "jest-puppeteer": "6.0.0",
45
- "puppeteer": "10.4.0",
46
- "ts-jest": "27.0.7",
47
- "ts-loader": "9.2.6",
48
- "ts-node": "10.3.0",
49
- "typescript": "4.3.4",
50
- "webdriverio": "7.16.3",
51
- "webpack": "5.60.0",
52
- "webpack-cli": "4.9.1",
53
- "webpack-dev-server": "4.3.1",
41
+ "html-loader": "4.2.0",
42
+ "jest": "29.4.2",
43
+ "jest-environment-jsdom": "^29.4.2",
44
+ "jest-puppeteer": "7.0.0",
45
+ "puppeteer": "19.6.3",
46
+ "ts-jest": "29.0.5",
47
+ "ts-loader": "9.4.2",
48
+ "ts-node": "10.9.1",
49
+ "typescript": "4.9.5",
50
+ "webdriverio": "8.3.5",
51
+ "webpack": "5.75.0",
52
+ "webpack-cli": "5.0.1",
53
+ "webpack-dev-server": "4.11.1",
54
54
  "webpack-node-externals": "3.0.0",
55
- "xlsx": "0.17.3"
55
+ "xlsx": "0.18.5"
56
+ },
57
+ "resolutions": {
58
+ "json-schema": "0.4.0"
56
59
  }
57
60
  }
@@ -11,11 +11,19 @@ import * as XLSX from 'xlsx';
11
11
 
12
12
  import * as utils from './utils';
13
13
 
14
+ // Fix for IE11: https://stackoverflow.com/questions/69485778/new-typescript-version-does-not-include-window-navigator-mssaveblob
15
+ declare global {
16
+ interface Navigator {
17
+ msSaveBlob?: (blob: any, defaultName?: string) => boolean
18
+ }
19
+ }
20
+
14
21
  export interface ConvertOptions {
15
22
  anchor?: (string|HTMLAnchorElement),
16
23
  openAsDownload?: boolean,
17
24
  format: ('csv' | 'xls' | 'xlsx'),
18
25
  filename?: string,
26
+ rtl?: boolean,
19
27
  }
20
28
  export interface FromOptions {
21
29
  table?: (string|HTMLTableElement),
@@ -28,13 +36,13 @@ export interface SheetOptions {
28
36
  filterRowFn?(row:any[]): boolean ,
29
37
  fixValue?(value:any, row:number, column:number): any,
30
38
  fixArray?(array:any[][]): any[][],
39
+ rtl?: boolean
31
40
  }
32
41
 
33
42
 
34
43
  const ExcellentExport = function() {
35
44
 
36
- const version = "3.7.3";
37
-
45
+ const version = "3.8.1";
38
46
 
39
47
  /*
40
48
  ExcellentExport.convert(options, sheets);
@@ -44,7 +52,8 @@ const ExcellentExport = function() {
44
52
  anchor: String or HTML Element,
45
53
  openAsDownload: boolean, // Use this options if not using an anchor tag
46
54
  format: 'xlsx' or 'xls' or 'csv',
47
- filename: String
55
+ filename: String,
56
+ rtl: boolean (optional), specify if all the workbook has text in RTL mode
48
57
  }
49
58
 
50
59
  Sheets must be an array of sheet configuration objects. Sheet description:
@@ -59,6 +68,7 @@ const ExcellentExport = function() {
59
68
  filterRowFn: function(row) {return true}, // Function to decide which rows are returned
60
69
  fixValue: function(value, row, column) {return fixedValue} // Function to fix values, receiving value, row num, column num
61
70
  fixArray: function(array) {return array} // Function to manipulate the whole data array
71
+ rtl: boolean // optional: specify if the sheet has text in RTL mode
62
72
  ...
63
73
  },
64
74
  {
@@ -69,7 +79,8 @@ const ExcellentExport = function() {
69
79
  const convert = function(options:ConvertOptions, sheets:SheetOptions[]) {
70
80
  const workbook = {
71
81
  SheetNames: [],
72
- Sheets: {}
82
+ Sheets: {},
83
+ Views: []
73
84
  };
74
85
 
75
86
  if (!options.format) {
@@ -86,7 +97,7 @@ const ExcellentExport = function() {
86
97
  }
87
98
 
88
99
  // Select data source
89
- let dataArray;
100
+ let dataArray: any[][];
90
101
  if (sheetConf.from && sheetConf.from.table) {
91
102
  dataArray = utils.tableToArray(utils.getTable(sheetConf.from.table));
92
103
  } else if(sheetConf.from && sheetConf.from.array) {
@@ -108,7 +119,7 @@ const ExcellentExport = function() {
108
119
  utils.removeColumns(dataArray, sheetConf.removeColumns);
109
120
  }
110
121
 
111
- // Convert data, by value
122
+ // Convert data. Function applied to each value independently, receiving (value, rownum, colnum)
112
123
  if (sheetConf.fixValue && typeof sheetConf.fixValue === 'function') {
113
124
  const fn = sheetConf.fixValue;
114
125
  dataArray.map((r, rownum) => {
@@ -128,9 +139,10 @@ const ExcellentExport = function() {
128
139
  workbook.SheetNames.push(name);
129
140
  const worksheet = XLSX.utils.aoa_to_sheet(dataArray, {sheet: name} as XLSX.AOA2SheetOpts);
130
141
  workbook.Sheets[name] = worksheet;
142
+ workbook.Views.push({RTL: options.rtl || sheetConf.rtl || false});
131
143
  });
132
144
 
133
- const wbOut:string = XLSX.write(workbook, {bookType: options.format, bookSST:true, type: 'binary'});
145
+ const wbOut:string = XLSX.write(workbook, {bookType: options.format, bookSST:true, type: 'binary', compression: true});
134
146
  try {
135
147
  const blob = new Blob([utils.string2ArrayBuffer(wbOut)], { type: "application/octet-stream" });
136
148
  const filename = (options.filename || 'download') + '.' + options.format;
package/src/utils.ts CHANGED
@@ -37,7 +37,7 @@ export const base64 = function(s:string) : string {
37
37
 
38
38
  export const format = function(s:string, context:any) : string {
39
39
  return s.replace(new RegExp("{(\\w+)}", "g"), function(m, p) {
40
- return context[p];
40
+ return context[p] || "{" + p + "}";
41
41
  });
42
42
  };
43
43
 
@@ -67,7 +67,7 @@ export const getAnchor = function(element :(HTMLAnchorElement|string)) : HTMLAnc
67
67
  * Encode a value for CSV.
68
68
  * @param {*} value
69
69
  */
70
- const fixCSVField = function(value:string, csvDelimiter:string) {
70
+ export const fixCSVField = function(value:string, csvDelimiter:string) : string {
71
71
  let fixedValue = value;
72
72
  const addQuotes = (value.indexOf(csvDelimiter) !== -1) || (value.indexOf('\r') !== -1) || (value.indexOf('\n') !== -1);
73
73
  const replaceDoubleQuotes = (value.indexOf('"') !== -1);
@@ -0,0 +1,29 @@
1
+ const assert = require('assert');
2
+
3
+ import * as utils from '../src/utils';
4
+
5
+
6
+ describe('Test utility functions', () => {
7
+
8
+ describe('base64', () => {
9
+ it('should encode a string to base64', () => {
10
+ assert.equal(utils.base64('test'), 'dGVzdA==');
11
+ });
12
+
13
+ it('should encode a unicode string to base64', () => {
14
+ assert.equal(utils.base64('test\u00A9'), "dGVzdMKp");
15
+ });
16
+
17
+ });
18
+
19
+
20
+ describe('test format function', () => {
21
+ it('should format a string', () => {
22
+ assert.equal(utils.format('aaaa {a} bbbb {b} cccc', {a:'1', b:'2', c:'3', d:'4'}), 'aaaa 1 bbbb 2 cccc');
23
+ });
24
+
25
+ it('should not replace if no data is provided', () => {
26
+ assert.equal(utils.format('aaaa {a} bbbb {b} cccc', {}), 'aaaa {a} bbbb {b} cccc');
27
+ });
28
+ });
29
+ });
@@ -0,0 +1,24 @@
1
+ const assert = require('assert');
2
+
3
+ import { fixCSVField } from '../src/utils';
4
+
5
+
6
+ describe('Test utility functions: csv functions', () => {
7
+
8
+ it('should keep the value if not delimiter found', () => {
9
+ assert.equal(fixCSVField('test', ','), 'test');
10
+ });
11
+
12
+ it('should fix a string with double quotes', () => {
13
+ const str = 'aaa"bbb';
14
+ const result = fixCSVField(str, "\"");
15
+ assert.equal(result, '\"aaa\"\"bbb\"');
16
+ });
17
+
18
+ it('should fix a field with space delimiter', () => {
19
+ const str = 'aaa bbb';
20
+ const result = fixCSVField(str, " ");
21
+ assert.equal(result, '\"aaa bbb\"');
22
+ });
23
+
24
+ });
@@ -3,9 +3,7 @@ const assert = require('assert');
3
3
  import { removeColumns } from '../src/utils';
4
4
 
5
5
 
6
- describe('Test utility functions', () => {
7
- beforeEach(() => {
8
- });
6
+ describe('Test utility functions: removeColumns', () => {
9
7
 
10
8
  it('should remove one column correctly', function() {
11
9
  const columns = [
package/tsconfig.json CHANGED
@@ -1,17 +1,17 @@
1
- {
2
- "compilerOptions": {
3
- "outDir": "./dist",
4
- "allowJs": true,
5
- "target": "ESNext",
6
- "sourceMap": true,
7
- "removeComments": false,
8
- "declaration": true,
9
- "rootDir": "src",
10
- "moduleResolution": "node",
11
- "esModuleInterop": true
12
- },
13
- "include": [
14
- "src/**/*.ts",
15
- "test/**/*.{ts,js}"
16
- ]
17
- }
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./dist",
4
+ "allowJs": true,
5
+ "target": "ESNext",
6
+ "sourceMap": true,
7
+ "removeComments": false,
8
+ "declaration": true,
9
+ "rootDir": "src",
10
+ "moduleResolution": "node",
11
+ "esModuleInterop": true
12
+ },
13
+ "include": [
14
+ "src/**/*.ts",
15
+ "test/**/*.{ts,js}"
16
+ ]
17
+ }
package/.travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - "14"
4
- env:
5
- - MOZ_HEADLESS=1
6
- addons:
7
- firefox: latest
8
- cache:
9
- yarn: true