先介绍一下背景
工作环境需要,有一套成型的模板文件(Word格式),有需要的情况下,需要一遍一遍的改,而且改的地方超级多,一不小心就给漏掉。
为什么不让用C#直接调用Office
首先,你要在服务器上安装Office,才能用C#调用;
其次,我真的是不知道怎么用C#在服务器端停止Word进程,每打开一次Word文件,就会创建一个word进程,几次下来,服务器资源就会耗尽。
Aspose.Word我用的是破解版
先看官方网站https://products.aspose.com/words,虽然我英文不太好,但是我也看的出来,如果想要没有限制,是需要付费的。
于是CSDN上下载了一个破解版。可以在这里下载链接: https://pan.baidu.com/s/1oAfyHho 密码: uqtn
我只用到了很少的小部分功能
其实也就是查找替换。
只要下载Aspose.Word.dll
到项目bin
文件夹中,就可以通过下面的代码使用:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39/// <summary>
/// 关键词替换
/// </summary>
/// <param name="bmk">参数为数据字典</param>
public void KeywordReplace(Dictionary<string, string> bmk)
{
try
{
doc = new Document(_filepath);
// _filepath是Word文件的目录
foreach (KeyValuePair<string, string> kvp in bmk)
{
if (kvp.Key.Substring(0, 1) == "$")
{
doc.Range.Replace(kvp.Key, kvp.Value, false, false);
}
else
{
Bookmark bm = doc.Range.Bookmarks[kvp.Key];
if (bm != null)
{
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveToBookmark(kvp.Key);
Shape shape = builder.InsertImage(kvp.Value);
shape.Width = 280;
shape.Height = 280;
shape.HorizontalAlignment = HorizontalAlignment.Center;
doc.Range.Bookmarks[kvp.Key].Remove();//移除书签
}
}
}
doc.Save(_filepath, SaveFormat.Doc);
}
catch(Exception e)
{
e.ToString();
}
}
对,就是这么简单。
上面的程序段执行之前,需要下面几个步骤:
- 创建Word模板,Word模板指的并不是
dot
格式的文件,它是普通的doc
格式的文件,但是文件中,可以设置特定格式的关键字。注意,关键字要有显著性。比如我把关键字都设置成了类似${Keyword1}
,${Keyword2}
,${Keyword3}
……这样的格式,这肯定和我将来要替换的文本内容不会一样。 - C#预先把Word模板文件放到一个新的目录中,记录下来新的目录的绝对地址。一定要注意,不要直接在Word模板上操作,原因不用我多说了吧。
- 准备一个数据字典参数。就是待替换的字符串和新的字符串组成的一个数据字典。
它还可以直接保存成PDF格式的文件
当然,并不完美。
因为Word中会有一些表格或者空行之类的,如果替换后的文本内容过长或过短,排版就会很不协调,需要下载下来之后,人工调整。
如果非要直接保存成PDF格式的文件,可以先得到PDF的文件名字:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/// <summary>
/// 得到PDF文件名
/// </summary>
/// <returns>返回PDF文件名</returns>
public string PdfFile()
{
string str = _filepath;
int i = str.LastIndexOf("doc");
if (i > -1)
{
str = str.Substring(0, i);
}
str += "pdf";
return str;
}
得到PDF文件的绝对地址以后,在KeywordReplace函数后面再加上doc.Save(PdfFile(), SaveFormat.Pdf);
即可。
虽然这个办法简陋了一点,但是确实是实现了我需要的功能。