feat:导出 excel 支持指定行 Closes #2738 (#7316)

This commit is contained in:
吴多益 2023-07-03 14:19:55 +08:00 committed by GitHub
parent 92f6244f0c
commit caea8ec5b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 138 additions and 1 deletions

View File

@ -2183,6 +2183,60 @@ crud 组件支持通过配置`headerToolbar`和`footerToolbar`属性,实现在
}
```
#### 指定导出行
> 3.2.0 及以上版本
可以通过配置 `rowSlice` 属性来控制导出哪些行
```schema: scope="body"
{
"type": "crud",
"syncLocation": false,
"api": "/api/mock2/sample",
"headerToolbar": [{
"type": "export-excel",
"label": "导出 1, 4, 5 行",
"rowSlice": "0,3:5"
}],
"columns": [
{
"name": "id",
"label": "ID"
},
{
"name": "engine",
"label": "Rendering engine"
},
{
"name": "browser",
"label": "Browser"
},
{
"name": "platform",
"label": "Platform(s)"
},
{
"name": "version",
"label": "Engine version"
},
{
"name": "grade",
"label": "CSS grade"
}
]
}
```
`rowSlice` 支持以下写法
- 取单个值 '1,2,3',代表取 1、2、3 索引的内容
- 取范围 '3:10',代表取 3-9 索引的内容
- ':' 代表所有行
- '1:' 代表从第二行开始到结束
- 结束可以是负数 ':-1',代表除了最后一个元素的所有元素,开始为空代表 0
- 前两种的组合 '1,3:10',代表取 1 索引和 3-9 索引的内容
#### 通过 api 导出 Excel
> 1.1.6 以上版本支持

View File

@ -0,0 +1,11 @@
import {arraySlice} from '../../src/utils/arraySlice';
test(`arrayslice:test`, () => {
const testArray = [0, 1, 2, 3, 4, 5];
expect(arraySlice(testArray, ':')).toEqual([0, 1, 2, 3, 4, 5]);
expect(arraySlice(testArray, '0,3,4')).toEqual([0, 3, 4]);
expect(arraySlice(testArray, '1:2')).toEqual([1]);
expect(arraySlice(testArray, '0:-2')).toEqual([0, 1, 2, 3]);
expect(arraySlice(testArray, '1:-2')).toEqual([1, 2, 3]);
expect(arraySlice(testArray, '0,1:-2')).toEqual([0, 1, 2, 3]);
});

View File

@ -0,0 +1,67 @@
/**
* 使 python
*
* * 1,2,3
* * 3:10
* * 1,2,3:10
* * :-1
*/
import {toJS, isObservableArray} from 'mobx';
export function arraySlice(array: any[], slice: string) {
if (typeof slice !== 'string') {
return array;
}
if (isObservableArray(array)) {
array = toJS(array);
}
slice = slice.trim();
if (!slice || !Array.isArray(array)) {
return array;
}
const parts = slice.split(',');
const ret: any[] = [];
const arrayLength = array.length;
if (!arrayLength) {
return array;
}
for (const part of parts) {
// 普通的场景
if (part.indexOf(':') === -1) {
const index = parseInt(part, 10);
if (!isNaN(index) && index < arrayLength) {
ret.push(array[index]);
}
} else {
const [start, end] = part.split(':');
let startIndex = parseInt(start || '0', 10);
if (isNaN(startIndex) || startIndex < 0) {
startIndex = 0;
}
// 大于就没意义了
if (startIndex >= arrayLength) {
continue;
}
let endIndex = parseInt(end, 10);
if (isNaN(endIndex)) {
endIndex = arrayLength;
}
// 负数就从后面开始取
if (endIndex < 0) {
endIndex = arrayLength + endIndex;
}
// 小于没有意义
if (endIndex < startIndex) {
continue;
}
if (endIndex > arrayLength) {
endIndex = arrayLength;
}
ret.push(...array.slice(startIndex, endIndex));
}
}
return ret;
}

View File

@ -54,6 +54,7 @@ export * from './toNumber';
export * from './decodeEntity';
export * from './style-helper';
export * from './resolveCondition';
export * from './arraySlice';
import animation from './Animation';

View File

@ -2,7 +2,7 @@
* Excel
*/
import {filter, isEffectiveApi} from 'amis-core';
import {filter, isEffectiveApi, arraySlice} from 'amis-core';
import './ColumnToggler';
import {TableStore} from 'amis-core';
import {saveAs} from 'file-saver';
@ -261,6 +261,9 @@ export async function exportExcel(
const remoteMappingCache: any = {};
// 数据从第二行开始
let rowIndex = 1;
if (toolbar.rowSlice) {
rows = arraySlice(rows, toolbar.rowSlice);
}
for (const row of rows) {
const rowData = createObject(data, row.data);
rowIndex += 1;

View File

@ -404,6 +404,7 @@ export type ExportExcelToolbar = SchemaNode & {
api?: SchemaApi;
columns?: string[];
exportColumns?: any[];
rowSlice?: string;
filename?: string;
};