Save PDF Blob is not working

Hi Team,

we have added Annotations freeText like below after adding Annotation trying to save that PDF as blob but it is not working. Can you please check and let me know how to save pdf.

Annotations code:
const freeText = new Annotations.FreeTextAnnotation();
// const pageNo = pageNo;
freeText.PageNumber = pageNo;
freeText.X = 370;
freeText.Y = 5;
freeText.Width = 235;
freeText.Height = 50;
freeText.setPadding(new Annotations.Rect(0, 0, 0, 0));
freeText.setContents(“Welcome”);
freeText.FillColor = new Annotations.Color(255,255,255);
freeText.TextColor = new Annotations.Color("#000000");
freeText.FontSize = ‘16pt’;
annotManager.addAnnotation(freeText, { autoFocus: false });
annotManager.redrawAnnotation(freeText);

Save PDF:

const doc = docViewer.getDocument();
const xfdfString = await annotManager.exportAnnotations();
const options = { xfdfString };
const data = await doc.getFileData(options);
const arr = new Uint8Array(data);
const blob = new Blob([arr], { type: ‘application/pdf’ });

Error :
ERROR Error: Uncaught (in promise): TypeError: Cannot convert undefined or null to object
TypeError: Cannot convert undefined or null to object

Hi Suresh,

I tested the following code and I get the blob as expected. When are you running your code? It could be the case that you are trying to download the document before it is actually loaded. Note that I am running the code after the documentLoaded event has been fired.

  docViewer.on('documentLoaded', async () => {
    const freeText = new Annotations.FreeTextAnnotation();
    const pageNo = 1;
    freeText.PageNumber = pageNo;
    freeText.X = 370;
    freeText.Y = 5;
    freeText.Width = 235;
    freeText.Height = 50;
    freeText.setPadding(new Annotations.Rect(0, 0, 0, 0));
    freeText.setContents('Welcome');
    freeText.FillColor = new Annotations.Color(255,255,255);
    freeText.TextColor = new Annotations.Color("#000000");
    freeText.FontSize = "16pt";
    annotManager.addAnnotation(freeText, { autoFocus: false });
    annotManager.redrawAnnotation(freeText);

    // Save PDF:
    const doc = docViewer.getDocument();
    const xfdfString = await annotManager.exportAnnotations();
    const options = { xfdfString };
    const data = await doc.getFileData(options);
    const arr = new Uint8Array(data);
    const blob = new Blob([arr], { type: "application/pdf" });
    console.log({ blob })
  })

Best Regards,
Armando Bollain
Software Developer
PDFTron Systems, Inc.
www.pdftron.com

Hi Suresh,

I tested the snippet I pasted on 7.3.3 and it worked as expected - the FreeText gets added, and I see the blob printed on the console. The snippet is a direct copy paste of what you shared initially so I wonder what else could be happening.

Are you able to share a repository in git where I can reproduce the error? Or can you share your entire WebViewer code so I can pinpoint the potential issue?

When you add the FreeText programatically with this code, does it work?

WebViewer(...)
  .then(instance => {
    const { Annotations, annotManager, docViewer } = instance;

    docViewer.on('documentLoaded', () => {
      const freeText = new Annotations.FreeTextAnnotation();
      freeText.PageNumber = 1;
      freeText.X = 150;
      freeText.Y = 200;
      freeText.Width = 150;
      freeText.Height = 50;
      freeText.setPadding(new Annotations.Rect(0, 0, 0, 0));
      freeText.setContents('My Text');
      freeText.FillColor = new Annotations.Color(0, 255, 255);
      freeText.FontSize = '16pt';

      annotManager.addAnnotation(freeText, { autoFocus: false });
      annotManager.redrawAnnotation(freeText);
    })
  })

Best Regards,
Armando Bollain
Software Developer
PDFTron Systems, Inc.

Hi Team,

I am using the below code

app.component.html:

app.component.js:

import {​​​​​​​ Component, ViewChild, OnInit, ElementRef, AfterViewInit }​​​​​​​ from ‘@angular/core’;
import WebViewer from ‘@pdftron/webviewer’;

// Please remove single quotes ‘@’ below Componenet
‘@‘Component({​​​​​​​
selector: ‘app-root’,
templateUrl: ‘./app.component.html’,
styleUrls: [’./app.component.css’]
}​​​​​​​)
export class HomeComponent implements OnInit, AfterViewInit {​​​​​​​
// Please remove single quotes ‘@’ below ViewChild
'@'ViewChild(‘viewer’) viewer: ElementRef;
wvInstance: any;

ngAfterViewInit(): void {​​​​​​​

WebViewer({​​​​​​​
  path: '../lib',
  initialDoc: '../files/webviewer-demo-annotated.pdf'
}​​​​​​​, this.viewer.nativeElement).then(instance => {​​​​​​​
  this.wvInstance = instance;
  const {​​​​​​​ Annotations, annotManager, docViewer }​​​​​​​ = this.wvInstance;
  // now you can access APIs through this.webviewer.getInstance()
  instance.openElements(['notesPanel']);
  // see https://www.pdftron.com/documentation/web/guides/ui/apis for the full list of APIs


  // or listen to events from the viewer element
  this.viewer.nativeElement.addEventListener('pageChanged', (e) => {​​​​​​​
    const [ pageNumber ] = e.detail;
    console.log(`Current page is ${​​​​​​​pageNumber}​​​​​​​`);
  }​​​​​​​);


  // or from the docViewer instance
  instance.docViewer.on('annotationsLoaded', () => {​​​​​​​
    console.log('annotations loaded');
  }​​​​​​​);


  // instance.docViewer.on('documentLoaded', this.wvDocumentLoadedHandler)
 instance.docViewer.on('documentLoaded', async () => {​​​​​​​
    const freeText = new Annotations.FreeTextAnnotation();
    const pageNo = 1;
    freeText.PageNumber = pageNo;
    freeText.X = 370;
    freeText.Y = 5;
    freeText.Width = 235;
    freeText.Height = 50;
    freeText.setPadding(new Annotations.Rect(0, 0, 0, 0));
    freeText.setContents('Welcome');
    freeText.FillColor = new Annotations.Color(255,255,255);
    freeText.TextColor = new Annotations.Color("#000000");
    freeText.FontSize = "16pt";
    annotManager.addAnnotation(freeText, {​​​​​​​ autoFocus: false }​​​​​​​);
    annotManager.redrawAnnotation(freeText);

    // Save PDF:
    const doc = docViewer.getDocument();
    const xfdfString = await annotManager.exportAnnotations();
    const options = {​​​​​​​ xfdfString }​​​​​​​;
    const data = await doc.getFileData(options);
    const arr = new Uint8Array(data);
    const blob = new Blob([arr], {​​​​​​​ type: "application/pdf" }​​​​​​​);
    console.log({​​​​​​​ blob }​​​​​​​)
  }​​​​​​​)
}​​​​​​​)

}​​​​​​​

}​​​​​​​

still getting the same error:
Unhandled Promise rejection: TypeError: Cannot convert undefined or null to object
at Function.keys ()
at n (CoreControls.js:938)
at CoreControls.js:939 ; Zone: ; Task: Promise.then ; Value: TypeError: Cannot convert undefined or null to object
at Function.keys ()
at n (CoreControls.js:938)
at CoreControls.js:939 undefined

Hi Suresh,

I am still not able to reproduce the issue with this code from your sample:

Webviewer({
  initialDoc: hashFile,
  path: '/lib',
}, document.getElementById('viewer')).then(instance => {

  const { docViewer, Annotations, annotManager } = instance;


  instance.openElements(['notesPanel']);
  // see https://www.pdftron.com/documentation/web/guides/ui/apis for the full list of APIs

  // or from the docViewer instance
  instance.docViewer.on('annotationsLoaded', () => {
    console.log('annotations loaded')
  });


  instance.docViewer.on('documentLoaded', async () => {
    const freeText = new Annotations.FreeTextAnnotation();
    const pageNo = 1;
    freeText.PageNumber = pageNo;
    freeText.X = 370;
    freeText.Y = 5;
    freeText.Width = 235;
    freeText.Height = 50;
    freeText.setPadding(new Annotations.Rect(0, 0, 0, 0));
    freeText.setContents('Welcome');
    freeText.FillColor = new Annotations.Color(255,255,255);
    freeText.TextColor = new Annotations.Color("#000000");
    freeText.FontSize = "16pt";
    annotManager.addAnnotation(freeText, { autoFocus: false });
    annotManager.redrawAnnotation(freeText);

    // Save PDF:
    const doc = docViewer.getDocument();
    const xfdfString = await annotManager.exportAnnotations();
    const options = { xfdfString };
    const data = await doc.getFileData(options);
    const arr = new Uint8Array(data);
    const blob = new Blob([arr], { type: "application/pdf" });
    console.log( {blob })
  })
});

I see the blob printed to the console. Is the issue potentially with how you have integrated WebViewer into your angular application? If you remove the code to print the blob, does the WebViewer run as expected?

Are you able to just add the FreeText programatically without errors?

We have a guide on integrating WebViewer into existing Angular projects:

The alternative is for you to host something on github where I can reproduce the issue on a dummy Angular app, as this code snippet works.

Best Regards,
Armando Bollain
Software Developer
PDFTron Systems, Inc.

Hi Armando,
we can able to add the FreeText programatically without errors. Once added FreeText save as Blob and download pdf is not working.

  1. I have upload the zip file in below Git except “lib” folder due to file size. Can you please download the zip file and try once.
  2. Download(under Menu->Download) also not working once annotation text added .

Git url : GitHub - SureshAbbvie/PdfTron

Can you please let me know if you need any more information.
Note : we are using Trial Version.

Hi Suresh,

I downloaded your zip file (it included lib as well), and noticed you don’t have all the correct library files, which is likely why you are getting this error. When I run your app with all the correct files, it prints the blob as expected and the doc can be downloaded. You can get the latest build form here.

Once I put all the library files in your app everything works as expected:
image

Best Regards,
Armando Bollain
Software Developer
PDFTron Systems, Inc.

Thanks Armando, It is working fine now.
Can you please let me know how to convert blob to base64.

Thanks,
Suresh M

Hi Suresh,

Glad to hear it worked out for you. To convert blob to base64 you can follow StackOverflow posts like the following:

If you have any other Webviewer question let us know in this forum, for other non-Webviewer related questions you can reach out in forums like StackOverflow.

All the best,
Armando Bollain
Software Developer
PDFTron Systems, Inc