C# - 如何以编程方式添加 Excel 工作表 - Office XP / 2003

发布于 2024-07-06 21:42:26 字数 466 浏览 12 评论 0原文

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

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

我尝试过:

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

但是我得到了COM异常,并且我的谷歌搜索没有给我任何答案。

HRESULT 异常:0x800A03EC 来源为:“Interop.Excel”

我希望有人能够让我摆脱痛苦。

I am just starting to fiddle with Excel via C# to be able to automate the creation, and addition to an Excel file.

I can open the file and update its data and move through the existing worksheets. My problem is how can I add new sheets?

I tried:

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

But I get below COM Exception and my googling has not given me any answer.

Exception from HRESULT: 0x800A03EC Source is: "Interop.Excel"

I am hoping someone maybe able to put me out of my misery.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

酒废 2024-07-13 21:42:26

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

这段代码对我有用:

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 问题中包含一条有用的经验法则:“永远不要对 COM 对象使用 2 个点”。 在你的代码中; 你会遇到真正的麻烦。 上面的演示代码没有正确清理 Excel 应用程序,但它是一个开始!

在研究这个问题时我发现一些其他有用的链接:

根据 MSDN

将新工作表添加到工作簿

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

希望有帮助。

You need to add a COM reference in your project to the "Microsoft Excel 11.0 Object Library" - or whatever version is appropriate.

This code works for me:

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;
    }
}

Note that you want to be very careful about properly cleaning up and releasing your COM object references. Included in that StackOverflow question is a useful rule of thumb: "Never use 2 dots with COM objects". In your code; you're going to have real trouble with that. My demo code above does NOT properly clean up the Excel app, but it's a start!

Some other links that I found useful when looking into this question:

According to MSDN

To use COM interop, you must have
administrator or Power User security
permissions.

Hope that helps.

送君千里 2024-07-13 21:42:26

感谢您的一些精彩回复。 @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();
            }
        }
    }
}

感谢您的帮助。

Would like to thank you for some excellent replies. @AR., your a star and it works perfectly. I had noticed last night that the Excel.exe was not closing; so I did some research and found out about how to release the COM objects. Here is my final code:

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();
            }
        }
    }
}

Thank you for all your help.

旧梦荧光笔 2024-07-13 21:42:26

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

我的两分钱。

Another "Up Tick" for AR..., but if you don't have to use interop I would avoid it altogether. This product is actually quite interesting:
http://www.clearoffice.com/ and it provides a very intuitive, fully managed, api for manipulation excel files and seems to be free. (at least for the time being) SpreadSheetGear is also excellent but pricey.

my two cents.

酒浓于脸红 2024-07-13 21:42:26

不要忘记添加对 Microsoft Excel 12.0/11.0 对象库参考

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;
}

Do not forget to include Reference to 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;
}
半寸时光 2024-07-13 21:42:26

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

You can use OLEDB to create and manipulate Excel files. See this question for links and samples.

梦里人 2024-07-13 21:42:26

以下是我发现的几件事:

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

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

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

Here are a couple things I figured out:

  1. You can't open more than one instance of the same object at the same time. For Example if you instanciate a new excel sheet object called xlsheet1 you have to release it before creating another excel sheet object ex xlsheet2. It seem as COM looses track of the object and leaves a zombie process on the server.

  2. Using the open method associated with excel.workbooks also becomes difficult to close if you have multiple users accessing the same file. Use the Add method instead, it works just as good without locking the file. eg. xlBook = xlBooks.Add("C:\location\XlTemplate.xls")

  3. Place your garbage collection in a separate block or method after releasing the COM objects.

流殇 2024-07-13 21:42:26

COM 绝对不是一个好方法。 更具体地说,如果您正在处理 Web 环境,那么这是不行的...

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

  • ExcelPackage for OOXML 格式 (Office 2007)

  • .XLS 格式的 NPOI (Office 2003)

查看这些博客文章:

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

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

COM is definitely not a good way to go. More specifically, it's a no go if you're dealing with web environment...

I've used with success the following open source projects:

  • ExcelPackage for OOXML formats (Office 2007)

  • NPOI for .XLS format (Office 2003)

Take a look at these blog posts:

Creating Excel spreadsheets .XLS and .XLSX in C#

NPOI with Excel Table and dynamic Chart

一江春梦 2024-07-13 21:42:26

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

Workbook workbook = null;
Worksheet worksheet = null;

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

Worksheet additionalWorksheet = workbook.ActiveSheet;

This is what i used to add addtional worksheet

Workbook workbook = null;
Worksheet worksheet = null;

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

Worksheet additionalWorksheet = workbook.ActiveSheet;
朦胧时间 2024-07-13 21:42:26

我在 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);

I had a similar problem application-level add-in in VSTO, the exception HRESULT: 0x800A03EC when adding new sheet.

The error code 0x800A03EC (or -2146827284) means NAME_NOT_FOUND; in
other words, you've asked for something, and Excel can't find it.

Dominic Zukiewicz @ Excel error HRESULT: 0x800A03EC while trying to get range with cell's name

Then I finally realized ThisWorkbook triggered the exception. ActiveWorkbook went OK.

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文