FreeGridv1.6.0English

인쇄와 PDF

헤더 행과 지정한 행을 페이지마다 반복하며 인쇄하거나 PDF로 저장합니다. 그룹 행, 합계, 조건부 서식, 제목, 꼬리말, 페이지 번호가 함께 나옵니다.

실행 예제인쇄와 PDF

원하는 용지로 인쇄하거나 PDF로 저장합니다. 페이지마다 헤더 행을 반복하고, 그룹 행·합계·제목·페이지 번호도 넣습니다.

이 데모의 코드
import { createGrid, type ColumnDef, type PrintOptions } from '@freegridjs/core';
import { HEADERS, makeRows } from '../data';
import { button, select, separator, text, toggle, 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 t = HEADERS[lang];
  const columns: ColumnDef[] = [
    { field: 'name', header: t.name, width: 150 },
    { field: 'country', header: t.country, width: 130 },
    { field: 'company', header: t.company, width: 130 },
    { header: t.revenue, children: [
      { field: 'q1', header: t.q1, type: 'number', format: '#,##0', width: 100, aggFunc: 'sum' },
      { field: 'q2', header: t.q2, type: 'number', format: '#,##0', width: 100, aggFunc: 'sum' },
    ] },
    { field: 'growth', header: t.growth, type: 'number', format: '0.0%', width: 90,
      cellClass: p => (typeof p.value === 'number' && p.value < 0 ? 'neg' : 'pos') },
    { field: 'active', header: t.active, type: 'boolean', width: 70 },
    { field: 'joined', header: t.joined, type: 'date', width: 110 },
  ];
  const grid = createGrid(ctx.host, {
    columns, data: makeRows(60), locale: lang, rowNumbers: true, groupBy: ['country'],
    summary: { rows: [{ label: h('Total', '합계'), columns: { q1: 'sum', q2: 'sum' } }] },
  });

  // what the buttons below change
  const opts: PrintOptions = {
    title: h('Sales, first half of 2026', '2026년 상반기 매출 현황'),
    subtitle: h('By country · Q1 and Q2', '국가별 · 1~2분기'),
    footer: h('ACME Inc. · Internal use only', '(주)에이크미 · 대외비'),
    paper: 'A4',
    orientation: 'auto',
  };

  // the page print() would print, shown under the grid
  const preview = document.createElement('iframe');
  preview.className = 'print-preview';
  preview.title = h('Print preview', '인쇄 미리보기');
  preview.setAttribute('sandbox', '');
  ctx.host.after(preview);
  // a little padding stands in for the paper margins
  const refresh = () => { preview.srcdoc = grid.getPrintHtml(opts).replace('<body>', '<body style="padding:24px 28px">'); };
  grid.on('sortChange', refresh);
  grid.on('filterChange', refresh);
  grid.on('groupChange', refresh);
  refresh();

  text(ctx, h('Group rows, totals, colors and row numbers print as they are; the preview below updates as you change the options. Right-click → Print… works too.',
    '그룹 행·합계·색·행 번호가 그대로 인쇄됩니다. 옵션을 바꾸면 아래 미리보기가 바로 바뀌고, 우클릭 → 인쇄…로도 인쇄할 수 있습니다.'));
  separator(ctx);
  button(ctx, h('Print', '인쇄하기'), () => grid.print(opts));
  select(ctx, h('Paper', '용지'), [['A4', 'A4'], ['A3', 'A3'], ['B4', 'B4'], ['letter', 'Letter']], 'A4', v => { opts.paper = v; refresh(); });
  select(ctx, h('Direction', '방향'), [['auto', h('Auto', '자동')], ['portrait', h('Portrait', '세로')], ['landscape', h('Landscape', '가로')]], 'auto',
    v => { opts.orientation = v; refresh(); });
  separator(ctx);
  toggle(ctx, h('Group rows', '그룹 행'), true, on => { opts.groups = on; refresh(); });
  toggle(ctx, h('Totals', '합계 행'), true, on => { opts.summary = on; refresh(); });
  toggle(ctx, h('Row numbers', '행 번호'), true, on => { opts.rowNumbers = on; refresh(); });
  toggle(ctx, h('Stripes', '줄무늬'), true, on => { opts.striped = on; refresh(); });
  toggle(ctx, h('Page numbers', '페이지 번호'), true, on => { opts.pageNumbers = on; refresh(); });
  separator(ctx);
  // headers print on every page; repeatRows adds the first rows too, repeatTitle the title block
  toggle(ctx, h('Header on every page', '페이지마다 헤더'), true, on => { opts.repeatHeader = on; refresh(); });
  select(ctx, h('Repeat rows', '반복할 행'), [['0', h('None', '없음')], ['1', '1'], ['2', '2'], ['3', '3']], '0', v => { opts.repeatRows = Number(v); refresh(); });
  toggle(ctx, h('Title on every page', '페이지마다 제목'), false, on => { opts.repeatTitle = on; refresh(); });
  separator(ctx);
  button(ctx, h('Save as PDF', 'PDF로 저장'), () => {
    grid.exportPdf(h('sales.pdf', '매출현황.pdf'), opts);
    ctx.log(h('exportPdf → sales.pdf', 'exportPdf → 매출현황.pdf'));
  });
  return grid;
}

print()는 지금 보이는 정렬·필터 그대로 표를 인쇄하고, exportPdf()는 같은 모양을 PDF 파일로 저장합니다. 다단 헤더, 그룹 행(접힌 그룹까지 건수와 합계 포함), 요약 행, cellClass 색, 조건부 서식(색·막대·아이콘)이 함께 나오고, 열 너비 비율을 유지한 채 용지 폭에 맞추며, 열이 많으면 자동으로 가로 방향이 됩니다. 마우스 우클릭 메뉴의 "인쇄…"와 "PDF로 내보내기"로도 할 수 있습니다.

페이지마다 반복할 행

여러 페이지에 걸친 표는 페이지마다 컬럼 헤더가 반복됩니다(repeatHeader, 기본 켜짐). 엑셀의 "반복할 행"처럼 앞쪽 몇 행을 페이지마다 다시 찍으려면 repeatRows에 행 수를 주고, 제목까지 반복하려면 repeatTitle: true를 주세요. 같은 설정이 PDF와 엑셀 파일(인쇄 제목)에도 적용됩니다.

grid.print({
  title: '2026년 상반기 매출 현황',
  subtitle: '국가별 · 1~2분기',
  footer: '(주)에이크미 · 대외비',
  paper: 'A4',              // A3, A5, B4, B5, letter, legal
  orientation: 'auto',      // 열이 많으면 가로
  repeatHeader: true,       // 페이지마다 헤더 행 반복 (기본)
  repeatRows: 1,            // 첫 번째 행(예: 전년 합계)도 페이지마다 반복
  repeatTitle: false,       // 제목은 첫 페이지에만
});
const html = grid.getPrintHtml({ title: '미리보기' });   // 인쇄될 HTML (미리보기용)

PDF로 저장

PDF는 별도 라이브러리 없이 브라우저 안에서 만듭니다. 페이지마다 표를 그려 넣는 방식이라 한글·일본어·중국어처럼 글꼴이 필요한 언어도 화면과 똑같이 나옵니다. 대신 PDF 안의 글자는 선택하거나 검색할 수 없습니다. 선명도는 resolution(기본 2), 파일 크기는 quality로 조절합니다.

grid.exportPdf('매출현황.pdf', { title: '2026년 상반기 매출 현황', repeatRows: 1 });

// 파일 대신 바이트로 받아 서버에 올리거나 메일에 첨부
const bytes = grid.getPdf({ paper: 'A3', resolution: 3 });   // Uint8Array (캔버스가 없으면 null)
await fetch('/api/reports', { method: 'POST', body: bytes, headers: { 'Content-Type': 'application/pdf' } });

엑셀 인쇄 제목

// 엑셀 파일도 인쇄할 때 헤더 행이 페이지마다 반복됩니다 (인쇄 제목)
grid.exportXlsx('매출.xlsx', { repeatRows: 1 });    // 헤더 + 첫 번째 행 반복
grid.exportXlsx('매출.xlsx', { repeatHeader: false });

옵션

이름타입설명
title / subtitle / footerstring맨 위 제목, 그 아래 한 줄, 페이지마다 왼쪽 아래 글.
paper / orientation'A4' | 'A3' | 'A5' | 'B4' | 'B5' | 'letter' | 'legal' / 'auto' | 'portrait' | 'landscape'기본 A4, 'auto'(열이 많으면 가로).
repeatHeaderboolean페이지마다 컬럼 헤더를 반복합니다(기본 true). 엑셀 내보내기에도 인쇄 제목으로 들어갑니다.
repeatRowsnumber앞쪽 n개 행도 헤더 아래에 페이지마다 반복합니다.
repeatTitleboolean첫 페이지뿐 아니라 모든 페이지에 제목을 넣습니다.
fitToWidth / groups / summary / striped / pageNumbers / printedAt / rowNumbersboolean열을 용지 폭에 맞춤, 그룹 행과 합계, 요약 행, 줄무늬, "1 / 3", 인쇄 일시, 번호 컬럼.
resolution / qualitynumberPDF 전용: 페이지 이미지 선명도(기본 2)와 JPEG 품질(기본 0.92).

이 페이지에 대한 질문

PDF로 내보낼 수 있나요?

네. grid.exportPdf("파일.pdf", 옵션)이 인쇄 모양 그대로 브라우저에서 PDF를 만들며 한글도 그대로 나옵니다. getPdf()는 바이트를 돌려줍니다.

인쇄할 때 페이지마다 헤더를 반복하려면?

헤더는 기본으로 반복됩니다(repeatHeader). repeatRows: n이면 앞쪽 n개 행도 반복하고, repeatTitle은 제목을 반복합니다. 엑셀 내보내기에도 같은 인쇄 제목이 들어갑니다.