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
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 String , ByVal 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
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 String , ByVal 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