easypoi导出--深度解析为什么,数字类型列的单元格不能合并不能为空

easypoi导出--深度解析为什么,数字类型列的单元格不能合并不能为空

问题一:数字类型列的单元格不能合并

easypoi导出时,给数字格式的列做纵向合并,前期发现:数字格式进行合并会报错,想要进行单元格合并的话单元格必须是字符串格式。
经过对源码的分析最终找到:PoiMergeCellUtil 这个类里的mergeCells 这个方法,
在这个方法中有一句代码:

String text = row.getCell(index).getStringCellValue();

这个不可以获取数值类型的单元格的数据,所以报错。继续观察发现:在“ getStringCellValue”这方法所在的接口中还有一个方法:

double getNumericCellValue();

我个人觉得可以在源码中加一个判断,从而使用“getNumericCellValue”这个方法,以达到数值单元格合并的效果。至于为什么easypoi没有这么做,因为没有更多文档以及个人理解问题的原因,我就不得而知了

mergeCells 方法的源码:

public static void mergeCells(Sheet sheet, Map<Integer, int[]> mergeMap, int startRow, int endRow) {
        Map<Integer, MergeEntity> mergeDataMap = new HashMap();
        if (mergeMap.size() != 0) {
            Set<Integer> sets = mergeMap.keySet();

            label55:
            for(int i = startRow; i <= endRow; ++i) {
                Row row = sheet.getRow(i);
                Iterator var9 = sets.iterator();

                while(true) {
                    while(true) {
                        if (!var9.hasNext()) {
                            continue label55;
                        }

                        Integer index = (Integer)var9.next();
                        if (row != null && row.getCell(index) != null) {
                            /**
                             * 这个getStringCellValue 方法不能获取数值类型的单元格的数据。所以会报错
                             */
                            String text = row.getCell(index).getStringCellValue();
                            if (StringUtils.isNotEmpty(text)) {
                                hanlderMergeCells(index, i, text, mergeDataMap, sheet, row.getCell(index), (int[])mergeMap.get(index));
                            } else {
                                mergeCellOrContinue(index, mergeDataMap, sheet);
                            }
                        } else if (mergeDataMap.get(index) != null && ((MergeEntity)mergeDataMap.get(index)).getEndRow() == 0) {
                            ((MergeEntity)mergeDataMap.get(index)).setEndRow(i - 1);
                        }
                    }
                }
            }

            if (mergeDataMap.size() > 0) {
                Iterator var11 = mergeDataMap.keySet().iterator();

                while(var11.hasNext()) {
                    Integer index = (Integer)var11.next();
                    if (((MergeEntity)mergeDataMap.get(index)).getEndRow() > ((MergeEntity)mergeDataMap.get(index)).getStartRow()) {
                        sheet.addMergedRegion(new CellRangeAddress(((MergeEntity)mergeDataMap.get(index)).getStartRow(), ((MergeEntity)mergeDataMap.get(index)).getEndRow(), index, index));
                    }
                }
            }

        }
    }

getRichStringCellValue方法源码

public String getStringCellValue() {
        HSSFRichTextString str = this.getRichStringCellValue();
        return str.getString();
	}

public HSSFRichTextString getRichStringCellValue() {
        switch(this._cellType) {
        case STRING:
            return this._stringValue;
        case BLANK:
            return new HSSFRichTextString("");
        case FORMULA:
            FormulaRecordAggregate fra = (FormulaRecordAggregate)this._record;
            checkFormulaCachedValueType(CellType.STRING, fra.getFormulaRecord());
            String strVal = fra.getStringValue();
            return new HSSFRichTextString(strVal == null ? "" : strVal);
        default:
            throw typeMismatch(CellType.STRING, this._cellType, false);
        }
    }

问题二:数字类型列的单元格不能为空

规定某一列是数字格式后,如果该列的某个单元格无数据是空白或者null,就会赋值成默认值:0;
在easypoi的"BaseExportService"这个类中的:"createDoubleCell"这个方法中它只会给数据不是null并且数据长度大于0的单元格赋值你规定的数据值,其余的会通过走”cell.setCellType(0);“这个语句将空值赋值上默认值:0.0D

流转过程:
createListCells方法中使用:

this.createDoubleCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? this.getStyles(false, entity) : this.getStyles(true, entity), entity);

将null改变成: “”
在:createDoubleCell中给有值的赋值,并且所有数据都要走:cell.setCellType(0);
在HSSFCell这个类的方法:setCellType 中使用语句:
(第二个参数true是用于启用setValue)

this.setCellType(cellType, true, row, col, styleIndex);

从这个setCellType方法中调用:

nrec.setValue(this.getNumericCellValue());

最终将默认值0.0D赋值上:
在这里插入图片描述
createListCells源码:

public void createListCells(Drawing patriarch, int index, int cellNum, Object obj, List<ExcelExportEntity> excelParams, Sheet sheet, Workbook workbook, short rowHeight) throws Exception {
        Row row;
        if (sheet.getRow(index) == null) {
            row = sheet.createRow(index);
            if (rowHeight != -1) {
                row.setHeight(rowHeight);
            }
        } else {
            row = sheet.getRow(index);
            if (rowHeight != -1) {
                row.setHeight(rowHeight);
            }
        }

        int k = 0;

        for(int paramSize = excelParams.size(); k < paramSize; ++k) {
            ExcelExportEntity entity = (ExcelExportEntity)excelParams.get(k);
            Object value = this.getCellValue(entity, obj);
            if (entity.getType() == BaseEntityTypeConstants.STRING_TYPE) {
                this.createStringCell(row, cellNum++, value == null ? "" : value.toString(), row.getRowNum() % 2 == 0 ? this.getStyles(false, entity) : this.getStyles(true, entity), entity);
                if (entity.isHyperlink()) {
                    row.getCell(cellNum - 1).setHyperlink(this.dataHandler.getHyperlink(row.getSheet().getWorkbook().getCreationHelper(), obj, entity.getName(), value));
                }
            } else if (entity.getType() == BaseEntityTypeConstants.DOUBLE_TYPE) {
                this.createDoubleCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? this.getStyles(false, entity) : this.getStyles(true, entity), entity);
                if (entity.isHyperlink()) {
                    row.getCell(cellNum - 1).setHyperlink(this.dataHandler.getHyperlink(row.getSheet().getWorkbook().getCreationHelper(), obj, entity.getName(), value));
                }
            } else {
                this.createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), obj);
            }
        }

    }

createDoubleCell源码:

public void createDoubleCell(Row row, int index, String text, CellStyle style, ExcelExportEntity entity) {
        Cell cell = row.createCell(index);
        if (text != null && text.length() > 0) {
            cell.setCellValue(Double.parseDouble(text));
        }

        cell.setCellType(0);
        if (style != null) {
            cell.setCellStyle(style);
        }

        this.addStatisticsData(index, text, entity);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Easypoi是一个用于POI操作的Java库,可以方便地操作Excel文件。导出动态合并单元格Easypoi的一个功能特性,可以通过一定的操作来实现。 首先,需要使用Easypoi提供的注解@ExcelCollection来标注需要导出数据集合,并设置合并和行。具体代码如下: ```java @ExcelCollection(name = "成绩表", orderNum = "1") private List<Student> studentList; @ExcelEntity(name = "学生信息") public class Student { @Excel(name = "学生姓名", mergeVertical = true) private String name; @Excel(name = "学生年龄") private Integer age; // 省略getter和setter方法 } ``` 其中,`@ExcelCollection`注解用于标注需要导出数据集合,`name`属性设置导出的sheet名称,`orderNum`属性设置导出的sheet顺序,`@ExcelEntity`注解用于标注实体类。 在`Student`类中,使用`@Excel`注解来标注需要导出的字段,`name`属性设置导出名,`mergeVertical`属性设置是否垂直合并单元格。 接下来,使用Easypoi提供的`ExcelExportUtil.exportExcel`方法来导出Excel文件,具体代码如下: ```java ExcelExportUtil.exportExcel(new ExportParams("成绩单", "学生信息"), Student.class, studentList); ``` 其中,`ExportParams`类用于设置导出的参数,包括文件名和sheet名称。 通过以上的步骤,即可使用Easypoi导出动态合并单元格Excel文件。 ### 回答2: Easypoi 是一个方便快捷的 Java Excel 操作工具类库,可以用来进行Excel 文件的导入和导出操作。它提供了丰富的功能,其中之一就是动态合并单元格。 使用 Easypoi 进行动态合并单元格导出操作,需要以下步骤: 1. 导入 Easypoi 的相关依赖包,并在项目中引入相应的类或方法。 2. 创建一个导出Excel 模板,定义需要合并单元格的位置。 3. 在代码中通过创建一个 Sheet 对象来表示 Excel 表格,并通过定义一系的 CellRangeAddress 对象来表示需要合并单元格区域。 4. 使用 Sheet 对象的 addMergedRegion 方法将定义好的单元格区域添加到 Sheet 中。 5. 将创建好的 Sheet 对象添加到 Workbook 中。 6. 通过输出流将 Workbook 写入到文件中,即可实现导出带有动态合并单元格Excel 文件。 动态合并单元格是一种非常实用的功能,可以使导出Excel 文件更加简洁和易读。而 Easypoi 提供的动态合并单元格的功能,可以帮助我们通过简单的代码实现这一操作,提高了开发的效率和便利性。 总之,通过 Easypoi导出功能,我们可以轻松地实现动态合并单元格的操作,使导出Excel 文件更加美观和易于查看。 ### 回答3: Easypoi是一款强大的Java Excel工具库,可以实现Excel的导入和导出操作。导出动态合并单元格是指根据特定条件对Excel中的单元格进行合并操作。 在使用Easypoi导出Excel,可以通过特定的逻辑判断来确定需要合并单元格,并使用Easypoi提供的合并单元格API来实现。 首先,需要创建一个Excel导出的模板,可以使用Excel模板工具直接在Excel中编辑,或者使用Easypoi提供的Excel模板注解来标注需要合并单元格。 然后,在Java代码中使用Easypoi的相关API来进行导出操作。首先,使用Workbook对象来创建一个Excel工作簿,然后创建Sheet对象。接着,使用Easypoi的相关API来设置表头、填充数据等操作。当需要合并单元格,可以使用Sheet对象的merge方法来进行合并操作。 在设置完所有需要合并单元格后,使用Easypoi的相关API将工作簿导出Excel文件。 最后,可以通过HttpServletResponse将导出Excel文件返回给前端,或者将文件保存到本地。 总而言之,使用Easypoi导出动态合并单元格的步骤主要包括:创建Excel模板、使用Easypoi的API进行数据填充和合并单元格操作、导出Excel文件。通过这些步骤,就可以轻松实现动态合并单元格导出操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值