amis 1.8.0-beta.13 → 1.8.0-beta.17

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.
Files changed (120) hide show
  1. package/lib/WithStore.js +1 -1
  2. package/lib/WithStore.js.map +2 -2
  3. package/lib/components/DatePicker.js +3 -1
  4. package/lib/components/DatePicker.js.map +2 -2
  5. package/lib/components/Progress.js +3 -4
  6. package/lib/components/Progress.js.map +2 -2
  7. package/lib/components/TabsTransfer.d.ts +22 -3
  8. package/lib/components/TabsTransfer.js +149 -42
  9. package/lib/components/TabsTransfer.js.map +2 -2
  10. package/lib/components/Tree.js +3 -1
  11. package/lib/components/Tree.js.map +2 -2
  12. package/lib/components/formula/Editor.js +4 -4
  13. package/lib/components/formula/Editor.js.map +2 -2
  14. package/lib/components/formula/VariableList.d.ts +63 -4
  15. package/lib/components/formula/VariableList.js +23 -8
  16. package/lib/components/formula/VariableList.js.map +2 -2
  17. package/lib/helper.css +1 -1
  18. package/lib/helper.css.map +1 -1
  19. package/lib/index.js +1 -1
  20. package/lib/renderers/Date.js +6 -1
  21. package/lib/renderers/Date.js.map +2 -2
  22. package/lib/renderers/Form/NestedSelect.d.ts +1 -1
  23. package/lib/renderers/Form/NestedSelect.js +7 -2
  24. package/lib/renderers/Form/NestedSelect.js.map +2 -2
  25. package/lib/renderers/Form/TabsTransfer.d.ts +6 -1
  26. package/lib/renderers/Form/TabsTransfer.js +155 -6
  27. package/lib/renderers/Form/TabsTransfer.js.map +2 -2
  28. package/lib/renderers/Form/TabsTransferPicker.d.ts +2 -2
  29. package/lib/renderers/Form/TabsTransferPicker.js +4 -4
  30. package/lib/renderers/Form/TabsTransferPicker.js.map +2 -2
  31. package/lib/renderers/Form/TreeSelect.js.map +2 -2
  32. package/lib/renderers/Form/index.js +6 -2
  33. package/lib/renderers/Form/index.js.map +2 -2
  34. package/lib/renderers/Markdown.js +4 -3
  35. package/lib/renderers/Markdown.js.map +2 -2
  36. package/lib/renderers/Nav.d.ts +21 -20
  37. package/lib/renderers/Nav.js +8 -1
  38. package/lib/renderers/Nav.js.map +2 -2
  39. package/lib/renderers/Page.js +1 -1
  40. package/lib/renderers/Page.js.map +2 -2
  41. package/lib/renderers/Service.js +1 -1
  42. package/lib/renderers/Service.js.map +2 -2
  43. package/lib/renderers/Table/exportExcel.d.ts +6 -0
  44. package/lib/renderers/Table/exportExcel.js +288 -0
  45. package/lib/renderers/Table/exportExcel.js.map +13 -0
  46. package/lib/renderers/Table/index.d.ts +1 -1
  47. package/lib/renderers/Table/index.js +4 -251
  48. package/lib/renderers/Table/index.js.map +2 -2
  49. package/lib/themes/ang-ie11.css +112 -36
  50. package/lib/themes/ang.css +100 -21
  51. package/lib/themes/ang.css.map +1 -1
  52. package/lib/themes/antd-ie11.css +112 -36
  53. package/lib/themes/antd.css +100 -21
  54. package/lib/themes/antd.css.map +1 -1
  55. package/lib/themes/cxd-ie11.css +97 -21
  56. package/lib/themes/cxd.css +100 -21
  57. package/lib/themes/cxd.css.map +1 -1
  58. package/lib/themes/dark-ie11.css +112 -36
  59. package/lib/themes/dark.css +100 -21
  60. package/lib/themes/dark.css.map +1 -1
  61. package/lib/themes/default-ie11.css +97 -21
  62. package/lib/themes/default.css +100 -21
  63. package/lib/themes/default.css.map +1 -1
  64. package/lib/utils/api.js +35 -6
  65. package/lib/utils/api.js.map +2 -2
  66. package/package.json +1 -1
  67. package/schema.json +1 -1
  68. package/scss/_properties.scss +4 -0
  69. package/scss/components/_formula.scss +77 -12
  70. package/scss/components/_progress.scss +2 -7
  71. package/scss/components/form/_date.scss +1 -0
  72. package/scss/components/form/_transfer.scss +21 -0
  73. package/scss/helper/layout/_display.scss +1 -1
  74. package/sdk/ang-ie11.css +130 -36
  75. package/sdk/ang.css +118 -21
  76. package/sdk/antd-ie11.css +130 -36
  77. package/sdk/antd.css +118 -21
  78. package/sdk/barcode.js +51 -51
  79. package/sdk/charts.js +14 -14
  80. package/sdk/codemirror.js +7 -7
  81. package/sdk/color-picker.js +65 -65
  82. package/sdk/cropperjs.js +2 -2
  83. package/sdk/cxd-ie11.css +115 -21
  84. package/sdk/cxd.css +118 -21
  85. package/sdk/dark-ie11.css +130 -36
  86. package/sdk/dark.css +118 -21
  87. package/sdk/exceljs.js +1 -1
  88. package/sdk/helper.css +1 -1
  89. package/sdk/helper.css.map +1 -1
  90. package/sdk/markdown.js +69 -69
  91. package/sdk/papaparse.js +1 -1
  92. package/sdk/renderers/Form/CityDB.js +1 -1
  93. package/sdk/rest.js +17 -17
  94. package/sdk/rich-text.js +62 -62
  95. package/sdk/sdk-ie11.css +115 -21
  96. package/sdk/sdk.css +118 -21
  97. package/sdk/sdk.js +1270 -1268
  98. package/sdk/thirds/hls.js/hls.js +1 -1
  99. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  100. package/sdk/tinymce.js +57 -57
  101. package/src/WithStore.tsx +1 -1
  102. package/src/components/DatePicker.tsx +2 -1
  103. package/src/components/Progress.tsx +6 -4
  104. package/src/components/TabsTransfer.tsx +253 -143
  105. package/src/components/Tree.tsx +3 -1
  106. package/src/components/formula/Editor.tsx +12 -5
  107. package/src/components/formula/VariableList.tsx +55 -21
  108. package/src/renderers/Date.tsx +14 -1
  109. package/src/renderers/Form/NestedSelect.tsx +11 -2
  110. package/src/renderers/Form/TabsTransfer.tsx +174 -11
  111. package/src/renderers/Form/TabsTransferPicker.tsx +5 -10
  112. package/src/renderers/Form/TreeSelect.tsx +15 -12
  113. package/src/renderers/Form/index.tsx +37 -16
  114. package/src/renderers/Markdown.tsx +4 -5
  115. package/src/renderers/Nav.tsx +7 -1
  116. package/src/renderers/Page.tsx +9 -2
  117. package/src/renderers/Service.tsx +8 -2
  118. package/src/renderers/Table/exportExcel.ts +289 -0
  119. package/src/renderers/Table/index.tsx +5 -252
  120. package/src/utils/api.ts +42 -10
@@ -0,0 +1,289 @@
1
+ /**
2
+ * 导出 Excel 功能
3
+ */
4
+
5
+ import {filter} from '../../utils/tpl';
6
+ import './ColumnToggler';
7
+ import {TableStore} from '../../store/table';
8
+ import {saveAs} from 'file-saver';
9
+ import {getVariable, removeHTMLTag, createObject} from '../../utils/helper';
10
+ import {
11
+ isPureVariable,
12
+ resolveVariableAndFilter
13
+ } from '../../utils/tpl-builtin';
14
+ import {BaseSchema} from '../../Schema';
15
+ import {toDataURL, getImageDimensions} from '../../utils/image';
16
+ import {TplSchema} from '../Tpl';
17
+ import {MappingSchema} from '../Mapping';
18
+ import {getSnapshot} from 'mobx-state-tree';
19
+ import {DateSchema} from '../Date';
20
+ import moment from 'moment';
21
+ import type {TableProps, ExportExcelToolbar} from './index';
22
+
23
+ /**
24
+ * 将 url 转成绝对地址
25
+ */
26
+ const getAbsoluteUrl = (function () {
27
+ let link: HTMLAnchorElement;
28
+ return function (url: string) {
29
+ if (!link) link = document.createElement('a');
30
+ link.href = url;
31
+ return link.href;
32
+ };
33
+ })();
34
+
35
+ export async function exportExcel(
36
+ ExcelJS: any,
37
+ props: TableProps,
38
+ toolbar: ExportExcelToolbar
39
+ ) {
40
+ const {store, env, classnames: cx, translate: __, data} = props;
41
+ let columns = store.filteredColumns || [];
42
+
43
+ let rows = [];
44
+ let tmpStore;
45
+ let filename = 'data';
46
+ // 支持配置 api 远程获取
47
+ if (typeof toolbar === 'object' && toolbar.api) {
48
+ const res = await env.fetcher(toolbar.api, data);
49
+ if (!res.data) {
50
+ env.notify('warning', __('placeholder.noData'));
51
+ return;
52
+ }
53
+ if (Array.isArray(res.data)) {
54
+ rows = res.data;
55
+ } else {
56
+ rows = res.data.rows || res.data.items;
57
+ }
58
+ // 因为很多方法是 store 里的,所以需要构建 store 来处理
59
+ tmpStore = TableStore.create(getSnapshot(store));
60
+ tmpStore.initRows(rows);
61
+ rows = tmpStore.rows;
62
+ } else {
63
+ rows = store.rows;
64
+ }
65
+
66
+ if (typeof toolbar === 'object' && toolbar.filename) {
67
+ filename = filter(toolbar.filename, data, '| raw');
68
+ }
69
+
70
+ if (rows.length === 0) {
71
+ env.notify('warning', __('placeholder.noData'));
72
+ return;
73
+ }
74
+
75
+ const workbook = new ExcelJS.Workbook();
76
+ const worksheet = workbook.addWorksheet('sheet', {
77
+ properties: {defaultColWidth: 15}
78
+ });
79
+ worksheet.views = [{state: 'frozen', xSplit: 0, ySplit: 1}];
80
+
81
+ let exportColumnNames = toolbar.columns;
82
+
83
+ if (isPureVariable(exportColumnNames)) {
84
+ exportColumnNames = resolveVariableAndFilter(
85
+ exportColumnNames,
86
+ data,
87
+ '| raw'
88
+ );
89
+ }
90
+
91
+ // 自定义导出列配置
92
+ if (toolbar.exportColumns && Array.isArray(toolbar.exportColumns)) {
93
+ columns = toolbar.exportColumns;
94
+ }
95
+
96
+ const filteredColumns = exportColumnNames
97
+ ? columns.filter(column => {
98
+ const filterColumnsNames = exportColumnNames!;
99
+ if (column.name && filterColumnsNames.indexOf(column.name) !== -1) {
100
+ return true;
101
+ }
102
+ return false;
103
+ })
104
+ : columns;
105
+
106
+ const firstRowLabels = filteredColumns.map(column => {
107
+ return column.label;
108
+ });
109
+ const firstRow = worksheet.getRow(1);
110
+ firstRow.values = firstRowLabels;
111
+ worksheet.autoFilter = {
112
+ from: {
113
+ row: 1,
114
+ column: 1
115
+ },
116
+ to: {
117
+ row: 1,
118
+ column: firstRowLabels.length
119
+ }
120
+ };
121
+ // 用于 mapping source 的情况
122
+ const remoteMappingCache: any = {};
123
+ // 数据从第二行开始
124
+ let rowIndex = 1;
125
+ for (const row of rows) {
126
+ rowIndex += 1;
127
+ const sheetRow = worksheet.getRow(rowIndex);
128
+ let columIndex = 0;
129
+ for (const column of filteredColumns) {
130
+ columIndex += 1;
131
+ const name = column.name!;
132
+ const value = getVariable(row.data, name);
133
+ if (typeof value === 'undefined' && !(column as TplSchema).tpl) {
134
+ continue;
135
+ }
136
+ // 处理合并单元格
137
+ if (name in row.rowSpans) {
138
+ if (row.rowSpans[name] === 0) {
139
+ continue;
140
+ } else {
141
+ // start row, start column, end row, end column
142
+ worksheet.mergeCells(
143
+ rowIndex,
144
+ columIndex,
145
+ rowIndex + row.rowSpans[name] - 1,
146
+ columIndex
147
+ );
148
+ }
149
+ }
150
+
151
+ const type = (column as BaseSchema).type || 'plain';
152
+ // TODO: 这里很多组件都是拷贝对应渲染的逻辑实现的,导致
153
+ if (type === 'image' && value) {
154
+ try {
155
+ const imageData = await toDataURL(value);
156
+ const imageDimensions = await getImageDimensions(imageData);
157
+ let imageWidth = imageDimensions.width;
158
+ let imageHeight = imageDimensions.height;
159
+ // 限制一下图片高宽
160
+ const imageMaxSize = 100;
161
+ if (imageWidth > imageHeight) {
162
+ if (imageWidth > imageMaxSize) {
163
+ imageHeight = (imageMaxSize * imageHeight) / imageWidth;
164
+ imageWidth = imageMaxSize;
165
+ }
166
+ } else {
167
+ if (imageHeight > imageMaxSize) {
168
+ imageWidth = (imageMaxSize * imageWidth) / imageHeight;
169
+ imageHeight = imageMaxSize;
170
+ }
171
+ }
172
+ const imageMatch = imageData.match(/data:image\/(.*);/);
173
+ let imageExt = 'png';
174
+ if (imageMatch) {
175
+ imageExt = imageMatch[1];
176
+ }
177
+ // 目前 excel 只支持这些格式,所以其它格式直接输出 url
178
+ if (imageExt != 'png' && imageExt != 'jpeg' && imageExt != 'gif') {
179
+ sheetRow.getCell(columIndex).value = value;
180
+ continue;
181
+ }
182
+ const imageId = workbook.addImage({
183
+ base64: imageData,
184
+ extension: imageExt
185
+ });
186
+ const linkURL = getAbsoluteUrl(value);
187
+ worksheet.addImage(imageId, {
188
+ // 这里坐标位置是从 0 开始的,所以要减一
189
+ tl: {col: columIndex - 1, row: rowIndex - 1},
190
+ ext: {
191
+ width: imageWidth,
192
+ height: imageHeight
193
+ },
194
+ hyperlinks: {
195
+ tooltip: linkURL
196
+ }
197
+ });
198
+ } catch (e) {
199
+ console.warn(e.stack);
200
+ }
201
+ } else if (type == 'link') {
202
+ const linkURL = getAbsoluteUrl(value);
203
+ sheetRow.getCell(columIndex).value = {
204
+ text: value,
205
+ hyperlink: linkURL
206
+ };
207
+ } else if (type === 'mapping') {
208
+ // 拷贝自 Mapping.tsx
209
+ let map = (column as MappingSchema).map;
210
+ const source = (column as MappingSchema).source;
211
+ if (source) {
212
+ let sourceValue = source;
213
+ if (isPureVariable(source)) {
214
+ sourceValue = resolveVariableAndFilter(
215
+ source as string,
216
+ data,
217
+ '| raw'
218
+ );
219
+ }
220
+
221
+ const mapKey = JSON.stringify(source);
222
+ if (mapKey in remoteMappingCache) {
223
+ map = remoteMappingCache[mapKey];
224
+ } else {
225
+ const res = await env.fetcher(sourceValue, data);
226
+ if (res.data) {
227
+ remoteMappingCache[mapKey] = res.data;
228
+ map = res.data;
229
+ }
230
+ }
231
+ }
232
+
233
+ if (typeof value !== 'undefined' && map && (map[value] ?? map['*'])) {
234
+ const viewValue =
235
+ map[value] ??
236
+ (value === true && map['1']
237
+ ? map['1']
238
+ : value === false && map['0']
239
+ ? map['0']
240
+ : map['*']); // 兼容平台旧用法:即 value 为 true 时映射 1 ,为 false 时映射 0
241
+ sheetRow.getCell(columIndex).value = removeHTMLTag(viewValue);
242
+ } else {
243
+ sheetRow.getCell(columIndex).value = removeHTMLTag(value);
244
+ }
245
+ } else if (type === 'date') {
246
+ let viewValue;
247
+ const {
248
+ fromNow,
249
+ format = 'YYYY-MM-DD',
250
+ valueFormat = 'X'
251
+ } = column as DateSchema;
252
+ if (value) {
253
+ let ISODate = moment(value, moment.ISO_8601);
254
+ let NormalDate = moment(value, valueFormat);
255
+
256
+ viewValue = ISODate.isValid()
257
+ ? ISODate.format(format)
258
+ : NormalDate.isValid()
259
+ ? NormalDate.format(format)
260
+ : false;
261
+ }
262
+
263
+ if (fromNow) {
264
+ viewValue = moment(value).fromNow();
265
+ }
266
+ if (viewValue) {
267
+ sheetRow.getCell(columIndex).value = viewValue;
268
+ }
269
+ } else {
270
+ if ((column as TplSchema).tpl) {
271
+ sheetRow.getCell(columIndex).value = removeHTMLTag(
272
+ filter((column as TplSchema).tpl, createObject(data, row.data))
273
+ );
274
+ } else {
275
+ sheetRow.getCell(columIndex).value = value;
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ const buffer = await workbook.xlsx.writeBuffer();
282
+
283
+ if (buffer) {
284
+ var blob = new Blob([buffer], {
285
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
286
+ });
287
+ saveAs(blob, filename + '.xlsx');
288
+ }
289
+ }
@@ -59,6 +59,9 @@ import ColumnToggler from './ColumnToggler';
59
59
  import {BadgeSchema} from '../../components/Badge';
60
60
  import offset from '../../utils/offset';
61
61
  import {getStyleNumber} from '../../utils/dom';
62
+ import {DateSchema} from '../Date';
63
+ import moment from 'moment';
64
+ import {exportExcel} from './exportExcel';
62
65
 
63
66
  /**
64
67
  * 表格列,不指定类型时默认为文本类型。
@@ -367,25 +370,13 @@ export interface TableProps extends RendererProps {
367
370
  itemBadge?: BadgeSchema;
368
371
  }
369
372
 
370
- type ExportExcelToolbar = SchemaNode & {
373
+ export type ExportExcelToolbar = SchemaNode & {
371
374
  api?: SchemaApi;
372
375
  columns?: string[];
373
376
  exportColumns?: any[];
374
377
  filename?: string;
375
378
  };
376
379
 
377
- /**
378
- * 将 url 转成绝对地址
379
- */
380
- const getAbsoluteUrl = (function () {
381
- let link: HTMLAnchorElement;
382
- return function (url: string) {
383
- if (!link) link = document.createElement('a');
384
- link.href = url;
385
- return link.href;
386
- };
387
- })();
388
-
389
380
  export default class Table extends React.Component<TableProps, object> {
390
381
  static propsList: Array<string> = [
391
382
  'header',
@@ -2281,245 +2272,7 @@ export default class Table extends React.Component<TableProps, object> {
2281
2272
  {
2282
2273
  onAction: () => {
2283
2274
  import('exceljs').then(async (ExcelJS: any) => {
2284
- let rows = [];
2285
- let tmpStore;
2286
- let filename = 'data';
2287
- // 支持配置 api 远程获取
2288
- if (typeof toolbar === 'object' && toolbar.api) {
2289
- const res = await env.fetcher(toolbar.api, data);
2290
- if (!res.data) {
2291
- env.notify('warning', __('placeholder.noData'));
2292
- return;
2293
- }
2294
- if (Array.isArray(res.data)) {
2295
- rows = res.data;
2296
- } else {
2297
- rows = res.data.rows || res.data.items;
2298
- }
2299
- // 因为很多方法是 store 里的,所以需要构建 store 来处理
2300
- tmpStore = TableStore.create(getSnapshot(store));
2301
- tmpStore.initRows(rows);
2302
- rows = tmpStore.rows;
2303
- } else {
2304
- rows = store.rows;
2305
- }
2306
-
2307
- if (typeof toolbar === 'object' && toolbar.filename) {
2308
- filename = filter(toolbar.filename, data, '| raw');
2309
- }
2310
-
2311
- if (rows.length === 0) {
2312
- env.notify('warning', __('placeholder.noData'));
2313
- return;
2314
- }
2315
-
2316
- const workbook = new ExcelJS.Workbook();
2317
- const worksheet = workbook.addWorksheet('sheet', {
2318
- properties: {defaultColWidth: 15}
2319
- });
2320
- worksheet.views = [{state: 'frozen', xSplit: 0, ySplit: 1}];
2321
-
2322
- let exportColumnNames = toolbar.columns;
2323
-
2324
- if (isPureVariable(exportColumnNames)) {
2325
- exportColumnNames = resolveVariableAndFilter(
2326
- exportColumnNames,
2327
- data,
2328
- '| raw'
2329
- );
2330
- }
2331
-
2332
- // 自定义导出列配置
2333
- if (toolbar.exportColumns && Array.isArray(toolbar.exportColumns)) {
2334
- columns = toolbar.exportColumns;
2335
- }
2336
-
2337
- const filteredColumns = exportColumnNames
2338
- ? columns.filter(column => {
2339
- const filterColumnsNames = exportColumnNames!;
2340
- if (
2341
- column.name &&
2342
- filterColumnsNames.indexOf(column.name) !== -1
2343
- ) {
2344
- return true;
2345
- }
2346
- return false;
2347
- })
2348
- : columns;
2349
-
2350
- const firstRowLabels = filteredColumns.map(column => {
2351
- return column.label;
2352
- });
2353
- const firstRow = worksheet.getRow(1);
2354
- firstRow.values = firstRowLabels;
2355
- worksheet.autoFilter = {
2356
- from: {
2357
- row: 1,
2358
- column: 1
2359
- },
2360
- to: {
2361
- row: 1,
2362
- column: firstRowLabels.length
2363
- }
2364
- };
2365
- // 用于 mapping source 的情况
2366
- const remoteMappingCache: any = {};
2367
- // 数据从第二行开始
2368
- let rowIndex = 1;
2369
- for (const row of rows) {
2370
- rowIndex += 1;
2371
- const sheetRow = worksheet.getRow(rowIndex);
2372
- let columIndex = 0;
2373
- for (const column of filteredColumns) {
2374
- columIndex += 1;
2375
- const name = column.name!;
2376
- const value = getVariable(row.data, name);
2377
- if (
2378
- typeof value === 'undefined' &&
2379
- !(column as TplSchema).tpl
2380
- ) {
2381
- continue;
2382
- }
2383
- // 处理合并单元格
2384
- if (name in row.rowSpans) {
2385
- if (row.rowSpans[name] === 0) {
2386
- continue;
2387
- } else {
2388
- // start row, start column, end row, end column
2389
- worksheet.mergeCells(
2390
- rowIndex,
2391
- columIndex,
2392
- rowIndex + row.rowSpans[name] - 1,
2393
- columIndex
2394
- );
2395
- }
2396
- }
2397
-
2398
- const type = (column as BaseSchema).type || 'plain';
2399
- if (type === 'image' && value) {
2400
- try {
2401
- const imageData = await toDataURL(value);
2402
- const imageDimensions = await getImageDimensions(imageData);
2403
- let imageWidth = imageDimensions.width;
2404
- let imageHeight = imageDimensions.height;
2405
- // 限制一下图片高宽
2406
- const imageMaxSize = 100;
2407
- if (imageWidth > imageHeight) {
2408
- if (imageWidth > imageMaxSize) {
2409
- imageHeight = (imageMaxSize * imageHeight) / imageWidth;
2410
- imageWidth = imageMaxSize;
2411
- }
2412
- } else {
2413
- if (imageHeight > imageMaxSize) {
2414
- imageWidth = (imageMaxSize * imageWidth) / imageHeight;
2415
- imageHeight = imageMaxSize;
2416
- }
2417
- }
2418
- const imageMatch = imageData.match(/data:image\/(.*);/);
2419
- let imageExt = 'png';
2420
- if (imageMatch) {
2421
- imageExt = imageMatch[1];
2422
- }
2423
- // 目前 excel 只支持这些格式,所以其它格式直接输出 url
2424
- if (
2425
- imageExt != 'png' &&
2426
- imageExt != 'jpeg' &&
2427
- imageExt != 'gif'
2428
- ) {
2429
- sheetRow.getCell(columIndex).value = value;
2430
- continue;
2431
- }
2432
- const imageId = workbook.addImage({
2433
- base64: imageData,
2434
- extension: imageExt
2435
- });
2436
- const linkURL = getAbsoluteUrl(value);
2437
- worksheet.addImage(imageId, {
2438
- // 这里坐标位置是从 0 开始的,所以要减一
2439
- tl: {col: columIndex - 1, row: rowIndex - 1},
2440
- ext: {
2441
- width: imageWidth,
2442
- height: imageHeight
2443
- },
2444
- hyperlinks: {
2445
- tooltip: linkURL
2446
- }
2447
- });
2448
- } catch (e) {
2449
- console.warn(e.stack);
2450
- }
2451
- } else if (type == 'link') {
2452
- const linkURL = getAbsoluteUrl(value);
2453
- sheetRow.getCell(columIndex).value = {
2454
- text: value,
2455
- hyperlink: linkURL
2456
- };
2457
- } else if (type === 'mapping') {
2458
- // 拷贝自 Mapping.tsx
2459
- let map = (column as MappingSchema).map;
2460
- const source = (column as MappingSchema).source;
2461
- if (source) {
2462
- let sourceValue = source;
2463
- if (isPureVariable(source)) {
2464
- sourceValue = resolveVariableAndFilter(
2465
- source as string,
2466
- data,
2467
- '| raw'
2468
- );
2469
- }
2470
-
2471
- const mapKey = JSON.stringify(source);
2472
- if (mapKey in remoteMappingCache) {
2473
- map = remoteMappingCache[mapKey];
2474
- } else {
2475
- const res = await env.fetcher(sourceValue, data);
2476
- if (res.data) {
2477
- remoteMappingCache[mapKey] = res.data;
2478
- map = res.data;
2479
- }
2480
- }
2481
- }
2482
-
2483
- if (
2484
- typeof value !== 'undefined' &&
2485
- map &&
2486
- (map[value] ?? map['*'])
2487
- ) {
2488
- const viewValue =
2489
- map[value] ??
2490
- (value === true && map['1']
2491
- ? map['1']
2492
- : value === false && map['0']
2493
- ? map['0']
2494
- : map['*']); // 兼容平台旧用法:即 value 为 true 时映射 1 ,为 false 时映射 0
2495
- sheetRow.getCell(columIndex).value =
2496
- removeHTMLTag(viewValue);
2497
- } else {
2498
- sheetRow.getCell(columIndex).value = removeHTMLTag(value);
2499
- }
2500
- } else {
2501
- if ((column as TplSchema).tpl) {
2502
- sheetRow.getCell(columIndex).value = removeHTMLTag(
2503
- filter(
2504
- (column as TplSchema).tpl,
2505
- createObject(data, row.data)
2506
- )
2507
- );
2508
- } else {
2509
- sheetRow.getCell(columIndex).value = value;
2510
- }
2511
- }
2512
- }
2513
- }
2514
-
2515
- const buffer = await workbook.xlsx.writeBuffer();
2516
-
2517
- if (buffer) {
2518
- var blob = new Blob([buffer], {
2519
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
2520
- });
2521
- saveAs(blob, filename + '.xlsx');
2522
- }
2275
+ exportExcel(ExcelJS, this.props, toolbar);
2523
2276
  });
2524
2277
  }
2525
2278
  }
package/src/utils/api.ts CHANGED
@@ -12,10 +12,12 @@ import {
12
12
  cloneObject,
13
13
  createObject,
14
14
  qsparse,
15
- uuid
15
+ uuid,
16
+ JSONTraverse
16
17
  } from './helper';
17
18
  import isPlainObject from 'lodash/isPlainObject';
18
19
  import {debug} from './debug';
20
+ import {evaluate, parse} from 'amis-formula';
19
21
 
20
22
  const rSchema = /(?:^|raw\:)(get|post|put|delete|patch|options|head|jsonp):/i;
21
23
 
@@ -94,24 +96,54 @@ export function buildApi(
94
96
  }
95
97
 
96
98
  const raw = (api.url = api.url || '');
97
- const idx = api.url.indexOf('?');
99
+ let ast: any = undefined;
100
+ try {
101
+ ast = parse(api.url);
102
+ } catch (e) {
103
+ console.warn(`api 配置语法出错:${e}`);
104
+ return api;
105
+ }
106
+ const url = ast.body
107
+ .map((item: any, index: number) => {
108
+ return item.type === 'raw' ? item.value : `__expression__${index}__`;
109
+ })
110
+ .join('');
111
+
112
+ const idx = url.indexOf('?');
113
+ let replaceExpression = (fragment: string) => {
114
+ return fragment.replace(
115
+ /__expression__(\d+)__/g,
116
+ (_: any, index: string) => {
117
+ return evaluate(ast.body[index], data, {
118
+ defaultFilter: 'url_encode'
119
+ });
120
+ }
121
+ );
122
+ };
98
123
 
99
124
  if (~idx) {
100
- const hashIdx = api.url.indexOf('#');
125
+ const hashIdx = url.indexOf('#');
101
126
  const params = qsparse(
102
- api.url.substring(
103
- idx + 1,
104
- ~hashIdx && hashIdx > idx ? hashIdx : undefined
105
- )
127
+ url.substring(idx + 1, ~hashIdx && hashIdx > idx ? hashIdx : undefined)
106
128
  );
129
+
130
+ // 将里面的表达式运算完
131
+ JSONTraverse(params, (value: any, key: string | number, host: any) => {
132
+ if (typeof value === 'string' && /^__expression__(\d+)__$/.test(value)) {
133
+ host[key] = evaluate(ast.body[RegExp.$1].body, data);
134
+ }
135
+ });
136
+
107
137
  api.url =
108
- tokenize(api.url.substring(0, idx + 1), data, '| url_encode') +
138
+ replaceExpression(url.substring(0, idx + 1)) +
109
139
  qsstringify(
110
140
  (api.query = dataMapping(params, data, undefined, api.convertKeyToPath))
111
141
  ) +
112
- (~hashIdx && hashIdx > idx ? api.url.substring(hashIdx) : '');
142
+ (~hashIdx && hashIdx > idx
143
+ ? replaceExpression(url.substring(hashIdx))
144
+ : '');
113
145
  } else {
114
- api.url = tokenize(api.url, data, '| url_encode');
146
+ api.url = replaceExpression(url);
115
147
  }
116
148
 
117
149
  if (ignoreData) {