Validate PDF/A - Showcase Demo

Requirements
View Demo

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: Follow get started in your preferred web stack for WebViewer
Step 2: Add the ES6 JavaScript sample code provided in this guide

Once you generate your license key, it will automatically be included in your sample code below.

License Key

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