在日常工作中,经常需要根据数据库查询结果生成报告。这些报告往往需要在Excel模板中动态填充数据。本文将介绍一种方法,使得用户可以自由修改模板布局,同时还能根据查询结果动态填充单元格。
需要创建一个报告,用户可以修改模板,改变单元格的位置,删除单元格,或者添加新的单元格。这些新单元格将从查询结果中获取值。
希望能够定义一个单元格名称,使其与查询结果返回的列名称相匹配。这样,可以遍历查询结果中的每个列,并获取对应的Excel单元格,而不受其位置的影响。
例如,以下C#代码尝试实现这一功能,但不幸的是,它不起作用:
foreach (DataRow dataRow in dataTable.Rows)
{
foreach (DataColumn dataColumn in dataTable.Columns)
{
Excel.Range cell = ws.Cells[dataColumn.ColumnName];
cell.Value = dataRow[dataColumn.ColumnName];
}
}
为了实现想要的结果,必须使用Excel对象的Worksheet中的Evaluate()方法。这个方法接受一个字符串,并开始寻找匹配该字符串的单元格(或单元格范围)。如果成功找到,它将返回一个Excel.Range对象实例,即请求的单元格:
foreach (DataRow dataRow in dataTable.Rows)
{
foreach (DataColumn dataColumn in dataTable.Columns)
{
Excel.Range cell = ws.Evaluate(dataColumn.ColumnName);
if (cell != null) cell.Value = dataRow[dataColumn.ColumnName];
}
}
要正确运行上述代码,必须指定单元格名称。要做到这一点,右键单击单元格并选择“定义名称”菜单项,这将打开一个弹出窗口,可以在其中定义单元格名称。“范围”选项允许您选择名称的可见性:这个名字必须在选定的范围内是唯一的:在整个Excel文档(Workbook)中唯一,或者在工作表(worksheet)中唯一。一旦分配了单元格名称,您可以在左上角看到它。设置单元格名称后,仍然可以使用传统的坐标方式获取它,如下所示:
Excel.Worksheet workSheet = workbookReport.Worksheets[1];
Excel.Range cell = workSheet.Cells[1, 2];
要删除单元格名称或简单地更改它,您必须使用“公式”选项卡下的“名称管理器”菜单项,这将打开以下页面,报告所有单元格的名称,允许您删除或更改它们的名字。在列表中选择一个名称,您可以通过单击“编辑”或“删除”按钮来修改它。
从查询结果开始,加载到DataTable中:
希望创建一个类似于Excel表格的报告。需要一种类似于数据透视表的东西,因为有按行组织的记录。可以通过为每个单元格分配一个与月份相关的名称来轻松解决这个问题:对于每个单元格,可以分配一个名称,该名称与DataTable列的名称加上月份编号相同:
现在,可以使用以下代码为每个匹配datatable列名称的单元格自动设置值:
foreach (DataRow dataRow in dataTable.Rows)
{
DateTime period = Convert.ToDateTime(dataRow["PERIOD_START_DATE"]);
foreach (DataColumn dataColumn in dataTable.Columns)
{
string cellName = dataColumn.ColumnName + "_" + period.Month.ToString("d2");
Excel.Range cell = workSheet.Evaluate(cellName) as Excel.Range;
if (cell != null) cell.Value = value;
}
}