如何读取和存储Access数据库中的OLE对象

分类: 代码, 笔记 | 标签: , , | 日期:2008-09-28 | 1 views

如何读取Access中OLE对象字段中的图片一文中,我们知道了存储于OLE对象中的图片的格式。其实,除了微软的Office文档之外,其余所有的文档在Access中手动插入的时候都会自动打包。下面就是这种包的格式。

ole

区块1存储内容为单字节的ASCII编码。内容形如”Package”或者是”Document”
区块2存储内容同上。若区块1为”Package”则与之相同,若区块1为”Document”则区块2为可能为”Word.Document.X”  其中X为Word版本号。若区块1为”工作表”,则区块2可能为”Excel.Sheet.X”  其中X为Excel版本号。
区块3的内容基本上与区块2相同。
其他的图中非常详细了。

&1存储的数据为区块7的长度。
&2存储的数据为区块8的长度。
&3存储的数据为区块9的长度。
其余为??的数据块,还摸不清规律,占用一个比特。不完整的今后补充。

2008年10月5日 @ 12:34
附上读取OLE对象中数据的代码,语言为VB.net

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Public Function ReadInnerFile(ByVal bytes() As Byte, Optional ByRef Filename As String = Nothing, Optional ByRef FullName As String = Nothing, Optional ByRef TempPath As String = Nothing) As Byte()
If bytes(16) = 255 AndAlso bytes(17) = 255 AndAlso bytes(18) = 255 AndAlso bytes(19) = 255 Then
Else
Return bytes
End If
Dim i As Int16 = 20, InnerType As String = ""
While bytes(i) <> 0
InnerType += Chr(bytes(i))
i += 1
End While
i += 1
Dim TypeDetail As String = ""
While bytes(i) <> 0
TypeDetail += Chr(bytes(i))
i += 1
End While
i += 13
Dim futherMore As String = ""
While bytes(i) <> 0
futherMore += Chr(bytes(i))
i += 1
End While
i += 9
Dim size As Integer = 0
Dim j As Integer
For j = 0 To 3
size += bytes(i + j) * Math.Pow(256, j)
Next
Dim fs() As Byte = {}
If InnerType <> "Package" Then
Filename = "temp."
If futherMore.Contains("Word") Then
If futherMore.Split(".")(2) = "12" Then
Filename += "docx"
Else
Filename += "doc"
End If
ElseIf futherMore.Contains("Excel") Then
If futherMore.Split(".")(2) = "12" Then
Filename += "xlsx"
Else
Filename += "xls"
End If
ElseIf futherMore.Contains("PowerPoint") Then
If futherMore.Split(".")(2) = "12" Then
Filename += "pptx"
Else
Filename += "ppt"
End If
ElseIf futherMore.Contains("Access") Then
If futherMore.Split(".")(2) = "12" Then
Filename += "accdb"
Else
Filename += "mdb"
End If
End If
Array.Resize(fs, size)
For j = i + 4 To i + 3 + size
fs(j - i - 4) = bytes(j)
Next
Return fs
End If
i += 6
Filename = ""
While bytes(i) <> 0
Filename += Chr(bytes(i))
i += 1
End While
i += 1
FullName = ""
While bytes(i) <> 0
FullName += Chr(bytes(i))
i += 1
End While
i += 9
TempPath = ""
While bytes(i) <> 0
TempPath += Chr(bytes(i))
i += 1
End While
i += 1
size = 0
For j = 0 To 3
size += bytes(i + j) * Math.Pow(256, j)
Next
Array.Resize(fs, size)
For j = i + 4 To i + 3 + size
fs(j - i - 4) = bytes(j)
Next
Return fs
End Function

你也许会喜欢的日志

3人发表了评论  ↓发表评论↓
  • 您有继续研究这个问题吗?MS对这个ole对象字段的封装好像没有解释。较早的资料曾提到***header,但都已过时

    类似的,Access中手工插入的OLE对象貌似与用代码插入的OLE对象不一样,同一份“.doc”文件用手工插入时名称显示为“microsoft 97-2003 文档”,而代码插入时则是“长二进制文件”!
    当手工插入OLE对象时Access会自动添加一些附加的信息,那请问该如何才能通过代码读取该类对象???

    [回复]

    lx 回复:

    @峰高的发光, 事实上,以后都没有再研究这个问题了. 手工插入的对象可以自己通过查看结构来得知,就像我枚举的几类文件一样: office系列文档都基本类似, 而图片文件就更加容易读取了.全部代码都在上面了. 至于什么时候是二进制什么时候是扩展的,这需要程序智能判断.使用if就可以

    [回复]

    峰高的发光 @ 2012年02月3日

    回复
  • 网上大多是二进制数据的例子。在Access中手工插入的OLE对象,点击就可以按原来的文件类型打开。ms真是有些糟糕。越来越复杂

    [回复]

    峰高的发光 @ 2012年02月3日

    回复

[ Ctrl+Enter提交 ]

3437471453591321281023251740504243322112038418334931126263041298715442436271424616193932548

Freelance PHP Developer