EPPlus:如何遍历工作表的每个内容块(单元格或合并区域)
本文关键字:单元格 区域 合并 何遍历 遍历 EPPlus 工作 | 更新日期: 2023-09-27 18:19:05
我试图遍历单元格和合并的单元格内的工作表,并替换一些模板文本与动态值。然而,直到现在,我还没有设法遍历所有非空单元格。目前我尝试了这个代码,但它抛出NullReferenceException当它试图访问合并单元格的Text属性。
我正在使用模板文件,从那里复制模板工作表到我的构造工作簿。我试着用一个没有副本的工作簿,它给出了相同的结果。
我还尝试将Where(cell => !cell. merge)闭包放入第一个foreach循环中,但结果相同。
using (var p = new ExcelPackage(new FileInfo(templateFile)))
{
var ws = _excel.Workbook.Worksheets.Add("Report", p.Workbook.Worksheets[sablonMunkafuzet]);
foreach (ExcelRangeBase cell in ws.Cells)
{
if (string.IsNullOrEmpty(cell.Text)) continue;
var s = cell.Text;
if (s.StartsWith("^^"))
ProcessCell(cell, s.Substring(2));
}
foreach (string mc in ws.MergedCells)
{
var s = ws.Cells[mc].Text;
if (s.StartsWith("^^"))
ProcessCell(ws.Cells[mc], s.Substring(2));
}
}
}
编辑:如果我在Excel中打开该模板,我想实现我手动做的事情。要找到出现特定文本模式的每个"块"(我的意思是单个单元格或合并的单元格范围),然后处理它,并将该"块"的值更改为我计算的值。
似乎我已经为我的场景找到了一个解决方案,如果将来有人需要这样的代码,这里是。
下面的代码段循环遍历工作表中的每个块(单个单元格或合并区域),并进行一些处理。在这种情况下,我正在做一个文本检查,如果有任何可替代的公式为我。^^是我的特殊信号,表示块中有一个模板定义,应该用我的运行时数据替换。
var ws = _excel.Workbook.Worksheets["myTemplateWorksheet"];
var dim = ws.Dimension;
// first loop through all non-merged cells
for (int r = dim.Start.Row; r <= dim.End.Row; ++r)
for (int c = dim.Start.Column; c <= dim.End.Column; ++c)
{
if (ws.Cells[r, c].Merge) continue;
string s = GetRangeText(ws.Cells[r,c]);
if (string.IsNullOrEmpty(s)) continue;
if (s.StartsWith("^^"))
ProcessCell(ws.Cells[r, c], s.Substring(2));
}
// then loop through all merged ranges
foreach (string mc in ws.MergedCells)
{
string s = GetRangeText(ws.Cells[mc]);
if (string.IsNullOrEmpty(s)) continue;
if (s.StartsWith("^^"))
ProcessCell(ws.Cells[mc], s.Substring(2));
}
使用helper方法,该方法从范围中提取文本,将合并范围的数组表示形式变为count:
private string GetRangeText(ExcelRangeBase range)
{
var val = range.Value;
string s = val as string;
if (string.IsNullOrEmpty(s))
{
object[,] arr = val as object[,];
if (arr != null && arr.GetLength(0) > 0 && arr.GetLength(1) > 0)
s = arr[0, 0] as string;
}
if (string.IsNullOrEmpty(s) && val != null)
s = val.ToString();
return s;
}