将数据表转换为Excel 2007(.xlsx)格式

10

我有一个DataTable,需要将其转换为Excel 2007格式并保存为Excel文件(.xlsx) 2007版本。

有人可以帮我完成这个任务吗?

5个回答

8
您可以使用 OLEDB 数据提供程序,将 Excel 视为另一个 ADO.NET 数据源,以便循环遍历 DataTable 行并将它们插入到 Excel 电子表格中。以下是一篇微软 KB 文章,其中详细介绍了许多细节。

http://support.microsoft.com/kb/316934/en-us

要记住的重点是,您可以在工作簿内创建工作表和工作表,并且可以通过在名称末尾添加“$”来引用现有工作表。如果省略工作表名称末尾的“$”,OLEDB提供程序将假定它是新工作表并尝试创建它。
引用工作表名称后面的美元符号表示该表存在。如果要创建新表,请不要使用美元符号,如本文的创建新工作簿和表部分所述。
您可以创建2003(.xls)或2007格式(xlsx)的电子表格,这是在连接字符串上定义的--您指定要写入的文件,然后只需指定扩展名。请确保使用正确的OLEDB提供程序版本。
如果要创建2003(.xls)版本,则使用此连接字符串:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Book1.xls;Extended Properties="Excel 8.0;HDR=YES

如果您想创建一个2007年的(.xlsx)版本,您需要使用以下连接字符串:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Book1.xlsx;Extended Properties="Excel 12.0;HDR=YES

为了创建XLSX文件,您可能需要从Microsoft下载ACE提供程序。您可以在这里找到它。

我通常使用XLS提供程序,所以我没有太多使用XLSX提供程序的经验。

希望这可以帮助您。如果您有其他问题,请告诉我。


我做了完全相同的事情。但是当我创建XLSX文件时,它会被创建,但是当我尝试打开它时,它显示文件已损坏。我该怎么办?我按照您提供的以上MS链接中的相同步骤进行操作。 - smilu
请注意,它将使用列中的前5到8个值来“猜测”其数据类型。然后,它将将任何不符合规定的值设置为NULL。例如,如果您有一个电话号码列,其中包含以下值:004412345677、00443777373、[...这里还有几个数字...]+44(22)3883774747、[....带加号和括号的更多电话号码...]等-所有这些非数字电话号码很可能会在您的结果文件中被放置为空。修复此设计缺陷的方法需要调整注册表。另一个选择可能是使用OpenXML SDK 2.5-从Microsoft免费下载。 - demp

3

我之前为公司编写了以下代码。它可以将任何类类型的可枚举对象的所有(get)属性导出到Excel,并打开Excel。您应该能够针对DataTable做出类似的操作。记得需要添加对Microsoft.Office.Interop.Excel的引用。

    public static void ExportToExcel<T>(IEnumerable<T> exportData)
    {
        Excel.ApplicationClass excel = new Excel.ApplicationClass();
        Excel.Workbook workbook = excel.Application.Workbooks.Add(true);
        PropertyInfo[] pInfos = typeof(T).GetProperties();
        if (pInfos != null && pInfos.Count() > 0)
        {
            int iCol = 0;
            int iRow = 0;
            foreach (PropertyInfo eachPInfo in pInfos.Where(W => W.CanRead == true))
            {
                // Add column headings...
                iCol++;
                excel.Cells[1, iCol] = eachPInfo.Name;
            }
            foreach (T item in exportData)
            {
                iRow++;
                // add each row's cell data...
                iCol = 0;
                foreach (PropertyInfo eachPInfo in pInfos.Where(W => W.CanRead == true))
                {
                    iCol++;
                    excel.Cells[iRow + 1, iCol] = eachPInfo.GetValue(item, null);
                }

            }
            // Global missing reference for objects we are not defining...
            object missing = System.Reflection.Missing.Value;
            // If wanting to Save the workbook...   
            string filePath = System.IO.Path.GetTempPath() + DateTime.Now.Ticks.ToString() + ".xlsm";
            workbook.SaveAs(filePath, Excel.XlFileFormat.xlOpenXMLWorkbookMacroEnabled, missing, missing, false, false, Excel.XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing);
            // If wanting to make Excel visible and activate the worksheet...
            excel.Visible = true;
            Excel.Worksheet worksheet = (Excel.Worksheet)excel.ActiveSheet;
            excel.Rows.EntireRow.AutoFit();
            excel.Columns.EntireColumn.AutoFit();
            ((Excel._Worksheet)worksheet).Activate();
        }
    }

2
我有一个DataTable需要转换为Excel 2007格式并保存为Excel文件(.xlsx) 2007。你能帮我实现吗?
你只需要将我的免费C#类添加到你的项目中,再加上一行代码即可。
详细信息(包括免费下载源代码和示例项目)在这里: Mikes Knowledge Base - Export to Excel 我的库使用免费的Microsoft OpenXML库(也提供在我的下载中)来编写文件,因此您不必使用重量级的VSTO库或在服务器上安装Excel。
此外,它创建一个真正的.xlsx文件,而不是其他一些方法将数据流写入逗号分隔文本文件,但将其命名为.xls文件。
顺便提一下,我在使用OLEDB写入Excel文件时遇到了很多困难,其中最大的问题是我使用的是Windows 7 64位系统,Office 2007(32位),而Microsoft ACE提供程序必须是64位版本...但如果你安装了32位版本的Office,就无法安装这个64位版本的提供程序。
所以,你必须先卸载Office,安装ACE驱动程序,然后重新安装Office。
但即使这样,我还是放弃了使用OLEDB...它不够稳定。

1

在我五年前写的一些旧代码中发现了这个应该可以工作的东西...

public static void DataTableToExcel(DataTable tbl)
{
    HttpContext context = HttpContext.Current;
    context.Response.Clear();
    foreach (DataColumn c in tbl.Columns)
    {
        context.Response.Write(c.ColumnName + ";");
    }
    context.Response.Write(Environment.NewLine);
    foreach (DataRow r in tbl.Rows)
    {
        for (int i = 0; i < tbl.Columns.Count; i++)
        {
            context.Response.Write(r[i].ToString().Replace(";", string.Empty) + ";");
        }
        context.Response.Write(Environment.NewLine);
    }
    context.Response.ContentType = "text/csv";
    context.Response.AppendHeader("Content-Disposition",
        "attachment; filename=export.csv");
    context.Response.End();
}

这将从ASP.NET输出一个CSV文件响应,Excel 2007可以打开。如果您想要,您可以更改扩展名以模仿Excel,只需替换以下行即可:
    context.Response.ContentType = "application/vnd.ms-excel";
    context.Response.AppendHeader("Content-Disposition",
        "attachment; filename=export.xlsx");

如果您不需要进行任何复杂操作,CSV 是最简单的方式。如果您确实需要将其作为本机格式的 Excel 2007 文件,则需要使用 Office 库来构建它或从 CSV 转换并保存/提供它。

这个链接也可能会有用:

如何在导出数据到 Excel 2007 时避免 Excel 提示窗口


嗨,我也在尝试做同样的事情...但是没有成功...你能回复我的帖子吗...谢谢。我的问题(http://stackoverflow.com/questions/13737495/format-error-while-exporting-to-excel-from-gridview-in-asp-net) - Sandeep

0

看到有人发布了“保存为CSV”选项。虽然那似乎不是OP正在寻找的答案,但这是我的版本,包括表头

    public static String ToCsv(DataTable dt, bool addHeaders)
    {
        var sb = new StringBuilder();
        //Add Header Header
        if (addHeaders)
        {
            for (var x = 0; x < dt.Columns.Count; x++)
            {
                if (x != 0) sb.Append(",");
                sb.Append(dt.Columns[x].ColumnName);
            }
            sb.AppendLine();
        }
        //Add Rows
        foreach (DataRow row in dt.Rows)
        {
            for (var x = 0; x < dt.Columns.Count; x++)
            {
                if (x != 0) sb.Append(",");
                sb.Append(row[dt.Columns[x]]);
            }
            sb.AppendLine();
        }
        return sb.ToString();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接