關(guān)于全域查找且替換
C#全域操作 Word 查找且替換主要包括如下四個對象:
序號 | 對象 | 說明 |
1 | Word.Appication.Selection | 窗格對象 |
2 | Word.Section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range | 頁眉對象 |
3 | Word.Section.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range | 頁腳對象 |
4 | Word.Shape.TextFrame.TextRange | 形狀對象 |
我們需要創(chuàng)建 Word.Find 對象,對上述相關(guān)區(qū)域分別進行查找替換操作。
Word應(yīng)用樣本
我們假設(shè)設(shè)計簡歷模板的輸出,并查找且替換對應(yīng)的關(guān)鍵字,如下圖:
其中對應(yīng)項目的關(guān)鍵字如 {xm}、{xb} 等則為查找且替換的對象,{grzp} 關(guān)鍵字處我們要處理圖片的插入。
SqlServer數(shù)據(jù)表部分設(shè)計樣本
設(shè)計 PersonInfo 數(shù)據(jù)表如下:
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]
GO
ALTER 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]中的數(shù)據(jù)。
范例運行環(huán)境
操作系統(tǒng): Windows Server 2019 DataCenter
操作系統(tǒng)上安裝 Office Excel 2016
數(shù)據(jù)庫:Microsoft SQL Server 2016
.net版本: .netFramework4.7.1 或以上
開發(fā)工具:VS2019 C#
配置Office DCOM
配置方法可參照我的文章《C# 讀取Word表格到DataSet》進行處理和配置。
設(shè)計實現(xiàn)
組件庫引入
實現(xiàn)原理
我們假設(shè)查詢出表數(shù)據(jù),存入對應(yīng)的變量,其中將二進制字段grzp數(shù)據(jù)寫入到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();
然后我們將其存到二維字符串數(shù)組 _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";
其中第一元素存儲要查找的關(guān)鍵字,第二元素存儲要替換的值。注意:替換圖片使用了自定義的RepalceFromImageFilename_ 前綴關(guān)鍵字,則表示值為對應(yīng)的文件路徑。數(shù)據(jù)準備完畢后,我們將通過遍歷數(shù)組對 Word 進行查找且替換操作。
查找且替換的核心代碼
窗格內(nèi)容
示例代碼如下:
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();
}
}
}
頁眉內(nèi)容
示例代碼如下:
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();
}
}
}
}
頁腳內(nèi)容
示例代碼如下:
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();
}
}
}
}
形狀內(nèi)容
示例代碼如下:
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();
}
}
}
}
小結(jié)
1、示例代碼是冗余的寫法,在實際應(yīng)用中我們需要進行優(yōu)化。
2、添加圖片后,代碼默認是使用完畢后,刪除圖片文件以釋放空間,我們自定義了 RepalceFromImageFilenameNoDelete_ 前綴關(guān)鍵字,表示使用完畢后不進行文件刪除。
3、示例代碼中 Word 表示 using Word=Microsoft.Office.Interop.Word; 的引用。
4、示例代碼 WordDoc 表示對 Word.Document 的引用。
該文章在 2025/1/14 15:39:43 編輯過