1. 程式人生 > >【前後端互動版】JAVA匯出資料到Excel表格

【前後端互動版】JAVA匯出資料到Excel表格

【背景】新入公司臨時進行維護現場版本,在修復bug之餘多了一些需求,其中一個就是匯出資料到Excel。

0、生成Excel工具類

package com.onewaveinc.utils;

import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.onewaveinc.mip.log.Logger;
import com.onewaveinc.user.entity.UserInfo;
/**
 * 生成Excel檔案工具類
 * @author wxin
 *
 */
public class ExcelUtil {

	private static Logger logger = Logger.getInstance(ExcelUtil.class);
    /**
     * 匯出Excel
     * @param sheetName sheet名稱
     * @param title 標題
     * @param values 內容
     * @param wb HSSFWorkbook物件
     * @return
     */
    public static HSSFWorkbook getHSSFWorkbook(String sheetName,String []title,List<UserInfo> valueList, HSSFWorkbook wb){

        // 第一步,建立一個HSSFWorkbook,對應一個Excel檔案
        if(wb == null){
            wb = new HSSFWorkbook();
        }

        // 第二步,在workbook中新增一個sheet,對應Excel檔案中的sheet
        HSSFSheet sheet = wb.createSheet(sheetName);

        // 第三步,在sheet中新增表頭第0行,注意老版本poi對Excel的行數列數有限制
        HSSFRow row = sheet.createRow(0);

        // 第四步,建立單元格,並設定值表頭 設定表頭居中
        HSSFCellStyle style = wb.createCellStyle();
        // 建立一個居中格式
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); 

        //宣告列物件
        HSSFCell cell = null;

        //建立標題
        for(int i=0;i<title.length;i++){
            cell = row.createCell((short) i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(style);
        }

        //建立內容
        if (null != valueList && valueList.size() > 0) {
        	for(int i=0;i<valueList.size();i++){
                row = sheet.createRow(i + 1);
                UserInfo userInfo = valueList.get(i);
                String []userInfoArray = {userInfo.getLoginName(),userInfo.getStbMac(),userInfo.getLoginIp(),
                		userInfo.getServerDomain(), userInfo.getTerminalModel(),userInfo.getTerminalVersion(),
                		userInfo.getServerIp(),	userInfo.getUpdateTime(),userInfo.getLoginTime()};
                for(int j=0;j<userInfoArray.length;j++){
                    //將內容按順序賦給對應的列物件
                    row.createCell((short) j).setCellValue(userInfoArray[j]);
                }
            }
        } else {
        	logger.error("使用者資訊無資料");
        }
        return wb;
    }
}

1、查詢ejabberd所有線上使用者JID;按照JID查詢使用者mac(唯一性);按照使用者mac獲取匯出的資料,呼叫ExcelUtil,生成表格。

package com.onewaveinc.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.onewaveinc.channel.entity.Channel;
import com.onewaveinc.channel.manager.ChannelManager;
import com.onewaveinc.core.datasource.Memcached;
import com.onewaveinc.core.datasource.impl.MemcachedFactory;
import com.onewaveinc.mip.log.Logger;
import com.onewaveinc.user.entity.User;
import com.onewaveinc.user.entity.UserInfo;
import com.onewaveinc.user.manager.UserManager;
import com.onewaveinc.user2channel.entity.UserChannelLogin;
import com.onewaveinc.user2channel.manager.UserChannelLoginManager;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
/**
 * 匯出所有線上使用者資訊到Excel表格
 * @author wxin
 *
 */
public class ExportXMPPUserInfo {

    private UserManager userManager;
    private UserChannelLoginManager userChannelLoginManager;
    private String path;
//    private final static String CONNECTED_USERS ="connected_users";
    /**
     * 載入ejabbered叢集的管理頁面賬號資訊至記憶體
     */
    private Map<String, String> ejabberedUserMap=new HashMap<String, String>();
    /**
     * 載入ejabbered叢集的url
     */
    private Map<String, String> ejabberedUrlMap=new HashMap<String, String>();
    
    private String xmppManageListStr;
    private ChannelManager channelManager;
    private MemcachedFactory memcachedFactory;
    private static Logger logger = Logger.getInstance(ExportXMPPUserInfo.class);
    
    public void run() throws InterruptedException, IOException {
         ExportExcel();
   }
    /**
     * 定時匯出XMPP每個機房(一個叢集)的線上使用者的資訊
     * 匯出資訊:使用者賬號,mac地址,登陸的IP,登陸域名,機頂盒的型號,版本,和以及登陸所在節點的ip,
     * 顯示 登陸的時間,登陸的時長(現在的時間減去登陸的時間)。
     */
    public  String ExportExcel() {
        String result = "";
        try {
            List<Channel> channelList = new ArrayList<Channel>();
            try {
                channelList =  channelManager.findChannelIdList();
            } catch (Exception e) {
                e.printStackTrace();
            }
            String serverName = "";
            String serverDomain = "";
            String urlAddress = "";
            String userNameAndPwd = "";
            String respStr = "";
            for (Channel channel : channelList) {
                serverName = channel.getName();
                serverDomain = channel.getHost();
                logger.debug("此次處理的叢集名稱為:" + serverName);
                urlAddress = ejabberedUrlMap.get(serverName)+"server/"+ serverDomain +"/online-users";
                userNameAndPwd = ejabberedUserMap.get(serverName);
                respStr = HttpUtil.sendPost(urlAddress, userNameAndPwd);
                logger.debug("1.從ejabberd獲取"+ serverName +"的線上使用者列表");
                List<String> jidList = new ArrayList<String>();
                jidList = getJidList(respStr);
                
                logger.debug("2.按照使用者列表查詢所需使用者資訊");
                List<UserInfo> userInfoList = getUserInfoList(jidList);
                
                logger.debug("3.匯出Excel表格到指定路徑:" + path);
                result = ImportDataExcel(userInfoList, serverName);
                logger.info("**此次處理結果為:"+result);
            }
            
        } catch (Exception e) {
            result = "failed";
            e.printStackTrace();
        }
        return result;
        
    }

    /**
     * 1、獲取使用者jidList
     * @param respStr
     * @return List<String> jidList
     */
    public List<String> getJidList(String respStr) {
        List<String> jidList = new ArrayList<String>();
        int indexOne = respStr.indexOf("<h1>Online Users</h1>")+"<h1>Online Users</h1>".length();
        int indexTwo = respStr.indexOf("</a><br/></div><div id='clearcopyright'></div>");
        if (-1 != indexOne && -1 != indexTwo && indexTwo > indexOne) {
            
            String usersStr = respStr.substring(indexOne, indexTwo);
            logger.debug("線上使用者列表為:"+ usersStr);
            String []infoArr = usersStr.split("</a><br/>");
            logger.debug("按照</a>進行拆分使用者列表" + Arrays.toString(infoArr));
            for (String userInfo : infoArr) {
                indexOne = userInfo.indexOf("/'>")+"/'>".length();
                String newUserInfo = userInfo.substring(indexOne);
                logger.debug("正在處理使用者JID為"+newUserInfo);
                jidList.add(newUserInfo);
            }
        }
        return jidList;
    }
    
    /**
     * 2、按照使用者列表查詢所需使用者資訊
     * @param jidList
     * @return List<UserInfo> userInfoList
     */
    public List<UserInfo> getUserInfoList (List<String> jidList) {
        List<UserInfo> userInfoList = new ArrayList<UserInfo>();
        try {
            Memcached memcached = memcachedFactory.getMemcachedService();
            
            for (String jid : jidList) {
                UserInfo userInfo = new UserInfo();
                List<User> userList = userManager.find("jid", jid);
                if (null != userList && userList.size() > 0) {
                    User user = userList.get(0);
                    
                    if (null != user.getTerminalModel()) {
                        userInfo.setTerminalModel(user.getTerminalModel());
                    } else {
                        userInfo.setTerminalModel("");
                    }
                    if (null != user.getTerminalVersion()) {
                        userInfo.setTerminalVersion(user.getTerminalVersion());
                    } else {
                        userInfo.setTerminalVersion("");
                    }
                    userInfo.setLoginName(user.getLoginname());
                    List<UserChannelLogin> userChannelLoginList = userChannelLoginManager.
                            findByProperty("stbMac", user.getMac());
                    if (null != userChannelLoginList && userChannelLoginList.size() > 0) {
                        UserChannelLogin userChannelLogin = userChannelLoginList.get(0);
                        String keyStbMac = "mdc_stbMac_" + userChannelLogin.getStbMac();
                        UserChannelLogin uclFromMem = (UserChannelLogin) memcached.get(keyStbMac);
                        Date updateDateTime = null;
                        if (null == uclFromMem) {
                            logger.info("快取中無資料,對應key為:" + keyStbMac);
                            updateDateTime = userChannelLogin.getCreateTime();
                            userInfo.setLoginIp(userChannelLogin.getLoginIp());
                            userInfo.setServerDomain(userChannelLogin.getServerDomain());
                            logger.info("快取中無登入時間、登入IP、登入域名,從資料庫中獲取");
                        } else {
                            logger.debug("從快取中獲取登入時間、登入IP、登入域名");
                            updateDateTime = uclFromMem.getUpdateTime();
                            userInfo.setLoginIp(uclFromMem.getLoginIp());
                            userInfo.setServerDomain(uclFromMem.getServerDomain());
                        }
                        Date now = new Date();
                        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        SimpleDateFormat formatter2 = new SimpleDateFormat("HH:mm:ss");
                        String loginTime = formatter2.format(now.getTime() - updateDateTime.getTime());
                        String updateTime = formatter.format(updateDateTime);
                        userInfo.setLoginTime(loginTime);
                        
                        userInfo.setServerIp(userChannelLogin.getServerIp());
                        userInfo.setStbMac(userChannelLogin.getStbMac());
                        userInfo.setUpdateTime(updateTime);
                    }
                }
                
                if (null != userInfo) {
                    userInfoList.add(userInfo);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return userInfoList;
    }
    
    /**
     * 3、匯出使用者資訊資料到Excel表格
     * @param userInfoList
     * @return msg “failed” or “success”
     */
    public String ImportDataExcel(List<UserInfo> userInfoList, String serverName) {
        String msg = "";
        String[] title = {"使用者賬號","mac地址","登陸IP","登陸域名","機頂盒型號", "機頂盒版本",
                "登入所在節點的IP", "登陸時間", "登陸時長"};
        //設定日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        // new Date()為獲取當前系統時間,也可使用當前時間戳
        String date = df.format(new Date());
        String fileName = serverName+"線上使用者資訊表"+date+".xls";
        String sheetName = serverName+"線上使用者資訊表";
        HSSFWorkbook wb = new HSSFWorkbook();
        wb = ExcelUtil.getHSSFWorkbook(sheetName, title, userInfoList, null);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try{
            wb.write(os);
        }
        catch (IOException e){
            msg = "failed";
            e.printStackTrace();
        }
        byte[] content = os.toByteArray();
        //Excel檔案生成後儲存的位置。
        File file = new File(path+"/"+fileName);
        OutputStream fos  = null;
        try{
            fos = new FileOutputStream(file);
            fos.write(content);
            os.close();
            fos.close();
            if ("".equals(msg)) {
                msg = "success";
            }
            logger.info("生成使用者資訊Excel表格成功:"+ fileName);
        }
        catch (Exception e){
            msg = "failed";
            logger.error("生成使用者資訊Excel表格失敗:"+ fileName);
            e.printStackTrace();
        }
        return msg;
    }
    
    /**
     * 載入各個Ejabbered叢集的Node節點
     */
    public void queryEjabberedNodes(){
        try {
            if(StringUtils.isNotBlank(xmppManageListStr)){
                String[] strArrayOne=xmppManageListStr.split(";");
                for(String strTempOne:strArrayOne){
                    String[] arr=strTempOne.split("=");
                    String[] strArrayTwo=arr[0].split(",");
                    logger.info("strArrayTwo[0]="+strArrayTwo[0]+",strArrayTwo[1]="
                            +strArrayTwo[1]+",strArrayTwo[2]="+strArrayTwo[2]
                                    +",arr[1]="+arr[1]);
                    ejabberedUrlMap.put(strArrayTwo[0], arr[1]);
                    String encodeUserAndPwd=Base64Uitl.encode((strArrayTwo[1]+":"+strArrayTwo[2]).getBytes());
                    ejabberedUserMap.put(strArrayTwo[0], encodeUserAndPwd);
                }
            }
        } catch (Exception e) {
            logger.error("處理配置項xmpp.management.url.list產生異常!",e);
        }
    }
    
    public UserManager getUserManager() {
        return userManager;
    }
    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }
    public UserChannelLoginManager getUserChannelLoginManager() {
        return userChannelLoginManager;
    }
    public void setUserChannelLoginManager(UserChannelLoginManager userChannelLoginManager) {
        this.userChannelLoginManager = userChannelLoginManager;
    }
    public String getPath() {
        return path;
    }
    public void setPath(String path) {
        this.path = path;
    }
    public Map<String, String> getEjabberedUserMap() {
        return ejabberedUserMap;
    }
    public void setEjabberedUserMap(Map<String, String> ejabberedUserMap) {
        this.ejabberedUserMap = ejabberedUserMap;
    }
    public Map<String, String> getEjabberedUrlMap() {
        return ejabberedUrlMap;
    }
    public void setEjabberedUrlMap(Map<String, String> ejabberedUrlMap) {
        this.ejabberedUrlMap = ejabberedUrlMap;
    }
    public String getXmppManageListStr() {
        return xmppManageListStr;
    }
    public void setXmppManageListStr(String xmppManageListStr) {
        this.xmppManageListStr = xmppManageListStr;
    }
    public ChannelManager getChannelManager() {
        return channelManager;
    }
    public void setChannelManager(ChannelManager channelManager) {
        this.channelManager = channelManager;
    }
    
}

2、資源(這種和前端互動的類統一名稱叫什麼)

@SuppressWarnings("deprecation")
@Resource("userLoginService")
@Bean("contbiz.imoss.userloginservice")

...

@Post
    @Path("exportExcel")
    public String ExportExcel() {
        String result = "";
        result = exportXMPPUserInfo.ExportExcel();
        return result;
    }

3、前端程式碼(公司自有框架)

W.$('exportExcel').on('click',function(e){    
        
        W.create('userLoginService/exportExcel').done(function(result){
            if (result == "success") {
                W.alert("匯出所有線上使用者成功");
            } else {
                W.alert("匯出所有線上使用者失敗");
            }
            
        });
    });

4、效果果展示

                                       

                                                                                圖1 區域性效果