简体   繁体   English

在 Safari 的新标签页中打开 PDF

[英]Open PDF in a new Tab in Safari

Help me I am in desperate need for help.帮助我,我非常需要帮助。 Now to the real issue.现在到真正的问题。

I have been trying to get my pdf to open up in new tab in Safari but till now I've only faced disappointment.我一直试图让我的 pdf 在 Safari 的新选项卡中打开,但直到现在我都感到失望。 I am using jsPDF for generating my PDFs and earlier I used it's我正在使用 jsPDF 生成我的 PDF,之前我用过它

doc.save(pdfName+".pdf")

method to do the same, as in the latest safari version "9.1.1(10601.6.17)" it broke.方法相同,因为在最新的 safari 版本“9.1.1(10601.6.17)”中它坏了。 I can still generate the pdf using jsPDF's inbuilt option:我仍然可以使用 jsPDF 的内置选项生成 pdf:

pdf.output('dataurl');

but, it tends to open the PDF in the same tab, and this behaviour is highly undesirable.但是,它倾向于在同一个选项卡中打开 PDF,这种行为是非常不可取的。 I tried various solutions available on the net to fix the issue but none works.我尝试了网上提供的各种解决方案来解决问题,但都没有用。 Some of the solutions that I tried are:我尝试过的一些解决方案是:

  1. Using window.open(), doesn't work.使用 window.open() 不起作用。
  2. Using location.href, doesn't work.使用 location.href 不起作用。
  3. Using doc.output('save', 'filename.pdf'), doc.output('datauri'), doc.output('dataurlnewwindow'), nothing works.使用 doc.output('save', 'filename.pdf'), doc.output('datauri'), doc.output('dataurlnewwindow'),没有任何效果。
  4. Also tried fake clicking by creating an anchor tag and setting it's target as '_blank' and then using eventDispatcher to stimulate a mouse click but it also didn't work.还尝试通过创建锚标记并将其目标设置为“_blank”然后使用 eventDispatcher 来刺激鼠标点击来进行假点击,但它也没有用。 Something like this:像这样:

     var a = window.document.createElement("a"); a.target = '_blank'; a.href = 'http://www.google.com'; var e = window.document.createEvent("MouseEvents"); e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); a.dispatchEvent(e);

Any suggestion on what I should do?关于我应该做什么的任何建议? I want my pdf to open up in a new tab and not in the same one as that of my application.我希望我的 pdf 在新选项卡中打开,而不是在与我的应用程序相同的选项卡中打开。

PS: Each of the solutions that I tried for Safari above work flawlessly in Chrome and Mozilla Firefox, I just can't figure out what's the deal with Safari. PS:我在上面为 Safari 尝试过的每个解决方案在 Chrome 和 Mozilla Firefox 中都可以完美运行,我只是不知道 Safari 有什么问题。 Any help would be appreciated.任何帮助,将不胜感激。

You could try the blob output. 你可以尝试blob输出。 Then generate a Data URI to this, and open it in a new window: 然后为此生成一个数据URI,并在新窗口中打开它:

var blob = pdf.output("blob");
window.open(URL.createObjectURL(blob));

If you can get your PDF as base64, this is how you can do with it (works on both Safari and Chrome)如果你能得到你的 PDF 作为 base64,这就是你可以做到的(适用于 Safari 和 Chrome)

let base64PDF = "JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKP....."// your base64 pdf data

let pdfWindow = window.open("", "_blank");

pdfWindow.document.write(
  "<title>Healthcare</title><iframe width='100%' style='margin: -8px;border: none;' height='100%' src='data:application/pdf;base64, " +
  encodeURI(base64PDF) +
  "'></iframe>"
);

Tried many solution mentioned in stackoverflow but nothing worked for me, Later checked the FileSave.js implementation and created a working solution for this issue.尝试了 stackoverflow 中提到的许多解决方案,但对我没有任何作用,后来检查了 FileSave.js 实现并为此问题创建了一个有效的解决方案。

  1. Note that I have successfully tested this solution in iOS Safari.请注意,我已在 iOS Safari 中成功测试了此解决方案。
  2. In function downloadPdfMobile the if part is for Web safari else part is for mobile safari.在函数downloadPdfMobile中,if 部分用于 Web safari else部分用于移动 safari。
  3. Normal Android chrome browser this will not work, you need to follow the traditional way.普通的 Android chrome 浏览器这是行不通的,你需要按照传统的方式。

First you need to get the base64 string from the jsPDF首先,您需要从 jsPDF 中获取 base64 字符串

const doc = new jsPDF.jsPDF({ unit: 'pt', putOnlyUsedFonts: true});
const pdfElement = document.getElementById('id');
var pdfName = 'Test.pdf';
  doc.html(pdfElement, {
    callback: (pdf) => {
      var base = pdf.output('datauristring').split(',')[1];
      downloadPdfMobile(pdfName, base);
    },
    margin: 20,
 });

This is how the downloadPdfMobile function looks like, First you need to convert the base64 t Blob.这就是 downloadPdfMobile 函数的样子,首先您需要转换 base64 t Blob。

downloadPdfMobile: function (FileName, content) {
                    var _global =
                        typeof window === "object" && window.window === window
                            ? window
                            : typeof self === "object" && self.self === self
                            ? self
                            : typeof global === "object" && global.global === global
                            ? global
                            : this;

                var isMacOSWebView =
                    _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent);

                var blob = this.base64toBlob(content);
            
                var popup = open("", "_blank");
                if (popup) {
                    popup.document.title = popup.document.body.innerText = "downloading...";
                }

                var force = blob.type === "application/octet-stream";
                var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;
                var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);

                if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== "undefined") {
                    var reader = new FileReader();
                    reader.onloadend = function () {
                        var url = reader.result;
                        url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, "data:attachment/file;");
                        if (popup) popup.location.href = url;
                        else location = url;
                        popup = null;
                    };
                    reader.readAsDataURL(blob);
                } else {
                    var URL = _global.URL || _global.webkitURL;
                    var url = URL.createObjectURL(blob);
                    if (popup) popup.location = url;
                    else location.href = url;
                    popup = null; 
                    setTimeout(function () {
                        URL.revokeObjectURL(url);
                    }, 4e4);
                }
            }


base64toBlob: function (base64str) {
                    var binary = atob(base64str.replace(/\s/g, ""));
                    var len = binary.length;
                    var buffer = new ArrayBuffer(len);
                    var view = new Uint8Array(buffer);
                    for (var i = 0; i < len; i++) {
                        view[i] = binary.charCodeAt(i);
                    }
                    return new Blob([view], {
                        type: "application/pdf",
                    });
                },

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM