سؤال

أنا على وشك إضافة قسم إلى تطبيق ASP.NET (VB.NET codebehind) والذي سيسمح للمستخدم بالحصول على البيانات التي يتم إرجاعها إليه كملف Excel، والذي سأقوم بإنشائه بناءً على بيانات قاعدة البيانات.في حين أن هناك عدة طرق للقيام بذلك، إلا أن كل منها له عيوبه الخاصة.كيف تريد أنت إرجاع البيانات؟أنا أبحث عن شيء نظيف ومباشر قدر الإمكان.

هل كانت مفيدة؟

المحلول

CSV

الايجابيات:

  • بسيط

سلبيات:

  • قد لا يعمل في مناطق أخرى أو في تكوينات مختلفة في Excel (على سبيل المثال.فاصل القائمة)
  • لا يمكن تطبيق التنسيق والصيغ وما إلى ذلك

لغة البرمجة

الايجابيات:

  • لا تزال بسيطة جدًا
  • يدعم التنسيق والصيغ البسيطة

سلبيات:

  • يجب عليك تسمية الملف باسم xls وقد يحذرك Excel بشأن فتح ملف Excel غير أصلي
  • ورقة عمل واحدة لكل مصنف

OpenXML (أوفيس 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

الايجابيات:

  • يستخدم مكتبات Microsoft الأصلية
  • قراءة الدعم للمستندات الأصلية

سلبيات:

  • بطيء جدا
  • مشكلات مطابقة التبعية/الإصدار
  • مشكلات التزامن/تكامل البيانات لاستخدام الويب عند القراءة
  • بطيء جدا
  • مشكلات القياس لاستخدام الويب (يختلف عن التزامن):تحتاج إلى إنشاء العديد من مثيلات تطبيق Excel الثقيل على الخادم
  • يتطلب ويندوز
  • هل ذكرت أنه بطيء؟

نصائح أخرى

يمكنك إخراج البيانات كخلايا جدول 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> 

إذا كانت قادمة من أ جدول البيانات:

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

هذا غلاف مجاني حول SpreadML - إنه يعمل بشكل رائع.

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

استنادًا إلى الإجابات المقدمة والتشاور مع زملاء العمل، يبدو أن الحل الأفضل هو إنشاء ملف XML أو جداول HTML ودفعه للأسفل كمرفق.التغيير الوحيد الذي أوصى به زملائي في العمل هو أن البيانات (أي.يمكن كتابة جداول HTML) مباشرة إلى كائن الاستجابة، وبالتالي التخلص من الحاجة إلى كتابة ملف، الأمر الذي قد يكون مزعجًا بسبب مشاكل الأذونات، وتنافس الإدخال/الإخراج، وضمان حدوث التطهير المجدول.

إليك مقتطف من الكود...لم أتحقق من ذلك بعد، ولم أقدم كل الكود المطلوب، لكنني أعتقد أنه يمثل الفكرة جيدًا.

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

نظرًا لأن 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

إذا تم حذف رأس المحتوى، يمكنك فقط إعادة كتابة html مباشرة، ولكن هذا قد لا يعمل بشكل صحيح طوال الوقت في جميع المتصفحات

أنا شخصياً أفضّل طريقة XML.سأعيد البيانات من قاعدة البيانات في مجموعة بيانات، وأحفظها في XMl، ثم أقوم بإنشاء ملف xslt يحتوي على قاعدة تحويل من شأنها تنسيق مستند مناسب، وسيؤدي تحويل XML البسيط إلى إنهاء المهمة.أفضل ما في الأمر هو أنه يمكنك تنسيق الخلايا وإجراء التنسيق الشرطي وإعداد الرؤوس والتذييلات وحتى تعيين نطاقات الطباعة.

لقد قمت بذلك عدة مرات وفي كل مرة كانت أسهل طريقة هي ببساطة إرجاع ملف CSV (قيمة مفصولة بفواصل).يستورده برنامج Excel بشكل مثالي، وهو سريع نسبيًا.

نقوم بتصدير البيانات من 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

لقد وجدت أنه في مكان ما، أنه يعمل بشكل جيد.

أوصي مكتبة توليد إكسل مفتوحة المصدر مجانية والذي يعتمد على OpenXML

لقد ساعدني منذ عدة أشهر.

فيما يلي تقرير يتم سحبه من إجراء مخزن.يتم تصدير النتائج إلى 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

إذا قمت بملء 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

فقط تجنب COM Interop عبر مساحة الاسم Microsoft.Office.Interop.إنه بطيء للغاية وغير موثوق به وغير قابل للتطوير.لا ينطبق على الماسوشية.

يمكنك إنشاء ملفات Excel منسقة بشكل جيد باستخدام هذه المكتبة، بسهولة تامة: http://officehelper.codeplex.com/documentation.

لا يحتاج Microsoft Office إلى التثبيت على خادم الويب!

CSV هو أسهل طريقة.في معظم الأحيان يتم ربطه ببرنامج Excel.وإلا فسيتعين عليك استخدام واجهات برمجة تطبيقات التشغيل الآلي أو تنسيق XML.ليس من الصعب استخدام واجهات برمجة التطبيقات وXML.

معلومات حول إنشاء XML لبرنامج Excel

إما أن أتبع مسار CSV (كما هو موضح أعلاه)، أو في كثير من الأحيان أستخدم Infragistics NetAdvantage لإنشاء الملف هذه الأيام.(في الغالبية العظمى من الأوقات التي يتم فيها تشغيل Infragistics، نقوم فقط بتصدير UltraWebGrid الموجود، وهو في الأساس حل ذو LOC واحد ما لم تكن هناك حاجة إلى تعديلات إضافية على التنسيق.يمكننا أيضًا إنشاء ملف Excel/BIFF يدويًا، ولكن نادرًا ما تكون هناك حاجة لذلك.)

يا رجل، في .net، أعتقد أنه من الممكن أن يكون لديك مكون يمكنه القيام بذلك، ولكن في asp الكلاسيكي قمت بذلك بالفعل من خلال إنشاء جدول html وتغيير نوع mime للصفحة إلى vnd/msexcel.أعتقد أنه إذا كنت تستخدم طريقة عرض الشبكة وقمت بتغيير نوع التمثيل الصامت، فربما ينبغي أن تعمل، لأن طريقة عرض الشبكة عبارة عن جدول html.

الطريقة الوحيدة المقاومة للرصاص لتجنب المثلثات الخضراء "يبدو أن هذه الأرقام مخزنة كنص" هي استخدام تنسيق Open XML.يجدر استخدامه، فقط لتجنب المثلثات الخضراء التي لا مفر منها.

أفضل طريقة رأيتها لتقارير Excel هي كتابة البيانات بتنسيق XML بامتداد XML وتدفقها إلى العملاء باستخدام نوع المحتوى الصحيح.(التطبيق/XLS)

يعمل هذا مع أي تقرير يتطلب تنسيقًا أساسيًا، ويتيح لك المقارنة مع جداول البيانات الموجودة باستخدام أدوات مقارنة النص.

بافتراض أن هذا خاص بالإنترانت، حيث يمكنك تعيين الأذونات وتفويض IE، يمكنك إنشاء جانب عميل المصنف باستخدام JScript/VBScript يقود برنامج Excel.ويمنحك هذا تنسيق Excel الأصلي، دون الحاجة إلى محاولة تشغيل Excel تلقائيًا على الخادم.

لست متأكدًا من أنني سأوصي حقًا بهذا الأسلوب بعد الآن إلا في سيناريوهات متخصصة إلى حد ما، ولكنه كان شائعًا إلى حد ما خلال ذروة ASP الكلاسيكية.

يمكنك بالطبع دائمًا اختيار مكونات الطرف الثالث.شخصياً، كانت لدي تجربة جيدة مع 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");

إحدى المشكلات التي واجهتها باستخدام أحد الحلول المقترحة أعلاه والتي تشبه هذه الإجابة هو أنه إذا قمت بدفع المحتوى للخارج كمرفق (ما وجدته هو الحل الأنظف للمتصفحات غير MS)، ثم فتحه في Excel 2000-2003، فإن نوعه هو "صفحة ويب Excel" وليس "صفحة ويب Excel" مستند Excel الأصلي.

ثم يتعين عليك أن تشرح للمستخدمين كيفية استخدام "حفظ كنوع" من داخل Excel لتحويله إلى مستند Excel.يعد هذا أمرًا مؤلمًا إذا احتاج المستخدمون إلى تحرير هذا المستند ثم إعادة تحميله على موقعك.

توصيتي هي استخدام CSV.إنه أمر بسيط، وإذا فتحه المستخدمون من داخل Excel، فإن Excel على الأقل يطالبهم بحفظه بتنسيقه الأصلي.

أود فقط إنشاء ملف CSV استنادًا إلى البيانات، لأنني أرى أنه الأنظف، ويحظى برنامج Excel بدعم جيد له.ولكن إذا كنت تحتاج إلى تنسيق أكثر مرونة، فأنا متأكد من وجود بعض أدوات الطرف الثالث لإنشاء ملفات Excel حقيقية.

إليك حلًا لتدفقات جدول البيانات كملف 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();
}

لقد قمت للتو بإنشاء وظيفة للتصدير من نموذج ويب C# للتفوق على أمل أن يساعد الآخرين

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

إذا كان عليك استخدام Excel بدلاً من ملف CSV، فستحتاج إلى استخدام أتمتة OLE على مثيل Excel على الخادم.أسهل طريقة للقيام بذلك هي الحصول على ملف قالب وملئه بالبيانات برمجياً.قمت بحفظه في ملف آخر.

نصائح:

  • لا تفعل ذلك بشكل تفاعلي.اطلب من المستخدم بدء العملية ثم نشر صفحة تحتوي على رابط الملف.يؤدي هذا إلى تخفيف مشكلات الأداء المحتملة أثناء إنشاء جدول البيانات.
  • استخدم القالب كما وصفته من قبل.ويجعل من السهل تعديله.
  • تأكد من ضبط برنامج Excel على عدم ظهور مربعات حوار منبثقة.على خادم الويب، سيؤدي هذا إلى تعليق نسخة Excel بأكملها.
  • احتفظ بمثيل Excel على خادم منفصل، ويفضل أن يكون خلف جدار الحماية، حتى لا يتم كشفه باعتباره ثغرة أمنية محتملة.
  • إبقاء العين على استخدام الموارد.يعد إنشاء مجموعة بيانات عبر واجهة أتمتة OLE (توجد PIA مجرد حشوات فوق هذه) عملية ثقيلة الوزن إلى حد ما.إذا كنت بحاجة إلى توسيع نطاق ذلك ليشمل كميات كبيرة من البيانات، فقد تحتاج إلى أن تكون ذكيًا إلى حد ما في بنيتك.

ستعمل بعض أساليب "استخدام أنواع mime لخداع Excel لفتح جدول HTML" إذا كنت لا تمانع في أن يكون تنسيق الملف أساسيًا بعض الشيء.تعمل هذه الأساليب أيضًا على إيقاف العمل الثقيل لوحدة المعالجة المركزية على العميل.إذا كنت تريد تحكمًا دقيقًا في تنسيق جدول البيانات، فربما يتعين عليك استخدام برنامج Excel نفسه لإنشاء الملف كما هو موضح أعلاه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top