如何通过书签为Word自动化表格添加行号?附代码示例
通过书签为Word自动化表格添加行号的实现方案
问题描述
我希望通过书签定位Word中的表格,实现自动化添加行号的功能,以下是我编写的代码:

原始代码
using System; using System.Data; using System.Data.OleDb; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; using Word = Microsoft.Office.Interop.Word; namespace Deneme { public partial class Form3 : Form { public Form3() { InitializeComponent(); } private DataTable GetDataSource() { var dt = new DataTable(); using (var conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=gezievrak2541.mdb; Mode = ReadWrite")) { conn.Open(); using (var adapter = new OleDbDataAdapter("SELECT tcno, sinifi FROM gezilistemiz25 where sinifi IS NOT NULL GROUP BY tcno, sinifi order BY Left(sinifi,1) desc,Left(sinifi,13) asc,Left(sinifi,12) asc", conn)) { adapter.Fill(dt); } return dt; } } private void Sabitbilgi() { DataTable dt = GetDataSource(); object oMissing = Missing.Value; Word.Application oWord = new Word.Application(); oWord.Visible = true; object oTemplatePath = Application.StartupPath + "\\Deneme.docx"; Word.Document oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing); object Index = "sinifi"; Word.Table tbl = oWordDoc.Bookmarks.get_Item(ref Index).Range.Tables[1]; int i = 1; foreach (DataRow r in dt.Rows) r["tcno"] = i++; // 给行号赋值 foreach (DataRow dr in dt.Rows) { Word.Row newRow = tbl.Rows.Add(ref oMissing); for (int j = 1; j <= dt.Columns.Count; j++) { newRow.Cells[j].Range.Text = dr[j - 1].ToString(); } } Marshal.ReleaseComObject(tbl); Marshal.ReleaseComObject(oWordDoc); Marshal.ReleaseComObject(oWord); } private void Form3_Load(object sender, EventArgs e) { Sabitbilgi(); } } }
优化与实现说明
你的核心逻辑是可行的,针对行号添加和代码健壮性,可做以下调整:
1. 直接在行插入时赋值行号
无需修改数据源DataTable,在插入每行时直接设置行号,避免对原始数据的改动:
// 替换原有行号赋值和循环部分 int rowNumber = 1; foreach (DataRow dr in dt.Rows) { Word.Row newRow = tbl.Rows.Add(ref oMissing); // 第一列设置行号 newRow.Cells[1].Range.Text = rowNumber.ToString(); // 第二列填充班级信息 newRow.Cells[2].Range.Text = dr["sinifi"].ToString(); rowNumber++; }
2. 添加书签存在性校验
避免因书签不存在导致程序报错:
string bookmarkName = "sinifi"; if (!oWordDoc.Bookmarks.Exists(bookmarkName)) { MessageBox.Show($"未找到指定书签:{bookmarkName}"); oWord.Quit(); return; }
3. 优化COM对象释放逻辑
添加异常捕获和有序释放,避免Office进程残留:
try { // 核心操作代码 } catch (Exception ex) { MessageBox.Show($"操作失败:{ex.Message}"); } finally { // 按从内到外顺序释放COM对象 if (tbl != null) Marshal.ReleaseComObject(tbl); if (oWordDoc != null) Marshal.ReleaseComObject(oWordDoc); if (oWord != null) { oWord.Quit(ref oMissing, ref oMissing, ref oMissing); Marshal.ReleaseComObject(oWord); } }
完整优化后的Sabitbilgi方法
private void Sabitbilgi() { DataTable dt = GetDataSource(); object oMissing = Missing.Value; Word.Application oWord = null; Word.Document oWordDoc = null; Word.Table tbl = null; try { oWord = new Word.Application(); oWord.Visible = true; object oTemplatePath = Application.StartupPath + "\\Deneme.docx"; oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing); string bookmarkName = "sinifi"; if (!oWordDoc.Bookmarks.Exists(bookmarkName)) { MessageBox.Show($"未找到书签:{bookmarkName}"); return; } tbl = oWordDoc.Bookmarks[bookmarkName].Range.Tables[1]; int rowNumber = 1; foreach (DataRow dr in dt.Rows) { Word.Row newRow = tbl.Rows.Add(ref oMissing); // 第一列赋值行号 newRow.Cells[1].Range.Text = rowNumber.ToString(); // 第二列填充班级信息 newRow.Cells[2].Range.Text = dr["sinifi"].ToString(); rowNumber++; } } catch (Exception ex) { MessageBox.Show($"执行出错:{ex.Message}"); } finally { // 释放COM对象 if (tbl != null) Marshal.ReleaseComObject(tbl); if (oWordDoc != null) Marshal.ReleaseComObject(oWordDoc); if (oWord != null) { oWord.Quit(ref oMissing, ref oMissing, ref oMissing); Marshal.ReleaseComObject(oWord); } } }
内容的提问来源于stack exchange,提问作者user17750070
相关产品推荐
相关产品推荐

