FreeGridv0.7.0English

스프레드시트 기능

셀 병합, 채우기 핸들, 합계 상태 표시줄, 고정 행, Ctrl+F 찾기.

이 데모의 코드

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 });
  // Sorted by country so identical countries sit together and merge into one tall cell.
  const data = makeRows(400).sort((a, b) => a.country.localeCompare(b.country) || a.company.localeCompare(b.company));
  const money = { type: 'number', format: '#,##0', width: 110, editable: true } as const;
  const columns: ColumnDef[] = [
    { field: 'country', header: h('Country', '국가'), width: 140, pinned: 'left', merge: true },
    { field: 'company', header: h('Company', '회사'), width: 140, merge: true },
    { field: 'name', header: h('Name', '이름'), width: 160, editable: true },
    { field: 'q1', header: h('Q1 revenue', '1분기 매출'), ...money, wrapHeaderText: true },
    { field: 'q2', header: h('Q2 revenue', '2분기 매출'), ...money, wrapHeaderText: true },
    { field: 'q3', header: h('Q3 revenue', '3분기 매출'), ...money, wrapHeaderText: true },
    { field: 'q4', header: h('Q4 revenue', '4분기 매출'), ...money, wrapHeaderText: true },
    { field: 'joined', header: h('Joined', '가입일'), type: 'date', width: 120, editable: true },
  ];
  const grid = createGrid(ctx.host, {
    columns,
    data,
    locale: lang,
    theme: 'erp',
    statusBar: true, // counts and totals of the selected cells
    fillHandle: true, // drag the blue corner to fill
    pinnedTopRows: [{ country: h('Target', '목표'), name: '—', q1: 50000, q2: 55000, q3: 60000, q4: 65000 }],
  });
  grid.on('cellValueChanged', e => ctx.log(`cellValueChanged → ${e.colId}: ${String(e.oldValue)} → ${String(e.newValue)}`));

  text(ctx, h('Drag across Q1–Q4 cells to see totals below. Pull the blue corner down to fill. Ctrl+F finds.',
    '1~4분기 셀을 드래그하면 아래에 합계가 나옵니다. 파란 모서리를 끌어내려 채워 보세요. Ctrl+F로 찾기.'));
  separator(ctx);
  button(ctx, h('Find "Granite"', '"Granite" 찾기'), () => ctx.log(`find → ${grid.find('Granite')} matches`));
  button(ctx, h('Next match', '다음 찾기'), () => grid.findNext());
  button(ctx, h('Clear find', '찾기 지우기'), () => grid.clearFind());
  button(ctx, h('Fill Q1 of the first 10 rows with a series', '첫 10행 1분기를 연속값으로 채우기'), () => {
    grid.setRange({ start: { rowIndex: 0, colId: 'q1' }, end: { rowIndex: 0, colId: 'q1' } });
    grid.pasteText('1000\n2000');
    grid.setRange({ start: { rowIndex: 0, colId: 'q1' }, end: { rowIndex: 1, colId: 'q1' } });
    grid.fillRange({ start: { rowIndex: 0, colId: 'q1' }, end: { rowIndex: 9, colId: 'q1' } });
  });
  button(ctx, h('Undo', '실행 취소'), () => grid.undo());
  return grid;
}