需求背景: 在Excel的实际使用过程当中,动态生成报表、导出报表等都是最终用户经常使用的功能,使用常规的方式针对模板中具体的每一个单元格编程,动态的插入数据库中数据到Excel报表模板的每个单元格,就能够实现动态报表功能。可是不少时候用户报表的样式不是一成不变的,如某公司2015年的产品报表但愿在2014年的产品报表基础上,进行一些报表文本颜色、数据显示位置等方面的调整,2014年报表模板中“合计”数据原来位于单元格:A50,调整后,2015年报表模板中的“合计”数据单元格位于:A80。因为生成报表的程序代码是针对报表模板中的每个具体的单元格编程的,模板中数据项所在单元格的位置发生了改变,就须要同步修改填充数据的程序代码,原来给A50单元格填充数据的代码须要修改成操做A80单元格。如果每次Excel模板的调整都须要开发人员从新修改代码来实现的话,那就是一项永远不会完成的工做了。数据库
定义名称:Excel中有一个特别好的工具就是“定义名称”,顾名思义,就是为一个单元格或者区域定义一个名称,这样的话,咱们在以后的程序控制时能够很方便的用所定义的名称进行代码编写。编程
下面以给一个区域定义名称为例介绍一下Excel定义名称的操做步骤:工具
在PageOffice开发平台下,为了更好的在Excel模板中动态的、灵活的填充数据,专门开发了相应的程序接口,提供了完美解决上述问题的方法——openCellByDefinedName()和openTableByDefinedName()。在代码实现过程当中,经过灵活的运用这两个方法,便可完美的实如今不修改代码的状况下,知足最终用户自定义修改Excel模板的需求。spa
1、openCellByDefinedName和openTableByDefinedName的定义说明code
这两个方法用来实现操做用户自定义Excel模板中的。其中openCellByDefinedName()方法用来打开Excel中具备指定名称的单元格,并返回 Cell 对象。openTableByDefinedName()方法用来打开具备指定名称的单元格区域(通常为连续的多个单元格,在PageOffice的概念里称这块区域为一个Table),并返回 Table 对象。对象
Java方法:blog
openCellByDefinedName(String definedName); openTableByDefinedName(String definedName, int rowCount, int colCount, boolean autoIncrease);
ASP.NET方法:接口
public Cell OpenCellByDefinedName( string DefinedName ) public Table OpenTableByDefinedName( string DefinedName, int RowCount, int ColCount, bool AutoIncrease )
2、编写代码给Excel模板中的表格填充数据开发
Java部分代码以下:文档
Workbook workBook = new Workbook(); Sheet sheet = workBook.openSheet("Sheet1"); //定义Table对象,参数“report”就是Excel模板中定义的单元格区域的名称 Table table = sheet.openTableByDefinedName("report", 10, 5, false); //给区域中的单元格赋值 table.getDataFields().get(0).setValue("轮胎"); table.getDataFields().get(1).setValue("100"); table.getDataFields().get(2).setValue("120"); table.getDataFields().get(3).setValue("500"); table.getDataFields().get(4).setValue("120%"); table.nextRow(); //若是循环填充数据的话,执行下一行 table.close(); //定义单元格对象,参数“year”就是Excel模板中定义的单元格的名称 Cell cellYear = sheet.openCellByDefinedName("year"); Calendar c=new GregorianCalendar(); int year=c.get(Calendar.YEAR);//获取年份 cellYear.setValue(year + "年"); Cell cellName = sheet.openCellByDefinedName("name"); cellName.setValue("张三"); poCtrl1.setWriter(workBook); ……
ASP.NET部分代码以下:
PageOffice.ExcelWriter.Workbook wk = new PageOffice.ExcelWriter.Workbook(); PageOffice.ExcelWriter.Sheet sheet = wk.OpenSheet("Sheet1"); //定义Table对象,参数“report”就是Excel模板中定义的单元格区域的名称 PageOffice.ExcelWriter.Table table = sheet.OpenTableByDefinedName("report", 10, 5, false); //给区域中的单元格赋值 table.DataFields[0].Value = "轮胎"; table.DataFields[1].Value = "100"; table.DataFields[2].Value = "120"; table.DataFields[3].Value = "500"; table.DataFields[4].Value = "120%"; table.NextRow();//若是循环填充数据的话,执行下一行 table.Close(); //定义单元格对象,参数“year”就是Excel模板中定义的单元格的名称 PageOffice.ExcelWriter.Cell cellYear = sheet.OpenCellByDefinedName("year"); cellYear.Value="2015年"; PageOffice.ExcelWriter.Cell cellName = sheet.OpenCellByDefinedName("name"); cellName.Value = "张三"; PageOfficeCtrl1.SetWriter(wk);// 注意不要忘记此代码,若是缺乏此句代码,不会赋值成功。 ……
在填充数据的代码不作任何修改的状况下,打开两个不一样的Excel模板并填充数据的效果:
能够看出在不需修改代码的状况下,用户能够根据实际需求自行定义Excel模板。只要Excel模板中有代码中所涉及到的定义名称(如“report”、“year”、“name”),那么不管定义了该名称的单元格区域的位置、大小怎么变化,程序都会自动在变化后的位置填充数据。而若是程序代码中涉及到的定义名称在Excel模板中不存在的话,那么对该对象的全部操做将被自动忽略,打开的Excel文档中也不会再显示相应的信息。
openCellByDefinedName()和openTableByDefinedName()方法相比于openCell()和openTable()方法的具体优点在于:
而若是使用openTableByDefinedName()来分别打开这两个Table,且设置表格也会按实际数据行数自动扩展,当Table1自动扩展后数据行数为12行,填充范围为第4-15行时,Table2的起始位置将再也不是固定不变的,Table2的起始位置由原来的第13行变成了第21行,填充范围为第21-24行。这样一来,先后两个Table的数据就不会发生重叠覆盖的现象了,填充数据后的效果如图3所示。
当Excel模板数据内容不变,样式(数据的位置、大小等)改变时, openCell()和openTable()必需要修改其方法中的参数,即操做的单元格和Table对象,不然显示或提交的数据时就可能发生错乱;而openCellByDefinedName()和openTableByDefinedName()方法只要提早在模板中定义好要填充数据的单元格区域的名称,那么不管数据的位置、大小怎么变化,都不需修改代码就能将数据准确填充到相应的位置,并准确获取到提交的数据。
还能够实现用户可根据实际状况和实际需求自行便捷、简单地定义Excel模板,而无需每次更改模板时都要联系程序的开发者更改代码。PageOffice开发平台以其更好的灵活性和适应性,充分的知足了最终用户对系统功能的要求,极大的减小了程序开发者对系统后期的维护量。
详细请参考PageOffice开发包中Samples4示例: 2、3三、给Excel模板中定义了名称的一块区域赋值(专业版、企业版)