阿里巴巴EasyExcel使用(1)-簡單寫數據


一、說明

最近公司開發一個財務使用的系統,報表比較多。 以前用過POI,JXL,也遇到過OOM問題, 所以學習一下阿里的Excel工具:https://github.com/alibaba/easyexcel

開發中主要用到:

① 簡單數據導出,也就是查詢實體導出(這里一般會自定義導出某些字段)

②自定義單元格樣式,比如高亮顯示"小計","總計"行等

③合並單元格

那就先來試試簡單數據導出吧

、pom引入

從官方文檔上,目前版本2.2.0-beta1,那我們隨便選一個2.X的版本,網上資料一般是1.1.1版本的,1.X和2.X版本個人感覺差別是有點大的~~

 <!-- 阿里開源EXCEL -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <!-- <version>1.1.1</version>-->
            <version>2.1.6</version>
        </dependency>

三、准備工作

這里准備兩個實體,一個是官方文檔的實體 DemoData類(帶注解),一個是自定義的User類

@Data
public class DemoData {
    @ExcelProperty("字符串標題")
    private String string;
    @ExcelProperty("日期標題")
    private Date date;
   @ExcelProperty("數字標題")
    private Double doubleData;
    /**
     * 忽略這個字段
     */
    @ExcelIgnore
    private String ignore;
}
@Data
public class User {
    private String uid;
    private String name;
    private Integer age;
    private Date birthday;
}

准備模擬數據

/**
     * 模擬實體數據
     *
     * @return
     */
    private List<DemoData> getDemoDataList() {
        List<DemoData> list = new ArrayList<DemoData>();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字符串" + i);
            //data.setDate(new Date());
            //設置屬性一部分為空值
            if (i % 2 == 0) {
                data.setDoubleData(null);
            } else {
                data.setDate(new Date());
            }
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }


    /**
     * 模擬實體數據
     *
     * @return
     */
    private List<User> getUserList() {
        List<User> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setUid("識別碼" + i);
            user.setAge(i * 10);
            //設置屬性一部分為空值
            if (i % 2 == 0) {
                user.setBirthday(new Date());
            } else {
                user.setBirthday(null);
            }
            user.setName("用戶名" + i);
            list.add(user);
        }
        return list;
    }

 在盤符准備2個Excel文件用於導入數據,我用的是 I:\\temp\\writeDemo1.xlsx 和 I:\\temp\\writeDemo2.xlsx

 設置表頭和內容的策略,這個是官方文檔復制過來的。

/**
     * 獲取策略,這個策略是 頭是頭的樣式 內容是內容的樣式 其他的策略可以自己實現
     *
     * @return
     */
    private HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
        // 頭的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景設置為紅色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());

        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 10);

        headWriteCellStyle.setWriteFont(headWriteFont);
        // 內容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 這里需要指定 FillPatternType 為FillPatternType.SOLID_FOREGROUND 不然無法顯示背景顏色.頭默認了 FillPatternType所以可以不指定
        //contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景綠色
        //contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
        //WriteFont contentWriteFont = new WriteFont();
        // 字體大小
        //contentWriteFont.setFontHeightInPoints((short)20);
        //contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 這個策略是 頭是頭的樣式 內容是內容的樣式 其他的策略可以自己實現
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        return horizontalCellStyleStrategy;
    }

 

四、設置列寬

1.X的版本是通過生成sheet,使用sheet設置寬度,2.X版本后大部分方法已經過期,不推薦使用了,而大部分都是使用EasyExcel類直接構造並實現大部分功能;

根據官方文檔的提示只需要注冊寫入處理器就可以了(WriteHandler),我這里直接復制一份過來修修改改~紅色代碼部分主要是關鍵部分

/**
 * 自定義攔截器
 *
 * @author
 */
public class CustomSheetWriteHandler implements SheetWriteHandler {
    //列寬集合
    private List<Integer> columnWidths;
    //構造
    public CustomSheetWriteHandler(List<Integer> columnWidths) {
        this.columnWidths = columnWidths;
    }

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomSheetWriteHandler.class);

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        LOGGER.info("第{}個Sheet寫入成功。", writeSheetHolder.getSheetNo());

        // 區間設置 第一列第一行和第二行的數據。由於第一行是頭,所以第一、二行的數據實際上是第二三行
       /* CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 2, 0, 0);
        DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();
        DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"測試1", "測試2"});
        DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
        writeSheetHolder.getSheet().addValidationData(dataValidation);*/
        LOGGER.info("普通策略設置setColumnWidth開始~");
        if(CollectionUtils.isNotEmpty(columnWidths)){
            for (int i = 0; i < columnWidths.size(); i++) { writeSheetHolder.getSheet().setColumnWidth(i, columnWidths.get(i)); } }
        LOGGER.info("普通策略設置setColumnWidth結束~");
    }
}

 

五、根據注解導出數據到Excel文件中

   /**
     * 寫入到固定文件中
     *
     * @throws IOException
     */
    @Test
    public void writeToExcelFile() {
        //寫入的文excel文件
        String fileName = "I:\\temp\\writeDemo1.xlsx";
        //獲取頭和內容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();

        //列寬的策略,寬度是小單位
        Integer columnWidthArr[] = {3000, 6000};
        List<Integer> columnWidths = Arrays.asList(columnWidthArr);
        CustomSheetWriteHandler customSheetWriteHandler = new CustomSheetWriteHandler(columnWidths);

        // 根據用戶傳入字段 假設我們只要導出 string date
        String[] filds = {"string", "date"};

        //獲取模擬的實體數據集合
        List<DemoData> demoDataList = getDemoDataList();

        //這里需要指定寫用哪個class去寫,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉
        EasyExcel.write(fileName, DemoData.class)
                .registerWriteHandler(horizontalCellStyleStrategy)
                .registerWriteHandler(customSheetWriteHandler)
                //這個是導出需要展示的列
                .includeColumnFiledNames(Arrays.asList(filds))
                .sheet("模板")
                .doWrite(demoDataList);
    }

效果:

 

 

 

六、自定義導出數據到Excel文件中

    /**
     * 寫入到固定文件中,這里不使用注解的方式寫入列和對應的屬性
     *
     * @throws IOException
     */
    @Test
    public void writeToExcelFile2() {
        //寫入的文excel文件
        String fileName = "I:\\temp\\writeDemo2.xlsx";
        //獲取頭和內容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();

        //列寬的策略,寬度是小單位
        Integer columnWidthArr[] = {3000, 3000, 2000, 6000};
        List<Integer> columnWidths = Arrays.asList(columnWidthArr);
        CustomSheetWriteHandler customSheetWriteHandler = new CustomSheetWriteHandler(columnWidths);

        // 根據用戶傳入字段 假設我們只要導出 string date
        String[] filds = {"uid", "name", "age", "birthday"};

        String[] headers = {"唯一識別碼", "姓名", "年齡", "生日"};

        List head = getHeadByFilds(headers);

        //獲取模擬的實體數據集合
        List<User> userList = getUserList();

        //這里指定頭的名字去寫入,然后寫到第一個sheet,名字為模板 然后文件流會自動關閉
        EasyExcel.write(fileName)
                .head(head)
                .registerWriteHandler(horizontalCellStyleStrategy)
                .registerWriteHandler(customSheetWriteHandler)
                .includeColumnFiledNames(Arrays.asList(filds))
                .sheet("模板")
                .doWrite(userList);
    }

效果:

六、總結 

后面繼續實現合並單元格、自定義單元格、web導出和導入等功能~

 


免責聲明!

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



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