From b2bce1b5df8a506c212dc0526f6b94dae78c22ff Mon Sep 17 00:00:00 2001 From: lrc <571244399@qq.com> Date: Thu, 16 Jul 2026 21:11:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Depplus=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Component/XericUIActionTable.ExcelIO.cs | 635 ++++++++++-------- .../XericUIActionTable.ExcelIO.cs.meta | 11 + 2 files changed, 380 insertions(+), 266 deletions(-) create mode 100644 Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs.meta diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs index 8247db5..51e56d2 100644 --- a/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs @@ -15,266 +15,153 @@ namespace XericUI.XTable.Rendering.Component /// public partial class XericUIActionTable { - #region 导入 + #region 导入(公开入口) /// /// 从 Excel .xlsx 文件加载数据到表格。 - /// 支持文本、合并单元格、列宽、行高的导入。 /// /// Excel 文件路径 /// 工作表索引(0-based),默认 0 即第一个工作表 public void LoadFromExcelFile(string filePath, int sheetIndex = 0) { - if (string.IsNullOrEmpty(filePath)) + if (!TryOpenPackage(filePath, out ExcelPackage package)) return; + using (package) { - Debug.LogWarning("[XTable] LoadFromExcelFile: 文件路径为空"); - return; - } - - if (!File.Exists(filePath)) - { - Debug.LogWarning($"[XTable] LoadFromExcelFile: 文件不存在: {filePath}"); - return; - } - - try - { - using (var package = new ExcelPackage(new FileInfo(filePath))) + if (sheetIndex < 0 || sheetIndex >= package.Workbook.Worksheets.Count) { - if (sheetIndex < 0 || sheetIndex >= package.Workbook.Worksheets.Count) - { - Debug.LogWarning($"[XTable] LoadFromExcelFile: 工作表索引 {sheetIndex} 超出范围(共 {package.Workbook.Worksheets.Count} 个工作表)"); - return; - } - ExcelWorksheet ws = package.Workbook.Worksheets[sheetIndex]; - if (ws == null) - { - Debug.LogWarning("[XTable] LoadFromExcelFile: 工作簿中没有工作表"); - return; - } - - // 确定行列数 - int rows = 0, cols = 0; - if (ws.Dimension != null) - { - rows = ws.Dimension.Rows; - cols = ws.Dimension.Columns; - } - - if (rows <= 0 || cols <= 0) - { - Debug.LogWarning("[XTable] LoadFromExcelFile: Excel 文件为空或无法识别行列数"); - return; - } - - // 确保数据层存在 - if (m_TableData == null) - m_TableData = new XTableData(); - - // 设置行高 - m_RowHeights = new float[rows]; - for (int r = 0; r < rows; r++) - { - float h = (float)ws.Row(r + 1).Height; - m_RowHeights[r] = h > 0 ? h : Config.DefaultCellHeight; - } - - // 设置列宽 - m_ColWidths = new float[cols]; - for (int c = 0; c < cols; c++) - { - float w = (float)ws.Column(c + 1).Width; - m_ColWidths[c] = w > 0 ? w : Config.DefaultCellWidth; - } - - // 读取单元格文本 - for (int r = 0; r < rows; r++) - { - for (int c = 0; c < cols; c++) - { - object val = ws.Cells[r + 1, c + 1].Value; - if (val != null) - { - string text = val.ToString(); - if (!string.IsNullOrEmpty(text)) - { - var cell = m_TableData.GetOrCreateCell(r, c); - cell.Text = text; - } - } - } - } - - // 读取合并单元格 - if (ws.MergedCells.Count > 0) - { - m_TableData.ClearAllMerges(); - foreach (string mergeAddr in ws.MergedCells) - { - try - { - var addr = new ExcelAddressBase(mergeAddr); - int startR = addr.Start.Row - 1; // 1-based → 0-based - int startC = addr.Start.Column - 1; - int endR = addr.End.Row - 1; - int endC = addr.End.Column - 1; - int rowSpan = endR - startR + 1; - int colSpan = endC - startC + 1; - - if (rowSpan > 1 || colSpan > 1) - { - if (endR < rows && endC < cols) - m_TableData.MergeCells(startR, startC, rowSpan, colSpan); - } - } - catch - { - // 忽略无法解析的合并地址 - } - } - } - - // 读取冻结窗格 - string freezePanes = ws.View.FreezePanes; - if (!string.IsNullOrEmpty(freezePanes)) - { - try - { - var addr = new ExcelAddressBase(freezePanes); - int freezeRows = addr.Start.Row - 1; // 1-based → 冻结行数 - int freezeCols = addr.Start.Column - 1; // 1-based → 冻结列数 - if (freezeRows > 0 || freezeCols > 0) - SetFreezeCount(freezeRows, freezeCols); - } - catch - { - // 忽略解析失败的冻结地址 - } - } - - // 标记脏并刷新 - MarkDirty(TableDirtyType.DataChanged | TableDirtyType.LayoutChanged); - RecalculateTotalSize(); - RefreshView(); + Debug.LogWarning($"[XTable] LoadFromExcelFile: 工作表索引 {sheetIndex} 超出范围(共 {package.Workbook.Worksheets.Count} 个工作表)"); + return; } + ExcelWorksheet ws = package.Workbook.Worksheets[sheetIndex]; + if (!TryGetWorksheetDimension(ws, out int rows, out int cols)) return; + EnsureTableData(); + LoadFromExcelFileCore(ws, rows, cols); } - catch (Exception ex) + } + + /// + /// 从 Excel .xlsx 文件加载数据到表格,按工作表名称选择。 + /// + /// Excel 文件路径 + /// 工作表名称 + public void LoadFromExcelFile(string filePath, string sheetName) + { + if (string.IsNullOrEmpty(sheetName)) { - Debug.LogError($"[XTable] LoadFromExcelFile 失败: {ex.Message}\n{ex.StackTrace}"); + Debug.LogWarning("[XTable] LoadFromExcelFile: 工作表名称为空"); + return; + } + if (!TryOpenPackage(filePath, out ExcelPackage package)) return; + using (package) + { + ExcelWorksheet ws = package.Workbook.Worksheets[sheetName]; + if (ws == null) + { + Debug.LogWarning($"[XTable] LoadFromExcelFile: 找不到工作表 \"{sheetName}\""); + return; + } + if (!TryGetWorksheetDimension(ws, out int rows, out int cols)) return; + EnsureTableData(); + LoadFromExcelFileCore(ws, rows, cols); } } #endregion - #region 导出 + #region 导出(公开入口) /// - /// 将表格数据导出为 Excel .xlsx 文件。 - /// 支持文本、合并单元格、列宽、行高、样式(颜色/字体/填充)、边框缓存的导出。 + /// 将表格数据导出为 Excel .xlsx 文件,写入指定名称的工作表。 + /// 文件不存在时自动创建;已存在时查找或追加同名工作表。 /// /// Excel 文件路径 /// 工作表名称,默认 "Sheet1" public void SaveToExcelFile(string filePath, string sheetName = "Sheet1") { - if (string.IsNullOrEmpty(filePath)) - { - Debug.LogWarning("[XTable] SaveToExcelFile: 文件路径为空"); - return; - } - - // 确保目录存在 - string dir = Path.GetDirectoryName(filePath); - if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) - Directory.CreateDirectory(dir); + if (string.IsNullOrEmpty(sheetName)) sheetName = "Sheet1"; + if (!EnsureDirectory(filePath)) return; try { - using (var package = new ExcelPackage()) + if (File.Exists(filePath)) { - if (string.IsNullOrEmpty(sheetName)) - sheetName = "Sheet1"; - ExcelWorksheet ws = package.Workbook.Worksheets.Add(sheetName); - - int rows = m_RowHeights?.Length ?? 0; - int cols = m_ColWidths?.Length ?? 0; - - if (rows == 0 || cols == 0) + // 追加到已有文件 + using (var package = new ExcelPackage(new FileInfo(filePath))) { - // 空表格:创建空文件 + ExcelWorksheet ws = package.Workbook.Worksheets[sheetName] + ?? package.Workbook.Worksheets.Add(sheetName); + SaveToExcelFileCore(ws); + package.Save(); + } + } + else + { + // 创建新文件 + using (var package = new ExcelPackage()) + { + ExcelWorksheet ws = package.Workbook.Worksheets.Add(sheetName); + SaveToExcelFileCore(ws); package.SaveAs(new FileInfo(filePath)); - return; } + } + } + catch (Exception ex) + { + Debug.LogError($"[XTable] SaveToExcelFile 失败: {ex.Message}\n{ex.StackTrace}"); + } + } - // 设置列宽 - for (int c = 0; c < cols; c++) - ws.Column(c + 1).Width = m_ColWidths[c]; + /// + /// 将表格数据导出到 Excel .xlsx 文件,按索引覆盖指定工作表。 + /// 文件不存在时自动创建。 + /// + /// Excel 文件路径 + /// 工作表索引(0-based) + public void SaveToExcelFile(string filePath, int sheetIndex) + { + if (sheetIndex < 0) + { + Debug.LogWarning($"[XTable] SaveToExcelFile: 工作表索引不能为负数"); + return; + } + if (!EnsureDirectory(filePath)) return; - // 设置行高 - for (int r = 0; r < rows; r++) + try + { + if (File.Exists(filePath)) + { + // 写入已有文件的指定 sheet + using (var package = new ExcelPackage(new FileInfo(filePath))) { - float h = m_RowHeights[r]; - if (h > 0) - ws.Row(r + 1).Height = h; - } - - // 写入冻结窗格 - if (m_FreezeRowCount > 0 || m_FreezeColCount > 0) - { - int freezeRow = m_FreezeRowCount + 1; // 1-based: 冻结行数的下一行 - int freezeCol = m_FreezeColCount + 1; // 1-based: 冻结列数的下一列 - ws.View.FreezePanes = ExcelCellBase.GetAddress(freezeRow, freezeCol); - } - - // 写入单元格数据和样式 - for (int r = 0; r < rows; r++) - { - for (int c = 0; c < cols; c++) + int count = package.Workbook.Worksheets.Count; + ExcelWorksheet ws; + if (sheetIndex < count) { - // 跳过被合并覆盖的单元格(稍后通过合并区域统一处理) - if (m_TableData != null && m_TableData.IsCellMerged(r, c)) - continue; - - var cell = m_TableData?.GetCell(r, c); - if (cell == null) continue; - - var excelCell = ws.Cells[r + 1, c + 1]; - - // 写入文本 - if (!string.IsNullOrEmpty(cell.Text)) - excelCell.Value = cell.Text; - - // 应用样式 - string ns = !string.IsNullOrEmpty(cell.StyleNamespace) - ? cell.StyleNamespace - : m_DefaultStyleNamespace; - if (!string.IsNullOrEmpty(ns)) - ApplyStyleToExcelCell(excelCell, ns); + ws = package.Workbook.Worksheets[sheetIndex]; } + else + { + // 超出范围则追加,中间空缺补空白 sheet + while (package.Workbook.Worksheets.Count <= sheetIndex) + package.Workbook.Worksheets.Add("Sheet" + (package.Workbook.Worksheets.Count + 1)); + ws = package.Workbook.Worksheets[sheetIndex]; + } + SaveToExcelFileCore(ws); + package.Save(); } - - // 写入合并单元格 - if (m_TableData != null) + } + else + { + // 创建新文件 + using (var package = new ExcelPackage()) { - WriteMergedCellsToExcel(ws, rows, cols); + // 补齐到目标索引 + while (package.Workbook.Worksheets.Count <= sheetIndex) + package.Workbook.Worksheets.Add("Sheet" + (package.Workbook.Worksheets.Count + 1)); + ExcelWorksheet ws = package.Workbook.Worksheets[sheetIndex]; + SaveToExcelFileCore(ws); + package.SaveAs(new FileInfo(filePath)); } - - // 写入边框缓存 - if (m_TableData != null) - { - WriteBorderCacheToExcel(ws, rows, cols); - } - - // 写入表格外边框 - if (m_TableData != null && m_TableData.OuterBorderNs != null && m_TableData.OuterBorderNs.Count > 0) - { - var outerRange = ws.Cells[1, 1, rows, cols]; - var border = outerRange.Style.Border; - border.BorderAround(ExcelBorderStyle.Thin, - System.Drawing.Color.FromArgb(180, 180, 180)); - } - - // 保存 - package.SaveAs(new FileInfo(filePath)); } } catch (Exception ex) @@ -285,18 +172,255 @@ namespace XericUI.XTable.Rendering.Component #endregion + #region 导入核心 + + /// + /// 从已打开的工作表读取数据填入表格。 + /// + private void LoadFromExcelFileCore(ExcelWorksheet ws, int rows, int cols) + { + // 设置行高 + m_RowHeights = new float[rows]; + for (int r = 0; r < rows; r++) + { + float h = (float)ws.Row(r + 1).Height; + m_RowHeights[r] = h > 0 ? h : Config.DefaultRowHeight; + } + + // 设置列宽 + m_ColWidths = new float[cols]; + for (int c = 0; c < cols; c++) + { + float w = (float)ws.Column(c + 1).Width; + m_ColWidths[c] = w > 0 ? w : Config.DefaultColumnWidth; + } + + // 读取单元格文本 + for (int r = 0; r < rows; r++) + { + for (int c = 0; c < cols; c++) + { + object val = ws.Cells[r + 1, c + 1].Value; + if (val != null) + { + string text = val.ToString(); + if (!string.IsNullOrEmpty(text)) + { + var cell = m_TableData.GetOrCreateCell(r, c); + cell.Text = text; + } + } + } + } + + // 读取合并单元格 + if (ws.MergedCells.Count > 0) + { + m_TableData.ClearAllMerges(); + foreach (string mergeAddr in ws.MergedCells) + { + try + { + var addr = new ExcelAddressBase(mergeAddr); + int startR = addr.Start.Row - 1; + int startC = addr.Start.Column - 1; + int endR = addr.End.Row - 1; + int endC = addr.End.Column - 1; + int rowSpan = endR - startR + 1; + int colSpan = endC - startC + 1; + + if ((rowSpan > 1 || colSpan > 1) && endR < rows && endC < cols) + m_TableData.MergeCells(startR, startC, rowSpan, colSpan); + } + catch + { + // 忽略无法解析的合并地址 + } + } + } + + // 读取冻结窗格 + // FreezePanes 是 EPPlus 的写入方法,读取需通过工作表 XML 中的 d:pane 节点 + try + { + var nsMgr = new System.Xml.XmlNamespaceManager(ws.WorksheetXml.NameTable); + nsMgr.AddNamespace("d", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + var paneNode = ws.WorksheetXml.SelectSingleNode("//d:pane[@state='frozen']", nsMgr); + if (paneNode?.Attributes != null) + { + string xSplit = paneNode.Attributes["xSplit"]?.Value; + string ySplit = paneNode.Attributes["ySplit"]?.Value; + int freezeRows = int.TryParse(ySplit, out var fr) ? fr : 0; + int freezeCols = int.TryParse(xSplit, out var fc) ? fc : 0; + if (freezeRows > 0 || freezeCols > 0) + SetFreezeCount(freezeRows, freezeCols); + } + } + catch + { + // 忽略解析失败的冻结信息 + } + + // 标记脏并刷新 + MarkDirty(TableDirtyType.DataChanged | TableDirtyType.LayoutChanged); + RecalculateTotalSize(); + RefreshView(); + } + + #endregion + + #region 导出核心 + + /// + /// 将表格数据写入已准备好的工作表。 + /// + private void SaveToExcelFileCore(ExcelWorksheet ws) + { + int rows = m_RowHeights?.Length ?? 0; + int cols = m_ColWidths?.Length ?? 0; + + if (rows == 0 || cols == 0) return; + + // 设置列宽 + for (int c = 0; c < cols; c++) + ws.Column(c + 1).Width = m_ColWidths[c]; + + // 设置行高 + for (int r = 0; r < rows; r++) + { + float h = m_RowHeights[r]; + if (h > 0) ws.Row(r + 1).Height = h; + } + + // 写入冻结窗格 + if (m_FreezeRowCount > 0 || m_FreezeColCount > 0) + { + int freezeRow = m_FreezeRowCount + 1; + int freezeCol = m_FreezeColCount + 1; + ws.View.FreezePanes(freezeRow, freezeCol); + } + + // 写入单元格数据和样式 + for (int r = 0; r < rows; r++) + { + for (int c = 0; c < cols; c++) + { + if (m_TableData != null && m_TableData.IsCellMerged(r, c)) + continue; + + var cell = m_TableData?.GetCell(r, c); + if (cell == null) continue; + + var excelCell = ws.Cells[r + 1, c + 1]; + + if (!string.IsNullOrEmpty(cell.Text)) + excelCell.Value = cell.Text; + + string ns = !string.IsNullOrEmpty(cell.StyleNamespace) + ? cell.StyleNamespace + : m_DefaultStyleNamespace; + if (!string.IsNullOrEmpty(ns)) + ApplyStyleToExcelCell(excelCell, ns); + } + } + + // 写入合并单元格 + if (m_TableData != null) + WriteMergedCellsToExcel(ws, rows, cols); + + // 写入边框缓存 + if (m_TableData != null) + WriteBorderCacheToExcel(ws, rows, cols); + + // 写入表格外边框 + if (m_TableData?.OuterBorderNs != null && m_TableData.OuterBorderNs.Count > 0) + { + var outerRange = ws.Cells[1, 1, rows, cols]; + outerRange.Style.Border.BorderAround(ExcelBorderStyle.Thin, + System.Drawing.Color.FromArgb(180, 180, 180)); + } + } + + #endregion + #region 辅助方法 + /// 打开 Excel 包,失败时 LogWarning 并返回 false。 + private static bool TryOpenPackage(string filePath, out ExcelPackage package) + { + package = null; + if (string.IsNullOrEmpty(filePath)) + { + Debug.LogWarning("[XTable] LoadFromExcelFile: 文件路径为空"); + return false; + } + if (!File.Exists(filePath)) + { + Debug.LogWarning($"[XTable] LoadFromExcelFile: 文件不存在: {filePath}"); + return false; + } + try + { + package = new ExcelPackage(new FileInfo(filePath)); + return true; + } + catch (Exception ex) + { + Debug.LogError($"[XTable] 无法打开 Excel 文件: {ex.Message}"); + return false; + } + } + + /// 获取工作表的有效维度,空表返回 false。 + private static bool TryGetWorksheetDimension(ExcelWorksheet ws, out int rows, out int cols) + { + rows = 0; cols = 0; + if (ws == null) + { + Debug.LogWarning("[XTable] 工作表为空"); + return false; + } + if (ws.Dimension != null) + { + rows = ws.Dimension.Rows; + cols = ws.Dimension.Columns; + } + if (rows <= 0 || cols <= 0) + { + Debug.LogWarning("[XTable] Excel 文件为空或无法识别行列数"); + return false; + } + return true; + } + + /// 确保数据层存在。 + private void EnsureTableData() + { + if (m_TableData == null) + m_TableData = new XTableData(); + } + + /// 确保导出目录存在,路径为空时返回 false。 + private static bool EnsureDirectory(string filePath) + { + if (string.IsNullOrEmpty(filePath)) + { + Debug.LogWarning("[XTable] SaveToExcelFile: 文件路径为空"); + return false; + } + string dir = Path.GetDirectoryName(filePath); + if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) + Directory.CreateDirectory(dir); + return true; + } + /// /// 将 XTable 的 StyleNamespace 映射为 Excel 单元格样式(字体颜色、背景、字号、对齐)。 /// private void ApplyStyleToExcelCell(ExcelRange excelCell, string ns) { - if (string.IsNullOrEmpty(ns)) return; - + // ns 已确保非空 var style = excelCell.Style; - - // 字体颜色 Color fgColor = GetCellFgColor(ns); style.Font.Color.SetColor(System.Drawing.Color.FromArgb( (byte)(fgColor.a * 255), @@ -304,7 +428,6 @@ namespace XericUI.XTable.Rendering.Component (byte)(fgColor.g * 255), (byte)(fgColor.b * 255))); - // 背景填充 Color bgColor = GetCellBgColor(ns); style.Fill.PatternType = ExcelFillStyle.Solid; style.Fill.BackgroundColor.SetColor(System.Drawing.Color.FromArgb( @@ -313,12 +436,10 @@ namespace XericUI.XTable.Rendering.Component (byte)(bgColor.g * 255), (byte)(bgColor.b * 255))); - // 字体大小 int fontSize = GetCellFontSize(ns); if (fontSize > 0) style.Font.Size = fontSize; - // 对齐 style.HorizontalAlignment = ExcelHorizontalAlignment.Center; style.VerticalAlignment = ExcelVerticalAlignment.Center; } @@ -337,18 +458,15 @@ namespace XericUI.XTable.Rendering.Component foreach (var desc in block.MergeDescriptors) { - if (desc.IsCrossBlock) continue; // 跨块合并暂不处理 + if (desc.IsCrossBlock) continue; - // 计算全局坐标 int blockRow = block.BlockRow; int blockCol = block.BlockCol; int globalStartRow = blockRow * m_TableData.BlockSizeY + desc.LocalStartRow; int globalStartCol = blockCol * m_TableData.BlockSizeX + desc.LocalStartCol; - int endR = globalStartRow + desc.MergeRowSpan - 1; int endC = globalStartCol + desc.MergeColSpan - 1; - // 检查边界 if (endR >= rows || endC >= cols) continue; var range = ws.Cells[globalStartRow + 1, globalStartCol + 1, endR + 1, endC + 1]; @@ -368,12 +486,10 @@ namespace XericUI.XTable.Rendering.Component { for (int c = 0; c < cols; c++) { - // 跳过被合并覆盖的单元格 if (m_TableData.IsCellMerged(r, c)) continue; var excelCell = ws.Cells[r + 1, c + 1]; - // 右侧边框 string rightNs = m_TableData.GetBorderRightNs(r, c); if (!string.IsNullOrEmpty(rightNs)) { @@ -382,13 +498,10 @@ namespace XericUI.XTable.Rendering.Component excelCell.Style.Border.Right.Style = BorderWidthToStyle(width); excelCell.Style.Border.Right.Color.SetColor( System.Drawing.Color.FromArgb( - (byte)(color.a * 255), - (byte)(color.r * 255), - (byte)(color.g * 255), - (byte)(color.b * 255))); + (byte)(color.a * 255), (byte)(color.r * 255), + (byte)(color.g * 255), (byte)(color.b * 255))); } - // 底部边框 string bottomNs = m_TableData.GetBorderBottomNs(r, c); if (!string.IsNullOrEmpty(bottomNs)) { @@ -397,10 +510,8 @@ namespace XericUI.XTable.Rendering.Component excelCell.Style.Border.Bottom.Style = BorderWidthToStyle(width); excelCell.Style.Border.Bottom.Color.SetColor( System.Drawing.Color.FromArgb( - (byte)(color.a * 255), - (byte)(color.r * 255), - (byte)(color.g * 255), - (byte)(color.b * 255))); + (byte)(color.a * 255), (byte)(color.r * 255), + (byte)(color.g * 255), (byte)(color.b * 255))); } } } @@ -409,36 +520,28 @@ namespace XericUI.XTable.Rendering.Component for (int c = 0; c < cols; c++) { string topNs = m_TableData.GetBorderBottomNs(-1, c); - if (!string.IsNullOrEmpty(topNs)) - { - Color color = GetCellBorderColor(topNs); - float width = GetCellBorderWidth(topNs); - ws.Cells[1, c + 1].Style.Border.Top.Style = BorderWidthToStyle(width); - ws.Cells[1, c + 1].Style.Border.Top.Color.SetColor( - System.Drawing.Color.FromArgb( - (byte)(color.a * 255), - (byte)(color.r * 255), - (byte)(color.g * 255), - (byte)(color.b * 255))); - } + if (string.IsNullOrEmpty(topNs)) continue; + Color color = GetCellBorderColor(topNs); + float width = GetCellBorderWidth(topNs); + ws.Cells[1, c + 1].Style.Border.Top.Style = BorderWidthToStyle(width); + ws.Cells[1, c + 1].Style.Border.Top.Color.SetColor( + System.Drawing.Color.FromArgb( + (byte)(color.a * 255), (byte)(color.r * 255), + (byte)(color.g * 255), (byte)(color.b * 255))); } // 左侧外框(第一列左侧) for (int r = 0; r < rows; r++) { string leftNs = m_TableData.GetBorderRightNs(r, -1); - if (!string.IsNullOrEmpty(leftNs)) - { - Color color = GetCellBorderColor(leftNs); - float width = GetCellBorderWidth(leftNs); - ws.Cells[r + 1, 1].Style.Border.Left.Style = BorderWidthToStyle(width); - ws.Cells[r + 1, 1].Style.Border.Left.Color.SetColor( - System.Drawing.Color.FromArgb( - (byte)(color.a * 255), - (byte)(color.r * 255), - (byte)(color.g * 255), - (byte)(color.b * 255))); - } + if (string.IsNullOrEmpty(leftNs)) continue; + Color color = GetCellBorderColor(leftNs); + float width = GetCellBorderWidth(leftNs); + ws.Cells[r + 1, 1].Style.Border.Left.Style = BorderWidthToStyle(width); + ws.Cells[r + 1, 1].Style.Border.Left.Color.SetColor( + System.Drawing.Color.FromArgb( + (byte)(color.a * 255), (byte)(color.r * 255), + (byte)(color.g * 255), (byte)(color.b * 255))); } } diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs.meta b/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs.meta new file mode 100644 index 0000000..fcb93b8 --- /dev/null +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20fe94b5450de624a9198b851207193a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: