pdf-lite 1.0.4 → 1.0.6
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 +37 -87
- package/README.md +104 -144
- package/dist/acroform/acroform-manager.d.ts +49 -0
- package/dist/acroform/acroform-manager.js +215 -0
- package/dist/acroform/index.d.ts +1 -0
- package/dist/acroform/index.js +1 -0
- package/dist/core/generators.d.ts +2 -2
- package/dist/core/generators.js +3 -3
- package/dist/core/incremental-parser.d.ts +1 -1
- package/dist/core/incremental-parser.js +1 -1
- package/dist/core/objects/pdf-array.d.ts +3 -3
- package/dist/core/objects/pdf-array.js +4 -4
- package/dist/core/objects/pdf-boolean.d.ts +2 -2
- package/dist/core/objects/pdf-boolean.js +2 -2
- package/dist/core/objects/pdf-comment.d.ts +3 -3
- package/dist/core/objects/pdf-comment.js +4 -4
- package/dist/core/objects/pdf-date.d.ts +1 -1
- package/dist/core/objects/pdf-date.js +1 -1
- package/dist/core/objects/pdf-dictionary.d.ts +3 -3
- package/dist/core/objects/pdf-dictionary.js +5 -5
- package/dist/core/objects/pdf-hexadecimal.d.ts +3 -3
- package/dist/core/objects/pdf-hexadecimal.js +6 -6
- package/dist/core/objects/pdf-indirect-object.d.ts +5 -5
- package/dist/core/objects/pdf-indirect-object.js +9 -9
- package/dist/core/objects/pdf-name.d.ts +2 -2
- package/dist/core/objects/pdf-name.js +2 -2
- package/dist/core/objects/pdf-null.d.ts +2 -2
- package/dist/core/objects/pdf-null.js +2 -2
- package/dist/core/objects/pdf-number.d.ts +3 -3
- package/dist/core/objects/pdf-number.js +3 -3
- package/dist/core/objects/pdf-object-reference.d.ts +2 -2
- package/dist/core/objects/pdf-object-reference.js +2 -2
- package/dist/core/objects/pdf-start-xref.d.ts +4 -4
- package/dist/core/objects/pdf-start-xref.js +4 -4
- package/dist/core/objects/pdf-stream.d.ts +9 -8
- package/dist/core/objects/pdf-stream.js +39 -26
- package/dist/core/objects/pdf-string.d.ts +3 -3
- package/dist/core/objects/pdf-string.js +4 -4
- package/dist/core/objects/pdf-trailer.d.ts +8 -8
- package/dist/core/objects/pdf-trailer.js +6 -6
- package/dist/core/objects/pdf-xref-table.d.ts +7 -7
- package/dist/core/objects/pdf-xref-table.js +8 -8
- package/dist/core/serializer.d.ts +3 -3
- package/dist/core/serializer.js +2 -2
- package/dist/core/streams/object-stream.d.ts +3 -3
- package/dist/core/streams/object-stream.js +2 -2
- package/dist/core/tokens/boolean-token.d.ts +1 -1
- package/dist/core/tokens/boolean-token.js +1 -1
- package/dist/core/tokens/byte-offset-token.d.ts +2 -2
- package/dist/core/tokens/byte-offset-token.js +2 -2
- package/dist/core/tokens/comment-token.d.ts +2 -2
- package/dist/core/tokens/comment-token.js +4 -4
- package/dist/core/tokens/end-array-token.d.ts +1 -1
- package/dist/core/tokens/end-array-token.js +2 -2
- package/dist/core/tokens/end-dictionary-token.d.ts +1 -1
- package/dist/core/tokens/end-dictionary-token.js +2 -2
- package/dist/core/tokens/end-object-token.d.ts +1 -1
- package/dist/core/tokens/end-object-token.js +2 -2
- package/dist/core/tokens/end-stream-token.d.ts +2 -2
- package/dist/core/tokens/end-stream-token.js +2 -2
- package/dist/core/tokens/hexadecimal-token.d.ts +2 -2
- package/dist/core/tokens/hexadecimal-token.js +2 -2
- package/dist/core/tokens/name-token.d.ts +1 -1
- package/dist/core/tokens/name-token.js +2 -2
- package/dist/core/tokens/null-token.d.ts +1 -1
- package/dist/core/tokens/null-token.js +2 -2
- package/dist/core/tokens/number-token.d.ts +3 -3
- package/dist/core/tokens/number-token.js +3 -3
- package/dist/core/tokens/object-reference-token.d.ts +1 -1
- package/dist/core/tokens/object-reference-token.js +2 -2
- package/dist/core/tokens/start-array-token.d.ts +1 -1
- package/dist/core/tokens/start-array-token.js +2 -2
- package/dist/core/tokens/start-dictionary-token.d.ts +1 -1
- package/dist/core/tokens/start-dictionary-token.js +2 -2
- package/dist/core/tokens/start-object-token.d.ts +1 -1
- package/dist/core/tokens/start-object-token.js +2 -2
- package/dist/core/tokens/start-stream-token.d.ts +3 -3
- package/dist/core/tokens/start-stream-token.js +3 -3
- package/dist/core/tokens/start-xref-token.d.ts +1 -1
- package/dist/core/tokens/start-xref-token.js +2 -2
- package/dist/core/tokens/stream-chunk-token.d.ts +2 -2
- package/dist/core/tokens/stream-chunk-token.js +1 -1
- package/dist/core/tokens/string-token.d.ts +2 -2
- package/dist/core/tokens/string-token.js +3 -3
- package/dist/core/tokens/token.d.ts +1 -1
- package/dist/core/tokens/token.js +1 -1
- package/dist/core/tokens/trailer-token.d.ts +1 -1
- package/dist/core/tokens/trailer-token.js +2 -2
- package/dist/core/tokens/whitespace-token.d.ts +2 -2
- package/dist/core/tokens/whitespace-token.js +1 -1
- package/dist/core/tokens/xref-table-entry-token.d.ts +3 -3
- package/dist/core/tokens/xref-table-entry-token.js +2 -2
- package/dist/core/tokens/xref-table-section-start-token.d.ts +2 -2
- package/dist/core/tokens/xref-table-section-start-token.js +3 -3
- package/dist/core/tokens/xref-table-start-token.d.ts +1 -1
- package/dist/core/tokens/xref-table-start-token.js +2 -2
- package/dist/crypto/key-derivation/key-derivation-aes256.d.ts +1 -1
- package/dist/crypto/key-derivation/key-derivation-aes256.js +2 -2
- package/dist/crypto/key-gen/key-gen-rc4-128.d.ts +1 -1
- package/dist/crypto/key-gen/key-gen-rc4-128.js +5 -5
- package/dist/crypto/types.d.ts +1 -1
- package/dist/filters/asciihex.d.ts +1 -1
- package/dist/filters/asciihex.js +2 -2
- package/dist/filters/lzw.d.ts +1 -1
- package/dist/filters/types.d.ts +1 -1
- package/dist/pdf/pdf-document.d.ts +28 -14
- package/dist/pdf/pdf-document.js +60 -21
- package/dist/pdf/pdf-reader.d.ts +3 -3
- package/dist/pdf/pdf-reader.js +2 -2
- package/dist/pdf/pdf-revision.d.ts +5 -5
- package/dist/pdf/pdf-revision.js +4 -4
- package/dist/pdf/pdf-xref-lookup.d.ts +7 -7
- package/dist/pdf/pdf-xref-lookup.js +11 -10
- package/dist/security/crypt-filters/aesv2.d.ts +2 -2
- package/dist/security/crypt-filters/aesv2.js +2 -2
- package/dist/security/crypt-filters/aesv3.d.ts +2 -2
- package/dist/security/crypt-filters/aesv3.js +2 -2
- package/dist/security/crypt-filters/base.d.ts +4 -4
- package/dist/security/crypt-filters/base.js +3 -3
- package/dist/security/crypt-filters/identity.d.ts +2 -2
- package/dist/security/crypt-filters/identity.js +1 -1
- package/dist/security/crypt-filters/v2.d.ts +1 -1
- package/dist/security/crypt-filters/v2.js +1 -1
- package/dist/security/handlers/base.d.ts +4 -4
- package/dist/security/handlers/base.js +12 -12
- package/dist/security/handlers/pubSec.d.ts +3 -3
- package/dist/security/handlers/pubSec.js +10 -10
- package/dist/security/handlers/utils.d.ts +4 -4
- package/dist/security/handlers/utils.js +12 -12
- package/dist/security/handlers/v1.d.ts +4 -4
- package/dist/security/handlers/v1.js +7 -7
- package/dist/security/handlers/v2.d.ts +3 -3
- package/dist/security/handlers/v2.js +5 -5
- package/dist/security/handlers/v4.d.ts +6 -6
- package/dist/security/handlers/v4.js +11 -11
- package/dist/security/handlers/v5.d.ts +5 -5
- package/dist/security/handlers/v5.js +9 -9
- package/dist/security/types.d.ts +9 -9
- package/dist/signing/document-security-store.d.ts +11 -11
- package/dist/signing/document-security-store.js +4 -4
- package/dist/signing/signatures/adbe-pkcs7-detached.d.ts +4 -4
- package/dist/signing/signatures/adbe-pkcs7-detached.js +11 -11
- package/dist/signing/signatures/adbe-pkcs7-sha1.d.ts +4 -4
- package/dist/signing/signatures/adbe-pkcs7-sha1.js +12 -12
- package/dist/signing/signatures/adbe-x509-rsa-sha1.d.ts +4 -4
- package/dist/signing/signatures/adbe-x509-rsa-sha1.js +8 -8
- package/dist/signing/signatures/base.d.ts +5 -5
- package/dist/signing/signatures/base.js +11 -11
- package/dist/signing/signatures/etsi-cades-detached.d.ts +4 -4
- package/dist/signing/signatures/etsi-cades-detached.js +17 -17
- package/dist/signing/signatures/etsi-rfc3161.d.ts +2 -2
- package/dist/signing/signatures/etsi-rfc3161.js +9 -9
- package/dist/signing/signatures/index.d.ts +6 -6
- package/dist/signing/signatures/index.js +6 -6
- package/dist/signing/signer.d.ts +3 -3
- package/dist/signing/signer.js +10 -10
- package/dist/signing/types.d.ts +7 -7
- package/dist/signing/utils.d.ts +2 -2
- package/dist/signing/utils.js +1 -1
- package/dist/utils/algos.js +1 -1
- package/dist/utils/bytesToHex.d.ts +1 -1
- package/dist/utils/bytesToHex.js +2 -2
- package/dist/utils/bytesToHexBytes.d.ts +1 -1
- package/dist/utils/bytesToString.d.ts +1 -1
- package/dist/utils/concatUint8Arrays.d.ts +1 -1
- package/dist/utils/escapeString.d.ts +1 -1
- package/dist/utils/escapeString.js +1 -1
- package/dist/utils/hexBytesToBytes.d.ts +1 -1
- package/dist/utils/hexBytesToString.d.ts +1 -1
- package/dist/utils/hexToBytes.d.ts +1 -1
- package/dist/utils/hexToBytes.js +2 -2
- package/dist/utils/padBytes.d.ts +1 -1
- package/dist/utils/replaceInBuffer.d.ts +1 -1
- package/dist/utils/stringToBytes.d.ts +1 -1
- package/dist/utils/stringToHexBytes.d.ts +1 -1
- package/dist/utils/unescapeString.d.ts +1 -1
- package/dist/xfa/index.d.ts +1 -0
- package/dist/xfa/index.js +1 -0
- package/dist/xfa/xfa-manager.d.ts +44 -0
- package/dist/xfa/xfa-manager.js +138 -0
- package/package.json +3 -3
package/EXAMPLES.md
CHANGED
|
@@ -915,6 +915,18 @@ function createTextField(
|
|
|
915
915
|
// Default appearance string (font and size)
|
|
916
916
|
fieldDict.set('DA', new PdfString('/Helv 12 Tf 0 g'))
|
|
917
917
|
|
|
918
|
+
// Border style (solid, 1pt width)
|
|
919
|
+
const borderDict = new PdfDictionary()
|
|
920
|
+
borderDict.set('W', new PdfNumber(1))
|
|
921
|
+
borderDict.set('S', new PdfName('S'))
|
|
922
|
+
fieldDict.set('BS', borderDict)
|
|
923
|
+
|
|
924
|
+
// Appearance characteristics
|
|
925
|
+
const mkDict = new PdfDictionary()
|
|
926
|
+
mkDict.set('BC', new PdfArray([new PdfNumber(0)])) // Border color (black)
|
|
927
|
+
mkDict.set('BG', new PdfArray([new PdfNumber(1)])) // Background color (white)
|
|
928
|
+
fieldDict.set('MK', mkDict)
|
|
929
|
+
|
|
918
930
|
return new PdfIndirectObject({ content: fieldDict })
|
|
919
931
|
}
|
|
920
932
|
|
|
@@ -951,6 +963,18 @@ function createCheckboxField(
|
|
|
951
963
|
fieldDict.set('V', new PdfName(checked ? 'Yes' : 'Off'))
|
|
952
964
|
fieldDict.set('AS', new PdfName(checked ? 'Yes' : 'Off'))
|
|
953
965
|
|
|
966
|
+
// Border style
|
|
967
|
+
const borderDict = new PdfDictionary()
|
|
968
|
+
borderDict.set('W', new PdfNumber(1))
|
|
969
|
+
borderDict.set('S', new PdfName('S'))
|
|
970
|
+
fieldDict.set('BS', borderDict)
|
|
971
|
+
|
|
972
|
+
// Appearance characteristics
|
|
973
|
+
const mkDict = new PdfDictionary()
|
|
974
|
+
mkDict.set('BC', new PdfArray([new PdfNumber(0)])) // Border color (black)
|
|
975
|
+
mkDict.set('BG', new PdfArray([new PdfNumber(1)])) // Background color (white)
|
|
976
|
+
fieldDict.set('MK', mkDict)
|
|
977
|
+
|
|
954
978
|
return new PdfIndirectObject({ content: fieldDict })
|
|
955
979
|
}
|
|
956
980
|
|
|
@@ -978,7 +1002,7 @@ const contentStream = new PdfIndirectObject({
|
|
|
978
1002
|
0 -30 Td (Email:) Tj
|
|
979
1003
|
0 -30 Td (Phone:) Tj
|
|
980
1004
|
0 -30 Td (Subscribe to newsletter:) Tj
|
|
981
|
-
ET`,
|
|
1005
|
+
ET `,
|
|
982
1006
|
}),
|
|
983
1007
|
})
|
|
984
1008
|
document.add(contentStream)
|
|
@@ -1041,7 +1065,8 @@ acroForm.set(
|
|
|
1041
1065
|
subscribeField.reference,
|
|
1042
1066
|
]),
|
|
1043
1067
|
)
|
|
1044
|
-
//
|
|
1068
|
+
// With appearance streams provided, we don't need NeedAppearances
|
|
1069
|
+
// This prevents Acrobat from modifying the PDF on open
|
|
1045
1070
|
acroForm.set('NeedAppearances', new PdfBoolean(true))
|
|
1046
1071
|
|
|
1047
1072
|
// Default resources for the form (font)
|
|
@@ -1051,9 +1076,12 @@ const helveticaFont = new PdfDictionary()
|
|
|
1051
1076
|
helveticaFont.set('Type', new PdfName('Font'))
|
|
1052
1077
|
helveticaFont.set('Subtype', new PdfName('Type1'))
|
|
1053
1078
|
helveticaFont.set('BaseFont', new PdfName('Helvetica'))
|
|
1054
|
-
|
|
1079
|
+
const helveticaFontObj = new PdfIndirectObject({ content: helveticaFont })
|
|
1080
|
+
document.add(helveticaFontObj)
|
|
1081
|
+
formFontDict.set('Helv', helveticaFontObj.reference)
|
|
1055
1082
|
formResources.set('Font', formFontDict)
|
|
1056
1083
|
acroForm.set('DR', formResources)
|
|
1084
|
+
acroForm.set('DA', new PdfString('/Helv 12 Tf 0 g'))
|
|
1057
1085
|
|
|
1058
1086
|
const acroFormObj = new PdfIndirectObject({ content: acroForm })
|
|
1059
1087
|
document.add(acroFormObj)
|
|
@@ -1081,90 +1109,12 @@ console.log('Created form-empty.pdf with empty form fields')
|
|
|
1081
1109
|
const emptyFormBytes = await fs.readFile(`${tmpFolder}/form-empty.pdf`)
|
|
1082
1110
|
const filledDocument = await PdfDocument.fromBytes([emptyFormBytes])
|
|
1083
1111
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
// Read the catalog object
|
|
1091
|
-
const catalogObj = await filledDocument.readObject({
|
|
1092
|
-
objectNumber: catalogRef.objectNumber,
|
|
1093
|
-
})
|
|
1094
|
-
if (!catalogObj || !(catalogObj.content instanceof PdfDictionary)) {
|
|
1095
|
-
throw new Error('Catalog object not found')
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
// Get the AcroForm reference
|
|
1099
|
-
const acroFormRef = catalogObj.content.get('AcroForm')
|
|
1100
|
-
if (!acroFormRef || !(acroFormRef instanceof PdfObjectReference)) {
|
|
1101
|
-
throw new Error('No AcroForm found in PDF')
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
// Read the AcroForm object
|
|
1105
|
-
const filledAcroFormObj = await filledDocument.readObject({
|
|
1106
|
-
objectNumber: acroFormRef.objectNumber,
|
|
1112
|
+
await filledDocument.acroForm.setFieldValues({
|
|
1113
|
+
name: 'John Doe',
|
|
1114
|
+
email: 'john.doe@example.com',
|
|
1115
|
+
phone: '+1 (555) 123-4567',
|
|
1116
|
+
subscribe: 'Off', // For checkbox, use the "Yes/Off" value
|
|
1107
1117
|
})
|
|
1108
|
-
if (
|
|
1109
|
-
!filledAcroFormObj ||
|
|
1110
|
-
!(filledAcroFormObj.content instanceof PdfDictionary)
|
|
1111
|
-
) {
|
|
1112
|
-
throw new Error('AcroForm object not found')
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
// Get the fields array
|
|
1116
|
-
const fieldsArray = filledAcroFormObj.content.get('Fields')
|
|
1117
|
-
if (!fieldsArray || !(fieldsArray instanceof PdfArray)) {
|
|
1118
|
-
throw new Error('No fields found in AcroForm')
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
// Helper function to find a field by name
|
|
1122
|
-
async function findField(
|
|
1123
|
-
fieldName: string,
|
|
1124
|
-
): Promise<PdfIndirectObject<PdfDictionary> | null> {
|
|
1125
|
-
for (const fieldRef of fieldsArray.items) {
|
|
1126
|
-
if (!(fieldRef instanceof PdfObjectReference)) continue
|
|
1127
|
-
const fieldObj = await filledDocument.readObject({
|
|
1128
|
-
objectNumber: fieldRef.objectNumber,
|
|
1129
|
-
})
|
|
1130
|
-
if (!fieldObj || !(fieldObj.content instanceof PdfDictionary)) continue
|
|
1131
|
-
|
|
1132
|
-
const name = fieldObj.content.get('T')
|
|
1133
|
-
if (name instanceof PdfString) {
|
|
1134
|
-
// Convert bytes to string for comparison
|
|
1135
|
-
const nameStr = name.value
|
|
1136
|
-
if (nameStr === fieldName) {
|
|
1137
|
-
return fieldObj as PdfIndirectObject<PdfDictionary>
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
return null
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
// Update the name field value
|
|
1145
|
-
const nameFieldObj = await findField('name')
|
|
1146
|
-
if (nameFieldObj) {
|
|
1147
|
-
nameFieldObj.content.set('V', new PdfString('John Doe'))
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
// Update the email field value
|
|
1151
|
-
const emailFieldObj = await findField('email')
|
|
1152
|
-
if (emailFieldObj) {
|
|
1153
|
-
emailFieldObj.content.set('V', new PdfString('john.doe@example.com'))
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
// Update the phone field value
|
|
1157
|
-
const phoneFieldObj = await findField('phone')
|
|
1158
|
-
if (phoneFieldObj) {
|
|
1159
|
-
phoneFieldObj.content.set('V', new PdfString('+1 (555) 123-4567'))
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
// Check the subscribe checkbox
|
|
1163
|
-
const subscribeFieldObj = await findField('subscribe')
|
|
1164
|
-
if (subscribeFieldObj) {
|
|
1165
|
-
subscribeFieldObj.content.set('V', new PdfName('Yes'))
|
|
1166
|
-
subscribeFieldObj.content.set('AS', new PdfName('Yes'))
|
|
1167
|
-
}
|
|
1168
1118
|
|
|
1169
1119
|
// Save the filled form
|
|
1170
1120
|
await fs.writeFile(`${tmpFolder}/form-filled.pdf`, filledDocument.toBytes())
|
|
@@ -1174,7 +1124,7 @@ console.log('\nForm field values:')
|
|
|
1174
1124
|
console.log('- Name: John Doe')
|
|
1175
1125
|
console.log('- Email: john.doe@example.com')
|
|
1176
1126
|
console.log('- Phone: +1 (555) 123-4567')
|
|
1177
|
-
console.log('- Subscribe:
|
|
1127
|
+
console.log('- Subscribe: Off')
|
|
1178
1128
|
```
|
|
1179
1129
|
|
|
1180
1130
|
## Tokeniser usage example
|
package/README.md
CHANGED
|
@@ -18,6 +18,93 @@ PRs and issues are welcome!
|
|
|
18
18
|
- **Browser and Node.js support**: Works seamlessly in both environments, allowing for versatile usage.
|
|
19
19
|
- **Low-level API**: Provides a low-level API for advanced users who want to manipulate PDF files directly, as well as a higher-level API for easier usage.
|
|
20
20
|
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install pdf-lite
|
|
25
|
+
yarn add pdf-lite
|
|
26
|
+
pnpm add pdf-lite
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
The library provides both low-level and high-level APIs for working with PDF documents. See [PDF Support](#pdf-support) for a list of supported features.
|
|
32
|
+
|
|
33
|
+
### Reading a PDF
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { PdfReader } from 'pdf-lite/pdf/pdf-reader'
|
|
37
|
+
import { readFile } from 'fs/promises'
|
|
38
|
+
|
|
39
|
+
const pdfBytes = await readFile('document.pdf')
|
|
40
|
+
const doc = await PdfReader.fromBytes([pdfBytes])
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Creating a PDF from Scratch
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { PdfDocument } from 'pdf-lite/pdf/pdf-document'
|
|
47
|
+
import { PdfDictionary } from 'pdf-lite/core/objects/pdf-dictionary'
|
|
48
|
+
import { PdfIndirectObject } from 'pdf-lite/core/objects/pdf-indirect-object'
|
|
49
|
+
import { PdfStream } from 'pdf-lite/core/objects/pdf-stream'
|
|
50
|
+
import { PdfName } from 'pdf-lite/core/objects/pdf-name'
|
|
51
|
+
import { PdfArray } from 'pdf-lite/core/objects/pdf-array'
|
|
52
|
+
import { PdfNumber } from 'pdf-lite/core/objects/pdf-number'
|
|
53
|
+
|
|
54
|
+
// Create the document
|
|
55
|
+
const document = new PdfDocument()
|
|
56
|
+
|
|
57
|
+
// Create content stream
|
|
58
|
+
const contentStream = new PdfIndirectObject({
|
|
59
|
+
content: new PdfStream({
|
|
60
|
+
header: new PdfDictionary(),
|
|
61
|
+
original: 'BT /F1 24 Tf 100 700 Td (Hello, PDF-Lite!) Tj ET',
|
|
62
|
+
}),
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// Create and commit objects
|
|
66
|
+
document.commit(contentStream)
|
|
67
|
+
// ... create pages, catalog, etc.
|
|
68
|
+
|
|
69
|
+
// Output the PDF
|
|
70
|
+
console.log(document.toString())
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Working with Encryption
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { PdfDocument } from 'pdf-lite/pdf/pdf-document'
|
|
77
|
+
import { PdfV2SecurityHandler } from 'pdf-lite/security/handlers/v2'
|
|
78
|
+
|
|
79
|
+
const document = new PdfDocument()
|
|
80
|
+
// ... build your PDF structure
|
|
81
|
+
|
|
82
|
+
// Set up encryption
|
|
83
|
+
document.securityHandler = new PdfV2SecurityHandler({
|
|
84
|
+
password: 'user-password',
|
|
85
|
+
documentId: 'unique-doc-id',
|
|
86
|
+
encryptMetadata: true,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
// Encrypt the document
|
|
90
|
+
await document.encrypt()
|
|
91
|
+
|
|
92
|
+
console.log(document.toString())
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Signing PDFs
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import {
|
|
99
|
+
PdfAdbePkcs7DetachedSignatureObject,
|
|
100
|
+
PdfEtsiCadesDetachedSignatureObject,
|
|
101
|
+
} from 'pdf-lite'
|
|
102
|
+
|
|
103
|
+
// See examples directory for complete signing implementations
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
For more detailed examples, see the [EXAMPLES.md](EXAMPLES.md) file and the [examples/](examples/) directory.
|
|
107
|
+
|
|
21
108
|
## PDF Support
|
|
22
109
|
|
|
23
110
|
### Low-level PDF constructs
|
|
@@ -100,6 +187,22 @@ Long-Term Validation (LTV) support ensures that digital signatures remain valid
|
|
|
100
187
|
- [x] Timestamping
|
|
101
188
|
- [x] Verification of existing signatures
|
|
102
189
|
|
|
190
|
+
### AcroForm filling
|
|
191
|
+
|
|
192
|
+
Supports filling out AcroForm forms within PDF documents, allowing for dynamic content generation and user interaction.
|
|
193
|
+
|
|
194
|
+
[x] Text fields
|
|
195
|
+
[x] Checkboxes
|
|
196
|
+
[x] Radio buttons
|
|
197
|
+
[x] Dropdowns
|
|
198
|
+
|
|
199
|
+
### XFA Forms
|
|
200
|
+
|
|
201
|
+
You can read/write XFA XML data from PDFs, but rendering and filling XFA forms is not supported.
|
|
202
|
+
|
|
203
|
+
[x] Read XFA XML
|
|
204
|
+
[x] Write XFA XML
|
|
205
|
+
|
|
103
206
|
## Future Plans
|
|
104
207
|
|
|
105
208
|
- **Writing Linearized PDF**: Writing linearized PDFs for faster web viewing, improving user experience when accessing documents online.
|
|
@@ -133,156 +236,13 @@ pnpm test:unit
|
|
|
133
236
|
pnpm test:acceptance
|
|
134
237
|
```
|
|
135
238
|
|
|
136
|
-
### Package Structure
|
|
137
|
-
|
|
138
|
-
The main package (`packages/pdf-lite`) contains:
|
|
139
|
-
|
|
140
|
-
- **src/core/** - Low-level PDF constructs (objects, parser, tokenizer)
|
|
141
|
-
- **src/pdf/** - High-level PDF document handling
|
|
142
|
-
- **src/signing/** - Digital signature support
|
|
143
|
-
- **src/security/** - Encryption and security handlers
|
|
144
|
-
- **src/filters/** - Compression/decompression filters
|
|
145
|
-
|
|
146
239
|
## Contributing
|
|
147
240
|
|
|
148
241
|
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
149
242
|
|
|
150
|
-
## Installation
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
npm install pdf-lite
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
or
|
|
157
|
-
|
|
158
|
-
```bash
|
|
159
|
-
yarn add pdf-lite
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
or
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
pnpm add pdf-lite
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## Usage
|
|
169
|
-
|
|
170
|
-
The library provides both low-level and high-level APIs for working with PDF documents.
|
|
171
|
-
|
|
172
|
-
### Reading a PDF
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
import { PdfReader } from 'pdf-lite/pdf/pdf-reader'
|
|
176
|
-
import { readFile } from 'fs/promises'
|
|
177
|
-
|
|
178
|
-
const pdfBytes = await readFile('document.pdf')
|
|
179
|
-
const doc = await PdfReader.fromBytes([pdfBytes])
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Creating a PDF from Scratch
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
import { PdfDocument } from 'pdf-lite/pdf/pdf-document'
|
|
186
|
-
import { PdfDictionary } from 'pdf-lite/core/objects/pdf-dictionary'
|
|
187
|
-
import { PdfIndirectObject } from 'pdf-lite/core/objects/pdf-indirect-object'
|
|
188
|
-
import { PdfStream } from 'pdf-lite/core/objects/pdf-stream'
|
|
189
|
-
import { PdfName } from 'pdf-lite/core/objects/pdf-name'
|
|
190
|
-
import { PdfArray } from 'pdf-lite/core/objects/pdf-array'
|
|
191
|
-
import { PdfNumber } from 'pdf-lite/core/objects/pdf-number'
|
|
192
|
-
|
|
193
|
-
// Create the document
|
|
194
|
-
const document = new PdfDocument()
|
|
195
|
-
|
|
196
|
-
// Create content stream
|
|
197
|
-
const contentStream = new PdfIndirectObject({
|
|
198
|
-
content: new PdfStream({
|
|
199
|
-
header: new PdfDictionary(),
|
|
200
|
-
original: 'BT /F1 24 Tf 100 700 Td (Hello, PDF-Lite!) Tj ET',
|
|
201
|
-
}),
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
// Create and commit objects
|
|
205
|
-
document.commit(contentStream)
|
|
206
|
-
// ... create pages, catalog, etc.
|
|
207
|
-
|
|
208
|
-
// Output the PDF
|
|
209
|
-
console.log(document.toString())
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Working with Encryption
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
import { PdfDocument } from 'pdf-lite/pdf/pdf-document'
|
|
216
|
-
import { PdfV2SecurityHandler } from 'pdf-lite/security/handlers/v2'
|
|
217
|
-
|
|
218
|
-
const document = new PdfDocument()
|
|
219
|
-
// ... build your PDF structure
|
|
220
|
-
|
|
221
|
-
// Set up encryption
|
|
222
|
-
document.securityHandler = new PdfV2SecurityHandler({
|
|
223
|
-
password: 'user-password',
|
|
224
|
-
documentId: 'unique-doc-id',
|
|
225
|
-
encryptMetadata: true,
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
// Encrypt the document
|
|
229
|
-
await document.encrypt()
|
|
230
|
-
|
|
231
|
-
console.log(document.toString())
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### Signing PDFs
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
import {
|
|
238
|
-
PdfAdbePkcs7DetachedSignatureObject,
|
|
239
|
-
PdfEtsiCadesDetachedSignatureObject,
|
|
240
|
-
} from 'pdf-lite'
|
|
241
|
-
|
|
242
|
-
// See examples directory for complete signing implementations
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
For more detailed examples, see the [EXAMPLES.md](EXAMPLES.md) file and the [examples/](examples/) directory.
|
|
246
|
-
|
|
247
|
-
## Project Structure
|
|
248
|
-
|
|
249
|
-
This project is organized as a monorepo:
|
|
250
|
-
|
|
251
|
-
- **packages/pdf-lite** - Main library package
|
|
252
|
-
- **examples/** - Example scripts demonstrating library usage
|
|
253
|
-
- **scripts/** - Build and development scripts
|
|
254
|
-
|
|
255
243
|
## API Reference
|
|
256
244
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
```typescript
|
|
260
|
-
// PDF Document
|
|
261
|
-
import { PdfDocument } from 'pdf-lite/pdf/pdf-document'
|
|
262
|
-
import { PdfReader } from 'pdf-lite/pdf/pdf-reader'
|
|
263
|
-
|
|
264
|
-
// Core PDF objects
|
|
265
|
-
import { PdfArray } from 'pdf-lite/core/objects/pdf-array'
|
|
266
|
-
import { PdfDictionary } from 'pdf-lite/core/objects/pdf-dictionary'
|
|
267
|
-
import { PdfStream } from 'pdf-lite/core/objects/pdf-stream'
|
|
268
|
-
import { PdfString } from 'pdf-lite/core/objects/pdf-string'
|
|
269
|
-
import { PdfName } from 'pdf-lite/core/objects/pdf-name'
|
|
270
|
-
import { PdfNumber } from 'pdf-lite/core/objects/pdf-number'
|
|
271
|
-
import { PdfIndirectObject } from 'pdf-lite/core/objects/pdf-indirect-object'
|
|
272
|
-
import { PdfObjectReference } from 'pdf-lite/core/objects/pdf-object-reference'
|
|
273
|
-
|
|
274
|
-
// Security
|
|
275
|
-
import { PdfV2SecurityHandler } from 'pdf-lite/security/handlers/v2'
|
|
276
|
-
|
|
277
|
-
// Signing
|
|
278
|
-
import {
|
|
279
|
-
PdfAdbePkcs7DetachedSignatureObject,
|
|
280
|
-
PdfAdbePkcs7Sha1SignatureObject,
|
|
281
|
-
PdfAdbePkcsX509RsaSha1SignatureObject,
|
|
282
|
-
PdfEtsiCadesDetachedSignatureObject,
|
|
283
|
-
PdfEtsiRfc3161SignatureObject,
|
|
284
|
-
} from 'pdf-lite'
|
|
285
|
-
```
|
|
245
|
+
See the [documentation folder](./docs/README.md) or the document site for a complete API reference.
|
|
286
246
|
|
|
287
247
|
## License
|
|
288
248
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PdfDocument } from '../pdf/pdf-document.js';
|
|
2
|
+
/**
|
|
3
|
+
* Manages AcroForm fields in PDF documents.
|
|
4
|
+
* Provides methods to read and write form field values.
|
|
5
|
+
*/
|
|
6
|
+
export declare class PdfAcroFormManager<T extends Record<string, string> = Record<string, string>> {
|
|
7
|
+
private document;
|
|
8
|
+
private _acroForm?;
|
|
9
|
+
constructor(document: PdfDocument);
|
|
10
|
+
/**
|
|
11
|
+
* Checks if the document contains AcroForm fields.
|
|
12
|
+
* @returns True if the document has AcroForm fields, false otherwise
|
|
13
|
+
*/
|
|
14
|
+
hasAcroForm(): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Gets all form field values as a key-value map.
|
|
17
|
+
* @returns Object with field names as keys and values as strings
|
|
18
|
+
*/
|
|
19
|
+
getFieldValues(): Promise<T | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Sets a form field value by field name.
|
|
22
|
+
* @param fieldName The name of the field to set
|
|
23
|
+
* @param value The value to set
|
|
24
|
+
* @throws Error if the field is not found
|
|
25
|
+
*/
|
|
26
|
+
setFieldValues(newFields: Partial<T>): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Gets the AcroForm indirect object from the document catalog.
|
|
29
|
+
* @returns The AcroForm indirect object or null if not found
|
|
30
|
+
*/
|
|
31
|
+
private getAcroFormObject;
|
|
32
|
+
/**
|
|
33
|
+
* Gets the AcroForm dictionary from the document catalog.
|
|
34
|
+
* @returns The AcroForm dictionary or null if not found
|
|
35
|
+
*/
|
|
36
|
+
private getAcroForm;
|
|
37
|
+
/**
|
|
38
|
+
* Recursively collects field values from the field tree.
|
|
39
|
+
*/
|
|
40
|
+
private collectFieldValues;
|
|
41
|
+
/**
|
|
42
|
+
* Finds a field by its fully qualified name.
|
|
43
|
+
*/
|
|
44
|
+
private findFieldByName;
|
|
45
|
+
/**
|
|
46
|
+
* Gets the fully qualified field name.
|
|
47
|
+
*/
|
|
48
|
+
private getFieldName;
|
|
49
|
+
}
|