excel導出工具

介紹

excel導出工具java

整個項目的代碼結構以下git

com
\---utils
    +---demo # 案例相關
    |   |   ExcelExportApplication.java # springboot啓動類
    |   |
    |   +---bean
    |   |       DemoBean.java # 測試bean
    |   |
    |   +---controller
    |   |       ExcelExportController.java # 測試url訪問彈出下載excel文件和導出excel到文件
    |   |
    |   \---exportParam
    |       |   DemoExportParam.java # 導出參數
    |       |
    |       \---dataConversion
    |               HobbyConversion.java # 愛好屬性導出轉換類
    |               SexConversion.java # 性別屬性導出轉換類
    |
    \---excelExport # 導出工具包
        |   AsyncExportExcel.java #多線程導出
        |   ExportExcel.java # 導出工具類
        |
        +---data
        |       BaseParam.java # 基礎導出參數類
        |
        +---dataConversion
        |       DataExportConversion.java # 屬性導出轉換接口
        |
        +---defaultDataHandle # 默認的數據處理
        |       AbstractDataHandler.java
        |       BooleanDataHandler.java
        |       DataHandlerFactory.java
        |       DateDataHandler.java
        |       StringDataHandler.java
        |
        \---style # 默認的樣式
                AbstractCellStyle.java
                DefaultDataCellStyle.java
                DefaultTitleCellStyle.java

簡單的來講excel導出能夠分爲幾步github

  1. 得到須要導出的數據
  2. 設置excel的工做表(sheet)名稱
  3. 設置當前工做表的第一行,也就是標題行
  4. 將數據逐行填充,有須要的數據進行轉換

使用

ExportExcel工具類

首先實例化ExportExcel工具類,我這裏提供了三個構造函數spring

public ExportExcel() 

public ExportExcel(SXSSFWorkbook workbook) 

public ExportExcel(SXSSFWorkbook workbook, AbstractCellStyle titleCellStyle, AbstractCellStyle dataCellStyle)

一般使用的是無參構造函數。另外兩個都須要本身實例化workbook對象,有三個參數的構造函數,須要傳入workbook、標題行樣式對象、數據行樣式對象。關於樣式對象下方有說明。springboot


實例化ExportExcel工具類以後,須要調用exportExcel方法,方法定義以下多線程

public void exportExcel(String sheetName, BaseParam baseParam, OutputStream out)
參數名稱 參數內容
sheetName 工做表(sheet)的名稱
baseParam 繼承BaseParam的導出參數對象(後面會說明)
out OutputStream對象、例如FileOutputStream

樣式抽象類AbstractCellStyle

public abstract class AbstractCellStyle {
    Workbook workbook;
    CellStyle style;
    Font font;

    public AbstractCellStyle(Workbook workbook) {
        this.workbook = workbook;
        style = workbook.createCellStyle();
        font = workbook.createFont();
    }

    protected abstract void setStyle();

    protected abstract void setFont();


    public CellStyle getCellStyle() {
        style.setFont(font);
        return style;
    }
}

經過繼承樣式抽象類AbstractCellStyle,能夠實現下方兩個方法app

// 設置樣式
protected abstract void setStyle();
// 設置字體
protected abstract void setFont();

經過這兩個方法能夠修改單元格的樣式和字體。ide

基礎導出參數類BaseParam

BaseParam類代碼以下函數

public class BaseParam {
    public List data = new ArrayList<>();
    public List<ColumnParam> columnParams = new ArrayList<>();
    
    //Set Get Constructor

    /**
     * 數據行參數
     */
    public class ColumnParam{```}
}

屬性

能夠看到BaseParam類有兩個屬性工具

public List data = new ArrayList<>();
public List<ColumnParam> columnParams = new ArrayList<>();

data毫無疑問是存放須要導出的數據,而columnParams是存放每一列的數據,如今來看看內部類ColumnParam

內部類ColumnParam

public class ColumnParam{
        private String headerName;
        private String fieldName;
        private DataExportConversion conversion;//數據轉換
        
        //Set Get Constructor
    }
屬性
屬性名稱 屬性內容
headerName 標題名稱
fieldName 實體類對應的屬性名
conversion 數據轉換對象
數據轉換接口DataExportConversion
public interface DataExportConversion<T> {
    String transferData(T data);
}

好比說,獲取出來的數據是0、1,而後你須要將數據轉換成女、男,那麼就能夠實現數據轉換接口DataExportConversion,自定義轉換輸出的格式,代碼以下

public class SexConversion implements DataExportConversion<Integer> {
    @Override
    public String transferData(Integer data) {
        if (0 == data){
            return "女";
        } else if (1 == data){
            return "男";
        }
        return "不詳";
    }
}

案例

場景

原始數據以下

姓名 性別 出生日期 愛好(List對象)
塵心 0 2018-08-08 14:59:11 [舞刀,弄槍]
千月 1 2018-08-08 14:59:11 [唱歌,跳舞]

須要轉換爲下方內容

姓名 性別 出生日期 愛好
塵心 2018-08-08 14:59:11 舞刀,弄槍
千月 2018-08-08 14:59:11 唱歌,跳舞

實體類以下

public class DemoBean {

    //姓名
    private String name;

    //性別,0->女,1->男
    private Integer sex;

    //出生日期
    private Date birthday;

    //愛好
    private List<String> hobbies;

    //Set Get
    
}

數據轉換

能夠看到有兩個屬性須要轉換,分別是性別和愛好。性別的數據轉換上面已經有了,就不貼出來了,下面是愛好的數據轉換

public class HobbyConversion implements DataExportConversion<List<String>> {
    @Override
    public String transferData(List<String> data) {
        StringBuilder hobby = new StringBuilder();

        for (String s:data){
            hobby.append(s).append(",");
        }

        //移除最後一個逗號
        if (hobby.length() >= 1){
            hobby.deleteCharAt(hobby.length()-1);
        }

        return hobby.toString();
    }
}

導出參數類

數據轉換類寫好了以後,開始編寫導出參數類,代碼以下

public class DemoExportParam extends BaseParam {
    public DemoExportParam(List<DemoBean> list) {
        setData(list);
        setColumnParam();
    }

    private void setColumnParam() {
        columnParams.add(new ColumnParam("姓名","name"));
        columnParams.add(new ColumnParam("性別","sex", new SexConversion()));
        columnParams.add(new ColumnParam("出生日期","birthday"));
        columnParams.add(new ColumnParam("愛好","hobbies", new HobbyConversion()));
    }
}

在實例化DemoExportParam時,須要傳入導出的數據,同時設置每一列對應的列參數ColumnParam。
能夠看到總共有4個列參數

  • 第一列標題名稱爲姓名,對應的屬性名稱爲name
  • 第二列標題名稱爲性別,對應的屬性名稱爲sex,還有數據轉換對象SexConversion
  • 第三列標題名稱爲出生日期,對應的屬性名稱爲birthday
  • 第四列標題名稱爲愛好,對應的屬性名稱爲hobbies,數據轉換對象HobbyConversion

導出

先寫一個生成數據的方法,以下

private List<DemoBean> getDemoBeanList(){
    DemoBean man = new DemoBean();
    DemoBean woman = new DemoBean();

    String[] manHobbys = {"舞刀", "弄槍"};
    String[] womanHobbys = {"唱歌", "跳舞"};

    man.setName("塵心").setBirthday(new Date()).setSex(0).setHobbies(Arrays.asList(manHobbys));
    woman.setName("千月").setBirthday(new Date()).setSex(1).setHobbies(Arrays.asList(womanHobbys));


    //將兩個bean添加到list中
    List<DemoBean> list = new ArrayList<>();
    list.add(man);
    list.add(woman);

    return list;
}

接下來有兩種數據導出方式,一種是url訪問彈出下載excel文件,另一種是導出excel到文件

url訪問彈出下載excel文件

@ResponseBody
@RequestMapping("/export")
public void exportByWeb(HttpServletResponse response) throws IOException {

    OutputStream out = new BufferedOutputStream(response.getOutputStream());

    response.reset();
    String headStr = "attachment; filename=" + URLEncoder.encode("導出demo.xlsx", "utf-8");
    response.setContentType("application/vnd.ms-excel;charset=UTF-8");
    response.setHeader("Content-Disposition", headStr);

    //得到導出數據
    List<DemoBean> list = getDemoBeanList();

    DemoExportParam demoExportParam = new DemoExportParam(list);

    ExportExcel exportExcel = new ExportExcel();
    exportExcel.exportExcel("demo", demoExportParam, response.getOutputStream());

    out.flush();
    out.close();
}

導出excel到文件

@Test
public void exportByFile() throws IOException {

    File file = new File("F:\\導出demo.xlsx");
    FileOutputStream out = new FileOutputStream(file);

    //得到導出數據
    List<DemoBean> list = getDemoBeanList();

    DemoExportParam demoExportParam = new DemoExportParam(list);

    ExportExcel exportExcel = new ExportExcel();
    exportExcel.exportExcel("demo", demoExportParam, out);

    out.flush();
    out.close();
}

項目位置:https://github.com/rainbowda/utils/tree/master/excel_export,有須要的能夠去下載。

相關文章
相關標籤/搜索