繁体   English   中英

将字符串从 C# 发送到客户端并转换为 Uint8Array 类型的字节数组,然后转换为 blob 以打开 excel 文件。 参与的柯基犬

[英]sending string from C# to client and converting into Uint8Array type byte array and then into blob to open excel file. Corgi Involved

因此,在 C# 代码中,我将柯基犬发送给拥有柯基宝宝的客户。 在这里使用 ClosedXml。

 var wbCorgiBabiesTemplate = new XLWorkbook();
                var wsCoriBabiesAmendementTemplate = wbCorgiBabiesTemplate.Worksheets.Add(" Work Sheet Corgi baby Template");
                wsCoriBabiesAmendementTemplate.Cell("A1").Value = "Corgi Parent";
                wsCoriBabiesAmendementTemplate.Cell("B1").Value = "Corgi Child";

                wsCoriBabiesAmendementTemplate.Cell("A2").Value = "Petunia";
                wsCoriBabiesAmendementTemplate.Cell("B2").Value = "Khaleesi";

                using (var ms = new MemoryStream())
                {
                    wbCorgiBabiesTemplate.SaveAs(ms);
                   byte[]  Corgibabies = ms.ToArray();
                }
       corgi.Corgibabies = System.Text.Encoding.UTF8.GetString(Corgibabies);
            
         return corgi;

之后在客户端中,我想在 excel 表中打开 corgibabies,但这里的转换在某处是错误的,我认为 excel 表无法正确打开。

var fileName = 'CorgiBabies.xlsx';

     dataAccessService.get('corgi')
            .then(function(response) {
                let utf8Encode = new TextEncoder();
                var strBytes = utf8Encode.encode(response.corgiBabies);
            
                    var a = document.createElement("a");
                    document.body.appendChild(a);
                    a.style = "display: none";
                    
                    var file = new Blob([strBytes], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
                    var fileURL = window.URL.createObjectURL(file);
                    a.href = fileURL;
                    a.download = fileName;
                    a.click();
                
            })

下面是 excel 表给我的图像错误

在此处输入图像描述

假设你在.Net Core+(否则你可以找到 System.Buffers Nuget package for.Net 标准或框架),在服务器端尝试

using System.Buffers; 
using System.Buffers.Text;

并插入

var outputBuffer = new Span<byte>();
var status = Base64.EncodeToUtf8(Corgibabies, outputBuffer, out var consumed, out var written);
// sanity check
// if (status != OperationStatus.Done) throw new Exception();`

// do the above just before replacing
// System.Text.Encoding.UTF8.GetString(Corgibabies);

// with
System.Text.Encoding.UTF8.GetString(outputBuffer);

现在我很确定这将确保服务器响应客户端应该期望的内容,但我还没有准备好测试 Javascript 方面的事情(还)。 同时让我知道这是否有助于您取得进步。

PS1:原始代码中的错误是隐含假设Corgibabies是一个包含 UTF8 编码字符串字节的数组。 它实际上包含通常是磁盘上的 .xlsx 文件的原始字节。 需要将其转换为文本(Base64 编码)并确保文本为 UTF8。 显然在 Javascript 你需要做相反的事情 - UTF8 Base64 到二进制,保存到磁盘,在 Excel 中打开...

您可以使其与File一起使用,而不是将string作为内容返回。

        public ActionResult Get()
        {
            var wbCorgiBabiesTemplate = new XLWorkbook();
            var wsCoriBabiesAmendementTemplate = wbCorgiBabiesTemplate.Worksheets.Add(" Work Sheet Corgi baby Template");
            wsCoriBabiesAmendementTemplate.Cell("A1").Value = "Corgi Parent";
            wsCoriBabiesAmendementTemplate.Cell("B1").Value = "Corgi Child";

            wsCoriBabiesAmendementTemplate.Cell("A2").Value = "Petunia";
            wsCoriBabiesAmendementTemplate.Cell("B2").Value = "Khaleesi";
            wbCorgiBabiesTemplate.SaveAs("new.xlsx");
            var ms = new MemoryStream();
           wbCorgiBabiesTemplate.SaveAs(ms);

            ms.Position = 0;
            var fileName = "CorgiBabies.xlsx";
            return File(ms, "application/octet-stream", fileName);
        }

Api 致电:

<a href="https://localhost:7135/api/downloadExcel"></a>

或者

fetch('https://localhost:7135/api/downloadExcel')
  .then(resp => resp.blob())
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    // the filename you want
    a.download = 'CorgiBabies.xlsx';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
  })
  .catch(() => alert('oh no!'));

编号: git

ClosedXML有几个扩展可以帮助您实现所需的功能:

您可以为您的项目安装适当的扩展,以帮助您快速访问下载工作簿。 您还可以将文件保存在磁盘上,并将文件链接(路径)传递给 JavaScript,然后继续处理 JavaScript 中的文件。

如果您需要知道如何让用户从 ASP.NET 下载文件,那么您可以这样做:

简单的工作簿:

C#:ASP.NET MVC

[HttpGet]
public ActionResult Download(string fileName)
{
    // create workbook 
    var workbook = new XLWorkbook();
    var sheet = workbook.Worksheets.Add("Worksheet 1");
    sheet.Cell("A1").Value = "A1";
    sheet.Cell("B1").Value = "B1";
    sheet.Cell("A2").Value = "A2";
    sheet.Cell("B2").Value = "B2";
    
    // get workbook bytes 
    byte[] workbookBytes;
    
    using (var memoryStream = new MemoryStream())
    {
        workbook.SaveAs(memoryStream);
        workbookBytes = memoryStream.ToArray();
    }

    return File(workbookBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
}

C#: ASP.NET Web Z6450242531912981C3683CAE88A32A6Z6

public void Export(HttpResponse response, string fileName)
{
    // create workbook 
    var workbook = new XLWorkbook();
    var sheet = workbook.Worksheets.Add("Worksheet 1");
    sheet.Cell("A1").Value = "A1";
    sheet.Cell("B1").Value = "B1";
    sheet.Cell("A2").Value = "A2";
    sheet.Cell("B2").Value = "B2";

    HttpResponse httpResponse = response;
    httpResponse.Clear();
    httpResponse.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    httpResponse.AddHeader("content-disposition", $"attachment;filename=\"{fileName}.xlsx\"");

    using (var memoryStream = new MemoryStream())
    {
        workbook.SaveAs(memoryStream);
        memoryStream.WriteTo(httpResponse.OutputStream);
    }

    httpResponse.End();
}

以上示例将直接将文件下载到客户端设备中。 但是,如果要将工作簿字节传递给 JavaScript,则需要将其转换为 base64 字符串并将其传递给JavaScript ,如下所示:

var base64String = Convert.ToBase64String(workbookBytes);

然后从JavaScript将其解码为Uint8Array

/*
    JavaScript
*/
// get base64 string array and decoded it
var data = atob(serverSideResult);

var array = new Array(data.length);

for (var i = 0; i < data.length; i++) {
    array[i] = data.charCodeAt(i);
}

// final result
var dataUint8Array = new Uint8Array(array);

现在您可以像普通Uint8Array dataUint8Array

如果要将其传递回服务器端,可以将数组转换为 base64 字符串,然后将其传递给服务器端,如下所示:

/*
    JavaScript
*/
let binaryString = ''

for (var i = 0; i < dataUint8Array.byteLength; i++) {
    binaryString += String.fromCharCode(dataUint8Array[i]);
}
//pass base64Result to the server-side (C#)
var base64Result = window.btoa(binaryString);

然后从C#你只需要将它从 base64 字符串转换回数组,如下所示:

var bytes = Convert.FromBase64String(dataReceivedFromJavaScript);

其中bytes将是byte[]

暂无
暂无

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

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