@ticatec/batch-data-uploader 0.0.4 → 0.0.10

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,154 +1,107 @@
1
- # Excel Batch Data Upload Component
1
+ # Excel Data Batch Upload Processing Component / Data Recognition Component
2
2
 
3
- [[中文文档](./README_CN.md)]
3
+ ## [中文文档](./README_CN.md)
4
4
 
5
- This component is designed to batch import data from Excel files and handle uploads. It supports upload status management, exporting error rows, multilingual adaptation, data preprocessing, and more. By defining template classes and using a unified UI dialog component, it enables quick adaptation for various types of Excel data upload needs.
5
+ # @ticatec/batch-data-uploader
6
6
 
7
- ## Features
8
-
9
- * Parse `.xls` / `.xlsx` files
10
- * Custom column mapping and formatting
11
- * Batch upload with configurable batch size
12
- * Extensible data preprocessing logic (e.g., merging, grouping)
13
- * Upload status display: Pending, Uploading, Success, Failed
14
- * Export error rows to Excel
15
- * Multilingual support (based on `@ticatec/i18n`)
7
+ A universal Svelte component for batch data uploading, supporting Excel file parsing, local preprocessing, field mapping validation, multilingual prompts, import validation, and error messaging.
16
8
 
17
9
  ---
18
10
 
19
- ## Usage
20
-
21
- ### Installation
22
-
23
- ```bash
24
- npm i @ticatec/batch-data-uploader
25
- ```
26
-
27
- ### 1. Define a Template Class
28
-
29
- Extend `BaseTemplate`, provide field definitions and upload logic, and optionally override `consolidateData` to process data.
30
-
31
- ```ts
32
- import BaseUploadTemplate from '@ticatec/batch-data-uploader/BaseUploadTemplate';
33
- import type DataColumn from '@ticatec/batch-data-uploader/DataColumn';
34
-
35
- class MyDataTemplate extends BaseUploadTemplate {
36
- constructor(uploadFun: UploadFun) {
37
- const columns: DataColumn[] = [
38
- { text: 'Name', field: 'name', pos: 0 },
39
- { text: 'Email', field: 'email', pos: 1 },
40
- { text: 'Age', field: 'age', pos: 2, parser: val => parseInt(val) },
41
- ];
42
- super(columns, uploadFun, 50);
43
- }
44
-
45
- // Optional: Override to implement merge/group logic
46
- protected consolidateData(rows: Array<any>) {
47
- return super.consolidateData(rows);
48
- }
49
- }
50
- ```
11
+ ## ✨ Features
51
12
 
52
- ### 2. Use the Upload Dialog Component
53
-
54
- ```svelte
55
- <script lang="ts">
56
- import UploadDialog from './UploadDialog.svelte';
57
- import { MyDataTemplate } from './MyDataTemplate';
58
-
59
- let showDialog = false;
60
-
61
- function doUpload(rows: any[]): Promise<void> {
62
- const dataChunk = rows.map(row => row.data);
63
- return fetch('/api/upload', {
64
- method: 'POST',
65
- body: JSON.stringify(dataChunk),
66
- }).then(res => {
67
- if (!res.ok) throw new Error('Upload failed');
68
- // After upload, write result info to row.error if needed
69
- });
70
- }
71
-
72
- const template = new MyDataTemplate(doUpload);
73
-
74
- const showUploadDialog = () => {
75
- window.Dialog.showModal(UploadDialog, {
76
- title: 'Batch Add Employees',
77
- template,
78
- });
79
- }
80
- </script>
81
-
82
- <button on:click={() => showUploadDialog()}>Import Data</button>
83
- ```
13
+ - 📂 Supports drag-and-drop and file selection for uploading `.xlsx` files
14
+ - 🧠 Local parsing of Excel data without server preprocessing
15
+ - 🧩 Supports field mapping and custom parsers
16
+ - 📝 Data preview and validation with highlighted error prompts
17
+ - 🌐 Multilingual support (built-in Chinese and English)
18
+ - 🔌 Compatible with the UI element style of `@ticatec/uniface-element`
84
19
 
85
20
  ---
86
21
 
87
- ## Parameter Reference
88
-
89
- ### `BaseTemplate` Constructor Parameters
90
-
91
- | Name | Type | Description |
92
- | ----------- | ------------------------------- | -------------------------------------------- |
93
- | `columns` | `DataColumn[]` | Defines column position and format |
94
- | `uploadFun` | `(arr: any[]) => Promise<void>` | Upload function, called in batches |
95
- | `batchSize` | `number` (default: 50) | Number of rows per upload batch |
96
- | `rowOffset` | `number` (default: 1) | Row offset for data start (e.g. skip header) |
22
+ ## 📦 Installation
97
23
 
98
- ### `DataColumn` Interface
99
-
100
- ```ts
101
- interface DataColumn {
102
- text: string; // Column display text
103
- field: string; // Data field path (supports nesting)
104
- pos: number; // Excel column index (starting from 0)
105
- parser?: (val: any) => any; // Optional parser function for cell values
106
- }
24
+ ```bash
25
+ npm install @ticatec/batch-data-uploader xlsx
107
26
  ```
108
27
 
109
28
  ---
110
29
 
111
- ## Upload Workflow
30
+ ## 📁 Project Structure
112
31
 
113
- 1. User selects an Excel file
114
- 2. Call `BaseTemplate.parseExcelFile(file)` to parse data
115
- 3. Display preview data table with `Pending` status
116
- 4. User clicks upload, system calls `uploadFun` in batches
117
- 5. Mark successful items, retain `error` info for failed items
118
- 6. Failed rows can be exported to Excel
32
+ The main components and classes are as follows:
119
33
 
120
- ---
121
-
122
- ## Exporting Error Data
123
-
124
- Use `BaseTemplate.exportErrorRowsToExcel(filename: string)` to export rows with errors as an Excel file, including original columns and error messages.
34
+ | File | Description |
35
+ | -------------------------- | ----------------------------------------------------- |
36
+ | `FileUploadWizard.svelte` | Main upload dialog, uses `BaseUploadTemplate` to upload and validate data |
37
+ | `EncodingWizard.svelte` | Field mapping dialog, uses `BaseEncodingTemplate` to map Excel fields |
38
+ | `BaseTemplate.ts` | Abstract base class encapsulating Excel parsing and column definition logic |
39
+ | `BaseUploadTemplate.ts` | Upload template base class for validation, preprocessing, and data uploading |
40
+ | `BaseEncodingTemplate.ts` | Encoding template base class for dynamic field mapping and transformation |
41
+ | `utils.ts` | Utility functions, such as `setNestedValue` and `getNestedValue` |
42
+ | `i18n_resources` | Multilingual resource definitions, supporting Chinese and English switching |
125
43
 
126
44
  ---
127
45
 
128
- ## Customization Options
129
-
130
- * **Custom Column Display**: Define column fields and formatting functions
131
- * **Custom Status Field**: Built-in `status` column, can be customized per business needs
132
- * **Data Cleaning & Validation**: Implement in `consolidateData()` method
133
- * **Multilingual Text**: Use `getI18nText` from `@ticatec/i18n`
46
+ ## 🚀 Usage
47
+
48
+ ### Batch Data Upload
49
+
50
+ [Implementing Batch Data Upload](./documents/FileUploadWizard.md)
51
+
52
+ ### Data Parsing and Validation
53
+
54
+ [Implementing Data Parsing and Validation](./documents/EncodingWizard.md)
55
+
56
+ ## 🌐 Multilingual Support
57
+
58
+ By leveraging `@ticatec/i18n` and `i18n_resources`, automatic switching between Chinese and English is supported. You can customize internationalization by extending `i18nKeys` and resource files.
59
+
60
+ English resource file, loadable via i18n tools:
61
+
62
+ ```json
63
+ {
64
+ "batchUploading": {
65
+ "status": {
66
+ "pending": "To upload",
67
+ "uploading": "Uploading...",
68
+ "successful": "Success",
69
+ "fail": "Failure"
70
+ },
71
+ "parsing": "Parsing file...",
72
+ "parseFailure": "Cannot parse file: {{name}}",
73
+ "waitUploading": "Cannot exit during uploading!",
74
+ "button": {
75
+ "upload": "Upload",
76
+ "save": "Save error data",
77
+ "open": "Open",
78
+ "confirm": "Confirm"
79
+ },
80
+ "errorTitle": "Error",
81
+ "sheetName": "Abnormal data",
82
+ "labelStatus": "Status",
83
+ "labelValid": "Validity",
84
+ "textValid": "Yes",
85
+ "textInvalid": "No"
86
+ }
87
+ }
88
+ ```
134
89
 
135
90
  ---
136
91
 
137
- ## Dependencies
92
+ ## 🧪 Examples
138
93
 
139
- * [`xlsx`](https://www.npmjs.com/package/xlsx)
140
- * [`@ticatec/uniface-element`](https://www.npmjs.com/package/@ticatec/uniface-element)
141
- * [`@ticatec/i18n`](https://www.npmjs.com/package/@ticatec/i18n)
94
+ Refer to the `src/routes/+page.svelte` example page for a complete usage flow and template definitions.
142
95
 
143
96
  ---
144
97
 
145
- ## License
98
+ ## 🪪 License
146
99
 
147
- MIT License.
100
+ MIT License © Ticatec
148
101
 
149
102
  ---
150
103
 
151
104
  ## Author
152
105
 
153
- Henry Feng
154
- [huili.f@gmail.com](mailto:huili.f@gmail.com)
106
+ Henry Feng
107
+ huili.f@gmail.com
@@ -0,0 +1,30 @@
1
+ import BaseTemplate from "./BaseTemplate";
2
+ import type DataColumn from "./DataColumn";
3
+ import type { DataColumn as TableColumn } from "@ticatec/uniface-element/DataTable";
4
+ export default abstract class BaseEncodingTemplate extends BaseTemplate {
5
+ private validColumn;
6
+ protected constructor(columns: Array<DataColumn>, rowOffset?: number);
7
+ /**
8
+ * 检查一行的数据是否合法
9
+ * @param row
10
+ * @protected
11
+ */
12
+ protected abstract isDataValid(row: any): boolean;
13
+ /**
14
+ *
15
+ * @param rows
16
+ * @protected
17
+ */
18
+ protected abstract encodeData(rows: Array<any>): Promise<Array<any>>;
19
+ /**
20
+ * 数据集是否有效
21
+ */
22
+ abstract get valid(): boolean;
23
+ /**
24
+ * 从服务器抓取数据,然后根据主键进行数据合并
25
+ * @param rows
26
+ * @protected
27
+ */
28
+ protected consolidateData(rows: Array<any>): Promise<Array<any>>;
29
+ get columns(): Array<TableColumn>;
30
+ }
@@ -0,0 +1,34 @@
1
+ import BaseTemplate from "./BaseTemplate";
2
+ import { getI18nText } from "@ticatec/i18n";
3
+ import i18nKeys from "./i18n_resources/i18nKeys";
4
+ const ValidData = `<span style="color: #76FF03">${getI18nText(i18nKeys.textValid)}</span>`;
5
+ const InvalidData = `<span style="color: #ff3e00">${getI18nText(i18nKeys.textInvalid)}</span>`;
6
+ export default class BaseEncodingTemplate extends BaseTemplate {
7
+ validColumn = {
8
+ text: getI18nText(i18nKeys.labelValid),
9
+ width: 90,
10
+ align: 'center',
11
+ escapeHTML: true,
12
+ formatter: row => this.isDataValid(row) ? ValidData : InvalidData
13
+ };
14
+ constructor(columns, rowOffset = 1) {
15
+ super(columns, rowOffset);
16
+ }
17
+ /**
18
+ * 从服务器抓取数据,然后根据主键进行数据合并
19
+ * @param rows
20
+ * @protected
21
+ */
22
+ async consolidateData(rows) {
23
+ let list = await this.encodeData(this.extractData(rows));
24
+ rows.forEach((item, idx) => {
25
+ if (list[idx]) {
26
+ rows[idx] = { ...item, ...list[idx] };
27
+ }
28
+ });
29
+ return rows;
30
+ }
31
+ get columns() {
32
+ return [...this._columns, this.validColumn];
33
+ }
34
+ }
@@ -22,6 +22,11 @@ export default abstract class BaseTemplate {
22
22
  * @param file
23
23
  */
24
24
  parseExcelFile(file: File): Promise<void>;
25
+ /**
26
+ * 获取实际待上传的数据
27
+ * @param arr
28
+ */
29
+ protected extractData(arr: Array<any>): any[];
25
30
  /**
26
31
  * 包裹数据
27
32
  * @param data
@@ -34,8 +34,9 @@ export default class BaseTemplate {
34
34
  const rows = [];
35
35
  for (let rowIndex = range.s.r + this.rowOffset; rowIndex <= range.e.r; rowIndex++) {
36
36
  const rowObject = {};
37
- for (const colDef of this._columns) {
38
- const cellAddress = { r: rowIndex, c: colDef.pos };
37
+ for (let i = 0; i < this._columns.length; i++) {
38
+ const colDef = this._columns[i];
39
+ const cellAddress = { r: rowIndex, c: i };
39
40
  const cellRef = XLSX.utils.encode_cell(cellAddress);
40
41
  const cell = sheet[cellRef];
41
42
  const rawValue = cell?.v;
@@ -46,6 +47,22 @@ export default class BaseTemplate {
46
47
  }
47
48
  this._list = await this.consolidateData(rows);
48
49
  }
50
+ /**
51
+ * 获取实际待上传的数据
52
+ * @param arr
53
+ */
54
+ extractData(arr) {
55
+ let list = arr.map(item => {
56
+ let result = {};
57
+ for (let col of this._columns) {
58
+ if (col.visible != false && col.ignore != false) {
59
+ utils.setNestedValue(result, col.field, utils.getNestedValue(item.data, col.field));
60
+ }
61
+ }
62
+ return result;
63
+ });
64
+ return list;
65
+ }
49
66
  /**
50
67
  * 包裹数据
51
68
  * @param data
@@ -1,18 +1,18 @@
1
1
  import BaseTemplate from "./BaseTemplate";
2
2
  import type { DataColumn as TableColumn } from "@ticatec/uniface-element/DataTable";
3
3
  import type DataColumn from "./DataColumn";
4
- export type UploadFun = (arr: Array<any>) => Promise<void>;
4
+ export type UploadFun = (arr: Array<any>) => Promise<Array<any>>;
5
5
  export type UpdateProgressStatus = () => void;
6
6
  export default abstract class BaseUploadTemplate extends BaseTemplate {
7
- protected uploadFun: UploadFun;
8
7
  protected batchSize: number;
9
8
  protected updateProgressStatus: UpdateProgressStatus | null;
10
- protected constructor(columns: Array<DataColumn>, uploadFun: UploadFun, batchSize?: number, rowOffset?: number);
9
+ protected constructor(columns: Array<DataColumn>, batchSize?: number, rowOffset?: number);
11
10
  /**
12
11
  * 状态更新的监听器
13
12
  * @param value
14
13
  */
15
14
  setProgressStatusListener(value: UpdateProgressStatus): void;
15
+ protected abstract uploadData(list: Array<any>): Promise<Array<any>>;
16
16
  /**
17
17
  * 上传数据
18
18
  */
@@ -4,8 +4,8 @@ import i18nKeys from "./i18n_resources/i18nKeys";
4
4
  import utils from "./utils";
5
5
  import * as XLSX from 'xlsx';
6
6
  const statusColumn = {
7
- text: "status",
8
- width: 150,
7
+ text: getI18nText(i18nKeys.labelStatus),
8
+ width: 240,
9
9
  resizable: true,
10
10
  formatter: row => {
11
11
  if (row.status == 'P') {
@@ -25,13 +25,10 @@ const statusColumn = {
25
25
  }
26
26
  };
27
27
  export default class BaseUploadTemplate extends BaseTemplate {
28
- uploadFun;
29
28
  batchSize;
30
29
  updateProgressStatus = null;
31
- constructor(columns, uploadFun, batchSize = 50, rowOffset = 1) {
30
+ constructor(columns, batchSize = 50, rowOffset = 1) {
32
31
  super(columns, rowOffset);
33
- ;
34
- this.uploadFun = uploadFun;
35
32
  this.batchSize = batchSize;
36
33
  }
37
34
  /**
@@ -45,12 +42,20 @@ export default class BaseUploadTemplate extends BaseTemplate {
45
42
  * 上传数据
46
43
  */
47
44
  async upload() {
48
- for (let i = 0; i < this.list.length; i += this.batchSize) {
49
- const chunk = this.list.slice(i, i + this.batchSize);
45
+ for (let i = 0; i < this._list.length; i += this.batchSize) {
46
+ const chunk = this._list.slice(i, i + this.batchSize);
50
47
  chunk.forEach(item => item.status = 'U');
51
48
  this.updateProgressStatus?.();
52
- await this.uploadFun(chunk);
53
- chunk.forEach(item => item.status = 'D');
49
+ let list = await this.uploadData(this.extractData(chunk));
50
+ for (let j = 0; j < chunk.length; j++) {
51
+ this._list[i + j].status = 'D';
52
+ if (list[j]) {
53
+ if (list[j].error) {
54
+ this._list[i + j].error = list[j].error;
55
+ this._list[i + j].errorText = list[j].errorText;
56
+ }
57
+ }
58
+ }
54
59
  this.updateProgressStatus?.();
55
60
  }
56
61
  }
@@ -2,13 +2,13 @@ import type { DataColumn as TableColumn } from "@ticatec/uniface-element/DataTab
2
2
  export type ParserText = (text: string) => any;
3
3
  export default interface DataColumn extends TableColumn {
4
4
  /**
5
- * 在excel中的列号
5
+ * 字段名
6
6
  */
7
- pos: number;
7
+ field: string;
8
8
  /**
9
- * 对于的字段名
9
+ * 是否忽略,上传的时候不采用,仅用于前台显示
10
10
  */
11
- field: string;
11
+ ignore?: boolean;
12
12
  /**
13
13
  * 解析函数
14
14
  */
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import Dialog from "@ticatec/uniface-element/Dialog";
3
+ import type {ButtonAction, ButtonActions} from "@ticatec/uniface-element/ActionBar";
4
+ import DataTable, {type IndicatorColumn} from "@ticatec/uniface-element/DataTable";
5
+ import {getI18nText} from "@ticatec/i18n";
6
+ import Box from "@ticatec/uniface-element/Box"
7
+ import {onMount} from "svelte";
8
+ import type DataColumn from "./DataColumn";
9
+ import i18nKeys from "./i18n_resources/i18nKeys";
10
+ import type BaseEncodingTemplate from "./BaseEncodingTemplate";
11
+
12
+ export let title: string;
13
+ export let width: string = "800px";
14
+ export let height: string = "600px"
15
+ export let closeHandler: any;
16
+ export let template: BaseEncodingTemplate;
17
+ export let confirmCallback: any;
18
+
19
+
20
+ const btnChoose: ButtonAction = {
21
+ label: getI18nText(i18nKeys.button.open),
22
+ type: 'primary',
23
+ handler: () => {
24
+ uploadField.value = '';
25
+ uploadField.click();
26
+ }
27
+ }
28
+
29
+ const btnConfirm: ButtonAction = {
30
+ label: getI18nText(i18nKeys.button.confirm),
31
+ type: 'primary',
32
+ handler: ()=> {
33
+ confirmCallback?.(template.list);
34
+ closeHandler?.();
35
+ }
36
+ }
37
+
38
+ let actions: ButtonActions = [btnChoose];
39
+ let uploadField: any;
40
+ let list: Array<any> = [];
41
+ let filename: string;
42
+
43
+ const parseExcelFile = async (excelFile: File) => {
44
+ if (excelFile) {
45
+ filename = excelFile.name;
46
+ window.Indicator.show(getI18nText(i18nKeys.parsing));
47
+ try {
48
+ await template.parseExcelFile(excelFile);
49
+ list = template.list;
50
+ if (template.valid) {
51
+ actions = [btnConfirm, ...actions]
52
+ }
53
+ } catch (ex) {
54
+ window.Toast.show(getI18nText(i18nKeys.parseFailure, {name: excelFile.name}));
55
+ } finally {
56
+ window.Indicator.hide();
57
+ }
58
+ }
59
+ }
60
+
61
+
62
+ let columns: Array<DataColumn>;
63
+
64
+ onMount(async () => {
65
+ columns = template.columns;
66
+ });
67
+
68
+
69
+ const indicatorColumn: IndicatorColumn = {
70
+ width: 40,
71
+ selectable: false,
72
+ displayNo: true
73
+ }
74
+
75
+
76
+ </script>
77
+
78
+ <Dialog {title} {closeHandler} {actions}
79
+ content$style="width: {width}; height: {height}; padding: 12px;">
80
+ <Box style="border: 1px solid var(--uniface-editor-border-color, #F8FAFC); width: 100%; height: 100%; "
81
+ round>
82
+ <DataTable style="width: 100%; height: 100%" {list} {indicatorColumn} {columns}>
83
+
84
+ </DataTable>
85
+ </Box>
86
+ <input type="file" bind:this={uploadField} on:change={(e) => parseExcelFile(e.target.files?.[0])} style="display: none"
87
+ accept=".xls,.xlsx,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
88
+
89
+ </Dialog>
@@ -0,0 +1,26 @@
1
+ import type BaseEncodingTemplate from "./BaseEncodingTemplate";
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: Props & {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const EncodingWizard: $$__sveltets_2_IsomorphicComponent<{
16
+ title: string;
17
+ width?: string;
18
+ height?: string;
19
+ closeHandler: any;
20
+ template: BaseEncodingTemplate;
21
+ confirmCallback: any;
22
+ }, {
23
+ [evt: string]: CustomEvent<any>;
24
+ }, {}, {}, string>;
25
+ type EncodingWizard = InstanceType<typeof EncodingWizard>;
26
+ export default EncodingWizard;
@@ -2,21 +2,19 @@
2
2
  import Dialog from "@ticatec/uniface-element/Dialog";
3
3
  import type {ButtonAction, ButtonActions} from "@ticatec/uniface-element/ActionBar";
4
4
  import DataTable, {type IndicatorColumn} from "@ticatec/uniface-element/DataTable";
5
- import i18n, {getI18nText} from "@ticatec/i18n";
5
+ import {getI18nText} from "@ticatec/i18n";
6
6
  import Box from "@ticatec/uniface-element/Box"
7
7
  import {onMount} from "svelte";
8
- import type BaseTemplate from "./BaseTemplate";
9
- import type DataColumn from "@ticatec/uniface-element/DataTable";
8
+ import type DataColumn from "./DataColumn";
10
9
  import i18nKeys from "./i18n_resources/i18nKeys";
11
10
  import type BaseUploadTemplate from "./BaseUploadTemplate.js";
12
11
 
13
12
  export let title: string;
14
-
15
13
  export let width: string = "800px";
16
14
  export let height: string = "600px"
17
-
18
15
  export let closeHandler: any;
19
16
  export let template: BaseUploadTemplate;
17
+ export let afterUploaded: ()=>Promise<void>;
20
18
 
21
19
  type ProcessStatus = 'Init' | 'Pending' | 'Uploading' | 'Done'; //初始状态,待上传,上传中,处理完成
22
20
 
@@ -27,6 +25,7 @@
27
25
  label: getI18nText(i18nKeys.button.open),
28
26
  type: 'primary',
29
27
  handler: () => {
28
+ uploadField.value = '';
30
29
  uploadField.click();
31
30
  }
32
31
  }
@@ -38,6 +37,7 @@
38
37
  status = 'Uploading';
39
38
  try {
40
39
  await template.upload();
40
+ await afterUploaded?.();
41
41
  } finally {
42
42
  status = 'Done';
43
43
  }
@@ -58,16 +58,18 @@
58
58
  let filename: string;
59
59
 
60
60
  const parseExcelFile = async (excelFile: File) => {
61
- filename = excelFile.name;
62
- window.Indicator.show(getI18nText(i18nKeys.parsing));
63
- try {
64
- await template.parseExcelFile(excelFile);
65
- list = template.list;
66
- status = list.length > 0 ? 'Pending' : 'Init';
67
- } catch (ex) {
68
- window.Toast.show(getI18nText(i18nKeys.parseFailure, {name: excelFile.name}));
69
- } finally {
70
- window.Indicator.hide();
61
+ if (excelFile) {
62
+ filename = excelFile.name;
63
+ window.Indicator.show(getI18nText(i18nKeys.parsing));
64
+ try {
65
+ await template.parseExcelFile(excelFile);
66
+ list = template.list;
67
+ status = list.length > 0 ? 'Pending' : 'Init';
68
+ } catch (ex) {
69
+ window.Toast.show(getI18nText(i18nKeys.parseFailure, {name: excelFile.name}));
70
+ } finally {
71
+ window.Indicator.hide();
72
+ }
71
73
  }
72
74
  }
73
75
 
@@ -84,7 +86,7 @@
84
86
 
85
87
 
86
88
  const indicatorColumn: IndicatorColumn = {
87
- width: 60,
89
+ width: 40,
88
90
  selectable: false,
89
91
  displayNo: true
90
92
  }
@@ -18,6 +18,7 @@ declare const FileUploadWizard: $$__sveltets_2_IsomorphicComponent<{
18
18
  height?: string;
19
19
  closeHandler: any;
20
20
  template: BaseUploadTemplate;
21
+ afterUploaded: () => Promise<void>;
21
22
  }, {
22
23
  [evt: string]: CustomEvent<any>;
23
24
  }, {}, {}, string>;
@@ -16,6 +16,7 @@ declare const langRes: {
16
16
  };
17
17
  errorTitle: string;
18
18
  sheetName: string;
19
+ labelStatus: string;
19
20
  };
20
21
  };
21
22
  export default langRes;
@@ -15,7 +15,8 @@ const langRes = {
15
15
  open: '文件'
16
16
  },
17
17
  errorTitle: '异常原因',
18
- sheetName: '错误数据'
18
+ sheetName: '错误数据',
19
+ labelStatus: "状态"
19
20
  }
20
21
  };
21
22
  export default langRes;
@@ -13,9 +13,14 @@ declare const langRes: {
13
13
  upload: string;
14
14
  save: string;
15
15
  open: string;
16
+ confirm: string;
16
17
  };
17
18
  errorTitle: string;
18
19
  sheetName: string;
20
+ labelStatus: string;
21
+ labelValid: string;
22
+ textValid: string;
23
+ textInvalid: string;
19
24
  };
20
25
  };
21
26
  export default langRes;