使用Jasper Reports是否可以动态生成报告,而不需要为每个报告生成一个jasper文件?

9
我需要根据动态提供的各种参数生成报告。在某些情况下,这些参数可能为空。
例如,从表格“人员”中,包含“ID”,“姓名”,“年龄”,“性别”和“婚姻状况”等字段,我需要生成关于“30岁已婚男性”的报告。有时,需要获取“已婚女性”,而不考虑年龄。如果我在两种情况下都使用相同的jasper,则第二种情况下年龄约束将为空。是否有任何方法来管理这种情况?
此外,是否可以动态指定要在报告中生成哪些字段?

您可以根据参数轻松构建查询。您是否想动态设置列的数量和顺序? - Alex K
@Alex K但是当任何一个参数变为空值时(例如在我的问题的第二种情况中不应考虑年龄等约束条件),将无法获取任何记录。此外,我想动态设置列的数量和顺序。 - Naveed S
借助IReport,使用浮动列数量构建模板会很困难。您可以使用表达式设置列的可见性,但模板将变得过于复杂。如果您能够使用Java代码,那么就更容易了。 - Alex K
2个回答

13

使用JasperReport API生成动态报表的示例:

    //JasperDesign
    JasperDesign jasperDesign = new JasperDesign();
    jasperDesign.setName("The dynamically generated report");
    jasperDesign.setPageWidth(595);
    jasperDesign.setPageHeight(842);
    jasperDesign.setColumnWidth(515);
    jasperDesign.setColumnSpacing(0);
    jasperDesign.setLeftMargin(40);
    jasperDesign.setRightMargin(40);
    jasperDesign.setTopMargin(50);
    jasperDesign.setBottomMargin(50);

    //Query
    JRDesignQuery query = new JRDesignQuery();
    query.setText("SELECT * FROM Address $P!{OrderByClause}");
    jasperDesign.setQuery(query);

    //Fields
    JRDesignField field = new JRDesignField();
    field.setName("Id");
    field.setValueClass(java.lang.Integer.class);
    jasperDesign.addField(field);

    field = new JRDesignField();
    field.setName("FirstName");
    field.setValueClass(java.lang.String.class);
    jasperDesign.addField(field);

    field = new JRDesignField();
    field.setName("LastName");
    field.setValueClass(java.lang.String.class);
    jasperDesign.addField(field);

    //some code

    //Detail
    band = new JRDesignBand();
    band.setHeight(40);

    JRDesignStaticText staticText = new JRDesignStaticText();
    staticText.setX(0);
    staticText.setY(0);
    staticText.setWidth(60);
    staticText.setHeight(20);
    staticText.setMode(ModeEnum.OPAQUE);
    staticText.setHorizontalAlignment(HorizontalAlignEnum.LEFT);
    staticText.setStyle(boldStyle);
    staticText.setText("ID: ");
    staticText.getLineBox().getLeftPen().setLineWidth(1);
    staticText.getLineBox().getTopPen().setLineWidth(1);
    staticText.getLineBox().setLeftPadding(10);
    band.addElement(staticText);

    textField = new JRDesignTextField();
    textField.setX(60);
    textField.setY(0);
    textField.setWidth(200);
    textField.setHeight(20);
    textField.setHorizontalAlignment(HorizontalAlignEnum.LEFT);
    textField.setStyle(normalStyle);
    expression = new JRDesignExpression();
    expression.setValueClass(java.lang.Integer.class);
    expression.setText("$F{Id}");
    textField.setExpression(expression);
    textField.getLineBox().getTopPen().setLineWidth(1);
    textField.getLineBox().getRightPen().setLineWidth(1);
    textField.getLineBox().setLeftPadding(10);
    band.addElement(textField);

    staticText = new JRDesignStaticText();
    staticText.setX(0);
    staticText.setY(20);
    staticText.setWidth(60);
    staticText.setHeight(20);
    staticText.setMode(ModeEnum.OPAQUE);
    staticText.setHorizontalAlignment(HorizontalAlignEnum.LEFT);
    staticText.setStyle(boldStyle);
    staticText.setText("Name: ");
    staticText.getLineBox().getLeftPen().setLineWidth(1);
    staticText.getLineBox().getBottomPen().setLineWidth(1);
    staticText.getLineBox().setLeftPadding(10);
    band.addElement(staticText);

    textField = new JRDesignTextField();
    textField.setStretchWithOverflow(true);
    textField.setX(60);
    textField.setY(20);
    textField.setWidth(200);
    textField.setHeight(20);
    textField.setPositionType(PositionTypeEnum.FLOAT);
    textField.setStyle(normalStyle);
    expression = new JRDesignExpression();
    expression.setValueClass(java.lang.String.class);
    expression.setText("$F{FirstName} + \" \" + $F{LastName}");
    textField.setExpression(expression);
    textField.getLineBox().getRightPen().setLineWidth(1);
    textField.getLineBox().getBottomPen().setLineWidth(1);
    textField.getLineBox().setLeftPadding(10);
    band.addElement(textField);

    ((JRDesignSection) jasperDesign.getDetailSection()).addBand(band);

您可以在JasperReports发布包%JasperReportsFolder%/demo/samples文件夹中找到更多示例。


谢谢你的帮助。我认为使用动态Jasper会更好,因为未来可能会出现许多可能的所需条件组合。它不是提供了一种更灵活的方式来动态管理列的可见性吗? - Naveed S
@NaveedS 请添加使用API构建报告的示例。 - Alex K
我使用Dynamic Jasper生成报表的代码如下:FastReportBuilder fastReportBuilder = new FastReportBuilder();for (Field field : requiredFields()) { fastReportBuilder.addColumn(field.getTitle(), field.getName(), field.getDataType(), 50);} fastReportBuilder.setQuery("someQuery", "sql"); fastReportBuilder.setTitle("someTitle"); DynamicReport dynamicReport = fastReportBuilder.build(); JasperPrint jasperPrint = DynamicJasperHelper.generateJasperPrint(dynamicReport, new ClassicLayoutManager(), sqlConnection, null); - Naveed S
1
我还没有做任何关于格式化或样式外观的工作(稍后会完成)。我只关心动态生成内容。 - Naveed S
只是想说这个源代码可以在文件NoXmlDesignApp.java中找到。谢谢你的回答。 - Ximo Dante

1
你应该尝试使用Dynamic Jasper。这正是Dynamic Jasper设计的用例类型。您可以使用相同的模板生成具有不同列的报告。
更多信息:http://dynamicjasper.com/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接