【问题标题】:Excel file with multiple sheets from SSRS Reports带有来自 SSRS 报告的多张工作表的 Excel 文件
【发布时间】:2009-12-07 22:38:14
【问题描述】:

假设我有 3 个字节数组,每个代表一个 .xls 文件。我如何将它们组合成一个带有 3 张纸的 xls 文件。 SSRS 报告非常丰富,并且包含图表 spoledb 不是一种选择。

性能并不重要,因此如果需要,我可以将它们保存到磁盘,作为最后的手段,我什至可以使用 excel 宏(如果我知道该怎么做的话)。我尝试使用 microsodt.office.interop.excel 但我只能设法将新工作表添加到文件中,我无法添加现有工作表。

任何帮助将不胜感激。

【问题讨论】:

  • @Paul 我对您的工作流程有点困惑,您正在流式传输的 3 个 xls 文件中的字节数组在哪里? SSRS 适合在哪里?
  • bvyte arays 在内存中,理想情况下我会将它们组合在内存中,但我不确定这是否可行。字节数组来自以编程方式导出 ssrs 报告。
  • @Paul - 看起来乔伊的回答应该这样做。

标签: c# .net excel reporting-services office-interop


【解决方案1】:

在我看来,您只需要一种以编程方式将字节数组写入工作簿的方法。
这是一种将 byte[] 作为工作表写入特定 WorkBook 的方法:

public static void WriteToSheet(string targetBookPath, byte[] fileBytes)
{
    try {
        
        object x = Type.Missing;
        
        //Create a temp file to encapsulate Byte array
        string tmpPath = IO.Path.ChangeExtension(IO.Path.GetTempFileName(), ".xls");
        My.Computer.FileSystem.WriteAllBytes(tmpPath, fileBytes, false);
        
        //Start Excel Application (COM)
        Excel.Application xlApp = new Excel.Application();
        
        //Open target book
        Excel.Workbook targetBook = xlApp.Workbooks.Open(targetBookPath, x, x, x, x, x, x, x, x, x, 
        x, x, x, x, x);
        
        //Open temp file with Excel Interop
        Excel.Workbook sourceBook = xlApp.Workbooks.Open(tmpPath, x, x, x, x, x, x, x, x, x, 
        x, x, x, x, x);
        
        //Get a reference to the desired sheet 
        Excel.Worksheet sourceSheet = (Excel.Worksheet)sourceBook.Worksheets(1);
        
        //Copy the temp sheet into WorkBook specified as "Before" parameter
        Excel.Worksheet targetBefore = (Excel.Worksheet)targetBook.Worksheets(1);
        try {
            sourceSheet.Copy(targetBefore, x);
            
            //Save and Close
            sourceBook.Close(false, x, x);
            targetBook.Close(true, x, x);
            xlApp.Workbooks.Close();
                
            xlApp.Quit();
        }
        catch (Exception ex) {
            Debug.Fail(ex.ToString);
        }
        finally {
            
            //Release COM objects
            //   Source
            DESTROY(sourceSheet);
            DESTROY(sourceBook);
            
            //   Target
            DESTROY(targetBefore);
            DESTROY(targetBook);
            
            //   App
                
            DESTROY(xlApp);
        }
        
        //Kill the temp file
            
        My.Computer.FileSystem.DeleteFile(tmpPath);
    }
    catch (Exception ex) {
        Debug.Fail(ex.ToString);
    }
}

DESTROY 方法释放 COM 的东西,这很重要:

public static void DESTROY(object o)
{
    try {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
    }
    catch (Exception ex) {
        Debug.Fail(ex.ToString);
        ErrorLog.Write(ex.ToString);
    }
    finally {
        o = null;
    }
}

如果我理解正确,您需要做的就是:

  1. 创建一个新的工作簿
  2. 循环遍历字节数组
  3. 为每个 Byte 数组调用 WriteToSheet

【讨论】:

  • 这看起来不错,我到办公室去看看。
  • 我编辑了代码以便更好地使用 COM。如果您不以“应得的”尊重对待 COM,您可能会遇到一些令人沮丧的错误。这对我有用!
  • 我在这里取得了进展,我认为我需要对 COM 对象进行一些编组,因为我无法删除 tmp 文件 atm。
  • Any1 知道如何抑制“您要保存 xyx.xls”对话框吗?
  • @Paul - 有两种方法可以禁止保存更改对话框。首先,如果要保存它,请在关闭之前在工作簿上调用 Save 或 SaveAs。如果您不想保存,请在 Excel 应用程序对象上设置 DisplayAlerts = false (xlApp.DisplayAlerts = false)
【解决方案2】:

是否必须将工作表作为单独的报告生成然后合并? SoftArtisans OfficeWriter 可以以编程方式组合来自字节数组的多个电子表格,但我们也有SSRS integration,它允许您直接创建多表报告。使用 OfficeWriter Designer Excel 加载项,您可以直接在 Excel 中设计一个包含 3 个工作表的报告并将其发布到 SSRS。

免责声明:我为 SoftArtisans 工作

【讨论】:

    【解决方案3】:

    SpreadsheetGear for .NET可以做到:

    • 使用 SpreadsheetGear.Factory.GetWorkbookSet().Workbooks.OpenFromMemory(byte[]) 从字节数组加载源工作簿。根据字节数组的来源,您可能更喜欢使用 GetWorkbookSet().Workbooks.OpenFromStream(System.IO.Stream stream) 从流中直接加载。
    • 使用 Factory.GetWorkbook() 创建新的目标工作簿或使用 Factory.GetWorkbook(string filename) 打开模板目标工作簿。
    • 使用 SpreadsheetGear.ISheet.CopyAfter 或 ISheet.CopyBefore 从每个源工作簿复制工作表。
    • 使用 IWorkbook.SaveAs(string filename, FileFormat fileFormat)、IWorkbook.SaveToMemory(FileFormat fileFormat) 或 IWorkbook.SaveToStream(System.IO.Stream stream, FileFormat fileFormat) 保存目标工作簿。

    您可以查看大量实时 ASP.NET 示例here 并下载免费试用版here

    在我们的 Excel 报告示例页面here 上,有一个“带图表的工作表到多个带图表的工作表”示例可能会有所帮助。

    免责声明:我拥有 SpreadsheetGear LLC

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多