我一直认为它确实如此,虽然我不知道我的想法在哪里...我总是认为将电子表格视为2D数组很容易,但有些搜索SO表明每个人都是使用第三方库?或者,所有那些需要安装不需要Office的解决方案的人......如果我没有这个限制,它会变得更容易吗?
正如我所说,我看了SO,但没有看到这个特定问题的答案。不过也许我的搜索技巧很糟糕......
编辑:我的想法是想在C#应用中打开XLS / CSV文档。我不希望来自单元格的任何复杂数据,只需能够从每个单元格中读取文本值。理想情况下,使用Cell.getText()方法将电子表格视为2D单元格数组的包装器是我需要的所有复杂性。
答案 0 :(得分:7)
Yes, .NET has built-in Office functionality。但是你会试图用它来打败自己。它也很好隐藏,只与Office 2007及更高版本兼容(除非您下载Office 2003 / XP的兼容性插件)。
最好使用some of the APIs designed to interoperate with Office而不是单独行动。链接用于Office Open XML SDK,可用于创建。* x Office文件(.docx,.xslx等)。
如果您想知道System.IO.Packaging如何与Office相关,则文档跟踪从此处开始:
http://msdn.microsoft.com/en-us/library/dd371623(VS.85).aspx
简写版本是新的办公室格式为Open XML documents。什么是Open XML文档?它们是包含在ZIP文件中的资源包(例如图像)和XML文件。您可以使用任何新的Office文件,将扩展名更改为.zip,然后将其打开以进行查看。
这是什么意思?这意味着您可以解压缩这些文件,将部件作为XDocuments加载并转到城镇。当然,您必须将文件解压缩到一个临时位置,对多个XML文件进行排序以找到您想要的文件,管理更改文件之间的所有连接等等。
或者,您可以使用System.IO.Packaging命名空间及其类型来打开这些文件,访问包中的不同组件(甚至远程),更改它们,并将更改刷新回磁盘。
现在,虽然您可以使用命名空间轻松完成此操作,但您无法安全访问Open XML文件中的不同包。你必须使用魔法字符串来获取部分。这也意味着您几乎必须了解Open XML架构,这很糟糕。
这就是MS提供Open XML SDK的原因,您可以将它与System.IO.Packaging结合使用来打开,更改和保存Open XML office文档。
使用我的first link添加second link,您就会得到原始问题的答案。
要回答OP的澄清,它不会那么容易。 xls文件很复杂;细胞不仅仅是一个二维阵列。但是有免费的API可以帮助您打开和访问其中的数据。
如果您要打开Office 2007兼容文件,我强烈建议您查看Office Open XML SDK。如果您打算打开旧版本(Office 2003,XP),我建议在codeplex.com上使用Excel中的众多项目之一(我想想我使用了{{ 3}})。其中有很多,旨在使Excel电子表格中的数据访问变得非常容易。但不太容易[x] [y]。
答案 1 :(得分:4)
如果要打开较旧格式的.XLS(Excel 97-2003)文件,而不是较新的* .XLSX,则可以尝试使用JET提供程序:
OleDbConnection con = new OleDbConnection(string.Format(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"",
"filename.xls"
));
con.Open();
OleDbDataAdapter ad = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", con);
DataTable t = new DataTable();
ad.Fill(t);
这会将数据放入DataTable中,操作相当容易。
答案 2 :(得分:2)
Visual Basic是(或至少是)用于处理Office应用程序的.NET语言中的优秀,尽管您也可以使用C#。
答案 3 :(得分:2)
不确定您想要做什么,但有一个完整的网站可以在Visual Studio中使用Office。
Understanding the Excel Object Model from a Visual Studio 2005 Developer's Perspective
您可能需要Visual Studio Tools for Office。
答案 4 :(得分:2)
我认为Excel Data Reader会有所帮助。您可以将Microsoft Excel文件('97 -2007)直接读入数据集。
以下是一些示例代码(来自网站):
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//...
//4. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
//5. Data Reader methods
while (excelReader.Read())
{
//excelReader.GetInt32(0);
}
//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
答案 5 :(得分:0)
不,.NET没有内置的Office功能。
答案 6 :(得分:0)
答案 7 :(得分:0)
我发现将办公室文件保存为XML文档然后解析和操作XML比在Office Interop深处停留更容易。我发现自己说的很多。你的旅费可能会改变。 XML格式适用于较大的文件,但它的易用性非常值得。
答案 8 :(得分:0)
您是否尝试过查看Visual Studio Tools for Office?它是一个完整的托管API,用于处理所有Office应用程序。
使用VSTO进行了大量的开发工作,通过论坛等进行判断。以下是使用LINQ等处理VSTO的辅助API:
答案 9 :(得分:0)
约翰,
这取决于环境。我们的应用程序几乎完全一样。直到最近我们才使用Interop。只要不留下COM组件,就不会太难使用。
不幸的是,缺点是Office 2007不支持任何类型的服务器自动化(对操作系统没有讨厌的黑客攻击),因此如果您在非UI环境/自动化任务中运行,那么您将无法使用Interop。
你可以使用像ADO这样的东西,我相信它没有相同的细胞概念,所以它不能用于我们需要的东西。
或者,有一些好的图书馆,请查看我的review。 FlexCel是我们购买的优先选择。便宜,快速且易于使用。
答案 10 :(得分:0)
实际上,我会把它恰恰相反......所以Office仍然没有.Net功能?如果能够在.Net中构建宏而不是坚持使用VBA,那将是很好的。
我知道我可以从Visual Studio中的Office扩展性项目中获得相同的功能,但我正在谈论的事情本身对Office本身更为“原生”。对于某些情况,做一个可扩展性项目是一个很大的过度杀伤。
答案 11 :(得分:0)
尝试使用http://www.codeplex.com/xlslinq
以下示例按工作表的名称查找工作表。
using(XlsWorkbook book = new XlsWorkbook("TestData\\100.xls")) {
var sheets = from s in book.Worksheets
where s.Name == "100"
select s;
foreach(var sheet in sheets) Console.WriteLine(sheet.Name);
}
答案 12 :(得分:0)
Office的界面并不难以使用。这里的小Excel示例(如下) - 打开工作表,使用RegExp解析整个事物寻找特定的“命中”:
internal void OpenSearchAndReplace(string path, Logger log)
{
object nullobj = System.Reflection.Missing.Value;
ConfigurationManager conf = new ConfigurationManager();
try
{
if (_excelApp == null)
_excelApp = new Excel.Application();
Excel.Workbook book = _excelApp.Workbooks.Open(path, nullobj, nullobj, nullobj, nullobj, nullobj, nullobj,
nullobj, nullobj, nullobj, nullobj,
nullobj, nullobj, nullobj, nullobj);
Excel.Worksheet worksheet;
if( book.Worksheets.Count > 1 )
worksheet = (Excel.Worksheet)book.Worksheets.get_Item("Sheet1");
else
worksheet = (Excel.Worksheet)book.ActiveSheet;
Excel.Range range = worksheet.UsedRange;
object[,] values = (object[,])range.Value2;
for (int row = 1; row <= values.GetUpperBound(0); ++row)
{
for (int col = 1; col <= values.GetUpperBound(1); ++col)
{
string value = Convert.ToString(values[row, col]);
if (Regex.IsMatch(value, @conf.GetFullyQualifiedRegExp()))
{
range.Cells.set_Item(row, col, conf.GetReplacementText());
}
}
}
book.Save();
Marshal.ReleaseComObject(worksheet );
log.LogExcelFile( "File " + path + " has been processed\n" );
}
catch (Exception ex)
{...}
但是请 - 如果你不想让很多物品挂在地上,请记得强制使用Garbagecollector :):
// Force the garbagecollector to kill objects.
// Waiting for it to finish
GC.Collect();
GC.WaitForPendingFinalizers();