Web應用中不免會遇到須要將數據導出並生成excel文件的需求。一樣,對於本博客中的總結,也是創建在爲了完成這樣的一個需求,纔開始去了解其實現形式,而且順利完成需求的開發,先將實現過程總結於此。本博文是本人的勞動成果所得,在博客園總結分享,歡迎轉載。在沒有做者的書面說明的狀況下,必須保留本段聲明。做者:itRed 郵箱:it_red@sina.com 博客連接:http://www.cnblogs.com/itred GitHub連接:http://github.com/itredhtml
根據本身的梳理,完成這樣的需求在本身的技術範圍以內比較承認的有兩種方式,其一是利用第三方插件JXL實現excel文件的生成,另外一種方式則是不須要第三方的插件,直接經過jsp頁面的設置和action層的response跳轉完成excel文件的生成。綜合來說,採用第三方插件不只可以知足功能性需求,並且還提供函數、字體、顏色及其餘方面的接口,若是直接採用jsp跳轉形式,則樣式會略顯低調,可是其實現形式很容易理解,無需瞭解更多的技術層面的東西。現將兩種具體的實現方式列出:前端
Demo 1:java
首先來個簡單易懂的。直接在action中將數據放到session服務器緩存中,而後再跳轉到指定的jsp頁面,在指定的jsp頁面中設置其ContentType,這個會牽扯到http協議的response.ContentType 。不一樣的ContentType會影響到客戶端看到的具體效果,默認的ContentType爲text/html,也就是最爲常見的網頁格式。git
新建web項目,加入struts2的相關jar包, 在默認的index.jsp頁面加入一個form表單,本案例僅僅完成功能,數據在後臺已經封裝好,無前端交互,直接input一個提交按鈕,轉向action。index.jsp的源碼以下:github
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>導出</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <form action="getXls_excel" method="post"> <input type="submit" value="提交" /> </form> </body> </html>
而後新建action名爲ExcelAction,源碼以下:web
package com.red.action; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * jsp形式導出excel * @author Red */ public class ExcelAction extends ActionSupport { private static final long serialVersionUID = -3673769122296267756L; protected HttpServletRequest request = ServletActionContext.getRequest(); protected HttpServletResponse response = ServletActionContext.getResponse(); public void getXls() throws IOException { StringBuffer sb = new StringBuffer(); sb.append("<table><tr><td>用戶名稱</td><td>郵箱地址</td></tr>"); Map<String, String> map = new HashMap<String, String>(); map.put("red1", "it_red@sina.com"); map.put("red2", "it_red@sohu.com"); map.put("red3", "it_red@163.com"); for (String key : map.keySet()) { sb.append("<tr><td>").append(key).append("</td><td>").append(map.get(key)).append("</td></tr>"); } request.getSession().setAttribute("excel", sb.toString()); response.sendRedirect(request.getContextPath() + "/export.jsp"); } }
而後新建一個跳轉後的jsp頁面,也便是處理excel文件的工具。源碼以下:apache
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ page contentType="application/msexcel"%> <% response.setContentType("application/msexcel;charset=UTF-8"); response.setHeader("Content-disposition", "attachment; filename=test.xls"); %> <html> <head> <title>Excel</title> </head> <body> <% String str = new String(session.getAttribute("excel").toString()); out.print(str); %> </body> </html>
在這裏導出的文檔編碼是根據本地電腦的編碼形式進行編碼的,因此,若是本地是中文則須要修改response.setContentType("application/msexcel;charset=UTF-8");中的編碼,將其改成GBK或者GB18030,只要支持中文就行。瀏覽器
功能實現,基本效果以下:緩存
Demo2:服務器
第二種方式是直接經過流的形式響應客戶端瀏覽器,經過瀏覽器來提供下載。只是在這個地方,將ContentType設置在了action中,而並不是是在jsp頁面上。
加入JXL的jar包,Action源碼:
package com.red.action; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jxl.Workbook; import jxl.format.UnderlineStyle; import jxl.write.Colour; import jxl.write.Label; import jxl.write.WritableCellFormat; import jxl.write.WritableFont; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; import jxl.write.WriteException; import jxl.write.biff.RowsExceededException; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * 第三方插件導出Excel * @author Red */ public class WriteExcelAction extends ActionSupport { HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); public void writeExcel() throws RowsExceededException, WriteException, IOException { OutputStream os = response.getOutputStream();// 取得輸出流 response.reset();// 清空輸出流 response.setHeader("Content-disposition", "attachment; filename=testRed.xls");// 設定輸出文件頭 response.setContentType("application/msexcel");// 定義輸出類型 WritableWorkbook wbook = Workbook.createWorkbook(os); // 創建excel文件 String tmptitle = "測試數據"; // 標題 WritableSheet wsheet = wbook.createSheet(tmptitle, 0); // sheet名稱 // 設置excel標題 WritableFont wfont = new WritableFont(WritableFont.ARIAL, 16, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK); WritableCellFormat wcfFC = new WritableCellFormat(wfont); wcfFC.setBackground(Colour.AQUA); wsheet.addCell(new Label(1, 0, tmptitle, wcfFC)); wfont = new jxl.write.WritableFont(WritableFont.ARIAL, 14, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK); wcfFC = new WritableCellFormat(wfont); // 開始生成主體內容 wsheet.addCell(new Label(0, 2, "姓名")); wsheet.addCell(new Label(1, 2, "郵箱")); // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Map<String, String> map = new HashMap<String, String>(); map.put("Red1", "it_red@sina.com"); map.put("Red2", "it_red@sohu.com"); map.put("Red3", "it_red@163.com"); int count = 0; for (String key : map.keySet()) { wsheet.addCell(new Label(0, count + 3, key)); wsheet.addCell(new Label(1, count + 3, map.get(key))); count++; } // 主體內容生成結束 wbook.write(); // 寫入文件 wbook.close(); os.close(); // 關閉流 } }
實現效果以下:
在完成以上兩個Demo以後,打開其生成的excel文件,很容易看到二者的差異。其實對於究竟選擇哪一種形式來生成excel文件,仍是須要根據實際的開發狀況及應用自己來決定的。各有其特色和好處以及缺點。l另外,當你能理解以上代碼時,以上代碼便不只僅只能生成excel文件了,天然而然就能夠生成一些其餘文件。
另附本博文中所涉及到的案例源碼請點擊連接
做者:itRed 博客:http://itred.cnblogs.com |