如何用C#查找Excel中目标字符串旁单元格内容并写入文本文件?
解决Excel查找指定字符串并提取相邻单元格值的问题
首先,咱们来拆解你遇到的问题和错误根源:
你看到的Microsoft.CSharp.RuntimeBinder.RuntimeBinderException错误,核心原因是这行代码:
return ws.Cells[i, j++];
ws.Cells[i, j++]返回的是Excel的Range对象(也就是System.__ComObject),并非字符串类型,你直接把它当作string返回,自然会触发类型不匹配的错误。另外,你的ReadCell方法现在只检查单个单元格,完全没实现“遍历查找指定字符串”的核心需求,这也是功能无法正常工作的关键。
接下来,咱们一步步修正代码,实现你的需求:
1. 重构Excel操作类,实现查找逻辑
首先,我们把Class1改成更易维护的工具类,添加遍历查找的方法,同时处理Excel资源释放(避免后台残留Excel进程):
using Microsoft.Office.Interop.Excel; using System; using System.Collections.Generic; using _Excel = Microsoft.Office.Interop.Excel; namespace WindowsFormsApp2 { class ExcelHelper { private readonly string _filePath; private readonly _Application _excelApp; private Workbook _workbook; private Worksheet _worksheet; public ExcelHelper(string filePath, int sheetIndex) { _filePath = filePath; _excelApp = new _Excel.Application(); _workbook = _excelApp.Workbooks.Open(filePath); _worksheet = (Worksheet)_workbook.Worksheets[sheetIndex]; } // 查找包含指定字符串的单元格,返回其右侧相邻单元格的所有值 public List<string> FindTargetAndGetAdjacentValues(string targetText) { var resultList = new List<string>(); // 获取工作表中实际有数据的区域,避免遍历空单元格 Range usedRange = _worksheet.UsedRange; // 遍历每一行每一列 for (int row = 1; row <= usedRange.Rows.Count; row++) { for (int col = 1; col <= usedRange.Columns.Count; col++) { Range currentCell = usedRange.Cells[row, col]; // 先判断单元格值是否为空,避免空引用 if (currentCell.Value2 == null) continue; string cellContent = currentCell.Value2.ToString(); // 你问的Contains方法这里就可以用,用来判断是否包含目标字符串 if (cellContent.Contains(targetText)) { // 获取右侧相邻单元格(同一行,列数+1) Range adjacentCell = usedRange.Cells[row, col + 1]; if (adjacentCell.Value2 != null) { resultList.Add(adjacentCell.Value2.ToString()); } else { resultList.Add("相邻单元格无内容"); } } } } return resultList; } // 必须调用这个方法释放Excel资源,否则后台会残留Excel进程 public void CleanupResources() { _workbook.Close(); _excelApp.Quit(); // 手动释放COM对象 System.Runtime.InteropServices.Marshal.ReleaseComObject(_worksheet); System.Runtime.InteropServices.Marshal.ReleaseComObject(_workbook); System.Runtime.InteropServices.Marshal.ReleaseComObject(_excelApp); } } }
2. 修正Form1中的调用逻辑
现在修改Form1的代码,调用上面的工具类,把结果写入文本文件:
using System; using System.IO; using System.Windows.Forms; using System.Collections.Generic; namespace WindowsFormsApp2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { ProcessExcelAndExport(); } private void ProcessExcelAndExport() { string excelPath = @"C:\Users\info\Documents\Zkouska.xlsx"; string outputTxtPath = @"C:\Users\info\Documents\new.txt"; string targetString = "Z_KomSilnice_L (24200)/7 "; ExcelHelper excelHelper = null; try { // 初始化Excel工具,指定第1个工作表(Excel工作表索引从1开始) excelHelper = new ExcelHelper(excelPath, 1); // 执行查找并获取相邻单元格值 List<string> extractedValues = excelHelper.FindTargetAndGetAdjacentValues(targetString); // 写入文本文件,false表示覆盖原有内容,true则是追加 using (StreamWriter writer = new StreamWriter(outputTxtPath, false)) { foreach (string value in extractedValues) { writer.WriteLine(value); // 每个值单独占一行 } } MessageBox.Show("操作完成!已提取数据到文本文件"); } catch (Exception ex) { MessageBox.Show($"操作出错:{ex.Message}"); } finally { // 确保无论是否出错,都释放Excel资源 excelHelper?.CleanupResources(); } } } }
关键细节说明
- 关于Contains方法:完全可以使用!上面的代码里已经用
cellContent.Contains(targetText)实现了模糊匹配,比精确相等更灵活,符合你的查找需求。 - Excel资源释放:一定要调用
CleanupResources方法,否则Excel进程会一直在后台运行,占用系统内存。 - 空值处理:每次读取单元格值前都判断是否为null,避免空引用异常。
- 遍历效率:使用
UsedRange只遍历有数据的区域,不会浪费时间在空单元格上。
现在运行代码,就能实现你想要的功能:在Excel中找到包含指定字符串的单元格,提取其右侧相邻单元格的值并写入文本文件了。
内容的提问来源于stack exchange,提问作者userdavid
相关产品推荐
相关产品推荐

