1

我目前正在将 Excel 解决方案升级为 Web 解决方案。在这个过程中,我需要将现有数据上传到新的(SQL Server)数据库中。

问题是,我还需要上传存储在 Excel 文件中的图像(作为形状)。在数据库中,它们将以 PNG 格式存储为 bytearray。

检索任何嵌入图像的来源的最佳方法是什么?

我目前正在考虑使用ws.Shapes("img_1").CopyPicture和一些 API 函数来检索它——但到目前为止,我一直在寻找正确的 API 函数。另外,不确定是否有更简单/更优雅的方式......

4

2 回答 2

0

如果您不介意将所有图像作为文件保存在磁盘中,然后将它们上传到数据库,您可以将 Excel 工作簿或工作表保存为“网页”。

这将创建一个 html 文件和一个目录,其中填充了原始 Excel 文件所具有的任何图像(每个图像一个 PNG 文件)。

于 2013-07-11T12:24:59.080 回答
0

好的,终于找到了解决办法。不确定这是最优雅的版本 - 现在它需要 IrfanView 或其他转换器 - 但它可以完成工作。可以调用fctStrConvertImageToString(Sheets("YourSheet").Shapes("YorImage"))并将此图像的 PBG 作为字符串返回:

Option Explicit

Private Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(8) As Byte
End Type

Private Type PICTDESC
    cbSize As Long
    picType As Long
    hImage As Long
End Type

Private Declare Function OpenClipboard& Lib "user32" (ByVal hwnd&)
Private Declare Function EmptyClipboard& Lib "user32" ()
Private Declare Function GetClipboardData& Lib "user32" (ByVal wFormat%)
Private Declare Function SetClipboardData& Lib "user32" (ByVal wFormat&, ByVal hMem&)
Private Declare Function CloseClipboard& Lib "user32" ()
Private Declare Function CopyImage& Lib "user32" (ByVal handle&, ByVal un1&, ByVal n1&, ByVal n2&, ByVal un2&)
Private Declare Function IIDFromString Lib "ole32" (ByVal lpsz As String, ByRef lpiid As GUID) As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32" (pPictDesc As PICTDESC, ByRef riid As GUID, ByVal fOwn As Long, ByRef ppvObj As IPicture) As Long

Public Function fctStrConvertImageToString(shp As Shape) As String
    Const cStrPath As String = "C:\Temp\"
    Const cStrFileName As String = "temp"
    Const cStrSourceExtension As String = "bmp"
    Const cStrTargetExtension As String = "png"

    Dim strSource As String, strTarget As String


    If shp.Type <> msoPicture Then Exit Function

    shp.CopyPicture 1, xlBitmap

    strSource = cStrPath & cStrFileName & "." & cStrSourceExtension
    strTarget = cStrPath & cStrFileName & "." & cStrTargetExtension

    subSavePicAsBitmap strSource

    subConvertFile strSource, strTarget

    fctStrConvertImageToString = fctStrReadFile(strTarget)

    Kill strSource
    Kill strTarget
End Function

Private Sub subSavePicAsBitmap(strFile As String)
    Const cStrPictureIID = "{7BF80981-BF32-101A-8BBB-00AA00300CAB}"

    Dim hCopy&: OpenClipboard 0&
    Dim iPic As IPicture
    Dim tIID As GUID
    Dim tPICTDEST As PICTDESC
    Dim lngReturn As Long

    hCopy = CopyImage(GetClipboardData(2), 0, 0, 0, &H4)
    CloseClipboard
    If hCopy = 0 Then Exit Sub

    lngReturn = IIDFromString(StrConv(cStrPictureIID, vbUnicode), tIID)
    If lngReturn Then Exit Sub

    With tPICTDEST
        .cbSize = Len(tPICTDEST)
        .picType = 1
        .hImage = hCopy
    End With
    lngReturn = OleCreatePictureIndirect(tPICTDEST, tIID, 1, iPic)

    SavePicture iPic, strFile
End Sub

Private Sub subConvertFile(strSource As String, strTarget As String)
    Const cStrConverter = """c:\Program Files (x86)\IrfanView\i_view32.exe"""
    Shell cStrConverter & " " & strSource & " /convert=" & strTarget, 0
End Sub

Private Function fctStrReadFile(strFile As String)
    Dim hFile As Long

    hFile = FreeFile
    Open strFile For Binary Access Read As #hFile
    fctStrReadFile = Input$(LOF(hFile), hFile)
    Close #hFile

End Function
于 2013-07-11T12:34:00.923 回答