EPPLUS——CAD c#读写EXCEL的第三方库

 EPPLUS(可支持NET35)

在 CAD 的 C# 二次开发中,使用 EPPLUS 库处理 Excel 文件具有以下显著优点,尤其在兼容性、便捷性和性能等方面契合 CAD 项目的需求:

1. 跨.NET 版本兼容性强,适配 CAD 多环境部署

  • 多框架支持:EPPLUS 从早期的.NET 3.5 到最新的.NET 4.8 均能稳定运行,而 CAD 二次开发中常面临不同 AutoCAD 版本(如 2014-2024)对应不同.NET 框架的情况(例如老版本 CAD 可能基于.NET 3.5,新版本基于.NET 4.5+)。这种兼容性避免了因框架不匹配导致的开发适配问题,无需为不同 CAD 版本单独调整代码。
  • 部署轻量:无需额外安装.NET 扩展包,只需引用 EPPLUS.dll 即可集成,适合 CAD 插件的轻量化部署(CAD 插件通常要求安装包简洁,避免依赖冲突)。

2. 无需安装 Office,解决 CAD 环境依赖痛点

  • 无 COM 组件依赖:传统 Excel 操作库(如 Microsoft.Office.Interop.Excel)依赖本地 Office 安装,而 CAD 服务器或用户环境可能未安装 Office,或存在版本冲突(如 CAD 后台服务场景)。EPPLUS 基于纯.NET 代码,通过 EPPlus 命名空间直接操作 Excel 文件(.xlsx 格式),完全脱离 Office 环境,避免因 COM 组件引发的权限、稳定性问题(如 CAD 进程中 COM 组件崩溃)。
  • 跨平台潜力:虽然 CAD 主要运行在 Windows,但 EPPLUS 支持.NET Core(需适配版本),若未来涉及 CAD 跨平台开发(如 Linux 环境的轻量化 CAD 工具),可无缝迁移。

3. 高效处理 CAD 数据,适配工程场景需求

  • 大数据量导出:CAD 图纸常包含大量构件、属性数据(如管线参数、构件坐标),EPPLUS 采用流式处理(Streaming 模式),可高效生成包含数万行数据的 Excel 文件,内存占用低,避免 CAD 进程因内存溢出卡顿。例如,导出建筑模型的所有构件属性时,性能优势明显。
  • 格式与图表定制:支持自定义 Excel 格式(如单元格样式、行列冻结、条件格式)、生成工程报表常用的图表(如工程量柱状图、构件分布饼图),便于将 CAD 数据可视化。例如,可将图纸中的钢筋分布数据直接生成 Excel 图表,辅助施工交底。
  • 批量导入支持:支持从 Excel 导入参数到 CAD 模型(如通过 Excel 表格批量创建构件),EPPLUS 的解析效率高,可处理包含复杂公式或合并单元格的工程表格,减少手动录入误差。

4. 开发便捷性与社区支持

  • API 简洁易用:EPPLUS 的 API 设计贴近 Excel 操作逻辑(如 Workbook→Worksheet→Cell 层级操作),C# 开发者可快速上手,无需深入学习复杂模型。例如,读取 CAD 选中构件的属性并写入 Excel,代码量少且逻辑清晰。
  • 开源与商业灵活选择:免费版(LGPL 协议)适合个人或开源项目,商业版(EPPlus Professional)提供更完善的技术支持和企业授权,满足 CAD 项目的商业发布需求(如设计院插件需合规授权)。
  • 错误处理友好:支持 Excel 文件异常解析(如损坏文件)和内存管理,减少 CAD 插件因 Excel 操作导致的崩溃风险,提升用户体验。

5. 与 CAD 对象模型无缝集成

  • 数据映射便捷:可直接将 CAD 对象(如 Entity、BlockReference)的属性(如坐标、图层、自定义参数)映射到 Excel 单元格,无需复杂转换。例如,遍历图纸中所有门窗构件,将其尺寸、材质等属性导出到 Excel 表格。
  • 事务性操作支持:配合 CAD 的事务机制(如 Transaction),可在 Excel 操作中结合 CAD 的撤销 / 重做功能,确保数据一致性(如导入 Excel 参数失败时,CAD 操作可回滚)。

总结

在 CAD C# 二次开发中,EPPLUS 凭借跨框架兼容性、无 Office 依赖、高效数据处理能力,成为工程数据报表生成、批量参数导入导出的理想选择。尤其在需要适配不同 CAD 版本、避免环境依赖、处理大量工程数据的场景下,其优势更为突出,可显著提升插件的稳定性和开发效率。

​public class EPPlus{// 主方法:导出数据库到Excel[CommandMethod("Epp")]public void 读取数据库ToExcel_EPPlus(){// ====================== 步骤1:配置数据库连接 ======================string connectionString ="Data Source=rm-wz9a";// 生成Excel路径(桌面+时间戳命名)string fileName = string.Format("{0:yyyyMMddHHmmss}.xlsx", DateTime.Now);string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);string filePath = Path.Combine(desktopPath, fileName);using (ExcelPackage package = new ExcelPackage()){try{// ====================== 步骤4:为每个表创建Sheet并写入数据 ======================foreach (string tableName in tableNames){try{// 创建工作表(表名作为Sheet名,限制31字符)string sheetName = tableName.Length > 31 ? tableName.Substring(0, 31) : tableName;ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(sheetName);// 读取表结构和数据(通过自定义类TableData)TableData tableData = ReadTableData(connection, tableName);//if (tableData.Headers.Count == 0 || tableData.Data.Count == 0)//{//    Z.ed.WriteMessage($"表 {tableName} 无数据或结构,跳过");//    continue;//}// ====================== 步骤5:写入表头(带样式) ======================for (int col = 0; col < tableData.Headers.Count; col++){worksheet.Cells[1, col + 1].Value = tableData.Headers[col];// 表头样式:加粗、浅蓝背景、自动换行(EPPlus 4.x 样式设置)worksheet.Cells[1, col + 1].Style.Font.Bold = true;worksheet.Cells[1, col + 1].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;worksheet.Cells[1, col + 1].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightBlue);worksheet.Cells[1, col + 1].Style.WrapText = true;}// 步骤6:写入表数据并设置格式for (int row = 0; row < tableData.Data.Count; row++){for (int col = 0; col < tableData.Data[row].Length; col++){object cellValue = tableData.Data[row][col];worksheet.Cells[row + 2, col + 1].Value = cellValue;// 根据字段类型设置 Excel 格式Type columnType = tableData.ColumnTypes[col];if (columnType == typeof(DateTime)){// 日期时间格式(Excel 自定义格式)worksheet.Cells[row + 2, col + 1].Style.Numberformat.Format = "yyyy-mm-dd hh:mm:ss";}else if (columnType == typeof(decimal) || columnType == typeof(double)){// 数值格式(保留2位小数)worksheet.Cells[row + 2, col + 1].Style.Numberformat.Format = "#,##0.00";}// 可扩展其他类型(如整数、布尔值等)}}// 定义表格范围(表头+数据行):第1行到最后一行数据,第1列到最后一列int lastRow = tableData.Data.Count + 1;  // 数据行从第2行开始,最后一行是数据行数+1(表头占1行)int lastCol = tableData.Headers.Count;var tableRange = worksheet.Cells[1, 1, lastRow, lastCol];// 设置外边框(上下左右)tableRange.Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;tableRange.Style.Border.Top.Color.SetColor(System.Drawing.Color.Black);tableRange.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;tableRange.Style.Border.Bottom.Color.SetColor(System.Drawing.Color.Black);tableRange.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;tableRange.Style.Border.Left.Color.SetColor(System.Drawing.Color.Black);tableRange.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;tableRange.Style.Border.Right.Color.SetColor(System.Drawing.Color.Black);// ====================== 设置内部横线(单元格之间的横线) // 范围:第1行到倒数第1行(最后一行的下边框是外框,无需重复设置)var horizontalRange = worksheet.Cells[1, 1, lastRow - 1, lastCol];horizontalRange.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;horizontalRange.Style.Border.Bottom.Color.SetColor(System.Drawing.Color.Black);// ====================== 设置内部竖线(单元格之间的竖线) ======================// 范围:第1列到倒数第1列(最后一列的右边框是外框,无需重复设置)var verticalRange = worksheet.Cells[1, 1, lastRow, lastCol - 1];verticalRange.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;verticalRange.Style.Border.Right.Color.SetColor(System.Drawing.Color.Black);// 自动调整列宽worksheet.Cells[1, 1, tableData.Data.Count + 1, tableData.Headers.Count].AutoFitColumns();}catch (Exception ex){Z.ed.WriteMessage($"处理表 {tableName} 失败: {ex.Message}");}}}// ====================== 步骤7:保存Excel文件 ======================FileInfo fileInfo = new FileInfo(filePath);package.SaveAs(fileInfo);Z.ed.WriteMessage($"Excel文件已保存至: {filePath}");// 自动打开文件(可选)System.Diagnostics.Process.Start("explorer.exe", filePath);}catch (Exception ex){Z.ed.WriteMessage($"系统错误: {ex.Message}");}}}public class TableData{public List<string> Headers { get; set; }  // 表头(列名+类型)public List<Type> ColumnTypes { get; set; }  // 新增:字段类型(如 typeof(DateTime))public List<object[]> Data { get; set; }    // 表数据}}​

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux知识回顾总结----进程状态

本章将会介绍进程的一些概念&#xff1a;冯诺伊曼体系结构、进程是什么&#xff0c;怎么用、怎么表现得、进程空间地址、物理地址、虚拟地址、为什么存在进程空间地址、如何感性得去理解进程空间地址、环境变量是如何使用的。 目录 1. 冯诺伊曼体系结构 1.1 是什么 1.2 结论 …

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…

Android Test3 获取的ANDROID_ID值不同

Android Test3 获取的ANDROID_ID值不同 这篇文章来说明上一篇文章中说到的一个现象&#xff1a;在同一个项目中&#xff0c;创建不同的 app module&#xff0c;运行同一段测试代码&#xff0c;获取到的 ANDROID_ID 的值不同。 我也是第一次认真研究这个现象&#xff0c;这个还…

JSON 和 LabVIEW Data Types 互相转换

使用JSONtext C:\Program Files (x86)\National Instruments\LabVIEW 2021\examples\JDP Science\JSONtext JSONtext LabVIEW Data Types.vi

docker和docker-compose的版本对应关系怎么看?

docker和docker-compose的版本对应关系怎么看&#xff1f;最近在安装这两个工具&#xff0c;像知道他们的版本对应关系&#xff0c;查了不少资料才找到。 虽然 Docker 和 Docker Compose 的版本并不严格绑定&#xff0c;但是在某些情况下&#xff0c;新版本的 Docker Compose …

邮科ODM摄像头:多维度护航高铁安全系统方案解析

‌高铁作为现代交通的重要支柱&#xff0c;其安全稳定运行依赖于高效的监控体系。摄像头系统作为高铁安全管理的“视觉感知中枢”&#xff0c;凭借多场景覆盖、智能分析以及环境适应性设计&#xff0c;在行车安全、设备维护、乘客服务等方面发挥着不可或缺的作用。本文将从技术…

盒模型小全

CSS盒子模型详解 1. 定义 CSS盒子模型是用于描述HTML元素在页面中布局和表现的核心概念之一。在CSS中&#xff0c;所有HTML元素都被视为一个矩形的盒子&#xff0c;这些盒子封装了周围的HTML元素&#xff0c;并允许在其他元素和周围元素边框之间的空间放置内容。 2. 组成部分…

自定义鼠标效果 - 浏览器扩展使用教程

自定义鼠标效果 - 浏览器扩展使用教程 这里写目录标题 自定义鼠标效果 - 浏览器扩展使用教程功能特点安装方法Chrome/Edge浏览器 使用指南1. 更改鼠标光标样式2. 启用鼠标轨迹效果3. 自定义轨迹效果点状/彩虹/渐隐轨迹&#xff1a;表情轨迹&#xff1a; 管理自定义光标支持的文…

基于SpringBoot实现的课程答疑系统设计与实现【源码+文档】

基于SpringBootVue实现的课程答疑系统采用前后端分离架构方式&#xff0c;系统设计了管理员、学生、老师三种角色&#xff0c;系统实现了用户登录与注册、个人中心、学生管理、老师管理、科目类型管理、学生问题管理、老师回答管理、老师信息管理、关注列表管理、交流区、轮播图…

御微半导体面试总结

前一阵子在公司干的难受&#xff0c;所以再合肥这边面试了几家公司&#xff0c;挑一个御微半导体来说一下吧&#xff0c;公司主要是做半导体晶元测量的&#xff0c;具体啥我也不太明白。 公司产品线多&#xff0c;每条产品线配有独立的软件、结构、光学控制等人员开发语言和框…

Android Compose 自定义圆形取色盘

val Dp.toPx: Floatget() {var scale 3f // MyApplication.context.resources.displayMetrics.apply { // scale density // }return value * scale}val colors List(360) { i ->Color.hsv(360f - i, 1f, 1f) // 360到1的所有HSV颜色 }Preview …

vscode 配置 latex

下载插件 安装插件前自行安装 texlive, 按照 https://tug.org/texlive/ 要求安装 找到 settings 打开 json 文件 在 json 文件中添加如下配置 "latex-workshop.latex.tools": [{"name": "latexmk","command": "latexmk",&qu…

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(质检)

船舶质检管理现状&#xff1a;质检环节部分依赖人工检测&#xff0c;质检员依据质量标准对产品进行抽检或全检。人工质检受质检员主观因素影响较大&#xff0c;不同质检员对标准的把握可能存在差异。 一、痛点与需求 1 Arbigtec 人工经验依赖严重&#xff1a; 质检员的检测准确…

jenkins gerrit-trigger插件配置

插件gerrit-trigger下载好之后要在Manage Jenkins -->Gerrit Trigger-->New Server 中新增Gerrit Servers 配置好保存后点击“状态”查看是否正常

ubuntu24.04下 zookeeper3.8.4 集群的配置

1、环境 1.1 三台机器网络互通&#xff0c;并做hosts解析 准备三台及以上ubuntu24.04主机&#xff08;奇数&#xff09; rootzk-node01:~# hostname zk-node01rootzk-node01:~# cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 u24-server10.0.49.215 zk-node01 10.0.4…

火山引擎 veFuser:面向扩散模型的图像与视频生成推理服务框架

资料来源&#xff1a;火山引擎-开发者社区 DiT 模型与推理挑战 近年来&#xff0c;扩散模型&#xff08;Diffusion Models&#xff09;在生成式人工智能领域取得了突破性进展&#xff0c;尤其是在图像和视频生成方面表现卓越。基于 Transformer 的扩散模型&#xff08;DiT, D…

动态多目标进化算法:VARE(Vector Autoregressive Evolution)求解DF1-DF14,提供完整MATLAB代码

一、VARE简介 VARE&#xff08;Vector Autoregressive Evolution&#xff09;算法是2023年提出的一种新型的动态多目标优化&#xff08;DMO&#xff09;算法&#xff0c;旨在有效处理随时间变化的多目标优化问题。它通过结合向量自回归&#xff08;VAR&#xff09;模型和环境感…

【JavaEE】-- HTTPS

文章目录 1. HTTPS是什么&#xff1f;2. 加密是什么&#xff1f;2.1 引入对称加密&#xff08;效率高&#xff09;2.2 引入非对称加密&#xff08;效率低&#xff09;2.3 引入证书2.3.1 数据签名2.3.2 通过证书解决中间人攻击 1. HTTPS是什么&#xff1f; HTTP也是一个应用层协…

撰写脚本,通过发布/joint_states话题改变机器人在Rviz中的关节角度

撰写脚本&#xff0c;通过发布/joint_states话题改变机器人在Rviz中的关节角度 提问 为我写一个改变关节base_spherical_center_high_joint角度的python脚本吧。适用于ROS2的humble 回答 下面是一个适用于 ROS 2 Humble 的 Python 脚本&#xff0c;它会以指定频率持续发布 …

Redis : Hash类型

哈希类型 哈希类型的命令 hset 设置key指定的字段&#xff08;field&#xff09;的值&#xff08;value&#xff09; 也可以设置多组field和value hget 获得哈希中指定字段的值 如果该字段为空或者key为空则返回nil hexists 判断哈希中是否有该字段的值 如果有则会返回1…