导入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里却预览不到数据行,只能看见标题行 ...
随机推荐
- vue3中watch监听不是你想的那样简单
vue3 中watch监听数组,数组变化后未触发回调 今天发生了一个很神奇的现象,就是我使用watch监听数组时. 被监听的数组已经发生了变化.但是没有触发回调操作. 当时的我感到很疑惑? 不应该呀? ...
- ccs3动画-div向上移动的动画
<head> <meta charset="UTF-8"> <meta name="viewport" content=" ...
- elementUI自定义单选框内容
<template> <div> <div class="heng-div"> <el-radio v-model="radio ...
- 机器学习算法(四): 基于支持向量机的分类预测(SVM)
机器学习算法(四): 基于支持向量机的分类预测 本项目链接:https://www.heywhale.com/home/column/64141d6b1c8c8b518ba97dcc 1.相关流程 支 ...
- SpringCloud-Gateway搭建保姆级教程
一.网关介绍 1.什么是网关? 使⽤服务⽹关作为接⼝服务的统⼀代理,前端通过⽹关完成服务的统⼀调⽤ 2.⽹关可以⼲什么? 路由:接⼝服务的统⼀代理,实现前端对接⼝服务的统⼀访问 过滤:对⽤户请求进⾏拦 ...
- C/C++可变参数模版和函数指针的结合
目录 1.说明 2.模板类传入固定参数的C函数指针 3.模板类传入固定参数的C++函数指针 3.1.用函数对象替代函数指针存储 4.模板类传入不定参数的C函数指针 5.模板类传入不定参数的C++成员函 ...
- SDK多项目开发与联调
在SDK开发中,因为是往外提供的功能静态库,所以在开发的时候要验证开发的SDK是否功能正常,这里就需要做进行边开发边联调的工作. 下面使用的开发模式是创建一个WorkSpace工作工具,SDK项目和D ...
- (C语言)课后题之计算器
#include <stdio.h> void main() { //定义两个算术变量,四个运算结果变量 int a,b,sum,sub,mul,mod; double div; prin ...
- 内存泄漏定位工具之 mtrace(一)
1 前言 mtrace(memory trace),是 GNU Glibc 自带的内存问题检测工具,它可以用来协助定位内存泄露问题.它的实现源码在glibc源码的malloc目录下,其基本设计原理为设 ...
- 【题解】P5461 赦免战俘
一.题目 现有 \(2^n\times2^n\ (n≤10)\) 名作弊者站成一个正方形方阵等候 kkksc03 的发落.kkksc03 决定赦免一些作弊者.他将正方形矩阵均分为 4 个更小的正方形矩 ...