向用戶顯示報告時,我們的應用程序將提供以下功能:
- 用戶將能夠選擇報告的輸出格式。
- 報告視圖將是可本地化的,并將以與應用程序用戶相同的語言環境輸出。
最初設定
為了避免從功能上創建所有CRUD,為簡單起見,我將初始化包含將使用SQL腳本顯示的值的表。 僅幾條記錄就??足以滿足本文的目的,因此,我將使用以下腳本來提供書本表:
insert into book(title, author, published_year, genre, price)values('The Futurogical Congress', 'Stanislaw Lem', '1978', 'SciFi', 2.5);
insert into book(title, author, published_year, genre, price)values('Brave New World', 'H. G. Wells', '1975', 'SciFi', 3.99);
insert into book(title, author, published_year, genre, price)values('Treasure Island', 'Robert Lewis Stevenson', '1948', 'Adventures', 4.45);
insert into book(title, author, published_year, genre, price)values('The Lord of the Rings', 'J. R. Tolkien', '1945', 'Fantasy', 12.23);
insert into book(title, author, published_year, genre, price)values('In Cold Blood', 'Truman Capote', '1966', 'Nonfiction', 9.50);
我將創建一個資源包,其中將包含視圖和報告的本地化文本。 該文件的名稱為Messages.properties ,我將其添加到資源根文件夾下的包net.sf.jasperreports.jsf.sample.usecases中 。 文件內容如下:
report.format.select=Select report formatbookList.pageTitle=Browsing Books
bookList.id=Reference ID
bookList.title=Title
bookList.author=Author
bookList.genre=Genre
bookList.year=Year
bookList.price=Price
我添加了與上一個文件類似的另一個文件,但名為Messages_es.properties并保留了西班牙語翻譯,如果您對支持多個以上的語言感興趣,可以添加其他首選語言。 必須在faces-config.xml文件中配置先前的資源文件:
<faces-config ...><application><locale-config><default-locale>en</default-locale><supported-locale>es</supported-locale></locale-config><resource-bundle><var>Messages</var><base-name>net.sf.jasperreports.jsf.sample.usecases.Messages</base-name></resource-bundle></application>
</faces-config>
由于使用的是Maven,因此我將在項目結構中配置一個文件夾來保存報告的.jrxml文件,并配置POM以對該文件夾運行JasperReports編譯器。 我選擇的文件夾名稱是src / main / jasperreports , JasperReports Maven插件的POM配置如下:
<plugin><groupId>org.codehaus.mojo</groupId><artifactId>jasperreports-maven-plugin</artifactId><version>1.0-beta-2</version><executions><execution><goals><goal>compile-reports</goal></goals></execution></executions><configuration><outputDirectory>target/jasperreports/jasper</outputDirectory></configuration><dependencies><dependency><groupId>net.sf.jasperreports</groupId><artifactId>jasperreports</artifactId><version>4.5.1</version></dependency></dependencies>
</plugin>
我還將在Maven WAR插件中添加一些額外的配置,以便它可以收集JasperReports編譯器生成的所有.jasper文件并將它們打包在應用程序WAR文件中:
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>2.2</version><configuration><webResources><resource><directory>src/main/jasperreports</directory><includes><include>**/*.jrxml</include></includes><targetPath>resources/reports/sources</targetPath></resource><resource><directory>target/jasperreports/jasper</directory><includes><include>**/*.jasper</include></includes><targetPath>resources/reports/jasper</targetPath></resource></webResources></configuration>
</plugin>
您可能會注意到,我將JasperReports的.jrxml文件打包在Web應用程序檔案中。 當使用插件時,我們可以將其作為報告模板資源進行引用,插件引擎足夠智能,可以識別所引用文件的類型,而當使用對報告源文件的引用時,插件將即時編譯報告。 但是,首選方法應該始終是使用.jasper文件,因為它比其他文件具有更好的性能。 ?
設計報告模板
如本系列簡介中所述,我將使用的JasperReports視覺設計工具是iReport,那里有很多關于如何使用iReport的教程,因此我將跳過這一部分。 但是,由于我要設計一個可識別語言環境的報告,因此必須注意JasperReports網站上提供的I18n Sample 。
因此,我們啟動iReport并選擇一個空白報告模板。 由于我們的報告將使用基于SQL的數據源,因此可視設計器完成加載后,我們必須配置SQL語句以從數據庫中獲取數據。 為此,我們必須在設計器視圖中單擊縮放選項左側的按鈕,然后選擇“報告查詢”標簽:
我將用來獲取數據的SQL查詢是我們可以做的最簡單的查詢。 輸入該SQL語句后,iReport將在窗口下部顯示所有可用字段。 如果它可以加載所有字段而沒有任何錯誤,則單擊“確定”按鈕以保存它們以進行報告:
select * from book;
我最終報告中將輸出的所有文本都將來自資源包或數據庫本身。 因此,正如JasperReports i18n示例所指出的,無論何時要輸出一些文本,都應使用文本字段。 報表設計視圖將如下圖所示:
報告模板文件的XML視圖將類似于以下內容:
<?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="booklist" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20"topMargin="20" bottomMargin="20"><property name="ireport.zoom" value="1.5"/><property name="ireport.x" value="0"/><property name="ireport.y" value="0"/><queryString><![CDATA[select * from book]]></queryString><field name="BOOK_ID" class="java.lang.Integer"/><field name="TITLE" class="java.lang.String"/><field name="AUTHOR" class="java.lang.String"/><field name="PUBLISHED_YEAR" class="java.lang.String"/><field name="GENRE" class="java.lang.String"/><field name="PRICE" class="java.math.BigDecimal"/><background><band splitType="Stretch"/></background><title><band height="38" splitType="Stretch"><textField><reportElement x="0" y="0" width="227" height="29"/><textElement><font size="18" isBold="true"/></textElement><textFieldExpression><![CDATA[$R{bookList.pageTitle}]]></textFieldExpression></textField></band></title><columnHeader><band height="27" splitType="Stretch"><textField><reportElement x="0" y="0" width="100" height="20"/><textElement><font isBold="true"/></textElement><textFieldExpression><![CDATA[$R{bookList.id}]]></textFieldExpression></textField><textField><reportElement x="113" y="2" width="155" height="20"/><textElement><font isBold="true"/></textElement><textFieldExpression><![CDATA[$R{bookList.title}]]></textFieldExpression></textField><textField><reportElement x="285" y="2" width="100" height="20"/><textElement><font isBold="true"/></textElement><textFieldExpression><![CDATA[$R{bookList.author}]]></textFieldExpression></textField><textField><reportElement x="398" y="2" width="100" height="20"/><textElement><font isBold="true"/></textElement><textFieldExpression><![CDATA[$R{bookList.year}]]></textFieldExpression></textField></band></columnHeader><detail><band height="21" splitType="Stretch"><textField><reportElement x="0" y="0" width="100" height="20"/><textElement/><textFieldExpression class="java.lang.Integer"><![CDATA[$F{BOOK_ID}]]></textFieldExpression></textField><textField><reportElement x="113" y="0" width="155" height="20"/><textElement/><textFieldExpression><![CDATA[$F{TITLE}]]></textFieldExpression></textField><textField><reportElement x="285" y="0" width="100" height="20"/><textElement/><textFieldExpression><![CDATA[$F{AUTHOR}]]></textFieldExpression></textField><textField><reportElement x="398" y="0" width="112" height="20"/><textElement/><textFieldExpression><![CDATA[$F{PUBLISHED_YEAR}]]></textFieldExpression></textField></band></detail><columnFooter><band height="45" splitType="Stretch"/></columnFooter><pageFooter><band height="25" splitType="Stretch"><textField><reportElement x="227" y="0" width="100" height="20"/><textElement textAlignment="Center"/><textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression></textField></band></pageFooter><summary><band height="42" splitType="Stretch"/></summary>
</jasperReport>
將此文件保存在先前創建的src / main / jasperreports文件夾中,您可以開始下一節了。
設計JSF視圖
我們的JSF View將基于Facelets ,因此它將被編寫為XHTML文件,在其中我們需要聲明將要使用的不同庫名稱空間。 有關如何設置Facelets的說明,請直接轉到其文檔 (JSF 2.x應用程序無需額外配置即可直接支持Facelets)。
以下代碼片段顯示了Facelets模板的內容,我將使用它們來呈現圖書清單的用戶界面。 復制它并將其保存在Web應用程序內容文件中的文件中。 我將使用的文件名為/book/bookList.xhtml :
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:f="http://java.sun.com/jsf/core"xmlns:h="http://java.sun.com/jsf/html"xmlns:jr="http://jasperreportjsf.sf.net/tld/jasperreports-jsf-1_3.tld">
<head><title>Book List - JasperReports JSF Use Cases</title>
</head>
<body>
<h1><h:outputText value="#{Messages['bookList.pageTitle']}"/></h1><div><h:form id="bookListForm"><jr:source id="bookSource" type="jndi" value="java:comp/env/jdbc/BookStoreDB"/><h:panelGrid columns="3"><h:outputLabel for="reportFormat" value="#{Messages['report.format.select']}" /><h:selectOneMenu id="reportFormat" value="#{bookList.reportFormat}"onchange="document.bookListForm.submit();"><f:selectItems value="#{bookList.reportFormats}" /></h:selectOneMenu><jr:reportLink id="reportLink" format="#{bookList.reportFormat}"target="blank" source="bookSource"value="/resources/reports/jasper/booklist.jasper"resourceBundle="#{Messages}"><h:outputText value="#{Messages['bookList.action.show']}"/></jr:reportLink></h:panelGrid><h:dataTable value="#{bookList.allBooks}" var="book"><h:column><f:facet name="header"><h:outputText value="#{Messages['bookList.title']}"/></f:facet><h:outputText value="#{book.title}"/></h:column><h:column><f:facet name="header"><h:outputText value="#{Messages['bookList.author']}"/></f:facet><h:outputText value="#{book.author}"/></h:column><h:column><f:facet name="header"><h:outputText value="#{Messages['bookList.year']}"/></f:facet><h:outputText value="#{book.publishedYear}"/></h:column><h:column><f:facet name="header"><h:outputText value="#{Messages['bookList.genre']}"/></f:facet><h:outputText value="#{book.genre}"/></h:column></h:dataTable></h:form>
</div>
</body>
</html>
突出顯示的行是我們添加JasperReports JSF插件組件的位置:
- 首先,在第14行,我們通過<jr:source>標記定義了一個報告源組件。 該組件不會將任何數據輸出到呈現HTML,但是可以由庫的可視組件引用,以告訴他們如何獲取呈現報表內容所需的數據。
- 從第21行到第26行,我們通過<jr:reportLink>標記定義一個報告鏈接組件。 該組件將輸出一個標準的 HTML元素,該元素指向由插件引擎生成的特殊URL。 當單擊它時,插件的引擎將攔截該URL并替換一些JSF生命周期階段來處理報告數據并生成結果。 注意,報表組件具有一個屬性resourceBundle,它指向我們在第一部分中創建的消息包。
注意 : resourceBundle屬性已在JasperReports JSF插件的主干版本(在編寫此行時)中可用,該版本使用標記庫的1.3版本。 對于仍在使用1.2版標記庫的用戶,他們可以獲得類似的結果,將參數添加到報表鏈接中:
<jr:reportLink id="reportLink" format="#{bookList.reportFormat}"target="blank" source="bookSource"value="/resources/reports/jasper/booklist.jasper"><f:param name="RESOURCE_BUNDLE" value="#{Messages}" /><h:outputText value="#{Messages['bookList.action.show']}"/>
</jr:reportLink>
除了突出顯示的行外,我還添加了代碼以呈現一個組合框,其中包含JasperReports JSF插件支持的所有導出選項以及一個數據表,該數據表將為表簿布置不同的記錄。
注意 :組合框包含一個onchange屬性,該屬性旨在使用報表導出選項的新值提交表單。 我必須這樣做,才能使報告鏈接在版本2.x之前的JSF中正常工作,因為該版本不提供任何AJAX支持。
上面顯示的JSF視圖需要一個托管Bean才能工作,該托管Bean將向用戶界面提供值:
public class BookListView {private BookManager bookManager;private List allBooks;private String reportFormat = "pdf";public void setBookManager(BookManager bookManager) {this.bookManager = bookManager;}public List getAllBooks() {if (allBooks == null) {allBooks = bookManager.getAllBooks();}return allBooks;}public String getReportFormat() {return reportFormat;}public void setReportFormat(String reportFormat) {this.reportFormat = reportFormat;}public List getReportFormats() {FacesContext context = FacesContext.getCurrentInstance();JRFacesContext jrContext = JRFacesContext.getInstance(context);List list = new ArrayList();for (String format : jrContext.getAvailableExportFormats()) {list.add(new SelectItem(format, format));}return list;}}
bookManager字段是對接口的引用,該接口將提供從數據庫中獲取所有書籍的邏輯:
public interface BookManager {public List getAllBooks();
}
如本系列的介紹文章中所述,我將不介紹實現用例所需的其他類或接口的細節,因為由每個特定用戶來決定哪種框架將提供應用程序的框架。 ?
一起測試
現在該檢查所有功能是否正常運行了。 因此,讓我們打包我們的Web應用程序,將其部署到我們的Tomcat服務器上,然后在您喜歡的瀏覽器中輸入以下URL: http:// localhost:8080 / jrjsf-usecases / book / bookList.jsf 。
注意 :在執行部署操作之前,Derby(數據庫)和Tomcat(應用程序服務器)必須正在運行。
因此,這是我們的瀏覽器輸出前面提到的URL的內容時的外觀:
現在,單擊“顯示報告”鏈接以查看報告的輸出,其中填充了我們資源包中的字符串和數據庫中的數據:
這是從報告的PDF視圖中截取的示例屏幕截圖。 使用用戶界面中的組合框可以更改報告導出格式。
結論
因此,完成所有操作,這是向JavaServer Faces應用程序添加報告的最簡單方法。 我從一個簡單的示例開始,我將不時為其添加更復雜的功能。 希望您喜歡這篇文章并回來以后的出版物,好東西還沒有出現!
參考: JasperReports JSF插件用例–來自Code Nibbles博客的JCG合作伙伴 Alonso Dominguez的簡單列表報告 。
翻譯自: https://www.javacodegeeks.com/2012/07/jasperreports-jsf-plugin-use-cases-2.html