PageOffice ZoomSeal ZDFOffice 技术支持 合作伙伴 会员登录 如何购买

PageOffice自定义Excel模板/PageOffice定义名称的用法

      Excel的实际使用过程中,动态生成报表、导出报表等都是最终用户常常使用的功能,使用常规的方式针对模板中具体的每个单元格编程,动态的插入数据库中数据到Excel报表模板的每一个单元格,就可以实现动态报表功能。但是很多时候用户报表的样式不是一成不变的,如某公司2015年的产品报表希望在2014年的产品报表基础上,进行一些报表文本颜色、数据显示位置等方面的调整,2014年报表模板中“合计”数据原来位于单元格:A50,调整后,2015年报表模板中的“合计”数据单元格位于:A80。由于生成报表的程序代码是针对报表模板中的每一个具体的单元格编程的,模板中数据项所在单元格的位置发生了改变,就需要同步修改填充数据的程序代码,原来给A50单元格填充数据的代码需要修改为操作A80单元格。若是每次Excel模板的调整都需要开发人员重新修改代码来实现的话,那就是一项永远不会完成的工作了。不过不用担心,PageOffice开发平台就专门针对这一问题给出了解决方案。

 

PageOffice开发平台下,为了更好的在Excel模板中动态的、灵活的填充数据,专门开发了相应的程序接口,提供了完美解决上述问题的方法——openCellByDefinedName()openTableByDefinedName()。在代码实现过程中,通过灵活的运用这两个方法,即可完美的实现在不修改代码的情况下,满足最终用户自定义修改Excel模板的需求。

一、openCellByDefinedNameopenTableByDefinedName的定义说明

PageOffice提供了openCellByDefinedName(java.lang.String definedName)openTableByDefinedName(java.lang.String definedName, int rowCount, int colCount, boolean autoIncrease)(以Java语言为例)两个方法,来实现用户自定义Excel模板。其中openCellByDefinedName()方法用来打开Excel中具有指定名称(Excel中定义的名称)的单元格,并返回 Cell 对象。openTableByDefinedName()方法用来打开具有指定名称的单元格区域(一般为连续的多个单元格,在PageOffice的概念里称这块区域为一个Table),并返回 Table 对象。这两个方法具体的使用说明和介绍可查看PageOffice服务器端的开发帮助,里面有详细的说明和介绍,此处不再赘述。

二、openCellByDefinedNameopenTableByDefinedName的优势

 

PageOffice开发平台下也还有其他的打开CellTable的方法,如openCell(java.lang.String cellAddress)——打开指定的单元格,并返回 Cell 对象,openTable(java.lang.String rangeAddress)——打开指定的单元格区域,并返回 Table 对象。

从功能上看openCellByDefinedName()openCell()都是用来打开单元格的,openTableByDefinedName()openTable()都是用来打开Table的。但其中,openCell()openTable()是用来打开Excel模板中固定位置的单元格和Table的,而openCellByDefinedName()openTableByDefinedName()方法则可以打开Excel模板中位置不固定的单元格和Table。当打开的Excel模板完全固定不变时,使用两者均可,代码实现的效果相同;可是一旦Excel模板会发生变化时,就会发现两者之间实现的效果区别很大了。

openCellByDefinedName()openTableByDefinedName()方法相比于openCell()openTable()方法的具体优势在于:

 

1,可以避免同一个Excel工作薄中有多个表格时,上面的表格数据行增长后与下面的表格数据出现互相覆盖的问题。

假如在一个Excel模板的同一个工作薄中,使用openTable(rangeAddress)方法打开两个不同的Table,分别为Table1(数据填充范围:第4-7行,行数:4行)、Table2(数据填充范围:第13-16行)。而要动态填充到Table1里的实际数据行数为12行,超过了指定的单元格区域行数,且Table1设置了默认自动扩展单元格行数到实际大小,并且给新的单元格数据行应用 RangeAddress 指定的单元格区域的格式,那么数据填充完后,Table1的实际填充范围应该是第4-15行;然而由于Table2的起始填充位置是不变的,还是从第13行开始填充,这样一来,Table2填充的数据就会覆盖Table113-15行的数据,即发生数据重叠覆盖的现象。

 

实例参考:二、33Excel模板中定义了名称的一块区域赋值(专业版、企业版) 中的

3、演示openTableopenTableByDefinedName方法填充数据到相同Excel模板,在动态填充的数据按实际数据行数自动扩展的情况下,生成的文件显示出不同的效果

 

如数据填充前的模板如图1所示,数据填充至模板后可能就会出现如图2所示的现象:

 

1数据填充前Excel模板

 

2数据填充后发生数据重叠覆盖的现象

 

如果使用openTableByDefinedName()来分别打开这两个Table,且设置表格也会按实际数据行数自动扩展,当Table1自动扩展后数据行数为12行,填充范围为第4-15时,Table2的起始位置将不再是固定不变的,Table2的起始位置由原来的第13行变成了第21行,填充范围为第21-24行。这样一来,前后两个Table的数据就不会发生重叠覆盖的现象了,填充数据后的效果如图3所示。

 

3

 

2、当Excel模板数据内容不变,样式(数据的位置、大小等)改变时, openCell()openTable()必须要修改其方法中的参数,即操作的单元格和Table对象,否则显示或提交的数据时就可能发生错乱;而openCellByDefinedName()openTableByDefinedName()方法只要提前在模板中定义好要填充数据的单元格区域的名称,那么无论数据的位置、大小怎么变化,都不需修改代码就能将数据准确填充到相应的位置,并准确获取到提交的数据。

要想使用openCellByDefinedName()openTableByDefinedName()方法,需先在Excel模板中定义好要填充数据的单元格区域的名称。所以首先需要了解如何给单元格区域定义名称。Excel自身有一个“定义名称”的功能,可以给任意的一个单元格或一块区域定义一个名称。具体的操作如下:

在本地磁盘上打开一个Excel文件模板,选中需要填充数据的单元格区域,如B4:F13,如图5所示;

 

5

1)在选中的单元格区域上,“右击→定义名称”(或者点击Office工具栏上的“公式→定义名称“),在名称输入框中输入该区域的名称,如命名为“report”,点击“确定”按钮即可。如图6、图7所示。

 

6

 

7

2)若是需要删除、修改定义好的单元格区域,可点击Office工具栏上的“公式→名称管理器“来对名称进行管理,图8所示。

 

8

下面就以一个具体的示例来进一步详细的介绍一下如何使用这两个方法解决Excel模板样式变动问题。

实例参考:二、33给Excel模板中定义了名称的一块区域赋值(专业版、企业版) 中的

2、演示如何在不修改代码的情况下,填充数据到用户自定义的两个不同的Excel模板,显示出不同的效果

1、 定义Excel模板一

依照上面定义单元格名称的方法,在本地磁盘上打开一个Excel文件“temp1.xls”作为模板一,分别在 “temp1.xls”中选中“B4:F13”区域定义名称为“report”、选中单元格“C2“定义名称为“year”,选中单元格“F15”定义名称为“name”。依次类推,定义好模板一。

2、 定义Excel模板二

1) 在本地磁盘上再打开一个Excel文件“temp2.xls”作为模板二。

2) 在模板二中再次给单元格区域定义名称。分别将选中的区域“C5:G24”命名为“report”;单元格“C3”(由多个单元格合并而成)命名为“year”;再假如模板一中定义名称为“name”的单元格在模板二中不需要显示该数据,那么就无需再定义该名称。在程序运行时当“openTableByDefinedName()”和“openCellByDefinedName()”方法找不到指定名称的单元格或区域时,对该对象的所有操作将自动全部被忽略。

3、 编写代码实现在线打开Excel模板并填充数据

下面以Java代码为例(C#PHP分别有相应的示例),部分代码如下:

.......

    

  1. //定义Workbook对象 
  2. Workbook workBook = new Workbook(); 
  3. //定义Sheet对象,"Sheet1"是打开的Excel表单的名称 
  4. Sheet sheet = workBook.openSheet("Sheet1"); 
  5. //定义Table对象,参数“report”就是Excel模板中定义的单元格区域的名称 
  6. Table table = sheet.openTableByDefinedName("report"105false); 
  7. //给区域中的单元格赋值 
  8. table.getDataFields().get(0).setValue("轮胎"); 
  9. table.getDataFields().get(1).setValue("100"); 
  10. table.getDataFields().get(2).setValue("120"); 
  11. table.getDataFields().get(3).setValue("500"); 
  12. table.getDataFields().get(4).setValue("120%"); 
  13. //循环下一行 
  14. table.nextRow(); 
  15. //关闭table对象 
  16. table.close(); 
  17.  
  18. //定义单元格对象,参数“year”就是Excel模板中定义的单元格的名称 
  19. Cell cellYear = sheet.openCellByDefinedName("year"); 
  20. // 给单元格赋值 
  21. Calendar c=new GregorianCalendar(); 
  22. int year=c.get(Calendar.YEAR);//获取年份 
  23. cellYear.setValue(year + "年"); 
  24.  
  25. Cell cellName = sheet.openCellByDefinedName("name"); 
  26. cellName.setValue("张三"); 
  27. poCtrl1.setWriter(workBook); 

……

在不修改上述代码的情况下,填充数据到模板一、模板二的具体实现效果如下:

  打开模板一并填充数据,实现的效果如图9所示

 

9

 

 

  打开模板二并填充数据,实现的效果如图10所示:

 

10

综上所述,可以看出在不需修改代码的情况下,用户可以根据实际需求自行定义Excel模板。只要Excel模板中有代码中所涉及到的定义名称(如“report”、“year”、“name”),那么无论定义了该名称的单元格区域的位置、大小怎么变化,程序都会自动在变化后的位置填充数据;而如果程序代码中涉及到的定义名称在Excel模板中不存在的话,那么对该对象的所有操作将被自动忽略,打开的Excel文档中也不会再显示相应的信息。

三、总结

针对Excel文档,在PageOffice开发平台下,可以完美的解决同一个工作簿中上面的表格数据行增长后与下面的表格数据出现互相覆盖的问题,还可以实现用户可根据实际情况和实际需求自行便捷、简单地定义Excel模板,而无需每次更改模板时都要联系程序的开发者更改代码。PageOffice开发平台以其更好的灵活性和适应性,充分的满足了最终用户对系统功能的要求,极大的减少了程序开发者对系统后期的维护量。

另外顺便提一下Word文档,在PageOffice开发平台下,可通过数据区域(DataRegion)和数据标签(DataTag)的帮助实现自定义Word模板,使最终用户也可以根据需求变化重新编辑定义Word模板,而不再每次变更Word模板都需要程序开发者修改一次代码。关于用户如何实现自定义Word模板并动态填充生成Word文档的功能,请您参考Samples示例包综合演示中的第12个示例“三、12、实现用户自定义Word模板动态生成文件(专业版、企业版)”。

返回顶部 在线购买 下载中心 400-6600-770 2692936468