Menghasilkan file Excel di ASP.NET [ditutup]


99

Saya akan menambahkan bagian ke aplikasi ASP.NET (codebehind VB.NET) yang memungkinkan pengguna mendapatkan data yang dikembalikan kepada mereka sebagai file Excel, yang akan saya buat berdasarkan data database. Meskipun ada beberapa cara untuk melakukan ini, masing-masing memiliki kekurangannya sendiri. Bagaimana Anda mengembalikan data? Saya mencari sesuatu yang sebersih dan semudah mungkin.


Jawaban:


131

CSV

Kelebihan:

  • Sederhana

Kekurangan:

  • Ini mungkin tidak berfungsi di lokal lain atau dalam konfigurasi Excel yang berbeda (yaitu Pemisah daftar)
  • Tidak dapat menerapkan pemformatan, rumus, dll

HTML

Kelebihan:

  • Masih cukup sederhana
  • Mendukung formulasi dan formula sederhana

Kekurangan:

  • Anda harus memberi nama file sebagai xls dan Excel mungkin memperingatkan Anda tentang membuka file Excel non-native
  • Satu lembar kerja per buku kerja

OpenXML (Office 2007 .XLSX)

Kelebihan:

  • Format Excel asli
  • Mendukung semua fitur Excel
  • Tidak dibutuhkan salinan penginstalan Excel
  • Dapat menghasilkan tabel Pivot
  • Dapat dibuat menggunakan proyek sumber terbuka EPPlus

Kekurangan:

  • Kompatibilitas terbatas di luar Excel 2007 (seharusnya tidak menjadi masalah saat ini)
  • Rumit kecuali Anda menggunakan komponen pihak ketiga

SpreadSheetML (XML format terbuka)

Kelebihan:

  • Sederhana dibandingkan dengan format Excel asli
  • Mendukung sebagian besar fitur Excel: pemformatan, gaya, rumus, beberapa lembar per buku kerja
  • Excel tidak perlu diinstal untuk menggunakannya
  • Tidak diperlukan pustaka pihak ketiga - cukup tulis xml Anda
  • Dokumen dapat dibuka dengan Excel XP / 2003/2007

Kekurangan:

  • Kurangnya dokumentasi yang bagus
  • Tidak didukung di versi Excel yang lebih lama (pra-2000)
  • Hanya tulis, setelah Anda membukanya dan membuat perubahan dari Excel, itu akan diubah menjadi Excel asli.

XLS (dibuat oleh komponen pihak ketiga)

Kelebihan:

  • Hasilkan file Excel asli dengan semua pemformatan, rumus, dll.

Kekurangan:

  • Biaya uang
  • Tambahkan dependensi

COM Interop

Kelebihan:

  • Menggunakan perpustakaan Microsoft asli
  • Baca dukungan untuk dokumen asli

Kekurangan:

  • Sangat lambat
  • Masalah kecocokan ketergantungan / versi
  • Masalah integritas data / konkurensi untuk penggunaan web saat membaca
  • Sangat lambat
  • Masalah penskalaan untuk penggunaan web (berbeda dari konkurensi): perlu membuat banyak contoh aplikasi Excel yang berat di server
  • Membutuhkan Windows
  • Apakah saya menyebutkan bahwa itu lambat?

1
Batasan "Hanya tulis" yang disebutkan untuk SpreadsheetML tidak sepenuhnya menjadi masalah, karena Anda dapat menyimpan file excel sebagai SpreadsheetML jika diinginkan.
Brian

1
SpreadsheetML dapat merusak Excel 2003 jika Anda membuat file besar dengannya. Jangan percaya: /
Brian

2
Anda dapat Menyimpan kembali ke file SpreadsheetML dengan baik di Office 2002 dan 2003. Tidak ada Simpan Sebagai diperlukan. SpreadsheetML tidak dapat menyimpan makro, bagan, grafik, dan beberapa peluang dan akhir lainnya, termasuk fitur baru Office 2007 (misalnya, lebih dari 3 format bersyarat). Karena XML bertele-tele, Zipping SpreadsheetML sebelum mengirim dari server (menggunakan SharpZipLib adalah opsi) berfungsi sangat baik untuk mengurangi waktu pengunduhan - sebenarnya, harus disebutkan bahwa OpenXML tetap disimpan dalam wadah ZIP. @ Brian: Saya menggunakan SpreadsheetML kompleks dalam kisaran 50-100MB setiap hari tanpa masalah crash.
richardtallent

Jika ada kemungkinan Anda harus mengekspor data dalam jumlah besar, Anda harus mengekspor sebagai CSV. Selain SpreadsheetML, lebih sulit untuk membuat solusi yang berkinerja baik dengan format lain. HTML dapat ditulis dan dibaca secara efisien, tetapi membutuhkan spesifikasi lebih lanjut agar berguna. Baik HTML dan SpreadsheetML memiliki masalah lain terkait file besar seperti yang disebutkan Brian dalam komentarnya. Jadi jika Anda hanya perlu ekspor data sederhana tetap dengan CSV.
JohannesH

2
@pomarc: Ini mungkin mudah, tapi tidak bersih. Pengguna menginginkan file Excel dan Anda memberinya file HTML dengan ekstensi palsu.
Heinzi

38

Anda dapat mengeluarkan data sebagai sel tabel html, menempelkan .xlsatau .xlsxekstensi di atasnya, dan Excel akan membukanya seolah-olah itu adalah dokumen asli. Anda bahkan dapat melakukan beberapa pemformatan terbatas dan penghitungan rumus dengan cara ini, jadi ini jauh lebih hebat daripada CSV. Selain itu, mengeluarkan tabel html seharusnya cukup mudah dilakukan dari platform web seperti ASP.Net;)

Jika Anda memerlukan beberapa lembar kerja atau lembar kerja bernama dalam Buku Kerja Excel Anda, Anda bisa melakukan sesuatu yang serupa melalui skema XML yang disebut SpreadSheetML. Ini bukan format baru yang disertakan dengan Office 2007, tetapi sesuatu yang sama sekali berbeda yang berfungsi sejauh Excel 2000. Cara termudah untuk menjelaskan cara kerjanya adalah dengan sebuah contoh:

<?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> 

12
Anda dapat mengganti nama file dengan extensio .xml dan menambahkan ini: <? mso-application progid = "Excel.Sheet"?> tepat setelah <? xml version = "1.0"?> dengan cara ini windows mengenali bahwa file tersebut adalah File Excel, akan memberikan ikon yang tepat, akan terbuka excel ketika Anda mengklik file tersebut dan Excel tidak akan mengeluh bahwa format file dan isinya tidak sesuai. selamat tinggal.
pomarc

1
@pomarc Kekurangannya adalah program lain yang mengimpor file excel tidak akan mengenalinya. Tapi kemudian, mereka mungkin tidak akan mengurai xml.
Joel Coehoorn

1
Saya telah menggunakan teknik ini dengan cukup berhasil. Ini akan menjadi rekomendasi saya - sangat sederhana dan sangat efektif.
NealB

Dua masalah potensial (YMMV) dengan data tabular HTML yang disamarkan sebagai file XLS: (1) Microsoft Excel akan memangkas spasi dan nol terdepan secara otomatis; dan (2) Microsoft Excel 2010 memperingatkan pengguna saat membuka file XLS yang berisi data tabular HTML. Solusi untuk # 1 tampaknya adalah creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel (jika spasi / nol utama signifikan dan perlu dipertahankan).
iokevins

Sekadar klarifikasi, sementara saya memang menyebutkan tabel HTML, poin utama dari jawaban ini adalah SpreadsheetML, yang lebih dari sekadar data tabular HTML. Excel melihatnya sebagai asli.
Joel Coehoorn

16

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

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

1
Hanya kode yang saya butuhkan, terima kasih. :)
Kjensen

Scott, ada apa dengan tanda pound ("£")? Bagaimana jika saya membutuhkannya? Adakah karakter lain yang berbahaya?
Piotr Owsiak

SEMPURNA. Hanya apa yang saya butuhkan.
Brad Bruce

tanda £ sebenarnya hanya sesuatu yang saya butuhkan untuk salah satu pelanggan saya. kamu bisa mengeluarkannya.
SpoiledTechie.com

Dua masalah potensial (YMMV) dengan data tabular HTML yang disamarkan sebagai file XLS: (1) Microsoft Excel akan memangkas spasi dan nol terdepan secara otomatis; dan (2) Microsoft Excel 2010 memperingatkan pengguna saat membuka file XLS yang berisi data tabular HTML. Solusi untuk # 1 tampaknya adalah creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel (jika spasi / nol utama signifikan dan perlu dipertahankan). File data CSV juga mengalami # 1 saat dibuka di Microsoft Excel.
iokevins


5

Berdasarkan jawaban yang diberikan, dan konsultasi dengan rekan kerja, tampaknya solusi terbaik adalah menghasilkan file XML atau tabel HTML dan mendorongnya ke bawah sebagai lampiran. Satu perubahan yang direkomendasikan oleh rekan kerja saya adalah bahwa data (yaitu tabel HTML) dapat ditulis langsung ke objek Respon, sehingga menghilangkan kebutuhan untuk menulis file, yang dapat merepotkan karena masalah perizinan, I / O pertentangan, dan memastikan bahwa pembersihan terjadwal terjadi.

Ini potongan kodenya ... Saya belum memeriksa ini, dan saya belum memberikan semua kode yang dipanggil, tapi saya pikir itu mewakili ide dengan baik.

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

2
Dan, Anda berada di jalur yang benar. Dan saya merekomendasikan SpreadsheetML daripada HTML - ruang bernafas untuk masa depan, karena dukungan HTML sangat terbatas. Tetapi dengan HTML, SpreadsheetML, dan OpenXML, ukuran file bisa jadi agak besar, dan tidak akan di-gzip oleh server. OpenXML memerlukan wadah ZIP dengan banyak file di dalamnya, dan SpreadsheetML serta HTML keduanya jauh lebih cepat untuk diunduh jika Anda membuat zip terlebih dahulu dan mengirim zip sebagai lampiran. Gunakan SharpZipLib dan streaming ke sana daripada langsung ke Respon.
richardtallent

4

karena Excel memahami HTML, Anda cukup menulis data sebagai tabel HTML ke file temp dengan ekstensi .xls, dapatkan FileInfo untuk file tersebut, dan hancurkan kembali menggunakan

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

jika Anda ingin menghindari file temp, Anda dapat menulis ke aliran dalam memori dan menulis kembali byte daripada menggunakan WriteFile

jika header panjang konten dihilangkan, Anda dapat langsung menulis html kembali, tetapi ini mungkin tidak berfungsi dengan benar sepanjang waktu di semua browser


2
Dua masalah potensial (YMMV) dengan data tabular HTML yang disamarkan sebagai file XLS: (1) Microsoft Excel akan memangkas spasi dan nol terdepan secara otomatis; dan (2) Microsoft Excel 2010 memperingatkan pengguna saat membuka file XLS yang berisi data tabular HTML. Solusi untuk # 1 tampaknya adalah creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel (jika spasi / nol utama signifikan dan perlu dipertahankan).
iokevins

3

Saya pribadi lebih suka metode XML. Saya akan mengembalikan data dari database dalam Dataset, menyimpannya ke XMl, lalu saya membuat file xslt yang berisi aturan transformasi yang akan memformat dokumen yang tepat, dan transformasi XML sederhana akan menyelesaikan pekerjaan. Bagian terbaik dari hal ini, Anda dapat memformat sel, melakukan pemformatan bersyarat, mengatur header dan footer, dan bahkan mengatur rentang cetak.


2

Saya telah melakukan ini beberapa kali dan setiap kali cara termudah adalah dengan mengembalikan file CSV (Comma Separated Value). Excel mengimpornya dengan sempurna, dan relatif cepat untuk dilakukan.


Satu masalah potensial (YMMV) dengan data CSV: Microsoft Excel akan memangkas ruang depan dan nol secara otomatis
iokevins

2

kami mengekspor data dari datagrid ke excel setiap saat. Mengonversinya ke HTML lalu menulis ke file 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()

Satu-satunya gotcha dengan metode ini adalah banyak kisi kami memiliki tombol atau tautan di dalamnya sehingga Anda memerlukan ini juga:

'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

Saya menemukan bahwa di suatu tempat, itu bekerja dengan baik.


2
Dua masalah potensial (YMMV) dengan data tabular HTML yang disamarkan sebagai file XLS: (1) Microsoft Excel akan memangkas spasi dan nol terdepan secara otomatis; dan (2) Microsoft Excel 2010 memperingatkan pengguna saat membuka file XLS yang berisi data tabular HTML. Solusi untuk # 1 tampaknya adalah creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel (jika spasi / nol utama signifikan dan perlu dipertahankan).
iokevins


2

Berikut adalah laporan yang diambil dari prosedur tersimpan. Hasilnya diekspor ke Excel. Ini menggunakan ADO bukan ADO.NET dan alasan mengapa baris ini

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

Itu melakukan sebagian besar pekerjaan dan tidak tersedia di 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

1

Jika Anda mengisi GridView dengan data, Anda dapat menggunakan fungsi ini untuk mendapatkan data berformat HTML, tetapi menunjukkan pada browser bahwa ini adalah file 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

Dua masalah potensial (YMMV) dengan data tabular HTML yang disamarkan sebagai file XLS: (1) Microsoft Excel akan memangkas spasi dan nol terdepan secara otomatis; dan (2) Microsoft Excel 2010 memperingatkan pengguna saat membuka file XLS yang berisi data tabular HTML. Solusi untuk # 1 tampaknya adalah creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel (jika spasi / nol utama signifikan dan perlu dipertahankan).
iokevins

1

Hindari saja COM Interop melalui namespace Microsoft.Office.Interop. Ini sangat lambat dan tidak dapat diandalkan dan tidak dapat diukur. Tidak berlaku untuk masokis.




0

Saya menggunakan rute CSV (seperti dijelaskan di atas), atau lebih sering hari ini, saya menggunakan Infragistics NetAdvantage untuk menghasilkan file. (Sebagian besar waktu di mana Infragistics sedang dimainkan, kami hanya mengekspor UltraWebGrid yang ada, yang pada dasarnya adalah solusi satu-LOC kecuali diperlukan penyesuaian pemformatan tambahan. Kami juga dapat membuat file Excel / BIFF secara manual, tetapi jarang ada kebutuhan untuk itu.)


0

man, di. bersih saya rasa Anda bisa memiliki komponen yang bisa melakukan itu, tetapi di asp klasik saya telah melakukannya membuat tabel html dan mengubah tipe mime halaman ke vnd / msexcel. Saya kira jika Anda menggunakan gridview dan mengubah jenis mime mungkin itu harus berfungsi, karena gridview adalah tabel html.


Dua masalah potensial (YMMV) dengan data tabular HTML yang disamarkan sebagai file XLS: (1) Microsoft Excel akan memangkas spasi dan nol terdepan secara otomatis; dan (2) Microsoft Excel 2010 memperingatkan pengguna saat membuka file XLS yang berisi data tabular HTML. Solusi untuk # 1 tampaknya adalah creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel (jika spasi / nol utama signifikan dan perlu dipertahankan).
iokevins

0

Satu-satunya cara antipeluru untuk menghindari segitiga hijau "Sepertinya angka-angka ini disimpan sebagai teks" adalah dengan menggunakan format Open XML. Layak digunakan, hanya untuk menghindari segitiga hijau yang tak terhindarkan.


0

Metode terbaik yang pernah saya lihat untuk laporan excel adalah menulis data dalam XML dengan ekstensi XML dan mengalirkannya ke klien dengan tipe konten yang benar. (aplikasi / xls)

Ini berfungsi untuk laporan apa pun yang memerlukan pemformatan dasar, dan memungkinkan Anda membandingkan dengan spreadsheet yang ada dengan menggunakan alat perbandingan teks.


0

Dengan asumsi ini untuk intranet, di mana Anda dapat mengatur izin dan mengamanatkan IE, Anda dapat membuat sisi klien buku kerja dengan JScript / VBScript yang menjalankan Excel . Ini memberi Anda pemformatan Excel asli, tanpa perlu repot mencoba mengotomatiskan Excel di server.

Saya tidak yakin saya benar-benar akan merekomendasikan pendekatan ini lagi kecuali dalam skenario yang cukup khusus, tetapi itu cukup umum selama masa kejayaan ASP klasik.


0

Anda tentu saja selalu dapat menggunakan komponen pihak ketiga. Secara pribadi, saya memiliki pengalaman yang baik dengan Spire.XLS http://www.e-iceblue.com/xls/xlsintro.htm

Komponen ini cukup mudah digunakan dalam aplikasi Anda:

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

0

Salah satu masalah yang saya temui menggunakan salah satu solusi yang disarankan di atas yang mirip dengan jawaban ini adalah jika Anda mendorong konten keluar sebagai lampiran (apa yang saya temukan sebagai solusi terbersih untuk browser non-ms) , lalu buka di Excel 2000-2003, jenisnya adalah "Halaman Web Excel" dan bukan dokumen Excel asli.

Kemudian Anda harus menjelaskan kepada pengguna bagaimana menggunakan "Simpan sebagai tipe" dari dalam Excel untuk mengubahnya menjadi dokumen Excel. Ini merepotkan jika pengguna perlu mengedit dokumen ini dan kemudian mengunggahnya kembali ke situs Anda.

Rekomendasi saya adalah menggunakan CSV. Ini sederhana dan jika pengguna membukanya dari dalam Excel, Excel setidaknya meminta mereka untuk menyimpannya dalam format aslinya.


Anda harus berhati-hati dengan CSV jika pengguna Anda tersebar di seluruh dunia. Di sini, di Jerman, koma digunakan sebagai pemisah desimal sehingga titik koma digunakan sebagai pemisah nilai. Menyulitkan untuk membuat satu file yang dapat dibaca di semua budaya yang berbeda. Oleh karena itu pilihan saya akan memilih salah satu format XML.
paul

0

Saya hanya akan membuat file CSV berdasarkan data, karena saya melihatnya sebagai yang terbersih, dan Excel memiliki dukungan yang baik untuk itu. Tetapi jika Anda memerlukan format yang lebih fleksibel, saya yakin ada beberapa alat pihak ke-3 untuk menghasilkan file excel yang sebenarnya.


0

Berikut adalah solusi untuk mengalirkan data keluar sebagai CSV. Cepat, bersih, dan mudah, dan menangani koma pada masukan.

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

-1

baru saja membuat fungsi untuk mengekspor dari formulir web C # untuk unggul semoga membantu orang lain

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

-5

Jika Anda harus menggunakan Excel dan bukan file CSV, Anda harus menggunakan otomatisasi OLE pada contoh Excel di server. Cara termudah untuk melakukannya adalah dengan memiliki file template dan secara terprogram mengisinya dengan data. Anda menyimpannya ke file lain.

Tips:

  • Jangan lakukan itu secara interaktif. Minta pengguna memulai proses dan kemudian memposting halaman dengan link ke file. Ini mengurangi potensi masalah kinerja saat spreadsheet dibuat.
  • Gunakan template seperti yang saya jelaskan sebelumnya. Itu membuatnya lebih mudah untuk memodifikasinya.
  • Pastikan bahwa Excel diatur untuk tidak memunculkan dialog. Di server web, ini akan menggantung seluruh contoh excel.
  • Simpan contoh Excel di server terpisah, sebaiknya di belakang firewall, sehingga tidak terekspos sebagai lubang keamanan potensial.
  • Perhatikan penggunaan sumber daya. Menghasilkan spreadhseet melalui antarmuka otomasi OLE (PIA hanyalah shims dari ini) adalah proses yang cukup berat. Jika Anda perlu menskalakan ini ke volume data yang tinggi, Anda mungkin perlu sedikit pandai dengan arsitektur Anda.

Beberapa pendekatan 'gunakan mime-types untuk mengelabui excel ke dalam membuka tabel HTML' akan berfungsi jika Anda tidak keberatan dengan format file yang agak mendasar. Pendekatan ini juga mengalihkan pekerjaan berat CPU ke klien. Jika Anda ingin mengontrol format spreadsheet, Anda mungkin harus menggunakan Excel itu sendiri untuk menghasilkan file seperti dijelaskan di atas.


Ide buruk melakukan otomatisasi dari server web. Alternatifnya mungkin tampak hack-ish, tetapi mereka benar-benar akan bekerja jauh lebih baik.
Joel Coehoorn

Kami menggunakan OLE sisi server dengan Excel dan ini sangat merepotkan di bagian belakang. Jika bukan karena risiko pada produk kami **, kami akan menggunakan solusi lain. ** Lebih baik iblis yang Anda kenal ...
DaveE
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.