.Net 中处理Word(2007)文档的一种方法

有的时候我们需要在程序中处理Word文档,比如,删除或替换掉文档中的某些字符串,实现这个功能有很多方法,我这里介绍一种方法,个人认为其效率要优于其它方法,但本方法目前只适用于office 2007 中的Excel,Word, PowerPoint. 下面引用一些msdn上关于office 2007的介绍. 2007 Microsoft Office system为Microsoft Office Excel 2007,Microsoft Office Word 2007,和Microsoft Office PowerPoint 2007采用了基于XML的文件格式,新的格式增强了文件与数据的管理能力,数据恢复能力,以及与业务线系统的互操作能力。它们是对早期版本的二进制文件的扩展。任何支持XML的应用程序都可以访问新文件格式当中的数据,并与之协同工作。这些应用程序并不需要成为Microsoft Office system或Microsoft产品的一部分。用户也可以使用标准的转换来提取或重新组织数据。另外,有关安全性的担忧也大大的降低,因为信息是存储在XML当中的,它从本质上来讲都是纯文本的。因此,数据可以没有任何障碍地通过企业防火墙进行传递。
注意:
不要将Office Open XML格式与Microsoft Windows XML Paper Specification格式相混淆。Office Open XML格式使用Open Packaging Conventions,XML Paper Specification (XPS)也使用它。但是,这两种格式在许多重要的方面是不同的。XPS是一个页面内的,固定的文档格式,它是在Microsoft Windows Vista操作系统当中所引入的。而Office Open XML格式是面向Office Word 2007,Office Excel 2007,和Office PowerPoint 2007的完全可编辑的文件格式。虽然它们在XML和ZIP压缩的使用方面有很多相似的地方,但是它们在文件格式的设计和使用目的上还是有着很大的不同。
更详细的信息请参考:http://www.microsoft.com/china/msdn/library/office/office/OfficeOpenXMLFormats.mspx?mfr=true

为了打开一个Word 2007 XML文件

1. 创建一个临时目录来存储文件和它的部件。
2. 创建一个Word 2007文档,包括文本,图片,以及其它元素,保存为一个.docx文件。
3. 在文件名的末端添加一个.zip扩展名。
4. 双击文件。这时将会在ZIP应用程序当中打开该文件。您可以查看组成文件的每个部件。(可以不用winrar压缩工具打开,以windows默认的zip格式打开)
5. 将这些部件提取到刚才创建的临时目录当中。

这时就可以看到组成docx文件的所有XML格式的文件.这里需要大家详细阅读一下我上面给的链接的内容,现在我主要介绍一下在.net中处理word(2007)文档的一种方法,需要说明的是在.net frameword 2.0 中并没有提供相关的类来处理zip格式的文件,在.net framework 3.0中提供了一个类Package,所属的命名空间为System.IO.Packaging,因此在本例中要实现对word文档的处理必须安装.net frameword 3.0 或者 3.5,在引用中要添加对WindowsBase.dll的引用,这个DLL文件在windows 2003 系统里位于C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\目录下.
我做的这个例子是替换Word页脚中的链接,将http://www.google.cn/ 替换为http://www.cnblogs.com/.其它的处理可以用类似的方法来操作.下面是代码:

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.IO;
 5using System.IO.Packaging;
 6
 7namespace WordProcess
 8{
 9    class Program
10    {
11        static void Main(string[] args)
12        {
13            string filePath = "test.docx"
14            string content = null;
16
17            string contentType;
18            CompressionOption option;
19            PackageRelationshipCollection relations;
20
21            try
22            {
23                
25                //打开docx文件
26                using (Package zip = System.IO.Packaging.Package.Open(fileZip, FileMode.OpenOrCreate, FileAccess.ReadWrite))
27                {
28
29                    foreach (PackagePart part in zip.GetParts())
30                    {
31                        //寻找页脚所在的文件
32                        if (part.Uri.OriginalString == "/word/footer2.xml")
33                        {
34                            StreamReader sr = new StreamReader(part.GetStream());
35                            content = sr.ReadToEnd();
36                            //替换内容
37                            if (content != null)
38                                content = content.Replace("http://www.google.cn""http://www.cnblogs.com");
39                            sr.Close();
40
41                            contentType = part.ContentType;
42                            option = part.CompressionOption;
43                            relations = part.GetRelationships();
44
45                            //删除 footer2.xml
46                            zip.DeletePart(part.Uri);
47
48                            //创建一个新的 footer2.xml
49                            Uri tempUri = PackUriHelper.CreatePartUri(new Uri("/word/footer2.xml", UriKind.Relative));
50                            PackagePart tempPart = zip.CreatePart(tempUri, contentType, option);
51
52                            //将修改后的 footer2.xml
53                            using (StreamWriter sw = new StreamWriter(tempPart.GetStream()))
54                            {
55                                sw.Write(content);
56                                sw.Flush();
57                                sw.Close();
58                            }

59
60                            //创建tempart与各XML文件之间的关系,非常重要
61                            foreach (PackageRelationship relation in relations)
62                            {
63                                tempPart.CreateRelationship(relation.TargetUri, relation.TargetMode, relation.RelationshipType, relation.Id);
64                            }

65
66                            zip.Close();
67
68                            break;
69                        }

70                    }

73                }

74            }

75            catch (Exception ex)
76            {
77                throw new Exception(ex.Message);
78            }

79        }

80    }

81}

82

以上代码复制后可以直接运行,只需在debug目录下创建一个word(2007)文档,并插入页脚,当然也可以更改一下代码里的设置. 该方法同样适用于Microsoft Office Excel 2007和Microsoft Office PowerPoint 2007,利用这种方法可以实现以操作XML文件的方式对以上三种文档进行操作,比如去掉文档中的写保护,替换或删除部分内容等.此方法占用内存少,执行效率也比较高. 第一次想把文章放到首页,不足之处,请大家指教,一定改正!


今天是全国哀悼日,向在汶川地震中遇难的同胞致敬,祝你们在天堂幸福!

 

posted @ 2008-05-19 11:25 qiangzi 阅读(1805) 评论(7)  编辑 收藏

  回复  引用  查看    
#1楼 2008-05-19 12:46 | SZW      
请问楼主把.docx换成.zip的用意何在?System.IO.Packaging.Package不是可以直接读取docx(本质就是zip)吗?修改操作必须这样做吗?
  回复  引用    
#2楼 2008-05-19 13:20 | 哈哈哈 [未注册用户]
一楼愤青,呵呵
  回复  引用  查看    
#3楼 2008-05-19 13:55 | SZW      
@哈哈哈
想不明白当然要学习一下,不放过任何一个机会:)
  回复  引用  查看    
#4楼 2008-05-19 14:15 | SZW      
@qiangzi0303
这个好像没有太大关系吧,改变扩展名并不能改变文件本身的格式。docx完全可以作为一个package被读取,前几天有位朋友发了这个文章,你可以看一下:http://www.cnblogs.com/tthxnz/archive/2008/05/17/1201531.html

他里面写的是读取,而本文涉及到了修改,我就是不太明白为什么要刻意这么转换一下,是不是有什么用意在里面,理论上说不转换也是可以的。
  回复  引用  查看    
#5楼 [楼主]2008-05-19 15:45 | qiangzi      
@SZW
谢谢SZW老兄,确实没有必要把docx转化成zip格式,原文已修改. 在解决这个问题的时候遇到的最大困难是修改了XML文件以后再把它保存到packagepart中去.在这个例子中解决的办法是,先把footer2.xml的内容读取到内存,然后赋给一个string类型的变量,把footer2.xml删除掉,再创建一个packagepart,命名为footer2.xml. 然后再创建footer2.xml与其它xml文件之间的关系. 如果不创建关系的话,那么被修改的word文档再次被打开时会报错,说文件已损坏.
  回复  引用  查看    
#6楼 2008-05-20 13:35 | 簡簡單單..      
学习学习..

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-05-19 15:37 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: