假设您已经在名为“customers”的报告设计文件中将表格定义为报告项目。顾名思义,该表格用于显示示例数据库中的所有客户。此外,它还有一个用于按照国家来对项目进行分组的表格组和一些列出了有界数据集属性的列。
当从表格中删除一列时,没有明确定义列宽度的其他列,它们的宽度被重新计算的结果并不令人满意。在这种情况下对宽度计算没有太多的控制权是通过在BIRT引擎使用之前操作rptdesign文件通过Design Engine API解决此问题的原因。
在主要解释之前,我想先介绍几种可用于操作报告文件并扩展BIRT的API:
借助Chart Engine API,你可以创建自定义图表。您需要了解那些必须被用于实现图表功能的程序接口,并遵循izs创建图表的严格规则。我猜测结果看起来像rpt设计人员使用的3选项卡作为图表设置。Chart Engine API的一个特点是它可以单独用于BIRT之外,这意味着您可以将它的库绑定到任何Java应用程序,而无需使用BIRT部分。
要创建自定义报告项目,您需要使用REAPI。报告项目的输出包括多种格式的图像,例如jpg,png和svg。由于与开发Chart Engine API相比,开发人员可以拥有更多自由操作的空间,因此您可以使用自定义项目开发图表。作为渲染库,如果输出是SVG,建议使用Java2D [ref] [ref] 或ApacheBatik [ref]库。
DEAPI用于创建或操作报告文件,如rptlibrary,rptdesign或rpttemplate。通过这个API,新的报表设计对象可以在运行时创建,或者在Java程序中给定的XML报表文件来转换为Java对象进行进一步的操作。本文描述了此API的一个实用案例。
在这种情况下,列的宽度可以从代码中看到的固定像素值。宽度的重新计算将在coldropedum之后执行。但是,我们要如何通过API删除一列表格呢?
步骤1 - 将rptdesign文件转换为Java对象
此解决方案的第一步是将当前的rptdesign文件转换为Java对象。因为需要进一步处理表格对象,所以需要在找到相应表格后进行对象转换。将建立的通用报告项目投射到TableHandle中可以完成这项工作。
... IReportRunnable design
... int posn
//步骤1 - 将XML文件信息转换为java对象
try {
design = engine.openReportDesign("report" + File.separator
+ "simpletable.rptdesign");
} catch (EngineException e) {
e.printStackTrace();
}
步骤2 - 找到表格
第二步是从rptdesign文件中找到正确的表格。ReportDesinger类中的“findElement” - 方法是为此目的而编写的。您可以通过查找,从中获取任何报告对象项作为自己的对象。这背后的想法类似于JavaScript在DOM对象上使用的“getById”方法,但这里使用的是name属性替代id作为唯一标识属性。
接下来的步骤是查找并删除列。在此之前,我们需要删除放置在列上的单元格。还需要从维度组中删除单元格。通过以下步骤可以达到此方法。
//步骤2 - 找到表格
TableHandle customerTable = (TableHandle)((ReportDesignHandle) design.getDesignHandle()).findElement("CustomerTable");
步骤3 - 查找并删除页眉和页脚
表组对象是表对象的一部分。该API有自己的方法通过Java对象来获取它
//步骤3 - 查找并删除页眉和页脚
for (int i = 0; i < customerTable.getGroups().getCount(); i++) {
TableGroupHandle tableGroupHandle = (TableGroupHandle) customerTable
.getGroups().get(i);
iterateAndDeleteFrom(tableGroupHandle.getHeader(), posn);
iterateAndDeleteFrom(tableGroupHandle.getFooter(), posn);
}
...
public static void iterateAndDeleteFrom(SlotHandle slothandle, int columnNumber) {
for (int j = 0; j < slothandle.getCount(); j++) {
dropCell(slothandle.get(j), columnNumber);
}
}
...
public static void dropCell(DesignElementHandle designElementHandle,
int posn) {
if (designElementHandle != null) {
if (designElementHandle instanceof RowHandle) {
RowHandle rowHandle = (RowHandle) designElementHandle;
if (rowHandle != null && rowHandle.getCells() != null
&& rowHandle.getCells().get(posn) != null) {
try {
rowHandle.getCells().get(posn).drop();
} catch (SemanticException e) {
e.printStackTrace();
}
}
}
}
}
步骤4 - 查找并删除标题,详细信息和页脚
//步骤4 - 查找并删除标题,详细信息和页脚
iterateAndDeleteFrom(customerTable.getHeader(), posn);
iterateAndDeleteFrom(customerTable.getDetail(), posn);
iterateAndDeleteFrom(customerTable.getFooter(), posn);
步骤5 - 删除列
接下来的步骤是通过“drop” - 方法查找和删除列
//步骤5 - 删除列
try {
if (customerTable.getColumns().get(posn) != null) {
customerTable.getColumns().get(posn).drop();
//Step 6 - recalculating the widths
recalculatingWidths(columnWidths, posn);
}
} catch (SemanticException e) {
e.printStackTrace();
}
步骤6 - 重新计算宽度
private static void recalculatingWidths(List<Integer> columnWidths, int posn) {
int distribution = 2;
if (posn == 0 || posn == 4) {
distribution = 3;
}
int additionalWidth = Math.round(columnWidths.get(posn) / distribution);
for (int i = 0; i < columnWidths.size(); i++) {
if (i != 0 && i != 4 && i != posn) {
columnWidths.set(i, columnWidths.get(i) + additionalWidth);
}
}
columnWidths.remove(posn);
}
步骤7 - 重新设置表格
在删除一列后,我们需要将新的宽度设置给其他的列。
for (int i = 0; i < columnWidths.size(); i++) {
if (customerTable.getColumns().get(i) != null) {
try {
customerTable.getColumns().get(i).setProperty("width", columnWidths.get(i) + "px");
} catch (SemanticException e) {
e.printStackTrace();
}
}
}
提示:这里显示的示例表具有简单的结构。当使用col-和row-span时,它会变得更加复杂。然后你必须知道哪些表单元素存在并且必须被删除。结构复杂可能会让人困惑。你可以通过尝试和错误来猜测结果,例如在更改应该删除的单元ID后创建报告,或者更好地调试遍历所有slothandler(如rowhandler和cellhandler)的代码并获取他们的ID来确切地看到哪些元素被操纵。对象处理程序的id对应于那些在单元格和任何其他XML元素的报告文件中作为XML属性找到的id。
在这个例子中,我使用了最新版本的eclipse和BIRT。对于这个例子,使用了三个文件,两个Java和rptdesign文件作为源文件。
许多报告任务可以通过使用API或脚本解决。当更改不那么复杂时,我更喜欢使用脚本,比如设置报告参数或数据集的颜色。当一个场景如本文所述时,API解决方案是一个不错的选择。当然你也可以使用脚本,但是整个逻辑应该在XML文件中实现,它将在运行或渲染任务中评估和执行,这是我想避免的。对于我来说,这种情况就是为使用BIRT编写报表设计文件准备的,并且应该在运行和渲染任务运行之前完成。
本文致力于通过Designe Engine API将表格用作eclipse BIRT rptdesign.xml文件的一部分进行操作。通过这个例子,你知道用这个API做什么以及它存在的原因。有了这个API,您可以通过Java访问rpt文件,这使得在运行时操作甚至创建这些文件提供了可能性。Thouse功能可用于实现复杂的预处理模块,这些模块可用于以下应用:
转换为当前报表设计对象。
这个例子的源码可以从https://github.com/kstojanovski/birt获得。使用designengineapi文件夹并启动EngineMain类的main方法以查看此处所述的处理。