Open scrmtrey91 opened 2 years ago
Can you share a reproducible example or more information about your scenario (vaadin version, component version, if this is browser specific, etc)? I did a quick test in the latest Vaadin version and latest component version and printing works okay. See pdf-viewer-test.zip.
Your example works (printing). Hmm interesing, maybe it works because of springboot. I am not using springboot.
I am using java 17, pnpm, vaadin-cdi, some other addons, webpack latest vaadin and latest addon version. The app is deployed on Payara 5.2022.3, the application is war not jar.
Sorry i can not share the real app with you.
I tried different browser (safari lates osx) and throws the same error.
New error:
Uncaught Not Found (webpack-internal:///../target/flow-frontend/print-js/dist/print.js:468:9)
I looked into developer tools , console in chrome...and it looks like the PDF cannot be fetch when the print button is clicked.
The reason why print.js does not work (no data pdf to print).
It seems vaadin build wrong path to dynamic content. It is missing the app context root before /VAADIN/...
Download button is using correct URL path to dynamic content :
It is using context root path befoe /VAADIN/ , thats why resource is resolved and download works.
Steps to reproduce error:
1) Go to : https://vaadin.com/hello-world-starters
2) Choose started : VAADIN 23 - CDI
3) add pdf addon + pdf files in resources + web pack flag
4) Run payara , deploy war
5) Print PDF NOT working, download working OK
Zip project sample not working properly: skeleton-starter-flow-cdi-23.zip
I have a similar issue with both the download and print function. I'm using Spring boot, Vaadin 23 and java 17. Rather than reading a pdf file from disc as in the pdf-viewer-test sample provided above (which works fine with my setup), I'm using JasperExportManager to export to a temporary pdf file as follows:
jasperPrint = JasperFillManager.fillReport(filePath, param, conUser); File reportFile = File.createTempFile("output", ".pdf"); JasperExportManager.exportReportToPdfFile(jasperPrint, reportFile.getAbsolutePath()); FileInputStream fs = getInputStream(reportFile); StreamResource resource = new StreamResource(displayName, () -> fs); pdfViewer = new PdfViewer(); pdfViewer.setSrc(resource);
The pdf displays OK in the viewer, but both print and download fail with "java.io.IOException: Stream Closed" error (even though I have not programmatically closed the stream). I think this means the stream has already been consumed in setting the Viewer and unavailable to print/download. Any help appreciated.
any news about that ?
Any fixes for print button not working ?
It takes wrong URL for file (without context root of app) thus file not found 404 and print button not working.
The problem is in file "print.js" in line 811:
params.printable = /^(blob|http|\/\/)/i.test(params.printable) ? params.printable : window.location.origin + (params.printable.charAt(0) !== '/' ? '/' + params.printable : params.printable); // Get the file through a http request (Preload)
It only gets origin of window which does not include app context root.
If the app is deployed on server behind reverse-proxy (the url of app is mapped by external domain, context path is hidden), then the print works.
Example: 1) https://localhost:8181/AppRoot -> print not working (it only gets https://localhost:8181/) 2) https://app-root-proxy/ -> print works (correct origin because of no port and context root: https://app-root-proxy/)
I now have the download and print buttons working with an inputstream source on the fly using the following code:
jasperPrint = JasperFillManager.fillReport(filePath, param, conUser);
byte[] byteArray = JasperExportManager.exportReportToPdf(jasperPrint);
resource = new StreamResource(displayName, () -> new ByteArrayInputStream(byteArray));
resource.setContentType("application/pdf");
pdfViewer.setSrc(resource);
I had originally created a temp file from JasperPrint, but here the StreamResource is derived from a PDF byte array by way of ByteArrayInputStream. I'm using pdfviewer version 2.7.2 in Vaadin 23.3.5.
I have exact same code as you (from 1 year ago), always from byte array input stream (it is also jasper report byte pdf data).
BUT still does not work. Download working, print not working (because print.js build wrong URL path to get the PDF source, see the comments above).
pdfviewer version 2.7.2 in Vaadin 24.0.4 (but even with vaadin 23 does not work).
So I'm running my code in development with no reverse proxy at http://localhost:8080/ - not tried it in production server yet. My issue (see previous post) was that when the InputStream is assigned to a variable before instantiating StreamResource, the PDF is displayed correctly in the viewer, but the download creates an empty PDF and the print does nothing because the stream is empty (had been consumed, but I don't get the print.js javascript error you described above). If the StreamResource is instantiated directly with "new ByteArrayInputStream(byteArray"), the PDF is populated correctly.
So this produces an empty (corrupt) PDF:
private InputStream is; //
is = new ByteArrayInputStream(byteArray);
resource = new StreamResource(displayName, () -> is);
But this works:
resource = new StreamResource(displayName, () -> new ByteArrayInputStream(byteArray));
However I think that may be different to your problem.
Try running the app with context root instead.
Example: /AppName
https/localhost:8181/AppName
Without context root (empty) it is working.
But we have multiple war deployed , so we cannot have empty context root of app.
You're right, I can reproduce the error by configuring the root context path. As you said above, it seems to be a problem with "window.location origin" in print,js which only gets the base URL. I think it should be window.location origin + window.location.pathname as per this:
https://www.samanthaming.com/tidbits/86-window-location-cheatsheet/
Yp. Probably fix. I guess it will never be fixed.
@scrmtrey91 Are you customer of ours with some subscription tier? If yes, which one?
We have Vaadin Pro Subscription.
I think it should be window.location origin + window.location.pathname
Probably don't want the entire pathname. It will include the route path, which you don't want. You will want only context path and servlet mapping (vaadin.urlMapping) if configured.
Hi, I'm facing the same problem. Finally I solve it by calling PdfViewer.setSrc() with a full url instead of the relative url generated by StreamResource. It works fine for me.
// Create your StreamResource StreamResource streamResource = new StreamResource(...);
StreamRegistration streamRegistration = VaadinSession.getCurrent().getResourceRegistry().registerResource(streamResource);
// Create a full string URI ... String uri = scheme + "://" + serverName + ":" + serverPort + contextPath + "/" + streamRegistration.getResourceUri();
// Create a PdfViewer instance and set the source with the full URI PdfViewer pdfViewer = new PdfViewer(); pdfViewer.setSrc(uri); ...
I solved it using same approach from @jm2rodriguez, but keeping it relative
String contextPath = VaadinRequest.getCurrent().getContextPath();
StreamRegistration streamRegistration = VaadinSession.getCurrent().getResourceRegistry().registerResource(streamResource));
String uri = contextPath + "/" + streamRegistration.getResourceUri();
viewer.setSrc(uri);
Print button is displayed correctly but it does not work, it does not print the PDF.
Error is in javascript of print.js:
I need this feature to work for clients. Now they download the PDF first then print it with windows or browser native viewer.
But i really want to use your addon because it is great and clean with only the necessary functions.