Java工具類--使用原生POI實現導出Excel功能1


為什么要使用原生的POI

項目中需要用到導出Excel的功能,一開始用的是阿里的easyExcel,據說是性能比較好,原本本地測試沒啥問題,一到了線上的環境后,就出現了幾個報錯,百度了一下大概是說缺少了某種字體啥的,可參考的解決方案不多,再說我不能保證到時現場的技術人員懂得裝這啥啥字體,最后還是自己封裝一下原生的POI,爭取使用起來跟easyExcel差不多的簡單快捷,對於小項目來說是夠用的。

快速使用

1.在pom.xml中導入依賴

<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.10-FINAL</version>
</dependency>

2.新建一個ExcelUtil工具類,復制以下的代碼

package com.rui.hellospringboot.Utils;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;

public class ExportExcelUtil {

    /**
     * 導出excel表
     * @param response
     * @param name
     * @throws IOException
     */
    public static <T>void exportExel(HttpServletResponse response,List<T> list,String[] title, String name) {

        try {
            HSSFWorkbook wb = generateExelFile(list, title,name);

            //到這里,excel就已經生成了,然后就需要通過流來寫出去
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            //將excel寫入流
            wb.write(byteArrayOutputStream);
            //設置文件標題
            String outFile = name + ".xls";
            //設置返回的文件類型
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            //對文件編碼
            outFile = response.encodeURL(new String(outFile.getBytes("gb2312"), "iso8859-1"));
            //使用Servlet實現文件下載的時候,避免瀏覽器自動打開文件
            response.addHeader("Content-Disposition", "attachment;filename=" + outFile);
            //設置文件大小
            response.setContentLength(byteArrayOutputStream.size());
            //創建Cookie並添加到response中
            Cookie cookie = new Cookie("fileDownload", "true");
            cookie.setPath("/");
            response.addCookie(cookie);
            //將流寫進response輸出流中
            ServletOutputStream outputstream = response.getOutputStream();
            byteArrayOutputStream.writeTo(outputstream);

            byteArrayOutputStream.close();
            outputstream.flush();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成Excel文件
     * @param list
     * @return
     */
    public static <T> HSSFWorkbook generateExelFile(List<T> list,String[] title,String sheetName) throws IllegalAccessException {
        //生成exel文件
        //創建工作薄
        HSSFWorkbook wb = new HSSFWorkbook();
        //創建工作表
        HSSFSheet sheet = wb.createSheet();
        sheet.createFreezePane(0, 1, 0, 1);
        wb.setSheetName(0, sheetName);

        /*//默認寬高
        sheet.setDefaultColumnWidth((short) 20);
        sheet.setDefaultRowHeight((short) 2000);*/

        //創建樣式和字體
        HSSFCellStyle curStyle = wb.createCellStyle();
        HSSFFont curFont = wb.createFont();
        Font font = wb.getFontAt((short) 0);
        CellStyle style = wb.createCellStyle();
        font.setCharSet(HSSFFont.DEFAULT_CHARSET);
        //更改默認字體大小
        font.setFontHeightInPoints((short) 12);
        font.setFontName("宋體");
        style.setFont(font);

        //創建行列
        HSSFRow nRow = sheet.createRow(0);
        HSSFCell nCell = nRow.createCell(0);
        //設置列的樣式(具體實現在后面......)
        nCell.setCellStyle(mainTitleStyle(curStyle, curFont));
        //控制行號列號
        int rowNo = 0;

        //設置標題到第一行的列中
        nRow = sheet.createRow(rowNo++);
        for (int i = 0; i < title.length; i++) {
            nCell = nRow.createCell(i);
            nCell.setCellValue(title[i]);
            nCell.setCellStyle(textStyle(curStyle, curFont));
        }
        //創建樣式和字體
        curStyle = wb.createCellStyle();
        curFont = wb.createFont();


        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

        //封裝exel 表體
        for (int i = 0; i < list.size(); i++) {
            T dto = list.get(i);
            Class<?> aClass = dto.getClass();
            nRow = sheet.createRow(rowNo++);
            //HSSFCell nCell;
            int colNo = 0;//控制列號
            //第一列
            Field[] fields = aClass.getDeclaredFields();
            for (int j=0;j<title.length;j++){
                Field field=fields[j];
                field.setAccessible(true);
                nCell = nRow.createCell(colNo++);
                nCell.setCellValue(field.get(dto).toString());
                nCell.setCellStyle(textStyle(curStyle, curFont));
            }
        }
        return wb;
    }

    /**
     * 表格內容樣式
     *
     * @param curStyle
     * @param curFont
     * @return
     */
    public static HSSFCellStyle textStyle(HSSFCellStyle curStyle, HSSFFont curFont) {
        curStyle.setAlignment(CellStyle.ALIGN_CENTER);    //水平居中
        curStyle.setWrapText(true); // 自動換行
        curFont.setFontName("宋體");//字體
        curFont.setFontHeightInPoints((short) 10);//字體大小
        curStyle.setFont(curFont); // 綁定關系
        return curStyle;
    }

    /**
     * 表格標題樣式
     *
     * @param curStyle
     * @param curFont
     * @return
     */
    public static HSSFCellStyle mainTitleStyle(HSSFCellStyle curStyle, HSSFFont curFont) {
        curStyle.setAlignment(CellStyle.ALIGN_GENERAL);    //水平居中
        curFont.setFontHeightInPoints((short) 16);//字體大小
        curStyle.setFont(curFont); // 綁定關系
        return curStyle;
    }
}

3.工具類的使用

訪問 /exportExcel 路徑就能下載關於Person表的Excel了。

    @GetMapping(value = "/exportExcel")
    public void exportExcel(HttpServletResponse response) throws IOException {

        Person p1 = new Person(01, "zhangsan", 20,"廣州", 5000);
        Person p2 = new Person(02, "lisi", 20,"杭州", 8000);
        Person p3 = new Person(03, "wangwu", 20,"上海", 15000);
        List<Person> personList = Arrays.asList(p1, p2, p3);
        String[] title={"序號","姓名","年齡","地址","工資"};
        ExportExcelUtil.exportExel(response,personList,title,"用戶統計表");
    }

4.效果

在這里插入圖片描述

注意事項:

如果上述的Person類中有些字段不需要導出到Excel的話,應該把不需要導出的字段放在最后面,然后標題titile里面只寫需要導出的字段即可(一定要按順序)。

針對這些問題,后續加上了注解方式,使用起來更加簡便:

使用原生POI實現導出Excel功能2-注解方式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM