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

Word自动化循环操作报错:多数据行导出问题咨询

问题分析与解决方法

你的代码核心问题是逻辑顺序完全颠倒:你在遍历每个Word合并字段时,反复查询数据库并循环所有数据行,这会导致第一个字段写完所有行数据后,后续字段再读取数据时reader已经处于末尾,触发读取错误。正确的逻辑应该是先读取所有数据库数据,再针对每一行数据,基于模板生成对应的Word内容并填充字段。

修正后的代码

using System;
using System.Data.OleDb;
using System.Windows.Forms;
using Word = Microsoft.Office.Interop.Word;

public void ExportToWord()
{
    Object oMissing = System.Reflection.Missing.Value;
    Word.Application oWord = new Word.Application();
    oWord.Visible = true;
    string templatePath = Application.StartupPath + "\\GeziListesi.docx";

    // 一次性读取所有数据库数据
    using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=gezievrak2541.mdb; Mode = ReadWrite"))
    {
        conn.Open();
        using (OleDbCommand cmd = new OleDbCommand("Select * from gezibilgileri25", conn))
        {
            using (OleDbDataReader dr = cmd.ExecuteReader())
            {
                // 遍历每一行数据
                while (dr.Read())
                {
                    // 基于模板新建文档副本
                    Word.Document oWordDoc = oWord.Documents.Add(ref templatePath, ref oMissing, ref oMissing, ref oMissing);

                    // 遍历文档合并字段,填充当前行数据
                    foreach (Word.Field myMergeField in oWordDoc.Fields)
                    {
                        Word.Range rngFieldCode = myMergeField.Code;
                        string fieldText = rngFieldCode.Text;

                        if (fieldText.StartsWith(" MERGEFIELD"))
                        {
                            int endMerge = fieldText.IndexOf("\\");
                            string fieldName = fieldText.Substring(11, endMerge - 11).Trim();

                            switch (fieldName)
                            {
                                case "tcno":
                                    myMergeField.Select();
                                    oWord.Selection.TypeText(dr["tcno"].ToString());
                                    break;
                                case "adsoyad":
                                    myMergeField.Select();
                                    oWord.Selection.TypeText($"{dr["adi"]} {dr["soyadi"]}");
                                    break;
                                case "sinifi":
                                    myMergeField.Select();
                                    oWord.Selection.TypeText(dr["sinifi"].ToString());
                                    break;
                                case "unvan":
                                    myMergeField.Select();
                                    oWord.Selection.TypeText(dr["unvani"].ToString());
                                    break;
                            }
                        }
                    }
                }
            }
        }
    }

    // 清理COM对象,避免内存泄漏
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

关键改动说明

  • 逻辑顺序调整:先读取全量数据库数据,再逐行处理,每行对应一份模板文档,彻底避免reader越界问题。
  • 资源优化:数据库连接、命令仅初始化一次,减少重复连接的开销和资源浪费。
  • 代码简化:用switch替代多分支if,字段匹配逻辑更清晰易维护。
  • 避免重复写入:每个合并字段仅填充当前行的对应数据,不会出现同一字段重复写入所有行内容的错误。

额外优化建议

如果需要将所有数据导出到同一个Word文档,可以修改逻辑:打开一份模板文档后,每处理完一行数据就插入分页,复制模板内容到新页面,再填充下一行数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:17:36