jasperReports1.1.1增加了对交叉报表的支持,下午看了下它的三个例子.暂时记下收获:
一直对交叉报表的具体定义不太明了.个人理解是报表的行和列都是从数据库中读去的而不是普通那种列固定行是从数据库中读取(这里的数据源不一定是来自关系数据库).
crosstab 的dtt定义为:
<!ELEMENT crosstab (reportElement, crosstabParameter*, parametersMapExpression?, crosstabDataset?, rowGroup*, columnGroup*, measure*, crosstabCell*, whenNoDataCell?)>
<!ATTLIST crosstab
isRepeatColumnHeaders (true | false) "true"
isRepeatRowHeaders (true | false) "true"
columnBreakOffset NMTOKEN "10"
>
crosstabParameter:是交叉表中要用到的参数
如下:
<crosstabParameter name="Country" class="java.lang.String">
<parameterValueExpression>$F{ShipCountry}</parameterValueExpression>
</crosstabParameter>
这个就是把总表的一个域定义到交叉表的一个参数Country,这样在交叉表的数据集的查询或其他地方就可以使用这个参数了
交叉表的参数定义:
<crosstabParameter name="Country" class="java.lang.String">
<parameterValueExpression>$F{ShipCountry}</parameterValueExpression>
</crosstabParameter>
这里定义了 一个参数Country,他的来源是主表的ShipCountry域.
crosstabDataset:交叉表允许有自己的数据集
如下:
<crosstabDataset>
<dataset>
<datasetRun subDataset="Country_Orders">
<datasetParameter name="Country">
<datasetParameterExpression><![CDATA[$F{ShipCountry}]]></datasetParameterExpression>
</datasetParameter>
</datasetRun>
</dataset>
</crosstabDataset>
在这个例子中引用了预定义的子数据集Country_Orders(下面会有这个的定义),并且把子数据集中要用到的一个参数的数据来源传递过去.
下面是那个子数据源的定义:
<subDataset name="Country_Orders">
<parameter name="Country" class="java.lang.String"/>
<queryString><![CDATA[
SELECT ShippedDate, ShipRegion, ShipCity, Freight
FROM Orders
WHERE
ShipCountry = $P{Country} AND
ShippedDate IS NOT NULL
]]></queryString>
<field name="ShippedDate" class="java.sql.Timestamp"/>
<field name="ShipRegion" class="java.lang.String"/>
<field name="ShipCity" class="java.lang.String"/>
<field name="Freight" class="java.lang.Float"/>
</subDataset>
在这个例子中定义了子数据源Country_Orders,他用到了参数Country,我门可以再上面看到这个参数在交叉表中的定义,以及在交叉表的数据源的指定时把参数的来源ShipCountry也传了过去.
下面是交叉表的列头和行头的来源指定:
<rowGroup name="Region" width="50" totalPosition="End">
<bucket>
<bucketExpression class="java.lang.String">$F{ShipRegion}</bucketExpression>
</bucket>
<crosstabRowHeader>
<cellContents>
<box leftBorder="2Point" bottomBorder="2Point" rightBorder="2Point"/>
<textField>
<reportElement x="5" y="5" width="40" height="40"/>
<textFieldExpression><![CDATA[$V{Region} == null ? "No region" : $V{Region}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabRowHeader>
<crosstabTotalRowHeader>
<cellContents backcolor="#60FFFF">
<box leftBorder="2Point" bottomBorder="2Point" rightBorder="2Point"/>
<textField>
<reportElement x="5" y="5" width="110" height="20"/>
<textFieldExpression>$P{Country} + " Total"</textFieldExpression>
</textField>
</cellContents>
</crosstabTotalRowHeader>
</rowGroup>
可以看到在上面这段代码中行的标题的指定包含了两部分crosstabRowHeader和crosstabTotalRowHeader.其中bucket来指定这个行标题的分组表达式,同时为他指定了一个名字也就是行分组名字Region,这样在下面可以按一个变量的形式来引用他.
列的标题指定与此类似:
<columnGroup name="ShipYear" height="30" totalPosition="End" headerPosition="Stretch">
<bucket>
<bucketExpression class="java.util.Date">CrosstabApp.truncateToYear($F{ShippedDate})</bucketExpression>
</bucket>
<crosstabColumnHeader>
<cellContents>
<box topBorder="2Point" bottomBorder="2Point" rightBorder="2Point"/>
<rectangle radius="10">
<reportElement x="4" y="4" width="52" height="22"/>
<graphicElement pen="1Point"/>
</rectangle>
<textField pattern="yyyy">
<reportElement x="5" y="5" width="50" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.util.Date">$V{ShipYear}</textFieldExpression>
</textField>
</cellContents>
</crosstabColumnHeader>
<crosstabTotalColumnHeader>
<cellContents backcolor="#FFFF60">
<box topBorder="2Point" bottomBorder="2Point" rightBorder="2Point"/>
<staticText>
<reportElement x="5" y="5" width="20" height="15"/>
<text>Total</text>
</staticText>
</cellContents>
</crosstabTotalColumnHeader>
</columnGroup>
下面就是为具体单元格的显示样式及内容:
<crosstabCell rowTotalGroup="Region" columnTotalGroup="ShipYear">
<cellContents backcolor="#60FF60">
<box bottomBorder="1Point" rightBorder="1Point"/>
<textField pattern="#0.0">
<reportElement x="0" y="0" width="30" height="30" style="Arial_Bold"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.Float">$V{FreightSum}</textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
这里:rowTotalGroup,columnTotalGroup分别指定了这类单元格要显示的对应行列分组,也可以只有部分指定,如只指定行或列或行和列都不指定,这样分别有他门自己的意思.对于这个我们工可写出4中类型的crosstabCell,
再这之前回有个显示内容的定义:如下
<measure name="FreightSum" class="java.lang.Float" calculation="Sum">
<measureExpression>$F{Freight}</measureExpression>
</measure>
这里定义了一个变量FreightSum,他的来源是$F{Freight},计算类型是Sum,我们可以按自己的需求改动这些.
对于是多大范围的数据进行Sum,就由引用这个变量的crosstabCell 所指定的行和列来划定.对于上面那个就是由Region和ShipYear来决定的总计.
另:我门也可以对行和列进行多个分组,方法类似,具体可参考例子ShipmentsReport
明天在写 饿死俺了 牙疼 5555555555555 写完了,表达能力欠缺呀,郁闷!