logo资料库

C#操作word模板.docx

第1页 / 共22页
第2页 / 共22页
第3页 / 共22页
第4页 / 共22页
第5页 / 共22页
第6页 / 共22页
第7页 / 共22页
第8页 / 共22页
资料共22页,剩余部分请下载后查看
C#操作 Word 书签模板 C#操作 Word 书签模板 一制作模板 1 新建一个文档,设置文档内容。对于循环的部分,建议放到表格内,这样容易定位、选择、 复制、粘贴。 2 将鼠标定位到要插入书签的位置,从菜单上,“插入”->“书签”,弹出对话框,输入书签 名,点击“添加”按钮。 插入以下书签:order_num,报告日期_,报表模板__,name,age,结论__ 其中,报表模板__,用于定位模板表格。可有可无,没有时,默认表格 1。 完成后,所有书签的名称和位置如下图所示:
3 保存模板,比如“word 书签模板.doc” 二 添加引用 1 右击“解决方案资源管理器”中的项目目录下的“引用”,选择“添加引用”,打开“添加 引用”对话框 2 对于 WindowsForm 方式时,在“添加引用”-->“COM”-->“Microsoft Word 11.0 Object Library”, 点击“确定”
3 对于 WebSite 网站方式时,打开“添加引用”-->“浏览”项-->”Microsoft.Office.Interop.Word.dll” 文件,选中它,点击“确定” 注意:此处要查找的“Microsoft.Office.Interop.Word.dll”版本必须为“11.*.*.*”,“*”代表 数字 以上版本对应是 Office Word 2003 版本。 三 编译执行 如 果 编 译 时 产 生 错 误 CS1752: 无 法 嵌 入 互 操 作 类 型 “Microsoft.Office.Interop.Word.ApplicationClass”。请改用适用的接口。 ,那么,点击 “解决方案”下“工程名称”之下的“引用”之下的 Word,在其属性下,将 “潜入互操作类型”,由 true 改为 false 即可。
运行结过如下: 四 主要的代码如下:
1 首先引用(WindowsForm):Microsoft Word 11.0 Object Library 或者引用(WebSite):Microsoft.Office.Interop.Word.dll 2 在使用的程序中,加入以下语句 using Word = Microsoft.Office.Interop.Word; ===== 1 主操作界面代码 === using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Word = Microsoft.Office.Interop.Word; using word_namespace; namespace winFormApp_word_bookmark { public partial class Form1 : Form { private object missing = System.Reflection.Missing.Value; WordHelper wdHelp; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { wdHelp = new WordHelper(); wdHelp.CreateOneDocument("c:\\ii.doc", missing, missing, missing); //1 这里简单生成样例数据表,工作中要以实际的数据集为准 DataTable dt = new DataTable(); dt.Columns.Add("name", typeof(string)); dt.Columns.Add("age", typeof(int)); DataRow dr = dt.NewRow(); dr["name"] = "张三"; dr["age"] = 20; dt.Rows.Add(dr); dr = dt.NewRow(); dr["name"] = "李四"; dr["age"] = 25; dt.Rows.Add(dr); //2 调用模板替换函数,生成实际的数据 SetNameCellValue(dt);
wdHelp.SaveAs("c:\\bb.doc"); wdHelp.Close(); MessageBox.Show("ok"); } public void SetNameCellValue(DataTable dt) { //(一) 这里设置表头的项目,比如报表日期 //特别注意:为了容易起见,命名单元格的规则如下,注意:word 中书签不能以下划 线开头,可能是保留的书签使用 //1.1 开头处的命名单元格,以 1 个下划线结尾,比如,报告日期_ //1.2 中间循环命名单元格,就是正常的,与数据集的字段名一致为好 //1.3 结尾处的命名单元格,以 2 个下划线结尾,比如,合计__ try {//为了程序自动处理方便起见 wdHelp.GoToBookMark("报告日期_");//开始处的命名单元格,都以 1 个下划线_结尾 wdHelp.InsertText(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")); } catch (System.Exception ex) { } //(二) 根据数据源的个数,设置重复变化的数据行组, //1 声明与命名单元格相关的变量和数组 int min_Row = 65536, min_Col = 65536, max_Row = 0; string min_Name = ""; int nameCellCount = wdHelp.wordDoc.Bookmarks.Count;//获得命名单元格的总数 int[] nameCellRow = new int[nameCellCount];//某个命名单元格的行 int[] nameCellColumn = new int[nameCellCount];//某个命名单元格的列 string[] nameCellTag = new string[nameCellCount];//某个命名单元格的常规地址 ,比如 $A$1 string[] nameCellName = new string[nameCellCount];//某个命名单元格的自定义名称, 比如 工资 string strName, str; int row1, row2;//选择重复的行 int nameCellIdx = 0; Word.Range tmpRange,srcRange,desRange; //2 寻找所有命名的单元格,并找到行号最小者,以便在它之前插入循环行 for (int k = 0; k < nameCellCount; k++) { strName = wdHelp.wordDoc.Bookmarks[k + 1].Name;// str = strName.Substring(strName.Length - 1, 1); if (str == "_") { continue;//如果第一个字符为下划线,则认为是固定命名单元格,不是命名的循
环单元格 } try { tmpRange = wdHelp.wordDoc.Bookmarks.get_Item(strName).Range; nameCellColumn[nameCellIdx] = tmpRange.Cells[1].ColumnIndex;// app.ActiveCell.Column; nameCellRow[nameCellIdx] = tmpRange.Cells[1].RowIndex;//app.ActiveCell.Row; nameCellName[nameCellIdx] = strName; nameCellTag[nameCellIdx] = "";// app.ActiveCell.Address;//$A$1 nameCellTag[nameCellIdx] = "";// nameCellTag[nameCellIdx].Split('$')[1];//$A$1--> A if (min_Row > nameCellRow[nameCellIdx]) { min_Row = nameCellRow[nameCellIdx];//最小的行号 min_Col = nameCellColumn[nameCellIdx]; min_Name = nameCellName[nameCellIdx]; } nameCellRow[nameCellIdx]; ;//最大行号 nameCellIdx++;//真实的循环的命名单元格序号 if (max_Row < nameCellRow[nameCellIdx]) max_Row = } catch (System.Exception ex) { } } nameCellCount = nameCellIdx;//实际要处理的循环的命名单元格数目 int loopRow = max_Row - min_Row + 1;//一次循环的函数 //3 也 可 以 使 用 //foreach ( Word.Bookmark bk in wh.wordDoc.Bookmarks)MessageBox.Show(bk.Name); Word.Table operTable; // 方法 1 通常使用第一个表来作为模板表 operTable = wdHelp.wordDoc.Tables[1]; // 方法 2 使用一个书签来标志模板表 try {//使用一个特殊的标签 table_bookmark_template_ tmpRange = wdHelp.wordDoc.Bookmarks.get_Item("报表模板__").Range;// operTable = tmpRange.Tables[1];//得到该书签所在的表,以它为报表的循环模板 } catch (System.Exception ex) { } // int template_start = 0;
int template_end = 0; int table_columns=operTable.Columns.Count;//本表格的烈数 tmpRange = operTable.Cell(min_Row, 1).Range; template_start =tmpRange.Start;//循环行组的第一行,第一个单元格,到文档开头的距 tmpRange = operTable.Cell(max_Row, table_columns).Range; template_end = tmpRange.Start; //循环行组的最后行,最后一个单元格,到文档开头的 离 距离 srcRange = operTable.Cell(1, 1).Range; desRange = operTable.Cell(1, 1).Range; //4 根据数据集的实际数据行数,查找命名单元格,循环插入数据 int cur_row = min_Row;//0;// min_Row;// for (int dt_row_idx = 0; dt_row_idx {//循环实际的数据行数 //goto xx1;//跳过方法 1 //方法 1 整体多行组,复制和粘贴,看起来复杂 //4.1 找到行号最小的循环行组的命名单元格,以它来定位 tmpRange = wdHelp.wordDoc.Bookmarks.get_Item(min_Name).Range;//app.Goto(min_Name); //4.2 //插入循环重复的摸板行组的行,使得所有命名单元格都向后移,以便下次循 环查找定位使用 app.ActiveCell.EntireRow.Insert(); // for (int j = 0; j < loopRow; j++) // {//插入需要重复循环的行数 loopRow 的空行 // // } //4.3 定位到摸板行组首行 tmpRange = wdHelp.wordDoc.Bookmarks.get_Item(min_Name).Range;//转到摸板行组 的行号最小的命名单元格,以它来定位 row1 = tmpRange.Cells[1].RowIndex;//a //摸板行组的第一行 row2 = row1 + loopRow - 1; //摸板行组的最后一行 template_start = operTable.Cell(row1, 1).Range.Start; //template_end = operTable.Cell(row2, table_columns).Range.Start;//这样少一列 template_end = operTable.Cell(row2+1, 1).Range.Start;//到下一行,第一个单元格 //4.4 复制整体模板的多行组,固定的摸板的格式和相关的文字说明,也可一个一 个单元格复制 srcRange.SetRange(template_start, template_end);//整体多行组复制摸板行组 srcRange.Copy(); //4.5 定位到新加入行的第一个单元格内 //row1 = row1 - loopRow;//向上回退到新加入的行组 //row2 = row2 - loopRow; //4.6 粘贴整体多行组,固定的摸板的格式和相关的文字说明 desRange = operTable.Rows[row1].Range;//整体多行组粘贴摸板行组 desRange.Paste(); xx1:
分享到:
收藏