PDF Viewer for Vaadin 13

I’m trying to attach a pdf viewer in my vaadin app. And I have 2 possible solutions in mind:

  1. Use an existing component in Vaadin…All samples I see are from Vaadin 8 using Embedded object. Is there any compatible PDF viewer component for Vaadin 13?
  2. using 3rd party javascript library. I’m trying to use [ViewerJS]
    (https://viewerjs.org/) but I’m unable to load the static Index.html as instructed in ViewerJS [instruction.]
    (https://viewerjs.org/instructions/).
    As per ViewerJS instruction I could create a link like so (where ViewerJS is in my server folder):
Here are the basic steps that are necessary to put ViewerJS on your website.

Everything starts with downloading ViewerJS from the website.
Unpack the file on your computer. This will give you a folder called 'ViewerJS'. Upload that folder to your webserver, preferably to the top folder. Now you are ready to see ViewerJS in action.

<a href="/ViewerJS/#../path/to/filename.ext">

Tried calling a javascript window.open() function but I can’t seem to reference the static html page.

UI.getCurrent().getPage().executeJavaScript("window.open('/static/frontend/ViewerJS/','_blank')");

Getting
Could not navigate to ‘static/frontend/ViewerJS/’
Reason: Couldn’t find route for ‘static/frontend/ViewerJS/’

Hi Jason,

I don’t think you need an additional javascript library to achieve this. This is a quick and dirty solution that I came up with (based on this [stackoverflow post]
(https://stackoverflow.com/questions/14081128/how-can-i-embed-a-pdf-viewer-in-a-web-page/14081168#14081168)):

@Tag("object")
public class EmbeddedPdfDocument extends Component implements HasSize {

  public EmbeddedPdfDocument(StreamResource resource) {
    this();
    getElement().setAttribute("data", resource);
  }

  public EmbeddedPdfDocument(String url) {
    this();
    getElement().setAttribute("data", url);
  }

  protected EmbeddedPdfDocument() {
    getElement().setAttribute("type", "application/pdf");
    setSizeFull();
  }
}

This component can be used in three ways:

  1. Hosting a remote pdf document via a full URL:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument("https://vaadin.com/download/book-of-vaadin/vaadin-7/pdf/book-of-vaadin.pdf"));
    setHeight("100%");
  }
}
  1. Hosting a static document from the applications src/main/webapp/frontend directory:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument("frontend/book-of-vaadin.pdf"));
    setHeight("100%");
  }
}
  1. Dynamically reading a PDF in the application and exposing it to the user through a StreamResource:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument(new StreamResource("book-of-vaadin.pdf", () -> {
      try {
        return getPdfInputStream();
      } catch (FileNotFoundException e) {
        return new ByteArrayInputStream(new byte[]{});
      }
    })));
    setHeight("100%");
  }

  private InputStream getPdfInputStream() throws FileNotFoundException {
    return new FileInputStream("/home/dennis/workspace/vaadin/src/main/webapp/frontend/book-of-vaadin.pdf");
  }
}

You can use this add-on
[PDF Viewer for Vaadin 13]
(https://vaadin.com/directory/component/pdf-browser)

Dennis Reichenberg:
Hi Jason,

I don’t think you need an additional javascript library to achieve this. This is a quick and dirty solution that I came up with (based on this [stackoverflow post]
(https://stackoverflow.com/questions/14081128/how-can-i-embed-a-pdf-viewer-in-a-web-page/14081168#14081168)):

@Tag("object")
public class EmbeddedPdfDocument extends Component implements HasSize {

  public EmbeddedPdfDocument(StreamResource resource) {
    this();
    getElement().setAttribute("data", resource);
  }

  public EmbeddedPdfDocument(String url) {
    this();
    getElement().setAttribute("data", url);
  }

  protected EmbeddedPdfDocument() {
    getElement().setAttribute("type", "application/pdf");
    setSizeFull();
  }
}

This component can be used in three ways:

  1. Hosting a remote pdf document via a full URL:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument("https://vaadin.com/download/book-of-vaadin/vaadin-7/pdf/book-of-vaadin.pdf"));
    setHeight("100%");
  }
}
  1. Hosting a static document from the applications src/main/webapp/frontend directory:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument("frontend/book-of-vaadin.pdf"));
    setHeight("100%");
  }
}
  1. Dynamically reading a PDF in the application and exposing it to the user through a StreamResource:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument(new StreamResource("book-of-vaadin.pdf", () -> {
      try {
        return getPdfInputStream();
      } catch (FileNotFoundException e) {
        return new ByteArrayInputStream(new byte[]{});
      }
    })));
    setHeight("100%");
  }

  private InputStream getPdfInputStream() throws FileNotFoundException {
    return new FileInputStream("/home/dennis/workspace/vaadin/src/main/webapp/frontend/book-of-vaadin.pdf");
  }
}

This is exactly what I was looking for.
Thank you

Syam Pillai:
You can use this add-on
[PDF Viewer for Vaadin 13]
(https://vaadin.com/directory/component/pdf-browser)

Unfortunately, this shows a conflict with a particular dependency.

Caused by: org.eclipse.aether.collection.UnsolvableVersionConflictException: Could not resolve version conflict among [org.vaadin.klaudeta:grid-pagination:jar:1.0.0 -> org.webjars.bowergithub.klaudeta:plutonium-pagination:jar:0.2.1 -> org.webjars.bowergithub.polymerelements:paper-button:jar:[2.1.3,3), org.vaadin.alejandro:pdf_browser:jar:1.0.0-alpha1 -> org.webjars.bowergithub.ingressorapidowebcomponents:pdf-browser-viewer:jar:1.0.6 -> org.webjars.bowergithub.polymerelements:paper-button:jar:[1.0.12,2)]

	at org.eclipse.aether.util.graph.transformer.NearestVersionSelector.newFailure(NearestVersionSelector.java:150)
	at org.eclipse.aether.util.graph.transformer.NearestVersionSelector.backtrack(NearestVersionSelector.java:111)
	at org.eclipse.aether.util.graph.transformer.NearestVersionSelector.selectVersion(NearestVersionSelector.java:84)
	at org.eclipse.aether.util.graph.transformer.ConflictResolver.transformGraph(ConflictResolver.java:187)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.collectDependencies(DefaultDependencyCollector.java:273)

This is a real problem with webjars when we have independent jars depend on different versions of the same dependent jar. However, since webjars generally do not contain Java class files, it should not cause an issue at runtime (each webcomponent has its own scope for html, css or other resource files - I may be wrong here, I am not a webcomponent expert). Unfortunately, IDEs do not understand this.

Thank you Dennis Reichenberg :slight_smile:
it work fine - Vaadin 14.0.0

Hi,

The solution provided by Dennis works fine for me on Microsoft Edge (Vaadin 14) but will not work in Chrome or Firefox.

My Chrome settings are configured to open the PDF not download it. If I set it to download I get a PDF icon and can open the file in a Adobe Acrobat viewer.

I can access the files directly from both browsers perfectly but if I go through my application using Dennis’s solution above I get a blank screen - no errors.

Anyone have any ideas or suggestions?

Thanks, John

Hi

I fixed this - it was a setting on my Tomcat server. I had the http security filter set DENY.

Edge must ignore this and the other two browsers respect the setting.

I set the “anticlickJackingOption” to SAMEORIGIN and both chrome and firefox work now as expected.

John.

Out of curiosity, does anybody else have difficulty with viewing multi page PDF’s using this method on iOS devices? It will display the first page, but not let you scroll to other pages.

Yes, I have the same problem with Safari on IOS devices and also with EDGE.

Chrome and Firefox work as I would expect and I can scroll through a multi-page PDF.

Hi!

Is there a good solution for viewing PDF-files in Vaadin 15?

For Vaadin 8 I used https://vaadin.com/directory/component/wt-pdf-viewer.

Greetings
Thomas

This works (thank you), however for me, the PDF viewer is 150px high, unless I specifically set the height to something else in pixels.

Dennis Reichenberg:
Hi Jason,

I don’t think you need an additional javascript library to achieve this. This is a quick and dirty solution that I came up with (based on this [stackoverflow post]
(https://stackoverflow.com/questions/14081128/how-can-i-embed-a-pdf-viewer-in-a-web-page/14081168#14081168)):

@Tag("object")
public class EmbeddedPdfDocument extends Component implements HasSize {

  public EmbeddedPdfDocument(StreamResource resource) {
    this();
    getElement().setAttribute("data", resource);
  }

  public EmbeddedPdfDocument(String url) {
    this();
    getElement().setAttribute("data", url);
  }

  protected EmbeddedPdfDocument() {
    getElement().setAttribute("type", "application/pdf");
    setSizeFull();
  }
}

This component can be used in three ways:

  1. Hosting a remote pdf document via a full URL:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument("https://vaadin.com/download/book-of-vaadin/vaadin-7/pdf/book-of-vaadin.pdf"));
    setHeight("100%");
  }
}
  1. Hosting a static document from the applications src/main/webapp/frontend directory:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument("frontend/book-of-vaadin.pdf"));
    setHeight("100%");
  }
}
  1. Dynamically reading a PDF in the application and exposing it to the user through a StreamResource:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument(new StreamResource("book-of-vaadin.pdf", () -> {
      try {
        return getPdfInputStream();
      } catch (FileNotFoundException e) {
        return new ByteArrayInputStream(new byte[]{});
      }
    })));
    setHeight("100%");
  }

  private InputStream getPdfInputStream() throws FileNotFoundException {
    return new FileInputStream("/home/dennis/workspace/vaadin/src/main/webapp/frontend/book-of-vaadin.pdf");
  }
}

Dennis’s solution worked for us! Thank you, Dennis!

Thomas Niedergesaess:
Hi!

Is there a good solution for viewing PDF-files in Vaadin 15?

For Vaadin 8 I used https://vaadin.com/directory/component/wt-pdf-viewer.

Greetings
Thomas

Paul Corbett:

Dennis Reichenberg:
Hi Jason,

I don’t think you need an additional javascript library to achieve this. This is a quick and dirty solution that I came up with (based on this [stackoverflow post]
(https://stackoverflow.com/questions/14081128/how-can-i-embed-a-pdf-viewer-in-a-web-page/14081168#14081168)):

@Tag("object")
public class EmbeddedPdfDocument extends Component implements HasSize {

  public EmbeddedPdfDocument(StreamResource resource) {
    this();
    getElement().setAttribute("data", resource);
  }

  public EmbeddedPdfDocument(String url) {
    this();
    getElement().setAttribute("data", url);
  }

  protected EmbeddedPdfDocument() {
    getElement().setAttribute("type", "application/pdf");
    setSizeFull();
  }
}

This component can be used in three ways:

  1. Hosting a remote pdf document via a full URL:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument("https://vaadin.com/download/book-of-vaadin/vaadin-7/pdf/book-of-vaadin.pdf"));
    setHeight("100%");
  }
}
  1. Hosting a static document from the applications src/main/webapp/frontend directory:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument("frontend/book-of-vaadin.pdf"));
    setHeight("100%");
  }
}
  1. Dynamically reading a PDF in the application and exposing it to the user through a StreamResource:
@Route("test")
public class TestView extends Div {
  public TestView() {
    add(new EmbeddedPdfDocument(new StreamResource("book-of-vaadin.pdf", () -> {
      try {
        return getPdfInputStream();
      } catch (FileNotFoundException e) {
        return new ByteArrayInputStream(new byte[]{});
      }
    })));
    setHeight("100%");
  }

  private InputStream getPdfInputStream() throws FileNotFoundException {
    return new FileInputStream("/home/dennis/workspace/vaadin/src/main/webapp/frontend/book-of-vaadin.pdf");
  }
}

Dennis’s solution worked for us! Thank you, Dennis!

How can I set “page-fit” fit a full page into component?

I’m going to bump this again. Viewing PDF’s on iOS only shows the first page. Are there any libraries that work with flow ( 14+ ) aside from directly embedding the pdf?

Brad Harrison:
I’m going to bump this again. Viewing PDF’s on iOS only shows the first page. Are there any libraries that work with flow ( 14+ ) aside from directly embedding the pdf?

Did you try this add-on? https://vaadin.com/directory/component/pdf-browser/overview

Jean-Christophe Gueriaud:

Brad Harrison:
I’m going to bump this again. Viewing PDF’s on iOS only shows the first page. Are there any libraries that work with flow ( 14+ ) aside from directly embedding the pdf?

Did you try this add-on? https://vaadin.com/directory/component/pdf-browser/overview

Be aware…this is not working with Vaadin 14.5.3.

Jean-Christophe Gueriaud:

Brad Harrison:
I’m going to bump this again. Viewing PDF’s on iOS only shows the first page. Are there any libraries that work with flow ( 14+ ) aside from directly embedding the pdf?

Did you try this add-on? https://vaadin.com/directory/component/pdf-browser/overview

Yeah, I did try that one but I still have the same problem. iOS only renders the first page of a multipage document. The only library I’ve seen work so far is [Pdf.js]
(https://mozilla.github.io/pdf.js/).

In one of my Vaadin 8 projects I use the https://vaadin.com/directory/component/wt-pdf-viewer addon which uses the pdf.js library. Works great, but only Vaadin 8.