@microsoft/connected-workbooks 2.1.16-beta → 2.1.24-beta

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
@@ -24,24 +24,20 @@ Connected Workbooks allows you to avoid "data dumps" in CSV form, providing a ri
24
24
 
25
25
  ### 1. Export a table directly from an Html page:
26
26
  ```typescript
27
- import { workbookManager } from '@microsoft/connected-workbooks';
27
+ import workbookManager from '@microsoft/connected-workbooks';
28
28
 
29
29
  const blob = await workbookManager.generateTableWorkbookFromHtml(document.querySelector('table') as HTMLTableElement);
30
30
  workbookManager.downloadWorkbook(blob, "MyTable.xlsx");
31
31
  ```
32
+
32
33
  ### 2. Export a table from raw data:
33
- ```typescript
34
- import { workbookManager } from '@microsoft/connected-workbooks';
34
+ ```
35
+ import workbookManager from '@microsoft/connected-workbooks';
35
36
 
36
37
  const grid = {
37
- "header": [
38
- { "name": "Product", "type": DataTypes.autodetect },
39
- { "name": "Price", "type": DataTypes.autodetect },
40
- { "name": "InStock", "type": DataTypes.autodetect },
41
- { "name": "Category", "type": DataTypes.autodetect },
42
- { "name": "Date", "type": DataTypes.autodetect }
43
- ],
44
- "gridData": [
38
+ "promoteHeaders": true,
39
+ "data": [
40
+ ["Product", "Price", "InStock", "Category", "Date"],
45
41
  ["Widget A", 19.99, true, "Electronics", "10/26/2024"],
46
42
  ["Gizmo B", 9.99, true, "Accessories", "10/26/2024"],
47
43
  ["Bubala", 14.99, false, "Accessories", "10/22/2023"],
@@ -60,13 +56,13 @@ workbookManager.downloadWorkbook(blob, "MyTable.xlsx");
60
56
  document.querySelector('table') as HTMLTableElement,
61
57
  {createdBy: 'John Doe', lastModifiedBy: 'Jane Doe', description: 'This is a sample table'});
62
58
 
63
- workbookManager.downloadWorkbook(blob, "MyTable.xlsx");
59
+ workbookManager.downloadWorkbook(blob, "MyTable.xlsx");
64
60
  ```
65
61
  ![image](https://github.com/microsoft/connected-workbooks/assets/7674478/c267c9eb-6367-419d-832d-5a835c7683f9)
66
62
 
67
63
  ### 4. Export a Power Query connected workbook:
68
64
  ```typescript
69
- import { workbookManager } from '@microsoft/connected-workbooks';
65
+ import workbookManager from '@microsoft/connected-workbooks';
70
66
 
71
67
  const blob = await workbookManager.generateSingleQueryWorkbook({
72
68
  queryMashup: 'let \
@@ -75,9 +71,9 @@ const blob = await workbookManager.generateSingleQueryWorkbook({
75
71
  Source',
76
72
  refreshOnOpen: true});
77
73
  workbookManager.downloadWorkbook(blob, "MyConnectedWorkbook.xlsx");
78
- });
79
74
  ```
80
75
  ![image](https://github.com/microsoft/connected-workbooks/assets/7674478/57bd986c-6309-4963-8d86-911ccf496c3f)
76
+
81
77
  (after refreshing on open)
82
78
  ### Advanced Usage - bring your own template:
83
79
 
@@ -86,7 +82,7 @@ You can use the library with your own workbook as a template!
86
82
  ```typescript
87
83
  const blob = await workbookManager.generateSingleQueryWorkbook(
88
84
  { queryMashup: query, refreshOnOpen: true },
89
- undefined /* optional gridData */,
85
+ undefined /* optional Grid */,
90
86
  templateFile);
91
87
  workbookManager.downloadWorkbook(blob, "MyBrandedWorkbook.xlsx");
92
88
  ```
@@ -109,6 +105,74 @@ const [templateFile, setTemplateFile] = useState<File | null>(null);
109
105
  setTemplateFile(e!.target!.files!.item(0));
110
106
  }}/>
111
107
  ```
108
+ ### API
109
+ The library exposes a workbookManager, which generates a workbook via several APIs:
110
+
111
+ #### 1. Generate a Power Query connected workbook
112
+ ```typescript
113
+ async function `generateSingleQueryWorkbook`: `Promise<Blob>`
114
+ ```
115
+
116
+ |Parameter | Type | Required | Description |
117
+ |--- |--- |--- |--- |
118
+ |query | [QueryInfo](#queryinfo) | __required__ | Power Query mashup |
119
+ | grid | [Grid](#grid) | optional | Initial grid data |
120
+ | fileConfigs | [FileConfigs](#fileconfigs) | optional | Custom file configurations |
121
+
122
+ #### 2. Generate a table workbook from a Html page
123
+ ```typescript
124
+ async function `generateTableWorkbookFromHtml`: `Promise<Blob>`
125
+ ```
126
+
127
+ |Parameter | Type | Required | Description |
128
+ |--- |--- |--- |--- |
129
+ | htmlTable | HTMLTableElement | __required__ | Initial data loaded to workbook |
130
+ | docProps | [DocProps](#docprops) | optional | Custom workbook properties |
131
+
132
+ #### 3. Generate a table workbook with raw data
133
+ ```typescript
134
+ async function `generateTableWorkbookFromGrid`: `Promise<Blob>`
135
+ ```
136
+
137
+ |Parameter | Type | Required | Description |
138
+ |--- |--- |--- |--- |
139
+ | grid | [Grid](#grid) | __required__ | Initial data loaded to workbook |
140
+ | docProps | [DocProps](#docprops) | optional | Custom workbook properties |
141
+ </br>
142
+
143
+ ### Types
144
+
145
+ #### QueryInfo
146
+ |Parameter | Type | Required | Description |
147
+ |---|---|---|---|
148
+ | queryMashup | string | __required__ | Mashup string
149
+ | refreshOnOpen | boolean | __required__ | Should workbook data refresh upon open
150
+ | queryName | string | optional | Query name, defaults to "Query1"
151
+
152
+ #### Grid
153
+ |Parameter | Type | Required | Description |
154
+ |---|---|---|---|
155
+ | data | (string | number | boolean)[][] | __required__ | Grid data
156
+ | promoteHeaders | boolean | optional | Should first row of gridData be used as the header, defaults to false - generating "Column1", "Column2"...
157
+
158
+
159
+ #### FileConfigs
160
+ |Parameter | Type | Required | Description |
161
+ |---|---|---|---|
162
+ | templateFile | File | optional | Custom Excel workbook |
163
+ | docProps | [DocProps](#docprops) | optional | Custom workbook properties |
164
+
165
+ #### DocProps
166
+ |Parameter | Type | Required
167
+ |---|---|---|
168
+ | title | string | optional
169
+ | subject | string | optional
170
+ | keywords | string | optional
171
+ | createdBy | string | optional
172
+ | description | string | optional
173
+ | lastModifiedBy | string | optional
174
+ | category | string | optional
175
+ | revision | number | optional
112
176
 
113
177
  ## Contributing
114
178
 
@@ -1,55 +1,48 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseToTableData = void 0;
3
4
  const constants_1 = require("./utils/constants");
4
- const types_1 = require("./types");
5
- class GridParser {
6
- parseToTableData(initialDataGrid) {
7
- if (!initialDataGrid) {
8
- return undefined;
9
- }
10
- this.validateGridHeader(initialDataGrid);
11
- const rows = this.parseGridRows(initialDataGrid, initialDataGrid.header);
12
- return { columnMetadata: initialDataGrid.header, rows: rows };
5
+ const parseToTableData = (grid) => {
6
+ if (!grid) {
7
+ return undefined;
13
8
  }
14
- parseGridRows(initialDataGrid, columnMetadata) {
15
- const gridData = initialDataGrid.gridData;
16
- if (!gridData) {
17
- throw new Error(constants_1.gridNotFoundErr);
18
- }
19
- const rows = [];
20
- for (const rowData of gridData) {
21
- const row = [];
22
- let colIndex = 0;
23
- for (const prop in rowData) {
24
- const dataType = columnMetadata[colIndex].type;
25
- const cellValue = rowData[prop];
26
- if (dataType == types_1.DataTypes.number) {
27
- if (isNaN(Number(cellValue))) {
28
- throw new Error(constants_1.invalidValueInColumnErr);
29
- }
30
- }
31
- else if (dataType == types_1.DataTypes.boolean) {
32
- if (cellValue != "1" && cellValue != "0") {
33
- throw new Error(constants_1.invalidValueInColumnErr);
34
- }
35
- }
36
- row.push(rowData[prop].toString());
37
- colIndex++;
38
- }
39
- rows.push(row);
40
- }
41
- return rows;
9
+ const columnNames = generateColumnNames(grid);
10
+ const rows = parseGridRows(grid);
11
+ return { columnNames: columnNames, rows: rows };
12
+ };
13
+ exports.parseToTableData = parseToTableData;
14
+ const parseGridRows = (grid) => {
15
+ const gridData = grid.data;
16
+ if (!gridData) {
17
+ throw new Error(constants_1.gridNotFoundErr);
42
18
  }
43
- validateGridHeader(data) {
44
- const headerData = data.header;
45
- if (!headerData) {
46
- throw new Error(constants_1.headerNotFoundErr);
19
+ const rows = [];
20
+ if (!grid.promoteHeaders) {
21
+ const row = [];
22
+ for (const prop in gridData[0]) {
23
+ const cellValue = gridData[0][prop];
24
+ row.push(cellValue.toString());
47
25
  }
48
- for (const prop in headerData) {
49
- if (!(headerData[prop].type in types_1.DataTypes)) {
50
- throw new Error(constants_1.invalidDataTypeErr);
51
- }
26
+ rows.push(row);
27
+ }
28
+ for (let i = 1; i < gridData.length; i++) {
29
+ const rowData = gridData[i];
30
+ const row = [];
31
+ for (const prop in rowData) {
32
+ const cellValue = rowData[prop];
33
+ row.push(cellValue.toString());
52
34
  }
35
+ rows.push(row);
36
+ }
37
+ return rows;
38
+ };
39
+ const generateColumnNames = (grid) => {
40
+ if (grid.promoteHeaders) {
41
+ return grid.data[0].map((columnName) => columnName.toString());
42
+ }
43
+ const columnNames = [];
44
+ for (let i = 0; i < grid.data[0].length; i++) {
45
+ columnNames.push(`Column ${i + 1}`);
53
46
  }
54
- }
55
- exports.default = GridParser;
47
+ return columnNames;
48
+ };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
- export { default as workbookManager } from "./workbookManager";
2
- export { DataTypes } from "./types";
3
- export type { QueryInfo } from "./types";
1
+ import * as workbookManager from "./workbookManager";
2
+ import { DataTypes } from "./types";
3
+ import type { QueryInfo, FileConfigs, Grid } from "./types";
4
+ export { DataTypes };
5
+ export type { QueryInfo, FileConfigs, Grid };
6
+ export default workbookManager;
package/dist/index.js CHANGED
@@ -1,12 +1,32 @@
1
1
  "use strict";
2
2
  // Copyright (c) Microsoft Corporation.
3
3
  // Licensed under the MIT license.
4
- var __importDefault = (this && this.__importDefault) || function (mod) {
5
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
17
+ }) : function(o, v) {
18
+ o["default"] = v;
19
+ });
20
+ var __importStar = (this && this.__importStar) || function (mod) {
21
+ if (mod && mod.__esModule) return mod;
22
+ var result = {};
23
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
24
+ __setModuleDefault(result, mod);
25
+ return result;
6
26
  };
7
27
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.DataTypes = exports.workbookManager = void 0;
9
- var workbookManager_1 = require("./workbookManager");
10
- Object.defineProperty(exports, "workbookManager", { enumerable: true, get: function () { return __importDefault(workbookManager_1).default; } });
11
- var types_1 = require("./types");
28
+ exports.DataTypes = void 0;
29
+ const workbookManager = __importStar(require("./workbookManager"));
30
+ const types_1 = require("./types");
12
31
  Object.defineProperty(exports, "DataTypes", { enumerable: true, get: function () { return types_1.DataTypes; } });
32
+ exports.default = workbookManager;
package/dist/types.d.ts CHANGED
@@ -17,23 +17,19 @@ export interface Metadata {
17
17
  queryName: string;
18
18
  }
19
19
  export interface TableData {
20
- columnMetadata: ColumnMetadata[];
20
+ columnNames: string[];
21
21
  rows: string[][];
22
22
  columnwidth?: number;
23
23
  }
24
- export interface ColumnMetadata {
25
- name: string;
26
- type: DataTypes;
27
- }
28
24
  export interface Grid {
29
- header: ColumnMetadata[];
30
- gridData: (string | number | boolean)[][];
25
+ data: (string | number | boolean)[][];
26
+ promoteHeaders?: boolean;
31
27
  }
32
- export interface TableDataParser {
33
- parseToTableData: (grid: any) => TableData | undefined;
28
+ export interface FileConfigs {
29
+ templateFile?: File;
30
+ docProps?: DocProps;
34
31
  }
35
32
  export declare enum DataTypes {
36
- autodetect = -1,
37
33
  null = 0,
38
34
  string = 1,
39
35
  number = 2,
package/dist/types.js CHANGED
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.DocPropsAutoUpdatedElements = exports.DocPropsModifiableElements = exports.DataTypes = void 0;
6
6
  var DataTypes;
7
7
  (function (DataTypes) {
8
- DataTypes[DataTypes["autodetect"] = -1] = "autodetect";
9
8
  DataTypes[DataTypes["null"] = 0] = "null";
10
9
  DataTypes[DataTypes["string"] = 1] = "string";
11
10
  DataTypes[DataTypes["number"] = 2] = "number";
@@ -2,7 +2,8 @@
2
2
  // Copyright (c) Microsoft Corporation.
3
3
  // Licensed under the MIT license.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.falseStr = exports.trueStr = exports.maxQueryLength = exports.divider = exports.section1PathPrefix = exports.emptyValue = exports.falseValue = exports.trueValue = exports.pivotCachesPathPrefix = exports.xmlTextResultType = exports.textResultType = exports.application = exports.uint8ArrayType = exports.blobFileType = exports.stylesNotFoundErr = exports.EmptyQueryNameErr = exports.QueryNameMaxLengthErr = exports.invalidDataTypeErr = exports.headerNotFoundErr = exports.invalidValueInColumnErr = exports.gridNotFoundErr = exports.tableNotFoundErr = exports.queryTableNotFoundErr = exports.templateWithInitialDataErr = exports.formulaSectionNotFoundErr = exports.queryConnectionNotFoundErr = exports.queryAndPivotTableNotFoundErr = exports.queryNameNotFoundErr = exports.emptyQueryMashupErr = exports.base64NotFoundErr = exports.sheetsNotFoundErr = exports.connectionsNotFoundErr = exports.sharedStringsNotFoundErr = exports.docPropsRootElement = exports.docPropsCoreXmlPath = exports.section1mPath = exports.pivotCachesPath = exports.queryTablesPath = exports.workbookXmlPath = exports.queryTableXmlPath = exports.tableXmlPath = exports.sheetsXmlPath = exports.sharedStringsXmlPath = exports.connectionsXmlPath = void 0;
5
+ exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.BOM = exports.falseStr = exports.trueStr = exports.maxQueryLength = exports.divider = exports.section1PathPrefix = exports.emptyValue = exports.falseValue = exports.trueValue = exports.pivotCachesPathPrefix = exports.xmlTextResultType = exports.textResultType = exports.application = exports.uint8ArrayType = exports.blobFileType = exports.stylesNotFoundErr = exports.EmptyQueryNameErr = exports.QueryNameMaxLengthErr = exports.invalidDataTypeErr = exports.headerNotFoundErr = exports.invalidValueInColumnErr = exports.gridNotFoundErr = exports.tableNotFoundErr = exports.queryTableNotFoundErr = exports.templateWithInitialDataErr = exports.formulaSectionNotFoundErr = exports.queryConnectionNotFoundErr = exports.queryAndPivotTableNotFoundErr = exports.queryNameNotFoundErr = exports.emptyQueryMashupErr = exports.base64NotFoundErr = exports.sheetsNotFoundErr = exports.connectionsNotFoundErr = exports.sharedStringsNotFoundErr = exports.docPropsRootElement = exports.docPropsCoreXmlPath = exports.section1mPath = exports.pivotCachesPath = exports.queryTablesPath = exports.workbookXmlPath = exports.queryTableXmlPath = exports.tableXmlPath = exports.sheetsXmlPath = exports.sharedStringsXmlPath = exports.connectionsXmlPath = void 0;
6
+ exports.URLS = void 0;
6
7
  exports.connectionsXmlPath = "xl/connections.xml";
7
8
  exports.sharedStringsXmlPath = "xl/sharedStrings.xml";
8
9
  exports.sheetsXmlPath = "xl/worksheets/sheet1.xml";
@@ -47,6 +48,7 @@ exports.divider = "/";
47
48
  exports.maxQueryLength = 80;
48
49
  exports.trueStr = "true";
49
50
  exports.falseStr = "false";
51
+ exports.BOM = '\ufeff';
50
52
  exports.element = {
51
53
  sharedStringTable: "sst",
52
54
  text: "t",
@@ -119,6 +121,7 @@ exports.elementAttributesValues = {
119
121
  };
120
122
  exports.defaults = {
121
123
  queryName: "Query1",
124
+ sheetName: "Sheet1"
122
125
  };
123
126
  exports.URLS = {
124
127
  PQ: [
@@ -55,16 +55,16 @@ const getCellReferenceRelative = (col, row) => {
55
55
  const getTableReference = (numberOfCols, numberOfRows) => {
56
56
  return `A1:${getCellReferenceRelative(numberOfCols, numberOfRows)}`;
57
57
  };
58
- const createCellElement = (doc, colIndex, rowIndex, dataType, data) => {
58
+ const createCellElement = (doc, colIndex, rowIndex, data) => {
59
59
  const cell = doc.createElementNS(doc.documentElement.namespaceURI, constants_1.element.kindCell);
60
60
  cell.setAttribute(constants_1.elementAttributes.row, getCellReferenceRelative(colIndex, rowIndex + 1));
61
61
  const cellData = doc.createElementNS(doc.documentElement.namespaceURI, constants_1.element.cellValue);
62
- updateCellData(dataType, data, cell, cellData);
62
+ updateCellData(data, cell, cellData);
63
63
  cell.appendChild(cellData);
64
64
  return cell;
65
65
  };
66
- const updateCellData = (dataType, data, cell, cellData) => {
67
- switch (resolveType(dataType, data)) {
66
+ const updateCellData = (data, cell, cellData) => {
67
+ switch (resolveType(data)) {
68
68
  case types_1.DataTypes.string:
69
69
  cell.setAttribute(constants_1.element.text, constants_1.dataTypeKind.string);
70
70
  break;
@@ -77,10 +77,7 @@ const updateCellData = (dataType, data, cell, cellData) => {
77
77
  }
78
78
  cellData.textContent = data;
79
79
  };
80
- const resolveType = (originalDataType, originalData) => {
81
- if (originalDataType !== types_1.DataTypes.autodetect) {
82
- return originalDataType;
83
- }
80
+ const resolveType = (originalData) => {
84
81
  const data = originalData;
85
82
  let dataType = isNaN(Number(data)) ? types_1.DataTypes.string : types_1.DataTypes.number;
86
83
  if (dataType == types_1.DataTypes.string) {
@@ -4,14 +4,8 @@ exports.extractTableValues = void 0;
4
4
  const extractTableValues = (table) => {
5
5
  const headers = [];
6
6
  const rows = [];
7
- // Extract headers
8
- const headerRow = table.rows[0];
9
- for (let i = 0; i < headerRow.cells.length; i++) {
10
- const cell = headerRow.cells[i];
11
- headers.push(cell.textContent || "");
12
- }
13
7
  // Extract values from each row
14
- for (let i = 1; i < table.rows.length; i++) {
8
+ for (let i = 0; i < table.rows.length; i++) {
15
9
  const row = table.rows[i];
16
10
  const rowData = [];
17
11
  for (let j = 0; j < row.cells.length; j++) {
@@ -20,6 +14,6 @@ const extractTableValues = (table) => {
20
14
  }
21
15
  rows.push(rowData);
22
16
  }
23
- return [headers, rows];
17
+ return rows;
24
18
  };
25
19
  exports.extractTableValues = extractTableValues;