若依管理系統源碼分析-導出Excel時怎樣通過注解中readConverterExp實現格式化導出列的顯示格式(0和1格式化為是否)


場景

在數據庫中存儲某些個是否的字段時,有時會使用tinint進行存儲

 

 

這樣會在實體類中生成布爾類型的變量

private Boolean sfkt;

有時也會用int進行存儲是否

 

 

那么在實體類中就可能用Integer和String進行是否字段的存取

private String sfcl;

那么在使用若依自帶的導出時,如果不加修改,則會直接將對應的字段的列導出為0或者1,true或者false。

如果想要根據此列的0和1進而顯示是和否怎樣顯示。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。

實現

如果是0和1格式化為是和否

找到對應的實體類中的屬性,在注解上添加

@Excel(name = "是否處理完成",readConverterExp = "0=否,1=是")
private String sfcl;

添加讀取轉換表達式屬性readConverterExp就可以實現,具體見下面源碼分析。

如果是true和false格式化為是和否

@Excel(name = "是否跨天",readConverterExp = "false=否,true=是")
private Boolean sfkt;

表達式的格式要固定如上,值可以自己根據要求去添加。

下面分析為什么這樣添加就可以。

源碼分析

在SpringbBoot后台接口中

    @GetMapping("/export")
    public AjaxResult export(KqBcgl kqBcgl)
    {
        List<KqBcgl> list = kqBcglService.getBcListByNameToExport(kqBcgl);
        ExcelUtil<KqBcgl> util = new ExcelUtil<KqBcgl>(KqBcgl.class);
        return util.exportExcel(list, "bcgl");
    }

其中list是查詢數據庫的數據。

然后調用工具類生成工具類對象,主要是調用exportExcel方法來生成Excel

在方法中

    public AjaxResult exportExcel(List<T> list, String sheetName)
    {
        this.init(list, sheetName, Type.EXPORT);
        return exportExcel();
    }

調用了init方法,生成一些工作簿以及列等相關信息的對象。

在方法createExcelField中

   private void createExcelField()
    {
        this.fields = new ArrayList<Object[]>();
        List<Field> tempFields = new ArrayList<>();
        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        for (Field field : tempFields)
        {
            // 單注解
            if (field.isAnnotationPresent(Excel.class))
            {
                putToField(field, field.getAnnotation(Excel.class));
            }

            // 多注解
            if (field.isAnnotationPresent(Excels.class))
            {
                Excels attrs = field.getAnnotation(Excels.class);
                Excel[] excels = attrs.value();
                for (Excel excel : excels)
                {
                    putToField(field, excel);
                }
            }
        }
    }

和方法createWorkbook中

    public void createWorkbook()
    {
        this.wb = new SXSSFWorkbook(500);
    }

主要是讀取注解和調用了POI的一些方法用來初始化Excel的相關對象。

構建excel數據的方法主要是exportExcel()

 

   public AjaxResult exportExcel()
    {
        OutputStream out = null;
        try
        {
            // 取出一共有多少個sheet.
            double sheetNo = Math.ceil(list.size() / sheetSize);
            for (int index = 0; index <= sheetNo; index++)
            {
                createSheet(sheetNo, index);

                // 產生一行
                Row row = sheet.createRow(0);
                int column = 0;
                // 寫入各個字段的列頭名稱
                for (Object[] os : fields)
                {
                    Excel excel = (Excel) os[1];
                    this.createCell(excel, row, column++);
                }
                if (Type.EXPORT.equals(type))
                {
                    fillExcelData(index, row);
                }
            }
            String filename = encodingFilename(sheetName);
            out = new FileOutputStream(getAbsoluteFile(filename));
            wb.write(out);
            return AjaxResult.success(filename);
        }
        catch (Exception e)
        {
            log.error("導出Excel異常{}", e.getMessage());
            throw new CustomException("導出Excel失敗,請聯系網站管理員!");
        }
        finally
        {
            if (wb != null)
            {
                try
                {
                    wb.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
            if (out != null)
            {
                try
                {
                    out.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
        }
    }

這其中使用填充excel的方法fillExcelData

    public void fillExcelData(int index, Row row)
    {
        int startNo = index * sheetSize;
        int endNo = Math.min(startNo + sheetSize, list.size());
        for (int i = startNo; i < endNo; i++)
        {
            row = sheet.createRow(i + 1 - startNo);
            // 得到導出對象.
            T vo = (T) list.get(i);
            int column = 0;
            for (Object[] os : fields)
            {
                Field field = (Field) os[0];
                Excel excel = (Excel) os[1];
                // 設置實體類私有屬性可訪問
                field.setAccessible(true);
                this.addCell(excel, row, vo, field, column++);
            }
        }
    }

上面的fields是讀取的注解列表,

     /**
     * 注解列表
     */
    private List<Object[]> fields;

遍歷每個注解對象后調用addCell方法

 

   public Cell addCell(Excel attr, Row row, T vo, Field field, int column)
    {
        Cell cell = null;
        try
        {
            // 設置行高
            row.setHeight((short) (attr.height() * 20));
            // 根據Excel中設置情況決定是否導出,有些情況需要保持為空,希望用戶填寫這一列.
            if (attr.isExport())
            {
                // 創建cell
                cell = row.createCell(column);
                cell.setCellStyle(styles.get("data"));

                // 用於讀取對象中的屬性
                Object value = getTargetValue(vo, field, attr);
                String dateFormat = attr.dateFormat();
                String readConverterExp = attr.readConverterExp();
                if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
                {
                    cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value));
                }
                else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
                {
                    cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp));
                }
                else
                {
                    // 設置列類型
                    setCellVo(value, attr, cell);
                }
            }
        }
        catch (Exception e)
        {
            log.error("導出Excel失敗{}", e);
        }
        return cell;
    }

在這里是執行填充單元格的方法,其中

  String readConverterExp = attr.readConverterExp();

就是獲取上面設置的注解readConverterExp屬性

 else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
     {
          cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp));
      }

判斷如果不為空的話將單元格的值和傳遞的表達式傳遞給方法convertByExp

    /**
     * 解析導出值 0=男,1=女,2=未知
     * 
     * @param propertyValue 參數值
     * @param converterExp 翻譯注解
     * @return 解析后值
     * @throws Exception
     */
    public static String convertByExp(String propertyValue, String converterExp) throws Exception
    {
        try
        {
            String[] convertSource = converterExp.split(",");
            for (String item : convertSource)
            {
                String[] itemArray = item.split("=");
                if (itemArray[0].equals(propertyValue))
                {
                    return itemArray[1];
                }
            }
        }
        catch (Exception e)
        {
            throw e;
        }
        return propertyValue;
    }

 

首先將表達式按照逗號分隔,獲取分隔后的數組,然后遍歷數組。

再根據=分隔,如果等號左邊即分割后數組的第一個值與單元格的值相等,就返回等號右邊的值即分隔后的第二個值。

這樣就實現了按照指定表達式將單元格的值進行格式化顯示。

 


免責聲明!

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



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