导入Excel文件的时候公式为【#Ref!】应该怎么解决?
前言
在我们使用Excel时,经常会遇到一个问题,就是导入Excel时公式显示为【#Ref!】的情况。这通常是因为公式中引用的单元格已被删除或对应的工作表被删除,导致原公式无法识别对应的参数而显示为【#Ref!】。
比如在一张Excel表中,sheet1 中 A1 单元格的公式为‘=Sheet2!B1’,如果 Sheet2 由于各种历史原因丢失,那么此时 sheet1 中 A1 计算结果为【#Ref!】,如果此时想查找到 Sheet2 怎么办呢?今天小编就将为大家介绍如何用葡萄城公司的Java API 组件——GrapeCity Documents for Excel(以下简称GcExcel)来查找丢失的Sheet页。
具体操作步骤
1)准备
首先创建公式
Workbook workbook = new Workbook();
IWorksheet workSheet = workbook.getWorksheets().get(0);
workSheet.setName("sheet1");
workSheet.getRange(1, 1).setFormula("sheet2!F7");
workSheet.getRange(3, 3).setFormula("Sheet3!A1");
2)查找
接下来,通过Find进行遍历查询所有的【#Ref!】公式,GcExcel提供了各种类型的查找替换。
FindOptions tempVar = new FindOptions();
//设置通过文本查找
tempVar.setLookIn(FindLookIn.Texts);
IRange range = null;
do {
range = searchRange.find("Ref", range, tempVar);
if (range == null) {
break;
} else {
//在这里做相应的逻辑
}
} while (true);
上述代码是查找替换的基础代码,我们发现上述代码 searchRange 未定义,searchRange 可以是整个 sheet, 也可以是一片区域,接下来我们定义searchRange 。
3)特殊单元格
GcExcel 提供了找到错误公式的能力,通过 specialCells 可以查找到错误公式,并返回错误公式的区域为第二步中的searchRange变量 。
IRange searchRange = workSheet.getCells().specialCells(SpecialCellType.Formulas, SpecialCellsValue.Errors);
现在我们已经找到了对应的所有为【#Ref!】的单元格,接下来开始做查找成功之后的逻辑。
4)公式解析
查找成功后,可以通过 range.getFormula() 获取到公式,接下来对公式进行解析,由于 Excel 公式有的简单,有的复杂,不能单纯判断等号后,感叹号前的字符串为sheet 名称,我们要通过公式树去遍历解析。
GcExcel 提供了公式解析器,调用 parse 拿到公式树,之后可以通过 getWorksheetName 获取 sheetName,相关代码如下:
//将公式中等号去掉,并进行解析
FormulaSyntaxTree syntaxTree = FormulaSyntaxTree.Parse(range.getFormula().replaceFirst("=", ""));
addNotFoundSheet(syntaxTree.getRoot(), workbook);
addNotFoundSheet 定义如下:
private static void addNotFoundSheet(SyntaxNode node, Workbook workbook) {
if (node == null) {
return;
}
if (node instanceof ReferenceNode) {
String sheetName = ((ReferenceNode) node).getReference().getWorksheetName();
if (workbook.getWorksheets().get(sheetName) == null) {
IWorksheet tempSheet = workbook.getWorksheets().add();
tempSheet.setName(sheetName);
}
}
for (SyntaxNode child : node.getChildren()) {
addNotFoundSheet(child, workbook);
}
}
在上述代码中首先判断node是否是 ReferenceNode 类型,如果是的话,通过 node.getReference().getWorksheetName() 获取 sheetName,并判断当前工作簿是否存在此sheet,如果不存在则进行添加。
处理后,对其子节点进行递归判断,重复上述步骤,直到 node 节点为 null,退出递归查询。
最后附上完整版的代码:
public static void main(String[] args) throws Exception {
Workbook workbook = new Workbook();
IWorksheet workSheet = workbook.getWorksheets().get(0);
workSheet.setName("sheet1");
workSheet.getRange(1, 1).setFormula("sheet2!F7");
workSheet.getRange(3, 3).setFormula("Sheet3!A1");
FindOptions tempVar = new FindOptions();
tempVar.setLookIn(FindLookIn.Texts);
IRange searchRange = workSheet.getCells().specialCells(SpecialCellType.Formulas, SpecialCellsValue.Errors);
IRange range = null;
do {
range = searchRange.find("Ref", range, tempVar);
if (range == null) {
break;
} else {
FormulaSyntaxTree syntaxTree = FormulaSyntaxTree.Parse(range.getFormula().replaceFirst("=", ""));
addNotFoundSheet(syntaxTree.getRoot(), workbook);
}
} while (true);
}
private static void addNotFoundSheet(SyntaxNode node, Workbook workbook) {
if (node == null) {
return;
}
if (node instanceof ReferenceNode) {
String sheetName = ((ReferenceNode) node).getReference().getWorksheetName();
if (workbook.getWorksheets().get(sheetName) == null) {
IWorksheet tempSheet = workbook.getWorksheets().add();
tempSheet.setName(sheetName);
}
}
for (SyntaxNode child : node.getChildren()) {
addNotFoundSheet(child, workbook);
}
}
通过上述代码,可以查找到”sheet2“与”sheet3“,并进行添加。
总结
以上就是使用GcExcel解决导入Excel文件的时候公式为【#Ref!】问题的全过程,如果您想了解更多详细信息,欢迎点击这里查看。
扩展链接:
如何使用 Blazor 框架在前端浏览器中导入/导出 Excel XLSX
简便实用:在 ASP.NET Core 中实现 PDF 的加载与显示
导入Excel文件的时候公式为【#Ref!】应该怎么解决?的更多相关文章
- .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)
.Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) [原文地址] 通过MVC控制器导出导入Excel文件(可用于java SSH架构) public cl ...
- Java POI导入Excel文件
今天在公司需要做个导入Excel文件的功能,所以研究了一下,参考网上的一些资料总算是做出来了,在此记录一下防止以后忘记怎么弄. 本人用的是poi3.8,所以需要的JAR包如下: poi-3.8.jar ...
- phpexcel导入excel文件报the filename xxx is not recognised as an OLE file错误。
工作中频繁会用phpexcel类导入excel文件的数据到数据库,目前常用的excel文件格式有:xls.csv.xlsx. 刚开始,针对xls文件,使用如下程序,能正常运行: $objReader ...
- YII使用PHPExcel导入Excel文件的方法
1.下载phpexcel,将压缩包中的classes复制到protected/extensions下并修改为PHPExcel. 2.修改YII配置文件config/main.php 'import'= ...
- springMVC(5)---导入excel文件数据到数据库
springMVC(5)---导入excel文件数据到数据库 上一篇文章写了从数据库导出数据到excel文件,这篇文章悄悄相反,写的是导入excel文件数据到数据库.上一篇链接:springMVC(4 ...
- excel数据 入库mysql 和 mysql数据 导入excel文件
1.excel数据入库mysql 首先准备excel文件, 标红的地方需要留意,一个是字段名所在行,一个表名对应页: 然后私用mysql工具 navicat, 选择数据库,然后导入文件, 选中相应ex ...
- java后端导入excel模板和导入excel文件去读数据
模板转载地址:https://www.cnblogs.com/zhangyangtao/p/9802948.html 直接上代码(我是基于ssm写的demo,导入文件目前只能读取.xls后缀的exce ...
- C# Aspose.Cells方式导入Excel文件
读取Excel 类 我返回的是DataTable 类型 也可以返回DataSet类型 public class XlsFileHelper { public DataTable ImportExcel ...
- 利用kettle组件导入excel文件到数据库
利用kettle组件导入excel文件到数据库 1. 实现目标 把excel文件内容导入到目标表中:然后用java调用kettle的转换.excel文件的内容仅仅有两列,示比例如以下: wat ...
- PLSQL导入Excel文件预览不到数据行问题
今天,从Excel导入Oracle一些数据,在导入的过程中,遇到一个问题,Excel里面有好几万条数据,但是通过PLSQL导入向导导入Excel文件之后,在PLSQL里却预览不到数据行,只能看见标题行 ...
随机推荐
- JavaScript一种新的数据结构类型Map
什么是map 它类似于对象,是键值对的集合,但键的范围不局限在于字符串.各种类型的值(包含对象)都可以作为键. 如果同一个键被多次赋值,后面的值将会覆盖其那面的值.如果读取一个未知的键,返回的是und ...
- el-popover 点击取消按钮,弹窗仍然无法关闭
<el-popover placement="bottom" width="200" :ref="aa" :visible.sync= ...
- 结构体定义及结构体粒度(alignment)
结构体定义及结构体粒度(alignment) #pragma pack(1) typedef struct _STUDENT_INFORMATION_ { int Age; char v1; int ...
- python从新手到安装指南
说到python我是跟着官方文档自学入门,本文适用于windows 操作系统,基于Inter和amd的CPU(涵盖市面80%的电脑) 下载和安装python 对于window操作系统的初学者,进入 p ...
- gym中的discrete类、box类和multidiscrete类简介和使用
相关文章: Box() dict()可用于创建连续的空间:OpenAI Gym Discrete和Box spaces同时存在,代码该怎么写:gym中各种离散连续写法 解读gym中的action_sp ...
- 快递单信息抽取【二】基于ERNIE1.0至ErnieGram + CRF预训练模型
相关文章: 1.快递单中抽取关键信息[一]----基于BiGRU+CR+预训练的词向量优化 2.快递单信息抽取[二]基于ERNIE1.0至ErnieGram + CRF预训练模型 3.快递单信息抽取[ ...
- 10.5 认识XEDParse汇编引擎
XEDParse 是一款开源的x86指令编码库,该库用于将MASM语法的汇编指令级转换为对等的机器码,并以XED格式输出,目前该库支持x86.x64平台下的汇编编码,XEDParse的特点是高效.准确 ...
- 从嘉手札<2023-11-13>
1. 很多时候 成功并不等同于成长 成功是很多因素复合形成的一种结果 而并不等同于一个人阅历的丰富.认知的提高 2. 我一直认为 世界不属于投机者 也不属于堕落者 信念感在这个大数据泛滥.碎片化汹涌的 ...
- a标签download属性跨域问题
1.如果是加载了非同源的内容,该属性将失效,等于导航功能 2.在服务端设置Content-Disposition,使用HTTP响应头Content-disposition进行处理 3.先下载数据文件, ...
- 转换流(InputStreamReader OutputStreamWriter)
1.字节输出转换流(OutputStreamWriter) 1 package iochange; 2 3 import java.io.*; 4 5 /* 6 java.io.OutputStrea ...