ExcelQuicker模板功能的高级应用
这张薪资报表的需求原型是如下
(图1)
数据表Schema如下
Employee
Position
Salary
Bonus
这些信息是直接导出到上表中的前四列,另外:
(1) Insurance为Salary的18%;
(2) Tax的计算方式如个人所得税计算方式,阶梯型计算,以除去Insurance后的Salary加上Bonus为扣税基数
(3) Housing Income,住房公积金帐户,为Salary的14%
(4) Income=Salary+Bonus-Insurance-Tax+Housing Income
收入=基本工资+奖金-四金-税+住房公积金(虽然还有养老保险、医保等,但养老保险是几十年后的事情,医保太少,这里就不计入了^_^)
Employee-Income列表下方的:
Salary Expenditure为所有员工的工资+Bonus
Insurance Expenditure为公司为所有员工交纳的四金,为员工基本工资的44%
Total为上两项总和
由于四金和税的计算方式变化很快,根据用户需要,要做的很灵活,能够对需求的变更做出快速响应,甚至是现场解决,基于此,把四金和税的计算放在C#中硬编码明显不符合用户的需要。这套报表使用ExcelQuicker来实现,我选择了在模板上实现这些计算功能,以便在需求变更时,能够直接修改Excel模板文件。
我们知道在Excel中,是支持Formula公式的,对于一行Employee-Salary记录的设置或许不难,我简单描述如下,
(图2)
设置Insurance单元格”= C5* 0.18” (即基本工资的18%),以此类推可算出Tax和Housing Income,对于Tax的计算稍微复杂一些,这里不再详述,请参见Excel Web Sample6对应的模板文件。
这样就完成了一行的设置,看看我的模板行吧,
(图3)
(也就是说,只要在这行列中输入Salary、Bonus后,就会自动显示Insurance、Tax、Housing Income和Income数据。)
在实际编码中,我们会从数据库得到Employee,Position,Salary和Bonus四列的DataTable数据集,它对应于ExcelQuicker中的EQTable对象,EQTable的主要作用是将Datagrid或者DataTable导出到报表中,它有一个属性叫InsertMode,意为是否是插入模式,当设置为true时,它会将整个DataTable对象插入到Excel中指定的一行(其实现原理是不断的复制该行,使其行数与需要导出的行数一样时,再导出每一行数据)。
EQTable tableEmployee = new EQTable(dt, 5, 1);//dt是DataTable对象
tableEmployee.InsertMode = true;
上面语句的意思是将dt导出到Excel中的第5行第1列(该行为我们设置的上述模板行),使用插入模式。
这样,在导出时,ExcelQuicker会自动复制该模板行,并将其应用到DataTable数据集中的每一行数据,这样就完整的显示了整个Employee-Salary列表
我们注意到列表下方还有Salary Expenditure,Insurance Expenditure和Total,它们的定义这里不再累述。
在模板中,我设置
Salary Expenditure = SUM(C5:C6)+SUM(D5:D6)
Insurance Expenditure = SUM(C5:C6)*0.42
Total =SUM(B7,B8)
这里需要说明一下,为什么是设置C5:C6呢?
因为EQTable对象是插入到C5:C6,而Excel高级的地方在于,当有插入是,它会自动改变公式的计算范围,实际上对于上述的Salary Expenditure = SUM(C5:C6)+SUM(D5:D6)就会因为插入的EQTable而动态的改变公式为= SUM(C5:CRow)+SUM(D5:DRow),同样Insurance Expenditure,Total也会改变随着Employee-Salary数据的插入而改变公式。
在理解上上面的Excel模板原理后,我们来看看剩下的C#编码
DataTable dt = DataEntity.GetEmployees();
//Set excel template document
string strTemplate = "Sample6.xls";
//Get the output report file name from ExcelQuicker dynamically.
string strFileName = EQWebKit.GenerateAutoFileName();
//Construct EQApplication object
EQApplication objApp = new EQApplication(strFileName, strTemplate, true);
//Declare and set the name of worksheet
EQWorksheet objWS = new EQWorksheet("Salary");
//Set the report month-year
objWS.Add(new EQCell(DateTime.Now.ToString("yyyy-MM"), 2, 2));
//Construct EQTable object to output variable dt
EQTable tableEmployee = new EQTable(dt, 5, 1);
tableEmployee.InsertMode = true;
objWS.Add(tableEmployee);
objApp.Add(objWS);
objApp.Output();
这样,当我们的算法发生改变需要调整时,我们只需要调整Excel模板中的公式即可,完全没有必要编译工程,甚至稍微对Excel精通一点的客户也可以自己解决。
该示例可以在最新的ExcelQuicker Web Sample 6中找到
http://220.165.4.133:81/ControlAndSource/ExcelQuicker_Source.rar
http://220.165.4.133:81/ControlAndSource/ExcelQuicker_Web_Sample.rar