在ASP.NET中生成Excel文件

时间:2008-09-29 19:49:11

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

我即将向ASP.NET应用程序添加一个部分(VB.NET代码隐藏),允许用户将数据作为Excel文件返回给它们,我将根据数据库数据生成该文件。虽然有几种方法可以做到这一点,但每种方法都有其自身的缺点。 将如何返回数据?我正在寻找尽可能干净和简单的东西。

26 个答案:

答案 0 :(得分:130)

CSV

优点:

  • 简单

缺点:

  • 它可能无法在其他区域设置或不同的Excel配置(即列表分隔符)
  • 中使用
  • 无法应用格式,公式等

HTML

优点:

  • 还很简单
  • 支持简单的格式化和公式

缺点:

  • 您必须将文件命名为xls,Excel可能会警告您打开非本机Excel文件
  • 每个工作簿一个工作表

OpenXML(Office 2007 .XLSX)

优点:

  • 原生Excel格式
  • 支持所有Excel功能
  • 不要要求 Excel的安装副本
  • 可以生成数据透视表
  • 可以使用开源项目EPPlus
  • 生成

缺点:

  • Excel 2007之外的兼容性有限(现在应该不是问题)
  • 除非您使用第三方组件,否则很复杂

SpreadSheetML(开放格式XML)

优点:

  • 与原生Excel格式相比简单
  • 支持大多数Excel功能:格式化,样式,公式,每个工作簿多个工作表
  • 不需要安装Excel即可使用它
  • 不需要第三方库 - 只需写出你的xml
  • 可以通过Excel XP / 2003/2007打开文档

缺点:

  • 缺乏良好的文档
  • 旧版本的Excel(2000年以前版本)不支持
  • 只写,因为一旦打开它并从Excel进行更改,它就会转换为原生Excel。

XLS(由第三方组件生成)

优点:

  • 使用所有格式化,公式等生成本机Excel文件。

缺点:

  • 成本金
  • 添加依赖项

COM Interop

优点:

  • 使用本机Microsoft库
  • 阅读对原生文档的支持

缺点:

  • 很慢
  • 依赖关系/版本匹配问题
  • 阅读时使用Web的并发/数据完整性问题
  • 很慢
  • 针对Web使用扩展问题(与并发性不同):需要在服务器上创建大量Excel应用程序实例
  • 需要Windows
  • 我提到它很慢吗?

答案 1 :(得分:38)

您可以将数据输出为html表格单元格,在其上添加.xls.xlsx扩展名,Excel将打开它,就像它是本机文档一样。您甚至可以通过这种方式进行有限的格式化和公式计算,因此它比CSV更强大。此外,从ASP.Net等网络平台输出html表应该很容易;)

如果在Excel工作簿中需要多个工作表或命名工作表,则可以通过名为SpreadSheetML的XML模式执行类似的操作。这是 Office 2007附带的新格式,但是与Excel 2000一样完全不同的东西。解释它如何工作的最简单方法是使用示例:

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
        xmlns:o="urn:schemas-microsoft-com:office:office"
        xmlns:x="urn:schemas-microsoft-com:office:excel"
        xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
        xmlns:html="http://www.w3.org/TR/REC-html40">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
      <Author>Your_name_here</Author>
      <LastAuthor>Your_name_here</LastAuthor>
      <Created>20080625</Created>
      <Company>ABC Inc</Company>
      <Version>10.2625</Version>
</DocumentProperties>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
        <WindowHeight>6135</WindowHeight>
        <WindowWidth>8445</WindowWidth>
        <WindowTopX>240</WindowTopX>
        <WindowTopY>120</WindowTopY>
        <ProtectStructure>False</ProtectStructure>
        <ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>

<Styles>
      <Style ss:ID="Default" ss:Name="Normal">
            <Alignment ss:Vertical="Bottom" />
            <Borders />
            <Font />
            <Interior />
            <NumberFormat />
            <Protection />
      </Style>
</Styles>

<Worksheet ss:Name="Sample Sheet 1">
<Table ss:ExpandedColumnCount="2" x:FullColumns="1" x:FullRows="1" ID="Table1">
<Column ss:Width="150" />
<Column ss:Width="200" />
<Row>
      <Cell><Data ss:Type="Number">1</Data></Cell>
      <Cell><Data ss:Type="Number">2</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">3</Data></Cell>
      <Cell><Data ss:Type="Number">4</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">5</Data></Cell>
      <Cell><Data ss:Type="Number">6</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">7</Data></Cell>
      <Cell><Data ss:Type="Number">8</Data></Cell>
</Row>
</Table>
</Worksheet>

<Worksheet ss:Name="Sample Sheet 2">
<Table ss:ExpandedColumnCount="2" x:FullColumns="1" x:FullRows="1" ID="Table2">
<Column ss:Width="150" />
<Column ss:Width="200" />
<Row>
      <Cell><Data ss:Type="String">A</Data></Cell>
      <Cell><Data ss:Type="String">B</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">C</Data></Cell>
      <Cell><Data ss:Type="String">D</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">E</Data></Cell>
      <Cell><Data ss:Type="String">F</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">G</Data></Cell>
      <Cell><Data ss:Type="String">H</Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook> 

答案 2 :(得分:16)

如果来自 DataTable

public static void DataTabletoXLS(DataTable DT, string fileName)
{
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Charset = "utf-16";
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}.xls", fileName));
    HttpContext.Current.Response.ContentType = "application/ms-excel";

    string tab = "";
    foreach (DataColumn dc in DT.Columns)
    {
        HttpContext.Current.Response.Write(tab + dc.ColumnName.Replace("\n", "").Replace("\t", ""));
        tab = "\t";
    }
    HttpContext.Current.Response.Write("\n");

    int i;
    foreach (DataRow dr in DT.Rows)
    {
        tab = "";
        for (i = 0; i < DT.Columns.Count; i++)
        {
            HttpContext.Current.Response.Write(tab + dr[i].ToString().Replace("\n", "").Replace("\t", ""));
            tab = "\t";
        }
        HttpContext.Current.Response.Write("\n");
    }
    HttpContext.Current.Response.End();
}

来自 Gridview

public static void GridviewtoXLS(GridView gv, string fileName)
{
    int DirtyBit = 0;
    int PageSize = 0;
    if (gv.AllowPaging == true)
    {
        DirtyBit = 1;
        PageSize = gv.PageSize;
        gv.AllowPaging = false;
        gv.DataBind();
    }

    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Charset = "utf-8";
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    HttpContext.Current.Response.AddHeader(
        "content-disposition", string.Format("attachment; filename={0}.xls", fileName));
    HttpContext.Current.Response.ContentType = "application/ms-excel";

    using (StringWriter sw = new StringWriter())
    using (HtmlTextWriter htw = new HtmlTextWriter(sw))
    {
        //  Create a table to contain the grid
        Table table = new Table();

        //  include the gridline settings
        table.GridLines = gv.GridLines;

        //  add the header row to the table
        if (gv.HeaderRow != null)
        {
            Utilities.Export.PrepareControlForExport(gv.HeaderRow);
            table.Rows.Add(gv.HeaderRow);
        }

        //  add each of the data rows to the table
        foreach (GridViewRow row in gv.Rows)
        {
            Utilities.Export.PrepareControlForExport(row);
            table.Rows.Add(row);
        }

        //  add the footer row to the table
        if (gv.FooterRow != null)
        {
            Utilities.Export.PrepareControlForExport(gv.FooterRow);
            table.Rows.Add(gv.FooterRow);
        }

        //  render the table into the htmlwriter
        table.RenderControl(htw);

        //  render the htmlwriter into the response
        HttpContext.Current.Response.Write(sw.ToString().Replace("£", ""));
        HttpContext.Current.Response.End();
    }

    if (DirtyBit == 1)
    {
        gv.PageSize = PageSize;
        gv.AllowPaging = true;
        gv.DataBind();
    }
}

private static void PrepareControlForExport(Control control)
{
    for (int i = 0; i < control.Controls.Count; i++)
    {
        Control current = control.Controls[i];
        if (current is LinkButton)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
        }
        else if (current is ImageButton)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
        }
        else if (current is HyperLink)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
        }
        else if (current is DropDownList)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
        }
        else if (current is CheckBox)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
        }

        if (current.HasControls())
        {
            Utilities.Export.PrepareControlForExport(current);
        }
    }
}

答案 3 :(得分:7)

这是一个围绕SpreadML的免费包装器 - 它运行良好。

http://www.carlosag.net/Tools/ExcelXmlWriter/

答案 4 :(得分:5)

根据给出的答案以及与同事的协商,最佳解决方案似乎是生成XML文件或HTML表格并将其作为附件下推。我的同事推荐的一个改变是数据(即HTML表)可以直接写入Response对象,因此无需写出文件,由于权限问题,I / O可能会很麻烦争用,并确保发生计划的清除。

这是代码的片段......我还没有检查过这个,我还没有提供所有被调用的代码,但我认为它代表了这个想法。

    Dim uiTable As HtmlTable = GetUiTable(groupedSumData)

    Response.Clear()

    Response.ContentType = "application/vnd.ms-excel"
    Response.AddHeader("Content-Disposition", String.Format("inline; filename=OSSummery{0:ddmmssf}.xls", DateTime.Now))

    Dim writer As New System.IO.StringWriter()
    Dim htmlWriter As New HtmlTextWriter(writer)
    uiTable.RenderControl(htmlWriter)
    Response.Write(writer.ToString)

    Response.End()

答案 5 :(得分:4)

由于Excel理解HTML,您只需将数据作为HTML表格写入扩展名为.xls的临时文件,获取文件的FileInfo,然后使用

将其重新打开。
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + fi.Name);
Response.AddHeader("Content-Length", fi.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(fi.FullName);
Response.End();

如果你想避开临时文件,你可以写入内存中的流并写回字节而不是使用WriteFile

如果省略了content-length标题,你可以直接写回html,但这可能无法在所有浏览器中一直正常工作

答案 6 :(得分:3)

我个人更喜欢XML方法。我将从数据集中的数据库中返回数据,将其保存到XMl,然后创建一个xslt文件,其中包含将格式化正确文档的转换规则,并且简单的XML转换将完成作业。关于此的最佳部分,您可以格式化单元格,进行条件格式设置,设置页眉和页脚,甚至设置打印范围。

答案 7 :(得分:2)

我们始终将数据从数据网格导出为ex​​cel。将其转换为HTML然后写入excel文件

Response.ContentType = "application/vnd.ms-excel"
    Response.Charset = ""
    Response.AddHeader("content-disposition", "fileattachment;filename=YOURFILENAME.xls")
    Me.EnableViewState = False
    Dim sw As System.IO.StringWriter = New System.IO.StringWriter
    Dim hw As HtmlTextWriter = New HtmlTextWriter(sw)
    ClearControls(grid)
    grid.RenderControl(hw)
    Response.Write(sw.ToString())
    Response.End()

这种方法唯一的问题是我们的很多网格都有按钮或链接,所以你也需要它:

'needed to export grid to excel to remove link button control and represent as text
Private Sub ClearControls(ByVal control As Control)
    Dim i As Integer
    For i = control.Controls.Count - 1 To 0 Step -1
        ClearControls(control.Controls(i))
    Next i

    If TypeOf control Is System.Web.UI.WebControls.Image Then
        control.Parent.Controls.Remove(control)
    End If

    If (Not TypeOf control Is TableCell) Then
        If Not (control.GetType().GetProperty("SelectedItem") Is Nothing) Then
            Dim literal As New LiteralControl
            control.Parent.Controls.Add(literal)
            Try
                literal.Text = CStr(control.GetType().GetProperty("SelectedItem").GetValue(control, Nothing))
            Catch
            End Try
            control.Parent.Controls.Remove(control)
        Else
            If Not (control.GetType().GetProperty("Text") Is Nothing) Then
                Dim literal As New LiteralControl
                control.Parent.Controls.Add(literal)
                literal.Text = CStr(control.GetType().GetProperty("Text").GetValue(control, Nothing))
                control.Parent.Controls.Remove(control)
            End If
        End If
    End If
    Return
End Sub

我发现在某处,它运作良好。

答案 8 :(得分:2)

我已经完成了几次,每次最简单的方法就是返回一个CSV(逗号分隔值)文件。 Excel完美地导入它,并且它的速度相对较快。

答案 9 :(得分:2)

我推荐基于OpenXML的free opensource excel generation libruary

几个月前它帮助了我。

答案 10 :(得分:2)

这是一个从存储过程中提取的报告。结果将导出到Excel。 它使用ADO而不是ADO.NET,原因是这一行

oSheet.Cells(2, 1).copyfromrecordset(rst1)

它执行大部分工作,但在ado.net中不可用。

‘Calls stored proc in SQL Server 2000 and puts data in Excel and ‘formats it

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim cnn As ADODB.Connection
        cnn = New ADODB.Connection
        cnn.Open("Provider=SQLOLEDB;data source=xxxxxxx;" & _
          "database=xxxxxxxx;Trusted_Connection=yes;")

        Dim cmd As New ADODB.Command


        cmd.ActiveConnection = cnn


        cmd.CommandText = "[sp_TomTepley]"
        cmd.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
        cmd.CommandTimeout = 0
        cmd.Parameters.Refresh()


        Dim rst1 As ADODB.Recordset
        rst1 = New ADODB.Recordset
        rst1.Open(cmd)

        Dim oXL As New Excel.Application
        Dim oWB As Excel.Workbook
        Dim oSheet As Excel.Worksheet

        'oXL = CreateObject("excel.application")
        oXL.Visible = True
        oWB = oXL.Workbooks.Add
        oSheet = oWB.ActiveSheet

        Dim Column As Integer
        Column = 1

        Dim fld As ADODB.Field
        For Each fld In rst1.Fields

            oXL.Workbooks(1).Worksheets(1).Cells(1, Column).Value = fld.Name
            oXL.Workbooks(1).Worksheets(1).cells(1, Column).Interior.ColorIndex = 15
            Column = Column + 1

        Next fld

        oXL.Workbooks(1).Worksheets(1).name = "Tom Tepley Report"
        oSheet.Cells(2, 1).copyfromrecordset(rst1)
        oXL.Workbooks(1).Worksheets(1).Cells.EntireColumn.AutoFit()


        oXL.Visible = True
        oXL.UserControl = True

        rst1 = Nothing

        cnn.Close()
        Beep()

    End Sub

答案 11 :(得分:1)

您可以使用此库轻松创建格式精美的Excel文件:http://officehelper.codeplex.com/documentation

不需要在网络服务器上安装Microsoft Office!

答案 12 :(得分:1)

通过Microsoft.Office.Interop命名空间避免COM Interop。它是如此缓慢,不可靠和不可扩展。不适用于受虐狂者。

答案 13 :(得分:1)

如果用数据填充GridView,可以使用此函数获取HTML格式的数据,但指示浏览器是excel文件。

 Public Sub ExportToExcel(ByVal fileName As String, ByVal gv As GridView)

        HttpContext.Current.Response.Clear()
        HttpContext.Current.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fileName))
        HttpContext.Current.Response.ContentType = "application/ms-excel"

        Dim sw As StringWriter = New StringWriter
        Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
        Dim table As Table = New Table

        table.GridLines = gv.GridLines

        If (Not (gv.HeaderRow) Is Nothing) Then
            PrepareControlForExport(gv.HeaderRow)
            table.Rows.Add(gv.HeaderRow)
        End If

        For Each row As GridViewRow In gv.Rows
            PrepareControlForExport(row)
            table.Rows.Add(row)
        Next

        If (Not (gv.FooterRow) Is Nothing) Then
            PrepareControlForExport(gv.FooterRow)
            table.Rows.Add(gv.FooterRow)
        End If

        table.RenderControl(htw)

        HttpContext.Current.Response.Write(sw.ToString)
        HttpContext.Current.Response.End()

    End Sub


    Private Sub PrepareControlForExport(ByVal control As Control)

        Dim i As Integer = 0

        Do While (i < control.Controls.Count)

            Dim current As Control = control.Controls(i)

            If (TypeOf current Is LinkButton) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, LinkButton).Text))

            ElseIf (TypeOf current Is ImageButton) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, ImageButton).AlternateText))

            ElseIf (TypeOf current Is HyperLink) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, HyperLink).Text))

            ElseIf (TypeOf current Is DropDownList) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, DropDownList).SelectedItem.Text))

            ElseIf (TypeOf current Is CheckBox) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, CheckBox).Checked))

            End If

            If current.HasControls Then
                PrepareControlForExport(current)
            End If

            i = i + 1

        Loop

    End Sub

答案 14 :(得分:0)

我使用上面提到的与this answer类似的解决方案之一遇到的一个问题是,如果您将内容作为附件推出(我发现这是最干净的解决方案)对于非ms浏览器),然后在Excel 2000-2003中打开它,它的类型是“Excel网页”而不是本机Excel文档。

然后,您必须向用户解释如何使用Excel中的“另存为类型”将其转换为Excel文档。如果用户需要编辑此文档,然后将其重新上传到您的网站,则会很麻烦。

我的建议是使用CSV。这很简单,如果用户在Excel中打开它,Excel至少会提示他们以原生格式保存它。

答案 15 :(得分:0)

这是一个将数据流作为CSV流出的解决方案。快速,干净,简单,它在输入中处理逗号。

public static void ExportToExcel(DataTable data, HttpResponse response, string fileName)
{
    response.Charset = "utf-8";
    response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    response.Cache.SetCacheability(HttpCacheability.NoCache);
    response.ContentType = "text/csv";
    response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);

    for (int i = 0; i < data.Columns.Count; i++)
    {
       response.Write(data.Columns[i].ColumnName);
       response.Write(i == data.Columns.Count - 1 ? "\n" : ",");
    }        
    foreach (DataRow row in data.Rows)
    {
        for (int i = 0; i < data.Columns.Count; i++)
        {
            response.Write(String.Format("\"{0}\"", row[i].ToString()));
            response.Write(i == data.Columns.Count - 1 ? "\n" : ",");
        }
    }

    response.End();
}

答案 16 :(得分:0)

CSV是最简单的方法。大部分时间它都链接到Excel。否则,您必须使用自动化API或XML格式。 API和XML并不难以使用。

Information about generating XML for Excel

答案 17 :(得分:0)

您当然可以选择第三方组件。就个人而言,我对Spire.XLS有http://www.e-iceblue.com/xls/xlsintro.htm

的良好体验

该组件在您的应用程序中非常易于使用:

        Workbook workbook = new Workbook();

        //Load workbook from disk.
        workbook.LoadFromFile(@"Data\EditSheetSample.xls");
        //Initailize worksheet
        Worksheet sheet = workbook.Worksheets[0];

        //Writes string
        sheet.Range["B1"].Text = "Hello,World!";
        //Writes number
        sheet.Range["B2"].NumberValue = 1234.5678;
        //Writes date
        sheet.Range["B3"].DateTimeValue = System.DateTime.Now;
        //Writes formula
        sheet.Range["B4"].Formula = "=1111*11111";

        workbook.SaveToFile("Sample.xls");

答案 18 :(得分:0)

假设这是一个内部网,您可以在其中设置权限并强制执行IE,您可以使用JScript/VBScript driving Excel生成工作簿客户端。这为您提供了原生的Excel格式,没有尝试在服务器上自动化Excel的麻烦。

我不确定我是否真的会推荐这种方法,除非在相当小的情况下,但在经典的ASP鼎盛时期它是相当普遍的。

答案 19 :(得分:0)

我见过的excel报告的最佳方法是使用XML扩展以XML格式写出数据并将其流式传输到具有正确内容类型的客户端。 (应用/ XLS)

这适用于任何需要基本格式化的报告,并允许您使用文本比较工具与现有电子表格进行比较。

答案 20 :(得分:0)

避免“看起来这些数字存储为文本”绿色三角形的唯一防弹方法是使用Open XML格式。值得使用它,只是为了避免不可避免的绿色三角形。

答案 21 :(得分:0)

man,在.net中我想你可以有一个组件可以做到这一点,但在经典的asp我已经完成了创建一个html表并将页面的mime tipe更改为vnd / msexcel。我想如果你使用gridview并更改mime类型,它可能会起作用,因为gridview是一个html表。

答案 22 :(得分:0)

我要么采用CSV路由(如上所述),要么更常见,我使用Infragistics NetAdvantage生成文件。 (在Infragistics正在运行的绝大多数时间里,我们只是导出一个现有的UltraWebGrid,它本质上是一个LOC解决方案,除非需要额外的格式调整。我们也可以手动生成Excel / BIFF文件,但很少需要。)

答案 23 :(得分:0)

我只是根据数据创建一个CSV文件,因为我认为它是最干净的,Excel对它有很好的支持。但是如果你需要更灵活的格式,我相信有一些第三方工具可以生成真正的excel文件。

答案 24 :(得分:-1)

刚刚创建了一个从Web表单C#导出到excel希望它能帮助其他人的功能

    public void ExportFileFromSPData(string filename, DataTable dt)
    {
        HttpResponse response = HttpContext.Current.Response;

        //clean up the response.object
        response.Clear();
        response.Buffer = true;
        response.Charset = "";

        // set the response mime type for html so you can see what are you printing 
        //response.ContentType = "text/html";
        //response.AddHeader("Content-Disposition", "attachment;filename=test.html");

        // set the response mime type for excel
        response.ContentType = "application/vnd.ms-excel";
        response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
        response.ContentEncoding = System.Text.Encoding.UTF8;
        response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble());

        //style to format numbers to string
        string style = @"<style> .text { mso-number-format:\@; } </style>";
        response.Write(style);

        // create a string writer
        using (StringWriter sw = new StringWriter())
        {
            using (HtmlTextWriter htw = new HtmlTextWriter(sw))
            {
                // instantiate a datagrid
                GridView dg = new GridView();
                dg.DataSource = dt;
                dg.DataBind();

                foreach (GridViewRow datarow in dg.Rows)
                {
                    //format specific cell to be text 
                    //to avoid 1.232323+E29 to get 1232312312312312124124
                    datarow.Cells[0].Attributes.Add("class", "text");
                }

                dg.RenderControl(htw);
                response.Write(sw.ToString());
                response.End();
            }
        }
     }

答案 25 :(得分:-5)

如果必须使用Excel而不是CSV文件,则需要在服务器上的Excel实例上使用OLE自动化。最简单的方法是使用模板文件并以编程方式将其填入数据中。您将其保存到另一个文件。

提示:

  • 不要以交互方式进行。让用户启动该过程,然后发布包含该文件链接的页面。这可以在生成电子表格时缓解潜在的性能问题。
  • 使用我之前描述的模板。它可以更容易地修改它。
  • 确保Excel设置为不弹出对话框。在Web服务器上,这将挂起整个excel实例。
  • 将Excel实例保留在单独的服务器上,最好是在防火墙后面,因此不会将其暴露为潜在的安全漏洞。
  • 密切关注资源使用情况。在OLE自动化界面上生成spreadhseet(PIA只是对此进行填充)是一个相当重要的过程。如果您需要将其扩展为高数据量,您可能需要对您的架构有点聪明。

如果您不介意文件的格式有点基本,那么某些'使用mime-types来欺骗打开HTML表的方法'会有效。这些方法还可以将CPU繁重的工作转移到客户端上。如果您希望对电子表格的格式进行精细控制,则可能必须使用Excel本身来生成如上所述的文件。