【问题标题】:Download file with ClosedXML使用 ClosedXML 下载文件
【发布时间】:2014-04-13 07:38:21
【问题描述】:

全部

我如何下载文件以便用户看到它正在下载(就像使用流一样?)

我目前使用的是ClosedXML,但是如果我使用SaveAs方法,我必须给出一个硬编码的URL,如果我只是给出文件名它不会自动下载到下载文件夹。

下面的方法效果很好,但是我必须创建我自己的基于 HTML 的 excel 文件,并且文件变得太大了,当我使用 ClosedXML 时,文件只有 50% 或更少以下代码的大小: 但是,下载行为是我想要的。

有没有办法可以转换下面的代码,以便我可以将我的“工作簿”作为一个对象,它只是下载这个工作簿?

HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=Excel.xls");
HttpContext.Current.Response.Charset ="UTF-8";    
HttpContext.Current.Response.ContentEncoding=System.Text.Encoding.Default;
HttpContext.Current.Response.ContentType = "application/ms-excel";
ctl.Page.EnableViewState =false;   
System.IO.StringWriter  tw = new System.IO.StringWriter() ;
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter (tw);
ctl.RenderControl(hw);
HttpContext.Current.Response.Write(tw.ToString());
HttpContext.Current.Response.End();

谢谢

【问题讨论】:

    标签: c# asp.net closedxml


    【解决方案1】:

    如果您使用 MVC,只需使用 File() 方法,如下所示:

    using (XLWorkbook wb = new XLWorkbook())
     {
      //here you put your data in the WorkBook
      //then create a Memory Stream object
    using (MemoryStream stream = new MemoryStream())
      {
       //save the workbook as a MemoryStream
         wb.SaveAs(stream);
    
       //use the File method to return a File
       return File(stream.ToArray(), "filetype","fileName.extension");
       }
     }
    

    【讨论】:

    • 嗨,如何处理前端角度的请求,我在解析 时遇到 http 失败
    【解决方案2】:

    如果使用 Asp.Net MVC,基本相同,但稍微整洁一些(我是这么认为的:))。

    public ActionResult DownloadFile(XXXModel model)
    {
        using (var workbook = new XLWorkbook(XLEventTracking.Disabled))
        {
            // create worksheets etc..
    
            // return 
            using (var stream = new MemoryStream())
            {
                workbook.SaveAs(stream);
                stream.Flush();
    
                return new FileContentResult(stream.ToArray(),
                       "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                       {
                           FileDownloadName = "XXXName.xlsx"
                       };
            }
        }
    

    【讨论】:

    • 嗨,我正在使用 asp.net core api 和 angular。 Angular 在接收响应时出错,解析期间 http 失败
    【解决方案3】:
    //Method for Export Excel using Closed Xml
    public void ExportDataWithClosedXml_Method(DataTable table, string tabName, string fileType)
    {
        var workbook = new XLWorkbook();
        var ws = workbook.Worksheets.Add(table, tabName);
        int row = 2 + table.Rows.Count;
        int col = table.Columns.Count;
        var redRow = ws.Row(1);
        //redRow.Style.Fill.BackgroundColor = XLColor.Red;
        redRow.InsertRowsAbove(1);
        ws.Cell(1, 1).Value = "Name of Report Type";
        ws.Cell(1, 1).Style.Font.Bold = true;
        ws.Table(0).ShowAutoFilter = false;
        //ws.Row(2).Style.Fill.BackgroundColor = XLColor.Red;
        ws.Range(2, 1, 2, col).Style.Fill.BackgroundColor = XLColor.Green;
        ws.Range(2, 1, 2, col).Style.Font.Bold = true;
        ws.Range(3, 1, row, col).Style.Font.Italic = true;
    
        HttpContext.Current.Response.Clear();
        using (MemoryStream memoryStream = new MemoryStream())
        {
            workbook.SaveAs(memoryStream);
            memoryStream.WriteTo(HttpContext.Current.Response.OutputStream);
            memoryStream.Close();
        }
        if (fileType == "xlsx")
        {
            HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=\"Samplefile.xlsx\"");
        }
        else
        {
            HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=\"Samplefile.xls\"");
        }
        HttpContext.Current.Response.End();
    }
    

    【讨论】:

    • 复制所有从start和view中的代码-------------------------------- --@using (Html.BeginForm("ExportDataWithClosedXml", "Client", FormMethod.Post, new { enctype = "multipart/form-data" })) {
      }--------------- "ExportDataWithClosedXml" 是控制器名称。
    【解决方案4】:
    public ActionResult SendFile()
    {
        // Create the workbook
        XLWorkbook workbook = new XLWorkbook();
        workbook.Worksheets.Add("Sample").Cell(1, 1).SetValue("Hello World");
    
        // Send the file
        MemoryStream excelStream = new MemoryStream();
        workbook.SaveAs(excelStream);
        excelStream.Position = 0;
        return File(excelStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "MyFileName.xlsx");
    }
    

    【讨论】:

    • 您需要解释为什么这样做才能成为一个好的答案。
    • 使用这个解决方案我遇到了编码问题。
    • antoprd 有同样的答案。你的回答对你有什么帮助。
    【解决方案5】:

    下载可以更简单、更短一些,因此控制器中的完整操作可能如下所示 - 下载部分只是一行而不是七到十行

    public ActionResult XLSX()
    {
        System.IO.Stream spreadsheetStream = new System.IO.MemoryStream();
        XLWorkbook workbook = new XLWorkbook();
        IXLWorksheet worksheet = workbook.Worksheets.Add("example");
        worksheet.Cell(1, 1).SetValue("example");
        workbook.SaveAs(spreadsheetStream);
        spreadsheetStream.Position = 0;
    
        return new FileStreamResult(spreadsheetStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = "example.xlsx" };
    }
    

    【讨论】:

      【解决方案6】:

      旧线程,但我无法让公认的解决方案正常工作。更多的搜索提出了这个,这对我来说非常有用:

              // Create the workbook
              XLWorkbook workbook = new XLWorkbook();
              workbook.Worksheets.Add("Sample").Cell(1, 1).SetValue("Hello World");
      
              // Prepare the response
              HttpResponse httpResponse = Response;
              httpResponse.Clear();
              httpResponse.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
              httpResponse.AddHeader("content-disposition", "attachment;filename=\"HelloWorld.xlsx\"");
      
              // Flush the workbook to the Response.OutputStream
              using (MemoryStream memoryStream = new MemoryStream())
              {
                  workbook.SaveAs(memoryStream);
                  memoryStream.WriteTo(httpResponse.OutputStream);
                  memoryStream.Close();
              }
      
              httpResponse.End();
      

      【讨论】:

      【解决方案7】:

      SaveAs() 方法支持流,所以要获取 ClosedXml 工作簿作为我使用的流:

      public Stream GetStream(XLWorkbook excelWorkbook)
      {
          Stream fs = new MemoryStream();
          excelWorkbook.SaveAs(fs);
          fs.Position = 0;
          return fs;
      }
      

      然后下载文件:

      string myName = Server.UrlEncode(ReportName + "_" + DateTime.Now.ToShortDateString() + ".xlsx");
      MemoryStream stream = GetStream(ExcelWorkbook);
      
      Response.Clear();
      Response.Buffer = true;
      Response.AddHeader("content-disposition", "attachment; filename=" + myName);
      Response.ContentType = "application/vnd.ms-excel";
      Response.BinaryWrite(stream.ToArray());
      Response.End();
      

      【讨论】:

      • 嗨,我在 excelWorkbook.SaveAs(fs) 上收到“System.OutOfMemoryException”;
      • @Velkumar 这应该是一个新问题(或者可能已经在其他地方得到了回答)。对于 ClosedXML,您的文件可能太大。
      • 您好,是否需要返回内存流?如果你直接返回一个 XLWorkbook 对象呢?
      • 谢谢你。我不知道我做错了什么,但在邮递员上它得到了 200 OK,但它并没有停止。将流的位置设置为 0 为我修复了它。
      猜你喜欢
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 2016-04-26
      • 2016-04-17
      • 2015-06-21
      • 2021-09-03
      • 1970-01-01
      相关资源
      最近更新 更多