FreeGridv1.15.1한국어

Excel and PDF export

exportXlsx writes real Excel files with formats, colours and merged headers, exportWorkbook puts several grids in one file, and exportPdf saves the print layout.

Live demoExcel & PDF export

Real .xlsx files with formats and colours, a sheet per grid, and PDF files made in the browser.

Code for this demo
import { createGrid, exportWorkbook, 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, align: 'center' },
    { field: 'country', header: h('Country', '국가'), width: 140, filter: 'set' },
    { header: h('Revenue', '매출'), children: [
      // low values are red; the colour and the right alignment also go into the Excel file
      { field: 'q1', header: h('Q1', '1분기'), type: 'number', format: '#,##0', width: 110,
        cellClass: ({ value }) => (Number(value) < 20000 ? 'demo-low' : undefined) },
      { field: 'q2', header: h('Q2', '2분기'), type: 'number', format: '#,##0', width: 110 },
    ] },
    { field: 'growth', header: h('Growth', '성장률'), type: 'number', format: '0.0%', width: 100 },
    { field: 'joined', header: h('Joined', '가입일'), type: 'date', width: 120 },
  ];
  const grid = createGrid(ctx.host, { columns, data: makeRows(300), locale: lang, theme: 'classic', rowSelection: 'multiple' });

  text(ctx, h('Sort or filter first: the files hold what you see. Check a few rows for the second sheet.',
    '먼저 정렬하거나 필터를 걸어 보세요. 파일에는 보이는 그대로 들어갑니다. 몇 행을 체크하면 두 번째 시트에 들어갑니다.'));
  separator(ctx);
  button(ctx, h('Export Excel', '엑셀로 내보내기'), () => grid.exportXlsx(h('freegrid-demo.xlsx', 'freegrid-데모.xlsx')));
  button(ctx, h('Excel without styles', '스타일 없이 엑셀로'), () => grid.exportXlsx('plain.xlsx', { styles: false }));
  button(ctx, h('Checked rows only', '체크한 행만'), () => grid.exportXlsx('selected.xlsx', { rows: 'selected' }));
  // one file, two sheets: the filtered view and the checked rows
  button(ctx, h('Excel with two sheets', '시트 두 개짜리 엑셀'), () => exportWorkbook(h('two-sheets.xlsx', '시트2개.xlsx'), [
    { grid, sheetName: h('Filtered', '필터 결과') },
    { grid, sheetName: h('Checked', '체크한 행'), options: { rows: 'selected' } },
  ]));
  separator(ctx);
  button(ctx, h('Save as PDF', 'PDF로 저장'), () => {
    grid.exportPdf(h('people.pdf', '사람목록.pdf'), { title: h('People', '사람 목록'), subtitle: h('Current sort and filters', '지금 정렬·필터 그대로'), repeatRows: 0 });
    ctx.log('exportPdf');
  });
  return grid;
}

exportXlsx() saves the rows as a real Excel file, made in the browser without a library. Numbers stay numbers with the column's format (a number value is a number cell even in a column without type: 'number'; text such as '007' stays text), dates stay dates, column groups become merged header rows, merged cells stay merged, and the header is frozen with filter buttons. The file carries the column align and the text colour, background and bold that cellClass gives, and conditional formats; styles: false leaves the styling out. By default it holds what is on screen: the current sort and filters, and the visible columns.

// a real .xlsx: numbers, dates, formats, merged column-group headers, frozen header
grid.exportXlsx('orders.xlsx');
grid.exportXlsx('picked.xlsx', { columns: ['name', 'total'], rows: 'selected', sheetName: 'Picked' });
grid.exportXlsx('plain.xlsx', { styles: false });        // without align and cellClass colours

// rows to repeat on every printed page (print titles)
grid.exportXlsx('sales.xlsx', { repeatRows: 1 });        // the header rows + the first row

// the bytes instead of a download
const bytes = grid.getXlsx({ rows: 'all' });             // Uint8Array

Long sheets repeat the header rows on every printed page (print titles), like the grid's own printout; repeatRows adds the first rows, such as last year's total, and repeatHeader: false turns it off.

Excel files can carry the summary rows (summary: true) and, when rows are grouped, a row per group with its count and aggregates (groups: true); print and PDF include both unless you turn them off. Row colours from rowStyle are written as cell fills.

Several grids in one workbook

exportWorkbook() puts several grids into one .xlsx file, a sheet each, with each sheet's own options; buildWorkbook() returns the bytes. The same grid can appear twice, for example once filtered and once with only the checked rows.

import { exportWorkbook, buildWorkbook } from '@freegridjs/core';

// one file, a sheet per grid
exportWorkbook('report.xlsx', [
  { grid: orders, sheetName: 'Orders' },
  { grid: customers, sheetName: 'Customers', options: { rows: 'all' } },
]);
const bytes = buildWorkbook([{ grid: orders, sheetName: 'Orders' }]);   // Uint8Array

PDF files

exportPdf() saves the print layout as a PDF made in the browser, with the same title, paper, repeated header rows and page numbers; getPdf() returns the bytes to upload or attach to an email. Each page is drawn the way the screen draws it, so Korean, Japanese, Chinese and every other script come out exactly as shown; the text in the PDF cannot be selected or searched. resolution (default 2) sets the sharpness and quality the file size. Like printing, it stops at maxRows rows (1,000 by default).

grid.exportPdf('sales.pdf', { title: 'Sales, first half of 2026', repeatRows: 1 });

// or the bytes, to upload or attach to an email
const bytes = grid.getPdf({ paper: 'A3', resolution: 3 });   // Uint8Array (null without a canvas)
await fetch('/api/reports', { method: 'POST', body: bytes, headers: { 'Content-Type': 'application/pdf' } });

Protected sheets, pictures and notes

Excel files can be protected, include pictures from image columns, and turn cell notes into comments. See:

Excel options

NameTypeDescription
columnsstring[]Column ids in order (hidden columns allowed); default: the displayed columns.
rows'filtered' | 'all' | 'selected''filtered' (default: current sort and filters), 'all' (source order) or 'selected' (checked rows).
headers / sheetNameboolean / stringInclude the header rows (default true); the sheet name.
protect / notes / imagesboolean | { password } / boolean / booleanRead-only sheet (password to unprotect); cell notes as comments (default true); pictures of image columns (exportXlsx, getXlsxAsync).
summary / groupsbooleanAdd the summary rows; when rows are grouped, add a row per group with its count and aggregates.
stylesbooleanCarry column align and the text colour, background and bold of cellClass into the file (default true).
repeatHeader / repeatRowsboolean / numberPrint titles: header rows on every printed page (default true), plus the first n rows.
getXlsx(options?) / getXlsxSheet(options?)Uint8Array / XlsxSheetThe file as bytes, or one sheet for buildWorkbook / exportWorkbook.

PDF takes the print options plus resolution and quality. CSV and JSON exports are free; see CSV, JSON and import.

Questions about this page

Can FreeGrid export to Excel?

Yes. exportXlsx writes a real .xlsx file with number formats, dates, merged headers and colours, made in the browser; exportWorkbook puts several grids in one file.

Can FreeGrid export a PDF?

Yes. grid.exportPdf("file.pdf", options) saves the print layout as a PDF in the browser, with any language, and getPdf() returns the bytes.