C# 操作 Word 全域查找且替换(含图片对象)

目录

关于全域查找且替换

Word应用样本

SqlServer数据表部分设计样本

范例运行环境

配置Office DCOM

设计实现

组件库引入

实现原理

查找且替换的核心代码

窗格内容

页眉内容

页脚内容

形状内容

小结


关于全域查找且替换

C#全域操作 Word 查找且替换主要包括如下四个对象:

序号对象说明
1Word.Appication.Selection窗格对象
2Word.Section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range页眉对象
3Word.Section.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range页脚对象
4Word.Shape.TextFrame.TextRange形状对象

我们需要创建 Word.Find 对象,对上述相关区域分别进行查找替换操作。

Word应用样本

我们假设设计简历模板的输出,并查找且替换对应的关键字,如下图:

其中对应项目的关键字如 {xm}、{xb} 等则为查找且替换的对象,{grzp} 关键字处我们要处理图片的插入。

SqlServer数据表部分设计样本

设计 PersonInfo 数据表如下:

创建脚本如下:

CREATE TABLE [dbo].[PersonInfo]([id] [uniqueidentifier] ROWGUIDCOL  NOT NULL,[sfzh] [varchar](18) NOT NULL,[xm] [nvarchar](50) NOT NULL,[xb] [nvarchar](1) NULL,[grzp] [image] NULL,CONSTRAINT [PK_PersonInfo] PRIMARY KEY CLUSTERED 
([id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],CONSTRAINT [IX_PersonInfo] UNIQUE NONCLUSTERED 
([sfzh] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GOALTER TABLE [dbo].[PersonInfo] ADD  CONSTRAINT [DF_PersonInfo_id]  DEFAULT (newid()) FOR [id]
GO

通过查询 select sfzh,xm,xb,grzp from PersonInfo where id=xxx 得到DataSet,再取 Tables[0]中的数据。 

范例运行环境

操作系统: Windows Server 2019 DataCenter

操作系统上安装 Office Excel 2016

数据库:Microsoft SQL Server 2016

.net版本: .netFramework4.7.1 或以上

开发工具:VS2019  C#

配置Office DCOM

配置方法可参照我的文章《C# 读取Word表格到DataSet》进行处理和配置。

设计实现

组件库引入

实现原理

我们假设查询出表数据,存入对应的变量,其中将二进制字段grzp数据写入到d:\test.jpg生成图片,示例代码如下:

DataTable dt=DataSet.Tables[0];string sfzh = dt.Rows[0]["sfzh"].ToString();
object bt = dt.Rows[0]["grzp"];
byte[] bFile2 = (byte[])bt;
System.IO.File.WriteAllBytes("@d:\test.jpg", bFile2);string xm = dt.Rows[0]["xm"].ToString();
string xb = dt.Rows[0]["xb"].ToString();

 然后我们将其存到二维字符串数组 _repls 里,如下代码:

string[,] _repls = new string[4, 2];
_repls[0, 0] = "{sfzh}";
_repls[0, 1] = sfzh;
_repls[1, 0] = "{xm}";
_repls[1, 1] = xm;
_repls[2, 0] = "{xb}";
_repls[2, 1] = xb;
_repls[3, 0] = "RepalceFromImageFilename_{grzp}";
_repls[3, 1] = "@d:\test.jpg";

其中第一元素存储要查找的关键字,第二元素存储要替换的值。注意:替换图片使用了自定义的RepalceFromImageFilename_ 前缀关键字,则表示值为对应的文件路径。数据准备完毕后,我们将通过遍历数组对 Word 进行查找且替换操作。

查找且替换的核心代码

窗格内容

示例代码如下:

                WordApp.Options.ReplaceSelection = true;Word.Find fnd = WordApp.Selection.Find;for(int i=0;i<_repls.GetLength(0);i++){if (_repls[i, 0] == "" || _repls[i, 0] == null){continue;}fnd.ClearFormatting();string ft = _repls[i, 0];string replaceType = "";if (ft.IndexOf("RepalceFromImageFilename_") == 0){ft = ft.Replace("RepalceFromImageFilename_", "");replaceType = "RepalceFromImageFilename";}else if (ft.IndexOf("RepalceFromImageFilenameNoDelete_") == 0){ft = ft.Replace("RepalceFromImageFilenameNoDelete_", "");replaceType = "RepalceFromImageFilenameNoDelete";}Object findText = ft;Object matchCase = false;Object matchWholeWord = Type.Missing;Object matchWildcards = false;Object matchSoundsLike = false;Object matchAllWordForms = false;Object forward = true;Object wrap =Word.WdFindWrap.wdFindContinue;Object format = false;Object replaceWith ="";Object replace =Type.Missing;;Object matchKashida = Type.Missing;Object matchDiacritics = Type.Missing;Object matchAlefHamza = Type.Missing;Object matchControl = Type.Missing;while(fnd.Execute(ref findText, ref matchCase, ref matchWholeWord,ref matchWildcards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWith,ref replace, ref matchKashida, ref matchDiacritics,ref matchAlefHamza, ref matchControl)){string r_f=WordApp.Selection.Font.Name.ToString();if (replaceType == "RepalceFromImageFilename" || replaceType == "RepalceFromImageFilenameNoDelete"){if (File.Exists(_repls[i, 1].ToString())){WordApp.Selection.Range.Select();Word.InlineShape pic = WordApp.Selection.InlineShapes.AddPicture(_repls[i, 1].ToString(), false, true, WordApp.Selection.Range);if (replConfigs != null){string[] cv = replConfigs[ft].Split('|');pic.Width = int.Parse(cv[0]);pic.Height = int.Parse(cv[1]);}if (replaceType == "RepalceFromImageFilename"){File.Delete(_repls[i, 1].ToString());}}}else{WordApp.Selection.Range.Text = _repls[i, 1].ToString();}}}
页眉内容

示例代码如下:

                foreach (Word.Section header in WordDoc.Sections){Word.Range headerRange = header.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;Word.Find fnd = headerRange.Find;for (int i = 0; i < _repls.GetLength(0); i++){if (_repls[i, 0] == "" || _repls[i, 0] == null){continue;}fnd.ClearFormatting();string ft = _repls[i, 0];string replaceType = "";if (ft.IndexOf("RepalceFromImageFilename_") == 0){ft = ft.Replace("RepalceFromImageFilename_", "");replaceType = "RepalceFromImageFilename";}else if (ft.IndexOf("RepalceFromImageFilenameNoDelete_") == 0){ft = ft.Replace("RepalceFromImageFilenameNoDelete_", "");replaceType = "RepalceFromImageFilenameNoDelete";}Object findText = ft;Object matchCase = false;Object matchWholeWord = Type.Missing;Object matchWildcards = false;Object matchSoundsLike = false;Object matchAllWordForms = false;Object forward = true;Object wrap = Word.WdFindWrap.wdFindContinue;Object format = false;Object replaceWith = "";Object replace = Type.Missing; ;Object matchKashida = Type.Missing;Object matchDiacritics = Type.Missing;Object matchAlefHamza = Type.Missing;Object matchControl = Type.Missing;while (fnd.Execute(ref findText, ref matchCase, ref matchWholeWord, ref matchWildcards, ref matchSoundsLike, ref matchAllWordForms,ref forward, ref wrap, ref format, ref replaceWith, ref replace, ref matchKashida, ref matchDiacritics, ref matchAlefHamza, ref matchControl)){string r_f = WordApp.Selection.Font.Name.ToString();if (replaceType == "RepalceFromImageFilename" || replaceType == "RepalceFromImageFilenameNoDelete"){if (File.Exists(_repls[i, 1].ToString())){WordApp.Selection.Range.Select();Word.InlineShape pic = WordApp.Selection.InlineShapes.AddPicture(_repls[i, 1].ToString(), false, true, headerRange);if (replaceType == "RepalceFromImageFilename"){File.Delete(_repls[i, 1].ToString());}}}else{headerRange.Text = _repls[i, 1].ToString();}}}}
页脚内容

示例代码如下:

                foreach (Word.Section footer in WordDoc.Sections){Word.Range footerRange = footer.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;Word.Find fnd = footerRange.Find;for (int i = 0; i < _repls.GetLength(0); i++){if (_repls[i, 0] == "" || _repls[i, 0] == null){continue;}fnd.ClearFormatting();string ft = _repls[i, 0];string replaceType = "";if (ft.IndexOf("RepalceFromImageFilename_") == 0){ft = ft.Replace("RepalceFromImageFilename_", "");replaceType = "RepalceFromImageFilename";}else if (ft.IndexOf("RepalceFromImageFilenameNoDelete_") == 0){ft = ft.Replace("RepalceFromImageFilenameNoDelete_", "");replaceType = "RepalceFromImageFilenameNoDelete";}Object findText = ft;Object matchCase = false;Object matchWholeWord = Type.Missing;Object matchWildcards = false;Object matchSoundsLike = false;Object matchAllWordForms = false;Object forward = true;Object wrap = Word.WdFindWrap.wdFindContinue;Object format = false;Object replaceWith = "";Object replace = Type.Missing; ;Object matchKashida = Type.Missing;Object matchDiacritics = Type.Missing;Object matchAlefHamza = Type.Missing;Object matchControl = Type.Missing;while (fnd.Execute(ref findText, ref matchCase, ref matchWholeWord, ref matchWildcards, ref matchSoundsLike, ref matchAllWordForms,ref forward, ref wrap, ref format, ref replaceWith, ref replace, ref matchKashida, ref matchDiacritics, ref matchAlefHamza, ref matchControl)){string r_f = WordApp.Selection.Font.Name.ToString();//						WordApp.Selection.Font.Name=r_f;//						WordApp.Selection.Range//						WordApp.Selection.TypeText(_repls[i,1].ToString());if (replaceType == "RepalceFromImageFilename" || replaceType == "RepalceFromImageFilenameNoDelete"){if (File.Exists(_repls[i, 1].ToString())){WordApp.Selection.Range.Select();Word.InlineShape pic = WordApp.Selection.InlineShapes.AddPicture(_repls[i, 1].ToString(), false, true, footerRange);if (replaceType == "RepalceFromImageFilename"){File.Delete(_repls[i, 1].ToString());}}}else{footerRange.Text = _repls[i, 1].ToString();}}}}
形状内容

示例代码如下:

                foreach (Word.Shape shape in WordDoc.Shapes){if (shape.TextFrame.HasText == 0){continue; }Word.Find fnd = shape.TextFrame.TextRange.Find;//Word.Find fnd = WordDoc.Content.Find;for (int i = 0; i < _repls.GetLength(0); i++){if (_repls[i, 0] == "" || _repls[i, 0] == null){continue;}fnd.ClearFormatting();string ft = _repls[i, 0];string replaceType = "";if (ft.IndexOf("RepalceFromImageFilename_") == 0){ft = ft.Replace("RepalceFromImageFilename_", "");replaceType = "RepalceFromImageFilename";}else if (ft.IndexOf("RepalceFromImageFilenameNoDelete_") == 0){ft = ft.Replace("RepalceFromImageFilenameNoDelete_", "");replaceType = "RepalceFromImageFilenameNoDelete";}Object findText = ft;Object matchCase = false;Object matchWholeWord = Type.Missing;Object matchWildcards = false;Object matchSoundsLike = false;Object matchAllWordForms = false;Object forward = true;Object wrap = Word.WdFindWrap.wdFindContinue;Object format = false;Object replaceWith = "";Object replace = Type.Missing; ;Object matchKashida = Type.Missing;Object matchDiacritics = Type.Missing;Object matchAlefHamza = Type.Missing;Object matchControl = Type.Missing;while (fnd.Execute(ref findText, ref matchCase, ref matchWholeWord, ref matchWildcards, ref matchSoundsLike, ref matchAllWordForms,ref forward, ref wrap, ref format, ref replaceWith, ref replace, ref matchKashida, ref matchDiacritics, ref matchAlefHamza, ref matchControl)){string r_f = WordApp.Selection.Font.Name.ToString();if (replaceType == "RepalceFromImageFilename" || replaceType == "RepalceFromImageFilenameNoDelete"){if (File.Exists(_repls[i, 1].ToString())){Word.InlineShape pic = WordApp.Selection.InlineShapes.AddPicture(_repls[i, 1].ToString(), false, true, shape.TextFrame.TextRange);if (replaceType == "RepalceFromImageFilename"){File.Delete(_repls[i, 1].ToString());}}}else{shape.TextFrame.TextRange.Text = _repls[i, 1].ToString();}}}}

小结

1、示例代码是冗余的写法,在实际应用中我们需要进行优化。

2、添加图片后,代码默认是使用完毕后,删除图片文件以释放空间,我们自定义了 RepalceFromImageFilenameNoDelete_ 前缀关键字,表示使用完毕后不进行文件删除。

3、示例代码中 Word 表示 using Word=Microsoft.Office.Interop.Word; 的引用。

4、示例代码 WordDoc 表示对 Word.Document 的引用。

示例代码我们提供了操作的关键方法,这里仅作参考,其它代码不再做展示,欢迎大家评论指教!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/577129.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 抠取红色印章(透明背景)

一个亲戚让我帮他把照片里的红色印章抠出来&#xff0c;&#xff0c;&#xff0c;记录下处理过程&#xff0c;代码如下&#xff0c;可直接用&#xff1a; public static void signatureProcess(String sourceImagePath, String targetImagePath) {Graphics2D graphics2D null…

鸿蒙原生应用开发-网络管理HTTP数据请求

一、场景介绍 应用通过HTTP发起一个数据请求&#xff0c;支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。 二、接口说明 HTTP数据请求功能主要由http模块提供。 使用该功能需要申请ohos.permission.INTERNET权限。 涉及的接口如下表&#xff0c;具体的…

小白了解Pinia第2集 · 三大核心状态Getters、Actions以及Plugins 插件

三大核心状态 state 第1集有详细讲解&#xff1a;https://blog.csdn.net/qq_51463650/article/details/137137080?spm1001.2014.3001.5501 getters Getter 完全等同于 Store 状态的 计算值。 它们可以用 defineStore() 中的 getters 属性定义。 他们接收“状态”作为第一个…

QA测试开发工程师面试题满分问答2: 如何测试xx网站的评论功能?

针对 xx 网站的评论功能&#xff0c;可以从基础功能、用户交互、编辑撤回、权限相关、网络信号、异常、并发性能和安全性等方面的测试考虑&#xff1a; 基础功能测试 发布评论&#xff1a;验证用户是否可以成功发布评论&#xff0c;并确保评论内容正确显示在相关页面上。删除评…

JS数组练习

查找、筛选 Code <script>// 筛选>10的数组中元素var num1 [10, 2, 5, 0, 11, 121, 3, 0];var num2 [];var j 0;for (var i 0; i < num1.length; i) {// 法1// if (num1[i] > 10) {// num2[j] num1[i];// j;// }// 法2// if (num1[i] > 10) {/…

Spring日志框架

前言 本文我们简单说说关于Spring中的日志框架,以及对应的注解 我们知道,公司服务器在运行的时候,一定会打印日志,有很多优点,比如预防报警,或者是某重大事故尝试修复等等都需要查看日志 应该说日志对我们来说并不陌生,我们在之前刷题或者是程序遇到bug的时候也经常会将程序的状…

4、Cocos Creator 动画系统

Animation 组件是节点上的一个组件。Clip 动画剪辑就是一份动画的声明数据&#xff0c;我们将它挂载到 Animation 组件上&#xff0c;就能够将这份动画数据应用到节点上。 1、Clip 参数 1、sample&#xff1a;定义当前动画数据每秒的帧率&#xff0c;默认为 60&#xff0c;这…

C#属性显示

功能&#xff1a; 显示对象的属性&#xff0c;包括可显示属性、可编辑属性、及不可编辑属性。 1、MainWindow.xaml <Window x:Class"FlowChart.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://sche…

Unity颗粒血条的实现(原创,参考用)

1.创建3个静态物体摆好位置&#xff0c;并将其图层设为UI 2.编写一个脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class xt : MonoBehaviour {public GameObject xt1;public GameObject xt2;public GameObject xt3;int x 1;…

住宅IP是什么?与机房IP有哪些区别?

随着互联网的普及和发展&#xff0c;不同类型的IP地址在网络世界中扮演着重要角色。在网络架构中&#xff0c;机房IP和住宅IP是两种常见的IP类型&#xff0c;它们各有优劣&#xff0c;适用于不同的场景和需求。本文将对机房IP和住宅IP进行技术对比&#xff0c;并给出选择合适IP…

Oracle存数字精度问题number、binary_double、binary_float类型

--表1 score是number(10,5)类型 create table TEST1 (score number(10,5) ); --表2 score是binary_double类型 create table TEST2 (score binary_double ); --表3 score是binary_float类型 create table TEST3 (score binary_float );实验一&#xff1a;分别往三张表插入 小数…

【C++杂货铺】内管管理

目录 &#x1f308;前言&#x1f308; &#x1f4c1; C/C中内存分布 &#x1f4c1; new 和 delete的使用 &#x1f4c1; new 和 delete的优点 &#x1f4c1; new 和 delete的原理 &#x1f4c2; operator new 和 operator delete函数 &#x1f4c2; 内置类型 &#x1f4c2…