兩種方式實現java生成Excel

      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
GitHub:https://github.com/itRed 版權聲明:本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段說明,
且在文章明顯位置給出原文連接,不然保留追究法律責任的權利。
相關文章
相關標籤/搜索