Validate PDF/A Showcase Demo Code Sample

Quickly determine whether a PDF/A is fully compliant with the international standard ISO 19005:1/2/3/4. In case of non-compliance, you will obtain a detailed report of violations with a list of relevant error objects.

PDF/A is an ISO-standardized version of the Portable Document Format (PDF) specialized for use in the archiving and long-term preservation of electronic documents. PDF/A differs from PDF by prohibiting features unsuitable for long-term archiving, such as font linking (as opposed to font embedding) and encryption.

This demo allows you to:

  • Choose your own PDF file to validate
  • Check specification compliance to ISO 19005:1/2/3/4
  • Produce a results report
  • Customize compliance checks
  • Validate whether a PDF/A file is safe for long term storage

Implementation steps
To add PDF/A validation capability with WebViewer:


Step 1: Choose your preferred web stack
Step 2: Download any required modules listed in the Demo Dependencies section below
Step 3: Add the ES6 JavaScript sample code provided in this guide

Demo Dependencies
This sample uses the following:

Want to see a live version of this demo?

Try the PDF/A Validate demo

1/*
2ES6 Compliant Syntax
3GitHub Copilot, Version 1.0, Model GPT-4, 2024-06-09
4File: validate-pdfa/index.js
5*/
6
7import WebViewer from '@pdftron/webviewer';
8
9
10const element = document.getElementById('viewer');
11let theInstance = null;
12const onLoad = async (instance) => {
13 theInstance = instance;
14};
15
16WebViewer(
17 {
18 path: '/lib',
19 licenseKey: 'YOUR_LICENSE_KEY',
20 initialDoc: 'https://apryse.s3.us-west-1.amazonaws.com/public/files/samples/pdfa.pdf',
21 fullAPI: true, // Enable full API access to use validation features
22 },
23 element
24).then((instance) => {
25 onLoad(instance);
26});
27
28const pdfaLevels = [
29 { label: 'PDF/A-1A', value: '1A' },
30 { label: 'PDF/A-1B', value: '1B' },
31
32 { label: 'PDF/A-2A', value: '2A' },
33 { label: 'PDF/A-2B', value: '2B' },
34 { label: 'PDF/A-2U', value: '2U' },
35
36 { label: 'PDF/A-3A', value: '3A' },
37 { label: 'PDF/A-3B', value: '3B' },
38 { label: 'PDF/A-3U', value: '3U' },
39
40 { label: 'PDF/A-4', value: '4' },
41 { label: 'PDF/A-4E', value: '4E' },
42 { label: 'PDF/A-4F', value: '4F' },
43];
44
45// Validate PDF/A compliance
46// This is the main function, which checks the PDF/A compliance of the currently loaded document
47async function validatePdfa() {
48 let validResult = ""; // Replace with actual validation logic
49 const documentViewer = theInstance.Core.documentViewer;
50
51 const xfdfString = await theInstance.Core.annotationManager.exportAnnotations();
52 const currentDocument = documentViewer.getDocument();
53 const data = await currentDocument.getFileData({
54 xfdfString,
55 flags: theInstance.Core.SaveOptions.INCREMENTAL,
56 });
57
58 if(currentDocument.type !== 'pdf') {
59 labelStatus.textContent = '❌ Cannot validate PDF/A compliance. This document is not a PDF.';
60 labelStatus.style.backgroundColor = 'lightcoral';
61 return;
62 }
63 const pdfDoc = await currentDocument.getPDFDoc();
64 let pdfaVersion = await theInstance.Core.PDFNet.PDFACompliance.getDeclaredConformance(pdfDoc) - 1;
65 if(pdfaVersion === -1)
66 pdfaVersion = 0; // Default to PDF/A-1A if no conformance is declared
67
68 console.log(`PDF/A Version: ${pdfaVersion}`);
69 const conformanceLevel = theInstance.Core.PDFNet.PDFACompliance.Conformance[`e_Level${pdfaLevels[pdfaVersion].value}`];
70
71 const pdfa = await theInstance.Core.PDFNet.PDFACompliance.createFromBuffer(
72 false,
73 new Uint8Array(data),
74 '',
75 conformanceLevel
76 );
77
78 const errorCount = await pdfa.getErrorCount();
79 if (errorCount === 0) {
80 validResult = "✅ PDF/A Validation Successful. ";
81 validResult += `Standard: ${pdfaLevels[pdfaVersion].label}. `;
82 validResult += `Conformance Level: ${pdfaLevels[pdfaVersion].value}`;
83 labelStatus.style.backgroundColor = 'lightgreen';
84 } else {
85 labelStatus.style.backgroundColor = 'lightcoral';
86 validResult = "❌ PDF/A Validation Failed. This document is not a PDF/A.";
87 }
88
89 labelStatus.textContent = validResult;
90}
91
92const buttonValidate = document.createElement('button');
93buttonValidate.textContent = 'Validate PDF/A';
94buttonValidate.onclick = async () => {
95 validatePdfa();
96};
97
98const buttonUpload = document.createElement('button');
99buttonUpload.textContent = 'Upload Local PDF';
100buttonUpload.onclick = async () => {
101 fileUpload.click();
102};
103
104const labelStatus = document.createElement('label');
105labelStatus.textContent = `Click "${buttonValidate.textContent}" to validate the PDF/A compliance of the document.`;
106
107// UI section
108//
109// Helper code to add controls to the viewer holding the buttons and dropdown
110// This code creates a container for the buttons and dropdown, styles them, and adds them to the viewer
111
112
113// Create a container for all controls (file input buttons)
114const controlsContainer = document.createElement('div');
115
116const fileUpload = document.createElement('input');
117fileUpload.style.display = 'none';
118fileUpload.type = 'file';
119fileUpload.accept = '.pdf';
120fileUpload.onchange = (event) => {
121 const file = event.target.files[0];
122 if (file) {
123 labelStatus.style.backgroundColor = '';
124 labelStatus.textContent = `Loading document: ${file.name}`;
125 const reader = new FileReader();
126 reader.onload = () => {
127 theInstance.UI.loadDocument(reader.result, {filename: file.name});
128 };
129 reader.readAsArrayBuffer(file);
130 }
131};
132
133buttonUpload.className = 'btn-style';
134buttonValidate.className = 'btn-style';
135labelStatus.className = 'label-status';
136controlsContainer.className = 'button-container';
137controlsContainer.appendChild(fileUpload);
138controlsContainer.appendChild(buttonUpload);
139controlsContainer.appendChild(buttonValidate);
140controlsContainer.appendChild(labelStatus);
141element.insertBefore(controlsContainer, element.firstChild);

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales