一、出现问题的原因
在实现Excel中单元格的复制功能实现上,之前的代码是这样写的
/**
* copyCellValue() 方法用于将源单元格的值复制到目标单元格中。
* @param sourceCell 是源单元格对象
* @param destCell 是目标单元格对象
*/
public static void copyCellValue(Cell sourceCell, Cell destCell) {
// 如果 sourceCell 和 destCell 中任意一个为 null,则不进行操作,方法直接返回。
if (sourceCell == null || destCell == null) {
return;
}
// 首先,将源单元格的单元格样式克隆到目标单元格上,然后再将源单元格的值赋给目标单元格。
CellStyle sourceStyle = sourceCell.getCellStyle();
CellStyle destinationStyle = destCell.getSheet().getWorkbook().createCellStyle();
destinationStyle.cloneStyleFrom(sourceStyle);
destCell.setCellStyle(destinationStyle);
// 如果源单元格的数据类型为字符串类型,则复制字符串值;如果为布尔类型,则复制布尔值;如果为公式类型,则复制公式字符串;如果为数字类型,则复制数字值。
if (sourceCell.getCellTypeEnum().equals(CellType.STRING)) {
destCell.setCellValue(sourceCell.getStringCellValue());
} else if (sourceCell.getCellTypeEnum().equals(CellType.BOOLEAN)) {
destCell.setCellValue(sourceCell.getBooleanCellValue());
} else if (sourceCell.getCellTypeEnum().equals(CellType.FORMULA)) {
destCell.setCellValue(sourceCell.getCellFormula());
} else if (sourceCell.getCellTypeEnum().equals(CellType.NUMERIC)) {
if (DateUtil.isCellDateFormatted(sourceCell)) {
destCell.setCellValue(sourceCell.getDateCellValue());
} else {
destCell.setCellValue(sourceCell.getNumericCellValue());
}
// 如果源单元格是空的,则在目标单元格中写入一个空串("")。
} else if (sourceCell.getCellTypeEnum().equals(CellType.BLANK)) {
destCell.setCellValue("");
}
}
这样写在进行大部分数据类型复制的过程的都没有问题,但除了公式类型的数据不能成功复制,网上有一些博主的做法是直接将
if (DateUtil.isCellDateFormatted(sourceCell)) {
destCell.setCellValue(sourceCell.getDateCellValue());
} else {
destCell.setCellValue(sourceCell.getNumericCellValue());
}
复制到公式的类型下,当然这样也可以成功的将源单元格中的数据复制过来,而且复制过来的数据类型是相同的,但是这里有一个问题,就是当某个单元格是依赖这个复制过来的单元格时(比如有公式依赖关系),这种情况下就会出现,这个依赖的单元格的值就不能自动生成。
拿图说话吧,就是当从别的表复制110.73这个值过来后,下面的0这个数字根据公式关系就应该立刻发生改变,但结果是,按照映射关系,指定的单元格的值复制成功了,但是先关联的单元格的值并没有发生改变。
根本原因就是,仅仅只复制了内容没有复制样式,在这里体现出来的就是,公式没有复制过来
二、解决问题
尝试方法1、
将 destCell.setCellValue(sourceCell.getCellFormula()); 该成 destCell.setCellFormula(sourceCell.getCellFormula());
结果失败,公式转换不过去,计算出的结果通通为 0
尝试方法2、
经过查阅资料发现要在生成文件前加个一行代码,命令公式生效
于是我将 destinationWorkbook.setForceFormulaRecalculation(true);// 执行公式
分别和这两个
destCell.setCellValue(sourceCell.getCellFormula()); destCell.setCellFormula(sourceCell.getCellFormula());
进行组合并再尝试运行,发现还是不行。甚至直接解析不了了
尝试方法3、
正确尝试!!!!!!
destCell.setCellFormula(String.valueOf(sourceCell.getNumericCellValue()));
其实,解决问题的思路很简单,在经历之前的尝试后发现,只有把公式作为 NUMERIC 类型读进来才会有效果,但这样就不能用 setCellFormula 方法了,所以进行转换了一下,再结合
destinationWorkbook.setForceFormulaRecalculation(true);// 执行公式
就可以得到正确结果了。