【问题标题】:Window.Open with PDF stream instead of PDF locationWindow.Open 使用 PDF 流而不是 PDF 位置
【发布时间】:2014-05-11 08:57:55
【问题描述】:

基于问题Open PDF in new browser full window,看来我可以使用JavaScript打开一个带有PDF文件的新窗口,其中包含以下代码:

window.open('MyPDF.pdf', '_blank');

我想在从服务器返回时这样做,方法是添加一个字节数组而不是文件名,用作window.open 中的 URL 位置

我目前正在返回 PDF 文件,例如 this:

Response.Clear();
Response.ContentType = "application/pdf";
Response.BinaryWrite(pdfByteArray);
Response.Flush();

有没有办法在javascript中打开一个带有PDF字节数组的新窗口。

类似这样的:

var script = "window.open('" + pdfByteArray + "', '_blank');";
ScriptManager.RegisterClientScriptBlock(Parent.Page, typeof(Page), "pdf", script, true);

【问题讨论】:

标签: javascript asp.net .net pdf window.open


【解决方案1】:

看起来window.open 会将数据 URI 作为位置参数。

所以你可以从问题中这样打开它:Opening PDF String in new window with javascript:

window.open("data:application/pdf;base64, " + base64EncodedPDF);

这是一个 runnable example in plunkersample pdf file,它已经被 base64 编码。

然后在服务器上,你可以像这样将字节数组转换为base64编码:

string fileName = @"C:\TEMP\TEST.pdf";
byte[] pdfByteArray = System.IO.File.ReadAllBytes(fileName);
string base64EncodedPDF = System.Convert.ToBase64String(pdfByteArray);

注意:这似乎很难在 IE 中实现,因为 URL 长度太小,无法发送整个 PDF。

【讨论】:

  • 在阅读了有关类似问题的各种其他 cmets 之后,似乎有些人声称限制在 2048 字节和 32KB 之间。不幸的是,这两个对我来说都太小了。看起来仍然没有可靠的方法来告诉用户他们的 PDF 下载何时完成生成缺少 ajax 轮询线程。
  • 我需要导入哪个库才能使用System.Convert.ToBase64String?我在System pkg 中找不到Convert
  • 我在后端使用 php,所以我在发送 pdf 内容之前制作了 base64_encode(data)(跳过了你在那里写的 System.Convert.ToBase64String;它不适合我)。谢谢!
  • @KyleMit 很棒很棒的解决方案
  • 我需要更进一步,自动触发浏览器的“打印”功能。但是当我从新窗口对象调用window.print() 时,它什么也不做。我什至尝试调用setTimeout 以确保它已加载,但它不起作用。有人有什么想法吗?
【解决方案2】:

注意:我已经在最新版本的 IE 以及 Mozilla 和 Chrome 等其他浏览器中验证了这一点,这对我有用。希望它也适用于其他人。

if (data == "" || data == undefined) {
    alert("Falied to open PDF.");
} else { //For IE using atob convert base64 encoded data to byte array
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        var byteCharacters = atob(data);
        var byteNumbers = new Array(byteCharacters.length);
        for (var i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        var byteArray = new Uint8Array(byteNumbers);
        var blob = new Blob([byteArray], {
            type: 'application/pdf'
        });
        window.navigator.msSaveOrOpenBlob(blob, fileName);
    } else { // Directly use base 64 encoded data for rest browsers (not IE)
        var base64EncodedPDF = data;
        var dataURI = "data:application/pdf;base64," + base64EncodedPDF;
        window.open(dataURI, '_blank');
    }

}

【讨论】:

  • 我终于得到了使用 .NET 组合的东西: Response.Write(System.Convert.ToBase64String(bytearray));和上面的 javascript 块。谢谢@KyleMit!
  • 在 Chrome 中,我在打开 PDF 时收到 Not allowed to navigate top frame to data URL
【解决方案3】:

添加到 @Dinesh 的答案以处理 Chrome 和 Edge 中的 Not allowed to navigate top frame to data URL 错误

if (data == "" || data == undefined) {
    // Log Error: PDF data not available
} else {
    var byteCharacters = atob(data);                        
    var byteNumbers = new Array(byteCharacters.length);
    for (var i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    var byteArray = new Uint8Array(byteNumbers);
    var file = new Blob([byteArray], { type: 'application/pdf;base64' });
                            
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        // For IE
        window.navigator.msSaveOrOpenBlob(file, 'mypdf.pdf');
    } else {
        // For non-IE
        var fileURL = URL.createObjectURL(file);
        window.open(fileURL);
    }
}

【讨论】:

    猜你喜欢
    • 2016-04-02
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2020-02-20
    • 2015-06-01
    • 1970-01-01
    相关资源
    最近更新 更多