前言

在我们使用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 的加载与显示

如何在.NET电子表格应用程序中创建流程图

导入Excel文件的时候公式为【#Ref!】应该怎么解决?的更多相关文章

  1. .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)

    .Net MVC  导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) [原文地址] 通过MVC控制器导出导入Excel文件(可用于java SSH架构)   public cl ...

  2. Java POI导入Excel文件

    今天在公司需要做个导入Excel文件的功能,所以研究了一下,参考网上的一些资料总算是做出来了,在此记录一下防止以后忘记怎么弄. 本人用的是poi3.8,所以需要的JAR包如下: poi-3.8.jar ...

  3. phpexcel导入excel文件报the filename xxx is not recognised as an OLE file错误。

    工作中频繁会用phpexcel类导入excel文件的数据到数据库,目前常用的excel文件格式有:xls.csv.xlsx. 刚开始,针对xls文件,使用如下程序,能正常运行: $objReader ...

  4. YII使用PHPExcel导入Excel文件的方法

    1.下载phpexcel,将压缩包中的classes复制到protected/extensions下并修改为PHPExcel. 2.修改YII配置文件config/main.php 'import'= ...

  5. springMVC(5)---导入excel文件数据到数据库

    springMVC(5)---导入excel文件数据到数据库 上一篇文章写了从数据库导出数据到excel文件,这篇文章悄悄相反,写的是导入excel文件数据到数据库.上一篇链接:springMVC(4 ...

  6. excel数据 入库mysql 和 mysql数据 导入excel文件

    1.excel数据入库mysql 首先准备excel文件, 标红的地方需要留意,一个是字段名所在行,一个表名对应页: 然后私用mysql工具 navicat, 选择数据库,然后导入文件, 选中相应ex ...

  7. java后端导入excel模板和导入excel文件去读数据

    模板转载地址:https://www.cnblogs.com/zhangyangtao/p/9802948.html 直接上代码(我是基于ssm写的demo,导入文件目前只能读取.xls后缀的exce ...

  8. C# Aspose.Cells方式导入Excel文件

    读取Excel 类 我返回的是DataTable 类型 也可以返回DataSet类型 public class XlsFileHelper { public DataTable ImportExcel ...

  9. 利用kettle组件导入excel文件到数据库

    利用kettle组件导入excel文件到数据库 1.     实现目标 把excel文件内容导入到目标表中:然后用java调用kettle的转换.excel文件的内容仅仅有两列,示比例如以下: wat ...

  10. PLSQL导入Excel文件预览不到数据行问题

    今天,从Excel导入Oracle一些数据,在导入的过程中,遇到一个问题,Excel里面有好几万条数据,但是通过PLSQL导入向导导入Excel文件之后,在PLSQL里却预览不到数据行,只能看见标题行 ...

随机推荐

  1. ClickHouse(14)ClickHouse合并树MergeTree家族表引擎之VersionedCollapsingMergeTree详细解析

    目录 建表语法 使用场景 合并算法 使用例子. 资料分享 参考文章 VersionedCollapsingMergeTree引擎继承自MergeTree并将折叠行的逻辑添加到合并数据部分的算法中.Ve ...

  2. Gorm 应用开发时区问题与unique唯一索引字段数据冲突问题

    目录 一.定义表模型时区问题 1.1 time.Time 与int64 1.2 优势 二.unique唯一索引字段数据冲突问题 一.定义表模型时区问题 1.1 time.Time 与int64 一般情 ...

  3. P9779_[HUSTFC 2023] 不定项选择题_题解

    rt 题目 有一道共 n 个选项的不定项选择题,它的答案至少包含一个选项,由于题目与选项的内容晦涩难懂,你打算通过尝试每一种可能的答案来通过这道题. 初始时所有选项都没有被勾选,你可以执行任意次下述操 ...

  4. git checkout switch restore

    前言 在 Git 术语中,"checkout"是在目标实体的不同版本之间切换的行为.该命令对三个不同的实体进行操作:文件.提交和分支.除了"checkout"的 ...

  5. 手撕Vue-监听数据变化

    经过上一篇的介绍,已经实现了将模板编译成具体数据,接下来要介绍的是如何监听数据的变化,本章主要完成这个需求即可. 在我们文章的开始,我写了一个 Vue 双向数据绑定原理的文章当中封装了一个 Obser ...

  6. 多路转接高性能IO服务器|select|poll|epoll|模型详细实现

    前言 那么这里博主先安利一下一些干货满满的专栏啦! Linux专栏https://blog.csdn.net/yu_cblog/category_11786077.html?spm=1001.2014 ...

  7. uni-uadmin后台管理系统|uniapp+uView跨端后台框架实例

    基于uniapp+uview+uni-ui跨平台手机端后台管理系统UniappUAdmin. uniapp-uadmin 基于uni-app+uView+uniUI研发的跨端手机后台管理系统项目.全新 ...

  8. Oracle私网mtu滚动修改实施方案

    之前测试遇到过mtu修改不能滚动的情况,目前在自己测试环境重新反复验证发现正常是可以滚动的,下面梳理下整个实施方案: 环境:RHEL6 + Oracle 11.2.0.4 RAC(2 nodes) / ...

  9. Hive压缩和存储

    1.压缩 (1)Hive支持的压缩编码 压缩格式 工具 算法 文件扩展名 是否可切分 对应的编码/解码器 DEFLATE 无 DEFLATE .deflate 否 org.apache.hadoop. ...

  10. CF383C Propagating tree

    题目链接 题目 见链接. 题解 知识点:DFS序,树状数组. 我们需要对子树的不同奇偶层加减,用dfn序可以解决子树问题,但是并不能直接分奇偶. 一种比较麻烦的思路是,将dfn序分成两个序列,一个是偶 ...