You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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();
            }
        }
    }
}

关键细节说明

  1. 关于Contains方法:完全可以使用!上面的代码里已经用cellContent.Contains(targetText)实现了模糊匹配,比精确相等更灵活,符合你的查找需求。
  2. Excel资源释放:一定要调用CleanupResources方法,否则Excel进程会一直在后台运行,占用系统内存。
  3. 空值处理:每次读取单元格值前都判断是否为null,避免空引用异常。
  4. 遍历效率:使用UsedRange只遍历有数据的区域,不会浪费时间在空单元格上。

现在运行代码,就能实现你想要的功能:在Excel中找到包含指定字符串的单元格,提取其右侧相邻单元格的值并写入文本文件了。

内容的提问来源于stack exchange,提问作者userdavid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:28:13