如何使用Linq将数据写入Excel电子表格?
如何使用Linq写入Excel电子表格?
问题的原因:
1. CSV文件是大多数系统上与Excel相关联的文件格式。
2. 可以手动创建Excel Worksheet对象并进行手动填充。
3. 使用XLS / XLSX生成控件。
解决方法:
1. 创建CSV文件,该文件在大多数系统上与Excel相关联。
2. 手动创建Excel Worksheet对象并手动填充数据。
3. 使用XLS / XLSX生成控件,例如Spire.XLS。
以下是解决方法的具体步骤:
1. 创建CSV文件:
var csv = new StringBuilder(); // 添加列标题 csv.AppendLine("Column1,Column2,Column3"); // 添加数据行 csv.AppendLine("Data1,Data2,Data3"); // 保存文件 File.WriteAllText("path/to/file.csv", csv.ToString());
2. 创建Excel Worksheet对象并手动填充数据:
using (var workbook = new XLWorkbook()) { var worksheet = workbook.Worksheets.Add("Sheet1"); // 添加列标题 worksheet.Cell(1, 1).Value = "Column1"; worksheet.Cell(1, 2).Value = "Column2"; worksheet.Cell(1, 3).Value = "Column3"; // 添加数据行 worksheet.Cell(2, 1).Value = "Data1"; worksheet.Cell(2, 2).Value = "Data2"; worksheet.Cell(2, 3).Value = "Data3"; // 保存文件 workbook.SaveAs("path/to/file.xlsx"); }
3. 使用XLS / XLSX生成控件(例如Spire.XLS):
using (var workbook = new Workbook()) { var worksheet = workbook.Worksheets[0]; // 添加列标题 worksheet.Range["A1"].Value = "Column1"; worksheet.Range["B1"].Value = "Column2"; worksheet.Range["C1"].Value = "Column3"; // 添加数据行 worksheet.Range["A2"].Value = "Data1"; worksheet.Range["B2"].Value = "Data2"; worksheet.Range["C2"].Value = "Data3"; // 保存文件 workbook.SaveToFile("path/to/file.xls", ExcelVersion.Version2013); }
通过以上三种方法,您可以使用Linq来写入Excel电子表格。
在使用LINQ时,想要将数据写入Excel电子表格并不直接。原因是LINQ提供了查询生成功能,但不提供对象关系映射(O/R mapping)功能,而Excel无法处理从LINQ中输出的对象,因为它们不再是数据行。要实现这一目标,可以通过调用`(datacontext).GetCommand(yourLinqQueryHere)`方法来获取LINQ查询的命令文本,然后将其作为SqlCommand的CommandText。接着调用ExecuteReader()方法,然后使用GetSchemaTable()方法确定列的顺序。然后(假设你正在自动化Excel)将(DbDataReader).GetValues()的结果传递给Excel的(Worksheet).Row[x].Values,它会将结果写入Excel电子表格中。可能还需要对数据进行重新排序。如果你不是自动化Excel,可以使用Jet OLEDB提供程序将值倒入Excel,使用OleDbConnection,或者使用第三方组件生成电子表格。
如何使用Linq编写到Excel电子表格的问题是由于个人对使用库来完成此类任务的不喜欢而引起的。我使用反射来生成列标题并获取每行的单元格值。如果您使用的是.NET Framework 3.5,则可以利用扩展方法将任何
下面是我的实现方式:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace YourNameSpace
{
public static class ExcelExportExtensions
{
public static XDocument ToExcelXml(this IEnumerable
{
return rows.ToExcelXml("Sheet1");
}
public static XDocument ToExcelXml(this IEnumerable
{
sheetName = sheetName.Replace("/", "-");
sheetName = sheetName.Replace("\\", "-");
XNamespace mainNamespace = "urn:schemas-microsoft-com:office:spreadsheet";
XNamespace o = "urn:schemas-microsoft-com:office:office";
XNamespace x = "urn:schemas-microsoft-com:office:excel";
XNamespace ss = "urn:schemas-microsoft-com:office:spreadsheet";
XNamespace html = "http://www.w3.org/TR/REC-html40";
XDocument xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
var headerRow = from p in rows.First().GetType().GetProperties()
select new XElement(mainNamespace + "Cell",
new XElement(mainNamespace + "Data",
new XAttribute(ss + "Type", "String"), p.Name)); //使用反射生成标题
XElement workbook = new XElement(mainNamespace + "Workbook",
new XAttribute(XNamespace.Xmlns + "html", html),
new XAttribute(XName.Get("ss", "http://www.w3.org/2000/xmlns/"), ss),
new XAttribute(XName.Get("o", "http://www.w3.org/2000/xmlns/"), o),
new XAttribute(XName.Get("x", "http://www.w3.org/2000/xmlns/"), x),
new XAttribute(XName.Get("xmlns", ""), mainNamespace),
new XElement(o + "DocumentProperties",
new XAttribute(XName.Get("xmlns", ""), o),
new XElement(o + "Author", "Smartdesk Systems Ltd"),
new XElement(o + "LastAuthor", "Smartdesk Systems Ltd"),
new XElement(o + "Created", DateTime.Now.ToString())
), //结束文档属性
new XElement(x + "ExcelWorkbook",
new XAttribute(XName.Get("xmlns", ""), x),
new XElement(x + "WindowHeight", 12750),
new XElement(x + "WindowWidth", 24855),
new XElement(x + "WindowTopX", 240),
new XElement(x + "WindowTopY", 75),
new XElement(x + "ProtectStructure", "False"),
new XElement(x + "ProtectWindows", "False")
), //结束ExcelWorkbook
new XElement(mainNamespace + "Styles",
new XElement(mainNamespace + "Style",
new XAttribute(ss + "ID", "Default"),
new XAttribute(ss + "Name", "Normal"),
new XElement(mainNamespace + "Alignment",
new XAttribute(ss + "Vertical", "Bottom")
),
new XElement(mainNamespace + "Borders"),
new XElement(mainNamespace + "Font",
new XAttribute(ss + "FontName", "Calibri"),
new XAttribute(x + "Family", "Swiss"),
new XAttribute(ss + "Size", "11"),
new XAttribute(ss + "Color", "#000000")
),
new XElement(mainNamespace + "Interior"),
new XElement(mainNamespace + "NumberFormat"),
new XElement(mainNamespace + "Protection")
),
new XElement(mainNamespace + "Style",
new XAttribute(ss + "ID", "Header"),
new XElement(mainNamespace + "Font",
new XAttribute(ss + "FontName", "Calibri"),
new XAttribute(x + "Family", "Swiss"),
new XAttribute(ss + "Size", "11"),
new XAttribute(ss + "Color", "#000000"),
new XAttribute(ss + "Bold", "1")
)
)
), //结束样式
new XElement(mainNamespace + "Worksheet",
new XAttribute(ss + "Name", sheetName /* Sheet name */),
new XElement(mainNamespace + "Table",
new XAttribute(ss + "ExpandedColumnCount", headerRow.Count()),
new XAttribute(ss + "ExpandedRowCount", rows.Count() + 1),
new XAttribute(x + "FullColumns", 1),
new XAttribute(x + "FullRows", 1),
new XAttribute(ss + "DefaultRowHeight", 15),
new XElement(mainNamespace + "Column",
new XAttribute(ss + "Width", 81)
),
new XElement(mainNamespace + "Row", new XAttribute(ss + "StyleID", "Header"), headerRow),
from contentRow in rows
select new XElement(mainNamespace + "Row",
new XAttribute(ss + "StyleID", "Default"),
from p in contentRow.GetType().GetProperties()
select new XElement(mainNamespace + "Cell",
new XElement(mainNamespace + "Data", new XAttribute(ss + "Type", "String"), p.GetValue(contentRow, null))) /* 使用反射构建单元格 */ )
), //结束表格
new XElement(x + "WorksheetOptions",
new XAttribute(XName.Get("xmlns", ""), x),
new XElement(x + "PageSetup",
new XElement(x + "Header",
new XAttribute(x + "Margin", "0.3")
),
new XElement(x + "Footer",
new XAttribute(x + "Margin", "0.3")
),
new XElement(x + "PageMargins",
new XAttribute(x + "Bottom", "0.75"),
new XAttribute(x + "Left", "0.7"),
new XAttribute(x + "Right", "0.7"),
new XAttribute(x + "Top", "0.75")
)
),
new XElement(x + "Print",
new XElement(x + "ValidPrinterInfo"),
new XElement(x + "HorizontalResolution", 600),
new XElement(x + "VerticalResolution", 600)
),
new XElement(x + "Selected"),
new XElement(x + "Panes",
new XElement(x + "Pane",
new XElement(x + "Number", 3),
new XElement(x + "ActiveRow", 1),
new XElement(x + "ActiveCol", 0)
)
),
new XElement(x + "ProtectObjects", "False"),
new XElement(x + "ProtectScenarios", "False")
) //结束工作表选项
) //结束工作表
);
xdoc.Add(workbook);
return xdoc;
}
}
}
我还创建了另一个扩展方法来方便在Web场景中返回XDocument:
public static DownloadableFile ToDownloadableXmlFileForExcel2003(this System.Xml.Linq.XDocument file, string fileName) { MemoryStream ms = new MemoryStream(); XmlWriterSettings xmlWriterSettings = new XmlWriterSettings() { Encoding = Encoding.UTF8 }; XmlWriter xmlWriter = XmlWriter.Create(ms, xmlWriterSettings); file.Save(xmlWriter); //.Save()添加了头标签! xmlWriter.Close(); //必须关闭writer以将其内容转储到输出(内存流) DownloadableFile dbf = new DownloadableFile { FileName = String.Format("{0}.xls", fileName.Replace(" ", "")), Content = ms.ToArray(), MimeType = "application/vnd.ms-excel" }; ms.Close(); ms.Dispose(); return dbf; }
希望对您有所帮助!
我更新了ToDownloadableXmlFileForExcel2003()扩展方法,使用MemoryStream对象而不是.ToString(),这会导致OutOfMemoryException异常。使用我的方式生成XML XLS文档的一个问题是文件的大小。对于小型文档来说还好,但对于具有100k+行的大型xls表格来说就不行了。
这看起来很酷,所以我尝试了一下,但是出现了错误“Excel无法打开文件'newexcelfil2.xlsx',因为文件格式或文件扩展名无效。请验证文件没有损坏,并且文件扩展名与文件格式匹配。”我已经验证了xml的格式。
有人找到了您的代码并进行了微小的修改,还添加了一个名为ToExcelXmlWorksheet()的方法。他们的代码在以下网址:[https://scottstjohn.wordpress.com/2011/04/02/write-to-excel-xml-with-linq-to-xml/](https://scottstjohn.wordpress.com/2011/04/02/write-to-excel-xml-with-linq-to-xml/)