水如烟

秋里生活,恬淡宁静。那如洗碧空,那伏黄草地,风凉夜寂,心儿涌动,情绪萦绕。可以凭窗,可以临江,可以坐,可以仰卧,可以独处,可以相依。倚明月,抚清辉,人生多少情怀,尽在秋里?

原创 HOW TO:Office文档版本的检测收藏

新一篇: HOW TO:获取ExcelApplication COM对象的进程 | 旧一篇: QC工具与方法

Author:水如烟 

Office2007跟Office2003及以前的版本,文件的储存方式已大为不同.
无论是OleDb、Odbc的连接字符串还是文档打开的应用程序,两个版本也不一样了。

一般的,可以通过文件扩展名来辩别是哪个版本,如Excel,2003的扩展名为xls,2007的为xlsx
但是,如果扩展名不规范就无法辩别了,况且,象我,就习惯在程序中都输出为xls,不管是不是2007的。

在这种情况下,要对两种文档的关键字节进行对比来确定。

下面是现在的尝试(只实现Access,Excel,Word):

示例代码:

    '看Excel文档的版本
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        
Using dialog As New OpenFileDialog
            
With dialog
                
If .ShowDialog = Windows.Forms.DialogResult.OK Then
                    Console.WriteLine(Global.LzmTW.Data.MSOffice.VersionChecker.Check(.FileName, MSOffice.AppType.Excel).ToString)
                
End If
            
End With
        
End Using
    
End Sub

代码:

Namespace MSOffice
    
Public Enum AppType
        Access
        Excel
        Word
    
End Enum
End Namespace

Namespace MSOffice
    
Public Enum VersionType
        V2003
        V2007
        Unknown
    
End Enum
End Namespace

Namespace MSOffice

    
Public Class VersionChecker
        
Private Sub New()
        
End Sub

        
Shared Sub New()
            
Dim info As CompareInfo

            info 
= New CompareInfo
            
With info
                .Position 
= 0
                .Length 
= &HD
                .PivotalValues2003 
= New Byte() {&HD0, &HCF, &H11, &HE0, &HA1, &HB1, &H1A, &HE1, &H0, &H0, &H0, &H0, &H0, &H0}
                .PivotalValues2007 
= New Byte() {&H50, &H4B, &H3, &H4, &H14, &H0, &H6, &H0, &H8, &H0, &H0, &H0, &H21, &H0}
            
End With
            Collection.Add(AppType.Excel, info)

            info 
= New CompareInfo
            
With info
                .Position 
= 0
                .Length 
= &HD
                .PivotalValues2003 
= New Byte() {&HD0, &HCF, &H11, &HE0, &HA1, &HB1, &H1A, &HE1, &H0, &H0, &H0, &H0, &H0, &H0}
                .PivotalValues2007 
= New Byte() {&H50, &H4B, &H3, &H4, &H14, &H0, &H6, &H0, &H8, &H0, &H0, &H0, &H21, &H0}
            
End With
            Collection.Add(AppType.Word, info)

            info 
= New CompareInfo
            
With info
                .Position 
= 0
                .Length 
= &HF
                .PivotalValues2003 
= New Byte() {&H0, &H1, &H0, &H0, &H53, &H74, &H61, &H6E, &H64, &H61, &H72, &H64, &H20, &H4A, &H65, &H74}
                .PivotalValues2007 
= New Byte() {&H0, &H1, &H0, &H0, &H53, &H74, &H61, &H6E, &H64, &H61, &H72, &H64, &H20, &H41, &H43, &H45}
            
End With
            Collection.Add(AppType.Access, info)

        
End Sub


        
Public Shared Function Check(ByVal file As StringByVal apptype As AppType) As VersionType
            
Dim fileInfo As New System.IO.FileInfo(file)
            
If Not fileInfo.Exists Then Return VersionType.Unknown

            
Dim info As CompareInfo = Collection.Item(apptype)

            
If fileInfo.Length < info.Length Then Return VersionType.Unknown

            
Dim bytes(info.Length) As Byte

            
Using streamReader As System.IO.FileStream = fileInfo.OpenRead
                
With streamReader
                    .Read(bytes, info.Position, info.Length 
+ 1)
                
End With
            
End Using

            
Dim IsMatch As Boolean
            IsMatch 
= info.IsMatch2003(bytes)

            
If IsMatch Then Return VersionType.V2003

            IsMatch 
= info.IsMatch2007(bytes)

            
If IsMatch Then
                
Return VersionType.V2007
            
Else
                
Return VersionType.Unknown
            
End If

        
End Function


        
Private Shared Collection As New Dictionary(Of AppType, CompareInfo)

        
Private Class CompareInfo
            
Private gPosition As Integer = 0
            
Public Property Position() As Integer
                
Get
                    
Return gPosition
                
End Get
                
Set(ByVal value As Integer)
                    gPosition 
= value
                
End Set
            
End Property

            
Private gLength As Integer
            
Public Property Length() As Integer
                
Get
                    
Return gLength
                
End Get
                
Set(ByVal value As Integer)
                    gLength 
= value
                
End Set
            
End Property

            
Private gPivotalValues2003 As Byte()
            
Public Property PivotalValues2003() As Byte()
                
Get
                    
Return gPivotalValues2003
                
End Get
                
Set(ByVal value As Byte())
                    gPivotalValues2003 
= value
                
End Set
            
End Property

            
Private gPivotalValues2007 As Byte()
            
Public Property PivotalValues2007() As Byte()
                
Get
                    
Return gPivotalValues2007
                
End Get
                
Set(ByVal value As Byte())
                    gPivotalValues2007 
= value
                
End Set
            
End Property

            
Public Function IsMatch2003(ByVal bytes As Byte()) As Boolean
                
Return Compare(Me.PivotalValues2003, bytes)
            
End Function

            
Public Function IsMatch2007(ByVal bytes As Byte()) As Boolean
                
Return Compare(Me.PivotalValues2007, bytes)
            
End Function

            
Private Function Compare(ByVal bytes1 As Byte(), ByVal bytes2 As Byte()) As Boolean
                
Dim mIsMatch As Boolean = True

                
For i As Integer = 0 To bytes1.Length - 1
                    mIsMatch 
= bytes1(i).Equals(bytes2(i)) And mIsMatch
                    
If Not mIsMatch Then Exit For
                
Next

                
Return mIsMatch
            
End Function
        
End Class
    
End Class

End Namespace

发表于 @ 2008年04月25日 22:43:27|评论(loading...)|编辑

新一篇: HOW TO:获取ExcelApplication COM对象的进程 | 旧一篇: QC工具与方法

评论:没有评论。

发表评论  


登录
Csdn Blog version 3.1a
Copyright © 水如烟