成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

EasyExcel為單個(gè)Cell設(shè)置樣式

roundstones / 2819人閱讀

摘要:是阿里巴巴對(duì)封裝的一個(gè)庫(kù),號(hào)稱(chēng)解決了的問(wèn)題,并且在使用上也更方便一些然而我在使用的時(shí)候發(fā)現(xiàn)還是有很多坑,其中一個(gè)比較頭疼的是對(duì)單個(gè)單元格樣式的設(shè)置。

EasyExcel是阿里巴巴對(duì)POI封裝的一個(gè)庫(kù),號(hào)稱(chēng)解決了POI的OOM問(wèn)題,并且在使用上也更方便一些

Github:[](https://github.com/alibaba/ea...

然而我在使用的時(shí)候發(fā)現(xiàn)還是有很多坑,其中一個(gè)比較頭疼的是對(duì)單個(gè)單元格樣式的設(shè)置。EasyExcel提供了一個(gè)BaseRowModel作為每行數(shù)據(jù)的一個(gè)模型,并且其中有一個(gè)屬性cellStyleMap代表每列樣式的集合,本來(lái)我以為這個(gè)只要在自己定義模型的時(shí)候,也把CellStyle定義進(jìn)去就行了,然而,還是我想多了……定義了CellStyle并沒(méi)有什么卵用,這是第一個(gè)蛋疼的地方

/**
 * Excel基礎(chǔ)模型
 * @author jipengfei
 */
public class BaseRowModel {

    /**
     * 每列樣式
     */
    private Map cellStyleMap = new HashMap();

    public void addStyle(Integer row, CellStyle cellStyle){
        cellStyleMap.put(row,cellStyle);
    }

    public CellStyle getStyle(Integer row){
        return cellStyleMap.get(row);
    }

    public Map getCellStyleMap() {
        return cellStyleMap;
    }

    public void setCellStyleMap(Map cellStyleMap) {
        this.cellStyleMap = cellStyleMap;
    }
}

后來(lái)測(cè)試半天,才發(fā)現(xiàn)創(chuàng)建CellStyle時(shí)必須通過(guò)一個(gè)Workbook對(duì)象來(lái)創(chuàng)建,而這個(gè)Workbook不能隨便新建一個(gè)對(duì)象完事兒,得用你當(dāng)前寫(xiě)入的Workbook來(lái)創(chuàng)建對(duì)應(yīng)的CellStyle樣式才能起作用。然而……事情并沒(méi)有那么簡(jiǎn)單,經(jīng)過(guò)我對(duì)源碼的反復(fù)查看,EasyExcel生成excel表的步驟是用一個(gè)ExcelWriter來(lái)寫(xiě)入數(shù)據(jù),并沒(méi)有提供獲取Workbook的方法,不知道什么原因讓阿里巴巴不提供這樣一個(gè)接口……這是第二個(gè)蛋疼的地方

既然沒(méi)有提供接口,那就只能用反射來(lái)硬剛了,下面就直接上代碼了

我這里是在開(kāi)始寫(xiě)數(shù)據(jù)之前就將每張表的CellStyle與每張表關(guān)聯(lián)起來(lái),再在后面的handler中獲取到這個(gè)CellStyle進(jìn)行設(shè)置

package edu.uddp.util;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.event.WriteHandler;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.ExcelBuilderImpl;
import com.sun.corba.se.spi.orbutil.threadpool.Work;
import edu.uddp.enums.CellStyleEnum;
import edu.uddp.model.SignExcelRow;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFSheet;

import java.io.*;
import java.lang.reflect.Field;
import java.util.*;

/**
 * 生成Excel表
 *
 * @author Juzi
 * @date 2018/12/23 12:37
 * Blog https://juzibiji.top
 */
public class ExcelUtil {

    private static Map> cellStyles = new HashMap<>();

    /**
     * 使用java對(duì)象模型創(chuàng)建excel,并使用handler
     * 生成Excel格式為xlsx
     *
     * @param path           Excel生成路徑
     * @param headLineMun    表頭占幾行
     * @param data           傳入的鍵值對(duì)數(shù)據(jù)(key為sheet名,value為sheet數(shù)據(jù))
     * @param handler        自定義的EasyExcel Handler,不使用傳入null即可
     * @param columnWidthMap 每列寬度
     * @throws IOException
     */
    public static void createExcelWithModelAndHandler(
            String path, int headLineMun, Map> data, WriteHandler handler,
            Map columnWidthMap, List cellStyleEnums) throws IOException {

        File file = new File(path);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        OutputStream out = new FileOutputStream(path);
        // ExcelWriter用于導(dǎo)出Excel
        ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(null, out,
                ExcelTypeEnum.XLSX, true, handler);

        // 構(gòu)造單元格樣式
        Workbook workbook = getWorkbook(writer);
        cellStyles.put(workbook, createCellStyle(workbook, cellStyleEnums));

        // sheet的序號(hào),從1開(kāi)始
        int i = 1;
        // 遍歷傳入的sheet名和sheet數(shù)據(jù)來(lái)創(chuàng)建sheet
        for (Map.Entry> entry : data.entrySet()) {
            Sheet sheet = new Sheet(i, headLineMun, entry.getValue().get(0).getClass(), entry.getKey(), null);
            sheet.setColumnWidthMap(columnWidthMap);
            writer.write(entry.getValue(), sheet);
            i++;
        }
        // 必須要調(diào)用finish(),否則數(shù)據(jù)不會(huì)寫(xiě)入文件
        writer.finish();
        out.close();
    }


    /**
     * **獲取workbook**
     * 因?yàn)镋asyExcel這個(gè)庫(kù)設(shè)計(jì)的原因
     * 只能使用反射獲取workbook
     *
     * @param writer
     * @return
     */
    private static Workbook getWorkbook(ExcelWriter writer) {
        Workbook workbook = null;
        try {
            Class clazz1 = Class.forName("com.alibaba.excel.ExcelWriter");
            Field[] fs = clazz1.getDeclaredFields();
            for (Field field : fs) {
                // 要設(shè)置屬性可達(dá),不然會(huì)拋出IllegalAccessException異常
                field.setAccessible(true);
                if ("excelBuilder".equals(field.getName())) {
                    ExcelBuilderImpl excelBuilder = (ExcelBuilderImpl) field.get(writer);
                    Class clazz2 = Class.forName("com.alibaba.excel.write.ExcelBuilderImpl");
                    Field[] fs2 = clazz2.getDeclaredFields();
                    for (Field field2 : fs2) {
                        field2.setAccessible(true);
                        if ("context".equals(field2.getName())) {
                            WriteContext context = (WriteContext) field2.get(excelBuilder);
                            workbook = context.getWorkbook();
                        }
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return workbook;
    }

    public static Map createCellStyle(Workbook workbook, List cellStyleEnums) {
        Map map = new HashMap<>();
        for (CellStyleEnum cellStyleEnum : cellStyleEnums) {
            if (cellStyleEnum.getNo() == 1) {
                CellStyle cellStyle = workbook.createCellStyle();
                cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
                cellStyle.setBorderLeft(BorderStyle.THIN);//左邊框
                cellStyle.setBorderTop(BorderStyle.THIN);//上邊框
                cellStyle.setBorderRight(BorderStyle.THIN);//右邊框
                cellStyle.setAlignment(HorizontalAlignment.CENTER);
                map.put(cellStyleEnum.getName(), cellStyle);
            } else if (cellStyleEnum.getNo() == 2) {
                CellStyle cellStyle = workbook.createCellStyle();
                cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
                cellStyle.setBorderLeft(BorderStyle.THIN);//左邊框
                cellStyle.setBorderTop(BorderStyle.THIN);//上邊框
                cellStyle.setBorderRight(BorderStyle.THIN);//右邊框
                cellStyle.setAlignment(HorizontalAlignment.CENTER);
                cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
                map.put(cellStyleEnum.getName(), cellStyle);
            }
        }
        return map;
    }

    public static Map> getCellStyles() {
        return cellStyles;
    }
}

EasyExcel提供了一個(gè)WriteHandler,我們實(shí)現(xiàn)這個(gè)接口,就可以在每個(gè)單元格寫(xiě)入之后或者每行寫(xiě)入之前來(lái)進(jìn)行攔截(這個(gè)handler設(shè)計(jì)的也很蛋疼),并注入我們自己的業(yè)務(wù)邏輯(設(shè)置單元格樣式)。

package edu.uddp.handler;

import com.alibaba.excel.event.WriteHandler;
import edu.uddp.util.ExcelUtil;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;

import java.util.Map;

/**
 * 第三方庫(kù)EasyExcel的Handler
 * 教師端生成簽到歷史表Excel時(shí)
 * 將未簽到學(xué)生進(jìn)行特殊標(biāo)識(shí)
 *
 * @author Juzi
 * @since 2018/12/22 22:07
 * Blog https://juzibiji.top
 */
public class SignRecordExcelHandler implements WriteHandler {
    @Override
    public void sheet(int i, Sheet sheet) {

    }

    @Override
    public void row(int i, Row row) {

    }

    @Override
    public void cell(int i, Cell cell) {
        // 獲取當(dāng)前workbook對(duì)應(yīng)的CellStyle集合
        Map cellStyleMap = ExcelUtil.getCellStyles().get(cell.getSheet().getWorkbook());

        // 從第二行開(kāi)始設(shè)置格式,第一行是表頭
        if (cell.getRowIndex() > 0) {
            if (i == 7 && "未簽到".equals(cell.getStringCellValue())) {
                // 該生未簽到
                for (int j = 0; j < 8; j++) {
                    cell.getRow().getCell(j).setCellStyle(cellStyleMap.get("未簽到"));
                }
            } else if (i == 8 && "已簽到".equals(cell.getRow().getCell(7).getStringCellValue())) {
                // 該生已簽到
                for (int j = 0; j < 9; j++) {
                    cell.getRow().getCell(j).setCellStyle(cellStyleMap.get("已簽到"));
                }
            }else if(i == 8 && "未簽到".equals(cell.getRow().getCell(7).getStringCellValue())){
                cell.setCellStyle(cellStyleMap.get("已簽到"));
            }
        }
    }
}

上面有一些簡(jiǎn)單的邏輯處理,就不一一介紹了。

若文章有任何問(wèn)題,歡迎留言指出——作者博客:桔子筆記

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72841.html

相關(guān)文章

  • springboot批量導(dǎo)入excel數(shù)據(jù)

    摘要:背景小白今天閑著沒(méi)事,在公司摸魚(yú),以為今天有事無(wú)聊的一天,突然上頭說(shuō)小子,今天實(shí)現(xiàn)一下批量導(dǎo)入數(shù)據(jù)吧,當(dāng)時(shí)我的內(nèi)心是拒絕的,然后默默打開(kāi)。介紹框架本身并不支持讀取,所有讀取需要借助一些框架。 1 背景 小白今天閑著沒(méi)事,在公司摸魚(yú),以為今天有事無(wú)聊的一天,突然上頭說(shuō)小子,今天實(shí)現(xiàn)一下批量導(dǎo)入Excel數(shù)據(jù)吧,當(dāng)時(shí)我的內(nèi)心是拒絕的,然后默默打開(kāi)idea。 2 介紹 2.1 框架 java...

    Bmob 評(píng)論0 收藏0
  • 前端周刊第 4 期

    摘要:最快的方式測(cè)量屏幕上所有東西的尺寸,切圖必備收費(fèi),不貴,代碼沙箱,前端代碼在線編輯器,在線編程時(shí)代的到來(lái)。歡迎訂閱原周報(bào)改名為周刊更合適這個(gè)專(zhuān)欄每周末發(fā)布,同步更新在前端學(xué)堂微信公眾號(hào)。 周刊是個(gè)人本周內(nèi)看到的有意思的東西,或是技術(shù)學(xué)習(xí)的好文章或好資源,收集分享給大家。 開(kāi)源庫(kù)&框架動(dòng)向 Java 11 (LTS) 版本正式發(fā)布 TypeScript 發(fā)布 3.1.1 版本 Crea...

    Tonny 評(píng)論0 收藏0
  • java 導(dǎo)出 excel 最佳實(shí)踐,java 大文件 excel 避免OOM(內(nèi)存溢出) exce

    摘要:消費(fèi)之后,多線程處理文件導(dǎo)出,生成文件后上傳到等文件服務(wù)器。前端直接查詢(xún)并且展現(xiàn)對(duì)應(yīng)的任務(wù)執(zhí)行列表,去等文件服務(wù)器下載文件即可。這客戶體驗(yàn)不友好,而且網(wǎng)絡(luò)傳輸,系統(tǒng)占用多種問(wèn)題。拓展閱讀導(dǎo)出最佳實(shí)踐框架 產(chǎn)品需求 產(chǎn)品經(jīng)理需要導(dǎo)出一個(gè)頁(yè)面的所有的信息到 EXCEL 文件。 需求分析 對(duì)于 excel 導(dǎo)出,是一個(gè)很常見(jiàn)的需求。 最常見(jiàn)的解決方案就是使用 poi 直接同步導(dǎo)出一個(gè) exc...

    K_B_Z 評(píng)論0 收藏0
  • CSS命名規(guī)范

    摘要:命名規(guī)則樣式類(lèi)名全部用小寫(xiě),首字符必須是字母,禁止數(shù)字或其他特殊字符。其他禁止使用在樣式表命名中,一律使用命名。什么是命名空間通過(guò)統(tǒng)一的命名規(guī)范定義命名的范圍,成為命名空間。1 前端開(kāi)發(fā)命名規(guī)范 1.1 為什么要制定CSS命名規(guī)范 統(tǒng)一的命名規(guī)范,便于多人開(kāi)發(fā)維護(hù)時(shí)代碼統(tǒng)一,減少項(xiàng)目溝通和交接的成本,增加代碼的語(yǔ)義化。 1.2 CSS命名規(guī)則 樣式類(lèi)名全部用小寫(xiě),首字符必須是字母,禁止數(shù)...

    vvpale 評(píng)論0 收藏0
  • PC端CSS布局匯總

    摘要:因?yàn)槎撕鸵苿?dòng)端布局差異較大,所以我將兩端布局分開(kāi)講,本文章將針對(duì)端的布局進(jìn)行講解,以下代碼只寫(xiě)關(guān)鍵代碼。為了提高網(wǎng)頁(yè)性能,考慮到,表格元素盡量少用,有其他選擇的情況盡量用其他布局。 前言 此文章是 解剖CSS布局原理 的續(xù)集,之前那篇文章講的都是理論,本文章講具體的實(shí)例,根據(jù)自己對(duì)布局的理解與開(kāi)發(fā)經(jīng)驗(yàn)分為以下幾類(lèi)。 因?yàn)镻C端和移動(dòng)端布局差異較大,所以我將兩端布局分開(kāi)講,本文章將針對(duì)P...

    zhangxiangliang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<