pdf-lite 1.0.8 → 1.1.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/EXAMPLES.md +190 -1
- package/dist/acroform/acroform.d.ts +166 -0
- package/dist/acroform/acroform.js +412 -0
- package/dist/acroform/index.d.ts +1 -1
- package/dist/acroform/index.js +1 -1
- package/dist/acroform/manager.d.ts +26 -0
- package/dist/acroform/manager.js +39 -0
- package/dist/fonts/font-manager.d.ts +84 -0
- package/dist/fonts/font-manager.js +504 -0
- package/dist/fonts/index.d.ts +6 -0
- package/dist/fonts/index.js +6 -0
- package/dist/fonts/parsers/font-parser.d.ts +18 -0
- package/dist/fonts/parsers/font-parser.js +35 -0
- package/dist/fonts/parsers/otf-parser.d.ts +47 -0
- package/dist/fonts/parsers/otf-parser.js +349 -0
- package/dist/fonts/parsers/ttf-parser.d.ts +38 -0
- package/dist/fonts/parsers/ttf-parser.js +343 -0
- package/dist/fonts/parsers/woff-parser.d.ts +32 -0
- package/dist/fonts/parsers/woff-parser.js +137 -0
- package/dist/fonts/types.d.ts +69 -0
- package/dist/fonts/types.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/pdf/pdf-document.d.ts +6 -2
- package/dist/pdf/pdf-document.js +11 -2
- package/dist/xfa/index.d.ts +1 -1
- package/dist/xfa/index.js +1 -1
- package/package.json +1 -1
- package/dist/acroform/acroform-manager.d.ts +0 -49
- package/dist/acroform/acroform-manager.js +0 -215
- /package/dist/xfa/{xfa-manager.d.ts → manager.d.ts} +0 -0
- /package/dist/xfa/{xfa-manager.js → manager.js} +0 -0
package/EXAMPLES.md
CHANGED
|
@@ -1109,12 +1109,17 @@ console.log('Created form-empty.pdf with empty form fields')
|
|
|
1109
1109
|
const emptyFormBytes = await fs.readFile(`${tmpFolder}/form-empty.pdf`)
|
|
1110
1110
|
const filledDocument = await PdfDocument.fromBytes([emptyFormBytes])
|
|
1111
1111
|
|
|
1112
|
-
await filledDocument.acroForm.
|
|
1112
|
+
const acroform = await filledDocument.acroForm.getAcroForm()
|
|
1113
|
+
if (!acroform) {
|
|
1114
|
+
throw new Error('No AcroForm found in the document')
|
|
1115
|
+
}
|
|
1116
|
+
acroform.importData({
|
|
1113
1117
|
name: 'John Doe',
|
|
1114
1118
|
email: 'john.doe@example.com',
|
|
1115
1119
|
phone: '+1 (555) 123-4567',
|
|
1116
1120
|
subscribe: 'Off', // For checkbox, use the "Yes/Off" value
|
|
1117
1121
|
})
|
|
1122
|
+
await filledDocument.acroForm.write(acroform)
|
|
1118
1123
|
|
|
1119
1124
|
// Save the filled form
|
|
1120
1125
|
await fs.writeFile(`${tmpFolder}/form-filled.pdf`, filledDocument.toBytes())
|
|
@@ -1814,3 +1819,187 @@ console.log(
|
|
|
1814
1819
|
JSON.stringify(validationResult, null, 2),
|
|
1815
1820
|
)
|
|
1816
1821
|
```
|
|
1822
|
+
|
|
1823
|
+
## Custom font embedding example
|
|
1824
|
+
|
|
1825
|
+
```typescript
|
|
1826
|
+
// Demonstrates how to embed TrueType fonts and use standard PDF fonts
|
|
1827
|
+
|
|
1828
|
+
import { writeFileSync, readFileSync, existsSync } from 'fs'
|
|
1829
|
+
import { PdfArray } from 'pdf-lite/core/objects/pdf-array'
|
|
1830
|
+
import { PdfDictionary } from 'pdf-lite/core/objects/pdf-dictionary'
|
|
1831
|
+
import { PdfIndirectObject } from 'pdf-lite/core/objects/pdf-indirect-object'
|
|
1832
|
+
import { PdfName } from 'pdf-lite/core/objects/pdf-name'
|
|
1833
|
+
import { PdfNumber } from 'pdf-lite/core/objects/pdf-number'
|
|
1834
|
+
import { PdfStream } from 'pdf-lite/core/objects/pdf-stream'
|
|
1835
|
+
import { PdfDocument } from 'pdf-lite/pdf/pdf-document'
|
|
1836
|
+
import { parseFont } from 'pdf-lite'
|
|
1837
|
+
|
|
1838
|
+
// Helper to create a page
|
|
1839
|
+
function createPage(
|
|
1840
|
+
contentStreamRef: PdfIndirectObject<PdfStream>,
|
|
1841
|
+
resourcesRef: PdfIndirectObject<PdfDictionary>,
|
|
1842
|
+
pagesRef: PdfIndirectObject<PdfDictionary>,
|
|
1843
|
+
): PdfIndirectObject<PdfDictionary> {
|
|
1844
|
+
const pageDict = new PdfDictionary()
|
|
1845
|
+
pageDict.set('Type', new PdfName('Page'))
|
|
1846
|
+
pageDict.set(
|
|
1847
|
+
'MediaBox',
|
|
1848
|
+
new PdfArray([
|
|
1849
|
+
new PdfNumber(0),
|
|
1850
|
+
new PdfNumber(0),
|
|
1851
|
+
new PdfNumber(612),
|
|
1852
|
+
new PdfNumber(792),
|
|
1853
|
+
]),
|
|
1854
|
+
)
|
|
1855
|
+
pageDict.set('Contents', contentStreamRef.reference)
|
|
1856
|
+
pageDict.set('Resources', resourcesRef.reference)
|
|
1857
|
+
pageDict.set('Parent', pagesRef.reference)
|
|
1858
|
+
return new PdfIndirectObject({ content: pageDict })
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
function createPages(): PdfIndirectObject<PdfDictionary> {
|
|
1862
|
+
const pagesDict = new PdfDictionary()
|
|
1863
|
+
pagesDict.set('Type', new PdfName('Pages'))
|
|
1864
|
+
pagesDict.set('Kids', new PdfArray([]))
|
|
1865
|
+
pagesDict.set('Count', new PdfNumber(0))
|
|
1866
|
+
return new PdfIndirectObject({ content: pagesDict })
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
function createCatalog(
|
|
1870
|
+
pagesRef: PdfIndirectObject<PdfDictionary>,
|
|
1871
|
+
): PdfIndirectObject<PdfDictionary> {
|
|
1872
|
+
const catalogDict = new PdfDictionary()
|
|
1873
|
+
catalogDict.set('Type', new PdfName('Catalog'))
|
|
1874
|
+
catalogDict.set('Pages', pagesRef.reference)
|
|
1875
|
+
return new PdfIndirectObject({ content: catalogDict })
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
async function main() {
|
|
1879
|
+
const document = new PdfDocument()
|
|
1880
|
+
|
|
1881
|
+
// Create document structure
|
|
1882
|
+
const pages = createPages()
|
|
1883
|
+
const catalog = createCatalog(pages)
|
|
1884
|
+
|
|
1885
|
+
document.add(pages, catalog)
|
|
1886
|
+
document.trailerDict.set('Root', catalog.reference)
|
|
1887
|
+
await document.commit()
|
|
1888
|
+
|
|
1889
|
+
// Embed a standard font (built into all PDF readers)
|
|
1890
|
+
const helveticaBold =
|
|
1891
|
+
await document.fonts.embedStandardFont('Helvetica-Bold')
|
|
1892
|
+
const timesRoman = await document.fonts.embedStandardFont('Times-Roman')
|
|
1893
|
+
const courier = await document.fonts.embedStandardFont('Courier')
|
|
1894
|
+
|
|
1895
|
+
console.log(
|
|
1896
|
+
`Embedded standard fonts: ${helveticaBold}, ${timesRoman}, ${courier}`,
|
|
1897
|
+
)
|
|
1898
|
+
|
|
1899
|
+
// Embed Roboto TrueType font
|
|
1900
|
+
const fontPath = `${import.meta.dirname}/tmp/Roboto-Regular.ttf`
|
|
1901
|
+
|
|
1902
|
+
if (!existsSync(fontPath)) {
|
|
1903
|
+
console.error(`Font not found: ${fontPath}`)
|
|
1904
|
+
console.error(
|
|
1905
|
+
'Download it with: curl -L -o examples/tmp/Roboto-Regular.ttf "https://github.com/google/fonts/raw/main/ofl/roboto/Roboto%5Bwdth%2Cwght%5D.ttf"',
|
|
1906
|
+
)
|
|
1907
|
+
process.exit(1)
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
const fontData = readFileSync(fontPath)
|
|
1911
|
+
|
|
1912
|
+
// Parse the font file to extract metrics automatically
|
|
1913
|
+
// parseFont() auto-detects TTF, OTF, and WOFF formats
|
|
1914
|
+
const parser = parseFont(fontData)
|
|
1915
|
+
const fontInfo = parser.getFontInfo()
|
|
1916
|
+
const fontDescriptor = parser.getFontDescriptor('Roboto')
|
|
1917
|
+
|
|
1918
|
+
console.log(`Parsed font: ${fontInfo.fullName} (${fontInfo.fontFamily})`)
|
|
1919
|
+
|
|
1920
|
+
const robotoFont = await document.fonts.embedTrueTypeFont(
|
|
1921
|
+
fontData,
|
|
1922
|
+
'Roboto',
|
|
1923
|
+
fontDescriptor,
|
|
1924
|
+
)
|
|
1925
|
+
console.log(`Embedded Roboto TrueType font: ${robotoFont}`)
|
|
1926
|
+
|
|
1927
|
+
// Create resources dictionary with fonts
|
|
1928
|
+
const resourcesDict = new PdfDictionary()
|
|
1929
|
+
const fontDict = new PdfDictionary()
|
|
1930
|
+
|
|
1931
|
+
// Get font references from the font manager
|
|
1932
|
+
const helveticaFont = document.fonts.getFont('Helvetica-Bold')
|
|
1933
|
+
const timesFont = document.fonts.getFont('Times-Roman')
|
|
1934
|
+
const courierFont = document.fonts.getFont('Courier')
|
|
1935
|
+
|
|
1936
|
+
if (helveticaFont)
|
|
1937
|
+
fontDict.set(helveticaFont.baseFont, helveticaFont.fontRef.reference)
|
|
1938
|
+
if (timesFont) fontDict.set(timesFont.baseFont, timesFont.fontRef.reference)
|
|
1939
|
+
if (courierFont)
|
|
1940
|
+
fontDict.set(courierFont.baseFont, courierFont.fontRef.reference)
|
|
1941
|
+
|
|
1942
|
+
const roboto = document.fonts.getFont('Roboto')
|
|
1943
|
+
if (roboto) fontDict.set(roboto.baseFont, roboto.fontRef.reference)
|
|
1944
|
+
|
|
1945
|
+
resourcesDict.set('Font', fontDict)
|
|
1946
|
+
const resources = new PdfIndirectObject({ content: resourcesDict })
|
|
1947
|
+
|
|
1948
|
+
// Build content stream with different fonts
|
|
1949
|
+
// F1=Helvetica-Bold, F2=Times-Roman, F3=Courier, F4=Roboto
|
|
1950
|
+
const lines: string[] = [
|
|
1951
|
+
'BT',
|
|
1952
|
+
'/F1 24 Tf',
|
|
1953
|
+
'72 700 Td',
|
|
1954
|
+
'(PDF-Lite Custom Fonts Demo) Tj',
|
|
1955
|
+
'/F4 16 Tf',
|
|
1956
|
+
'0 -40 Td',
|
|
1957
|
+
'(This line uses embedded Roboto font!) Tj',
|
|
1958
|
+
'/F2 14 Tf',
|
|
1959
|
+
'0 -30 Td',
|
|
1960
|
+
'(This line uses Times Roman) Tj',
|
|
1961
|
+
'/F3 12 Tf',
|
|
1962
|
+
'0 -30 Td',
|
|
1963
|
+
'(This line uses Courier - great for code!) Tj',
|
|
1964
|
+
'/F2 12 Tf',
|
|
1965
|
+
'0 -50 Td',
|
|
1966
|
+
'(Standard PDF fonts are built into all PDF readers:) Tj',
|
|
1967
|
+
'0 -20 Td',
|
|
1968
|
+
'(- Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique) Tj',
|
|
1969
|
+
'0 -20 Td',
|
|
1970
|
+
'(- Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic) Tj',
|
|
1971
|
+
'0 -20 Td',
|
|
1972
|
+
'(- Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique) Tj',
|
|
1973
|
+
'0 -20 Td',
|
|
1974
|
+
'(- Symbol, ZapfDingbats) Tj',
|
|
1975
|
+
'/F4 12 Tf',
|
|
1976
|
+
'0 -40 Td',
|
|
1977
|
+
'(Custom TrueType fonts like Roboto are embedded in the PDF file.) Tj',
|
|
1978
|
+
'ET',
|
|
1979
|
+
]
|
|
1980
|
+
|
|
1981
|
+
const contentStream = new PdfIndirectObject({
|
|
1982
|
+
content: new PdfStream({
|
|
1983
|
+
header: new PdfDictionary(),
|
|
1984
|
+
original: lines.join('\n'),
|
|
1985
|
+
}),
|
|
1986
|
+
})
|
|
1987
|
+
|
|
1988
|
+
// Create page
|
|
1989
|
+
const page = createPage(contentStream, resources, pages)
|
|
1990
|
+
|
|
1991
|
+
// Update pages collection
|
|
1992
|
+
pages.content.set('Kids', new PdfArray([page.reference]))
|
|
1993
|
+
pages.content.set('Count', new PdfNumber(1))
|
|
1994
|
+
|
|
1995
|
+
document.add(resources, contentStream, page)
|
|
1996
|
+
await document.commit()
|
|
1997
|
+
|
|
1998
|
+
// Write output
|
|
1999
|
+
const outputPath = `${import.meta.dirname}/tmp/fonts-demo.pdf`
|
|
2000
|
+
writeFileSync(outputPath, document.toBytes())
|
|
2001
|
+
console.log(`\nPDF written to: ${outputPath}`)
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
main().catch(console.error)
|
|
2005
|
+
```
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { PdfDocument } from '../pdf/pdf-document.js';
|
|
2
|
+
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
3
|
+
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
4
|
+
import { PdfString } from '../core/objects/pdf-string.js';
|
|
5
|
+
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
6
|
+
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
7
|
+
import { PdfName } from '../core/objects/pdf-name.js';
|
|
8
|
+
import { PdfBoolean } from '../core/objects/pdf-boolean.js';
|
|
9
|
+
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
10
|
+
/**
|
|
11
|
+
* Field types for AcroForm fields
|
|
12
|
+
*/
|
|
13
|
+
export declare const PdfFieldType: {
|
|
14
|
+
readonly Text: "Tx";
|
|
15
|
+
readonly Button: "Btn";
|
|
16
|
+
readonly Choice: "Ch";
|
|
17
|
+
readonly Signature: "Sig";
|
|
18
|
+
};
|
|
19
|
+
export declare class PdfAcroFormField extends PdfDictionary<{
|
|
20
|
+
FT: PdfName<'Tx' | 'Btn' | 'Ch' | 'Sig'>;
|
|
21
|
+
T?: PdfString;
|
|
22
|
+
V?: PdfString | PdfName;
|
|
23
|
+
DV?: PdfString | PdfName;
|
|
24
|
+
DA?: PdfString;
|
|
25
|
+
AS?: PdfName;
|
|
26
|
+
Kids?: PdfArray<PdfObjectReference>;
|
|
27
|
+
P?: PdfObjectReference;
|
|
28
|
+
Rect?: PdfArray<PdfNumber>;
|
|
29
|
+
F?: PdfNumber;
|
|
30
|
+
Ff?: PdfNumber;
|
|
31
|
+
BS?: PdfDictionary;
|
|
32
|
+
MK?: PdfDictionary;
|
|
33
|
+
}> {
|
|
34
|
+
parent?: PdfAcroFormField;
|
|
35
|
+
readonly container?: PdfIndirectObject;
|
|
36
|
+
constructor(options?: {
|
|
37
|
+
container?: PdfIndirectObject;
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Gets the field type
|
|
41
|
+
*/
|
|
42
|
+
get fieldType(): string | null;
|
|
43
|
+
/**
|
|
44
|
+
* Gets the field name
|
|
45
|
+
*/
|
|
46
|
+
get name(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Sets the field name
|
|
49
|
+
*/
|
|
50
|
+
set name(name: string);
|
|
51
|
+
/**
|
|
52
|
+
* Gets the default value
|
|
53
|
+
*/
|
|
54
|
+
get defaultValue(): string;
|
|
55
|
+
/**
|
|
56
|
+
* Sets the default value
|
|
57
|
+
*/
|
|
58
|
+
set defaultValue(val: string);
|
|
59
|
+
get value(): string;
|
|
60
|
+
set value(val: string);
|
|
61
|
+
get checked(): boolean;
|
|
62
|
+
set checked(isChecked: boolean);
|
|
63
|
+
get fontSize(): number | null;
|
|
64
|
+
set fontSize(size: number);
|
|
65
|
+
get fontName(): string | null;
|
|
66
|
+
set fontName(fontName: string);
|
|
67
|
+
/**
|
|
68
|
+
* Gets field flags (bitwise combination of field attributes)
|
|
69
|
+
*/
|
|
70
|
+
get flags(): number;
|
|
71
|
+
/**
|
|
72
|
+
* Sets field flags
|
|
73
|
+
*/
|
|
74
|
+
set flags(flags: number);
|
|
75
|
+
/**
|
|
76
|
+
* Checks if the field is read-only
|
|
77
|
+
*/
|
|
78
|
+
get readOnly(): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Sets the field as read-only or editable
|
|
81
|
+
*/
|
|
82
|
+
set readOnly(isReadOnly: boolean);
|
|
83
|
+
/**
|
|
84
|
+
* Checks if the field is required
|
|
85
|
+
*/
|
|
86
|
+
get required(): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Sets the field as required or optional
|
|
89
|
+
*/
|
|
90
|
+
set required(isRequired: boolean);
|
|
91
|
+
/**
|
|
92
|
+
* Checks if the field is multiline (for text fields)
|
|
93
|
+
*/
|
|
94
|
+
get multiline(): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Sets the field as multiline (for text fields)
|
|
97
|
+
*/
|
|
98
|
+
set multiline(isMultiline: boolean);
|
|
99
|
+
/**
|
|
100
|
+
* Checks if the field is a password field (for text fields)
|
|
101
|
+
*/
|
|
102
|
+
get password(): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Sets the field as a password field (for text fields)
|
|
105
|
+
*/
|
|
106
|
+
set password(isPassword: boolean);
|
|
107
|
+
}
|
|
108
|
+
export declare class PdfAcroForm<T extends Record<string, string> = Record<string, string>> extends PdfDictionary<{
|
|
109
|
+
Fields: PdfArray<PdfObjectReference>;
|
|
110
|
+
NeedAppearances?: PdfBoolean;
|
|
111
|
+
SigFlags?: PdfNumber;
|
|
112
|
+
CO?: PdfArray<PdfObjectReference>;
|
|
113
|
+
DR?: PdfDictionary;
|
|
114
|
+
DA?: PdfString;
|
|
115
|
+
Q?: PdfNumber;
|
|
116
|
+
}> {
|
|
117
|
+
fields: PdfAcroFormField[];
|
|
118
|
+
readonly container?: PdfIndirectObject;
|
|
119
|
+
constructor(options: {
|
|
120
|
+
dict: PdfDictionary;
|
|
121
|
+
fields?: PdfAcroFormField[];
|
|
122
|
+
container?: PdfIndirectObject;
|
|
123
|
+
});
|
|
124
|
+
/**
|
|
125
|
+
* Gets the NeedAppearances flag
|
|
126
|
+
*/
|
|
127
|
+
get needAppearances(): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Sets the NeedAppearances flag to indicate that appearance streams need to be regenerated
|
|
130
|
+
*/
|
|
131
|
+
set needAppearances(value: boolean);
|
|
132
|
+
/**
|
|
133
|
+
* Gets the signature flags
|
|
134
|
+
*/
|
|
135
|
+
get signatureFlags(): number;
|
|
136
|
+
/**
|
|
137
|
+
* Sets the signature flags
|
|
138
|
+
*/
|
|
139
|
+
set signatureFlags(flags: number);
|
|
140
|
+
/**
|
|
141
|
+
* Gets the default appearance string for the form
|
|
142
|
+
*/
|
|
143
|
+
get defaultAppearance(): string | null;
|
|
144
|
+
/**
|
|
145
|
+
* Sets the default appearance string for the form
|
|
146
|
+
*/
|
|
147
|
+
set defaultAppearance(da: string);
|
|
148
|
+
/**
|
|
149
|
+
* Gets the default quadding (alignment) for the form
|
|
150
|
+
* 0 = left, 1 = center, 2 = right
|
|
151
|
+
*/
|
|
152
|
+
get defaultQuadding(): number;
|
|
153
|
+
/**
|
|
154
|
+
* Sets the default quadding (alignment) for the form
|
|
155
|
+
*/
|
|
156
|
+
set defaultQuadding(q: number);
|
|
157
|
+
/**
|
|
158
|
+
* Sets multiple field values by field name.
|
|
159
|
+
* @param values Object with field names as keys and values to set
|
|
160
|
+
* */
|
|
161
|
+
setValues(values: Partial<T>): void;
|
|
162
|
+
importData(fields: T): void;
|
|
163
|
+
exportData(): Partial<T>;
|
|
164
|
+
static fromDocument(document: PdfDocument): Promise<PdfAcroForm | null>;
|
|
165
|
+
write(document: PdfDocument): Promise<void>;
|
|
166
|
+
}
|