Tag: excel interop

如何在C#,2012版中正确清理Excel互操作对象

我正在用C#编写一个应用程序,它将通过互操作打开一个Excel电子表格(2007年,现在),做一些魔术,然后关闭。 “魔术”部分非常重要,因此该应用程序将包含对Excel生成的许多COM对象的许多引用。 我以前写过这种应用程序(事实上已经太多次了)但是我从来没有找到一种舒适的,“好闻”的方法来与COM对象进行交互。 问题部分在于,尽管进行了大量研究,我仍然不能完全理解COM,部分是因为互操作包装器隐藏了很多可能不应该隐藏的内容。 事实上,来自社区的这么多不同的,相互冲突的建议只会让事情变得更糟。 如果您无法从标题中分辨出来,我已经完成了我的研究。 标题暗示了这篇文章: 如何正确清理Excel互操作对象? 在2008年首次询问时,这个建议在当时非常有用且非常可靠(特别是“从不使用带有com对象的2个点”位),但现在看来已经过时了。 2010年3月,Visual Studio团队发布了一篇博客文章,警告其他程序员Marshal.ReleaseComObject [is] Considered Dangerous 。 文章提到了两篇文章, cbrumme的WebLog> ReleaseComObject以及接口指针和运行时可调用包装器(RCW)之间的映射 ,表明人们一直错误地使用ReleaseComInterop(cbrumme:“如果你是一个使用适度数量的客户端应用程序在托管代码中自由传递的COM对象,不应使用ReleaseComObject“)。 有没有人有一个中等复杂的应用程序的例子,最好使用多个线程,能够成功地在内存泄漏之间导航(Excel在应用程序关闭后继续在后台运行)和InvalidComObjectExceptions? 我正在寻找能够在创建它的上下文之外使用COM对象的东西,但是一旦应用程序完成它仍然可以清理它:内存管理策略的混合,可以有效地跨越托管/非管理鸿沟。 对于讨论这个问题的正确方法的文章或教程的引用将是一个非常受欢迎的替代方案。 我最好的Google-fu努力已经返回了显然不正确的ReleaseComInterop方法。 更新: (这不是答案) 发布后不久我发现了这篇文章: Jake Ginnivan的VSTO和COM Interop 我已经能够通过扩展方法实现他在“AutoCleanup”类中包装COM对象的策略,我对结果非常满意。 虽然它没有提供允许COM对象跨越创建它们的上下文边界的解决方案,并且仍然使用ReleaseComObject函数 ,但它至少提供了一个简洁易读的解决方案。 这是我的实现: class AutoCleanup : IDisposable { public T Resource { get; private set; } public AutoCleanup( T resource ) { this.Resource = resource; […]

关闭Excel应用程序的正确方法

我正在编写一个应用程序,它使用以下代码访问Excel文件: RBTApplication = new Excel.Application(); RBTWorkbooks = RBTApplication.Workbooks; RBTWorkbook = RBTApplication.Workbooks.Open( RBTDataSet.Instance.FilePath, 0, true, 5, “”, “”, true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, “\t”, true, false, 0, true, 1, 0 ); RBTWorksheet = (Excel.Worksheet)RBTWorkbook.Worksheets.get_Item( 1 ); RBTRange = RBTWorksheet.UsedRange; 在我加载了我需要的数据后,我尝试用这段代码关闭Excel应用程序: RBTWorkbook.Close(); RBTApplication.Quit(); RBTWorksheet.ReleaseComObject(); RBTWorkbook.ReleaseComObject(); RBTWorkbooks.ReleaseComObject(); RBTApplication.ReleaseComObject(); 我的问题是EXCEL.EXE进程仍在运行。 杀死所有Excel进程的简单解决方案听起来不太好,因为我的进程可能是同时使用的许多电子表格之一。 这个也会影响打开新的excel电子表格 – 每个电子表格都是只读的,直到我不会杀死这个过程。 那么……如何正确关闭这个应用程序或者杀死这个特定的进程(有没有办法从COM对象中获取PID?)。 我想我找到了一个(还没试过) – 在打开新的ExcellApp之前和之后获取excell进程列表,比较列表(得到差异),杀死知道其PID的特定进程。 但是这个解决方案似乎不是从我的应用程序中处理COM对象和其他应用程序的正确方法。

COM对象excel互操作清理

假设我有一个组件正在使用Workbook对象,并且在该方法体的中间某处我调用了另一个类的某个方法。 例如: public class MainComponent { public void MyMainMethod() { OtherComponent otherComponent = new OtherComponent(); Workbook document; // some work with workbook object // working with document and worksheet objects. otherComponent.MethodCall(document); // some work with workbook object and it’s worksheets. foreach(Worksheet sheet in document.Workheets) // do something with sheet } } public class OtherComponent { […]

Excel Interop中的“AutoFilter”是否有“姐妹”function,适用于列而不是行?

Excel Interop中的“AutoFilter”function允许您过滤列显示下方行中的数据。 我需要一个类似的function,允许用户选择要隐藏的列。 例如,具体而言,如果有一组列3..15(C..0)从“9月15日”到“9月16日”,它们之间有明显的月份(“10月15日”等)我希望用户能够选择要查看的那些列的任何子集。 被取消选择的人会“消失” 如何实现这一目标? 我尝试了以下,但第二个filter没有效果: private void AddFilters() { Range column1Row6 = _xlSheet.Range[_xlSheet.Cells[6, 1], _xlSheet.Cells[6, 1]]; column1Row6.AutoFilter(1, Type.Missing, XlAutoFilterOperator.xlAnd, Type.Missing, true); // Try to filter columns, too (not the contents, but which columns display) Range columns3And4 = _xlSheet.Range[_xlSheet.Cells[6, 3], _xlSheet.Cells[6, 15]]; columns3And4.AutoFilter(1, Type.Missing, XlAutoFilterOperator.xlAnd, Type.Missing, true); } 这可能吗? UPDATE 看一些遗留代码,看起来这段代码就是这样做的: var fld = […]

如何将两个excel文件合并为一个带有工作表名称的文件?

对于两个excel表的合并,我使用下面的代码。 using System; using Excel = Microsoft.Office.Interop.Excel; using System.Reflection; namespace MergeWorkBooks { class Program { static void Main(string[] args) { Excel.Application app = new Excel.Application(); app.Visible = true; app.Workbooks.Add(“”); app.Workbooks.Add(@”c:\MyWork\WorkBook1.xls”); app.Workbooks.Add(@”c:\MyWork\WorkBook2.xls”); for (int i = 2; i <= app.Workbooks.Count; i++) { int count = app.Workbooks[i].Worksheets.Count; app.Workbooks[i].Activate(); for (int j=1; j <= count; j++) { Excel._Worksheet […]

C#和Excel Interop问题,保存excel文件不顺畅

我可以打开和写入excel文件,但是当我尝试通过传递路径来保存文件时,保存操作会提示“保存”对话框。 我希望它能够在指定的路径上保存文件 代码如下: excelApp.Save(exportToDirectory); excelApp.Quit(); 其中, exportToDirectory是:“C:\ files \ strings.xlsx”。 PS:我已经检查了excel版本和类似的问题。 谢谢

尝试在没有对话框的情况下退出C#Excel工作簿

我正在使用Microsoft Office Interop编辑一些excel文件,当我关闭它们时,我使用 outputExcelWorkBook.Close(false, paramMissing, paramMissing); 但是仍然会出现一个对话框,即使我将false作为第一个参数传递。 我也用true尝试了它,并给它一个文件路径作为第二个参数,但在这两种情况下都会出现一个对话框,询问我是否要在关闭之前保存。 谁能告诉我这里发生了什么?

为什么Excel Interop会在处理文件后删除图像?

Excel Interop正在从已处理的文件中删除图像。 我正在使用Excel Interop,没有第三方组件(我知道)。 工作流程是 – 创建文件(模板)的副本(目标),填充单元格,更改单选按钮状态 创建预先存在的.xslm文件(模板)的副本(目标) 通过Excel Interop打开目标 填充目标单元格,更改单选按钮状态 带有图像的工作表不会被修改 关闭目标 在我的开发机器上,目标文件看起来很棒 – 所有内容都已填充,图像存在。 注意:在我的开发机器上,我正在运行VS2010 IDE中的代码。 在生产机器上 – 一切都已填充,但图像不存在。 相反,会出现以下错误: NB:在生产计算机上,它作为服务运行,具有本地服务帐户。 “在文件中找不到关系ID为rId1的图像部分” 整个工作簿通过以下代码打开: var workbook = workbooks.Open(targetPath 0, false, 5, Type.Missing, Type.Missing, false, XlPlatform.xlWindows, “”, true, false, 0, true, false, false); 请注意,代码中不会处理带有图像的工作表。 工作簿(和个人工作表)受到保护。 但是,受保护的模板在开发中正确处理,但不在生产中。 我不认为保护与它有任何关系(但谁知道,对吧?这是Interop。呃)。 该文件由另一方创建,所有组件(即图像)都驻留在.xslm结构中,而不是作为另一个服务器的链接。 我已经validation图像在模板文件中的生产计算机上可见,但在已处理的文件中不可见。 为了确认这不是在制作中打开文件的问题,我通过电子邮件发送了一份副本,图像仍然不存在。 我还确认,在我的开发机器上,处理过的文件确实有可见的图像。 我不保护工作表,并解压缩文件结构。 .jpg文件确实不存在于生产机器的已处理目标中。 还有一点需要注意 – […]

互操作后Excel过程仍然保持打开状态; 传统方法不起作用

我遇到了一些我正在调试的代码问题。 Excel interop用于从工作簿中提取某些值; 但是,程序退出后Excel仍保持打开状态。 我已经尝试了传统的解决方案,但它仍然在运行代码的所有机器上保持对Excel的引用 private void TestExcel() { Excel.Application excel = new Excel.Application(); Excel.Workbooks books = excel.Workbooks; Excel.Workbook book = books.Open(“C:\\test.xlsm”); book.Close(); books.Close(); excel.Quit(); Marshal.ReleaseComObject(book); Marshal.ReleaseComObject(books); Marshal.ReleaseComObject(excel); } 即使是这段简单的代码也可以使进程运行多个文件(xlsm,xlsx,xls)。 现在我们有一个解决方法来杀死我们已经打开的Excel进程,但我更愿意让这个工作为我自己的理智。 我应该补充一点,我把它缩小到Workbook变量。 如果我删除对books.Open()的调用以及对book所有引用,则它会成功关闭。

如何在SQL Server 2008中将Excel文件插入/检索到varbinary(max)列?

我正在尝试将Excel文件保存到数据库中,我不想使用文件流,因为它需要有一个服务器。 那么如何在具有varbinary(max)类型的列的表中插入/更新/选择?