在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本文欢迎转载,但必须在文章显眼处保留原文地址 http://www.cnblogs.com/Ss_Andy/archive/2010/11/02/1866762.html 最近在开发的项目中,又遇到一个和word有关的问题,就是用户修改了一个word文档的内容后,需要将这个文档另一个事生成好的文档进行对比,看是否有修改.从而决定要不要提示用户修改另一文档.. word文档的对比不像一般的txt文件,直接用File类进行读取操作.由于word的编码是没有公开的,所以想读取word里面的内容,还是得需要靠微软提供的office组件进行操作,不过这也麻烦,里面所提供几个读取的方法,好像都只是能读到纯文本而以,带格式都会给过滤掉,一般富格式都没有正常显示出来(比如flash,图片,表格),也许本人孤陋寡闻,在office组件中没有找到完美的解决方案,不过好在经过了几天的时间,也解决了这个问题,下面就说说解决方案吧!
目前想到的就有三种方式可以解决,下面为你一一道来. 一.第一种也是最简单方式,也是我第一时间想到的解决方案,可以将word文档转换成html文件,然后再将html文件转换成txt文件,然后用我们经常使用操作文件类File进行读取里面的文本(这时会包括html里面的标签,这样才能保留原先的格式),进行对比,这时读到的全是纯文档,在C#里面就直接当成字符串处理就得了!这个应该很容易很好理解吧!不过据比较牛X的同事说,因为word的功能非常强大,所以直接转换成html的话,可能会造成某些数据的丢失.PS:目前本人试过几次,都没有发现丢失的情况,可能测试的次数过少,或者说没有包函大量的数据吧! 优点:易懂,简单. 缺点:有可能造成丢失数据的风险. 二.第二种方式有版本要求,需要是office2007或者2007以上的版本,2007以上的文档保存文件后缀是docx,你可以使用C#将他进行重命名,改成压缩文件的格式,然后再进行解压,你会看到很多资源文件(你可以先手动操作一下,看明白流程),然后再读取里面相关的xml文件,进行对比,但由于生成的文件过多,这个过程应该是相当烦琐的,所以,本人没有实践过,但知道肯定是可以实现的.同时要求电脑上要装有解压程序(这个一般都会有拉,不过还是要考虑的,) 优点:应该是可以较完美的解决问题.也不会造成丢失数据的风险. 缺点:操作烦琐,要弄明白所解压后的相关资源文件,加上对比的东西会比较多,这个过程相当相当烦琐. 三.第三种,自认为是最完美的解决方法,目前项目也打算使用这种方式解决问题,下面说说具体的解决过程. 优点:性能不错,也应该是可以完美解决问题,目前还没有发现别的问题.所有比较都让微软帮我们做了. 缺点:还没发现.. 1.先添加引用Microsoft.Office.Interop.Word. 2.接着让Microsoft.Office.Interop.Word.Application加载其中一个doc文档 private Microsoft.Office.Interop.Word.Application _wordApplication; 3.再使用Microsoft.Office.Interop.Word.Application里面的一个比较功能 object compareTarget = Microsoft.Office.Interop.Word.WdCompareTarget.wdCompareTargetSelected; 简单介绍一下这个Compare函数的功能,file就是你要对比的第二文件, compareTarget =Microsoft.Office.Interop.Word.WdCompareTarget.wdCompareTargetSelected;就是将对比后的结果加在第二个文档里面(其实就是修订拉,用过word修订功能的人都知道,他就是把你做的修改显示在word里面,当你鼠标移上去,他就会提示你,哪个用户在什么时候做了什么事情(比如:张三2010-11-1 19:00:00 删除ABC),可能这样说,好像很模糊一样,大家自己试一下就一目了解拉! 当然,我们要的不是这样,我们要的是直接告诉我们,哪里不一样!不要让他去修改第二个文档.但我找了很久,都没有相关的函数可以读取到这些修订信息.好在前阵子用过dsoframer.ocx这个web版本word控件,里面有提供了一个方法,可以读取到文档中的修订信息(具体的dsoframer.ocx使用方法,可以上网找,有好多相关资料的,也可以留言大家讨论讨论哈),下面贴出dsoframer获取修订信息的具体代码
先让你界面上的dsoframer控件加载你的第二个文档,就是你调用Compare这个方法时传进去的file.然后下面再进行获取相关数据. var vCount = document.all.hideWord.GetRevCount(); //修改条数,比如删除一段话,vCount就是=1 for(var i=1;i<=vCount;i++){ //循环获取数据,i是表示第几条,2是表示做了什么操作 vOpt=1表示插入,=2表示删除 //可以把下面的2改成1,就是获取是哪个用户做了修改,好像1是获取用户吧,哈哈,自己动手试下吧! var vOpt = document.all.hideWord.GetRevInfo(i,2); var context = document.all.hideWord.GetRevInfo(i,3); //3是表示获取修改了什么信息,比如用户删除了ABC,这里context就会等于"ABC" }
看了上面这段代码,应该知道,我们是可以获取文档哪里不一样的了!因为在调用Compare这个方法的时候,微软已经帮我们做了比较了,我们只是把相关的信息提取出来而以. 不过上面的代码太片断了,我还是贴出我在项目中的代码吧,可能看上去比较清晰点..
//我项目中判断文档有没有改变,根据您自己的需求,可能这里会和我不一样! //下面这一段你可以不用管,是因为项目原因,需要忽略文档中的个别字符.
简单解释一下,比如文件A里面是abc,文档B里面是abd,你用上面的方法读取第二文档的修订信息时,将是两条数据!第一条:删除了c. 第二条:插入了d 就是说你所有的修改,他都说先删除,再插入的,会有两条记录的!当然,如果没有删除旧的数据,只是添加,就是一条,删除也是一样!但是修改就是两条数据了.
根据上我面的代码,你可能会发现,修订信息是提取到了,但第二文档中也显示了修订信息,我们要的应该只是对比,而不要改到第二个文档.那这时可以使用office组件里面提供的一个方法进行接受修订信息(等会我会贴出操作office组件的类). PS:如果第二word文档里面已经存在的修订信息的话,调用比较的方法会报错,所以我们在比较前,可以先让第二文档设置成接受修订(即使你没有修订信息也不会报错)
下面是我的 操作office组件的类(删除了大量与本贴无关的代码)
using System;
public class WordHelper object objfile = file; /// <summary>
上面的文字,我看上去我自己很清晰,如果是没有研究过这个问题的朋友看上去一定很像炒面, 但你如果研究过这个问题的话,应该还是可以看懂的!如果有不明白的话,可以留言我们讨论讨论吧!呵 大概的思路重新写一下:用office组件进行比较,比较的时候,会将不一样的地方使用修订(也有人叫笔记留痕)方式显示在第二个文档里面,然后再使用dsoframer控件加载第二个有修订信息的文档,进行读取.最后再让第二文档接受修订. 大概是这样的咯,不过在真正开发的时候,会遇到很多小问题的,如果遇到的朋友不妨提出来大家讨论讨论..
上面的三种方法是自己想的,不知有没有更好的方法,知道的朋友不妨通知一声,在下感激不尽.. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论