使用奇怪的字符C#MVC从服务器下载excel文件

时间:2016-10-17 04:18:06

标签: c# asp.net-mvc excel asp.net-mvc-5 openxml-sdk

大家好,

我有一个问题,我在服务器(.NET OpenXML SDK 2.5)上生成excel文件并写入MemoryStream。然后将MemoryStream的数组字节写入Response头到客户端。

但是在客户端解析错误导致编码文件与bom,我想。

如果你帮助我,我将不胜感激。谢谢。 所以这是我的代码:

[HttpPost]
public ActionResult ExportExcel(string fileName, System.Data.DataTable dataTable, Dictionary<string, string> headers, string[] groupBy = null)
{
    try
    {
        if (groupBy == null)
        {
            string absolutePath = ExportExcelWithoutGroupBy(fileName, dataTable, headers);
            byte[] filebytes = System.IO.File.ReadAllBytes(absolutePath);

            using (MemoryStream stream = new MemoryStream(filebytes))
            {
                Response.Clear();
                Response.ContentEncoding = System.Text.Encoding.UTF8;
                Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                Response.Charset = "";
                Response.AddHeader("Content-Disposition", String.Format(@"attachment; filename={0}", absolutePath));
                Response.AddHeader("content-length", Convert.ToString(stream.Length));
                //stream.Position = 0;
                //stream.WriteTo(Response.OutputStream);
                Response.BinaryWrite(stream.ToArray());
                Response.Flush();
                Response.End();
                return null;
            }
        }
        else
        {
            //not implemented yet
            return Json(new { Status = "Unsupported" }, JsonRequestBehavior.DenyGet);
        }
      }
      catch (Exception ex)
      {
          throw ex;
      }
}

private static string ExportExcelWithoutGroupBy(string fileName, System.Data.DataTable dataTable, Dictionary<string, string> headers)
{
    SpreadsheetDocument spreadsheetDocument = null;
    try
    {
         string absolutePath = System.Web.HttpContext.Current.Server.MapPath(@"/ExcelReport/" + fileName + ".xlsx");

         if (System.IO.File.Exists(absolutePath))
         {
             System.IO.File.Delete(absolutePath);
         }

         uint sheetId = 1;

         //create SpreadsheetDocument follow on filePath.
         //default parameter AutoSave = true, Editable = true, and Type = xlsx.
         spreadsheetDocument = SpreadsheetDocument.
         Create(absolutePath, SpreadsheetDocumentType.Workbook);

         // add WorkbookPart (excel file) to SpreadsheetDocument.
         WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
         workbookpart.Workbook = new Workbook();

         // add WorksheetPart (sheet) to WorkbookPart (excel).
         var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
         worksheetPart.Worksheet = new Worksheet();

         // create Sheets in excel
         Sheets sheets;
         sheets = spreadsheetDocument.WorkbookPart.Workbook.
                                                   AppendChild<Sheets>(new Sheets());

         //define style (css) in excel
         WorkbookStylesPart stylesPart = spreadsheetDocument.WorkbookPart.AddNewPart<WorkbookStylesPart>();
         stylesPart.Stylesheet = GenerateStyleSheet();
         stylesPart.Stylesheet.Save();

         //create sheetData to insert data in a sheet
         var sheetData = new SheetData();

         // add new sheet in array sheets
         var sheet = new Sheet()
         {
             Id = spreadsheetDocument.WorkbookPart.
                    GetIdOfPart(worksheetPart),
             SheetId = sheetId,
             Name = fileName + "_" + DateTime.Today.ToString("dd-MM-yyyy")
         };
         sheets.Append(sheet); //push new sheet

         //add row header
         AddRowHeader(worksheetPart, sheetData, headers);

         //add rows data from DataTable
         AddRowsDataDetail(worksheetPart, sheetData, headers, dataTable);

         workbookpart.Workbook.Save();

         return absolutePath;
     }
     catch (Exception ex)
     {
         throw ex;
     }
     finally
     {
         spreadsheetDocument.Close();
     }
}

在客户端

$.ajax({
     url: "/SupportMainPage/Utils/ExportExcel",
     data: { "fileName": "ExcelFile", "jsonData": JSON.stringify(srcSource), "headers": headers },
     type: 'POST',
     contentType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
     async: false,
     success: function (result) {
         debugger      
     },
     error: function (xhr, textStatus, throwException) {
         //here what I receive 
         //textStatus: parseerror
         //xhr.responseText: "Invalid XML: PK�YQIm�w��,xl/workbook.xml �(���An�0E�b�>�N)M�$l���T���ن�n,z�^�.����������/_�v�;cL�Br%�a�d\8�pʶj`;tK�I��':��R��0�<��'=�WiE3��Y�^�r�OsDe҈���k!6�+�����?ł��Ç|���j!7����)T�b���5�Ҋ�y}�Y���;N�Y�4��>y��qR�LO��0>t�����PK↵�YQI��,((_rels/.rels �(�<?xml version="1.0" encoding="utf-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">...
         debugger
     }
});

更新

在服务器端:

Response.ContentType = "application/octet-stream";

在客户端:

$.ajax({
 url: "/SupportMainPage/Utils/ExportExcel",
 data: { "fileName": "ExcelFile", "jsonData": JSON.stringify(srcSource), "headers": headers },
 type: 'POST',
 async: false,
 success: function (result) {
     var file = new Blob([result], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' });
     var fileURL = URL.createObjectURL(file);
     window.open(fileURL);
 },
 error: function (xhr, textStatus, throwException) {
     //here what I receive 
     //textStatus: parseerror
     //xhr.responseText: "Invalid XML: PK�YQIm�w��,xl/workbook.xml �(���An�0E�b�>�N)M�$l���T���ن�n,z�^�.����������/_�v�;cL�Br%�a�d\8�pʶj`;tK�I��':��R��0�<��'=�WiE3��Y�^�r�OsDe҈���k!6�+�����?ł��Ç|���j!7����)T�b���5�Ҋ�y}�Y���;N�Y�4��>y��qR�LO��0>t�����PK↵�YQI��,((_rels/.rels �(�<?xml version="1.0" encoding="utf-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">...
     debugger
 }
});

上面的代码已下载文件,但excel文件已损坏且无法打开。

1 个答案:

答案 0 :(得分:0)

您的xhr.responseText是一个xlsx文件 - 这是一个内部具有特定文件布局的ZIP存档。它不是任何有效的XML文件。

您很可能应该在隐藏的iframe中触发文件下载,而不是尝试将其作为AJAX响应接收。