2016-01-06 186 views
1

我有一个程序来自动填写发票excel文件,以便以后可以打印。我能够填充单元格并对其进行格式化。但是excel过程仍在后台运行。C# - 如何杀死在后台程序运行的excel进程

public void Write(tbl_Sale sale,List<SalesModel> saleCollection) 
{ 
    Mouse.SetCursor(Cursors.Wait); 
    Excel.Application application = null; 
    Workbook workbook = null; 
    Worksheet inputSheet = null; 
    Range range = null; 

    try 
    { 
     if (sale != null) 
     { 
      if (saleCollection.Count != 0) 
      { 
       application = new Excel.Application(); 
       FileInfo fileInfo = new FileInfo("Sample.xlsx"); 
       var sheet = "Invoice"; 
       workbook = application.Workbooks.Open(fileInfo.FullName); 
       inputSheet = workbook.Worksheets.Cast<Worksheet>().Where(w => w.Name == sheet).FirstOrDefault(); 

       range = inputSheet.Cells; 
       range.SetValue("G4", sale.Sale_ID); 
       range.SetValue("G5", sale.Sale_Date); 

       Range row = inputSheet.get_Range("A22", Missing.Value).EntireRow; 

       for (int i = 0; i < saleCollection.Count; i++) 
       { 
        row.Insert(XlInsertShiftDirection.xlShiftDown, row); 
        range = inputSheet.Cells; 
        range.SetValue("A" + (22 + i), i + 1); 

        range = inputSheet.Cells; 
        range.SetValue("B" + (22 + i), saleCollection[i].Product.Prod_Code); 
        range = inputSheet.Range["B" + (22 + i) + ":" + "D" + (22 + i)]; 
        range.Merge(); 

        range = inputSheet.Cells; 
        range.SetValue("E" + (22 + i), saleCollection[i].Product.Prod_Name); 
        range = inputSheet.Range["E" + (22 + i) + ":" + "K" + (22 + i)]; 
        range.Merge(); 
        range.HorizontalAlignment = 1; 

        range = inputSheet.Cells; 
        range.SetValue("X" + (22 + i), saleCollection[i].SalesDetail.SaleD_Quantity); 
        range = inputSheet.Range["X" + (22 + i) + ":" + "Y" + (22 + i)];       
        range.Merge(); 
        range.HorizontalAlignment = 1; 
        range.NumberFormat = "0.00"; 

        range = inputSheet.Cells; 
        range.SetValue("Z" + (22 + i), saleCollection[i].SalesDetail.SaleD_Rate); 
        range = inputSheet.Range["Z" + (22 + i) + ":" + "AA" + (22 + i)]; 
        range.Merge(); 
        range.HorizontalAlignment = 1; 
        range.NumberFormat = "0.00"; 

        range = inputSheet.Cells; 
        range.SetValue("AB" + (22 + i), saleCollection[i].SalesDetail.SaleD_Amount); 
        range = inputSheet.Range["AB" + (22 + i) + ":" + "AD" + (22 + i)]; 
        range.Merge(); 
        range.HorizontalAlignment = 1; ; 
        range.NumberFormat = "0.00"; 
       } 
       range = inputSheet.Cells; 
       range.SetValue("X" + (22 + saleCollection.Count + 2), saleCollection.Sum(s => s.SalesDetail.SaleD_Quantity)); 
       range.SetValue("AB" + (22 + saleCollection.Count + 2), sale.Sale_Total); 
       fileInfo = new FileInfo("Invoices\\" + sale.Sale_ID + ".xlsx"); 

       workbook.Application.DisplayAlerts = false; 
       workbook.SaveAs(fileInfo.FullName, XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing, false, false, XlSaveAsAccessMode.xlNoChange, XlSaveConflictResolution.xlLocalSessionChanges ,Type.Missing, Type.Missing, Type.Missing, Type.Missing); 

       releaseObject(row); 
       MessageBox.Show("Invoice exported successfully", "Invoice Export", MessageBoxButton.OK, MessageBoxImage.Information);      
       // Process.Start(fileInfo.FullName); 
      } 
     } 
    } 
    catch (Exception) 
    { 
     MessageBox.Show("Error while generating Excel report"); 
    } 
    finally 
    { 
     workbook.Close(0); 
     application.Quit(); 
     releaseObject(application); 
     releaseObject(workbook); 
     releaseObject(inputSheet); 
     releaseObject(range); 
     GC.Collect(); 
     Mouse.SetCursor(Cursors.Arrow); 
    } 
} 

我不能杀Excel进程从background.I不太清楚我在做什么上面wrong.The代码是整个东西我做的自动化Excel。请帮助我。

回答

1

我做的是使用一个初始化,并为Excel对象Deinitializer,像这样:

private void InitializeExcelObjects() 
{ 
    _xlApp = new Excel.Application 
    { 
     SheetsInNewWorkbook = 2, 
     StandardFont = "Tahoma", 
     StandardFontSize = 11 
    }; 

    _xlBook = _xlApp.Workbooks.Add(Type.Missing); 
    _xlApp.Windows.Application.ActiveWindow.DisplayGridlines = false; 

    _xlSheets = _xlBook.Worksheets; 
    _xlSheet = (Excel.Worksheet)_xlSheets.Item[1]; 
    _xlSheetDelPerf = (Excel.Worksheet)_xlSheets.Item[2]; 
} 

private void DeinitializeExcelObjects() 
{ 
    Marshal.ReleaseComObject(_xlSheet); 
    Marshal.ReleaseComObject(_xlSheetDelPerf); 

    Marshal.ReleaseComObject(_xlSheets); 

    _xlBook.Close(false, null, null); 
    Marshal.ReleaseComObject(_xlBook); 

    _xlApp.DisplayAlerts = false; 
    _xlApp.Quit(); 
    Marshal.ReleaseComObject(_xlApp); 
    _xlApp = null; 
} 

他们被称为是这样的:

public void GenerateDuckbilledPlatypusRpt() 
{ 
    try 
    { 
     InitializeExcelObjects(); 
     . . . // all the Excel generation code goes here 
    } 
    finally 
    { 
     DeinitializeExcelObjects(); 
    } 
} 

IOW,我想你可以改变你的代码如下:

public void Write(tbl_Sale sale,List<SalesModel> saleCollection) 
{ 
    Mouse.SetCursor(Cursors.Wait); 
    Excel.Application application = null; 
    Workbook workbook = null; 
    Worksheet inputSheet = null; 
    Range range = null; 

    try 
    { 
     . . . 
     InitializeExcelObjects(); 
     . . . 
    } 
    finally 
    { 
     DeinitializeExcelObjects(); 
     Mouse.SetCursor(Cursors.Arrow); 
    } 
} 

private void InitializeExcelObjects() 
{  
    application = new Excel.Application(); 

    workbook = application.Workbooks.Add(Type.Missing); 

    sheets = workbook.Worksheets; 
    inputSheet = (Excel.Worksheet)sheets.Item[1]; 
} 

private void DeinitializeExcelObjects() 
{ 
    Marshal.ReleaseComObject(inputSheet); 

    Marshal.ReleaseComObject(sheets); 

    workbook.Close(false, null, null); 
    Marshal.ReleaseComObject(workbook); 

    application.DisplayAlerts = false; 
    application.Quit(); 
    Marshal.ReleaseComObject(application); 
    application = null; 
} 

它适用于我;因人而异

+1

谢谢shannon,它工作完美 – user5552042

+0

不客气,很高兴它有帮助。我试图“付出代价”为我所能得到的所有帮助。 –

1

看到这个答案: How do I properly clean up Excel interop objects?

您使用releaseObject(application),但似乎是指一些方法你有没有显示。不确定那里有什么代码。

除了注意链接问题中的注意事项之外,还可以尝试使用Marshal.ReleaseComObject(application)

+0

这基本上是我的代码和OP的区别,我想(我使用Marshal.ReleaseComObject()而不是releaseObject()。 –