ReoGrid ReoGrid Web

ReoGrid Web v1.4 — page layout, print-perfect PDF export, and Excel-grade data features

· unvell team
ReoGrid Web v1.4 — page layout, print-perfect PDF export, and Excel-grade data features

ReoGrid Web is a JavaScript/TypeScript spreadsheet library that puts an Excel-grade editing experience — formula engine, xlsx I/O, canvas renderer — into a single dependency-free package, with first-class React and Vue wrappers and a free Lite tier on npm.

v1.4 changes what the grid is for. Until now it was an editing surface; v1.4 turns it into a document and reporting tool — you can lay out a page, paginate it with an Excel-style page-break preview, and export a print-perfect PDF entirely in the browser, with no server round-trip and no external PDF library. That headline sits on top of a batch of Excel-grade data features: pivot tables, table styles (Format as Table), data validation (入力規則), report binding (テンプレート明細繰り返し), cell comments (メモ), and named ranges — plus a round of xlsx-import fidelity fixes for Japanese business forms (発注書 / invoices).

It is additive: there are no breaking public-API changes. Page layout, PDF export, pivots, table styles, validation, report binding, and comments are Pro features; their read sides (and the whole named-range read path) work in Lite, so a Pro-authored document still renders and round-trips through a Lite viewer.


This is the release’s centerpiece. A worksheet now carries an Excel-style print settings model — paper size, orientation, margins, scale, and page order — and a page-break preview that draws the automatic breaks as dashed blue lines and manual/edge breaks as solid lines. You can drag a break to move it, or insert one by hand.

PDF export is generated by our own in-house engine. With usePageBreaks: true the exporter pulls paper size, orientation, margins, scale, and the computed page bands straight from the worksheet’s print settings — so the PDF paginates exactly like the on-screen preview. Supply a glyf TrueType font via options.font; the browser helper loadDefaultJapaneseFont() fetches Noto Sans JP once (then served from Cache Storage) so CJK text embeds correctly.

import { createReogrid, loadDefaultJapaneseFont } from '@reogrid/pro';

const grid = createReogrid({ workspace: '#app' });
const sheet = grid.worksheet;

// 1. Lay out the page like Excel — A4 portrait, 12mm margins, 100% scale.
sheet.setPrintSettings({
  paperSize: 'A4',
  orientation: 'portrait',
  margins: { top: 12, right: 12, bottom: 12, left: 12 },
  scale: 1,
});

// 2. Show the page-break preview and pin a manual break before the totals.
sheet.setShowPageBreaks(true);
sheet.insertRowPageBreak(40);

// 3. Export a print-perfect PDF that paginates exactly like the preview.
const font = await loadDefaultJapaneseFont();
grid.saveAsPdf({ font, usePageBreaks: true, filename: 'purchase-order.pdf' });

The paginating renderer draws cell backgrounds, text (alignment, overflow, wrapping, alternating-row colors, faux bold), grid lines, borders, merged-cell borders, embedded images, and rich-text runs — the same fidelity you see on screen. Need the raw bytes instead of a download? grid.exportPdf(options) returns a Uint8Array. And because loadFromFile / loadFromUrl now record the source name, saveAsPdf defaults its filename to the loaded document (purchase-order.xlsxpurchase-order.pdf).

This is what makes ReoGrid a fit for 帳票 work — invoices, purchase orders, delivery notes — where the layout on paper is the deliverable. See the PDF & printing docs and the PDF print demo.


Pivot tables

API-driven, live pivot tables computed from a source range and written back into the grid. Declare rows, columns, values, and an aggregation (sum / count / average / max / min / …); createPivot returns a handle you can update, refresh, or remove.

const pivot = sheet.createPivot({
  source: { row: 0, col: 0, rows: 201, columns: 5 }, // header row + 200 data rows, cols A:E
  anchor: { row: 0, column: 6 },
  rows: [{ field: 'Region' }],
  columns: [{ field: 'Product' }],
  values: [{ field: 'Sales', agg: 'sum', numberFormat: '#,##0' }],
});

pivot.refresh(); // recompute after editing the source

One thing to know: stored ranges don’t shift on row/column insert or delete, so call pivot.refresh() (or worksheet.refreshPivot(id)) after a structural edit. See the pivot table docs and the pivot demo.


Table styles — Format as Table

Apply an Excel built-in table style as a live overlay — the banding re-flows automatically when you insert or delete rows, and it round-trips through real xl/tables/*.xml. Use addTable on a range, or the fluent formatAsTable:

sheet.range('A1:E15').formatAsTable({
  style: 'TableStyleMedium9',
  showRowStripes: true,
});

Style names are the OOXML built-ins (TableStyleLight1..21, TableStyleMedium1..28, TableStyleDark1..11), and getTable / getTables read them back in Lite. See the table styles docs and the table styles demo.


Data validation — 入力規則

Attach validation to a cell or range: dropdown lists, whole / decimal / date / time / textLength comparisons, and custom formula rules — with stop / warning / information alerts (only stop blocks the edit). List rules auto-render a dropdown.

// Dropdown from an explicit list.
sheet.range('B2:B100').setValidation({
  type: 'list',
  options: ['Low', 'Medium', 'High'],
});

// Whole number 1–100, block anything else.
sheet.range('C2:C100').setValidation({
  type: 'whole',
  operator: 'between',
  value1: 1,
  value2: 100,
  errorMessage: 'Quantity must be a whole number between 1 and 100.',
});

Rules round-trip via the xlsx <dataValidations> element and JSON, and Pro-authored rules enforce in Lite via getValidations() / validate(). See the data validation docs.


Report binding — テンプレート明細繰り返し

Design a form once with {{token}} cells split into header / detail(×N) / footer sections, then bind data to materialize it in place. Header/footer tokens read top-level fields; each detail section repeats over the array named by its source. Per-row formulas relative-shift, footer aggregates expand over the materialized range, and pageBreakEvery: N pins a manual break every N records — ideal for fixed-form 帳票.

sheet.defineReportTemplate({
  columns: [0, 4],
  sections: [
    { role: 'header', rows: [0, 5] },
    { role: 'detail', rows: [6, 6], source: 'items', pageBreakEvery: 8 },
    { role: 'footer', rows: [7, 9] },
  ],
});

sheet.bindReport({
  invoiceNo: 'INV-2026-0042',
  date: '2026-06-18',
  customer: { name: 'Sample Co., Ltd.' },
  items: [
    { name: 'Website build', qty: 1, price: 350000 },
    { name: 'Maintenance (monthly)', qty: 12, price: 30000 },
  ],
});

unbindReport() restores the template. Pair this with saveAsPdf and you have a browser-side invoice/report pipeline. See the report binding docs.


Cell comments — メモ

Classic Excel comments, one per cell, with a red corner marker and a hover bubble:

sheet.cell('C1').setComment('Tax-exclusive unit price.', { author: 'Accounting' });

setComment / removeComment / clearComments / setCommentVisible write; getComment / getComments / hasComment read in Lite. Comments round-trip through JSON and are read from xlsx (VML write is deferred). See the cell comments docs.


Named ranges

Give a range a name and use it in formulas — workbook or sheet scope, with cascading recalculation and xlsx <definedNames> / JSON round-trip:

grid.defineName('Sales', 'A2:A100');
grid.defineName('TaxRate', 'Settings!$B$1');

sheet.cell('C1').value = '=SUM(Sales) * TaxRate';

The write side (defineName / removeName) is Pro-gated; reads and import (getName / getNames) work in Lite. See the named ranges docs.


Sharper xlsx import for Japanese business forms

A round of fidelity fixes lands with this release, aimed at real 発注書 / invoice files: locale-reserved date formats (numFmtId 27–36 / 50–58) now render as dates; the locale “short date” (14 / 22) maps to the East-Asian yyyy/m/d form; phonetic guides (<rPh> furigana) no longer leak into shared-string text; _xlfn.IFS(…) future-function markers resolve instead of #NAME?; tiny used ranges no longer collapse the grid; _x000D_ escapes are decoded; and hard line breaks auto-fit their row height. Copy now puts the displayed text on the clipboard, so a date cell copies 2023/2/28, not the serial 44985.


Upgrade

v1.4 is a drop-in upgrade — no code changes required.

yarn up @reogrid/pro@latest

Lite is on npm with no license key:

npm install @reogrid/lite

See the release notes for the complete v1.4 changelog, the PDF & printing, pivot table, and table styles docs for the full APIs, or try the PDF print, pivot table, and table styles demos. The pricing matrix has the Lite vs Pro breakdown.

Try ReoGrid Web in your project

Canvas-based Excel-compatible spreadsheet component for React and Vue. Lite is free — start with one npm install.

Related articles

Stay Updated

Be first to know — get updates as they ship

Get notified of new releases, features, and announcements.
No spam — just updates that matter.