C# 实现读取Excel文件并设置单元格计算公式再保存

背景:需求需要读取数据导出成Excel文件,并且其中有一列需要赋值为公式,用于用户自己修改数据自动计算
导出Excel,我用到开源包MiniExcel
Gitee地址MiniExcel源码介绍,功能说明
Nuget安装 搜索MiniExcel

导出代码如下:
 

//多个Sheet
var sheets = new Dictionary<string, object>();
//保存文件位置
string filePath = Path.Combine(Directory.GetCurrentDirectory(), $"ExportTemplate\\{DateTime.Now.ToString("yyyyMMddHHmmss")}_StoreInventoryDt.xlsx");
{    
List<dynamic> value = new List<dynamic>();
    int index = 2;
    foreach (var itemDetail in storeInventoryExcelDto.ExportList)
    {
        itemDetail.saleInventory = itemDetail.startInventory + itemDetail.barInventory + itemDetail.todayPickUp - itemDetail.saleCount;
        // 创建计算公式,例如:B2 + C2
        //string formula = $"={MiniExcel.GetColumns(columnIndex)}2 + {MiniExcel.GetColumns(columnIndex + 1)}2";
        value.Add(new
        {
            品名 = itemDetail.goodsName,
            品类 = itemDetail.goodsType,
            期初数 = itemDetail.startInventory,
            吧台入库 = itemDetail.barInventory,
            本日拾遗 = itemDetail.todayPickUp,
            售卖 = itemDetail.saleCount,
            置换 = itemDetail.changeCount,
            销售库存 = itemDetail.saleInventory,
            寄存 = itemDetail.inStorageCount,
            取出 = itemDetail.outStorageCount,
            总库存 = itemDetail.saleInventory + itemDetail.inStorageCount - itemDetail.outStorageCount,// itemDetail.totalInventory,
            本日实盘 = itemDetail.todayInventory,
            盘点差异 = itemDetail.inventoryDif,//$"=SUM(K{index},-L{index})", //
            备注 = "",
        });
        index++;
    }
    sheets.Add(storeInventoryExcelDto.InvDate.ToString("MM月dd日"), value.ToArray());
}
MiniExcel.SaveAs(filePath, sheets);

导出结果如下:

找了很久MiniExcel没有设置公式的方法,所以使用了ClosedXml
ClosedXml GitHub源码地址 ClosedXml源码和说明
说明文档-英文版

就是重新读取刚刚保存的excel文件,设置M列=K列-L列,M=K-L
代码如下:

//读取当前excel文件的sheet 
var sheetNames = MiniExcel.GetSheetNames(filePath);
 // 打开现有的Excel文件
 using (var workbook = new XLWorkbook(filePath))
 {
     foreach (var sheet in sheetNames)
     {
         // 获取工作表
         var worksheet = workbook.Worksheet(sheet);
         //获取数据行数
         int rowCount = worksheet.RowsUsed().Count();

         for (int i = 2; i <= rowCount; i++)
         {
             // 设置特定单元格的公式
             worksheet.Cell($"M{i}").FormulaA1 = $"=K{i}-L{i}"; // 使用K列引用样式设置公式
             // 或者使用行和列的索引
             //worksheet.Cell(1, 1).FormulaA1 = "=B1*C1"; // 第1行,第1列的单元格
            
         }
         // 保存更改
         workbook.Save();
     }
 }

就完成excel文件中指定某列的计算公式

整体代码:

    var sheets = new Dictionary<string, object>();
string filePath = Path.Combine(Directory.GetCurrentDirectory(), $"ExportTemplate\\{DateTime.Now.ToString("yyyyMMddHHmmss")}_StoreInventoryDt.xlsx");
    List<dynamic> value = new List<dynamic>();
    //storeInventoryExcelDto数据源
    foreach (var itemDetail in storeInventoryExcelDto.ExportList)
    {
        itemDetail.saleInventory = itemDetail.startInventory + itemDetail.barInventory + itemDetail.todayPickUp - itemDetail.saleCount;
        // 创建计算公式,例如:B2 + C2
        //string formula = $"={MiniExcel.GetColumns(columnIndex)}2 + {MiniExcel.GetColumns(columnIndex + 1)}2";
        value.Add(new
        {
            品名 = itemDetail.goodsName,
            品类 = itemDetail.goodsType,
            期初数 = itemDetail.startInventory,
            吧台入库 = itemDetail.barInventory,
            本日拾遗 = itemDetail.todayPickUp,
            售卖 = itemDetail.saleCount,
            置换 = itemDetail.changeCount,
            销售库存 = itemDetail.saleInventory,
            寄存 = itemDetail.inStorageCount,
            取出 = itemDetail.outStorageCount,
            总库存 = itemDetail.saleInventory + itemDetail.inStorageCount - itemDetail.outStorageCount,// itemDetail.totalInventory,
            本日实盘 = itemDetail.todayInventory,
            盘点差异 = itemDetail.inventoryDif,//$"=SUM(K{index},-L{index})", //
            备注 = "",
        });
    }
    sheets.Add(storeInventoryExcelDto.InvDate.ToString("MM月dd日"), value.ToArray());

MiniExcel.SaveAs(filePath, sheets);
var sheetNames = MiniExcel.GetSheetNames(filePath);
// 打开现有的Excel文件
using (var workbook = new XLWorkbook(filePath))
{
    foreach (var sheet in sheetNames)
    {
        // 获取工作表
        var worksheet = workbook.Worksheet(sheet);

        int rowCount = worksheet.RowsUsed().Count();

        for (int i = 2; i <= rowCount; i++)
        {
            // 设置特定单元格的公式
            worksheet.Cell($"M{i}").FormulaA1 = $"=K{i}-L{i}"; // 使用A1引用样式设置公式
            // 或者使用行和列的索引
            //worksheet.Cell(1, 1).FormulaA1 = "=B1*C1"; // 第1行,第1列的单元格
           
        }
        // 保存更改
        workbook.Save();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/909526.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于matlab的SVPWM逆变器死区补偿算法仿真研究

背景介绍&#xff1a; 三相脉宽调制(pulse width modulation&#xff0c;PWM)电压源逆变器(voltage source inverter&#xff0c;VSI)的死区效应可导致电机相电压和相电流畸变、零电流钳位效应以及转矩和转速脉动&#xff0c;系统性能降低。为提高系统运行性能&#xff0c;对V…

Spring Validation数据校检

文章目录 Spring Validation1 关于Spring Validation2 使用流程3 快速入门4 运行异常处理4.1 说明4.2 处理异常4.3 明确提示消息 5 常用注解5.1 NotNull注解5.2 NotEmpty 注解5.3 NotBlank 注解5.4 Size 注解5.5 Range 注解 6 非POJO参数校验6.1 使用流程6.2 使用示例 Spring V…

2024数据库国测揭晓:安全与可靠的新标准,你了解多少?

2024年数据库国测的结果&#xff0c;于9月份的最后一天发布了。 对于数据库行业的从业者来说&#xff0c;国测是我们绕不过去的坎儿。那么什么是国测&#xff1f;为什么要通过国测&#xff0c;以及国测的要求有哪些&#xff1f; 这篇文章带大家一探究竟。 国测 自愿平等、客…

前端入门一之CSS知识详解

前言 CSS是前端三件套之一&#xff0c;在MarkDown中也完美兼容这些语法&#xff1b;这篇文章是本人大一学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。 文章目录 Emmet语法&#xff1a;CSS基本语法&#xff1a;css语法结构只有3种&#xff1a…

虚拟现实和增强现实技术,如何打造沉浸式体验?

内容概要 在这个科技飞速发展的时代&#xff0c;虚拟现实&#xff08;VR&#xff09;与增强现实&#xff08;AR&#xff09;技术的结合就像调皮的小精灵&#xff0c;一下子把我们的生活变得神奇又有趣。想象一下&#xff0c;你正在游戏中与精灵搏斗&#xff0c;突然间身边的客…

EL面包屑导航实现

前言 el-breadcrumb 是 Element Plus 中的面包屑导航组件&#xff0c;主要用于展示当前页面在整个应用程序中的位置&#xff0c;并提供导航功能 https://element-plus.org/zh-CN/component/breadcrumb 基础用法 在 el-breadcrumb 中使用 el-breadcrumb-item 标签表示从首页开…

Qt 练习做一个登录界面

练习做一个登录界面 效果 UI图 UI代码 <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Dialog</class><widget class"QDialog" name"Dialog"><property name"ge…

c语言简单编程练习10

1、typedef和#define的区别 在用作数据类型替换时的区别&#xff1a; #include <stdio.h> #include <unistd.h>typedef char * A; //typedef需要&#xff1b; #define B char *int main(int argc, char *argv[]) {A a,b;B c,d;printf("a_size%ld\n"…

【spark的集群模式搭建】Standalone集群模式的搭建(简单明了的安装教程)

文章目录 1、使用Anaconda部署Python2、上传、解压、重命名3、创建软连接4、配置spark环境变量5、修改 spark-env.sh配置文件6、启动hdfs&#xff0c;创建文件夹7、修改spark-defaults.conf配置文件8、修改workers配置文件9、修改log4j.properties配置文件&#xff08;可选&…

ST-GCN模型实现花样滑冰动作分类

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

【RabbitMQ】03-交换机

1. 交换机 2. Fanout交换机 广播。生产者向exchange发消息 SpringBootTest public class SpringAmqpTest {Autowiredpublic RabbitTemplate rabbitTemplate;Testvoid testSimple() {String exchangName "hmall.fabout";rabbitTemplate.convertAndSend(exchangName…

【07】Maven项目多环境打包配置

&#xff08;1&#xff09;Web项目使用Maven进行多模块划分开发之后&#xff0c;面临一个问题&#xff0c;即如何加载不同环境的配置文件打包发布到不同的环境中&#xff1f; &#xff08;2&#xff09;不同的环境有开发环境、测试环境、线上生产环境等。 &#xff08;3&#x…

【Unity Shader】Special Effects(十)Change 变换(UI)

源码:[点我获取源码] 索引 Change 变换思路分析变换进度噪声纹理闪烁闪烁时机闪烁颜色闪烁动画Change 变换 变换的效果为图像间的切换带来动感过程,使用动画播放器: 思路分析 首先,从原始图像变换到目标图像是一个从0到1的过程,这个过程我们命名为变换进度(0为完全显…

关于wordpress instagram feed 插件 (现更名为Smash Balloon Social Photo Feed)

插件地址&#xff1a; Smash Balloon Social Photo Feed – Easy Social Feeds Plugin – WordPress 插件 | WordPress.org China 简体中文 安装后&#xff0c;配置教程&#xff1a; Setting up the Instagram Feed Pro WordPress Plugin - Smash Balloon 从这里面开始看就…

JavaScript的对象事件处理程序

一、对象的事件 对象的事件是指在一个对象上发生的特定动作或状态改变。对象可以是现实世界中的物体、概念、数据结构等。根据对象的类型和功能&#xff0c;可能会有不同类型的事件。 对象的事件一般由对象的方法或属性来处理和触发。通过定义对象的方法和属性&#xff0c;可…

Win11 CLion Qt开发探索

文章目录 一、Win11 CLion Qt需要的环境二、环境说明三、Win11 CLion Qt 开发步骤四、CLion Qt CMake脚本相关配置4.1 在CLion里如何使用资源文件.qrc4.2 Qt6 cmake如何添加ts翻译文件 五、程序打包 本篇博客介绍在Win11上使用CLion来编写Qt QWidget项目。 视频讲解&#xff1a…

Windows Server2012 R2搭建NFS服务器

正文共&#xff1a;1024 字 23 图&#xff0c;预估阅读时间&#xff1a;1 分钟 在测试vCenter的集群操作时&#xff0c;出现了共享vSAN错误的问题&#xff0c;导致无法继续。我也只好先创建一个共享NFS&#xff08;Network File System&#xff0c;网络文件系统&#xff09;存储…

信息安全工程师(77)常见网络安全应急事件场景与处理流程

前言 网络安全应急事件场景多样&#xff0c;处理流程也需根据具体情况灵活调整。以下将详述几种常见的网络安全应急事件场景及其处理流程。 一、数据泄露事件 场景描述&#xff1a; 数据泄露是指敏感、受保护或机密数据被未经授权的个人复制、传输、查看、窃取或使用。这种事件…

win10下MMSegmentation自定义数据集

下载1.2.1版本: Releases open-mmlab/mmsegmentation GitHub 安装环境 本地torch环境为1.9.1 pip install -U openmim mim install mmengine mim install "mmcv>=2.0.0" 报mmcv版本不匹配的问题,形如:MMCV==X.X.X is used but incompatible. Please inst…

低代码解锁跨平台应用开发新境界

数字化转型中&#xff0c;企业面临应用开发挑战&#xff0c;低代码平台成为理想选择。ZohoCreator提供统一开发环境、拖拽设计、预置模板等&#xff0c;支持高效构建跨平台应用&#xff0c;确保数据安全与合规&#xff0c;助力企业数字化转型。 一、低代码平台是什么&#xff1…