?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; } // 表數據}}?