react-pdf

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

@json-render/react-pdf

@json-render/react-pdf

React PDF renderer that generates PDF documents from JSON specs using
@react-pdf/renderer
.
基于
@react-pdf/renderer
实现的React PDF渲染器,可通过JSON规范生成PDF文档。

Installation

安装

bash
npm install @json-render/core @json-render/react-pdf
bash
npm install @json-render/core @json-render/react-pdf

Quick Start

快速开始

typescript
import { renderToBuffer } from "@json-render/react-pdf";
import type { Spec } from "@json-render/core";

const spec: Spec = {
  root: "doc",
  elements: {
    doc: { type: "Document", props: { title: "Invoice" }, children: ["page"] },
    page: {
      type: "Page",
      props: { size: "A4" },
      children: ["heading", "table"],
    },
    heading: {
      type: "Heading",
      props: { text: "Invoice #1234", level: "h1" },
      children: [],
    },
    table: {
      type: "Table",
      props: {
        columns: [
          { header: "Item", width: "60%" },
          { header: "Price", width: "40%", align: "right" },
        ],
        rows: [
          ["Widget A", "$10.00"],
          ["Widget B", "$25.00"],
        ],
      },
      children: [],
    },
  },
};

const buffer = await renderToBuffer(spec);
typescript
import { renderToBuffer } from "@json-render/react-pdf";
import type { Spec } from "@json-render/core";

const spec: Spec = {
  root: "doc",
  elements: {
    doc: { type: "Document", props: { title: "Invoice" }, children: ["page"] },
    page: {
      type: "Page",
      props: { size: "A4" },
      children: ["heading", "table"],
    },
    heading: {
      type: "Heading",
      props: { text: "Invoice #1234", level: "h1" },
      children: [],
    },
    table: {
      type: "Table",
      props: {
        columns: [
          { header: "Item", width: "60%" },
          { header: "Price", width: "40%", align: "right" },
        ],
        rows: [
          ["Widget A", "$10.00"],
          ["Widget B", "$25.00"],
        ],
      },
      children: [],
    },
  },
};

const buffer = await renderToBuffer(spec);

Render APIs

渲染API

typescript
import { renderToBuffer, renderToStream, renderToFile } from "@json-render/react-pdf";

// In-memory buffer
const buffer = await renderToBuffer(spec);

// Readable stream (pipe to HTTP response)
const stream = await renderToStream(spec);
stream.pipe(res);

// Direct to file
await renderToFile(spec, "./output.pdf");
All render functions accept an optional second argument:
{ registry?, state?, handlers? }
.
typescript
import { renderToBuffer, renderToStream, renderToFile } from "@json-render/react-pdf";

// 内存缓冲区
const buffer = await renderToBuffer(spec);

// 可读流(可管道传输到HTTP响应)
const stream = await renderToStream(spec);
stream.pipe(res);

// 直接导出到文件
await renderToFile(spec, "./output.pdf");
所有渲染函数都支持可选的第二个参数:
{ registry?, state?, handlers? }

Standard Components

标准组件

ComponentDescription
Document
Top-level PDF wrapper (must be root)
Page
Page with size (A4, LETTER), orientation, margins
View
Generic container (padding, margin, background, border)
Row
,
Column
Flex layout with gap, align, justify
Heading
h1-h4 heading text
Text
Body text (fontSize, color, weight, alignment)
Image
Image from URL or base64
Link
Hyperlink with text and href
Table
Data table with typed columns and rows
List
Ordered or unordered list
Divider
Horizontal line separator
Spacer
Empty vertical space
PageNumber
Current page number and total pages
组件描述
Document
顶级PDF容器(必须作为根节点)
Page
页面,支持配置尺寸(A4、LETTER)、方向、边距
View
通用容器(支持内边距、外边距、背景、边框)
Row
,
Column
Flex布局容器,支持间距、对齐、排列方式配置
Heading
h1-h4级标题文本
Text
正文文本(支持字号、颜色、字重、对齐方式配置)
Image
支持URL或base64格式的图片
Link
带文本和跳转地址的超链接
Table
支持类型化列和行的数据表格
List
有序或无序列表
Divider
水平分割线
Spacer
空白垂直占位区域
PageNumber
当前页码和总页数展示

Custom Catalog

自定义目录

typescript
import { defineCatalog } from "@json-render/core";
import { schema, defineRegistry, renderToBuffer } from "@json-render/react-pdf";
import { standardComponentDefinitions } from "@json-render/react-pdf/catalog";
import { z } from "zod";

const catalog = defineCatalog(schema, {
  components: {
    ...standardComponentDefinitions,
    Badge: {
      props: z.object({ label: z.string(), color: z.string().nullable() }),
      slots: [],
      description: "A colored badge label",
    },
  },
  actions: {},
});

const { registry } = defineRegistry(catalog, {
  components: {
    Badge: ({ props }) => (
      <View style={{ backgroundColor: props.color ?? "#e5e7eb", padding: 4 }}>
        <Text>{props.label}</Text>
      </View>
    ),
  },
});

const buffer = await renderToBuffer(spec, { registry });
typescript
import { defineCatalog } from "@json-render/core";
import { schema, defineRegistry, renderToBuffer } from "@json-render/react-pdf";
import { standardComponentDefinitions } from "@json-render/react-pdf/catalog";
import { z } from "zod";

const catalog = defineCatalog(schema, {
  components: {
    ...standardComponentDefinitions,
    Badge: {
      props: z.object({ label: z.string(), color: z.string().nullable() }),
      slots: [],
      description: "A colored badge label",
    },
  },
  actions: {},
});

const { registry } = defineRegistry(catalog, {
  components: {
    Badge: ({ props }) => (
      <View style={{ backgroundColor: props.color ?? "#e5e7eb", padding: 4 }}>
        <Text>{props.label}</Text>
      </View>
    ),
  },
});

const buffer = await renderToBuffer(spec, { registry });

External Store (Controlled Mode)

外部存储(受控模式)

Pass a
StateStore
for full control over state:
typescript
import { createStateStore } from "@json-render/react-pdf";

const store = createStateStore({ invoice: { total: 100 } });
store.set("/invoice/total", 200);
传入
StateStore
即可完全控制状态:
typescript
import { createStateStore } from "@json-render/react-pdf";

const store = createStateStore({ invoice: { total: 100 } });
store.set("/invoice/total", 200);

Server-Safe Import

服务端安全导入

Import schema and catalog without pulling in React:
typescript
import { schema, standardComponentDefinitions } from "@json-render/react-pdf/server";
无需引入React即可导入schema和目录:
typescript
import { schema, standardComponentDefinitions } from "@json-render/react-pdf/server";