带列设计器的 Excel 生成器






4.56/5 (25投票s)
一个完全可定制和可扩展的 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";
}
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;
}
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();
}
示例客户报表输入屏幕
如何打开列布局设计器窗口
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) 中解放出来,这些程序集体积庞大、内存消耗高且依赖于系统。