23

我刚刚开始通过 C# 摆弄 Excel,以便能够自动创建和添加到 Excel 文件。

我可以打开文件并更新其数据并在现有工作表中移动。我的问题是如何添加新工作表?

我试过:

Excel.Worksheet newWorksheet;
newWorksheet = (Excel.Worksheet)excelApp.ThisWorkbook.Worksheets.Add(
                Type.Missing, Type.Missing, Type.Missing, Type.Missing);

但是我低于COM Exception并且我的谷歌搜索没有给我任何答案。

HRESULT 的异常:0x800A03EC 源是:“Interop.Excel”

我希望有人能把我从痛苦中解救出来。

4

9 回答 9

42

您需要在项目中将 COM 引用添加到Microsoft Excel 11.0 Object Library - 或任何合适的版本。

这段代码对我有用:

private void AddWorksheetToExcelWorkbook(string fullFilename,string worksheetName)
{
    Microsoft.Office.Interop.Excel.Application xlApp = null;
    Workbook xlWorkbook = null;
    Sheets xlSheets = null;
    Worksheet xlNewSheet = null;

    try {
        xlApp = new Microsoft.Office.Interop.Excel.Application();

        if (xlApp == null)
            return;

        // Uncomment the line below if you want to see what's happening in Excel
        // xlApp.Visible = true;

        xlWorkbook = xlApp.Workbooks.Open(fullFilename, 0, false, 5, "", "",
                false, XlPlatform.xlWindows, "",
                true, false, 0, true, false, false);

        xlSheets = xlWorkbook.Sheets as Sheets;

        // The first argument below inserts the new worksheet as the first one
        xlNewSheet = (Worksheet)xlSheets.Add(xlSheets[1], Type.Missing, Type.Missing, Type.Missing);
        xlNewSheet.Name = worksheetName;

        xlWorkbook.Save();
        xlWorkbook.Close(Type.Missing,Type.Missing,Type.Missing);
        xlApp.Quit();
    }
    finally {
        Marshal.ReleaseComObject(xlNewSheet);
        Marshal.ReleaseComObject(xlSheets);
        Marshal.ReleaseComObject(xlWorkbook);
        Marshal.ReleaseComObject(xlApp);
        xlApp = null;
    }
}

请注意,您要非常小心地正确清理和释放您的 COM 对象引用。StackOverflow 问题中包含一个有用的经验法则:“Never use 2 dots with COM objects”。在您的代码中;你会遇到真正的麻烦。我上面的演示代码没有正确清理 Excel 应用程序,但这是一个开始!

在调查这个问题时,我发现其他一些有用的链接:

根据 MSDN

要使用 COM 互操作,您必须具有管理员或高级用户安全权限。

希望有帮助。

于 2008-10-10T23:19:47.660 回答
5

想感谢您的一些出色的答复。@AR.,你的明星,它工作得很好。我昨晚注意到Excel.exe没有关闭;所以我做了一些研究,发现了如何释放 COM 对象。这是我的最终代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using Excel;

namespace testExcelconsoleApp
{
    class Program
    {
        private String fileLoc = @"C:\temp\test.xls";

        static void Main(string[] args)
        {
            Program p = new Program();
            p.createExcel();
        }

        private void createExcel()
        {
            Excel.Application excelApp = null;
            Excel.Workbook workbook = null;
            Excel.Sheets sheets = null;
            Excel.Worksheet newSheet = null;

            try
            {
                FileInfo file = new FileInfo(fileLoc);
                if (file.Exists)
                {
                    excelApp = new Excel.Application();
                    workbook = excelApp.Workbooks.Open(fileLoc, 0, false, 5, "", "",
                                                        false, XlPlatform.xlWindows, "",
                                                        true, false, 0, true, false, false);

                    sheets = workbook.Sheets;

                    //check columns exist
                    foreach (Excel.Worksheet sheet in sheets)
                    {
                        Console.WriteLine(sheet.Name);
                        sheet.Select(Type.Missing);

                        System.Runtime.InteropServices.Marshal.ReleaseComObject(sheet);
                    }

                    newSheet = (Worksheet)sheets.Add(sheets[1], Type.Missing, Type.Missing, Type.Missing);
                    newSheet.Name = "My New Sheet";
                    newSheet.Cells[1, 1] = "BOO!";

                    workbook.Save();
                    workbook.Close(null, null, null);
                    excelApp.Quit();
                }
            }
            finally
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(newSheet);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);

                newSheet = null;
                sheets = null;
                workbook = null;
                excelApp = null;

                GC.Collect();
            }
        }
    }
}

谢谢你的帮助。

于 2008-10-11T08:38:41.930 回答
2

AR的另一个“Up Tick”......,但如果你不必使用互操作,我会完全避免它。这个产品实际上很有趣: http ://www.clearoffice.com/ ,它提供了一个非常直观的、完全托管的、用于处理 excel 文件的 api,并且似乎是免费的。(至少目前) SpreadSheetGear也很出色,但价格昂贵。

我的两分钱。

于 2008-10-11T06:39:20.173 回答
1

不要忘记包括参考Microsoft Excel 12.0/11.0 object Library

using Excel = Microsoft.Office.Interop.Excel;
// Include this Namespace

Microsoft.Office.Interop.Excel.Application xlApp = null;
Excel.Workbook xlWorkbook = null;
Excel.Sheets xlSheets = null;
Excel.Worksheet xlNewSheet = null;
string worksheetName ="Sheet_Name";
object readOnly1 = false;

object isVisible = true;

object missing = System.Reflection.Missing.Value;

try
{
    xlApp = new Microsoft.Office.Interop.Excel.Application();

    if (xlApp == null)
        return;

    // Uncomment the line below if you want to see what's happening in Excel
    // xlApp.Visible = true;

    xlWorkbook = xlApp.Workbooks.Open(@"C:\Book1.xls", missing, readOnly1, missing, missing, missing, missing, missing, missing, missing, missing, isVisible, missing, missing, missing);

    xlSheets = (Excel.Sheets)xlWorkbook.Sheets;

    // The first argument below inserts the new worksheet as the first one
    xlNewSheet = (Excel.Worksheet)xlSheets.Add(xlSheets[1], Type.Missing, Type.Missing, Type.Missing);
    xlNewSheet.Name = worksheetName;

    xlWorkbook.Save();
    xlWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
    xlApp.Quit();
}
finally
{
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlNewSheet);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
    //xlApp = null;
}
于 2012-03-31T21:49:38.127 回答
0

您可以使用 OLEDB 创建和操作 Excel 文件。有关链接和示例,请参阅此问题

于 2008-10-11T00:21:08.410 回答
0

这是我想出的几件事:

  1. 您不能同时打开同一个对象的多个实例。例如,如果您实例化一个名为的新 excel 工作表对象xlsheet1,则必须在创建另一个 excel 工作表对象 ex 之前释放它xlsheet2。似乎 COM 失去了对对象的跟踪,并在服务器上留下了一个僵尸进程。

  2. 如果您有多个用户访问同一个文件,使用 关联的打开方法excel.workbooks也变得难以关闭。改用 Add 方法,它在不锁定文件的情况下同样有效。例如。xlBook = xlBooks.Add("C:\location\XlTemplate.xls")

  3. 释放 COM 对象后,将垃圾收集器放在单独的块或方法中。

于 2010-01-21T17:51:58.960 回答
0

COM绝对不是一个好方法。更具体地说,如果您正在处理网络环境,那就不行了......

我已经成功使用了以下开源项目:

  • OOXML 格式的 ExcelPackage (Office 2007)

  • .XLS 格式的 NPOI (Office 2003)

看看这些博客文章:

在 C# 中创建 Excel 电子表格 .XLS 和 .XLSX

带有 Excel 表格和动态图表的 NPOI

于 2012-02-16T13:20:27.593 回答
0

这是我用来添加附加工作表的

Workbook workbook = null;
Worksheet worksheet = null;

workbook = app.Workbooks.Add(1);
workbook.Sheets.Add();

Worksheet additionalWorksheet = workbook.ActiveSheet;
于 2013-12-10T07:41:57.753 回答
0

我在 VSTO 中遇到了类似的应用程序级加载项问题,添加新工作表时出现异常 HRESULT: 0x800A03EC。

错误代码 0x800A03EC(或 -2146827284)表示 NAME_NOT_FOUND;换句话说,你已经要求了一些东西,而 Excel 找不到它。

Dominic Zukiewicz @ Excel 错误 HRESULT: 0x800A03EC 在尝试使用单元格名称获取范围时

然后我终于意识到ThisWorkbook触发了异常。ActiveWorkbook正常。

Excel.Worksheet newSheetException = Globals.ThisAddIn.Application.ThisWorkbook.Worksheets.Add(Type.Missing, sheet, Type.Missing, Type.Missing);
Excel.Worksheet newSheetNoException = Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets.Add(Type.Missing, sheet, Type.Missing, Type.Missing);
于 2014-10-03T13:59:17.657 回答