![](/img/trans.png)
[英]C# COM Interop Excel: How to write to cells from C# using Interop Excel?
[英]Eliminating use of '2 dots' when using Excel Interop Com Objects - C#
我在發布Excel Interop Com Objects時遇到問題,當我嘗試保存然后關閉通過Excel Interop創建的Excel工作簿時,導致我的c#應用程序崩潰。 我覺得問題是在某些情況下我使用'2點'與excel互操作COM對象,這是我不讀的。 我已經從大多數代碼行中刪除了2個點,但我正在找到一種方法來重新創建以下代碼行,以便它們只使用一個點。 如果有人有任何建議我會非常感激。
workbook = (Excel.Workbook)app.Workbooks.Open(startForm.excelFileLocation,);
workbook = (Excel.Workbook)app.Workbooks.Add(1);
workSheet_range.Font.Color = System.Drawing.Color.FloralWhite.ToArgb();
workSheet_range.Font.Bold = font;
workSheet_range.Interior.Color = System.Drawing.Color.Red.ToArgb();
驗證每條指令的返回類型並單獨分解。
您的第一行以“app.Workbooks”開頭,它返回Workbooks類型的對象。 然后Open指令返回一個工作簿:
workbooks = app.Workbooks;
workbook = workbooks.Open(startForm.excelFileLocation);
然后您可以像這樣拆分第二個:
workbook = workbooks.add(1);
如果你沒有“點擊”實際的InterOp對象,可以使用多個點。
這是一個完整的示例:
Using Excel = Microsoft.Office.Interop.Excel;
public void Read()
{
Excel.Application xlApp = new Excel.Application();
Excel.Workbooks xlWorkBooks = xlApp.Workbooks;
Excel.Workbook xlWorkBook = xlWorkBooks.Open(sourceFile);
Excel.Worksheet xlWorkSheet = xlWorkBook.Worksheets[ 1 ];
Excel.Range range = xlWorkSheet.UsedRange;
range = range.Cells;
Array myValues = ( Array )range.Value; //now holds all the data in the sheet
//The following is to ensure the EXCEL.EXE instance is released...
//If you edit this code, know that using 2 dots (ex: range.Cells.Value) can create weird stuff!
xlWorkBook.Close(false);
xlWorkBooks.Close();
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlWorkBooks);
releaseObject(xlApp);
xlWorkSheet = null;
xlWorkBooks = null;
xlWorkBook = null;
xlApp = null;
}
private static void releaseObject( object obj )
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
Console.WriteLine("Unable to release the Object " + ex.ToString());
}
}
總結這里的所有信息。
例如:
using Microsoft.Office.Interop.Excel;
...
var missing = Type.Missing;
using (AutoReleaseComObject<Microsoft.Office.Interop.Excel.Application> excelApplicationWrapper = new AutoReleaseComObject<Microsoft.Office.Interop.Excel.Application>(new Microsoft.Office.Interop.Excel.Application()))
{
var excelApplicationWrapperComObject = excelApplicationWrapper.ComObject;
excelApplicationWrapperComObject.Visible = true;
var excelApplicationWrapperComObjectWkBooks = excelApplicationWrapperComObject.Workbooks;
try
{
using (AutoReleaseComObject<Workbook> workbookWrapper = new AutoReleaseComObject<Workbook>(excelApplicationWrapperComObjectWkBooks.Open(@"C:\Temp\ExcelMoveChart.xlsx", false, false, missing, missing, missing, true, missing, missing, true, missing, missing, missing, missing, missing)))
{
var workbookComObject = workbookWrapper.ComObject;
Worksheet sheetSource = workbookComObject.Sheets["Sheet1"];
ChartObject chartObj = (ChartObject)sheetSource.ChartObjects("Chart 3");
Chart chart = chartObj.Chart;
chart.Location(XlChartLocation.xlLocationAsObject, "Sheet2");
ReleaseObject(chart);
ReleaseObject(chartObj);
ReleaseObject(sheetSource);
workbookComObject.Close(false);
}
}
finally
{
excelApplicationWrapperComObjectWkBooks.Close();
ReleaseObject(excelApplicationWrapperComObjectWkBooks);
excelApplicationWrapper.ComObject.Application.Quit();
excelApplicationWrapper.ComObject.Quit();
ReleaseObject(excelApplicationWrapper.ComObject.Application);
ReleaseObject(excelApplicationWrapper.ComObject);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
private static void ReleaseObject(object obj)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) > 0);
obj = null;
}
catch (Exception ex)
{
obj = null;
Console.WriteLine("Unable to release the Object " + ex.ToString());
}
}
我知道釋放所有對象,使用GC.Collect並且在分配時不使用兩個點似乎超過頂部但至少當我退出Excel實例時,進程被釋放,我不必以編程方式殺死Excel進程!
我建議使用像NetOffice這樣的庫,它將負責為你釋放所有資源(所以你不必擔心所有這些COM Interop調用),作為獎勵,會給你智能感知。
您可以通過NuGet安裝它或從站點下載程序集。
使用兩個點並不是“不允許”,但它肯定會對性能產生影響,尤其是在緊密循環中運行時。
每個“點”是對Excel庫的COM調用,它可能比正常的CLR對象訪問慢得多。 通常,您希望盡可能少地減少COM調用的數量。
除非重復使用相同的變量, 否則通過分成兩行從兩個點減少到一個點不會產生任何影響。 例如,改變
workSheet_range.Interior.Color = System.Drawing.Color.Red.ToArgb();
至
var interior = workSheet_range.Interior;
interior.Color = System.Drawing.Color.Red.ToArgb();
如果不重復使用interior
變量,則會對性能產生零影響,甚至可以“優化”回原始單線程。
但是,改變
var font = workSheet_range.Font;
font.Color = System.Drawing.Color.FloralWhite.ToArgb();
font.Bold = font;
將減少對workSheet_range.Font
的調用,以便您看到增量收益。
底線
我不會太擔心改變每個雙點調用,而是使用一個好的分析工具來確定代碼花費最多的時間,然后首先處理該區域。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.