renderpdf-js 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +204 -0
- package/README.md +275 -307
- package/dist/compose-pdf.d.ts +26 -0
- package/dist/document-colors.d.ts +8 -0
- package/dist/document-page.d.ts +115 -0
- package/dist/document-types.d.ts +135 -0
- package/dist/document.d.ts +64 -0
- package/dist/fonts.d.ts +4 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2051 -552
- package/dist/jspdf-adapter.d.ts +159 -0
- package/package.json +8 -3
package/API.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Document API
|
|
2
|
+
|
|
3
|
+
RenderPDF.js provides three ways to create a PDF: `renderPDF()` for supported HTML,
|
|
4
|
+
`imageToPDF()` for image files, and `createDocument()` for programmatic drawing.
|
|
5
|
+
All return or finalize into the same immutable `RenderPDFResult` with `pageCount`,
|
|
6
|
+
`warnings`, `toBlob()`, `toUint8Array()` and `download()`.
|
|
7
|
+
|
|
8
|
+
## Documents and fonts
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { createDocument } from 'renderpdf-js';
|
|
12
|
+
|
|
13
|
+
const response = await fetch('/fonts/ReportSans-Regular.ttf');
|
|
14
|
+
if (!response.ok) throw new Error('The font could not be loaded.');
|
|
15
|
+
|
|
16
|
+
const document = await createDocument({
|
|
17
|
+
unit: 'mm',
|
|
18
|
+
format: 'A4',
|
|
19
|
+
fonts: [{ family: 'Report Sans', data: await response.arrayBuffer() }],
|
|
20
|
+
metadata: { title: 'Report' },
|
|
21
|
+
});
|
|
22
|
+
const page = document.addPage();
|
|
23
|
+
page.drawText('Příliš žluťoučký kůň', {
|
|
24
|
+
x: 15,
|
|
25
|
+
y: 25,
|
|
26
|
+
font: 'Report Sans',
|
|
27
|
+
fontSize: 12,
|
|
28
|
+
});
|
|
29
|
+
await (await document.toResult()).download('report.pdf');
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`createDocument()` is asynchronous because it prepares fonts. Drawing and
|
|
33
|
+
measurement are synchronous afterwards, except `drawImage()` and `appendPDF()`,
|
|
34
|
+
which must be awaited. The document API does not require a browser or font
|
|
35
|
+
registration in the DOM. Use `registerFont()` separately for HTML exports.
|
|
36
|
+
|
|
37
|
+
| Setting | Default | Meaning |
|
|
38
|
+
| ------------- | ----------------------- | ----------------------------------------------------------------------------- |
|
|
39
|
+
| `unit` | `'pt'` | `'pt'`, `'mm'` or `'px'` for coordinates and dimensions. |
|
|
40
|
+
| `format` | `'A4'` | `'A4'`, `'A3'`, `'Letter'` or `{ width, height }` in document units. |
|
|
41
|
+
| `orientation` | `'portrait'` | Landscape swaps the supplied base axes. |
|
|
42
|
+
| `fonts` | Standard PDF fonts | Static TTF/OTF programs with `family`, `data`, optional `weight` and `style`. |
|
|
43
|
+
| `metadata` | Title: `'RenderPDF.js'` | Unicode title, author, subject and keyword strings. |
|
|
44
|
+
| `signal` | — | Cooperative cancellation via `AbortSignal`. |
|
|
45
|
+
|
|
46
|
+
Coordinates start at the top-left. Text `y` is a **baseline**, while rectangle and
|
|
47
|
+
image `y` is a top edge. Font sizes always use **points**, independent of `unit`.
|
|
48
|
+
`1 mm = 72/25.4 pt`; `1 px = 0.75 pt`. Rotation uses clockwise degrees.
|
|
49
|
+
|
|
50
|
+
Helvetica, Times and Courier include regular, bold, italic and bold-italic faces.
|
|
51
|
+
Their character sets are limited. For Czech and other Unicode text, provide an
|
|
52
|
+
appropriate font program. Select an exact face using `font`, `fontWeight` and
|
|
53
|
+
`fontStyle`; missing fonts and glyphs fail explicitly. Fonts are not substituted.
|
|
54
|
+
|
|
55
|
+
## Page management
|
|
56
|
+
|
|
57
|
+
`addPage(options?)` returns a page handle. It inherits document defaults; each page
|
|
58
|
+
can override its format and orientation. Documents start without an implicit page.
|
|
59
|
+
|
|
60
|
+
- `getPage(number)` and `getPages()` return existing handles in document order.
|
|
61
|
+
- `pageCount` reports the number of physical pages.
|
|
62
|
+
- `insertPage(number, options?)` inserts before a one-based position.
|
|
63
|
+
- `movePage(from, to)` reorders an existing page.
|
|
64
|
+
- `removePage(number)` removes an unreferenced page. Bookmark/link targets and
|
|
65
|
+
pages containing interactive fields cannot be removed; flatten fields first.
|
|
66
|
+
- `appendPDF(source, pageNumbers?)` imports supported native pages asynchronously.
|
|
67
|
+
- `addBookmark(title, { pageNumber, parent? })` creates a hierarchical page bookmark.
|
|
68
|
+
- `flattenForms()` replaces prepared form appearances with ordinary page content.
|
|
69
|
+
- `toResult()` finalizes once and reuses the completed result on later calls.
|
|
70
|
+
|
|
71
|
+
Page handles expose `width`, `height`, `rotation` and `setRotation(degrees)`.
|
|
72
|
+
Drawing coordinates are relative to the unrotated MediaBox; imported page origins
|
|
73
|
+
and `UserUnit` are normalized into physical document units. Crop boxes and view
|
|
74
|
+
rotation remain part of the page.
|
|
75
|
+
Page numbers are one-based. Removed handles cannot be drawn into. Bookmarks remain
|
|
76
|
+
attached to the same page when pages move. A finalized document cannot be edited.
|
|
77
|
+
|
|
78
|
+
## Text, graphics and images
|
|
79
|
+
|
|
80
|
+
`document.measureText(text, options?)` returns `width`, `height`, `ascent` and
|
|
81
|
+
`descent` in document units, using the same exact font as drawing.
|
|
82
|
+
|
|
83
|
+
| Page method | Input |
|
|
84
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
85
|
+
| `drawText(text, options)` | `x`, baseline `y`; optional font face, `fontSize`, `color`, `align`, `lineHeight`, `rotation`, `maxWidth`, `opacity` and `link`. |
|
|
86
|
+
| `drawLine(options)` | `x1`, `y1`, `x2`, `y2`; optional `color`, `width`, `opacity`. |
|
|
87
|
+
| `drawRectangle(options)` | `x`, `y`, `width`, `height` and paint settings. |
|
|
88
|
+
| `drawEllipse(options)` | Bounding rectangle and paint settings. |
|
|
89
|
+
| `drawCircle(options)` | Center `x`, `y`, `radius` and paint settings. |
|
|
90
|
+
| `drawSvgPath(path, options)` | SVG path data, `x`, `y`, optional `scale`, `rotation` and paint settings. |
|
|
91
|
+
| `drawImage(source, options)` | PNG/JPEG bytes, Blob, data URL, browser canvas/image; rectangle and optional rotation/opacity. **Await this call.** |
|
|
92
|
+
|
|
93
|
+
Paint settings are `fill`, `stroke`, `strokeWidth` and `opacity`. Colors accept
|
|
94
|
+
hexadecimal, `rgb()`/`rgba()` and common named colors. Unsupported colors fail
|
|
95
|
+
explicitly. Text line spacing defaults to `1.15` times the point size.
|
|
96
|
+
`drawSvgPath` draws native vector geometry; it does not interpret full SVG files.
|
|
97
|
+
Image placement uses the supplied rectangle and applies image orientation. For
|
|
98
|
+
multipage TIFF, use `imageToPDF()` and append its PDF result.
|
|
99
|
+
|
|
100
|
+
Paths use `moveTo()`, `lineTo()`, `curveTo()` and `closePath()`, followed by
|
|
101
|
+
`stroke()`, `fill()` or `fillAndStroke()`. `clip()` intersects the clip with the
|
|
102
|
+
current path; `discardPath()` ends the path afterwards. `clipRectangle()` combines
|
|
103
|
+
these steps. Use `saveGraphicsState()` and `restoreGraphicsState()` to bound
|
|
104
|
+
clipping and `transform([a,b,c,d,e,f])` changes.
|
|
105
|
+
|
|
106
|
+
Pending images, unfinished paths and unmatched graphics states prevent
|
|
107
|
+
finalization. Await each asynchronous image before further drawing on that page.
|
|
108
|
+
|
|
109
|
+
## Links, notes and forms
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
page.addLink('https://example.com/report', { x: 15, y: 10, width: 100, height: 20 });
|
|
113
|
+
page.addNote('Please review this value.', { x: 150, y: 30, width: 8, height: 8 });
|
|
114
|
+
page.addTextField(
|
|
115
|
+
'name',
|
|
116
|
+
{ x: 15, y: 50, width: 100, height: 12 },
|
|
117
|
+
{
|
|
118
|
+
value: 'Český text',
|
|
119
|
+
font: 'Report Sans',
|
|
120
|
+
fontSize: 12,
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
page.addCheckBox('approved', { x: 15, y: 70, width: 6, height: 6 }, { checked: true });
|
|
124
|
+
page.addDropdown('status', { x: 15, y: 90, width: 60, height: 12 }, ['Draft', 'Approved'], {
|
|
125
|
+
value: 'Draft',
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Field options include font face, `fontSize`, `textColor`, `borderColor`,
|
|
130
|
+
`backgroundColor`, `borderWidth`, `readOnly` and `required`. Text fields support
|
|
131
|
+
`multiline` and `maxLength`; dropdowns support `editable` and `multiselect`.
|
|
132
|
+
Field names must be unique. Supply a suitable font for Unicode appearances.
|
|
133
|
+
Fields are axis-aligned and reject nonidentity graphics transforms.
|
|
134
|
+
Field appearance colors must be opaque.
|
|
135
|
+
Links accept HTTP, HTTPS, mailto and telephone URLs; executable schemes are rejected.
|
|
136
|
+
|
|
137
|
+
For a left/right footer, draw independent text objects after the page count is known:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
for (const [index, output] of document.getPages().entries()) {
|
|
141
|
+
output.drawText('Printed by: Example', { x: 15, y: output.height - 8, fontSize: 8 });
|
|
142
|
+
output.drawText(`Page ${index + 1} of ${document.pageCount}`, {
|
|
143
|
+
x: output.width - 15,
|
|
144
|
+
y: output.height - 8,
|
|
145
|
+
fontSize: 8,
|
|
146
|
+
align: 'right',
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## PDF composition
|
|
152
|
+
|
|
153
|
+
`mergePDFs(sources, options?)` creates one PDF in source/page order.
|
|
154
|
+
`extractPDFPages(source, pageNumbers, options?)` preserves the requested one-based
|
|
155
|
+
order, including repeats. `splitPDF(source, options?)` returns one result per page.
|
|
156
|
+
Inputs accept `File`/`Blob`, `ArrayBuffer`, `Uint8Array` and completed export results;
|
|
157
|
+
the application fetches URLs itself. Options support `metadata`, `signal` and
|
|
158
|
+
`onProgress` with stage-local counters.
|
|
159
|
+
|
|
160
|
+
Pages retain text, vectors, image resources, sizes, crop boxes and rotation.
|
|
161
|
+
Explicit internal page links are remapped to the new page references. Named
|
|
162
|
+
destinations, links to omitted pages, encrypted/malformed PDFs and interactive
|
|
163
|
+
AcroForm/XFA inputs fail explicitly. Flatten fields before composition.
|
|
164
|
+
Document-level outlines, signatures, attachments and original metadata are not copied.
|
|
165
|
+
Composition is limited to 1,000 pages, 128 MiB per input and 256 MiB total input.
|
|
166
|
+
|
|
167
|
+
## DevExtreme adapter
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { createJsPDFAdapter } from 'renderpdf-js';
|
|
171
|
+
import { exportDataGrid } from 'devextreme/pdf_exporter';
|
|
172
|
+
|
|
173
|
+
const doc = await createJsPDFAdapter({
|
|
174
|
+
unit: 'mm',
|
|
175
|
+
format: 'A4',
|
|
176
|
+
orientation: 'landscape',
|
|
177
|
+
fonts: [{ family: 'Report Sans', data: fontBytes }],
|
|
178
|
+
});
|
|
179
|
+
doc.setFont('Report Sans');
|
|
180
|
+
await exportDataGrid({ jsPDFDocument: doc, component: grid, selectedRowsOnly: true });
|
|
181
|
+
await doc.save('grid.pdf');
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
The adapter is verified with DevExtreme 25.1.5. Its default unit is
|
|
185
|
+
`'mm'`, and it creates an initial page. Font metrics and drawing methods are
|
|
186
|
+
synchronous; ordered operations are flushed during asynchronous finalization.
|
|
187
|
+
Use `await doc.output('blob')`, `await doc.toBlob()` or `await doc.save(name)`.
|
|
188
|
+
Synchronous jsPDF output is not emulated. Fonts must be supplied to the factory;
|
|
189
|
+
VFS/runtime font registration and arbitrary jsPDF plugins are unsupported.
|
|
190
|
+
|
|
191
|
+
Supported methods include page selection/addition, font and color state, text
|
|
192
|
+
measurement/wrapping, text/line/rectangle/image drawing, clipping, graphics-state
|
|
193
|
+
save/restore and the exporter's unit/color compatibility properties. The adapter
|
|
194
|
+
does not expose all jsPDF APIs or its advanced scripting features.
|
|
195
|
+
|
|
196
|
+
Run the optional integration against your separately installed DevExtreme:
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
# Set RENDERPDF_DEVEXTREME_DIR to the absolute installed devextreme package directory.
|
|
200
|
+
npm run test:devextreme
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The regular checks do not require DevExtreme. Its implementation is not copied
|
|
204
|
+
into RenderPDF.js, and it is not a runtime or development dependency of the package.
|