Export, import & filters panel
Save to Excel or CSV, read Excel or CSV files back in, and filter from a side panel.
Code for this demo
import { createGrid, type ColumnDef } from '@freegridjs/core';
import { makeRows } from '../data';
import { button, separator, text, tr, type DemoContext } from '../ui';
export default function mount(ctx: DemoContext) {
const { lang } = ctx;
const h = (en: string, ko: string) => tr(lang, { en, ko });
const columns: ColumnDef[] = [
{ field: 'id', header: 'ID', type: 'number', width: 80 },
{ field: 'name', header: h('Name', '이름'), width: 160, editable: true },
{ field: 'country', header: h('Country', '국가'), width: 140, filter: 'set', editable: true },
{ header: h('Revenue', '매출'), children: [
{ field: 'q1', header: h('Q1', '1분기'), type: 'number', format: '#,##0', width: 110, editable: true },
{ field: 'q2', header: h('Q2', '2분기'), type: 'number', format: '#,##0', width: 110, editable: true },
] },
{ field: 'growth', header: h('Growth', '성장률'), type: 'number', format: '0.0%', width: 100 },
{ field: 'joined', header: h('Joined', '가입일'), type: 'date', width: 120, editable: true },
{ field: 'active', header: h('Active', '활성'), type: 'boolean', width: 80, editable: true },
];
const grid = createGrid(ctx.host, {
columns,
data: makeRows(300),
locale: lang,
theme: 'classic',
rowSelection: 'multiple',
sideBar: { open: true, panels: ['filters', 'columns'] },
});
grid.on('filterChange', e => ctx.log(`filterChange → ${Object.keys(e.filters).join(', ') || h('none', '없음')}`));
text(ctx, h('Filter on the right, then export only what you see. Right-click a cell for the same commands.',
'오른쪽 필터 패널로 걸러 낸 뒤 보이는 행만 내보내 보세요. 셀을 우클릭해도 같은 메뉴가 나옵니다.'));
separator(ctx);
button(ctx, h('Export Excel', '엑셀로 내보내기'), () => grid.exportXlsx(h('freegrid-demo.xlsx', 'freegrid-데모.xlsx')));
button(ctx, h('Export CSV', 'CSV로 내보내기'), () => grid.exportCsv(h('freegrid-demo.csv', 'freegrid-데모.csv')));
button(ctx, h('Export checked rows', '체크한 행만 내보내기'), () => grid.exportXlsx('selected.xlsx', { rows: 'selected' }));
separator(ctx);
// Import: a hidden file input behind a normal button
const input = document.createElement('input');
input.type = 'file';
input.accept = '.xlsx,.csv,.tsv,.txt';
input.hidden = true;
input.addEventListener('change', async () => {
const file = input.files?.[0];
input.value = '';
if (!file) return;
try {
const res = await grid.importFile(file, { mode: 'append' });
ctx.log(h(`imported ${res.rows.length} rows (${res.skipped} cells skipped) — Ctrl+Z undoes it`,
`${res.rows.length}행을 가져왔습니다 (건너뛴 셀 ${res.skipped}개) — Ctrl+Z로 되돌릴 수 있습니다`));
grid.scrollToRow(grid.getDisplayedRowCount() - 1);
} catch (e) {
ctx.log(`import failed: ${(e as Error).message}`);
}
});
ctx.controls.append(input);
button(ctx, h('Import Excel / CSV…', '엑셀·CSV 가져오기…'), () => input.click());
return grid;
}