Ähnlich wie Interceptor-Beispiel: Annotationen vor dem Speichern sperren in der Wirkung, geht dieser Interceptor noch etwas weiter: Wenn der Einbrennen-Button gedrückt wird, werden alle Annotationen im PDF dauerhaft in das PDF integriert:
class EDAnnotationFlattener {
// code fragements taken from https://docs.apryse.com/documentation/web/guides/annotation/flatten-annotations/
buttonDataElement = 'custom_annotation_flattener_button';
dialogDataElement = 'custom_annotation_flattener_dialog';
async flattenAllAnnotations(instance) {
const { documentViewer, PDFNet, annotationManager } = instance.Core;
await PDFNet.initialize();
const theDocument = await documentViewer.getDocument().getPDFDoc();
// export annotations from the document
const allAnnotations = await annotationManager.exportAnnotations();
// Run PDFNet methods with memory management
await PDFNet.runWithCleanup(async () => {
// lock the document before a write operation
// runWithCleanup will auto unlock when complete
theDocument.lock();
// import annotations to PDFNet
const fdfDocument = await PDFNet.FDFDoc.createFromXFDF(allAnnotations);
await theDocument.fdfUpdate(fdfDocument);
// flatten all annotations in the document
// see https://docs.apryse.com/api/web/Core.PDFNet.PDFDoc.html#flattenAnnotations__anchor
await theDocument.flattenAnnotations();
// clear the original annotations
annotationManager.deleteAnnotations(annotationManager.getAnnotationsList());
});
// clear the cache (rendered) data with the newly updated document
documentViewer.refreshAll();
// Update viewer to render with the new document
documentViewer.updateView();
// Refresh searchable and selectable text data with the new document
documentViewer.getDocument().refreshTextData();
}
initEditorConfiguration(instance) {
// Create a new action button
const aButton = {
dataElement: this.buttonDataElement,
type: 'actionButton',
img: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-fire" viewBox="0 0 16 16"><path d="M8 16c3.314 0 6-2 6-5.5 0-1.5-.5-4-2.5-6 .25 1.5-1.25 2-1.25 2C11 4 9 .5 6 0c.357 2 .5 4-2 6-1.25 1-2 2.729-2 4.5C2 14 4.686 16 8 16Zm0-1c-1.657 0-3-1-3-2.75 0-.75.25-2 1.25-3C6.125 10 7 10.5 7 10.5c-.375-1.25.5-3.25 2-3.5-.179 1-.25 2 1 3 .625.5 1 1.364 1 2.25C11 14 9.657 15 8 15Z"/></svg>',
title: 'Alle Anmerkungen einbrennen',
onClick: () => instance.UI.openElements([this.dialogDataElement]),
};
// Add the new button to the header
instance.UI.setHeaderItems((header) => {
header.push(aButton);
});
const body = document.createElement("div");
body.innerHTML = "Alle Anmerkungen werden unwiderruflich in das PDF integriert. Sind Sie sicher, dass Sie dies möchten?";
const modal = {
dataElement: this.dialogDataElement,
header: {
title: 'Annotationen einbrennen',
},
body: {
className: 'myCustomModal-body',
style: {textAlign: "center"}, // optional inline styles
children: [body], // HTML dom elements
},
footer: {
className: 'myCustomModal-footer footer',
style: {}, // optional inline styles
children: [
{
title: 'Abbrechen',
button: true,
style: {},
className: 'modal-button cancel-form-field-button',
onClick: async (e) => {
instance.UI.closeElements([this.dialogDataElement]);
},
},
{
title: 'Einbrennen',
button: true,
style: {},
className: 'modal-button confirm ok-btn',
onClick: async (e) => {
await this.flattenAllAnnotations(instance);
instance.UI.closeElements([this.dialogDataElement]);
},
},
],
},
};
instance.UI.addCustomModal(modal);
}
async updateEditorConfiguration(instance, info, config) {
if (info.mode != 'edit') {
instance.UI.disableElements([this.buttonDataElement]);
} else {
instance.UI.enableElements([this.buttonDataElement]);
}
}
}
window.ed.registerInterceptor(new EDAnnotationFlattener());
„Installiert“ werden kann dies wie üblich durch einfaches Abspeichern im Interceptors
-Verzeichnis als .js
-Datei:
Hinweis: Natürlich schützt dies nicht vor technisch versierter Manipulation des PDFs. So etwas lässt sich nur durch digitale Signaturen oder der Ablage in einem revisionssicheren Archiv verhindern.