C#传递Excel字节转UTF8字符串至前端,转Blob打开Excel报错求助
解决Excel二进制数据转字符串再还原后无法打开的问题
核心错误根源
Excel文件是二进制数据,不能通过UTF8编码在字节数组和字符串之间互相转换。UTF8是针对文本设计的编码,二进制数据中必然存在不符合UTF8规范的字节序列,转字符串时这些字节会被强制替换为无效字符(�),导致原始文件结构彻底损坏,最终生成的Excel文件无法被识别。
后端正确实现(C# + ClosedXml)
不要用UTF8转字符串,要么直接返回文件流,要么用Base64编码(专门用于二进制转安全文本的标准格式)。
方案1:直接返回文件流(推荐,无需前端额外处理)
using ClosedXML.Excel; using Microsoft.AspNetCore.Mvc; using System.IO; public IActionResult GenerateCorgiExcel() { // 创建Excel工作簿并填充数据 using var workbook = new XLWorkbook(); var worksheet = workbook.Worksheets.Add("Corgi亲子数据"); // 写入表头和示例数据 worksheet.Cell(1, 1).Value = "ID"; worksheet.Cell(1, 2).Value = "狗名"; worksheet.Cell(1, 3).Value = "亲代ID"; worksheet.Cell(2, 1).Value = 1; worksheet.Cell(2, 2).Value = "奶糖"; worksheet.Cell(2, 3).Value = null; worksheet.Cell(3, 1).Value = 2; worksheet.Cell(3, 2).Value = "年糕"; worksheet.Cell(3, 3).Value = 1; // 保存到MemoryStream using var stream = new MemoryStream(); workbook.SaveAs(stream); stream.Position = 0; // 直接返回Excel文件 return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Corgi亲子数据.xlsx"); }
方案2:返回Base64字符串(需前端配合解码)
如果业务必须返回字符串格式,改用Base64编码:
// 在上述代码基础上,替换返回逻辑 var excelBytes = stream.ToArray(); var base64String = Convert.ToBase64String(excelBytes); return Ok(base64String);
前端正确实现
对应方案1(直接接收文件流)
// 方式1:直接跳转下载 window.location.href = '/api/generateCorgiExcel'; // 方式2:通过Fetch处理后下载 fetch('/api/generateCorgiExcel') .then(res => res.blob()) .then(blob => { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'Corgi亲子数据.xlsx'; a.click(); URL.revokeObjectURL(url); });
对应方案2(解码Base64字符串)
fetch('/api/generateCorgiExcel') .then(res => res.text()) .then(base64Str => { // 解码Base64为字节数组 const binaryStr = atob(base64Str); const uint8Arr = new Uint8Array(binaryStr.length); for (let i = 0; i < binaryStr.length; i++) { uint8Arr[i] = binaryStr.charCodeAt(i); } // 生成Blob并下载 const blob = new Blob([uint8Arr], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'Corgi亲子数据.xlsx'; a.click(); URL.revokeObjectURL(url); });
内容的提问来源于stack exchange,提问作者NoStressDeveloper
相关产品推荐
相关产品推荐

