This sample is demonstrating how to integrate the Apryse WebViewer into Salesforce as a Lightning Web Component. For more information, see this guide.
WebViewer provides a slick out-of-the-box responsive UI that enables you to view, annotate and manipulate PDFs and other document types inside any web project.
Click the button below to view the full project in GitHub.
1import { LightningElement, track, wire } from 'lwc';
2// import { ShowToastEvent } from 'lightning/platformShowToastEvent';
3import { CurrentPageReference } from 'lightning/navigation';
4import { loadScript } from 'lightning/platformResourceLoader';
5import libUrl from '@salesforce/resourceUrl/lib';
6import myfilesUrl from '@salesforce/resourceUrl/myfiles';
7import { registerListener, unregisterAllListeners } from 'c/pubsub';
8
9export default class PdftronWebViewer extends LightningElement {
10 fullAPI = true;
11 @wire(CurrentPageReference) pageRef;
12
13 connectedCallback() {
14 registerListener('fileSelected', this.handleFileSelected, this);
15 }
16
17 disconnectedCallback() {
18 unregisterAllListeners(this);
19 }
20
21 handleFileSelected(file) {
22 this.iframeWindow.postMessage({type: 'OPEN_DOCUMENT', file: file}, '*')
23 }
24
25 divHeight = 600;
26 uiInitialized = false;
27 renderedCallback() {
28 if (this.uiInitialized) {
29 return;
30 }
31 this.uiInitialized = true;
32
33 Promise.all([
34 loadScript(this, libUrl + '/webviewer.min.js')
35 ])
36 .then(() => {
37 this.initUI();
38 })
39 .catch(console.error);
40 }
41 initUI() {
42 const myObj = {
43 libUrl: libUrl,
44 fullAPI: this.fullAPI,
45 namespacePrefix: '',
46 };
47
48 const url = myfilesUrl + '/webviewer-demo-annotated.pdf';
49 // var url = myfilesUrl + '/webviewer-demo-annotated.xod';
50 // var url = myfilesUrl + '/word.docx';
51
52 const viewerElement = this.template.querySelector('div')
53 const viewer = new WebViewer.Iframe({
54 path: libUrl, // path to the PDFTron 'lib' folder on your server
55 custom: JSON.stringify(myObj),
56 backendType: 'ems',
57 config: myfilesUrl + '/config_apex.js',
58 fullAPI: this.fullAPI,
59 enableFilePicker: this.enableFilePicker,
60 enableRedaction: this.enableRedaction,
61 enableMeasurement: this.enableMeasurement,
62 enableOptimizedWorkers: true,
63 // l: 'YOUR_LICENSE_KEY_HERE',
64 }, viewerElement);
65
66 viewerElement.addEventListener('ready', () => {
67 this.iframeWindow = viewerElement.querySelector('iframe').contentWindow
68 })
69
70 }
71}
72
1import getUser from '@salesforce/apex/PDFTron_ContentVersionController.getUser';
2import saveDocument from '@salesforce/apex/PDFTron_ContentVersionController.saveDocument';
3import libUrl from '@salesforce/resourceUrl/lib';
4import myfilesUrl from '@salesforce/resourceUrl/myfiles';
5import { fireEvent, registerListener, unregisterAllListeners } from 'c/pubsub';
6import { CurrentPageReference } from 'lightning/navigation';
7import { loadScript } from 'lightning/platformResourceLoader';
8import { api, LightningElement, wire } from 'lwc';
9import mimeTypes from './mimeTypes';
10
11function _base64ToArrayBuffer(base64) {
12 var binary_string = window.atob(base64);
13 var len = binary_string.length;
14 var bytes = new Uint8Array( len );
15 for (var i = 0; i < len; i++) {
16 bytes[i] = binary_string.charCodeAt(i);
17 }
18 return bytes.buffer;
19}
20
21export default class PdftronWvInstance extends LightningElement {
22 //initialization options
23 fullAPI = true;
24 enableRedaction = true;
25 enableFilePicker = true;
26
27 uiInitialized = false;
28
29 source = 'My file';
30 @api recordId;
31
32 @wire(CurrentPageReference)
33 pageRef;
34
35 username;
36
37 connectedCallback() {
38 registerListener('blobSelected', this.handleBlobSelected, this);
39 registerListener('closeDocument', this.closeDocument, this);
40 registerListener('downloadDocument', this.downloadDocument, this);
41 registerListener('fileSelected', this.handleFileSelected, this);
42 window.addEventListener('message', this.handleReceiveMessage.bind(this), false);
43 }
44
45 disconnectedCallback() {
46 unregisterAllListeners(this);
47 window.removeEventListener('message', this.handleReceiveMessage);
48 }
49
50 handleBlobSelected(record) {
51 const blobby = new Blob([_base64ToArrayBuffer(record.body)], {
52 type: mimeTypes[record.FileExtension]
53 });
54
55
56 const payload = {
57 blob: blobby,
58 extension: record.cv.FileExtension,
59 filename: record.cv.Title + "." + record.cv.FileExtension,
60 documentId: record.cv.Id
61 };
62
63 this.iframeWindow.postMessage({ type: 'OPEN_DOCUMENT_BLOB', payload }, '*');
64 }
65
66 renderedCallback() {
67 var self = this;
68
69 if (this.uiInitialized) {
70 return;
71 }
72
73 Promise.all([
74 loadScript(self, libUrl + '/webviewer.min.js')
75 ])
76 .then(() => this.handleInitWithCurrentUser())
77 .catch(console.error);
78 }
79
80 handleFileSelected(file) {
81 this.iframeWindow.postMessage({type: 'OPEN_DOCUMENT', file: file}, '*')
82 }
83
84 handleInitWithCurrentUser() {
85 getUser()
86 .then((result) => {
87 this.username = result;
88 this.error = undefined;
89
90 this.initUI();
91 })
92 .catch((error) => {
93 console.error(error);
94 this.showNotification('Error', error.body.message, 'error');
95 });
96 }
97
98 initUI() {
99 var myObj = {
100 libUrl: libUrl,
101 fullAPI: this.fullAPI || false,
102 namespacePrefix: '',
103 username: this.username,
104 };
105 var url = myfilesUrl + '/webviewer-demo-annotated.pdf';
106
107 const viewerElement = this.template.querySelector('div')
108 // eslint-disable-next-line no-unused-vars
109 const viewer = new WebViewer.Iframe({
110 path: libUrl, // path to the PDFTron 'lib' folder on your server
111 custom: JSON.stringify(myObj),
112 backendType: 'ems',
113 config: myfilesUrl + '/config_apex.js',
114 fullAPI: this.fullAPI,
115 enableFilePicker: this.enableFilePicker,
116 enableRedaction: this.enableRedaction,
117 enableMeasurement: this.enableMeasurement,
118 enableOptimizedWorkers: true,
119 loadAsPDF: true,
120 // l: 'YOUR_LICENSE_KEY_HERE',
121 }, viewerElement);
122
123 viewerElement.addEventListener('ready', () => {
124 this.iframeWindow = viewerElement.querySelector('iframe').contentWindow;
125 })
126
127 }
128
129 handleReceiveMessage(event) {
130 const me = this;
131 if (event.isTrusted && typeof event.data === 'object') {
132 switch (event.data.type) {
133 case 'SAVE_DOCUMENT':
134 const cvId = event.data.payload.contentDocumentId;
135 saveDocument({ json: JSON.stringify(event.data.payload), recordId: this.recordId ? this.recordId : '', cvId: cvId })
136 .then((response) => {
137 me.iframeWindow.postMessage({ type: 'DOCUMENT_SAVED', response }, '*')
138 fireEvent(this.pageRef, 'refreshOnSave', response);
139 })
140 .catch(error => {
141 me.iframeWindow.postMessage({ type: 'DOCUMENT_SAVED', error }, '*')
142 fireEvent(this.pageRef, 'refreshOnSave', error);
143 console.error(event.data.payload.contentDocumentId);
144 console.error(JSON.stringify(error));
145 this.showNotification('Error', error.body, 'error')
146 });
147 break;
148 default:
149 break;
150 }
151 }
152 }
153
154 downloadDocument() {
155 this.iframeWindow.postMessage({type: 'DOWNLOAD_DOCUMENT' }, '*')
156 }
157
158 @api
159 closeDocument() {
160 this.iframeWindow.postMessage({type: 'CLOSE_DOCUMENT' }, '*')
161 }
162}
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales