Java poi Excel 通用導出

最近項目中需要用到數據的導出與導入功能,我和我同事各負責一個, 我負責做導出這一塊,比較簡單。至於想看導入的同志們,我這裏暫時是沒有的,所以就不要浪費時間在這片文章上了。不過以後肯定會補上導入的功能。

鄙人看到一些博客上通過引用各種的util工具包,其實說白了還是利用apache的poi,在項目中直接導入poi包就可以。當然,你可以把代碼都抽取出來成工具類,這裏爲了方便理解,就不抽取了,廢話不多說。

1、首先準備一些poi的jar包,(這裏就不多說了,需要的朋友可以在我的資源裏尋找,等會我還會分享一下數據導出完整的源代碼,裏面也有jar包);

2、準備好jar包之後就可以寫代碼了,接下來我就把代碼寫簡單,讓大家都能看懂。至於你後面想用多麼牛逼的代碼實現它,都可以,只要原理懂了,其它的都不是事,對吧。
首先我要建一個實體類:Student.class

package testExport;

/**
 * 
 * @author zsl
 *
 */

public class Student {
    private Integer id;
    private String name;
    private String sex;
    public Student(Integer id, String name, String sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

這個不多說,接下來我還有一個類:ExportExcel.class


package testExport;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

//下面是和數據導出有關的包
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;

public class ExportExcel {
    public void Export(){
        // 聲明一個工作薄
        HSSFWorkbook wb = new HSSFWorkbook();
        //聲明一個單子並命名
        HSSFSheet sheet = wb.createSheet("學生表");
        //給單子名稱一個長度
        sheet.setDefaultColumnWidth((short)15);
        // 生成一個樣式  
        HSSFCellStyle style = wb.createCellStyle();
        //創建第一行(也可以稱爲表頭)
        HSSFRow row = sheet.createRow(0);
        //樣式字體居中
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        //給表頭第一行一次創建單元格
        HSSFCell cell = row.createCell((short) 0);
        cell.setCellValue("學生編號"); 
        cell.setCellStyle(style);
        cell = row.createCell( (short) 1);  
        cell.setCellValue("學生姓名");  
        cell.setCellStyle(style);  
        cell = row.createCell((short) 2);  
        cell.setCellValue("學生性別");  
        cell.setCellStyle(style);               
        //添加一些數據,這裏先寫死,大家可以換成自己的集合數據
        List<Student> list = new ArrayList<Student>();
        list.add(new Student(111,"張三","男"));
        list.add(new Student(111,"李四","男"));
        list.add(new Student(111,"王五","女"));

        //向單元格里填充數據
        for (short i = 0; i < list.size(); i++) {
            row = sheet.createRow(i + 1); 
            row.createCell(0).setCellValue(list.get(i)
                                .getId());                                                                                            
            row.createCell(1).setCellValue(list.get(i)
                                .getName());
            row.createCell(2).setCellValue(list.get(i)
                                .getSex());                                                                                                                                                                                                               
        }

        try {
            //默認導出到E盤下
            FileOutputStream out = new FileOutputStream("E://學生表.xls");
            wb.write(out);
            out.close();
            JOptionPane.showMessageDialog(null, "導出成功!");
        } catch (FileNotFoundException e) {
            JOptionPane.showMessageDialog(null, "導出失敗!");
            e.printStackTrace();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "導出失敗!");
            e.printStackTrace();
        }
    }
}

ok,上面這樣就結束了。大家可以測試下,只要把上面字體標紅部分的數據改成自己的數據集合即可。
下面看一下效果圖:

這裏寫圖片描述

下面附上源碼一份:
附件源碼:
Java利用POI實現數據Excel導出實例源碼

當然有什麼疑問,大家共同交流,共同進步。

注意

這樣就完成了。只要自己抽取出一個公用類,非常方便,簡單。當然你不抽取也是可以的。雖然抽取的時候比較麻煩,但是以後做多個表格的導出就方便了,磨刀還是不誤砍柴工的。

package com.tspt.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;

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;

public class ExportExcelUtil<T> {
        public void export(
            String sheetName, 
            String[] headers, String[] columns, 
            List<T> lists, 
            HttpServletRequest request,
            HttpServletResponse response) throws Exception 
        {
            HSSFWorkbook wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet(sheetName);
            sheet.setDefaultColumnWidth(15);
            HSSFCellStyle style = wb.createCellStyle();

            HSSFRow row = sheet.createRow(0);
            style.setAlignment(HSSFCellStyle.ALIGN_LEFT);

            for (int i = 0; i < headers.length; i++) {
                HSSFCell headerCell = row.createCell(i);
                headerCell.setCellValue(headers[i]);
                headerCell.setCellStyle(style);
            }

            Iterator<T> it = lists.iterator();
            int rowIndex = 0;
            while (it.hasNext()) {
                rowIndex++;
                row = sheet.createRow(rowIndex);
                T t = it.next();
                Field[] fields = t.getClass()
                            .getDeclaredFields();

                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    String fieldName = field.getName();

                    for (int j = 0; j < columns.length; j++) {
                        if (fieldName.equals(columns[j])) {
                        String getMethodName = "get" + 
                            fieldName.substring(0, 1).
                            toUpperCase() + fieldName.
                            substring(1);
                        Class cls = t.getClass();

                        Method getMethod = cls.getMethod(
                            getMethodName, new Class[] {});
                        Object val = getMethod.invoke(
                            t, new Object[] {});
                        String textVal = null;
                        if (null != val) {
                            textVal = val.toString();
                        } else {
                            textVal = null;
                        }
                            row.createCell(j).
                                setCellValue(textVal);
                    }
                }
            }
        }

        //try {
            //默認導出到E盤下
            //FileOutputStream out = new FileOutputStream("E://學生表.xls");
            //wb.write(out);
            //out.close();
            //JOptionPane.showMessageDialog(null, "導出成功!");
        //} catch (Exception e) {
           //JOptionPane.showMessageDialog(null, "導出失敗!");
        //e.printStackTrace();
        //}

        String filename = sheetName + ".xls";
        String filepath = request.getRealPath("/") + filename;
        FileOutputStream out = new FileOutputStream(filepath);
        wb.write(out);
        out.close();

        downloadExcel(filepath, response);
    }


    /**
     * 下載
     */
    public static void downloadExcel(String filepath, HttpServletResponse response)
            throws IOException {
        File file = new File(filepath);
        String fileName = file.getName();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("GBK"), "ISO8859-1"));
        response.setCharacterEncoding("utf-8");
        InputStream fis = new BufferedInputStream(new FileInputStream(file));
        byte[] b = new byte[fis.available()];
        fis.read(b);
        response.getOutputStream().write(b);
        fis.close();
    }

}

首先一個隨便創建任何一個實體類

package testExport;

/**
 * 
 * @author zsl
 *
 */

public class Student {
    private Integer id;
    private String name;
    private String sex;

    public Student(Integer id, String name, String sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

下面就是調用了。
//導出學生表

public String exportUser(HttpServletRequest request,HttpServletResponse response) throws Exception{
    String sheetName = "student";   //導出的Excel名稱
    String [] headers = {"編號","姓名","性別"};
    String [] columns = {"id","name","sex"};
    //添加一些數據,大家可以從數據庫裏讀取
    /爲了方便這裏先寫死,
    List<Student> list = new ArrayList<Student>();
    list.add(new Student(111,"張三","男"));
    list.add(new Student(111,"李四","男"));
    list.add(new Student(111,"王五","女"));
    ExportExcelUtil<Student> util = new ExportExcelUtil<Student>();
    util.export(sheetName,headers,columns,list,request,response);
}

注意:
1、這樣就大功告成了,但是有些問題需要大家自己去解決,比如request 和response 在你們的項目裏是怎麼獲取的;
因爲這裏把下載也包含了,所以程序裏需要這兩個參數,這裏我就沒有寫;
如果大家想要簡單測試一下,可以把request 和 response兩個參數去掉,ExportExcelUtil類裏面的註釋放開,然後註釋下面的代碼註釋掉就可以測試了;
3、需要導出哪些字段,只要在columns裏對應該實體的字段即可;
4、該工具類適用於任何實體類的導出;
5、本人沒有對字段類型進行判斷,導出數據全部爲字符串類型。(大家可以自己改進)
6、這種方式下載,不能用ajax調用導出,必須要使用window.location.href=”excel/export.do”

如果大家需求不同,可以自己在上面代碼基礎上再次進行封裝優化。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章