65.9K
CodeProject 正在变化。 阅读更多。
Home

带列设计器的 Excel 生成器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (25投票s)

2009年10月8日

CPOL

2分钟阅读

viewsIcon

64616

downloadIcon

2224

一个完全可定制和可扩展的 C# 库,可以轻松地为给定的 DataSet 生成 Excel 文件,并支持列布局设计。

引言

这是一个完全可定制和可扩展的 C# 库,使用 .NET Framework 3.5,可以通过传递 ADO.NET DataView 对象轻松创建 Excel 文件。 在某些情况下,您可能需要在不使用 MS Office 组件的情况下生成 MS Excel 格式的报表。 这种场景在许多项目的生产环境中很常见。

此外,此库将允许您自由地为给定的 DataSet 设计自己的列布局。 列布局设计器是一个 WinForms 应用程序。 具有导出功能的核心库可以在 WinForms 和 ASP.NET Web 应用程序中使用。 在运行时,如果它找不到给定报表的任何布局信息,它将导出所有列的数据。

类图

使用代码

  • 打开 Visual Studio 2008 IDE 并创建一个名为“SpreadsheetDemo”的 C# Windows 应用程序项目。
  • Form1 重命名为 TestReport
  • 添加对库的引用。
  • 将以下控件粘贴到 TestReport 窗体中
  • 类型 名称 标题
    Label lable1 国家
    ComboBox comboCountry
    Button btnGo GO
    DataGridView DataGridView1
    Label lblStatus 状态
    Button btnDesign 设计
    Button btnGenerateExcel 导出到 Excel
    Button btnCancel 取消

    该窗体应在 Visual Studio 设计视图中看起来像下面的屏幕

  • 在窗体的声明部分添加以下行
  • // variables
    private Spreadsheet spreadsheet  = null;
    private string reportId = string.Empty;
    private string reportTitle = string.Empty;
    private string reportConfigFile =  string.Empty;
    private string outputFile = string.Empty;
  • TestReport_Load 事件中添加以下行
  • // load the country data into combo box
    private void TestReport_Load(object sender, System.EventArgs e)
    {
        PrepareDataset();
    
        spreadsheet = new Spreadsheet();
        spreadsheet.OnProgress+= 
          new sommon.Spreadsheet.Spreadsheet.StatusHandler(xmlSheet_OnProgress);
        spreadsheet.OnError+=
          new sommon.Spreadsheet.Spreadsheet.StatusHandler(xmlSheet_OnError);
        spreadsheet.OnFinish+=
          new sommon.Spreadsheet.Spreadsheet.StatusHandler(xmlSheet_OnFinish);
    }
  • 添加以下方法
  • private void  PrepareDataset()
    {
        if(!File.Exists("Customers.xml"))
        {
            MessageBox.Show("Cannot find the Customers.xml file.", 
                            this.Text, MessageBoxButtons.OK, 
                            MessageBoxIcon.Exclamation );
            this.Close();
            return;
        }
    
        // prepare the dataset 
        reportDataSet.ReadXml("Customers.xml");
        reportDataSet.Tables[0].TableName = "Customers";
        reportDataSet.Tables[1].TableName = "Country";
    
        // set the combo box for country selection
        comboCountry.DataSource = reportDataSet.Tables["Country"].DefaultView;
        comboCountry.DisplayMember = "Country";
        comboCountry.ValueMember = "Country";
    }
  • 在“Go”按钮的 Click 事件中添加以下行
  • private void btnGo_Click(object sender, EventArgs e)
    {
       // Prepare dataset and bind the datasource to grid
        InitializeReportData();
    }
  • 添加以下方法
  • private void InitializeReportData()
    {
        // here you can build the dataset as per your requirement.
        // In this example we will simply filter the existing dataset
        // based on the country selection.
        DataView reportView = null;
        string country = comboCountry.Text;
        lblStatus.Text = "";
        if (country == "All")
             reportView = reportDataSet.Tables["Customers"].DefaultView;
        else
        {
            string rowFilter = "Country = '" + country + "'";
                               lblStatus.Text = "Filter: " +  rowFilter; 
            reportView = new DataView(reportDataSet.Tables["Customers"], 
                 rowFilter,"CompanyName", DataViewRowState.CurrentRows);
        }
    
        // assign reportView object to spreadsheet class
        spreadsheet.DataView = reportView;
    
        // bind the datasource into data grid
        dataGridView1.DataSource = reportView;
    
    }
  • 在“导出到 Excel”按钮的 Click 事件中添加以下行
  • private void btnGenerateExcel_Click(object sender, System.EventArgs e)
    {
        if(!ValidateAll())
        return;
        EnableButton(false);
        GenerateReport(OutputType.Excel);
        EnableButton(true);
    }
  • 添加以下方法
  • private void EnableButton(bool enable)
    {
        btnDesign.Enabled = enable;
        btnGenerateExcel.Enabled = enable;
        btnGenerateHtml.Enabled = enable;
    }
    
    private void GenerateReport(OutputType outputType)
    {
        reportId = "CustomerList";
        reportTitle = "List of Customer";
        reportConfigFile =  "Report.config";
        outputFile = Application.StartupPath + @"\"+ reportTitle;
        try
        {
            this.Cursor = Cursors.WaitCursor;
            // setting output file
            spreadsheet.ExportFile = outputFile;
    
            // Initialize the ColumnStyles item
            spreadsheet.InitializeReportColumns(reportConfigFile,reportId);
    
            // initialize the report data based on specified search criteria 
            InitializeReportData();
    
            if(spreadsheet.DataView.Count==0)
            {
                this.Cursor = Cursors.Default;
                MessageBox.Show("No Records Found.", 
                  this.Text,MessageBoxButtons.OK, 
                  MessageBoxIcon.Information,MessageBoxDefaultButton.Button1); 
                return;
            }
            spreadsheet.GenerateWorkSheet(outputType);
            this.Cursor = Cursors.Default;
        }
        catch(Exception ex)
        {
            this.Cursor = Cursors.Default;
            MessageBox.Show("Unable to generate report.\n"+ 
              ex.Message,this.Text,MessageBoxButtons.OK, 
              MessageBoxIcon.Error,MessageBoxDefaultButton.Button1); 
        }
    }
    
    private bool ValidateAll()
    {
        // for a demo purpose I have hard coded the return value 
        // as true but you can implement your own logic here.
        return true;
    }
  • 将以下行添加到“设计”按钮的 Click 事件
  • private void btnDesign_Click(object sender, System.EventArgs e)
    {
        reportId = "CustomerList";
        reportTitle = "List of Customer";
        reportConfigFile =  "Report.config";
        spreadsheet.InitializeReportColumns(reportConfigFile,reportId);
        // Prepare dataset
        InitializeReportData();
        ReportDesigner frm = 
           new ReportDesigner(reportConfigFile, reportId,spreadsheet);
        frm.ShowDialog();
    }
  • 按 F5 运行窗体。

示例客户报表输入屏幕

如何打开列布局设计器窗口

string reportId = "CustomerList";
string reportTitle = "List of Customer";
string reportConfigFile =  "Report.config";
Spreadsheet spreadsheet  = new Spreadsheet();

// Initialize the ColumnStyles item
spreadsheet.InitializeReportColumns(reportConfigFile,reportId);

// initialize the report data based on specified search criteria 
InitializeReportData();

// create instance of ReportDesigner class
ReportDesigner frm = new ReportDesigner(reportConfigFile, reportId,spreadsheet);

// show the designer window
frm.ShowDialog();

客户报表的列设计器屏幕

如何调用导出到 Excel 任务

reportId = "CustomerList";
reportTitle = "List of Customer";
reportConfigFile =  "Report.config";
outputFile = Application.StartupPath + @"\"+ reportTitle;
try
{
    this.Cursor = Cursors.WaitCursor;
    // setting output file
    spreadsheet.ExportFile = outputFile;
    // Initialize the ColumnStyles item
    spreadsheet.InitializeReportColumns(reportConfigFile,reportId);
    // initialize the report data based on specified search criteria 
    InitializeReportData();
    if(spreadsheet.DataView.Count==0)
    {
        this.Cursor = Cursors.Default;
        MessageBox.Show("No Records Found.", 
          this.Text,MessageBoxButtons.OK,MessageBoxIcon.Information,
          MessageBoxDefaultButton.Button1); 
        return;
    }
    spreadsheet.GenerateWorkSheet(outputType);
    this.Cursor = Cursors.Default;
}
catch(Exception ex)
{
    this.Cursor = Cursors.Default;
    MessageBox.Show("Unable to generate report.\n"+ ex.Message, 
      this.Text,MessageBoxButtons.OK,MessageBoxIcon.Error, 
      MessageBoxDefaultButton.Button1);
}

客户报表 (Excel)

Excel 生成器的工作原理

基本上,它创建一个 XML 电子表格文件作为输出。 GenerateWorkSheet 方法负责创建输出文件。 生成输出文件时遵循以下步骤

  • 声明一个 StringBuilder 类型的变量并将以下结果添加到其中
    • 创建一个 Excel 标头字符串
    • 创建所有样式字符串
    • 创建一个工作表选项字符串(仅需要一次)
    • 创建第一个工作表标签字符串
    • 创建表标签
    • 创建表标题样式标签
    • 循环遍历 DataView 并为每一行、每一列创建一个 Excel 兼容标签
    • 关闭 Workbook 标签
  • 将字符串保存在输出文件中。
  • 通知调用者有关状态。

结论

使用上面的库,您可以在几分钟内轻松生成 Excel 文件,从而提高您的效率和生产力。 此库使您可以从 MS Office Primary Interop Assemblies (PIA) 中解放出来,这些程序集体积庞大、内存消耗高且依赖于系统。

© . All rights reserved.