Some test text!
Salesforce / Guides / Saving Annotations
Platform
Documentation
First, you need to generate a base64 string that is sent to the Apex backend. Use the following function in your config_apex.js
file to achieve this:
async function saveDocument() {
const doc = docViewer.getDocument();
if (!doc) {
return;
}
instance.openElement('loadingModal');
const fileType = doc.getType();
const filename = doc.getFilename();
const xfdfString = await docViewer.getAnnotationManager().exportAnnotations();
const data = await doc.getFileData({
// Saves the document with annotations in it
xfdfString
});
let binary = '';
const bytes = new Uint8Array(data);
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
const base64Data = window.btoa(binary);
const payload = {
title: filename.replace(/\.[^/.]+$/, ""),
filename,
base64Data,
contentDocumentId: doc.__contentDocumentId
}
// Post message to LWC
parent.postMessage({ type: 'SAVE_DOCUMENT', payload }, '*');
}
async function saveDocument() {
const doc = docViewer.getDocument();
if (!doc) {
return;
}
readerControl.openElement('loadingModal');
const fileType = doc.getType();
const filename = doc.getFilename();
const xfdfString = await docViewer.getAnnotationManager().exportAnnotations();
const data = await doc.getFileData({
// Saves the document with annotations in it
xfdfString
});
let binary = '';
const bytes = new Uint8Array(data);
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
const base64Data = window.btoa(binary);
const payload = {
title: filename.replace(/\.[^/.]+$/, ""),
filename,
base64Data,
contentDocumentId: doc.__contentDocumentId
}
// Post message to LWC
parent.postMessage({ type: 'SAVE_DOCUMENT', payload }, '*');
}
Once you have your document's data converted, you can pass it to Apex. This snippet uses
//snipped for brevity
//see full github sample to see how to set up event flow
handleReceiveMessage(event) {
const me = this;
if (event.isTrusted && typeof event.data === 'object') {
switch (event.data.type) {
case 'SAVE_DOCUMENT':
saveDocument({ json: JSON.stringify(event.data.payload), recordId: this.recordId }).then((response) => {
me.iframeWindow.postMessage({ type: 'DOCUMENT_SAVED', response }, '*')
}).catch(error => {
console.error(JSON.stringify(error));
});
break;
default:
break;
}
}
}
Finally, you can use the below Apex code snippet to create a new ContentVersion record. This sample also links the newly created document to the sObject record you started from.
// force-app\main\default\classes\ContentVersionController.cls
public with sharing class ContentVersionController {
// snipped for brevity
@AuraEnabled
public static void saveDocument(String json, String recordId) {
try {
PDFTron_ContentVersionPayload pl = PDFTron_ContentVersionPayload.parse(json);
ContentVersion cv = new ContentVersion();
cv.ContentLocation = 'S'; //File originated in Salesforce
if(pl.contentDocumentId != null) {
cv.ContentDocumentId = pl.contentDocumentId;
cv.ReasonForChange = 'Saved from WebViewer';//only for file updates
} else {
for(ContentDocumentLink cdl :
[ SELECT ContentDocumentId, ContentDocument.Title
FROM ContentDocumentLink
WHERE LinkedEntityId = :recordId
AND ContentDocument.Title = :pl.title ]) {
if(cdl.ContentDocumentId != null) {
cv.ContentDocumentId = cdl.ContentDocumentId;
}
}
}
cv.VersionData = EncodingUtil.base64Decode(pl.base64Data);
cv.Title = pl.title;
cv.PathOnClient = pl.filename;
insert cv;
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
}
}
You can also find the full source code for an end to end flow in this Github repository.
Get the answers you need: Support