Excel文档是否可以作为字节加载到内存,填充和返回?

时间:2012-02-07 19:27:40

标签: c# .net excel export-to-excel

之前我曾使用Excel Interop打开Excel文件,向其中写入一些数据并保存。像这样:

public void WriteAFile()
{
    var xlApp = new Excel.ApplicationClass();
    var xlWorkbook = xlApp.Workbooks.Add(Missing.Value);
    var xlWorksheet = (Excel.Worksheet)xlWorkbook.Worksheets.get_Item(1);

    xlWorksheet.Name = "Some Name";

    // Write some contrived data
    for (var i = 0; i < 10; i++)
    {
        xlWorksheet.Cells[i + 1, 1] = i;
        xlWorksheet.Cells[i + 1, 2] = i + 1;
        //... and so on...
    }
    //... and so on...

    // Save the file
    xlWorkbook.SaveAs(
      @"",
      Excel.XlFileFormat.xlWorkbookNormal,
      Missing.Value,
      Missing.Value,
      false,
      false,
      Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
      Excel.XlSaveConflictResolution.xlLocalSessionChanges,
      false,
      Missing.Value,
      Missing.Value,
      Missing.Value
    );

    xlWorkbook.Close(true, Missing.Value, Missing.Value);
    xlApp.Quit();

    // release other resources, etc.
}

这适用于写入本地工作站上的文件的应用程序。但是,现在我正在开发一个需要将文件返回给用户的Web应用程序。问题是无法修改文件系统上的文件。所以我需要做的是:

  1. 将已知的Excel文件加载到内存中(请注意该文件为.xlsm并包含宏代码,下载后将在用户的工作站上运行。)
  2. 将已知数据写入文件中的已知位置(为了参数,将某些数值应用于工作表99中的前几个单元格)。
  3. 通过Web应用程序从内存中流式传输该文件(流式传输部分非常简单,它首先使字节数组对我来说变得更加棘手)。
  4. 我用Google搜索过,但没有发现任何东西。基本上只是我在上面的代码中执行的操作的说明和示例。使用COM互操作时也不足为奇,我上面的代码(很老)和我在网上找到的其他代码都有点过时了。我们使用的是.NET 4.0,因此任何可用的东西都适合我们。

    我在上面的代码中完全展示了我使用COM的经验。如果可能的话,我宁愿不使用COM。但是现在我只是难以起步。任何人都能指出我正确的方向吗?也许参考一些在这里特别有用的类或方法?感谢。

    PS 让我感到害怕的另一件事是Web服务器上需要Excel,以及Excel应用程序在Web服务器的控制台上打开并挂在用户身上的可能性 - 某种错误的错误。所以任何建议都非常感谢。

4 个答案:

答案 0 :(得分:3)

我最终使用了ClosedXML库。 (OpenXML本身就是......笨重。)作为打开文件,编写数据并返回字节数组的简单概念证明:

public byte[] GetExcelApplication(Guid sessionKey)
{
    // Input checking

    using (var workbook = new XLWorkbook(_excelFile))
    {
        var worksheets = workbook.Worksheets.Where(w => w.Name == "Session Key");
        if (worksheets.Count() < 1)
            throw new Exception("Excel file does not contain a worksheet called: Session Key");
        if (worksheets.Count() > 1)
            throw new Exception("Excel file contains multiple worksheets called: Session Key");

        var worksheet = worksheets.Single();
        var cell = worksheet.Cell("A1").Value = sessionKey.ToString();

        using (var ms = new MemoryStream())
        {
            workbook.SaveAs(ms);
            return ms.ToArray();
        }
    }
}

答案 1 :(得分:1)

使用c#4.0 COM应该会更容易,因为你可以使用动态。但它仍然是COM。 我使用了一个名为aspose cells的第三方产品。我不是为他们工作,但我真的很喜欢这个产品(即使它不是免费的)。这在处理excel时省去了很多麻烦。

答案 2 :(得分:0)

使用与COM类似的操作我将生成的Excel工作簿保存到临时文件夹,将其发送然后删除。不使用COM对我来说不是一个选项,因为工作簿还需要生成数据透视表和图表。

答案 3 :(得分:0)

老派,但是I wrote this a long time ago可以动态构建工作簿并将其导出。也许它可以让你走上正轨?