EasyPoi多sheet頁

 

背景:

有一個很重要的功能需要記錄日誌,在排查問題時需要將日誌內容導出Excel,並且針對不同的賬號對個別導出字段進行隱藏

準備工作:

引包

        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.1.0</version>
        </dependency>

EasyPoiUtils.java

@Component
public class EasyPoiUtils {
    private final static Logger logger = LoggerFactory.getLogger(EasyPoiUtils.class);
    /**
     * 功能描述:複雜導出Excel,包括文件名以及表名。創建表頭
     *
     * @param list           導出的實體類
     * @param title          表頭名稱
     * @param sheetName      sheet表名
     * @param pojoClass      映射的實體類
     * @param isCreateHeader 是否創建表頭
     * @param fileName
     * @param response
     * @return
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setCreateHeadRows(isCreateHeader);
        exportParams.setStyle(EasyPoiExcelStyleUtil.class);
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setCreateHeadRows(isCreateHeader);
        exportParams.setStyle(EasyPoiExcelStyleUtil.class);
        defaultExport(list, pojoClass, fileName, exportParams);
    }

    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
            downLoadExcel(fileName, workbook);
        }
    }
    /**
     * 功能描述:Excel導出
     *
     * @param fileName 文件名稱
     * @param workbook Excel對象
     * @return
     */
    public static void downLoadExcel(String fileName, Workbook workbook) {
        try {
            FileOutputStream fos = new FileOutputStream(fileName);
            workbook.write(fos);
        } catch (IOException e) {
            System.out.println("文件打開異常,請確認是否已打開");
        }
    }
    /**
     * 功能描述:複雜導出Excel,包括文件名以及表名,不創建表頭
     *
     * @param list      導出的實體類
     * @param title     表頭名稱
     * @param sheetName sheet表名
     * @param pojoClass 映射的實體類
     * @param fileName
     * @param response
     * @return
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setStyle(EasyPoiExcelStyleUtil.class);
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    /**
     * 功能描述:Map 集合導出
     *
     * @param list     實體集合
     * @param fileName 導出的文件名稱
     * @param response
     * @return
     */
    public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        defaultExport(list, fileName, response);
    }

    /**
     * 功能描述:默認導出方法
     *
     * @param list         導出的實體集合
     * @param fileName     導出的文件名
     * @param pojoClass    pojo實體
     * @param exportParams ExportParams封裝實體
     * @param response
     * @return
     */
    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
            downLoadExcel(fileName, response, workbook);
        }
    }

    /**
     * 功能描述:Excel導出
     *
     * @param fileName 文件名稱
     * @param response
     * @param workbook Excel對象
     * @return
     */
    public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 功能描述:默認導出方法
     *
     * @param list     導出的實體集合
     * @param fileName 導出的文件名
     * @param response
     * @return
     */
    private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        if (workbook != null) {
            downLoadExcel(fileName, response, workbook);
        }
    }

    /**
     * 功能描述:根據文件路徑來導入Excel
     *
     * @param filePath   文件路徑
     * @param titleRows  表標題的行數--對應數據對象
     * @param headerRows 表頭行數
     * @param pojoClass  Excel實體類
     * @return
     */
    public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
        //判斷文件是否存在
        if (StringUtils.isBlank(filePath)) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new RuntimeException("模板不能爲空");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 功能描述:根據接收的Excel文件來導入Excel,並封裝成實體類
     *
     * @param file       上傳的文件
     * @param titleRows  表標題的行數
     * @param headerRows 表頭行數
     * @param pojoClass  Excel實體類
     * @return
     */
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
        if (file == null) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new RuntimeException("excel文件不能爲空");
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        return list;
    }

    /**
     * 功能描述:根據接收的Excel文件來導入多個sheet,根據索引可返回一個集合
     * @param filePath   導入文件路徑
     * @param sheetIndex  導入sheet索引
     * @param titleRows  表標題的行數
     * @param headerRows 表頭行數
     * @param pojoClass  Excel實體類
     * @return
     */
    public static <T> List<T> importExcel(String filePath,int sheetIndex,Integer titleRows, Integer headerRows, Class<T> pojoClass) {
        // 根據file得到Workbook,主要是要根據這個對象獲取,傳過來的excel有幾個sheet頁
        ImportParams params = new ImportParams();
        // 第幾個sheet頁
        params.setStartSheetIndex(sheetIndex);
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new RuntimeException("模板不能爲空");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 功能描述:根據接收的Excel文件來導入多個sheet,根據索引可返回一個集合
     * @param list   實體對象集合
     * @param type  表格類型
     * @return
     */
    public static Workbook exportExcel(List<Map<String, Object>> list, ExcelType type) {
        Workbook workbook = getWorkbook(type, 0);
        Iterator var3 = list.iterator();

        while(var3.hasNext()) {
            Map<String, Object> map = (Map)var3.next();
            ExcelExportService service = new ExcelExportService();
            service.createSheet(workbook, (ExportParams)map.get("title"), (Class)map.get("entity"), (Collection)map.get("data"));
        }
        return workbook;
    }
    private static Workbook getWorkbook(ExcelType type, int size) {
        if (ExcelType.HSSF.equals(type)) {
            return new HSSFWorkbook();
        } else {
            return (Workbook)(size < USE_SXSSF_LIMIT ? new XSSFWorkbook() : new SXSSFWorkbook());
        }
    }
}

EasyPoiExcelStyleUtil .java 

public class EasyPoiExcelStyleUtil implements IExcelExportStyler {
    private static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT");
    private static final short FONT_SIZE_TEN = 10;
    private static final short FONT_SIZE_ELEVEN = 11;
    private static final short FONT_SIZE_TWELVE = 12;
    /**
     * 大標題樣式
     */
    private CellStyle headerStyle;
    /**
     * 每列標題樣式
     */
    private CellStyle titleStyle;
    /**
     * 數據行樣式
     */
    private CellStyle styles;

    public EasyPoiExcelStyleUtil(Workbook workbook) {
        this.init(workbook);
    }

    /**
     * 初始化樣式
     *
     * @param workbook
     */
    private void init(Workbook workbook) {
        this.headerStyle = initHeaderStyle(workbook);
        this.titleStyle = initTitleStyle(workbook);
        this.styles = initStyles(workbook);
    }

    /**
     * 大標題樣式
     *
     * @param color
     * @return
     */
    @Override
    public CellStyle getHeaderStyle(short color) {
        return headerStyle;
    }

    /**
     * 每列標題樣式
     *
     * @param color
     * @return
     */
    @Override
    public CellStyle getTitleStyle(short color) {
        return titleStyle;
    }

    /**
     * 數據行樣式
     *
     * @param parity 可以用來表示奇偶行
     * @param entity 數據內容
     * @return 樣式
     */
    @Override
    public CellStyle getStyles(boolean parity, ExcelExportEntity entity) {
        return styles;
    }

    /**
     * 獲取樣式方法
     *
     * @param dataRow 數據行
     * @param obj     對象
     * @param data    數據
     */
    @Override
    public CellStyle getStyles(Cell cell, int dataRow, ExcelExportEntity entity, Object obj, Object data) {
        return getStyles(true, entity);
    }

    /**
     * 模板使用的樣式設置
     */
    @Override
    public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) {
        return null;
    }

    /**
     * 初始化--大標題樣式
     *
     * @param workbook
     * @return
     */
    private CellStyle initHeaderStyle(Workbook workbook) {
        CellStyle style = getBaseCellStyle(workbook);
        style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true));
        return style;
    }

    /**
     * 初始化--每列標題樣式
     *
     * @param workbook
     * @return
     */
    private CellStyle initTitleStyle(Workbook workbook) {
        CellStyle style = getBaseCellStyle(workbook);
        style.setFont(getFont(workbook, FONT_SIZE_ELEVEN, false));
        //背景色
        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        return style;
    }

    /**
     * 初始化--數據行樣式
     *
     * @param workbook
     * @return
     */
    private CellStyle initStyles(Workbook workbook) {
        CellStyle style = getBaseCellStyle(workbook);
        style.setFont(getFont(workbook, FONT_SIZE_TEN, false));
        style.setDataFormat(STRING_FORMAT);
        return style;
    }

    /**
     * 基礎樣式
     *
     * @return
     */
    private CellStyle getBaseCellStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        //下邊框
        style.setBorderBottom(BorderStyle.THIN);
        //左邊框
        style.setBorderLeft(BorderStyle.THIN);
        //上邊框
        style.setBorderTop(BorderStyle.THIN);
        //右邊框
        style.setBorderRight(BorderStyle.THIN);
        //水平居中
        style.setAlignment(HorizontalAlignment.CENTER);
        //上下居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        //設置自動換行
        style.setWrapText(true);
        return style;
    }

    /**
     * 字體樣式
     *
     * @param size   字體大小
     * @param isBold 是否加粗
     * @return
     */
    private Font getFont(Workbook workbook, short size, boolean isBold) {
        Font font = workbook.createFont();
        //字體樣式
        font.setFontName("宋體");
        //是否加粗
        font.setBold(isBold);
        //字體大小
        font.setFontHeightInPoints(size);
        return font;
    }
}

隱藏字段代碼 HiddenColumnUtil.java

public class HiddenColumnUtil<T> {
    /**
     * 需要被反射的對象,使用泛型規範傳入對象
     */
    public T t;

    /**
     * 動態更改EasyPoi中控制列顯示的值
     *
     * @param columnName 需要轉換的列屬性名稱
     * @param target     默認true
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public void hihdColumn(String columnName, Boolean target) throws Exception {
        if (t == null) {
            throw new ClassNotFoundException("TARGET OBJECT NOT FOUNT");
        }
        if (StringUtils.isEmpty(columnName)) {
            throw new NullPointerException("COLUMN NAME NOT NULL");
        }
        if (target == null) {
            target = true;
        }
        //獲取目標對象的屬性值
        Field field = t.getClass().getDeclaredField(columnName);
        //獲取註解反射對象
        Excel excelAnnon = field.getAnnotation(Excel.class);
        //獲取代理
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(excelAnnon);
        Field excelField = invocationHandler.getClass().getDeclaredField("memberValues");
        excelField.setAccessible(true);
        Map memberValues = (Map) excelField.get(invocationHandler);
        memberValues.put("isColumnHidden", target);
    }

實體類

@Data
public class TestLogDTO {

    @Excel(name = "test1",orderNum = "1",width = 20,isColumnHidden = false)
    private String test1;

    @Excel(name = "test2",orderNum = "2",width = 20,isColumnHidden = false)
    private String test2;

    @Excel(name = "test3",orderNum = "3",width = 20,isColumnHidden = false)
    private String test3;
}

具體實現代碼

@Api(value = "日誌導出", tags = { "日誌導出" })
@RestController
@RequestMapping("/testExport")
public class TestLogController {

    @Autowired
    TestLogMapper testLogMapper;

    @PostMapping("/export")
    @ResponseBody
    @ResponseStatus(HttpStatus.CREATED)
    public String export(Long logId,String type,String excelName){
        TestLogPO testLogPO = testLogMapper.getLog(logId,type);
        if(StringUtils.isNullOrEmpty(testLogPO )){
            throw new ServiceBizException("日誌爲空!");
        }
        // Feature.OrderedField 防止數據轉成map順序發生改變
        Map<String,Object> logMap = JSONObject.parseObject(testLogPO.getResponseJson(), Map.class, Feature.OrderedField);
        Workbook workBook = null;
        try {
            List<Map<String, Object>> sheetsList = new ArrayList<>();
            if("0".equals(type)){
                setTest1Data(logMap,sheetsList,type);
            }else{
                // 針對不同類型有不同處理情況,此處省略setTest2Data
                setTest2Data(logMap,sheetsList,type);
            }
            // 執行方法
            workBook = EasyPoiUtils.exportExcel(sheetsList, ExcelType.HSSF);
            String name = excelName == "" ? "d:/ddd.xls" : "d:/"+excelName+".xls";
            FileOutputStream fos = new FileOutputStream(name);
            workBook.write(fos);
            fos.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(workBook != null) {
                try {
                    workBook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "success";
    }

    /**
     * 創建sheet頁
     * @param sheetName sheet頁名稱
     * @param clazz 類
     * @param list 呈現Excel具體數據
     * @return sheet頁對象
     */
    private Map<String, Object> setParmas(String sheetName,Object clazz,Object list){
        // 創建參數對象(用來設定excel得sheet得內容等信息)
        ExportParams exportParams = new ExportParams();
        // 設置sheet得名稱
        exportParams.setSheetName(sheetName);
        // 創建sheet1使用得map
        Map<String, Object> exportMap = new HashMap<>();
        // title的參數爲ExportParams類型,目前僅僅在ExportParams中設置了sheetName
        exportMap.put("title", exportParams);
        // 模版導出對應得實體類型
        exportMap.put("entity", clazz);
        // sheet中要填充得數據
        exportMap.put("data", list);
        return exportMap;
    }

    /**
     * 設置test1數據
     * @param  temporaryEndMap 日誌源
     * @param  sheetsList  sheet頁集合
     */
    private void setTest1Data(Map<String,Object> logMap,List<Map<String, Object>> sheetsList,String type){
        // 需求列表
        List<TestLogDTO> list = JSONArray.parseArray(JSON.toJSONString(logMap.get("list")), TestLogDTO.class);
        Map<String, Object> testMap = setParmas("測試列表",TestLogDTO.class,list);
        List<TestLogDTO> finalList = JSONArray.parseArray(JSON.toJSONString(logMap.get("finalList")), TestLogDTO.class);
        Map<String, Object> finalResultMap= setParmas("結果列表",TestLogDTO.class,finalList);

        // 處理隱藏字段
        hiddenColumn(list,type);
        sheetsList.add(testMap);
        sheetsList.add(finalResultMap);
    }

    /**
     * 處理不同類型隱藏字段
     * @param  list 數據源
     * @param  type 
     */
    private void hiddenColumn(List<TestLogDTO> list,String type){
        for (TestLogDTO item : list) {
            HiddenColumnUtil<TestLogDTO> easyPoiUtil = new HiddenColumnUtil<>();
            easyPoiUtil.t = item;
            try {
                if("0".equals(type)){
                    easyPoiUtil.hihdColumn("test2", true);
                    easyPoiUtil.hihdColumn("test3", true);
                }else if("1".equals(type)){
                    easyPoiUtil.hihdColumn("test1", true);
                    easyPoiUtil.hihdColumn("test3", true);
                }else{
                    easyPoiUtil.hihdColumn("test1", true);
                    easyPoiUtil.hihdColumn("test2", true);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

 

大部分代碼出自於:

網上各種找找抄抄,已經不記得瀏覽過哪些博客了

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章