【发布时间】:2012-05-16 23:33:48
【问题描述】:
我正在尝试使用 Microsoft Office EXCEL INTEROP 将 C# DataTable 动态导出到 EXCEL 文件(不创建物理文件),并通过 Response 对象通过 asp.net 网页下载它。我可以使用库生成内存流但是不知何故,文件没有通过内存流保存。参考代码如下。您需要参考 DocumentFormat.OpenXml.dll 和 WindowsBase.DLL(您可以从微软网站下载)。
任何想法如何解决这个问题? ? ?
Private void DownloadFile()
{
DataSet objTable = ReadTableFromViewstate();
if (objTable != null && objTable.Rows.Count > 0)
{
string strDownloadableFilename = "TestExcelFileName.xls";
MemoryStream fs1 = new MemoryStream();
if (CreateExcelFile.CreateExcelDocument(objTable, fs1))
{
Response.Clear();
byte[] data1 = new byte[fs1.Length];
fs1.Read(data1, 0, data1.Length);
fs1.Close();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", strDownloadableFilename));
Response.BinaryWrite(data1); ;
Response.End();
}
else
{
LblErrorMessage.Text = "Error Exporting File.";
}
}
}
..
public static bool CreateExcelDocument(DataSet ds, System.IO.Stream excelFileStream)
{
try
{
using (SpreadsheetDocument document = SpreadsheetDocument.Create(excelFileStream, SpreadsheetDocumentType.Workbook))
{
CreateParts(ds, document);
}
Trace.WriteLine("Successfully created: " + excelFileStream);
return true;
}
catch (Exception ex)
{
Trace.WriteLine("Failed, exception thrown: " + ex.Message);
return false;
}
}
..
private static void CreateParts(DataSet ds, SpreadsheetDocument document)
{
WorkbookPart workbookPart = document.AddWorkbookPart();
Workbook workbook = new Workbook();
workbookPart.Workbook = workbook;
// If we don't add a "WorkbookStylesPart", OLEDB will refuse to connect to this .xlsx file !
WorkbookStylesPart workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>("rIdStyles");
Stylesheet stylesheet = new Stylesheet();
workbookStylesPart.Stylesheet = stylesheet;
Sheets sheets = new Sheets();
// Loop through each of the DataTables in our DataSet, and create a new Excel Worksheet for each.
uint worksheetNumber = 1;
foreach (DataTable dt in ds.Tables)
{
// For each worksheet you want to create
string workSheetID = "rId" + worksheetNumber.ToString();
string worksheetName = dt.TableName;
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>(workSheetID);
WriteDataTableToExcelWorksheet(dt, worksheetPart);
Sheet sheet = new Sheet() { Name = worksheetName, SheetId = (UInt32Value)worksheetNumber, Id = workSheetID };
sheets.Append(sheet);
worksheetNumber++;
}
workbook.Append(sheets);
}
【问题讨论】:
-
为什么不以制表符分隔,然后将其发送给用户?它将在 Excel 中打开。
-
不是一个真正的答案,但我可以推荐 EPPLus 即时创建 Excel 文件。 stackoverflow.com/a/10547727/284240 那么你只需要
Response.BinaryWrite(pck.GetAsByteArray()); -
@James:感谢您的建议。但我不想那样做,否则我可能会生成 .csv 文件。我想使用 INTEROP,因为将来我想将图像/图形添加到 excel 表中(这也是即时的)。
-
@Tim:感谢您的链接,图书馆似乎很有希望。 :-) 但我正在尝试开发相同类型的库。我使用的代码几乎与编写库的代码相同。我需要 ExcelDocument.GetAsByteArray() 方法的实现。 (即它如何从 INTEROP 返回的 Stream 对象转换为 ByteArray)
标签: c# asp.net openxml office-interop openxml-sdk