打开XML导出数据表直接在磁盘上执行

我想导出datatable到xlsx直接到我的磁盘,而不是给服务器上的目标path和保存文件。

我有以下function:

private void ExportToCSVFileOpenXML(DataTable dt, string destination) { DataSet ds = new DataSet(); DataTable dtCopy = new DataTable(); dtCopy = dt.Copy(); ds.Tables.Add(dtCopy); try { var workbook = SpreadsheetDocument.Create(Server.MapPath("~/" + destination.Replace("/","").Replace(":","")), DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook); { var workbookPart = workbook.AddWorkbookPart(); workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook(); workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets(); foreach (System.Data.DataTable table in ds.Tables) { var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>(); var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData(); sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData); DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>(); string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart); uint sheetId = 1; if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0) { sheetId = sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1; } DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName }; sheets.Append(sheet); DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); List<String> columns = new List<string>(); foreach (System.Data.DataColumn column in table.Columns) { columns.Add(column.ColumnName); DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName); headerRow.AppendChild(cell); } sheetData.AppendChild(headerRow); foreach (System.Data.DataRow dsrow in table.Rows) { DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); foreach (String col in columns) { DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); // newRow.AppendChild(cell); } sheetData.AppendChild(newRow); } } } } catch (Exception) { throw; } } 

我怎样才能直接导出到磁盘,而不是通过给目的地path保存在服务器上:

 var workbook = SpreadsheetDocument.Create(Server.MapPath("~/" + destination.Replace("/","").Replace(":","")), DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook); 

请帮帮我。

SpreadsheetDocument.Create接受stream,string或包作为其第一个参数,所以我们可以使用MemoryStream在内存中创build工作簿并返回一个字节数组。

它应该是这样的:

 public byte[] ExportToCSVFileOpenXML(DataTable dt) { byte[] returnBytes = null; using (MemoryStream mem = new MemoryStream()) { var workbook = SpreadsheetDocument.Create(mem, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook); // your code workbook.WorkbookPart.Workbook.Save(); workbook.Close(); returnBytes = mem.ToArray(); } return returnBytes; } 

一旦你有一个字节数组传递它作为一个文件应该很容易。

如果你使用的是MVC,那么你的控制器应该是这样的:

 return File(ExportToCSVFileOpenXML(aTable), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "export.xlsx"); 

亚历克斯的回答导致我正确的答案。

我做了以下事情:

 private byte[] ExportToCSVFileOpenXML(DataTable dt) { DataSet ds = new DataSet(); DataTable dtCopy = new DataTable(); dtCopy = dt.Copy(); ds.Tables.Add(dtCopy); try { byte[] returnBytes = null; MemoryStream mem = new MemoryStream(); var workbook = SpreadsheetDocument.Create(mem, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook); { var workbookPart = workbook.AddWorkbookPart(); workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook(); workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets(); foreach (System.Data.DataTable table in ds.Tables) { var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>(); var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData(); sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData); DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>(); string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart); uint sheetId = 1; if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0) { sheetId = sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1; } DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName }; sheets.Append(sheet); DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); List<String> columns = new List<string>(); foreach (System.Data.DataColumn column in table.Columns) { columns.Add(column.ColumnName); DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName); headerRow.AppendChild(cell); } sheetData.AppendChild(headerRow); foreach (System.Data.DataRow dsrow in table.Rows) { DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); foreach (String col in columns) { DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); // newRow.AppendChild(cell); } sheetData.AppendChild(newRow); } } } workbook.WorkbookPart.Workbook.Save(); workbook.Close(); returnBytes = mem.ToArray(); return returnBytes; } catch (Exception) { throw; } } 

调用这个函数为:

 protected void hlInCorrectRecords_Click(object sender, EventArgs e) { lblmsg.Text = ""; DataSet dsDtUploadedSummary = (DataSet)ViewState["dsDtUploadedSummary"]; if (dsDtUploadedSummary.Tables.Count > 0) { DataTable dtFreshRecords = dsDtUploadedSummary.Tables[4]; if (dtFreshRecords.Rows.Count > 0 && dtFreshRecords != null) { Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; string filename = @"IncorrectRecordsUploaded_" + DateTime.Now.ToString(); Response.AddHeader("Content-Disposition", "inline;filename=" + filename.Replace("/", "").Replace(":", "")+".xlsx"); Response.BinaryWrite(ExportToCSVFileOpenXML(dtFreshRecords)); Response.Flush(); Response.End(); } else { lblmsg.Text = "No Data To Export"; } } else { lblmsg.Text = "No Data To Export"; } } 

感谢Alex。 我使用普通的ASP.NET而不是MVC