在.NET 2.0(在本例中为VB)中,是否有标准API将DataSet对象序列化为流,该流可以保存为制表符分隔文件并直接在Excel中打开?或者是否必须通过迭代表集合的成员来手动创建分隔文件?
在这种情况下,DataSet很小,由大约10个DataTable组成,每个DataTable有一行到几十行。我只是想知道是否有一个处理这种情况的内置机制,因为我认为它是一个相对常见的。
理想情况下,我希望能够在一次单击中返回所有内容 - 例如,客户端单击“生成报告”按钮,我汇编报告,并返回包含格式化数据的Response对象,提示保存或打开等等(我宁愿不让他们下载文件然后导入它,因为这似乎是一种不必要的麻烦的可用性。)
答案 0 :(得分:4)
有一个Excel的ADO.NET提供程序。 这意味着,如果您有数据集,则可以使用两个DataAdapter将数据从一个地方移动到另一个地方:从Oracle到Excel,从SQL到Excel,从Excel到Oracle等。
使用第一个DA从源填充DataSet,然后使用第二个DA更新目标。 DataAdapter不需要是相同的类型 - 您可以使用任何OleDbDataAdapter,SqlDataAdapter,OracleDataAdapter等进行读取和更新。
无需摆弄CSV或XML格式。无需使用Office Automation,因此没有PIA,它可以在服务器上运行。这只是ADO.NET。
要连接到Excel,请使用 Microsoft.Jet.OLEDB oledb提供程序。
摘录:
System.Data.DataSet ds1;
const string ConnStringSql= "Provider=sqloledb;Data Source=dinoch-8;Initial Catalog=Northwind;Integrated Security=SSPI;" ;
const string OutputFilename= "ExtractToExcel.xls";
const string ConnStringExcel=
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + OutputFilename + ";" +
"Extended Properties=\"Excel 8.0;HDR=yes;\""; // FIRSTROWHASNAMES=1;READONLY=false\"
const string sqlSelect="SELECT top 10 ProductId, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, GETDATE() as Extracted from Products order by UnitPrice";
const string sqlInsert="INSERT INTO Extracto (ProductId, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, Extracted) VALUES (@ProductId, @ProductName, @QuantityPerUnit, @UnitPrice, @UnitsInStock, @Extracted)";
private void ReadFromSql()
{
var ConnSql= new System.Data.OleDb.OleDbConnection(ConnStringSql);
var da1 = new System.Data.OleDb.OleDbDataAdapter();
da1.SelectCommand= new System.Data.OleDb.OleDbCommand(sqlSelect);
da1.SelectCommand.Connection= ConnSql;
ds1= new System.Data.DataSet();
da1.Fill(ds1, "Extracto");
}
private void InsertIntoExcel()
{
// need to update the row so the DA does the insert...
foreach (System.Data.DataRow r in ds1.Tables[0].Rows)
{
r.SetModified(); // mark the row as updated to force an insert
}
var da2 = new System.Data.OleDb.OleDbDataAdapter();
da2.UpdateCommand= new System.Data.OleDb.OleDbCommand(sqlInsert);
da2.UpdateCommand.Connection= ConnExcel;
da2.UpdateCommand.Parameters.Add("@ProductId", System.Data.OleDb.OleDbType.Integer, 4, "ProductId");
da2.UpdateCommand.Parameters.Add("@ProductName", System.Data.OleDb.OleDbType.VarWChar, 40, "ProductName");
da2.UpdateCommand.Parameters.Add("@QuantityPerUnit", System.Data.OleDb.OleDbType.VarWChar, 20, "QuantityPerUnit");
da2.UpdateCommand.Parameters.Add("@UnitPrice", System.Data.OleDb.OleDbType.Currency, 8, "UnitPrice");
da2.UpdateCommand.Parameters.Add("@UnitsInStock", System.Data.OleDb.OleDbType.SmallInt, 2, "UnitsInStock");
da2.UpdateCommand.Parameters.Add("@Extracted", System.Data.OleDb.OleDbType.Date, 8, "Extracted");
da2.Update(ds1, "Extracto");
}
这不是Excel自动化,因此适用于在服务器上使用Excel Automation的警告不适用。
您可以从现有的XLS文件(或XLSX)开始,只需填写命名范围即可。这使您有机会在插入ilve数据之前应用格式等。实质上,现有的XLS文件是一个模板 或者,您可以从零开始,在运行时完全动态地创建XLS文件和XLS文件中的表/范围。在这种情况下,XLS文件将非常普通/普通。没有格式,颜色,公式等。
答案 1 :(得分:0)
DataSet.writeXML(Stream)然后您可以将XML文件导入Excel
您还可以查看this utility为您完成此操作。
答案 2 :(得分:0)
您还可以使用简单的HTML表格标签(或网格视图)在.aspx页面上的HTML中创建表格,然后在您的代码隐藏中在页面中包含此行。载入:
Response.ContentType = "application/vnd.ms-excel"
享受:)
答案 3 :(得分:-2)
将数据集发送到xml DataSet.WriteXML
,您可以创建一个Xsl,将其转换为CSV(您可以使用XslTransform将xml转换为XSL)
编辑:其他选项是直接将其转换为CSV
Sub DataTable2CSV(ByVal table As DataTable, ByVal filename As String)
DataTable2CSV(table, filename, vbTab)
End Sub
Sub DataTable2CSV(ByVal table As DataTable, ByVal filename As String, _
ByVal sepChar As String)
Dim writer As System.IO.StreamWriter
Try
writer = New System.IO.StreamWriter(filename)
' first write a line with the columns name
Dim sep As String = ""
Dim builder As New System.Text.StringBuilder
For Each col As DataColumn In table.Columns
builder.Append(sep).Append(col.ColumnName)
sep = sepChar
Next
writer.WriteLine(builder.ToString())
' then write all the rows
For Each row As DataRow In table.Rows
sep = ""
builder = New System.Text.StringBuilder
For Each col As DataColumn In table.Columns
builder.Append(sep).Append(row(col.ColumnName))
sep = sepChar
Next
writer.WriteLine(builder.ToString())
Next
Finally
If Not writer Is Nothing Then writer.Close()
End Try
End Sub
除非你真的想用纯Excel格式