@pdftron/pdfnet-node-samples 9.5.0-5 → 9.5.0-5-beta
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/{samples/AddImageTest → AddImageTest}/AddImageTest.js +2 -2
- package/{samples/AdvancedImagingTest → AdvancedImagingTest}/AdvancedImagingTest.js +5 -5
- package/{samples/AnnotationTest → AnnotationTest}/AnnotationTest.js +1 -1
- package/BarcodeTest/BarcodeTest.js +120 -0
- package/{samples/BookmarkTest → BookmarkTest}/BookmarkTest.js +1 -1
- package/{samples/CAD2PDFTest → CAD2PDFTest}/CAD2PDFTest.js +5 -5
- package/{samples/ContentReplacerTest → ContentReplacerTest}/ContentReplacerTest.js +1 -1
- package/ConvertPrintTest/ConvertPrintTest.js +153 -0
- package/{samples/ConvertTest → ConvertTest}/ConvertTest.js +12 -79
- package/{samples/DataExtractionTest → DataExtractionTest}/DataExtractionTest.js +141 -10
- package/{samples/DigitalSignaturesTest → DigitalSignaturesTest}/DigitalSignaturesTest.js +126 -12
- package/DocumentCreationTest/DocumentCreationTest.js +409 -0
- package/{samples/ElementBuilderTest → ElementBuilderTest}/ElementBuilderTest.js +1 -1
- package/{samples/ElementEditTest → ElementEditTest}/ElementEditTest.js +1 -1
- package/{samples/ElementReaderAdvTest → ElementReaderAdvTest}/ElementReaderAdvTest.js +1 -1
- package/{samples/ElementReaderTest → ElementReaderTest}/ElementReaderTest.js +1 -1
- package/{samples/EncTest → EncTest}/EncTest.js +1 -1
- package/{samples/FDFTest → FDFTest}/FDFTest.js +1 -1
- package/FindReplaceTest/FindReplaceTest.js +56 -0
- package/{samples/HTML2PDFTest → HTML2PDFTest}/HTML2PDFTest.js +34 -35
- package/{samples/HighlightsTest → HighlightsTest}/HighlightsTest.js +1 -1
- package/{samples/ImageExtractTest → ImageExtractTest}/ImageExtractTest.js +3 -3
- package/{samples/ImpositionTest → ImpositionTest}/ImpositionTest.js +1 -1
- package/{samples/InteractiveFormsTest → InteractiveFormsTest}/InteractiveFormsTest.js +1 -1
- package/{samples/JBIG2Test → JBIG2Test}/JBIG2Test.js +7 -7
- package/{samples/LicenseKey → LicenseKey}/LicenseKey.js +3 -3
- package/{samples/LogicalStructureTest → LogicalStructureTest}/LogicalStructureTest.js +1 -1
- package/{samples/OCRTest → OCRTest}/OCRTest.js +6 -5
- package/{samples/OfficeTemplateTest → OfficeTemplateTest}/OfficeTemplateTest.js +2 -2
- package/{samples/OfficeToPDFTest → OfficeToPDFTest}/OfficeToPDFTest.js +1 -1
- package/{samples/OptimizerTest → OptimizerTest}/OptimizerTest.js +1 -1
- package/{samples/PDF2HtmlTest → PDF2HtmlTest}/PDF2HtmlTest.js +6 -6
- package/{samples/PDF2OfficeTest → PDF2OfficeTest}/PDF2OfficeTest.js +6 -6
- package/{samples/PDFATest → PDFATest}/PDFATest.js +1 -1
- package/{samples/PDFDocMemoryTest → PDFDocMemoryTest}/PDFDocMemoryTest.js +1 -1
- package/{samples/PDFDrawTest → PDFDrawTest}/PDFDrawTest.js +1 -1
- package/{samples/PDFLayersTest → PDFLayersTest}/PDFLayersTest.js +1 -1
- package/{samples/PDFPackageTest → PDFPackageTest}/PDFPackageTest.js +1 -1
- package/{samples/PDFPageTest → PDFPageTest}/PDFPageTest.js +1 -1
- package/{samples/PDFRedactTest → PDFRedactTest}/PDFRedactTest.js +1 -1
- package/PDFUATest/PDFUATest.js +88 -0
- package/{samples/PageLabelsTest → PageLabelsTest}/PageLabelsTest.js +1 -1
- package/{samples/PatternTest → PatternTest}/PatternTest.js +1 -1
- package/{samples/RectTest → RectTest}/RectTest.js +1 -1
- package/{samples/SDFTest → SDFTest}/SDFTest.js +3 -4
- package/{samples/StamperTest → StamperTest}/StamperTest.js +1 -1
- package/TestFiles/BusinessCardTemplate.pdf +0 -0
- package/TestFiles/Email.pdf +0 -0
- package/TestFiles/Fishermen.docx +0 -0
- package/TestFiles/Font_licenses.txt +140 -0
- package/TestFiles/Invoice.pdf +0 -0
- package/TestFiles/License.txt +1 -0
- package/TestFiles/Misc-Fixed.pfa +1166 -0
- package/TestFiles/NotoSans_with_hindi.ttf +0 -0
- package/TestFiles/Output/empty +1 -0
- package/TestFiles/SHA-2 Root USERTrust RSA CA Sectigo timestamping.crt +34 -0
- package/TestFiles/SYH_Letter.docx +0 -0
- package/TestFiles/Scientific_Publication.pdf +0 -0
- package/TestFiles/TigerText.pdf +0 -0
- package/TestFiles/US061222892-a.pdf +0 -0
- package/TestFiles/apryse.bmp +0 -0
- package/TestFiles/apryse.cer +0 -0
- package/TestFiles/apryse.pfx +0 -0
- package/TestFiles/autotag_input.pdf +0 -0
- package/TestFiles/butterfly.png +0 -0
- package/TestFiles/credit card numbers.pdf +0 -0
- package/TestFiles/dice.jpg +0 -0
- package/TestFiles/dice.u3d +0 -0
- package/TestFiles/doc_to_sign.pdf +0 -0
- package/TestFiles/factsheet_Arabic.docx +0 -0
- package/TestFiles/financial.pdf +0 -0
- package/TestFiles/find-replace-test.pdf +0 -0
- package/TestFiles/find-replace-test_(en_to_fr).xlf +88 -0
- package/TestFiles/fish.pdf +0 -0
- package/TestFiles/font.ttf +0 -0
- package/TestFiles/form1.pdf +246 -0
- package/TestFiles/form1_annots.xfdf +34 -0
- package/TestFiles/form1_data.fdf +4 -0
- package/TestFiles/form1_data.xfdf +140 -0
- package/TestFiles/formfields-scanned-withfields.pdf +0 -0
- package/TestFiles/formfields-scanned.pdf +0 -0
- package/TestFiles/formfields.pdf +0 -0
- package/TestFiles/grayscale.tif +0 -0
- package/TestFiles/hindi_sample_utf16le.txt +0 -0
- package/TestFiles/imagemask.dat +32 -0
- package/TestFiles/logo_red.png +0 -0
- package/TestFiles/lorem_ipsum.pdf +0 -0
- package/TestFiles/multipage.tif +0 -0
- package/TestFiles/my_stream.txt +2310 -0
- package/TestFiles/newsletter.pdf +0 -0
- package/TestFiles/newsletter.xod +0 -0
- package/TestFiles/numbered.pdf +0 -0
- package/TestFiles/op_blend_test.pdf +1497 -1
- package/TestFiles/palm.jp2 +0 -0
- package/TestFiles/paragraphs_and_tables.pdf +0 -0
- package/TestFiles/pdfnet.gif +0 -0
- package/TestFiles/pdftron_smart_substitution.plugin +0 -0
- package/TestFiles/peppers.jpg +0 -0
- package/TestFiles/signature.jpg +0 -0
- package/TestFiles/simple-emf.emf +0 -0
- package/TestFiles/simple-excel_2007.xlsx +0 -0
- package/TestFiles/simple-outlook.msg +0 -0
- package/TestFiles/simple-powerpoint_2007.pptx +0 -0
- package/TestFiles/simple-publisher.pub +0 -0
- package/TestFiles/simple-rtf.rtf +224 -0
- package/TestFiles/simple-text.txt +61 -0
- package/TestFiles/simple-visio.vsd +0 -0
- package/TestFiles/simple-webpage.html +731 -0
- package/TestFiles/simple-webpage.mht +6972 -0
- package/TestFiles/simple-webpage_files/colorschememapping.xml +2 -0
- package/TestFiles/simple-webpage_files/filelist.xml +14 -0
- package/TestFiles/simple-webpage_files/image001.gif +0 -0
- package/TestFiles/simple-webpage_files/image002.png +0 -0
- package/TestFiles/simple-webpage_files/image003.jpg +0 -0
- package/TestFiles/simple-webpage_files/image004.emz +0 -0
- package/TestFiles/simple-webpage_files/image005.gif +0 -0
- package/TestFiles/simple-webpage_files/image006.png +0 -0
- package/TestFiles/simple-webpage_files/image007.gif +0 -0
- package/TestFiles/simple-webpage_files/oledata.mso +0 -0
- package/TestFiles/simple-webpage_files/themedata.thmx +0 -0
- package/TestFiles/simple-word_2007.docx +0 -0
- package/TestFiles/simple-xps.xps +0 -0
- package/TestFiles/table.pdf +0 -0
- package/TestFiles/tagged.pdf +0 -0
- package/TestFiles/the_rime_of_the_ancient_mariner.docx +0 -0
- package/TestFiles/tiger.pdf +0 -0
- package/TestFiles/tiger.svg +378 -0
- package/TestFiles/waiver.pdf +0 -0
- package/TestFiles/waiver_withApprovalField.pdf +0 -0
- package/TestFiles/waiver_withApprovalField_certified.pdf +421 -1
- package/TestFiles/waiver_withApprovalField_certified_approved.pdf +465 -1
- package/{samples/TextExtractTest → TextExtractTest}/TextExtractTest.js +1 -1
- package/{samples/TextSearchTest → TextSearchTest}/TextSearchTest.js +2 -2
- package/TransPDFTest/TransPDFTest.js +68 -0
- package/{samples/U3DTest → U3DTest}/U3DTest.js +1 -1
- package/{samples/UndoRedoTest → UndoRedoTest}/UndoRedoTest.js +1 -1
- package/{samples/UnicodeWriteTest → UnicodeWriteTest}/UnicodeWriteTest.js +1 -1
- package/{samples/WebViewerConvertTest → WebViewerConvertTest}/WebViewerConvertTest.js +2 -2
- package/legal.txt +632 -0
- package/license.pdf +0 -0
- package/package.json +8 -6
- package/readme.md +32 -7
- package/{samples/runall.bat → runall.bat} +12 -12
- package/scripts/install.js +68 -0
- /package/{samples/runall.sh → runall.sh} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//---------------------------------------------------------------------------------------
|
|
2
|
-
// Copyright (c) 2001-
|
|
2
|
+
// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
|
|
3
3
|
// Consult legal.txt regarding legal and license information.
|
|
4
4
|
//---------------------------------------------------------------------------------------
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// The Data Extraction suite is an optional PDFNet add-on collection that can be used to
|
|
8
8
|
// extract various types of data from PDF documents.
|
|
9
9
|
//
|
|
10
|
-
// The
|
|
10
|
+
// The Apryse SDK Data Extraction suite can be downloaded from http://www.apryse.com/
|
|
11
11
|
//---------------------------------------------------------------------------------------
|
|
12
12
|
|
|
13
13
|
const fs = require('fs');
|
|
@@ -26,7 +26,7 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
26
26
|
|
|
27
27
|
//////////////////////////////////////////////////////////////////////////
|
|
28
28
|
|
|
29
|
-
await PDFNet.addResourceSearchPath('
|
|
29
|
+
await PDFNet.addResourceSearchPath('../../lib/');
|
|
30
30
|
|
|
31
31
|
//////////////////////////////////////////////////////////////////////////
|
|
32
32
|
// The following sample illustrates how to extract tables from PDF documents.
|
|
@@ -34,10 +34,10 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
34
34
|
|
|
35
35
|
// Test if the add-on is installed
|
|
36
36
|
if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_Tabular)) {
|
|
37
|
-
console.log('\nUnable to run Data Extraction:
|
|
37
|
+
console.log('\nUnable to run Data Extraction: Apryse SDK Tabular Data module not available.');
|
|
38
38
|
console.log('---------------------------------------------------------------');
|
|
39
39
|
console.log('The Data Extraction suite is an optional add-on, available for download');
|
|
40
|
-
console.log('at https://
|
|
40
|
+
console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
|
|
41
41
|
console.log('downloaded this module, ensure that the SDK is able to find the required files');
|
|
42
42
|
console.log('using the PDFNet.addResourceSearchPath() function.\n');
|
|
43
43
|
}
|
|
@@ -78,7 +78,7 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
78
78
|
outputFile = outputPath + 'financial.xlsx';
|
|
79
79
|
const outputXlsxStream = await PDFNet.Filter.createMemoryFilter(0, false);
|
|
80
80
|
const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
|
|
81
|
-
options.setPages(
|
|
81
|
+
options.setPages('1'); // page 1
|
|
82
82
|
await PDFNet.DataExtractionModule.extractToXLSXWithFilter(inputPath + 'financial.pdf', outputXlsxStream, options);
|
|
83
83
|
outputXlsxStream.memoryFilterSetAsInputFilter();
|
|
84
84
|
outputXlsxStream.writeToFile(outputFile, false);
|
|
@@ -95,10 +95,10 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
95
95
|
|
|
96
96
|
// Test if the add-on is installed
|
|
97
97
|
if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_DocStructure)) {
|
|
98
|
-
console.log('\nUnable to run Data Extraction:
|
|
98
|
+
console.log('\nUnable to run Data Extraction: Apryse SDK Structured Output module not available.');
|
|
99
99
|
console.log('---------------------------------------------------------------');
|
|
100
100
|
console.log('The Data Extraction suite is an optional add-on, available for download');
|
|
101
|
-
console.log('at https://
|
|
101
|
+
console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
|
|
102
102
|
console.log('downloaded this module, ensure that the SDK is able to find the required files');
|
|
103
103
|
console.log('using the PDFNet.addResourceSearchPath() function.\n');
|
|
104
104
|
}
|
|
@@ -133,10 +133,10 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
133
133
|
|
|
134
134
|
// Test if the add-on is installed
|
|
135
135
|
if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_Form)) {
|
|
136
|
-
console.log('\nUnable to run Data Extraction:
|
|
136
|
+
console.log('\nUnable to run Data Extraction: Apryse SDK AIFormFieldExtractor module not available.');
|
|
137
137
|
console.log('---------------------------------------------------------------');
|
|
138
138
|
console.log('The Data Extraction suite is an optional add-on, available for download');
|
|
139
|
-
console.log('at https://
|
|
139
|
+
console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
|
|
140
140
|
console.log('downloaded this module, ensure that the SDK is able to find the required files');
|
|
141
141
|
console.log('using the PDFNet.addResourceSearchPath() function.\n');
|
|
142
142
|
}
|
|
@@ -160,6 +160,137 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
160
160
|
fs.writeFileSync(outputFile, json);
|
|
161
161
|
|
|
162
162
|
console.log('Result saved in ' + outputFile);
|
|
163
|
+
|
|
164
|
+
//////////////////////////////////////////////////////////////////////////
|
|
165
|
+
// Detect and add form fields to a PDF document.
|
|
166
|
+
// Document already has form fields, and this sample will update to new found fields.
|
|
167
|
+
{
|
|
168
|
+
console.log('Detect and add form fields in a PDF file, keep new fields');
|
|
169
|
+
|
|
170
|
+
const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + 'formfields-scanned-withfields.pdf');
|
|
171
|
+
|
|
172
|
+
await PDFNet.DataExtractionModule.detectAndAddFormFieldsToPDF(doc);
|
|
173
|
+
outputFile = outputPath + 'formfields-scanned-fields-new.pdf';
|
|
174
|
+
await doc.save(outputFile, PDFNet.SDFDoc.SaveOptions.e_linearized);
|
|
175
|
+
|
|
176
|
+
console.log('Result saved in ' + outputFile);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
//////////////////////////////////////////////////////////////////////////
|
|
180
|
+
// Detect and add form fields to a PDF document.
|
|
181
|
+
// Document already has form fields, and this sample will keep the original fields.
|
|
182
|
+
{
|
|
183
|
+
console.log('Detect and add form fields in a PDF file, keep old fields');
|
|
184
|
+
|
|
185
|
+
const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + 'formfields-scanned-withfields.pdf');
|
|
186
|
+
|
|
187
|
+
const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
|
|
188
|
+
options.setOverlappingFormFieldBehavior('KeepOld');
|
|
189
|
+
|
|
190
|
+
await PDFNet.DataExtractionModule.detectAndAddFormFieldsToPDF(doc, options);
|
|
191
|
+
outputFile = outputPath + 'formfields-scanned-fields-old.pdf';
|
|
192
|
+
await doc.save(outputFile, PDFNet.SDFDoc.SaveOptions.e_linearized);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
console.log('Result saved in ' + outputFile);
|
|
196
|
+
|
|
197
|
+
} catch (err) {
|
|
198
|
+
console.log(err);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
//////////////////////////////////////////////////////////////////////////
|
|
203
|
+
// The following sample illustrates how to extract key-value pairs from PDF documents.
|
|
204
|
+
//////////////////////////////////////////////////////////////////////////
|
|
205
|
+
if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue)) {
|
|
206
|
+
console.log();
|
|
207
|
+
console.log('Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.');
|
|
208
|
+
console.log('---------------------------------------------------------------');
|
|
209
|
+
console.log('The Data Extraction suite is an optional add-on, available for download');
|
|
210
|
+
console.log('at http://www.apryse.com/. If you have already downloaded this');
|
|
211
|
+
console.log('module, ensure that the SDK is able to find the required files');
|
|
212
|
+
console.log('using the PDFNet.addResourceSearchPath() function.');
|
|
213
|
+
console.log();
|
|
214
|
+
}
|
|
215
|
+
else
|
|
216
|
+
{
|
|
217
|
+
try {
|
|
218
|
+
// Simple example: Extract Keys & Values as a JSON file
|
|
219
|
+
console.log('Extract Key-Value pairs as a JSON file');
|
|
220
|
+
await PDFNet.DataExtractionModule.extractData(inputPath + 'newsletter.pdf', outputPath + 'newsletter_key_val.json', PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue);
|
|
221
|
+
console.log('Result saved in ' + outputPath + 'newsletter_key_val.json');
|
|
222
|
+
|
|
223
|
+
const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
|
|
224
|
+
options.setPages('2-4');
|
|
225
|
+
|
|
226
|
+
const p2ExclusionZones = [];
|
|
227
|
+
// Exclude the ad on page 2
|
|
228
|
+
// These coordinates are in PDF user space, with the origin at the bottom left corner of the page
|
|
229
|
+
// Coordinates rotate with the page, if it has rotation applied.
|
|
230
|
+
p2ExclusionZones.push(new PDFNet.Rect(166, 47, 562, 222));
|
|
231
|
+
options.addExclusionZonesForPage(p2ExclusionZones, 2);
|
|
232
|
+
|
|
233
|
+
const p4InclusionZones = [];
|
|
234
|
+
const p4ExclusionZones = [];
|
|
235
|
+
// Only include the article text for page 4, exclude ads and headings
|
|
236
|
+
p4InclusionZones.push(new PDFNet.Rect(30, 432, 562, 684));
|
|
237
|
+
p4ExclusionZones.push(new PDFNet.Rect(30, 657, 295, 684));
|
|
238
|
+
options.addInclusionZonesForPage(p4InclusionZones, 4);
|
|
239
|
+
options.addExclusionZonesForPage(p4ExclusionZones, 4);
|
|
240
|
+
console.log('Extract Key-Value pairs from specific pages and zones as a JSON file');
|
|
241
|
+
await PDFNet.DataExtractionModule.extractData(inputPath + 'newsletter.pdf', outputPath + 'newsletter_key_val_with_zones.json', PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue, options);
|
|
242
|
+
console.log('Result saved in ' + outputPath + 'newsletter_key_val_with_zones.json');
|
|
243
|
+
} catch (err) {
|
|
244
|
+
console.log(err);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
//////////////////////////////////////////////////////////////////////////
|
|
249
|
+
// The following sample illustrates how to extract document classes from PDF documents.
|
|
250
|
+
//////////////////////////////////////////////////////////////////////////
|
|
251
|
+
|
|
252
|
+
// Test if the add-on is installed
|
|
253
|
+
if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification)) {
|
|
254
|
+
console.log('\nUnable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.');
|
|
255
|
+
console.log('---------------------------------------------------------------');
|
|
256
|
+
console.log('The Data Extraction suite is an optional add-on, available for download');
|
|
257
|
+
console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
|
|
258
|
+
console.log('downloaded this module, ensure that the SDK is able to find the required files');
|
|
259
|
+
console.log('using the PDFNet.addResourceSearchPath() function.\n');
|
|
260
|
+
}
|
|
261
|
+
else
|
|
262
|
+
{
|
|
263
|
+
try {
|
|
264
|
+
// Simple example: classify pages as a JSON file
|
|
265
|
+
console.log('Classify pages as a JSON file');
|
|
266
|
+
|
|
267
|
+
let outputFile = outputPath + 'Invoice_Classified.json';
|
|
268
|
+
await PDFNet.DataExtractionModule.extractData(inputPath + 'Invoice.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification);
|
|
269
|
+
|
|
270
|
+
console.log('Result saved in ' + outputFile);
|
|
271
|
+
|
|
272
|
+
///////////////////////////////////////////////////////
|
|
273
|
+
// Classify pages as a JSON string
|
|
274
|
+
console.log('Classify pages as a JSON string');
|
|
275
|
+
|
|
276
|
+
outputFile = outputPath + 'Scientific_Publication_Classified.json';
|
|
277
|
+
const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'Scientific_Publication.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification);
|
|
278
|
+
fs.writeFileSync(outputFile, json);
|
|
279
|
+
|
|
280
|
+
console.log('Result saved in ' + outputFile);
|
|
281
|
+
|
|
282
|
+
///////////////////////////////////////////////////////
|
|
283
|
+
// Example with customized options:
|
|
284
|
+
console.log('Classify pages with customized options');
|
|
285
|
+
|
|
286
|
+
const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
|
|
287
|
+
// Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
|
|
288
|
+
options.setMinimumConfidenceThreshold(0.7);
|
|
289
|
+
outputFile = outputPath + 'Email_Classified.json';
|
|
290
|
+
await PDFNet.DataExtractionModule.extractData(inputPath + 'Email.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification, options);
|
|
291
|
+
|
|
292
|
+
console.log('Result saved in ' + outputFile);
|
|
293
|
+
|
|
163
294
|
} catch (err) {
|
|
164
295
|
console.log(err);
|
|
165
296
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//---------------------------------------------------------------------------------------
|
|
2
|
-
// Copyright (c) 2001-
|
|
2
|
+
// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
|
|
3
3
|
// Consult legal.txt regarding legal and license information.
|
|
4
4
|
//---------------------------------------------------------------------------------------
|
|
5
5
|
|
|
@@ -356,11 +356,85 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
356
356
|
console.log('================================================================================');
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
const
|
|
359
|
+
const CustomSigningAPI = async (doc_path, cert_field_name, private_key_file_path, keyfile_password, public_key_file_path, appearance_image_path, digest_algorithm_type, PAdES_signing_mode, output_path) => {
|
|
360
|
+
console.log('================================================================================');
|
|
361
|
+
console.log('Custom signing PDF document');
|
|
362
|
+
|
|
363
|
+
const doc = await PDFNet.PDFDoc.createFromFilePath(doc_path);
|
|
364
|
+
doc.initSecurityHandler();
|
|
365
|
+
|
|
366
|
+
const page1 = await doc.getPage(1);
|
|
367
|
+
|
|
368
|
+
const digsig_field = await doc.createDigitalSignatureField(cert_field_name);
|
|
369
|
+
const widgetAnnot = await PDFNet.SignatureWidget.createWithDigitalSignatureField(doc, new PDFNet.Rect(143, 287, 219, 306), digsig_field);
|
|
370
|
+
await page1.annotPushBack(widgetAnnot);
|
|
371
|
+
|
|
372
|
+
// (OPTIONAL) Add an appearance to the signature field.
|
|
373
|
+
const img = await PDFNet.Image.createFromFile(doc, appearance_image_path);
|
|
374
|
+
await widgetAnnot.createSignatureAppearance(img);
|
|
375
|
+
|
|
376
|
+
// Create a digital signature dictionary inside the digital signature field, in preparation for signing.
|
|
377
|
+
await digsig_field.createSigDictForCustomSigning('Adobe.PPKLite',
|
|
378
|
+
PAdES_signing_mode ? PDFNet.DigitalSignatureField.SubFilterType.e_ETSI_CAdES_detached : PDFNet.DigitalSignatureField.SubFilterType.e_adbe_pkcs7_detached,
|
|
379
|
+
7500); // For security reasons, set the contents size to a value greater than but as close as possible to the size you expect your final signature to be, in bytes.
|
|
380
|
+
// ... or, if you want to apply a certification signature, use CreateSigDictForCustomCertification instead.
|
|
381
|
+
|
|
382
|
+
// (OPTIONAL) Set the signing time in the signature dictionary, if no secure embedded timestamping support is available from your signing provider.
|
|
383
|
+
const current_date = new PDFNet.Date();
|
|
384
|
+
await current_date.setCurrentTime();
|
|
385
|
+
await digsig_field.setSigDictTimeOfSigning(current_date);
|
|
386
|
+
|
|
387
|
+
await doc.save(output_path, PDFNet.SDFDoc.SaveOptions.e_incremental);
|
|
388
|
+
|
|
389
|
+
// Digest the relevant bytes of the document in accordance with ByteRanges surrounding the signature.
|
|
390
|
+
const pdf_digest = await digsig_field.calculateDigest(digest_algorithm_type);
|
|
391
|
+
|
|
392
|
+
const signer_cert = await PDFNet.X509Certificate.createFromFile(public_key_file_path);
|
|
393
|
+
|
|
394
|
+
// Optionally, you can add a custom signed attribute at this point, such as one of the PAdES ESS attributes.
|
|
395
|
+
// The function we provide takes care of generating the correct PAdES ESS attribute depending on your digest algorithm.
|
|
396
|
+
const pades_versioned_ess_signing_cert_attribute = await PDFNet.DigitalSignatureField.generateESSSigningCertPAdESAttribute(signer_cert, digest_algorithm_type);
|
|
397
|
+
|
|
398
|
+
// Generate the signedAttrs component of CMS, passing any optional custom signedAttrs (e.g. PAdES ESS).
|
|
399
|
+
// The signedAttrs are certain attributes that become protected by their inclusion in the signature.
|
|
400
|
+
const signedAttrs = await PDFNet.DigitalSignatureField.generateCMSSignedAttributes(pdf_digest, pades_versioned_ess_signing_cert_attribute);
|
|
401
|
+
|
|
402
|
+
// Calculate the digest of the signedAttrs (i.e. not the PDF digest, this time).
|
|
403
|
+
const signedAttrs_digest = await PDFNet.DigestAlgorithm.calculateDigest(digest_algorithm_type, signedAttrs);
|
|
404
|
+
|
|
405
|
+
//////////////////////////// custom digest signing starts ////////////////////////////
|
|
406
|
+
// At this point, you can sign the digest (for example, with HSM). We use our own SignDigest function instead here as an example,
|
|
407
|
+
// which you can also use for your purposes if necessary as an alternative to the handler/callback APIs (i.e. Certify/SignOnNextSave).
|
|
408
|
+
const signature_value = await PDFNet.DigestAlgorithm.signDigest(
|
|
409
|
+
signedAttrs_digest,
|
|
410
|
+
digest_algorithm_type,
|
|
411
|
+
private_key_file_path,
|
|
412
|
+
keyfile_password);
|
|
413
|
+
//////////////////////////// custom digest signing ends //////////////////////////////
|
|
414
|
+
|
|
415
|
+
// Then, load all your chain certificates into a container of X509Certificate.
|
|
416
|
+
const chain_certs = [];
|
|
417
|
+
|
|
418
|
+
// Then, create ObjectIdentifiers for the algorithms you have used.
|
|
419
|
+
// Here we use digest_algorithm_type (usually SHA256) for hashing, and RSAES-PKCS1-v1_5 (specified in the private key) for signing.
|
|
420
|
+
const digest_algorithm_oid = await PDFNet.ObjectIdentifier.createFromDigestAlgorithm(digest_algorithm_type);
|
|
421
|
+
const signature_algorithm_oid = await PDFNet.ObjectIdentifier.createFromPredefined(PDFNet.ObjectIdentifier.Predefined.e_RSA_encryption_PKCS1);
|
|
422
|
+
|
|
423
|
+
// Then, put the CMS signature components together.
|
|
424
|
+
const cms_signature = await PDFNet.DigitalSignatureField.generateCMSSignature(
|
|
425
|
+
signer_cert, chain_certs, digest_algorithm_oid, signature_algorithm_oid, signature_value, signedAttrs);
|
|
426
|
+
|
|
427
|
+
// Write the signature to the document.
|
|
428
|
+
await doc.saveCustomSignature(cms_signature, digsig_field, output_path);
|
|
429
|
+
|
|
430
|
+
console.log('================================================================================');
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
const TimestampAndEnableLTV = async (in_docpath, in_tsa_url, in_trusted_cert_path, in_appearance_img_path, in_outpath) => {
|
|
360
434
|
const doc = await PDFNet.PDFDoc.createFromFilePath(in_docpath);
|
|
361
435
|
doc.initSecurityHandler();
|
|
362
436
|
const doctimestamp_signature_field = await doc.createDigitalSignatureField();
|
|
363
|
-
const tst_config = await PDFNet.TimestampingConfiguration.createFromURL(
|
|
437
|
+
const tst_config = await PDFNet.TimestampingConfiguration.createFromURL(in_tsa_url);
|
|
364
438
|
const opts = await PDFNet.VerificationOptions.create(PDFNet.VerificationOptions.SecurityLevel.e_compatibility_and_archiving);
|
|
365
439
|
/* It is necessary to add to the VerificationOptions a trusted root certificate corresponding to
|
|
366
440
|
the chain used by the timestamp authority to sign the timestamp token, in order for the timestamp
|
|
@@ -439,9 +513,9 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
439
513
|
try {
|
|
440
514
|
await CertifyPDF(input_path + 'waiver_withApprovalField.pdf',
|
|
441
515
|
'PDFTronCertificationSig',
|
|
442
|
-
input_path + '
|
|
516
|
+
input_path + 'apryse.pfx',
|
|
443
517
|
'password',
|
|
444
|
-
input_path + '
|
|
518
|
+
input_path + 'apryse.bmp',
|
|
445
519
|
output_path + 'waiver_withApprovalField_certified_output.pdf');
|
|
446
520
|
await PrintSignaturesInfo(output_path + 'waiver_withApprovalField_certified_output.pdf');
|
|
447
521
|
} catch (err) {
|
|
@@ -453,7 +527,7 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
453
527
|
try {
|
|
454
528
|
await SignPDF(input_path + 'waiver_withApprovalField_certified.pdf',
|
|
455
529
|
'PDFTronApprovalSig',
|
|
456
|
-
input_path + '
|
|
530
|
+
input_path + 'apryse.pfx',
|
|
457
531
|
'password',
|
|
458
532
|
input_path + 'signature.jpg',
|
|
459
533
|
output_path + 'waiver_withApprovalField_certified_approved_output.pdf');
|
|
@@ -475,9 +549,9 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
475
549
|
}
|
|
476
550
|
|
|
477
551
|
//////////////////// TEST 4: Verify a document's digital signatures.
|
|
478
|
-
// EXPERIMENTAL. Digital signature verification is undergoing active development, but currently does not support a number of features. If we are missing a feature that is important to you, or if you have files that do not act as expected, please contact us using one of the following forms: https://
|
|
552
|
+
// EXPERIMENTAL. Digital signature verification is undergoing active development, but currently does not support a number of features. If we are missing a feature that is important to you, or if you have files that do not act as expected, please contact us using one of the following forms: https://apryse.com/form/trial-support or https://apryse.com/form/request
|
|
479
553
|
try {
|
|
480
|
-
if (!(await VerifyAllAndPrint(input_path + 'waiver_withApprovalField_certified_approved.pdf', input_path + '
|
|
554
|
+
if (!(await VerifyAllAndPrint(input_path + 'waiver_withApprovalField_certified_approved.pdf', input_path + 'apryse.cer'))) {
|
|
481
555
|
ret = 1;
|
|
482
556
|
}
|
|
483
557
|
} catch (err) {
|
|
@@ -487,7 +561,7 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
487
561
|
|
|
488
562
|
//////////////////// TEST 5: Verify a document's digital signatures in a simple fashion using the document API.
|
|
489
563
|
try {
|
|
490
|
-
if (!(await VerifySimple(input_path + 'waiver_withApprovalField_certified_approved.pdf', input_path + '
|
|
564
|
+
if (!(await VerifySimple(input_path + 'waiver_withApprovalField_certified_approved.pdf', input_path + 'apryse.cer'))) {
|
|
491
565
|
ret = 1;
|
|
492
566
|
}
|
|
493
567
|
} catch (err) {
|
|
@@ -495,10 +569,50 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
495
569
|
ret = 1;
|
|
496
570
|
}
|
|
497
571
|
|
|
498
|
-
//////////////////// TEST 6:
|
|
572
|
+
//////////////////// TEST 6: Custom signing API.
|
|
573
|
+
// The Apryse custom signing API is a set of APIs related to cryptographic digital signatures
|
|
574
|
+
// which allows users to customize the process of signing documents. Among other things, this
|
|
575
|
+
// includes the capability to allow for easy integration of PDF-specific signing-related operations
|
|
576
|
+
// with access to Hardware Security Module (HSM) tokens/devices, access to cloud keystores, access
|
|
577
|
+
// to system keystores, etc.
|
|
578
|
+
try {
|
|
579
|
+
await CustomSigningAPI(input_path + 'waiver.pdf',
|
|
580
|
+
'PDFTronCertificationSig',
|
|
581
|
+
input_path + 'apryse.pfx',
|
|
582
|
+
'password',
|
|
583
|
+
input_path + 'apryse.cer',
|
|
584
|
+
input_path + 'signature.jpg',
|
|
585
|
+
PDFNet.DigestAlgorithm.Type.e_SHA256,
|
|
586
|
+
true,
|
|
587
|
+
output_path + 'waiver_custom_signed.pdf');
|
|
588
|
+
} catch (err) {
|
|
589
|
+
console.log(err);
|
|
590
|
+
ret = 1;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
//////////////////// TEST 7: Timestamp a document, then add Long Term Validation (LTV) information for the DocTimeStamp.
|
|
499
594
|
// try {
|
|
595
|
+
// // Replace YOUR_URL_OF_TSA with the timestamp authority (TSA) URL to use during timestamping.
|
|
596
|
+
// // For example, as of June 2025, http://timestamp.globalsign.com/tsa/r6advanced1 was usable.
|
|
597
|
+
// // Note that this url may not work in the future. A reliable solution requires using your own TSA.
|
|
598
|
+
// const tsa_url = 'YOUR_URL_OF_TSA';
|
|
599
|
+
// if (tsa_url == 'YOUR_URL_OF_TSA')
|
|
600
|
+
// {
|
|
601
|
+
// throw new Error('The URL of your timestamp authority was not specified.');
|
|
602
|
+
// }
|
|
603
|
+
//
|
|
604
|
+
// // Replace YOUR_CERTIFICATE with the trusted root certificate corresponding to the chain used by the timestamp authority.
|
|
605
|
+
// // For example, as of June 2025, https://secure.globalsign.net/cacert/root-r6.crt was usable.
|
|
606
|
+
// // Note that this certificate may not work in the future. A reliable solution requires using your own TSA certificate.
|
|
607
|
+
// const trusted_cert_path = 'YOUR_CERTIFICATE';
|
|
608
|
+
// if (trusted_cert_path == 'YOUR_CERTIFICATE')
|
|
609
|
+
// {
|
|
610
|
+
// throw new Error('The path to your timestamp authority trusted root certificate was not specified.');
|
|
611
|
+
// }
|
|
612
|
+
//
|
|
500
613
|
// if (!(await TimestampAndEnableLTV(input_path + 'waiver.pdf',
|
|
501
|
-
//
|
|
614
|
+
// tsa_url,
|
|
615
|
+
// trusted_cert_path,
|
|
502
616
|
// input_path + 'signature.jpg',
|
|
503
617
|
// output_path + 'waiver_DocTimeStamp_LTV.pdf'))) {
|
|
504
618
|
// ret = 1;
|
|
@@ -524,4 +638,4 @@ const PDFTronLicense = require('../LicenseKey/LicenseKey');
|
|
|
524
638
|
exports.runDigitalSignatureTest();
|
|
525
639
|
})(exports);
|
|
526
640
|
// eslint-disable-next-line spaced-comment
|
|
527
|
-
//# sourceURL=DigitalSignatureTest.js
|
|
641
|
+
//# sourceURL=DigitalSignatureTest.js
|