当前位置: 首页 > article >正文

Java 读写 Excel 公式:从基础到高级的实战总结

做数据处理的朋友应该都遇到过这种场景需要批量生成带公式的Excel报表或者读取现有表格中的公式进行二次计算。以前我都是手动在Excel里写公式后来发现用Java代码来处理更高效尤其是数据量大的时候。今天整理一下平时用得比较多的几种Excel公式处理方式希望能给有同样需求的朋友一些参考。环境准备使用的库本文示例使用的是Spire.XLS for Java这是一个专门处理Excel文件的Java库。如果你项目中已经在用Apache POI也可以实现类似功能不过API会有些不同。安装方式Maven项目在pom.xml中添加依赖repositoriesrepositoryidcom.e-iceblue/idnamee-iceblue/nameurlhttps://repo.e-iceblue.cn/repository/maven-public//url/repository/repositoriesdependenciesdependencygroupIde-iceblue/groupIdartifactIdspire.xls/artifactIdversion14.12.0/version/dependency/dependenciesGradle项目在build.gradle中添加repositories { maven { url https://repo.e-iceblue.cn/repository/maven-public/ } } dependencies { implementation e-iceblue:spire.xls:14.12.0 }或者直接下载JAR包从官网导入项目。一、最基础的写入和读取公式1. 写入常见公式最常见的就是往单元格里写公式了。比如SUM、AVERAGE这些统计函数importcom.spire.xls.*;publicclassWriteFormulas{publicstaticvoidmain(String[]args){// 创建工作簿WorkbookworkbooknewWorkbook();// 获取第一个工作表Worksheetsheetworkbook.getWorksheets().get(0);// 准备测试数据sheet.getCellRange(B2).setNumberValue(7.3);sheet.getCellRange(C2).setNumberValue(5);sheet.getCellRange(D2).setNumberValue(8.2);// 写入求和公式sheet.getCellRange(E2).setFormula(SUM(B2:D2));// 写入平均值公式sheet.getCellRange(F2).setFormula(AVERAGE(B2:D2));// 保存文件workbook.saveToFile(result.xlsx,ExcelVersion.Version2013);// 释放资源workbook.dispose();System.out.println(文件已生成);}}注意一个小细节如果想在单元格里显示公式文本而不是计算结果需要在前面加个单引号// 这样单元格会显示 SUM(B2:D2) 这个文本sheet.getCellRange(A2).setText(SUM(B2:D2));2. 读取已有公式有时候需要读取现成Excel文件里的公式看看是怎么计算的WorkbookworkbooknewWorkbook();workbook.loadFromFile(existing.xlsx);Worksheetsheetworkbook.getWorksheets().get(0);// 获取公式字符串Stringformulasheet.getCellRange(C14).getFormula();System.out.println(公式: formula);// 获取公式计算结果doublevaluesheet.getCellRange(C14).getFormulaNumberValue();System.out.println(结果: value);这个功能在做公式审计或者模板分析时特别有用。二、跨工作表引用实际项目中经常需要跨Sheet引用数据写法跟Excel里一样// 引用Sheet1的B3单元格sheet.getCellRange(A1).setFormula(Sheet1!$B$3);// 引用某个区域的平均值sheet.getCellRange(A2).setFormula(AVERAGE(Sheet1!$D$3:G$3));绝对引用带$符号和相对引用的区别一定要搞清楚不然复制公式时容易出错。三、日期和时间函数处理时间相关的报表时这几个函数很实用// 当前日期时间sheet.getCellRange(A1).setFormula(NOW());sheet.getCellRange(A1).getCellStyle().setNumberFormat(yyyy-MM-DD HH:mm:ss);// 提取年、月、日sheet.getCellRange(B1).setFormula(YEAR(TODAY()));sheet.getCellRange(C1).setFormula(MONTH(TODAY()));sheet.getCellRange(D1).setFormula(DAY(TODAY()));// 提取时、分、秒sheet.getCellRange(E1).setFormula(HOUR(NOW()));sheet.getCellRange(F1).setFormula(MINUTE(NOW()));sheet.getCellRange(G1).setFormula(SECOND(NOW()));// 星期几sheet.getCellRange(H1).setFormula(WEEKDAY(TODAY()));NOW()函数每次打开文件都会重新计算如果需要固定时间建议计算后转成静态值。四、数学和统计函数除了基本的SUM、AVERAGE还有一些常用的// 最大值、最小值sheet.getCellRange(A1).setFormula(MAX(10,30,50));sheet.getCellRange(A2).setFormula(MIN(5,7,3));// 四舍五入sheet.getCellRange(A3).setFormula(ROUND(3.14159, 2));// 结果: 3.14// 取整sheet.getCellRange(A4).setFormula(INT(9.8));// 结果: 9// 绝对值sheet.getCellRange(A5).setFormula(ABS(-15.6));// 结果: 15.6// 平方根sheet.getCellRange(A6).setFormula(SQRT(144));// 结果: 12// 随机数sheet.getCellRange(A7).setFormula(RAND());// 0-1之间的随机数五、逻辑函数条件判断在报表中很常见// IF函数sheet.getCellRange(A1).setFormula(IF(B160, \及格\, \不及格\));// AND、ORsheet.getCellRange(A2).setFormula(AND(B160, C160));sheet.getCellRange(A3).setFormula(OR(B190, C190));// NOTsheet.getCellRange(A4).setFormula(NOT(TRUE));// 结果: FALSE实际应用用IF嵌套来做成绩等级划分IF(A190, \优秀\, IF(A180, \良好\, IF(A160, \及格\, \不及格\)))六、文本函数处理字符串时也少不了公式// 字符串长度sheet.getCellRange(A1).setFormula(LEN(\Hello World\));// 结果: 11// 截取子串sheet.getCellRange(A2).setFormula(MID(\Hello World\, 7, 5));// 结果: World// 类型转换sheet.getCellRange(A3).setFormula(VALUE(\123\));// 文本转数字七、数组公式高级用法数组公式可以一次性对多个值进行计算适合复杂的数据分析// 准备数据sheet.getCellRange(A1).setNumberValue(1);sheet.getCellRange(A2).setNumberValue(2);sheet.getCellRange(A3).setNumberValue(3);sheet.getCellRange(B1).setNumberValue(4);sheet.getCellRange(B2).setNumberValue(5);sheet.getCellRange(B3).setNumberValue(6);// 设置数组公式线性回归sheet.getCellRange(A5:C6).setFormulaArray(LINEST(A1:A3,B1:B3,TRUE,TRUE));// 计算公式值workbook.calculateAllValue();使用场景财务分析、统计建模时会用到这类高级函数。八、不依赖Excel直接计算公式值有时候不需要生成Excel文件只是想算个公式的结果可以直接计算WorkbookworkbooknewWorkbook();// 直接计算公式的值Objectresult1workbook.calculateFormulaValue(1020*3);System.out.println(result1);// 结果: 70Objectresult2workbook.calculateFormulaValue(SUM(1,2,3,4,5));System.out.println(result2);// 结果: 15// 甚至可以引用单元格workbook.getWorksheets().get(0).getCellRange(A1).setNumberValue(100);Objectresult3workbook.calculateFormulaValue(A1*2);System.out.println(result3);// 结果: 200这个功能在做快速计算或者公式验证时很方便不用真的创建Excel文件。九、移除公式保留计算结果有个实际需求给客户发报表时只想给他们看最终数据不想暴露计算公式。这时候可以把公式转成静态值WorkbookworkbooknewWorkbook();workbook.loadFromFile(with_formulas.xlsx);for(Worksheetsheet:(IterableWorksheet)workbook.getWorksheets()){for(CellRangecell:(IterableCellRange)sheet.getRange()){if(cell.hasFormula()){// 获取公式计算结果Objectvaluecell.getFormulaValue();// 清除公式cell.clear(ExcelClearOptions.ClearContent);// 设置为静态值cell.setValue(value.toString());}}}workbook.saveToFile(without_formulas.xlsx,ExcelVersion.Version2013);应用场景财务报表、对外发布的统计数据等需要保护公式逻辑的场景。十、Excel 2013的新函数新版Excel增加了一些实用函数比如位运算、URL编码等// 位运算sheet.getCellRange(A1).setFormula(BITOR(23,10));// 按位或sheet.getCellRange(A2).setFormula(BITAND(23,10));// 按位与sheet.getCellRange(A3).setFormula(BITLSHIFT(23,2));// 左移sheet.getCellRange(A4).setFormula(BITRSHIFT(23,2));// 右移// URL编码sheet.getCellRange(A5).setFormula(ENCODEURL(\https://example.com\));// ISO周数sheet.getCellRange(A6).setFormula(ISOWEEKNUM(DATE(2024,1,1)));// 精确舍入sheet.getCellRange(A7).setFormula(CEILING.PRECISE(-4.6, 3));sheet.getCellRange(A8).setFormula(FLOOR.MATH(12.758, 2, -1));这些函数在处理特定业务逻辑时很有用比如网络应用开发中的URL处理。十一、命名范围中使用公式如果公式里用到的区域经常变化可以用命名范围来简化// 定义命名范围Namenameworkbook.getNameList().add(SalesData);name.setRefersToRange(sheet.getCellRange(A1:A100));// 在公式中使用命名范围sheet.getCellRange(B1).setFormula(SUM(SalesData));这样做的好处是当数据区域扩展时只需要修改命名范围的定义不用改所有公式。十二、R1C1引用样式除了常见的A1样式Excel还支持R1C1引用方式行号列号// R1C1样式的公式sheet.getCellRange(C3).setR1C1Formula(R[-1]C[-1]R[-1]C[0]);// 意思是上一行左边一格 上一行当前列// 数组形式的R1C1公式sheet.getCellRange(D3:E4).setR1C1FormulaArray(R[-2]C[-3]:R[-1]C[-2]);什么时候用在程序化生成公式时R1C1方式更容易通过坐标计算来动态构建公式。十三、自定义函数加载项函数如果遇到Excel内置函数不够用的情况可以注册自定义函数// 注册加载项函数库workbook.registerAddInFunction(MyFunctions.xll);// 然后就可以像普通函数一样使用sheet.getCellRange(A1).setFormula(MYCUSTOMFUNC(B1,C1));适用场景有特殊计算需求的行业比如金融衍生品定价、工程计算等。十四、SUBTOTAL函数忽略隐藏行做数据筛选时普通的SUM会把隐藏行也算进去用SUBTOTAL可以避免这个问题// 第一个参数3表示COUNTA只统计可见单元格sheet.getCellRange(A1).setFormula(SUBTOTAL(3, B2:E100));常用功能代码1: AVERAGE2: COUNT3: COUNTA9: SUM109: SUM忽略隐藏值十五、实际项目中的综合应用最后分享一个实际场景生成月度销售报表。WorkbookworkbooknewWorkbook();Worksheetsheetworkbook.getWorksheets().get(0);// 1. 写入标题sheet.getCellRange(A1).setValue(月份);sheet.getCellRange(B1).setValue(销售额);sheet.getCellRange(C1).setValue(成本);sheet.getCellRange(D1).setValue(利润);sheet.getCellRange(E1).setValue(利润率);// 2. 写入数据并添加公式for(inti2;i13;i){sheet.getCellRange(Ai).setValue((i-1)月);sheet.getCellRange(Bi).setNumberValue(Math.random()*100000);sheet.getCellRange(Ci).setNumberValue(Math.random()*60000);// 利润 销售额 - 成本sheet.getCellRange(Di).setFormula(Bi-Ci);// 利润率 利润 / 销售额sheet.getCellRange(Ei).setFormula(Di/Bi);sheet.getCellRange(Ei).getCellStyle().setNumberFormat(0.00%);}// 3. 添加汇总行intlastRow14;sheet.getCellRange(AlastRow).setValue(合计);sheet.getCellRange(BlastRow).setFormula(SUM(B2:B13));sheet.getCellRange(ClastRow).setFormula(SUM(C2:C13));sheet.getCellRange(DlastRow).setFormula(SUM(D2:D13));sheet.getCellRange(ElastRow).setFormula(AVERAGE(E2:E13));// 4. 设置格式sheet.getAllocatedRange().autoFitColumns();sheet.getCellRange(A1:E1).getCellStyle().getExcelFont().isBold(true);workbook.saveToFile(monthly_report.xlsx,ExcelVersion.Version2013);这样一个完整的报表就生成了所有计算都是通过公式完成的后续修改原始数据结果会自动更新。小结总结一下几个关键点简单公式直接用setFormula()跟Excel里写法一致跨表引用用SheetName!CellAddress格式数组公式用setFormulaArray()记得调用calculateAllValue()只要计算结果不要公式遍历单元格转换直接计算公式值用calculateFormulaValue()不用创建文件新函数如位运算、URL编码等注意Excel版本兼容性实际使用中最重要的是理解业务需求选择合适的公式类型。不是所有场景都需要复杂的公式有时候简单的SUM、IF就能解决问题。希望这些经验对大家有帮助如果有其他好用的技巧欢迎交流

相关文章:

Java 读写 Excel 公式:从基础到高级的实战总结

做数据处理的朋友应该都遇到过这种场景:需要批量生成带公式的Excel报表,或者读取现有表格中的公式进行二次计算。以前我都是手动在Excel里写公式,后来发现用Java代码来处理更高效,尤其是数据量大的时候。 今天整理一下平时用得比较…...

昇腾CANN opbase与算子生态协作:从单一算子到完整计算图

前言 单个算子的性能再高,如果无法和其他算子高效协作,最终端到端的模型推理或训练性能也不会好。一个典型的深度学习模型包含几十到几百个算子,它们之间的数据流、内存分配、执行顺序都需要精心编排。opbase作为所有算子仓库的公共基础&…...

AI Agent Harness Engineering 反思机制3大实现路径:日志回溯 vs 强化学习 vs 人工反馈

AI Agent Harness Engineering 反思机制3大实现路径:日志回溯 vs 强化学习 vs 人工反馈 引言 痛点引入 想象一下:你花了整整两周,用 LangChain、AutoGPT 或者 LlamaIndex 搭了一个帮你写产品PRD草稿的AI Agent。你给它输入了竞品分析报告、用户访谈纪要、项目进度表,满心…...

牛客周赛 Round 142 C题及D题题解

首先是C题: 咱们先看题目: 链接:https://ac.nowcoder.com/acm/contest/133790/C 来源:牛客网。 这道题其实特别简单,我们只需要按顺序遍历数组,统计能依次被 1、2、3... 整除的元素数量,即…...

【芯片测试】:SmarTest 开发环境入门

SmarTest 开发环境入门:Eclipse IDE 集成与工作区管理系列: Advantest V93000 SmarTest 8 核心概念解析|第 1 篇(共 8 篇) 适合读者: 初次接触 SmarTest 的测试工程师、ATE 软件开发者前言 很多工程师第一次…...

AI应用开发

1.规划 2.记忆 2.工具 3.行动...

keil5下载配置Samsung固件包

我们要找的是非常经典的 S3C2440、S3C6410 或 S3C44B0X,这些属于早期的 ARM7 / ARM9 / ARM11 架构,它们使用的是旧版的数据库管理方式。直接访问这个网址:www.keil.com/mdk5/legacy网页往下拉,找到 ARM7, ARM9 & Cortex-R 这一…...

RAG + Agent = 王炸组合:知识增强型Agent详解

完整版合集、面试题库、项目实战,全网同名【图解 AI 系列】前几篇文章我们讲了Agent的核心能力:调用工具、记忆系统、规划能力、多Agent协作。但有一个问题一直没解决:Agent的知识从哪来? 大模型的知识是训练时学到的,…...

武汉专升本民办 vs 公办机构怎么选

每年到了专科大三的春天,武汉的专升本备考群里总会出现类似的问题:“公办机构是不是比民办靠谱?”“民办会不会拿钱不办事?”“集训营到底该冲公办还是选民办?”说实话,这个问题没有标准答案,因…...

快速上手:ClaudeCode安装全攻略

以下是从零开始安装 Claude Code 的详细操作步骤,涵盖环境准备、安装过程与验证方法。请根据你的操作系统选择对应的分支操作。 (PS: 官方文档: 接入 Claude Code | DeepSeek API Docs) 一、安装 Node.js 18 或更高版本 Claude Code 基于 Node.js 运行…...

[开源] 交班信息一致性校验系统:面向临床医护的实时语义冲突检测与结构化摘要生成

本项目是专为国内医院交班场景设计的电子病历(EMR)辅助工具,解决护士与医生在护理记录和病程记录中同步填写、异步理解、隐性冲突这一长期存在的质控盲区。我们不替代人工判断,而是把“同一时间窗内两条记录是否说同一件事”这件事…...

5-8倍加速:ncnn 3×3卷积模块

5-8倍加速:ncnn 33矩阵卷积模块 我把腾讯ncnn的33卷积从手工循环替换成了自己的算法(Im2Col GEMM),实测加速5到8倍。 适用于大通道数(inch≥16, outch≥32)、大分辨率特征图、服务端推理场景。小通道建议…...

昇腾CANN asc-tools:NPU 运维诊断工具的实战手册

asc-tools 是 CANN 的运维诊断工具包——不在开发阶段用,在部署和运维阶段用。NPU 集群跑了几个月突然性能下降、某张卡频现 ECC 错误、推理延迟从 50ms 涨到 200ms——这些生产环境的问题,asc-tools 帮你定位。 asc-tools 包含哪些工具 asc-tools/ ├─…...

SwinFusion论文精读与代码复现:拆解‘跨域远程学习’如何让图像融合效果开挂

SwinFusion技术解析:跨域远程学习如何重塑图像融合范式 图像融合技术正经历一场由Transformer架构引领的范式变革。传统方法在全局依赖建模和跨域交互方面的局限性,催生了基于Swin Transformer的创新解决方案。本文将深入剖析SwinFusion这一通用图像融合…...

Navicat Premium连不上SQL Server?别慌,先检查这两个最容易忽略的配置(附驱动安装)

Navicat Premium连接SQL Server的实战排错指南:从报错到畅通的完整解决方案 第一次用Navicat Premium连接SQL Server数据库时,那种期待又忐忑的心情我太熟悉了。明明按照教程一步步填写了IP、端口、用户名和密码,点击"测试连接"后却…...

tcpdump 核心选项与过滤表达式实战指南:从基础到高效网络排查

1. 从命令行到洞察力:为什么你需要精通 tcpdump如果你在运维、开发或者网络安全领域工作,网络问题排查几乎是你绕不开的日常。当服务调用超时、接口响应异常,或者流量出现诡异波动时,你需要的不是猜测,而是证据。tcpdu…...

别再让FFT精度拖后腿了!手把手教你用三点插值法把频率估计误差降到最低

别再让FFT精度拖后腿了!手把手教你用三点插值法把频率估计误差降到最低 在音频调谐器里校准乐器音高时,工程师发现440Hz的标准音高在1024点FFT中总是显示为439.2Hz;5G基站接收端解调时,载波频率的微小偏移导致误码率飙升&#xff…...

COLMAP实战:如何用命令行搞定无人机航拍图像的三维重建?

COLMAP实战:如何用命令行搞定无人机航拍图像的三维重建? 无人机航拍技术正在彻底改变测绘、考古、农业和工程巡检等领域的工作方式。想象一下,你刚刚完成了一次大规模的无人机航拍任务,带回了数百甚至数千张高分辨率图像。这些图像…...

Unity连接Arduino BLE实战:5分钟实现PC端双向通信

1. 这不是“配对”,而是让Unity像手机App一样和Arduino对话很多人第一次尝试Unity连接Arduino蓝牙模块时,会下意识打开Windows的“蓝牙设置”去“添加设备”——结果折腾半小时,Unity里依然收不到任何数据。我最初也这么干过,直到…...

HC-05蓝牙模块连接Arduino/STM32的实战避坑指南:从3.3V/5V电平匹配到手机APP调试全流程

HC-05蓝牙模块连接Arduino/STM32的实战避坑指南:从3.3V/5V电平匹配到手机APP调试全流程 当你第一次尝试将HC-05蓝牙模块连接到Arduino或STM32开发板时,可能会遇到各种令人沮丧的问题:模块不响应、手机搜索不到设备、数据传输不稳定。这些问题…...

TI C2000 DSP开发笔记:除了IQMath,F28377D的定点计算还有这些隐藏技巧(含FFT/FIR函数初探)

TI C2000 DSP开发笔记:F28377D定点计算高阶技巧与FFT/FIR实战解析 在嵌入式信号处理领域,定点计算一直是平衡性能与精度的关键选择。TMS320F28377D作为TI C2000系列中的高性能DSP控制器,其IQMath库提供的定点计算能力远超基础算术运算范畴。本…...

LERF:将语言嵌入3D辐射场,实现开放词汇的3D语义查询

1. 项目概述:当语言成为3D场景的“探针”如果你玩过NeRF(神经辐射场),肯定被它从几张2D照片生成逼真3D场景的能力震撼过。但不知道你有没有和我一样的感受:生成的3D模型虽然好看,但像个“美丽的哑巴”。我们…...

GF6-WFV数据FLAASH大气校正避坑全记录:参数设置、光谱响应函数选择与结果验证

GF6-WFV数据FLAASH大气校正实战指南:从参数优化到结果验证 当处理国产高分六号卫星WFV相机数据时,大气校正环节往往是整个流程中的关键瓶颈。不同于常规Landsat或Sentinel数据,GF6-WFV特有的波段设置和响应特性使得FLAASH参数配置充满陷阱。本…...

从VLP-16到国产激光雷达:拆解看机械旋转式LiDAR的技术传承与差异

从VLP-16到国产激光雷达:机械旋转式LiDAR的技术传承与创新 在自动驾驶技术快速发展的浪潮中,激光雷达(LiDAR)作为环境感知的核心传感器,其技术演进一直备受关注。VLP-16作为机械旋转式LiDAR的经典产品,不仅…...

URDF导入Unity实战指南:坐标系转换与物理仿真校准

1. 为什么URDF导入Unity这件事,2025年依然让人抓耳挠腮你刚在ROS里调通了机械臂的运动学解算,PID参数也压得差不多了,信心满满地想把模型拖进Unity做可视化调试——结果双击URDF文件,Unity弹出一串红色报错:“Unknown …...

AI时代软件工程教育:同理心融入技术课程的教学实践

1. 项目概述:当代码遇见人心最近几年,我一直在高校和培训机构里讲授软件工程相关的课程,从传统的软件生命周期、设计模式,到如今火热的敏捷开发、DevOps。一个越来越强烈的感受是:我们的技术教育,似乎正在与…...

CAD图纸版本转换软件 | Teigha File Converter (v4.3.2.0)

介绍 Teigha File Converter 是一款 CAD 图纸版本转换软件,它支转换到 2018 及以下的 DMG、DXF 格式。截图下载地址👇👇https://pan.baidu.com/s/1LbqDZMZjfzsqueFsVSvyjA?pwd4274...

Linux网络编程核心:Socket、字节序与TCP/UDP实战解析

1. 从零开始理解 Linux 网络编程:Socket、字节序与地址转换如果你刚开始接触 Linux 下的网络编程,看到一堆socket、bind、connect、htonl之类的函数,还有sockaddr_in这种结构体,可能会觉得头大。别担心,这种感觉我十几…...

别再为OLED图片显示发愁了!手把手教你用Image2Lcd和PCtoLCD2002搞定STM32图片取模

STM32 OLED图片显示实战:从取模到驱动的完整解决方案 在嵌入式开发中,OLED显示屏因其高对比度、低功耗和快速响应等特性,成为许多项目的首选显示方案。但对于初学者来说,如何将普通图片转换为单片机可识别的数据格式,并…...

电子供应链服务转型:从元器件分销到技术赋能与韧性构建

1. 项目概述:从“卖货”到“赋能”的供应链服务转型在电子元器件分销这个看似传统的行业里,我从业十几年,亲眼见证了从“电话传真报价”到“线上实时库存”的变迁。最近和一位行业老友,也是某知名分销商的资深销售总监聊天&#x…...