3

How can I open with javascript link data:application/pdf;filename=generated.pdf;base64;DATA in Chrome 71?
Link from console opened successfully, but not from code - unfortunately.
The snippet does not work for security reason. Only for code demonstration.
I read some similar questions, but did not find an answer.

enter image description here

var button = document.getElementById("button");

button.addEventListener("click", generate, false);

function generate() {

  var doc = new jsPDF({
    orientation: "l",
    unit: "mm"
  });

  doc.text('ACT', 130, 20);
  var string = doc.output('datauristring');
  console.log(string);
  var link = document.createElement('a');
  link.href = string;
  link.setAttribute('target', '_blank');
document.body.appendChild(link);
  link.click();
  link.parentNode.removeChild(link);
}
<script src="https://unpkg.com/jspdf@1.5.3/dist/jspdf.min.js"></script>
<button id="button">Generate pdf table</button>
Weihui Guo
  • 3,669
  • 5
  • 34
  • 56
eustatos
  • 686
  • 1
  • 10
  • 21
  • [Not allowed to navigate top frame to data URL](https://stackoverflow.com/questions/45493234/jspdf-not-allowed-to-navigate-top-frame-to-data-url?noredirect=1&lq=1) – Weihui Guo Feb 13 '19 at 01:45

6 Answers6

10

Try window.open() instead. The following code worked for me. You will need to modify the window/page size.

let dataSrc = pdf.output("datauristring");
let win = window.open("", "myWindow");
win.document.write("<html><head><title>jsPDF</title></head><body><embed src=" + 
    dataSrc + "></embed></body></html>");

Update:

Didn't realize that jsPDF comes with a built-in method pdf.output('dataurlnewwindow');, which uses iframe,

The downside of pdf.output('dataurlnewwindow') is that it opens a new tab/window with datauristring as the pdf file name and the download button doesn't work, while window.open(pdf.output('bloburl')) seems fine with the download button.

Okay, pdf file can be renamed like this:

pdf.setProperties({
    title: "jsPDF sample"
});

Update 2:

To avoid the page being cut off when a page is zoomed, you can set the html2canvas scale accordingly.

Weihui Guo
  • 3,669
  • 5
  • 34
  • 56
  • 1
    PDF opened by `pdf.output('dataurlnewwindow')` also disappears on hitting enter on address bar as there's no url in the address bar.`window.open(pdf.output('bloburl'))` doesn't have this problem – Pavindu Jun 14 '19 at 05:37
  • 2
    I've noticed that when using pdf.output('dataurlnewwindow') on Chrome, the new page continues to load. Which make you unable to use the download function. But on another browser like Firefox, the same method dosen't have that problem. There it works as intended. – Carsten Dec 29 '19 at 12:54
6

It's actually very easy, don't complicate things..

window.open(URL.createObjectURL(doc.output("blob")))

or a more verbose and less efficient version:

let newWindow = window.open('/');
fetch(doc.output('datauristring')).then(res => res.blob()).then(blob => {
    newWindow.location = URL.createObjectURL(blob);
})

(You need to open the new window immediately after the onclick or Chrome will block the popup. This solution is not as good because there is an unnecessary conversion from datauri to blob)

Kevin
  • 2,775
  • 4
  • 16
  • 27
3

This code works for me

  var doc = new jsPDF();
  doc.setProperties({
  title: "new Report"
  });
  doc.output('dataurlnewwindow');
Ajinz
  • 477
  • 4
  • 8
0

I run code from the question in the local machine and take this error:

Not allowed to navigate top frame to data URL: data:application/pdf;filename=generated.pdf;base64,...

JsPDF - Not allowed to navigate top frame to data URL

I tried the suggestion @WeihuiGuo. Unfortunately for me.

I found than Chrome automaticaly open pdf.

https://support.google.com/chrome/answer/6213030?hl=en
https://groups.google.com/a/chromium.org/forum/#!topic/chromium-bugs/z5hA0H6LFws

And not only for the new tab. Not opened on the current page too.
https://sphilee.github.io/jsPDF-CustomFonts-support/

In other browsers this page display correctly.

Such sad news.

eustatos
  • 686
  • 1
  • 10
  • 21
  • I am having trouble to understand what exactly your goal is now. If you just want to open your jspdf created pdf in a new tab/window, it can be as simple as `doc.output('dataurlnewwindow');`. See my updated answer. The error you got, `Not allowed to navigate top frame to data URL: data:application/pdf;filename=generated.pdf;base64,...` is more like you are trying to open the pdf at the same tab/window, not a new one. – Weihui Guo Feb 09 '19 at 02:54
  • @ WeihuiGuo, thank you for your patience and help. I haven't figured out the reason yet, but your code works now `pdf.output('dataurlnewwindow')` – eustatos Feb 09 '19 at 07:48
  • No problem. But the answer is not perfect. I found that if the user zoom in the page to a certain extent, the output may be cut off. I am still trying to figure out a way to fix that. – Weihui Guo Feb 11 '19 at 02:23
-1

You're generating a PDF from its raw data using Javascript. Why not use a reader like Adobe to render it? That is what is happening when you are clicking the link from the console. You could literally just open the link and it will open as a PDF. I think you are possibly over complicating this task.

Christopher Vickers
  • 1,773
  • 1
  • 14
  • 18
  • Thanks for the reply. Open pdf in the browser its business requirements. You probably know how it is ( I can download pdf. But his does not suit the customer – eustatos Feb 08 '19 at 12:24
  • Most browsers will still open it in the browser using the installed reader. I'm pretty sure that you still have some sort of pdf reader installed and that is what is opening it when you click on the link in the console. It might be that chrome has a built in reader. Try copy/pasting the link into the address bar. You could always open the link in an iframe and it will open it in the browser. If you are using the javascript library, then im not sure if that is creating a html page from PDF. – Christopher Vickers Feb 08 '19 at 15:14
-1

Just try this..it will work

var doc = new jsPDF({orientation: 'landscape',unit: 'mm',format: 'a4',putOnlyUsedFonts:true})
var burl = doc.output('bloburl');
console.log(burl)
var win = window.open(burl)
win.print()
Michael M.
  • 10,486
  • 9
  • 18
  • 34
  • 2
    Welcome to SO! Please don't post code-only answers but add a little textual explanation about how and why your approach works and what makes it different from the other answers given. You can find out more at our ["How to write a good answer"](https://stackoverflow.com/help/how-to-answer) page. – ahuemmer Dec 23 '22 at 12:08