【问题标题】:Export data to Excel file with ASP.NET MVC 4 C# is rendering into view使用 ASP.NET MVC 4 C# 将数据导出到 Excel 文件正在呈现到视图中
【发布时间】:2013-05-02 19:30:39
【问题描述】:

我无法将数据导出到 Excel。以下似乎将gridview呈现到我的视图中,而不是提示用户使用我在我的机器上安装的Excel打开。

 Public ActionResult ExportToExcel()
{            
    var products = this.Repository.Products.ToList();

    var grid = new GridView();
    grid.DataSource = from p in products
                      select new
                      {
                          Id = p.Id,
                          Name = p.Name
                      };
    grid.DataBind();

    Response.ClearContent();
    Response.Buffer = true;
    Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");
    Response.ContentType = "application/ms-excel";

    Response.Charset = "";
    StringWriter sw = new StringWriter();
    HtmlTextWriter htw = new HtmlTextWriter(sw);

    grid.RenderControl(htw);

    Response.Output.Write(sw.ToString());
    Response.Flush();
    Response.End();

    return View("MyView"); 
}

我做错了什么?

【问题讨论】:

  • 当我尝试返回视图时,应用程序中的某些内容无法正常工作。我最终不得不使用 return RedirectToAction("Action", "MyController");

标签: asp.net-mvc export-to-excel


【解决方案1】:

我已经尝试过您的代码,它运行良好。 该文件正在创建没有任何问题,这是我使用的代码(这是你的代码,我只是更改了数据源进行测试):

    public ActionResult ExportToExcel()
    {
        var products = new System.Data.DataTable("teste");
        products.Columns.Add("col1", typeof(int));
        products.Columns.Add("col2", typeof(string));

        products.Rows.Add(1, "product 1");
        products.Rows.Add(2, "product 2");
        products.Rows.Add(3, "product 3");
        products.Rows.Add(4, "product 4");
        products.Rows.Add(5, "product 5");
        products.Rows.Add(6, "product 6");
        products.Rows.Add(7, "product 7");


        var grid = new GridView();
        grid.DataSource = products;
        grid.DataBind();

        Response.ClearContent();
        Response.Buffer = true;
        Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");
        Response.ContentType = "application/ms-excel";

        Response.Charset = "";
        StringWriter sw = new StringWriter();
        HtmlTextWriter htw = new HtmlTextWriter(sw);

        grid.RenderControl(htw);

        Response.Output.Write(sw.ToString());
        Response.Flush();
        Response.End();

        return View("MyView");
    }

【讨论】:

  • 嗯。你是对的。一定是我的应用程序中的其他原因导致了这种情况。谢谢。我花了比我应该花的时间更长的时间!
  • 为什么不使用FileResult 操作?
  • 一个很好的例子,虽然更简洁地使用返回内容方法并且只设置文件名的标题。示例:Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls"); return Content(sw.ToString(), "application/ms-excel"); 这样,您可以摆脱所有其他响应。上例中的语句。此外,您不必返回从未真正使用过的视图。
  • 对于内容编码问题(可能会烧死你),请参阅 - stackoverflow.com/a/1685900/1560273
  • 伙计们,感谢您的回复,如何在多个工作簿中导出任何想法。
【解决方案2】:

您可以在任何控制器中调用辅助类

//view 
 @Html.ActionLink("Export to Excel", "Excel")

//controller Action
public void Excel()
{
    var model = db.GetModel()

    Export export = new Export();
    export.ToExcel(Response, model);
}

//helper class
public class Export
{        public void ToExcel(HttpResponseBase Response, object clientsList)
    {
        var grid = new System.Web.UI.WebControls.GridView();
        grid.DataSource = clientsList;
        grid.DataBind();
        Response.ClearContent();
        Response.AddHeader("content-disposition", "attachment; filename=FileName.xls");
        Response.ContentType = "application/excel";
        StringWriter sw = new StringWriter();
        HtmlTextWriter htw = new HtmlTextWriter(sw);

        grid.RenderControl(htw);
        Response.Write(sw.ToString());
        Response.End();
    }
}

【讨论】:

    【解决方案3】:

    第一步:查看页面代码

    <input type="button" id="btnExport" value="Export" class="btn btn-primary" />
    <script>
      $(document).ready(function () {
    
     $('#btnExport').click(function () {          
    
      window.location = '/Inventory/ExportInventory';
    
            });
    });
    </script>
    

    第 2 步:控制器代码

      public ActionResult ExportInventory()
            {
                //Load Data
                var dataInventory = _inventoryService.InventoryListByPharmacyId(pId);
                string xml=String.Empty;
                XmlDocument xmlDoc = new XmlDocument();
    
                XmlSerializer xmlSerializer = new XmlSerializer(dataInventory.GetType());
    
                using (MemoryStream xmlStream = new MemoryStream())
                {
                    xmlSerializer.Serialize(xmlStream, dataInventory);
                    xmlStream.Position = 0;
                    xmlDoc.Load(xmlStream);
                    xml = xmlDoc.InnerXml;
                }
    
                var fName = string.Format("Inventory-{0}", DateTime.Now.ToString("s"));
    
                byte[] fileContents = Encoding.UTF8.GetBytes(xml);
    
                return File(fileContents, "application/vnd.ms-excel", fName);
            }
    

    【讨论】:

    • 结果不是正确的 excel 文件格式。我使用了确切的代码:(
    • 添加 .xls 扩展名
    【解决方案4】:
      using (MemoryStream mem = new MemoryStream())
      {
        SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(mem, SpreadsheetDocumentType.Workbook);
    
        // Add a WorkbookPart to the document.
        WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
        workbookpart.Workbook = new Workbook();
    
        // Add a WorksheetPart to the WorkbookPart.
        WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
        worksheetPart.Worksheet = new Worksheet(new SheetData());
    
        // Add Sheets to the Workbook.
        Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
    
        SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
    
        // Add a row to the cell table.
        Row row;
        row = new Row() { RowIndex = 1 };
        sheetData.Append(row);
    
        // In the new row, find the column location to insert a cell in A1.  
        Cell refCell = null;
        foreach (Cell cell in row.Elements<Cell>())
        {
          if (string.Compare(cell.CellReference.Value, "A1", true) > 0)
          {
            refCell = cell;
            break;
          }
        }
    
        // Add the cell to the cell table at A1.
        Cell newCell = new Cell() { CellReference = "A1" };
        row.InsertBefore(newCell, refCell);
    
        // Set the cell value to be a numeric value of 100.
        newCell.CellValue = new CellValue("100");
        newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
    
        // Append a new worksheet and associate it with the workbook.
        Sheet sheet = new Sheet()
        {
          Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
          SheetId = 1,
          Name = "mySheet"
        };
    
        sheets.Append(sheet);
    
        workbookpart.Workbook.Save();
        spreadsheetDocument.Close();
    
        return File(mem.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "text.xlsx");
      }
    

    【讨论】:

    • 你用的是什么库?
    • 我认为他们使用的是 DocumentFormat.OpenXml,它是 Microsoft 创建的 Open Office 扩展。 link
    【解决方案5】:

    我以前做过这个,我认为你需要删除ActionResult。使其无效并删除返回视图(MyView)。这是解决方案

    【讨论】:

      【解决方案6】:

      我在我的控制器类中使用了一个列表来将数据设置到网格视图中。该代码对我来说很好用:

      public ActionResult ExpExcl()
      {
        List<PersonModel> person= new List<PersonModel>
         { 
          new PersonModel() {FirstName= "Jenny", LastName="Mathew", Age= 23},
          new PersonModel() {FirstName= "Paul", LastName="Meehan", Age=25}
         };
         var grid= new GridView();
         grid.DataSource= person;
         grid.DataBind();
      
         Response.ClearContent();
         Response.AddHeader("content-disposition","attachement; filename=data.xls");
         Response.ContentType="application/excel";
         StringWriter sw= new StringWriter();
         HtmlTextWriter htw= new HtmlTextWriter(sw); 
         grid.RenderControl(htw);
         Response.Output.Write(sw.ToString());
         Response.Flush();
         Response.End();
         return View();
       }
      

      【讨论】:

        【解决方案7】:

        在 MVC 中导出 excel 的适度方式是使用 Microsoft CloseXml。我写了一个简单的函数来将我的查询结果导出为 excel 表:

        using ClosedXML.Excel;
        ...
        public ActionResult ToExcel(List<Dictionary<string, string>> data, Dictionary<string, string> columnMap, string fileName, string sheetName)
        {
            var dtDataBuffer = new System.Data.DataTable("buffer");
        
            foreach (string col in columnMap.Values)
            {
                dtDataBuffer.Columns.Add(col, typeof(string));
            }
        
        
        
            foreach (var row in data)
            {
                List<string> rowData = new List<string> { };
        
        
                foreach (string col in columnMap.Keys)
                {
                    rowData.Add(row[col]);
                }
        
                dtDataBuffer.Rows.Add(rowData.ToArray());
            }
        
        
        
        
            var memoryStream = new MemoryStream();
        
            using (var workbook = new XLWorkbook())
            {
                var worksheet = workbook.Worksheets.Add(dtDataBuffer, sheetName);
                worksheet.Rows().Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
                worksheet.Rows().Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
                worksheet.Columns().AdjustToContents();
                workbook.SaveAs(memoryStream);
            }
        
            return File(memoryStream.ToArray(), "application/vnd.ms-excel", fileName);
        }
        

        这是一个使用示例(实际上我使用自己的类来运行查询和生成数据。您可以在此处找到 OracleSQL Server):

        public ActionResult myReportExport(){
            var data=List<Dictionary<string, string>>(){
                {{"Column1_Index","Column1_Value"},{"Column2_Index","Column2_Value"},...}
                ...
            };
            
            
            return ToExcel(data, new Dictionary<string, string> {
                    { "Column1_Index", "Column1 Title" } ,
                    { "Column2_Index", "Column2 Title" } ,
                    ...
                },
                "myFileName.xlsx",
                "my sheet name"
            );
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多