C# 字节数组到 Javascript Blob 以创建和自动下载 PDF 文件

Posted

技术标签:

【中文标题】C# 字节数组到 Javascript Blob 以创建和自动下载 PDF 文件【英文标题】:C# Bytes array to Javascript Blob to create and auto download PDF file 【发布时间】:2020-12-31 06:42:36 【问题描述】:

我在 C# 中有 web api,它返回 PDF 文件的字节数组。这是C#代码

    [HttpGet]
    [Route("Download")]
    public async Task<ActionResult<byte[]>> DownloadFiles(int fileDocumentId)
    

            var file = await _fileService.FetchFiles(fileDocumentId);
            return file.ArchiveData;
    

这就是我使用 javascript fetch 调用 web api 的方式。

function download(id) 
    fetch(`https://localhost:xxx/api/file/download?fileDocumentId=11`)
        .then(response => 
            debugger

            return response.json()
        )
        .then(result => 
            debugger
            console.log('Success:', result);       

            var file = new Blob([result],  type: 'application/pdf' );
            var fileURL = URL.createObjectURL(file);
            window.open(fileURL);         
        )

        .catch(function (error) 
            console.log('Request failed', error)
        );

上面确实创建并打开了一个 pdf 文件,但它已损坏。

console.log('Success:', result); 中,控制台的输出如下所示:

Success: JVBERi0xLjUNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1NWSkgL1N0cnVjdFRyZWVSb290IDI3OCAwIFIvTWFya0luZm88PC9NYXJrZWQgdHJ1ZT4+Pj4NCmVuZG9iag0KMiAwIG9iag0KPDwvVHlwZS9QYWdlcy9Db3VudCAzNS9LaWRzWyAzIDAgUiAxNyAwIFIgMjggMCBSIDMxIDAgUiAzOCAwIFIgNDAgMCBSIDQ0IDAgUiA0NSAwIFIgNDYgMCBSIDQ3IDAgUiA0OCAwIFIgNDkgMCBSIDUxIDAgUiA1MiAwIFIgNTMgMCBSIDU0IDAgUiA1NSAwIFIgNTYgMCBSIDU3IDAgUiA1OCAwIFIgNTkgMCBSIDYwIDAgUiA2MSAwIFIgNjIgMCBSIDYzIDAgUiA2NCAwIFIgNjUgMCBSIDY2IDAgUiA2NyAwIFIgNjggMCBSIDY5IDAgUiA3MCAwIFIgNzEgMCBSIDI2NiAwIFIgMjczIDAgUl0gPj4NCmVuZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVud

由于实际输出的太长,所以这里截断了。

在谷歌搜索更多之后,我还尝试了以下代码,该代码在创建 blob 之前将字节数组转换为 arrayBuffer。它确实创建并下载了 PDF,但是当我打开 PDF 时,该 PDF 也已损坏。

function downloadpdf(pdfUrl) 
    debugger
    fetch(pdfUrl).then(resp => resp.arrayBuffer()).then(resp => 
        const file = new Blob([resp],  type: 'application/pdf' );

        const fileURL = URL.createObjectURL(file);
        const link = document.createElement('a');
        link.href = fileURL;
        link.download = "FileName" + new Date() + ".pdf";
        link.click();
    );


downloadpdf('https://localhost:xxx/api/file/download?fileDocumentId=11')

对于FetchFiles 方法,基本上是读取PDF文件并将其转换为字节数组。

byte[] fileBytes = await File.ReadAllBytesAsync(file);

【问题讨论】:

我之前也遇到过同样的问题,记得我是通过关闭文件流解决的,还请分享FetchFiles函数内容 @ElasticCode,我添加了FetchFiles方法的一行代码 这能回答你的问题吗? Download file from an ASP.NET Web API method using AngularJS 【参考方案1】:

您的代码将字节数组返回到 JavaScript,您不需要这样做,只需将其返回为 FileContentResult,这会将二进制文件写入响应,浏览器会将其作为文件下载,即使您调用API 直接在浏览器中。

[HttpGet]
[Route("Download")]
public async Task<ActionResult> DownloadFiles(int fileDocumentId)

    string filePath = fileDocumentId=11;

    var file = await _fileService.FetchFiles(fileDocumentId);
    string fileName = "FileName" + DateTime.Now.ToString() + ".pdf";

    return File(file.ArchiveData, "application/force-download", fileName);

【讨论】:

以上是关于C# 字节数组到 Javascript Blob 以创建和自动下载 PDF 文件的主要内容,如果未能解决你的问题,请参考以下文章

将一个字节数组 (BLOB IBM DB2) 中的多个图像导出到磁盘

使用 C#(无 JavaScript)直接将 Blazor WebAssembly 文件分块到 Azure Blob 存储

如何将字节数组转换为blob

使用 Blob 在 SQLite 中存储字节数组

如何将字节数组插入 Informix blob

如何使用 C# 中的 Azure.Storage.Blobs 从 Azure 存储 Blob 以 ByteArray 格式获取文件