Saving Annotated PDF Files Using PDF.js

I’ve been working on a project where I need to save a PDF file after annotations have been added using PDF.js. Despite being able to successfully download the file with annotations, I’ve been unable to directly save the annotated file through my implementation.

Is it possible to save a PDF file with annotations using PDF.js? If so, could someone kindly provide a small demo or guide on the method you used to achieve this? Any tips, best practices, or code snippets would be greatly appreciated.

Thank you in advance for your assistance. I believe that if downloading the file with annotations is feasible, then saving it should be possible as well, and I’m eager to learn the right approach.

This is what I have so far, im able to get all the form fields except the annotated file on the backend,

<script>

document.addEventListener('DOMContentLoaded', ()= > {
    const iframe= document.getElementById('iframe_pdfjs')

    iframe.onload= function() {
        const iframeWindow = iframe.contentWindow

        // Listen for pagesloaded event to ensure PDF.js is fully initialized
        iframeWindow.addEventListener('pagesloaded', function() {
            console.log('PDF.js pages loaded')

            // Debugging: Log the PDFViewerApplication and related objects
            console.log('PDFViewerApplication:',
                        iframeWindow.PDFViewerApplication)
            console.log('PDF Viewer:',
                        iframeWindow.PDFViewerApplication.pdfViewer)
            console.log('Annotation Storage:',
                        iframeWindow.PDFViewerApplication.pdfViewer.annotationStorage)
            console.log('Annotation Editor Layer:',
                        iframeWindow.PDFViewerApplication.pdfViewer.annotationEditorLayer)

            // Try to access annotationStorage directly
            const annotationStorage = iframeWindow.PDFViewerApplication.pdfViewer.annotationStorage
            if (!annotationStorage) {
                console.error('Annotation storage not available')
                alert('Annotations could not be retrieved.')
                return
            }

            const annotations = annotationStorage.serialize()
            if (!annotations) {
                console.error('Annotations are null or undefined')
                alert('Failed to serialize annotations.')
                return
            }

            // Proceed to save the document
            document.getElementById('saveForm').addEventListener('submit', async function(event) {
                event.preventDefault()
                try {
                    const pdfDoc = iframeWindow.PDFViewerApplication.pdfDocument
                    const data = await pdfDoc.saveDocument({xfdfString: annotations})
                    const blob = new Blob([new Uint8Array(data)], {type: 'application/pdf'})

                    // Log to confirm the blob was created
                    console.log('Blob created:', blob)
                    console.log('Blob size:', blob.size)

                    const formData = new FormData()
                    formData.append('signed_document', blob,
                                    'signed_document.pdf')
                    formData.append('first_name', document.getElementById(
                        'id_first_name').value)
                    formData.append('last_name', document.getElementById(
                        'id_last_name').value)
                    formData.append(
                        'email', document.getElementById('id_email').value)
                    formData.append(
                        'phone', document.getElementById('id_phone').value)
                    formData.append(
                        'dob', document.getElementById('id_dob').value)
                    formData.append(
                        'gender', document.getElementById('id_gender').value)

                    const response= await axios.post('.', formData, {
                        headers: {
                            'X-CSRFToken': '{{ csrf_token }}',
                            'Content-Type': 'multipart/form-data'
                        }
                    })

                    if (response.status == = 200) {
                        window.location.href = '{% url "sign:thank_you" %}'
                    } else {
                        alert('Failed to save the signed document.')
                    }
                } catch(error) {
                    console.error('There was an error!', error)
                    alert('Failed to save the signed document.')
                }
            })
        })
    }
});
</script>