إنشاء ملف Excel في ASP.NET [مغلق]
-
02-07-2019 - |
سؤال
أنا على وشك إضافة قسم إلى تطبيق 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 - إنه يعمل بشكل رائع.
استنادًا إلى الإجابات المقدمة والتشاور مع زملاء العمل، يبدو أن الحل الأفضل هو إنشاء ملف 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.
إما أن أتبع مسار 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 نفسه لإنشاء الملف كما هو موضح أعلاه.