報表工具jasperreports其實分爲兩個大塊,IReport和Jasperreports,前者是一個報表定義和生成工具,後者在前者的工作基礎上進行web架構的動態查詢和輸出。
今天我們主要說前者ireport。ireport是sourceforge的項目,下載地址http://jasperforge.org/index.php?q=project/ireport。
簡單地說,ireport就是個用來畫報表(樣式上是what you see is what you get)的客戶端工具,我們可以用它來進行可視化的報表樣式編輯,並可連接數據庫生成報表,導出爲excel和pdf等文件格式,實際上它的主要作用是用來定義一個固定格式的後綴爲.jrxml的xml文件,這個文件定義了報表的樣式(如報表標題title、頁頭pageHeader、報表體detail、頁尾pageFooter等,包括頁寬、線條、字體等細節)和報表內容(pageHeader和detail中定義,前者定義報表的表頭,後者定義報表中每一列要展現的數據是什麼)。
至於ireport怎麼安裝使用的有關細節,網上已有許多資料,這裏就不贅述了。這裏我要做的是:用ireport設計一個通用的符合.jrxml文件格式的模板,在這個模板的基礎上根據數據庫裏的報表配置生成單獨的jrxml文件。
下面是我在ireport工具的輔助下得到的一個通用模板,用戶在前臺報表查詢時,程序會讀取數據庫中相應報表的配置,在這個模板的基礎上生成該報表對應的.jrxml文件。
<?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" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50">
<property name="ireport.zoom" value="1.2100000000000002"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<parameter name="ReportTitle" class="java.lang.String"/>
<parameter name="Reporter" class="java.lang.String"/>
<parameter name="ReportDate" class="java.lang.String"/>
<title>
<band height="68">
<line>
<reportElement x="0" y="0" width="515" height="1"/>
</line>
<textField isBlankWhenNull="true" bookmarkLevel="1">
<reportElement x="0" y="7" width="515" height="30"/>
<textElement textAlignment="Center">
<font fontName="宋體" size="22"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{ReportTitle}]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="388" y="37" width="35" height="15"/>
<textElement>
<font fontName="宋體" size="10"/>
</textElement>
<text><![CDATA[製表人:]]></text>
</staticText>
<staticText>
<reportElement x="377" y="52" width="46" height="15"/>
<textElement>
<font fontName="宋體" size="10"/>
</textElement>
<text><![CDATA[製表時間:]]></text>
</staticText>
<textField>
<reportElement x="423" y="37" width="92" height="15"/>
<textElement>
<font fontName="宋體" size="10"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{Reporter}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="423" y="53" width="92" height="15"/>
<textElement>
<font fontName="宋體" size="10"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{ReportDate}]]></textFieldExpression>
</textField>
</band>
</title>
<pageHeader>
<band height="20">
</band>
</pageHeader>
<detail>
<band height="15">
</band>
</detail>
<pageFooter>
<band height="33">
<line>
<reportElement x="0" y="10" width="515" height="1"/>
</line>
<textField>
<reportElement x="205" y="14" width="65" height="15"/>
<textElement textAlignment="Right">
<font fontName="宋體" size="10"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA["第" + String.valueOf($V{PAGE_NUMBER}) + "頁,共"]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="270" y="14" width="39" height="15"/>
<textElement>
<font fontName="宋體" size="10"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[String.valueOf($V{PAGE_NUMBER})+"頁 "]]></textFieldExpression>
</textField>
</band>
</pageFooter>
</jasperReport>
解釋一下:
<parameter name="ReportTitle" class="java.lang.String"/>
<parameter name="Reporter" class="java.lang.String"/>
<parameter name="ReportDate" class="java.lang.String"/>
定義了填充報表時需要輸入的三個參數,分表是報表標題,製表人和製表時間,這些參數將在程序填充報表時動態地獲取(如來於後臺數據庫)並顯示在報表中(注意title部分的紅色字體)。
title部分是在組建具體的.jrxml文件時用來定義報表標題部分的,直接copy引用即可。
pageHeader部分是用來定義報表頭的內容,它顯示了具體地一個報表顯示的列的列名,如:
<pageHeader>
<band height="20">
<staticText>
<reportElement mode="Opaque" x="0" y="5" width="50" height="15" forecolor="#FFFFFF" backcolor="#333333"/>
<textElement>
<font fontName="宋體" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
</textElement>
<text><![CDATA[編號]]></text>
</staticText>
<staticText>
<reportElement mode="Opaque" x="50" y="5" width="200" height="15" forecolor="#FFFFFF" backcolor="#333333"/>
<textElement textAlignment="Left" verticalAlignment="Top" rotation="None" lineSpacing="Single" markup="none">
<font fontName="宋體" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
</textElement>
<text><![CDATA[姓名]]></text>
</staticText>
<staticText>
<reportElement mode="Opaque" x="250" y="5" width="265" height="15" forecolor="#FFFFFF" backcolor="#333333"/>
<textElement textAlignment="Left" verticalAlignment="Top" rotation="None" lineSpacing="Single" markup="none">
<font fontName="宋體" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
</textElement>
<text><![CDATA[街道]]></text>
</staticText>
</band>
</pageHeader>
detail部分定義了每一列的數據來源。如:
<detail>
<band height="15">
<textField isStretchWithOverflow="true">
<reportElement stretchType="RelativeToTallestObject" x="0" y="0" width="50" height="15"/>
<box leftPadding="10" rightPadding="10">
<leftPen lineWidth="0.5"/>
<bottomPen lineWidth="0.5"/>
</box>
<textElement verticalAlignment="Middle">
<font fontName="宋體" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
</textElement>
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{id}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="true" pattern="" isBlankWhenNull="false">
<reportElement positionType="Float" stretchType="RelativeToTallestObject" mode="Transparent" x="50" y="0" width="200" height="15" forecolor="#000000" backcolor="#FFFFFF"/>
<box leftPadding="10" rightPadding="10">
<leftPen lineWidth="0.5"/>
<bottomPen lineWidth="0.5"/>
</box>
<textElement textAlignment="Left" verticalAlignment="Middle" rotation="None" lineSpacing="Single" markup="none">
<font fontName="宋體" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="true" pattern="" isBlankWhenNull="false">
<reportElement positionType="Float" stretchType="RelativeToTallestObject" mode="Transparent" x="250" y="0" width="265" height="15" forecolor="#000000" backcolor="#FFFFFF"/>
<box leftPadding="10" rightPadding="10">
<leftPen lineWidth="0.5"/>
<bottomPen lineWidth="0.5"/>
<rightPen lineWidth="0.5"/>
</box>
<textElement textAlignment="Left" verticalAlignment="Middle" rotation="None" lineSpacing="Single" markup="none">
<font fontName="宋體" size="10" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{street}]]></textFieldExpression>
</textField>
</band>
</detail>
請注意紅色字體的部分,它引用了通用模板中沒有定義的Field(需要在程序生成具體模板的時候根據後臺數據庫的報表配置動態地添加定義):
<field name="id" class="java.lang.Integer"/>
<field name="name" class="java.lang.String"/>
<field name="street" class="java.lang.String"/>
請注意,jrxml文件對元素的定義順序有嚴格要求,field的定義必須在parameter 後,否則jrxml文件無法編譯通過,其他元素的定義順序也必須一樣如例所示。
最後是頁尾pageFooter部分,它引用了jasperreport對象的一些固有屬性,如總頁碼、當前頁碼等。在這裏它也是通用的,生成具體報表的jrxml文件時直接copy引用即可。
好了,生成了報表的jrxml文件,接下來就要把它編譯成.jasper文件,用符合要求的數據來填充報表,並輸出爲excel、pdf、html等格式的報表文件,如何在web上做到這些呢?請看下一篇