Skip to content

Commit

Permalink
fix: export with formatted values (nhn#1499)
Browse files Browse the repository at this point in the history
* test: add test for export

* fix: export with formatted values

* chore: apply code reviews

* chore: fix lint error

* chore: remove unnecessary only flag in test

* chore: remove 'ToUse' suffix
  • Loading branch information
jajugoguma authored Nov 5, 2021
1 parent c22520b commit eb6cc86
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 28 deletions.
2 changes: 1 addition & 1 deletion packages/toast-ui.grid/cypress/integration/data.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ describe('setRow()', () => {
cy.getCell(1, 'name').should('have.text', 'observable');
});

it.only('should destroy the focusing layer, only when row will be filtered', () => {
it('should destroy the focusing layer, only when row will be filtered', () => {
createGrid();
cy.gridInstance().invoke('setFilter', 'age', 'number');
invokeFilter('age', [{ code: 'gt', value: 5 }]);
Expand Down
47 changes: 44 additions & 3 deletions packages/toast-ui.grid/cypress/integration/export.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ function clickExportMenuItemByFormat(format: 'csv' | 'xlsx') {

describe('Export data', () => {
const data = [
{ name: 'Sugar', artist: 'Maroon5', price: 1000 },
{ name: 'Get Lucky', artist: 'Daft Punk', price: 2000 },
{ name: '21', artist: 'Adele', price: 3000 },
{ name: 'Sugar', artist: 'Maroon5', price: 1000, typeCode: '2' },
{ name: 'Get Lucky', artist: 'Daft Punk', price: 2000, typeCode: '3' },
{ name: '21', artist: 'Adele', price: 3000, typeCode: '1' },
];
const columns = [
{
Expand Down Expand Up @@ -308,4 +308,45 @@ describe('Export data', () => {
});
});
});

describe('useFormattedValue option', () => {
beforeEach(() => {
const formatColumn = [
{
header: 'Type',
name: 'typeCode',
formatter: 'listItemText',
editor: {
type: 'select',
options: {
listItems: [
{ text: 'Deluxe', value: '1' },
{ text: 'EP', value: '2' },
{ text: 'Single', value: '3' },
],
},
},
},
];
cy.gridInstance().invoke('setColumns', formatColumn);
});

['csv', 'xlsx'].forEach((format) => {
it(`should export formatted data to '${format}' (useFormattedValue = true)`, () => {
cy.gridInstance().invoke('export', format, { useFormattedValue: true });

cy.wrap(callback).should('be.calledWithMatch', {
data: [['Type'], ['EP'], ['Single'], ['Deluxe']],
});
});

it(`should export original data to '${format}' (useFormattedValue = false(default))`, () => {
cy.gridInstance().invoke('export', format);

cy.wrap(callback).should('be.calledWithMatch', {
data: [['Type'], ['2'], ['3'], ['1']],
});
});
});
});
});
1 change: 1 addition & 0 deletions packages/toast-ui.grid/docs/ko/export.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ TOAST UI Grid는 `v4.19.0` 버전 부터 `csv`와 엑셀(`xlsx`)로 내보내기
| `columnNames` | `string[]` | `[...보이는 모든 컬럼명]` | 내보내려는 컬럼을 선택한다.<br>해당 배열에 요소가 1개 이상 전달되면 `includeHiddenColumns` 옵션의 값과 상관 없이 전달 받은 컬럼을 내보낸다. |
| `onlySelected` | `boolean` | `false` | 선택한 영역만 내보낼지 여부를 결정한다.<br>값이 참이면 `includeHiddenColumns` 옵션과 `columnNames` 옵션의 값과 상관 없이 현재 선택한 영역만 내보낸다.<br>선택 영역이 없다면 옵션 값과 상관 없이 지정한 컬럼의 데이터 또는 숨겨진 컬럼을 포함한 모든 컬럼의 데이터 또는 보이는 컬럼의 데이터를 내보낸다. |
| `onlyFiltered` | `boolean` | `true` | 필터링된 데이터만 내보낼지 여부를 결정한다.<br>값이 참이면 필터링된 데이터만 내보내고, 거짓이면 모든 데이터를 내보낸다. |
| `useFormattedValue` | `boolean` | `false` | 포맷된 데이터를 내보낼지 여부를 결정한다.<br>값이 참이면 포맷된 데이터를 내보내고, 거짓이면 원본 데이터를 내보낸다. |
| `delimiter` | `','\|';'\|'\t'\|'\|'` | `','` | CSV 내보내기 시 구분자를 정의한다. |
| `fileName` | `string` | `'grid-export'` | 내보낼 파일의 이름을 정의한다. |

Expand Down
4 changes: 3 additions & 1 deletion packages/toast-ui.grid/src/dispatch/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function getExportDataAndColumnsAndOptions(store: Store, options?: OptExport) {
onlyFiltered = true,
delimiter = ',',
fileName = 'grid-export',
useFormattedValue = false,
} = options || {};

const {
Expand All @@ -57,7 +58,8 @@ function getExportDataAndColumnsAndOptions(store: Store, options?: OptExport) {
store,
onlyFiltered ? filteredRawData : rawData,
columnNames,
onlySelected
onlySelected,
useFormattedValue
);

const exportOptions = {
Expand Down
1 change: 1 addition & 0 deletions packages/toast-ui.grid/src/grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,7 @@ export default class Grid implements TuiGrid {
* @param {string[]} [options.columnNames=[...allVisibleColumnNames]] - Columns names to export
* @param {boolean} [options.onlySelected=false] - Whether to export only the selected range
* @param {boolean} [options.onlyFiltered=true] - Whether to export only the filtered data
* @param {boolean} [options.useFormattedValue=false] - Whether to export formatted values or original values
* @param {','|';'|'\\t'|'|'} [options.delimiter=','] - Delimiter to export CSV
* @param {string} [options.fileName='grid-export'] - File name to export
*/
Expand Down
70 changes: 47 additions & 23 deletions packages/toast-ui.grid/src/query/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { isCheckboxColumn, isDragColumn, isRowNumColumn } from '../helper/column
import { includes } from '../helper/common';
import GridEvent from '../event/gridEvent';
import { convertHierarchyToData, getComplexColumnsHierarchy } from './column';
import { createFormattedValue } from '../store/helper/data';
import { Dictionary } from '@t/options';

export type EventType = 'beforeExport' | 'afterExport';

Expand All @@ -18,6 +20,37 @@ export interface EventParams {
exportFn?: (data: string[][]) => void;
}

function getColumnInfoDictionary(store: Store, columnNames: string[]) {
const colmnInfos: Dictionary<ColumnInfo> = {};

store.column.allColumns.forEach((columnInfo) => {
if (includes(columnNames, columnInfo.name)) {
colmnInfos[columnInfo.name] = columnInfo;
}
});

return colmnInfos;
}

function getValue(
row: Row,
colmnInfos: Dictionary<ColumnInfo>,
columName: string,
useFormattedValue: boolean,
index?: number
) {
if (isRowNumColumn(columName)) {
return `No.${index! + 1}`;
}

const origianlValue = row[columName];
const formattedValue = createFormattedValue(row, colmnInfos[columName]);

return useFormattedValue && String(origianlValue) !== formattedValue
? formattedValue
: (origianlValue as string);
}

export function createExportEvent(eventType: EventType, eventParams: EventParams) {
const { exportFormat, exportOptions, data, exportFn } = eventParams;
let props: GridEventProps = {};
Expand Down Expand Up @@ -129,33 +162,24 @@ export function getTargetData(
store: Store,
rows: Row[],
columnNames: string[],
onlySelected: boolean
onlySelected: boolean,
useFormattedValue: boolean
) {
if (onlySelected) {
let targetRows = rows;
const colmnInfoDictionary = getColumnInfoDictionary(store, columnNames);
const {
selection: { originalRange },
} = store;

const {
selection: { originalRange },
} = store;
let targetRows = rows;

if (originalRange) {
const [rowStart, rowEnd] = originalRange.row;
targetRows = rows.slice(rowStart, rowEnd + 1);
}

return targetRows.map((row) => columnNames.map((colName) => row[colName] as string));
if (onlySelected && originalRange) {
const [rowStart, rowEnd] = originalRange.row;
targetRows = rows.slice(rowStart, rowEnd + 1);
}

const data = rows.map((row, index) =>
columnNames.reduce((rowData: string[], colName) => {
if (isRowNumColumn(colName)) {
rowData.push(`No.${index + 1}`);
} else {
rowData.push(row[colName] as string);
}
return rowData;
}, [])
return targetRows.map((row, index) =>
columnNames.map((colName) =>
getValue(row, colmnInfoDictionary, colName, useFormattedValue, index)
)
);

return data;
}
1 change: 1 addition & 0 deletions packages/toast-ui.grid/types/store/export.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export interface OptExport {
columnNames?: string[];
delimiter?: ',' | ';' | '\t' | '|';
fileName?: string;
useFormattedValue?: boolean;
}

0 comments on commit eb6cc86

Please sign in to comment.