希望对 C# 有更了解的人可以指出我哪里出错了。
作为 Powershell 脚本编写者并且对 C# 相对较新,我在网页中添加了一个按钮,尝试将 GridView 导出到 .xlsx 文件,并使浏览器的行为就像正在下载文件一样。我已经将其用于 .xls 文件,但现在需要更新它以进行 .xlsx 导出。
GridView 是 SQL 表的 Web 视图。
我对其他人在线发布的将 GridView 导出到 .xlsx 的代码进行了很大程度的修改,但从未使其正常工作。
请找到以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Data;
using System.Web.UI.WebControls;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Wordprocessing;
using TableCell = System.Web.UI.WebControls.TableCell;
using System.Text;
using System.Runtime.InteropServices.ComTypes;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
ExportGridToExcel();
}
private void ExportGridToExcel()
{
DataTable dt = new DataTable("GridView_Data");
foreach (TableCell cell in GridView1.HeaderRow.Cells)
{
dt.Columns.Add(cell.Text);
}
foreach (GridViewRow row in GridView1.Rows)
{
dt.Rows.Add();
for (int i = 0; i < row.Cells.Count; i++)
{
dt.Rows[dt.Rows.Count - 1][i] = row.Cells[i].Text;
}
}
string FileName = "DataExport" + DateTime.Now + ".xlsx";
string FilePath = Path.GetTempPath();
string FileNameAndPath = "FilePath\\FileName";
using (MemoryStream MyMemoryStream = new MemoryStream())
//using (var workbook = SpreadsheetDocument.Create(MyMemoryStream, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
using (var workbook = SpreadsheetDocument.Create(MyMemoryStream, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new Workbook
{
Sheets = new Sheets()
};
var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
sheetPart.Worksheet = new Worksheet(sheetData);
Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<Sheet>().Count() > 0)
{
sheetId =
sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = "SoTExport" };
sheets.Append(sheet);
Row headerRow = new Row();
List<String> columns = new List<string>();
foreach (DataColumn column in dt.Columns)
{
columns.Add(column.ColumnName);
Cell cell = new Cell
{
DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String,
CellValue = new CellValue(column.ColumnName)
};
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow dsrow in dt.Rows)
{
Row newRow = new Row();
foreach (String col in columns)
{
Cell cell = new Cell
{
DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String,
CellValue = new CellValue(dsrow[col].ToString()) //
};
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=" + FileName);
workbookPart.Workbook.Save(MyMemoryStream);
MyMemoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void GridView1_SelectedIndexChanged1(object sender, EventArgs e)
{
}
}
单击“导出到 Excel”按钮时,会抛出错误:
无法在只写或只读模式下执行读/写操作。
调试一下,执行下面这行就抛出错误:
MyMemoryStream.WriteTo(Response.OutputStream);
我尝试将上面的行替换为:
Response.BinaryWrite(MyMemoryStream.ToArray());
但这给了我一个 1KB 的 Excel 文件,其中没有数据,并且也没有给我 Edge 中的“另存为”对话框。
我似乎无法理解数据应该如何工作。我可以看到电子表格对象是如何通过迭代 GridView/数据表来填充的,但实际上无法看到内存流如何发挥作用或为什么。
任何可以提供的帮助或指导将不胜感激,因为我现在束手无策。
真的非常感谢!
我尝试了网上看到的各种其他建议,但由于它们不起作用,我最终删除了这些行。 我期望或希望发生的是,数据表导出到.xlsx文件,数据与.aspx网页上的数据表(这是一个SQL表)相同,并且浏览器给出另存为对话框,以便用户可以将其保存在需要的地方,而不是自动下载。
如果我正确理解了您的问题,则您的网格已加载到 .aspx 页面上,并且您正尝试通过单击按钮从 GridView1 下载数据,该按钮调用 ExportGridToExcel() 方法。 您可以尝试下面的代码吗?您必须设置路径并让我知道这是否可以解决您的问题:
private void ExportGridToExcel()
{
Response.Clear();
Response.Buffer = true;
Response.ClearContent();
Response.ClearHeaders();
Response.Charset = "";
string FileName ="SoTDataExport"+DateTime.Now+".xlsx";
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmltextwrtter = new HtmlTextWriter(stringWriter);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType ="application/vnd.ms-excel";
Response.AddHeader("Content-Disposition","attachment;filename=" + FileName);
GridView1.GridLines = GridLines.Both;
GridView1.HeaderStyle.Font.Bold = true;
GridView1.RenderControl(htmltextwrtter);
Response.Write(stringWriter.ToString());
Response.End();
}