C# Blazor导出到Excel文件,格式或文件扩展名无效。

3

我有一个列表,正在尝试使用以下代码和ClosedXML nuget包将其导出到Excel,并遵循在线指南:

 private async TaskClickExportXLS()
        {
            
            await ExportToExcel(js, selectedFlyer.DealNo+"_SKY_CAT_Report.xlsx");
        }
        public async Task ExportToExcel(IJSRuntime js, string fileName)
        {
            blockProducts = blocks.SelectMany(b => b.Products).Distinct().ToList();
            var wb = new XLWorkbook();
            

            var ws = wb.Worksheets.Add("Sku Category Report");

            ws.Cell(1, 1).Value = "SKU";
            ws.Cell(1, 2).Value = "Product EN";
            ws.Cell(1, 3).Value = "Product FR";
            ws.Cell(1, 4).Value = "Category";
           
            foreach(var item in blockProducts)
            {
                ws.Cell(1, 1).Value = item.Sku;
                ws.Cell(1, 2).Value = item.ProductEn;
                ws.Cell(1, 3).Value = item.ProductFr;
                ws.Cell(1, 4).Value = item.MainCategory;
            }

            MemoryStream XLSStream = new();
            XLSStream.Position = 0;
            wb.SaveAs(XLSStream);
            
            var XLSSArray = XLSStream.ToArray();

            await js.InvokeVoidAsync("BlazorDownloadFile", fileName, XLSSArray);
        }

我也从指南中复制了这个js运行时文件:

function BlazorDownloadFile(filename, content) {


    // Create the URL
    const file = new File([content], filename, { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
    const exportUrl = URL.createObjectURL(file);

    // Create the <a> element and click on it
    const a = document.createElement("a");
    document.body.appendChild(a);
    a.href = exportUrl;
    a.download = filename;
    a.target = "_self";
    a.click();
    URL.revokeObjectURL(exportUrl);
}

我的文件下载成功,但是当我打开它时,出现“Excel无法打开文件,因为文件格式或扩展名无效”的提示。我已经上网做了研究,并尝试了以下方法 - 将流的位置设置为0。 在我的openfile.js中将文件类型更改为以下内容:type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 然而这似乎不能解决问题,当我调试代码时,代码似乎正常工作。任何帮助将不胜感激!

1
"async void" 是一个错误。它只适用于桌面应用程序中的事件处理程序。请改用 "async Task"。带有 "async void" 的方法无法等待,因此调用它们的代码将在不等待它们完成的情况下完成,并可能触发垃圾回收,从而处理异步方法使用的对象。 - Panagiotis Kanavos
跟随在线指南,是哪个指南? - Panagiotis Kanavos
@PanagiotisKanavos 这个链接 https://www.peug.net/en/blazor-create-or-export-your-data-to-excel/ - Adil15
指南有一个错误。不要使用 async void - Panagiotis Kanavos
@PanagiotisKanavos 我已经改成了async Task,但是仍然出现相同的错误。 - Adil15
显示剩余2条评论
1个回答

4

我曾尝试按照那个指南进行操作,但它对我无效。最终我采用将我的工作簿(wb)流式传输成字节数组,并将其作为参数传递给SaveAs函数的方法:

var bytes = new byte[0];
using (var ms = new MemoryStream())
{
     wb.SaveAs(ms);
     bytes = ms.ToArray();
}

await SaveAs(JSRuntime, fileName + ".xlsx", bytes);

这是SaveAs函数,它是异步任务,就像评论中所建议的一样:
async Task SaveAs(IJSRuntime js, string fileName, byte[] data)
{
    await js.InvokeAsync<object>(
        "BlazorDownloadFile",
        fileName,
        Convert.ToBase64String(data)
    );
}

以下是 JavaScript:

function BlazorDownloadFile(filename, bytesBase64) {
     var link = document.createElement('a');
     link.download = filename;
     link.href = "data:application/octet-stream;base64," + bytesBase64;
     document.body.appendChild(link); // Needed for Firefox
     link.click();
     document.body.removeChild(link);
}

我相信这些是我使用的参考资料:https://gist.github.com/danielplawgo/ac4d58837224dba7b6fc51de865b12da https://blazorfiddle.com/s/o8g3elz1


1
非常感谢您发布这个解决方案~ 它对我很有帮助! - Jiving Rockabilly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接