日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用PrimeFaces开发数据导出实用程序

發(fā)布時(shí)間:2023/12/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用PrimeFaces开发数据导出实用程序 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我的日常工作涉及大量使用數(shù)據(jù)。 我們使用關(guān)系數(shù)據(jù)庫來存儲(chǔ)所有內(nèi)容,因?yàn)槲覀円蕾囉谄髽I(yè)級(jí)的數(shù)據(jù)管理。 有時(shí),具有將數(shù)據(jù)提取為簡單格式(例如電子表格)的功能很有用,以便我們可以按需進(jìn)行操作。 這篇文章概述了我使用PrimeFaces 5.0生成有效且易于使用的基于JSF的數(shù)據(jù)導(dǎo)出實(shí)用程序所采取的步驟。 導(dǎo)出實(shí)用程序?qū)⑸梢粋€(gè)電子表格,其中包括列標(biāo)題。 用戶可以選擇要導(dǎo)出的數(shù)據(jù)庫字段以及應(yīng)該以什么順序?qū)С觥?

我們要確保我們擁有一個(gè)直觀的干凈用戶界面。 因此,我選擇不在屏幕上顯示任何數(shù)據(jù)。 而是,用戶界面包含一個(gè)PrimeFaces PickList組件,該組件列出了可供選擇的不同數(shù)據(jù)字段,以及一個(gè)用于生成導(dǎo)出的按鈕。 首先,設(shè)置數(shù)據(jù)庫基礎(chǔ)結(jié)構(gòu)以使此導(dǎo)出實(shí)用程序成為可能。

對(duì)于這篇文章,我增強(qiáng)了AcmePools應(yīng)用程序,該應(yīng)用程序是通過我在OTN上發(fā)布的名為PrimeFaces in the Enterprise的文章開發(fā)的 。 導(dǎo)出實(shí)用程序允許將客戶數(shù)據(jù)導(dǎo)出到電子表格中。 客戶數(shù)據(jù)包含在NetBeans安裝在Apache Derby內(nèi)的示例數(shù)據(jù)庫中,或者您可以將SQL腳本用于此文章。 在創(chuàng)建此導(dǎo)出實(shí)用程序之前,請(qǐng)?jiān)谀沫h(huán)境中下載或創(chuàng)建AcmePools項(xiàng)目。

數(shù)據(jù)導(dǎo)出實(shí)用程序分為兩部分,第一部分是PrimeFaces PickList組件,供用戶選擇要導(dǎo)出的字段,第二部分是導(dǎo)出按鈕,它將選擇的字段內(nèi)容提取到電子表格中。 最終結(jié)果將類似于圖1所示的用戶界面。

圖1:數(shù)據(jù)導(dǎo)出實(shí)用程序

開發(fā)PickList組件

首先,創(chuàng)建數(shù)據(jù)基礎(chǔ)結(jié)構(gòu)以支持PickList組件。 它由一個(gè)單獨(dú)的數(shù)據(jù)庫表組成,用于保存您要導(dǎo)出的實(shí)體數(shù)據(jù)的列名和標(biāo)簽,以及一個(gè)可選的數(shù)據(jù)庫序列,用于填充該表的主鍵。 在這種情況下,數(shù)據(jù)庫表名為COLUMN_MODEL,我們用與CUSTOMER數(shù)據(jù)庫表的數(shù)據(jù)庫列名稱相對(duì)應(yīng)的實(shí)體字段名稱填充該表。

-- Add support for data export create table column_model( id int primary key, column_name varchar(30), column_label varchar(150)); -- Optional sequence for primary key generation create sequence column_model_s start with 1 increment by 1; -- Load with field (database column) names insert into column_model values( 1, 'addressline1', 'Address Line 1');insert into column_model values( 2, 'addressline2', 'Address Line 2');insert into column_model values( 3, 'city', 'City');insert into column_model values( 4, 'creditLimit', 'Credit Limit');insert into column_model values( 5, 'customerId', 'Customer Id');insert into column_model values( 6, 'discountCode', 'Discount Code');insert into column_model values( 7, 'email', 'Email');insert into column_model values( 8, 'fax', 'Fax');insert into column_model values( 9, 'name', 'Name');insert into column_model values( 10, 'phone', 'Phone');insert into column_model values( 11, 'state', 'State');insert into column_model values( 12, 'zip', 'Zip');

接下來,創(chuàng)建一個(gè)實(shí)體類,該實(shí)體類可用于從組件內(nèi)部訪問列數(shù)據(jù)。 如果使用NetBeans等IDE,則可以通過向?qū)лp松完成此操作。 如果使用NetBeans,請(qǐng)右鍵單擊com.acme.acmepools.entity包,然后選擇“新建”->“數(shù)據(jù)庫中的實(shí)體類”,然后為我們的示例數(shù)據(jù)庫選擇數(shù)據(jù)源。 當(dāng)表列表填充時(shí),選擇COLUMN_MODEL表,如圖2所示。最后,選擇“下一步”和“完成”以創(chuàng)建實(shí)體類。

圖2.數(shù)據(jù)庫中的NetBeans IDE新實(shí)體類


完成后,名為ColumnModel的實(shí)體類應(yīng)如下所示:

package com.acme.acmepools.entity;import java.io.Serializable; import java.math.BigDecimal; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement;/**** @author Juneau*/ @Entity @Table(name = "COLUMN_MODEL") @XmlRootElement @NamedQueries({@NamedQuery(name = "ColumnModel.findAll", query = "SELECT c FROM ColumnModel c"),@NamedQuery(name = "ColumnModel.findById", query = "SELECT c FROM ColumnModel c WHERE c.id = :id"),@NamedQuery(name = "ColumnModel.findByColumnName", query = "SELECT c FROM ColumnModel c WHERE c.columnName = :columnName"),@NamedQuery(name = "ColumnModel.findByColumnLabel", query = "SELECT c FROM ColumnModel c WHERE c.columnLabel = :columnLabel")}) public class ColumnModel implements Serializable {private static final long serialVersionUID = 1L;@Id@Basic(optional = false)@NotNull@Column(name = "ID")private BigDecimal id;@Size(max = 30)@Column(name = "COLUMN_NAME")private String columnName;@Size(max = 150)@Column(name = "COLUMN_LABEL")private String columnLabel;public ColumnModel() {}public ColumnModel(BigDecimal id) {this.id = id;}public BigDecimal getId() {return id;}public void setId(BigDecimal id) {this.id = id;}public String getColumnName() {return columnName;}public void setColumnName(String columnName) {this.columnName = columnName;}public String getColumnLabel() {return columnLabel;}public void setColumnLabel(String columnLabel) {this.columnLabel = columnLabel;}@Overridepublic int hashCode() {int hash = 0;hash += (id != null ? id.hashCode() : 0);return hash;}@Overridepublic boolean equals(Object object) {// TODO: Warning - this method won't work in the case the id fields are not setif (!(object instanceof ColumnModel)) {return false;}ColumnModel other = (ColumnModel) object;if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {return false;}return true;}@Overridepublic String toString() {return "com.acme.acmepools.entity.ColumnModel[ id=" + id + " ]";}}

接下來,為新生成的實(shí)體類創(chuàng)建EJB會(huì)話bean,以便組件可以查詢列數(shù)據(jù)。 您也可以根據(jù)需要使用IDE。 如果使用NetBeans,請(qǐng)右鍵單擊com.acme.acmepools.session包,然后選擇“新建”->“實(shí)體類的會(huì)話Bean”。 對(duì)話框打開后,從左側(cè)列表中選擇實(shí)體類“ com.acme.acmepools.entity.ColumnModel”,然后單擊“完成”(圖3)。

圖3:用于實(shí)體類的NetBeans IDE會(huì)話Bean對(duì)話框


創(chuàng)建會(huì)話bean之后,添加一個(gè)名為findId()的方法,該方法可用于根據(jù)指定的列名返回列ID值。 ColumnModelFacade的完整資源應(yīng)如下所示:

package com.acme.acmepools.session;import com.acme.acmepools.entity.ColumnModel; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext;/**** @author Juneau*/ @Stateless public class ColumnModelFacade extends AbstractFacade {@PersistenceContext(unitName = "com.acme_AcmePools_war_AcmePools-1.0-SNAPSHOTPU")private EntityManager em;@Overrideprotected EntityManager getEntityManager() {return em;}public ColumnModelFacade() {super(ColumnModel.class);}public ColumnModel findId(String columnName){return (ColumnModel) em.createQuery("select object(o) from ColumnModel as o " +"where o.columnName = :columnName").setParameter("columnName", columnName).getSingleResult();}}

接下來,創(chuàng)建一些幫助程序類,這些類將用于在PickList組件中加載和管理數(shù)據(jù)。 第一個(gè)類名為ColumnBean,它用于存儲(chǔ)實(shí)體數(shù)據(jù),然后將其傳遞給PickList以供使用。 ColumnBean的代碼是一個(gè)簡單的POJO:

package com.acme.acmepools.bean;import java.math.BigDecimal;/**** @author juneau*/ public class ColumnBean {private BigDecimal id;private String columnName;private String columnLabel;public ColumnBean(BigDecimal id, String columnName, String columnLabel){this.id = id;this.columnName = columnName;this.columnLabel = columnLabel;}/*** @return the id*/public BigDecimal getId() {return id;}/*** @param id the id to set*/public void setId(BigDecimal id) {this.id = id;}/*** @return the columnName*/public String getColumnName() {return columnName;}/*** @param columnName the columnName to set*/public void setColumnName(String columnName) {this.columnName = columnName;}/*** @return the columnLabel*/public String getColumnLabel() {return columnLabel;}/*** @param columnLabel the columnLabel to set*/public void setColumnLabel(String columnLabel) {this.columnLabel = columnLabel;}}

PickList組件需要使用PrimeFaces DualListModel來訪問和更新數(shù)據(jù)。 因此,我們必須實(shí)現(xiàn)一個(gè)類,該類可用于將實(shí)體數(shù)據(jù)強(qiáng)制到ColumnBean POJO中,然后將其存儲(chǔ)到DualListModel中,以便PickList組件可以利用它。 在下面的名為PickListBean的類中,構(gòu)造函數(shù)接受作為實(shí)體數(shù)據(jù)的List <ColumnModel>作為參數(shù),執(zhí)行強(qiáng)制轉(zhuǎn)換,然后將其存儲(chǔ)到DualListModel <ColumnBean>集合中,以供組件使用。

package com.acme.acmepools.bean;/**** @author juneau*/import java.util.ArrayList; import java.util.List; import com.acme.acmepools.entity.ColumnModel;import org.primefaces.model.DualListModel;public class PickListBean {private DualListModel<ColumnBean> columns;private List<ColumnBean> source = null;private List<ColumnBean> target = null;public PickListBean(List<ColumnModel> columnModelList) {//Columns source = new ArrayList<ColumnBean>();target = new ArrayList<ColumnBean>();for(ColumnModel column:columnModelList){ColumnBean bean = new ColumnBean(column.getId(), column.getColumnName(), column.getColumnLabel());source.add(bean);}columns = new DualListModel<ColumnBean>(source, target);}public DualListModel<ColumnBean> getColumns() {return columns;}public void setColumns(DualListModel<ColumnBean> columns) {this.columns = columns;}}

最后,我們需要?jiǎng)?chuàng)建一個(gè)控制器類來訪問所有這些數(shù)據(jù)。 為此,請(qǐng)?jiān)赾om.acme.acmepools.jsf包中創(chuàng)建一個(gè)名為ColumnModelController的類,并通過使用@Named和@SessionScoped對(duì)其進(jìn)行注釋,使其成為CDI托管bean。 使該類實(shí)現(xiàn)Serializable。 初始控制器類應(yīng)如下所示(我們稍后將對(duì)其進(jìn)行更新以包括促進(jìn)導(dǎo)出的方法):

@Named @SessionScoped public class ColumnModelController implements Serializable {@EJBColumnModelFacade ejbFacade;private PickListBean pickListBean;private List<ColumnModel> columns;public DualListModel<ColumnBean> getColumns() {pickListBean = new PickListBean(ejbFacade.findAll());return pickListBean.getColumns();}public void setColumns(DualListModel<ColumnBean> columns) {pickListBean.setColumns(columns);} }

如您所見,getColumns()方法查詢ColumnModel實(shí)體,該實(shí)體通過PickListBean構(gòu)造函數(shù)填充DualListModel <ColumnBean>。

這將處理數(shù)據(jù)庫基礎(chǔ)結(jié)構(gòu)和業(yè)務(wù)邏輯……現(xiàn)在讓我們看一下用于PickList的PrimeFaces組件。 以下摘錄來自WebPages / poolCustomer / CustomerExport.xhtml視圖,其中包含PickList組件的標(biāo)記:

<p:panel header="Choose Columns for Export"><p:picklist effect="bounce" itemlabel="#{column.columnLabel}" itemvalue="#{column.columnName}" showsourcecontrols="true" showtargetcontrols="true" value="#{columnModelController.columns}" var="column"><f:facet name="sourceCaption">Columns</f:facet><f:facet name="targetCaption">Selected</f:facet></p:picklist></p:panel>

如您所見,PickList使用columnModelController.columns作為數(shù)據(jù),然后使用columnLabel字段顯示要導(dǎo)出的實(shí)體字段的名稱。 源和目標(biāo)PickList窗口的標(biāo)題可通過構(gòu)面進(jìn)行自定義。 添加導(dǎo)出功能現(xiàn)在,我們已經(jīng)開發(fā)了功能選擇列表,我們需要對(duì)選定的數(shù)據(jù)進(jìn)行一些處理。 在本練習(xí)中,我們將使用PrimeFaces DataExporter組件提取數(shù)據(jù)并將其存儲(chǔ)到Excel電子表格中。 實(shí)際上,我們需要將DataTable合并到視圖中以首先顯示數(shù)據(jù),然后可以使用DataExporter組件導(dǎo)出駐留在表中的數(shù)據(jù)。 為了構(gòu)造將用于顯示數(shù)據(jù)的DataTable,我們需要向ColumnModelController類添加一些方法。 這些方法將使我們能夠動(dòng)態(tài)地處理DataTable,以便我們可以根據(jù)在PickList中選擇的列構(gòu)造列。 實(shí)際上,DataTable將查詢所有Customer數(shù)據(jù),然后僅顯示在PickList中選擇的那些數(shù)據(jù)列。 (我們可以通過添加過濾器來修改此查詢,但這超出了本文的范圍)。 要向表中加載數(shù)據(jù),我們只需調(diào)用com.acme.acmepools.jsf.CustomerController getItems()方法即可返回所有數(shù)據(jù)……public List <Customer> getItems(){if(items == null){items = getFacade()。findAll(); } 退換貨品; }…現(xiàn)在,我們將必要的方法添加到ColumnModelController,以便我們可以動(dòng)態(tài)構(gòu)造表。 首先,添加一個(gè)單擊“導(dǎo)出”按鈕將被調(diào)用的方法。 此方法將負(fù)責(zé)構(gòu)建當(dāng)前選擇的列列表:

public void preProcess(Object document) {System.out.println("starting preprocess");updateColumns();}

接下來,讓我們看一下由preProcess()方法調(diào)用的updateColumns()的代碼:

/*** Called as preprocessor to export (after clicking Excel icon) to capture* the table component and call upon createDynamicColumns()*/public void updateColumns() {//reset table stateUIComponent table = FacesContext.getCurrentInstance().getViewRoot().findComponent(":customerExportForm:customerTable");table.setValueExpression("sortBy", null);//update columnscreateDynamicColumns();}

updateColumns()方法將UIComponent綁定到JSF視圖中的表。 然后,它有能力提供排序(如果選擇)。 接下來,讓我們看一下被調(diào)用的createDynamicColumns()方法。

private void createDynamicColumns() {String[] columnKeys = this.getIncludedColumnsByName().split(",");columns = new ArrayList<>();for (String columnKey : columnKeys) {String key = columnKey.trim();columns.add(new ColumnModel(getColumnLabel(key), key));}}

createDynamicColumns()方法可以完成一些工作。 首先,它從PickList中捕獲所有選定的列,并將它們存儲(chǔ)到名為columnKeys的String []中。 為此,我們使用名為getIncludedColumnsByName()的幫助程序方法,并以逗號(hào)分隔結(jié)果。 此方法的源如下,它基本上從PickListBean抓取當(dāng)前選擇的列,并將每個(gè)列附加到String上,然后將其返回給調(diào)用方。

public String getIncludedColumnsByName() {String tempIncludedColString = null;System.out.println("Number of included columns:" + pickListBean.getColumns().getTarget().size());List localSource = pickListBean.getColumns().getTarget();for (int x = 0; x <= localSource.size() - 1; x++) {String tempModel = (String) localSource.get(x);if (tempIncludedColString == null) {tempIncludedColString = tempModel;} else {tempIncludedColString = tempIncludedColString + "," + tempModel;}}return tempIncludedColString;}

接下來,createDynamicColumns()方法然后使用循環(huán)解析String []中的每個(gè)選定列,并將它們添加到columnList,后者將用于使用適當(dāng)?shù)牧袠?gòu)造DataTable。

現(xiàn)在,讓我們看一下用于構(gòu)造DataExport實(shí)用程序的標(biāo)記:

<p:datatable id="customerTable" rendered="false" value="#{customerController.items}" var="item" widgetvar="customerTable"> <p:columns columnindexvar="colIndex" value="#{columnModelController.dynamicColumns}" var="column"><f:facet name="header"><h:outputtext value="#{column.header}"></h:outputtext></f:facet><h:outputtext value="#{item[column.property]}"></h:outputtext></p:columns></p:datatable><hr /> <h:outputtext value="Type of file to export: "><h:commandlink><p:graphicimage value="/faces/resources/images/excel.png"><p:dataexporter filename="customers" id="propertyXlsExport" preprocessor="#{columnModelController.preProcess}" target="customerTable" type="xls"></p:dataexporter></p:graphicimage></h:commandlink> </h:outputtext>

如您所見,DataTable設(shè)置為不呈現(xiàn),因?yàn)槲覀兇_實(shí)不希望顯示它。 相反,我們希望使用DataExporter組件導(dǎo)出其內(nèi)容。 為了動(dòng)態(tài)構(gòu)造DataTable,這些列將調(diào)用columnModelController.dynamicColumns方法以返回動(dòng)態(tài)列列表。 該方法如下所示:

public List<ColumnModel> getDynamicColumns() {return columns;}

在DataExporter實(shí)用程序組件中,將columnModelController.preProcess方法分配給預(yù)處理器屬性以啟動(dòng)動(dòng)態(tài)列列表。 目標(biāo)設(shè)置為customerTable小部件,該部件是我們根據(jù)所選列動(dòng)態(tài)構(gòu)建的DataTable。 為了將其導(dǎo)出到xls電子表格,必須在項(xiàng)目的Maven POM中添加org.apache.poi依賴項(xiàng),如下所示:

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.7</version></dependency>

就是這樣…現(xiàn)在您應(yīng)該擁有使用PrimeFaces組件的功能齊全的數(shù)據(jù)導(dǎo)出實(shí)用程序。 使用以下鏈接可在GitHub上獲得完整的資源。 此代碼已用NetBeans IDE 8.0編寫,并已部署到GlassFish 4.0。 我在該項(xiàng)目中使用了PrimeFaces 5.0。

  • GitHub來源: https : //github.com/juneau001/AcmePools

翻譯自: https://www.javacodegeeks.com/2014/12/developing-a-data-export-utility-with-primefaces.html

總結(jié)

以上是生活随笔為你收集整理的使用PrimeFaces开发数据导出实用程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。