即使数据不存在,如何在交叉表中显示列
How to show column at Crosstab even the data is absent
有没有人有提示,如果我想从数组创建交叉表列,然后将更正信息插入交叉表?
例如,我的数据库中有如下 table:
客户----activity_date----activity|
客户 1 ---- 2016 年 1 月 1 日 ---- A|
客户 1 ---- 01-03-2016 ---- B|
客户 2 ---- 01-01-2016 ---- A|
当用户请求从 1 月 16 日到 3 月 16 日的报告时,报告应如下所示:
客户 ---- 01-2016 ---- 02-2016 ---- 03-2016 |
客户1 ---- Activity 计数:1 ---- Activity count:0 ---- Activity count:1
客户2 ---- Activity count:1 ---- Activity count:0 ---- Activity count:0
总计----Activitysum:2----Activitysum:0----Activitycount:1
目前的问题是,由于没有2016年2月的数据,所以报告中缺少02-2016这一列。
有没有什么方法(比如 scriptlet)创建一个数组作为列,然后告诉 JasperReport 在 activity_date == column_date 时插入正确的数据?
我正在使用 Jaspersoft Studio。
要显示没有日期的日期(在您的案例中没有活动),您应该使用数据源传递数据。 JasperReports 对任何日期范围或其他内容一无所知。它只是需要一个数据。
问题
- 第一个问题是即使数据不存在也要获取日期范围内的数据
- 第二个 - 避免在交叉表中显示 'null' 数据
解决方案
如果使用数据库,您可以使用外部连接和一些日期范围 'generator' 来显示数据。
我们应该解决这个任务:
获取某个时间段内所有日期(天)的列表。对于不同的 RDBMS,语法会有所不同。
对于 PostgreSQL 你可以在 Getting date list in a range in PostgreSQL post
对于 MySQL - MySQL how to fill missing dates in range & generate days from date range
对于 SQL 服务器 - SQL Server: How to select all days in a date range even if no data exists for some days
使用左或右 outter join.
Sorting 数据按日期和你想要的数据
如果使用 JavaBean datasources,您也应该这样做——添加您需要的日期(不含数据)并对数据进行排序。我们可以跳过实现数据排序并让 JasperReports 引擎为我们完成它。
交叉表有一个 'feature' - 我们无法隐藏带条件的行。即使我们将所有属性设置为隐藏所有 textFields - 也会绘制空行。如果我们尝试在 Crosstab 上使用过滤器,我们的额外行将消失。我认为好主意(在这种可怜的情况下)是为此类行指定特殊名称(我们也可以用更好的名称替换 0)。在我的样本中它将是 'Not set'.
样本
我在此示例中使用了 PostgreSQL。
报告模板
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="crss_dates_group" pageWidth="842" pageHeight="595" orientation="Landscape" whenNoDataType="AllSectionsNoDetail" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" isIgnorePagination="true" uuid="6886d70f-dbf3-4dfa-bbee-d5bc70b1c45d">
<style name="Crosstab Data Text" hAlign="Center"/>
<subDataset name="dsDates" uuid="9b8d3c04-25f5-40f0-b116-a77f8d2f7445">
<queryString language="SQL">
<![CDATA[SELECT activityName, to_char(generate_series, 'YYYY-MM-DD') AS activityDate
FROM myTable RIGHT OUTER JOIN (SELECT (generate_series('2010-07-18', '2010-07-29', '1 day'::interval))::date) fake
ON to_char(activityDateFromMyTable, 'YYYY-MM-DD')=to_char(generate_series, 'YYYY-MM-DD') ORDER BY 2, 1]]>
</queryString>
<field name="activityName" class="java.lang.String"/>
<field name="activityDate" class="java.lang.String"/>
<group name="activityDateGroup">
<groupExpression><![CDATA[$F{activityDate}]]></groupExpression>
</group>
</subDataset>
<title>
<band height="79" splitType="Stretch">
<crosstab>
<reportElement x="0" y="0" width="802" height="79" uuid="d39eef3f-aada-406f-99ee-1d2ce2bde5c8"/>
<crosstabDataset>
<dataset>
<datasetRun subDataset="dsDates" uuid="619c0498-512a-4f23-9f1e-6a5d7cfa986d">
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
</datasetRun>
</dataset>
</crosstabDataset>
<rowGroup name="activityName" width="95" totalPosition="End">
<bucket class="java.lang.String">
<bucketExpression><![CDATA[$F{activityName}]]></bucketExpression>
</bucket>
<crosstabRowHeader>
<cellContents backcolor="#F0F8FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="95" height="25" uuid="c25490b6-a836-41fb-a36c-a7ebb211bf03"/>
<textFieldExpression><![CDATA[$V{activityName} == null ? "Not set" : $V{activityName}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabRowHeader>
<crosstabTotalRowHeader>
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<staticText>
<reportElement x="0" y="0" width="95" height="25" uuid="12efa463-c4a3-4120-b0e2-0664856cc616"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Total by Date]]></text>
</staticText>
</cellContents>
</crosstabTotalRowHeader>
</rowGroup>
<columnGroup name="activityDate" height="30" totalPosition="End">
<bucket class="java.lang.String">
<bucketExpression><![CDATA[$F{activityDate}]]></bucketExpression>
</bucket>
<crosstabColumnHeader>
<cellContents backcolor="#F0F8FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="61" height="30" uuid="5b931464-5a7a-4e57-a51a-3d687c0a4130"/>
<textFieldExpression><![CDATA[$V{activityDate}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabColumnHeader>
<crosstabTotalColumnHeader>
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<staticText>
<reportElement x="0" y="0" width="50" height="30" uuid="227c77a6-b1c1-485f-95cf-95b43bc95920"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Total by Activity]]></text>
</staticText>
</cellContents>
</crosstabTotalColumnHeader>
</columnGroup>
<measure name="activityNameMeasure" class="java.lang.Integer" calculation="Count">
<measureExpression><![CDATA[$F{activityName}]]></measureExpression>
</measure>
<crosstabCell width="61" height="25">
<cellContents>
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="61" height="25" uuid="b8a8aacb-58d1-447a-9628-7f045b039f9f"/>
<textFieldExpression><![CDATA[$V{activityNameMeasure}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
<crosstabCell width="61" height="25" rowTotalGroup="activityName">
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="61" height="25" uuid="02e88c9a-e9cc-4674-9301-21676d3f33bc"/>
<textFieldExpression><![CDATA[$V{activityNameMeasure}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
<crosstabCell width="50" columnTotalGroup="activityDate">
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="50" height="25" uuid="d39d1353-61a6-4041-96d6-2065bae0041b"/>
<textFieldExpression><![CDATA[$V{activityNameMeasure}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
<crosstabCell rowTotalGroup="activityName" columnTotalGroup="activityDate">
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="50" height="25" uuid="09aa0d57-5cfa-4e78-af85-0e718c0fee44"/>
<textFieldExpression><![CDATA[$V{activityNameMeasure}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
</crosstab>
</band>
</title>
</jasperReport>
iReport 中的结果
备注:
我试图在 "Remove Line With Blank"、"Blank When Null"、"Print When Expression" 属性的帮助下隐藏空行(空行),但没有成功。挖掘源代码对我也没有帮助。
您可以在此处找到有关在交叉表中隐藏空记录的类似尝试的更多信息:
- 隐藏 NULL 行组
JasperReports
- Hide a row in crosstab
- how to hide row in crosstab when no data
- Crosstab: Suppress Null Column, Keep Row Details
也许是时候在 Jaspersoft/Tibco 社区为这个 "new old" 功能(隐藏空行)投票了 :)
有没有人有提示,如果我想从数组创建交叉表列,然后将更正信息插入交叉表?
例如,我的数据库中有如下 table:
客户----activity_date----activity|
客户 1 ---- 2016 年 1 月 1 日 ---- A|
客户 1 ---- 01-03-2016 ---- B|
客户 2 ---- 01-01-2016 ---- A|
当用户请求从 1 月 16 日到 3 月 16 日的报告时,报告应如下所示:
客户 ---- 01-2016 ---- 02-2016 ---- 03-2016 |
客户1 ---- Activity 计数:1 ---- Activity count:0 ---- Activity count:1
客户2 ---- Activity count:1 ---- Activity count:0 ---- Activity count:0
总计----Activitysum:2----Activitysum:0----Activitycount:1
目前的问题是,由于没有2016年2月的数据,所以报告中缺少02-2016这一列。
有没有什么方法(比如 scriptlet)创建一个数组作为列,然后告诉 JasperReport 在 activity_date == column_date 时插入正确的数据?
我正在使用 Jaspersoft Studio。
要显示没有日期的日期(在您的案例中没有活动),您应该使用数据源传递数据。 JasperReports 对任何日期范围或其他内容一无所知。它只是需要一个数据。
问题
- 第一个问题是即使数据不存在也要获取日期范围内的数据
- 第二个 - 避免在交叉表中显示 'null' 数据
解决方案
如果使用数据库,您可以使用外部连接和一些日期范围 'generator' 来显示数据。
我们应该解决这个任务:
获取某个时间段内所有日期(天)的列表。对于不同的 RDBMS,语法会有所不同。
对于 PostgreSQL 你可以在 Getting date list in a range in PostgreSQL post
对于 MySQL - MySQL how to fill missing dates in range & generate days from date range 对于 SQL 服务器 - SQL Server: How to select all days in a date range even if no data exists for some days使用左或右 outter join.
Sorting 数据按日期和你想要的数据
如果使用 JavaBean datasources,您也应该这样做——添加您需要的日期(不含数据)并对数据进行排序。我们可以跳过实现数据排序并让 JasperReports 引擎为我们完成它。
交叉表有一个 'feature' - 我们无法隐藏带条件的行。即使我们将所有属性设置为隐藏所有 textFields - 也会绘制空行。如果我们尝试在 Crosstab 上使用过滤器,我们的额外行将消失。我认为好主意(在这种可怜的情况下)是为此类行指定特殊名称(我们也可以用更好的名称替换 0)。在我的样本中它将是 'Not set'.
样本
我在此示例中使用了 PostgreSQL。
报告模板
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="crss_dates_group" pageWidth="842" pageHeight="595" orientation="Landscape" whenNoDataType="AllSectionsNoDetail" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" isIgnorePagination="true" uuid="6886d70f-dbf3-4dfa-bbee-d5bc70b1c45d">
<style name="Crosstab Data Text" hAlign="Center"/>
<subDataset name="dsDates" uuid="9b8d3c04-25f5-40f0-b116-a77f8d2f7445">
<queryString language="SQL">
<![CDATA[SELECT activityName, to_char(generate_series, 'YYYY-MM-DD') AS activityDate
FROM myTable RIGHT OUTER JOIN (SELECT (generate_series('2010-07-18', '2010-07-29', '1 day'::interval))::date) fake
ON to_char(activityDateFromMyTable, 'YYYY-MM-DD')=to_char(generate_series, 'YYYY-MM-DD') ORDER BY 2, 1]]>
</queryString>
<field name="activityName" class="java.lang.String"/>
<field name="activityDate" class="java.lang.String"/>
<group name="activityDateGroup">
<groupExpression><![CDATA[$F{activityDate}]]></groupExpression>
</group>
</subDataset>
<title>
<band height="79" splitType="Stretch">
<crosstab>
<reportElement x="0" y="0" width="802" height="79" uuid="d39eef3f-aada-406f-99ee-1d2ce2bde5c8"/>
<crosstabDataset>
<dataset>
<datasetRun subDataset="dsDates" uuid="619c0498-512a-4f23-9f1e-6a5d7cfa986d">
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
</datasetRun>
</dataset>
</crosstabDataset>
<rowGroup name="activityName" width="95" totalPosition="End">
<bucket class="java.lang.String">
<bucketExpression><![CDATA[$F{activityName}]]></bucketExpression>
</bucket>
<crosstabRowHeader>
<cellContents backcolor="#F0F8FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="95" height="25" uuid="c25490b6-a836-41fb-a36c-a7ebb211bf03"/>
<textFieldExpression><![CDATA[$V{activityName} == null ? "Not set" : $V{activityName}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabRowHeader>
<crosstabTotalRowHeader>
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<staticText>
<reportElement x="0" y="0" width="95" height="25" uuid="12efa463-c4a3-4120-b0e2-0664856cc616"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Total by Date]]></text>
</staticText>
</cellContents>
</crosstabTotalRowHeader>
</rowGroup>
<columnGroup name="activityDate" height="30" totalPosition="End">
<bucket class="java.lang.String">
<bucketExpression><![CDATA[$F{activityDate}]]></bucketExpression>
</bucket>
<crosstabColumnHeader>
<cellContents backcolor="#F0F8FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="61" height="30" uuid="5b931464-5a7a-4e57-a51a-3d687c0a4130"/>
<textFieldExpression><![CDATA[$V{activityDate}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabColumnHeader>
<crosstabTotalColumnHeader>
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<staticText>
<reportElement x="0" y="0" width="50" height="30" uuid="227c77a6-b1c1-485f-95cf-95b43bc95920"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Total by Activity]]></text>
</staticText>
</cellContents>
</crosstabTotalColumnHeader>
</columnGroup>
<measure name="activityNameMeasure" class="java.lang.Integer" calculation="Count">
<measureExpression><![CDATA[$F{activityName}]]></measureExpression>
</measure>
<crosstabCell width="61" height="25">
<cellContents>
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="61" height="25" uuid="b8a8aacb-58d1-447a-9628-7f045b039f9f"/>
<textFieldExpression><![CDATA[$V{activityNameMeasure}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
<crosstabCell width="61" height="25" rowTotalGroup="activityName">
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="61" height="25" uuid="02e88c9a-e9cc-4674-9301-21676d3f33bc"/>
<textFieldExpression><![CDATA[$V{activityNameMeasure}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
<crosstabCell width="50" columnTotalGroup="activityDate">
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="50" height="25" uuid="d39d1353-61a6-4041-96d6-2065bae0041b"/>
<textFieldExpression><![CDATA[$V{activityNameMeasure}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
<crosstabCell rowTotalGroup="activityName" columnTotalGroup="activityDate">
<cellContents backcolor="#BFE1FF" mode="Opaque">
<box>
<pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
</box>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="50" height="25" uuid="09aa0d57-5cfa-4e78-af85-0e718c0fee44"/>
<textFieldExpression><![CDATA[$V{activityNameMeasure}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
</crosstab>
</band>
</title>
</jasperReport>
iReport 中的结果
备注:
我试图在 "Remove Line With Blank"、"Blank When Null"、"Print When Expression" 属性的帮助下隐藏空行(空行),但没有成功。挖掘源代码对我也没有帮助。
您可以在此处找到有关在交叉表中隐藏空记录的类似尝试的更多信息:
- 隐藏 NULL 行组 JasperReports
- Hide a row in crosstab
- how to hide row in crosstab when no data
- Crosstab: Suppress Null Column, Keep Row Details
也许是时候在 Jaspersoft/Tibco 社区为这个 "new old" 功能(隐藏空行)投票了 :)