从Excel中删除行
以下是我尝试的方法:
答)我试图使用Microsoft.Office.Interop.Excel
从Excel表中删除行。 我在SSIS包中的脚本任务中这样做。
我将库添加到GAC,因为它提出了一个错误: Could not load Library
。
现在,它引发这个错误说: Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80040154
。
谷歌search这告诉我,我需要MS Office安装它的工作,我不希望因为我部署这个解决scheme的服务器是绝对不会有MS Office安装在它上面。 我不是专家,但我想知道为什么这样的操作是不可能的,通过简单地添加引用一个DLL? 为什么必须安装MS Office。
B)我也尝试过Oledb jet jet provider,但是这个不允许删除行。 它支持的唯一操作是插入,更新和select。
我在网上遇到的事情:
A) SO问题的答案build议使用Npoi ,但我不能完全依靠这个,因为今天免费的图书馆可以在未来得到支付。
B)我也遇到了EPP Plus库。 我已经使用它,并明白它是基于GNU公共许可证,但我担心使用它,因为它可能成为未来的付费工具。
C)我也遇到过使用Microsoft的Open XML SDK的人。 在我弄脏手之前,如果有人先告诉我是否应该使用这个,我会很喜欢。 不是我懒得自己尝试一下,但是我开始之前对我有什么帮助的是,这个SDK是否需要安装在机器上的任何外部程序。 因为它需要我安装一个msi才能够使用它。
有没有办法使用Microsoft COM组件来做到这一点? 我不是在这里问一个主观的问题。 我想知道技术上的障碍,如果有的话我使用上述三种研究工具。
提前致谢
关键是Interop你确实必须安装办公室。 所以直言不讳地说,你不能使用Interop。 如果你只需要支持xlsx文件,你可以用xml来完成。
看到这个和这个链接关于解压xlsx文件,编辑和重新打包的更多细节。 你唯一需要的就是解压缩它和你自己的xml处理代码。
如果要求也是支持xls文件,那么你有一些问题。 我过去没有任何额外的安装,但没有成功,所以我决定只支持xlsx。 我需要在服务器上安装一些.msi文件或办公室。
你说你在SSIS中使用脚本任务; 那么为什么不导入你想要从其中删除值的Excel文件(最好是将其保存到数据库中),然后用你想保留的数据生成一个新的xls文件。
或者完全不使用脚本任务,在数据stream中使用一个configuration好的excel源码和一个脚本组件(这与脚本任务基本上是一样的,只能在数据stream中使用这个脚本任务),并在那里做所有的工作。 如果你有一个到excel文件的dynamic连接,你总是可以使用variables(如果你在DataTools上的话)来configuration这样一个连接。
祝你好运!
如果你想使用Microsoft.Office.Interop.Excel那么,是的,你确实需要在服务器上的Excel。 因此,只要你只想处理基于xlsx的工作簿/ 2007+,那么我就会build议OpenXML是要走的路。 这只是一个学习曲线,你会发现Excel在后台为你做了多less工作,但是一旦你习惯了它,并不算太坏。
LINQPad中有一个很快的例子:
void Main() { string fileName = @"c:\temp\delete-row-openxml.xlsx"; using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fileName, true)) { // Get the necessary bits of the doc WorkbookPart workbookPart = doc.WorkbookPart; SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First(); SharedStringTable sst = sstpart.SharedStringTable; // Get the first worksheet WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); Worksheet sheet = worksheetPart.Worksheet; var rows = sheet.Descendants<Row>(); foreach (Row row in rows.Where(r => ShouldDeleteRow(r, sst))) { row.Remove(); } } } private bool ShouldDeleteRow(Row row, SharedStringTable sst) { // Whatever logic to apply to decide whether to remove a row or not string txt = GetCellText(row.Elements<Cell>().FirstOrDefault(), sst); return (txt == "Row 3"); } // Basic way to get the text of a cell - need to use the SharedStringTable private string GetCellText(Cell cell, SharedStringTable sst) { if (cell == null) return ""; if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString)) { int ssid = int.Parse(cell.CellValue.Text); string str = sst.ChildElements[ssid].InnerText; return str; } else if (cell.CellValue != null) { return cell.CellValue.Text; } return ""; }
请注意,这将清除该行,而不是所有其他行。 要做到这一点,你需要提供一些逻辑来调整剩余行的行索引。
为了回答更多的OP问题,除了标准的.Net框架之外,OpenXML msi是需要的。 该示例需要对WindowsBase.dll进行打包API引用,并使用DocumentFormat.OpenXml.Packaging和DocumentFormat.OpenXml.Spreadsheet语句。 OpenXML API包也可以通过Nuget在VS中引用,所以如果你不需要的话甚至不需要安装msi。 但是这样做是有道理的,恕我直言。
另一个你会发现非常有用的项目是OpenXML工具msi。 这可以让你打开一个Word或Excel文档,看看里面的XML布局 – 最有用的。