Создание файла Excel в ASP.NET

Я собираюсь добавить раздел в приложение ASP.NET(VB.NET codebehind), которое позволит пользователю получить данные, возвращенные им в виде файла Excel, которые я буду генерировать на основе данных базы данных. Хотя есть несколько способов сделать это, у каждого свои недостатки. Как бы вы вернули данные? Я ищу что-то, что было бы чистым и простым, насколько это возможно.

Ответ 1

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
  • Прочитать поддержку собственных документов

Минусы:

  • Очень медленно
  • Проблемы с зависимостью/версией соответствия
  • Concurrency/проблемы с целостностью данных для использования в Интернете при чтении
  • Очень медленно
  • Проблемы масштабирования для использования в Интернете (отличные от concurrency): необходимо создать на сервере множество экземпляров тяжелого приложения Excel.
  • Требуется Windows
  • Я упоминал, что он медленный?

Ответ 2

Вы можете вывести данные в виде ячеек таблицы html, вставить на него расширение .xls или .xlsx, а Excel откроет его, как если бы это был родной документ. Вы можете даже сделать некоторые ограниченные вычисления форматирования и формулы таким образом, так что это намного мощнее, чем CSV. Кроме того, вывод таблицы html довольно легко сделать с веб-платформы, такой как ASP.Net;)

Если вам нужно несколько рабочих листов или названных листов в книге Excel, вы можете сделать что-то подобное с помощью схемы XML под названием SpreadSheetML. Это не новый формат, поставляемый с 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> 

Ответ 3

Если из 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();
}

Из Гридвью:

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);
        }
    }
}

Ответ 5

На основе полученных ответов и консультаций с коллегами представляется, что наилучшим решением является создание либо XML файла, либо HTML-таблиц, и наложение его на вложение. Одно изменение, рекомендуемое моими сотрудниками, заключается в том, что данные (т.е. Таблицы HTML) могут быть записаны непосредственно в объект Response, что устраняет необходимость записи файла, что может быть затруднительным из-за проблем с разрешениями, ввода-вывода конкуренции и обеспечения того, что запланированная очистка происходит.

Вот фрагмент кода... Я еще не проверил это, и я не предоставил весь код, но думаю, что он хорошо представляет идею.

    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()

Ответ 6

так как Excel понимает HTML, вы можете просто записать данные в виде таблицы HTML в файл temp с расширением .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

если заголовок длины содержимого опущен, вы можете просто сразу написать html обратно, но это может работать некорректно все время во всех браузерах

Ответ 7

Я лично предпочитаю метод XML. Я верну данные из базы данных в наборе данных, сохраните его в XMl, затем создам файл xslt, который содержит правило преобразования, которое будет отформатировать правильный документ, а простой XML-преобразование завершит работу. Лучшая часть этого вы можете форматировать ячейки, выполнять условное форматирование, устанавливать заголовки и нижние колонтитулы и даже устанавливать диапазоны печати. ​​

Ответ 8

Я делал это несколько раз, и каждый раз самым простым способом было просто вернуть файл CSV (Comma Separated Value). Excel импортирует его идеально, и это относительно быстро сделать.

Ответ 9

мы экспортируем данные из datagrid, чтобы постоянно преуспеть. Преобразуя его в 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

Я обнаружил, что где-то это работает хорошо.

Ответ 10

Вот отчет, который извлекается из хранимой процедуры. Результаты экспортируются в 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

Ответ 12

Если вы заполните 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

Ответ 13

Просто избегайте COM-взаимодействия через пространство имен Microsoft.Office.Interop. Это так чертовски медленный, ненадежный и нескромный. Не применимо для мазохистов.

Ответ 14

Вы можете легко создавать файлы Excel, отлично отформатированные с помощью этой библиотеки: http://officehelper.codeplex.com/documentation.

Microsoft Office не нужно устанавливать на веб-сервере!

Ответ 15

Я бы просто создал CSV файл на основе данных, потому что я считаю это самым чистым, и Excel имеет хорошую поддержку для него. Но если вам нужен более гибкий формат, я уверен, что есть некоторые сторонние инструменты для генерации реальных файлов excel.

Ответ 16

CSV - самый простой способ. Большую часть времени он связан с Excel. В противном случае вы должны использовать API автоматизации или формат XML. API и XML не так уж сложно использовать.

Информация о создании XML для Excel

Ответ 17

Я либо иду по маршруту CSV (как описано выше), либо чаще в эти дни, я использую Infragistics NetAdvantage для генерации файла. (Очень большая часть времени, когда Infragistics находится в игре, мы просто экспортируем существующий UltraWebGrid, который по существу является решением с одним LOC, если не требуются дополнительные настройки форматирования. Мы могли бы вручную генерировать файл Excel/BIFF, но редко требуется.)

Ответ 18

man, in.net Я предполагаю, что у вас может быть компонент, который мог бы это сделать, но в классическом asp я уже сделал это, создав таблицу html и изменив mime tipe страницы на vnd/msexcel. Я предполагаю, что если вы используете gridview и меняете тип mime, возможно, он должен работать, потому что gridview является html-таблицей.

Ответ 19

Единственный пуленепробиваемый способ избежать "Похоже, что эти цифры хранятся как текстовые" зеленые треугольники - использовать формат Open XML. Это стоит использовать, чтобы избежать неизбежных зеленых треугольников.

Ответ 20

Лучший метод, который я видел для отчетов excel, - это вывести данные в XML с расширением XML и передать его клиентам с правильным типом контента. (Приложение/XLS)

Это работает для любого отчета, который требует базового форматирования и позволяет сравнивать с существующими электронными таблицами с помощью инструментов сравнения текста.

Ответ 21

Предполагая, что это для интрасети, где вы можете установить разрешения и мандат IE, вы можете создать клиентскую сторону рабочей книги с JScript/VBScript, управляющий Excel. Это дает вам собственное форматирование Excel без проблем с автоматизацией Excel на сервере.

Я не уверен, что я действительно рекомендую этот подход больше, кроме как в довольно нишевых сценариях, но он был довольно распространен во время классических аутсайдеров ASP.

Ответ 22

Конечно, вы всегда можете использовать сторонние компоненты. Лично у меня был хороший опыт работы с 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");

Ответ 23

Одна из проблем, с которыми я столкнулся, используя одно из предложенных выше решений, которые похожи на этот ответ что если вы выталкиваете контент как вложение (то, что я считаю самым чистым решением для браузеров без ms), затем откройте его в Excel 2000-2003, его тип - "Веб-страница Excel", а не родной Excel.

Затем вы должны объяснить пользователям, как использовать "Сохранить как тип" из Excel, чтобы преобразовать его в документ Excel. Это боль, если пользователям необходимо отредактировать этот документ, а затем повторно загрузить его на свой сайт.

Моя рекомендация - использовать CSV. Это просто, и если пользователи открывают его из Excel, Excel по крайней мере предлагает им сохранить его в своем родном формате.

Ответ 24

Здесь решение потока передает данные как 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();
}

Ответ 25

только что создала функцию для экспорта из веб-формы С#, чтобы преуспеть в надежде, что она поможет другим

    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();
            }
        }
     }

Ответ 26

Если вам нужно использовать Excel вместо CSV файла, вам нужно будет использовать автоматизацию OLE для экземпляра Excel на сервере. Самый простой способ сделать это - создать файл шаблона и программно заполнить его данными. Вы сохраняете его в другом файле.

Советов:

  • Не делайте это интерактивно. Попросите пользователя начать процесс, а затем отправить страницу со ссылкой на файл. Это уменьшает потенциальные проблемы производительности при создании электронной таблицы.
  • Используйте шаблон, как я описал ранее. Это облегчает его изменение.
  • Убедитесь, что в Excel не отображаются диалоги. На веб-сервере это повесит весь экземпляр excel.
  • Держите экземпляр Excel на отдельном сервере, желательно за брандмауэром, поэтому он не отображается как потенциальное отверстие безопасности.
  • Следите за использованием ресурсов. Создание дистрибутива поверх интерфейса автоматизации OLE (PIA - просто прокладки над этим) - довольно тяжелый процесс. Если вам нужно масштабировать это до больших объемов данных, вам может потребоваться несколько умнее с вашей архитектурой.

Некоторые из методов использования mime-типов для подбора excel в открытии HTML-таблицы будут работать, если вы не против того, чтобы формат файла был немного базовым. Эти подходы также помогают процессору тяжело работать на клиенте. Если вам нужен мелкомасштабный контроль над форматом электронной таблицы, вам, вероятно, придется использовать сам Excel для генерации файла, как описано выше.