1. 程式人生 > >簡單springboot+maven+poi匯出

簡單springboot+maven+poi匯出

1. 在pom.xml中新增一下依賴:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.13</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.15</version>
</dependency>

2. 公共方法,功能如下:

       2.1 相容65535行單sheet頁資料限制

       2.2 相容數字型別

       2.3 匯出資料帶格式屬性(邊框,自動調整列寬,字型,帶序號)

       2.4 自定義匯出,提供beanToMap方法,傳入匯出所需欄位名稱,對應欄位屬性,反射呼叫對應get方法獲取屬性值

       2.5 相容火狐瀏覽器/IE瀏覽器

    BeanToMap.java

import com.alibaba.dubbo.common.utils.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class BeanToMap<T> {


    public String getMethodName(String fieldName){
        byte[] buffer = fieldName.getBytes();
        buffer[0] = (byte)(buffer[0]-32);
        String name = new String(buffer);
        return "get"+name;
    }

    public Map<String,Object> getMap(T entity){
        Field[] fields = entity.getClass().getDeclaredFields();
        Map<String,Object> map = new HashMap<>();
        for (int j = 0; j < fields.length; j++) {
            try {
                Method method = entity.getClass().getMethod(getMethodName(fields[j].getName()));
                map.put(fields[j].getName(),method.invoke(entity));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return map;
    }


}

   PoiExcelExport.java

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

public class PoiExcelExport<T> {
    // excle匯出名稱
    private String fileName;
    // excel 表頭
    private String[] heads;
    // excel 列
    private String[] cols;
    // 設定數值型的列 從0開始計數
    private int[] numerics;
    //list集合
    private List<T> list;
    // 輸出流
    private OutputStream out;
    // 建構函式
    public PoiExcelExport(String fileName, String[] heads, String[] cols, List<T> list, OutputStream out) {
        this.fileName = fileName;
        this.heads = heads;
        this.cols = cols;
        this.list = list;
        this.out = out;
    }

    // 建構函式 帶數字型別
    public PoiExcelExport(String fileName, String[] heads, String[] cols, List<T> list, int[] numerics, OutputStream out) {
        this.fileName = fileName;
        this.heads = heads;
        this.cols = cols;
        this.list = list;
        this.numerics = numerics;
        this.out = out;
    }

    public void exportExcel() {

        HSSFWorkbook hssfworkbook = new HSSFWorkbook(); // 建立一個excel物件

        //sheet樣式定義【getColumnTopStyle()/getStyle()均為自定義方法 - 在下面  - 可擴充套件】
        HSSFCellStyle columnTopStyle = this.getColumnTopStyle(hssfworkbook);//獲取列頭樣式物件
        HSSFCellStyle style = this.getStyle(hssfworkbook);                    //單元格樣式物件
        for (int i = 0; i <= (list.size() / 65535); i++) {
            HSSFSheet hssfsheet = hssfworkbook.createSheet(); // 工作表

            // 工作表名稱
            hssfworkbook.setSheetName(i, fileName.replace(".xls", "") + "(第" + (i + 1) + "頁)");
            int beginRows = 65535 * i;
            int endRows = (list.size() > 65535 * (i + 1)) ? 65535 * (i + 1) - 1 : list.size() - 1;
            HSSFRow hssfrowHead = hssfsheet.createRow(0);
            // 輸出excel 表頭
            if (heads != null && heads.length > 0) {
                for (int h = 0; h < heads.length; h++) {
                    HSSFCell hssfcell = hssfrowHead.createCell(h, Cell.CELL_TYPE_STRING);
                    hssfcell.setCellValue(heads[h]);
                    hssfcell.setCellStyle(columnTopStyle);
                }
            }
            // 要設定數值型 列表
            // 是否是數值型
            boolean isnum = false;
            // 輸出excel 資料
            for (int curRow = beginRows; curRow <= endRows; curRow++) {
                // 獲取資料
                BeanToMap<T> btm = new BeanToMap<T>();
                Map<String,Object> hm = btm.getMap(list.get(curRow));
                // 建立excel行 表頭1行 導致資料行數 延後一行
                HSSFRow hssfrow = hssfsheet.createRow(curRow % 65535 + 1);
                // 讀取資料值
                for (int k = 0; k < cols.length; k++) {
                    HSSFCell hssfcell = hssfrow.createCell(k);
                    // hssfcell.setCellValue(hm.get(cols[k])==null?"":hm.get(cols[k]).toString());
                    isnum = false;
                    for (int z = 0; z < numerics.length; z++) {
                        if (numerics[z] == k) {
                            isnum = true;
                            break;
                        }
                    }

                    if (isnum) {

                       if(k==0){
                                hssfcell.setCellValue(curRow+1);
                       } else {
                           if (hm.get(cols[k]) != null || !hm.get(cols[k]).equals("")) {
                               hssfcell.setCellValue(Double.parseDouble(
                                       hm.get(cols[k]) == null ? "" : hm.get(cols[k]).toString().replace(",", "")));
                           }
                       }
                    } else {
                        hssfcell.setCellValue(hm.get(cols[k]) == null ? "" : hm.get(cols[k]).toString());
                    }
                    hssfcell.setCellStyle(style);
                }
            }
            //讓列寬隨著匯出的列長自動適應
            for (int colNum = 0; colNum < heads.length; colNum++) {
                int columnWidth = hssfsheet.getColumnWidth(colNum) / 256;
                for (int rowNum = 0; rowNum < hssfsheet.getLastRowNum(); rowNum++) {
                    HSSFRow currentRow;
                    //當前行未被使用過
                    if (hssfsheet.getRow(rowNum) == null) {
                        currentRow = hssfsheet.createRow(rowNum);
                    } else {
                        currentRow = hssfsheet.getRow(rowNum);
                    }
                    if (currentRow.getCell(colNum) != null) {
                        HSSFCell currentCell = currentRow.getCell(colNum);
                        if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                            int length = currentCell.getStringCellValue().getBytes().length;
                            if (columnWidth < length) {
                                columnWidth = length;
                            }
                        }
                    }
                }
                if(colNum == 0){
                    hssfsheet.setColumnWidth(colNum, (columnWidth-2) * 256);
                }else{
                    hssfsheet.setColumnWidth(colNum, (columnWidth+4) * 256);
                }
            }
        }
        // excel生成完畢,寫到輸出流
        try {
            hssfworkbook.write(out);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * 列頭單元格樣式
     */
    public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {

        // 設定字型
        HSSFFont font = workbook.createFont();
        //設定字型大小
        font.setFontHeightInPoints((short)11);
        //字型加粗
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        //設定字型名字
        font.setFontName("Courier New");
        //設定樣式;
        HSSFCellStyle style = workbook.createCellStyle();
        //設定底邊框;
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        //設定底邊框顏色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        //設定左邊框;
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        //設定左邊框顏色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        //設定右邊框;
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        //設定右邊框顏色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        //設定頂邊框;
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        //設定頂邊框顏色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //在樣式用應用設定的字型;
        style.setFont(font);
        //設定自動換行;
        style.setWrapText(false);
        //設定水平對齊的樣式為居中對齊;
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        //設定垂直對齊的樣式為居中對齊;
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

        return style;

    }

    /*
     * 列資料資訊單元格樣式
     */
    public HSSFCellStyle getStyle(HSSFWorkbook workbook) {
        // 設定字型
        HSSFFont font = workbook.createFont();
        //設定字型大小
        //font.setFontHeightInPoints((short)10);
        //字型加粗
        //font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        //設定字型名字
        font.setFontName("Courier New");
        //設定樣式;
        HSSFCellStyle style = workbook.createCellStyle();
        //設定底邊框;
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        //設定底邊框顏色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        //設定左邊框;
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        //設定左邊框顏色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        //設定右邊框;
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        //設定右邊框顏色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        //設定頂邊框;
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        //設定頂邊框顏色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //在樣式用應用設定的字型;
        style.setFont(font);
        //設定自動換行;
        style.setWrapText(false);
        //設定水平對齊的樣式為居中對齊;
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        //設定垂直對齊的樣式為居中對齊;
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        //資料格式
        style.setDataFormat(HSSFDataFormat.getBuiltinFormat("##0"));

        return style;

    }

}

    ServletUtil.java

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class ServletUtil {
    private String fileName;
    private HttpServletRequest req;
    private HttpServletResponse resp;
    public OutputStream getOut(){
        try {
            return resp.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    public ServletUtil(HttpServletResponse resp){
        this.resp = resp;
    }
    public ServletUtil(String fileName,
                       HttpServletRequest req,
                       HttpServletResponse resp){
        this.fileName = fileName;
        this.req = req;
        this.resp = resp;
    }
    public void poiExcelServlet(){
        resp.setContentType("application/vnd.ms-excel");
        String contentDisposition = "";
        try {
            if (req.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
                contentDisposition = "attachment; filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO8859-1")
                        + "\"";// firefox瀏覽器
            } else {
                contentDisposition = "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"";// IE瀏覽器
            }
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        resp.setHeader("Content-Disposition", contentDisposition);
        resp.setCharacterEncoding("UTF-8");
    }
}

    Controller層:

/**
	 * 賬號資料匯出excel
	 * @param req
	 * @param resp
	 */
	@RequestMapping(value = "/export",method = RequestMethod.GET)
	public void export(@RequestBody String json,HttpServletRequest req,HttpServletResponse resp){
		LOG.info("ENTER /uas/admin/export,paramter is {}",json);
                //準備資料
                List<Model> list = service.getList(json);
		//執行匯出
		String fileName = "自定義檔名稱.xls";
		ServletUtil su = new ServletUtil(fileName, req, resp);
		su.poiExcelServlet();

		String[] heads = {"欄位1","欄位2","欄位3","欄位4"};
		String[] cols = {"field1","field2","field3","field4"};
                //這裡傳第幾個欄位是數字,從0開始
                int[] numerics = {0,2};
		ServletUtil suresp = new ServletUtil(resp);
		PoiExcelExport<Model> pee = new PoiExcelExport<>(fileName, heads, cols, list, numerics, suresp.getOut());
		pee.exportExcel();
	}
over.
文章借鑑 https://www.cnblogs.com/xiaopotian/p/8043147.html,感謝!