游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4146|回复: 0

[转载] [转] 一键将图片批量导入excel

[复制链接]

6

主题

22

帖子

174

积分

注册会员

Rank: 2

积分
174
发表于 2016-4-11 14:53:32 | 显示全部楼层 |阅读模式
        最近抽空写了一个小工具,一键将图片批量导入excel。这个工具主要是为了方便整理游戏项目中用到的图片,尤其是对于需要对界面图片字进行翻译时,可快速生成需求文档。 目前的项目有几个G的图片资源,数千张图片,人工插入费时费力,就写了这个小工具。下面是VBA代码,只需将其粘贴到excel编辑器内,写入图片目录地址,执行“批量导入”即可完成导入。

第一步:新建工作表
新建“目录”、“文件夹目录(勿删)”共2个空白工作表。
在“目录”表中J1写入准备导入的图片目录。




第二步:粘贴VBA代码
将一下代码粘贴到VBA编辑器内。
a.新建模块1,粘贴以下代码:

Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public dizhi, BName As String, mypic, Picwidth, Picheight
Private Function ShowFolderList(folderspec)
'获取folderspec下的子文件夹列表 返回数组
    Dim i, fs, f, f1, s, sf, arr
    Dim hs, h, h1, hf
    ReDim arr(1 To 60000)
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set f = fs.GetFolder(folderspec)
    Set sf = f.SubFolders
    For Each f1 In sf
        i = i + 1
        arr(i) = f1.Name
    Next
    ReDim Preserve arr(1 To i)
    ShowFolderList = arr
End Function


Sub 获取子目录内图片名()
    '清空表“文件夹目录(勿删)”里的数据
    Sheets("文件夹目录(勿删)").Select
    Cells.Select
    Selection.ClearContents
    '获取图片目录地址
    dizhi = Sheets("目录").Cells(1, 10)   
    Call 导出根目录 '导出根目录=============================
    '写入所有子目录下png图片名
    For genmlwjj = 1 To 100
        If (Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1) = "") Then
            Exit For
        End If        
            zimulu = dizhi & "\" & Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1).Value
            Sheets("文件夹目录(勿删)").Cells(2, genmlwjj + 1) = "子目录" & zimulu            
            tupianming = Dir(zimulu & "\*.png")
            hang = 3
        Do While tupianming > ""
            Cells(hang, genmlwjj + 1).Value = tupianming
            hang = hang + 1
            tupianming = Dir
        Loop   
    Next genmlwjj
End Sub

Private Sub 导出根目录()
    Dim arr
    arr = ShowFolderList(dizhi)
    Debug.Print Join(arr, vbCr) '调试打印
    [A3].Resize(UBound(arr)) = Application.Transpose(arr) '输出到A列
    Sheets("文件夹目录(勿删)").Cells(2, 1) = "目录" & dizhi '输出A列字段名到表“文件夹目录(勿删)”
End Sub


Sub 新建或重置文件夹目录表()
    Dim Wss As Worksheet, BName As String
'    判断表“文件夹目录(勿删)”是否存在
    BName = "文件夹目录(勿删)"
    On Error Resume Next
    Set Wss = ActiveWorkbook.Sheets(BName)
    If Wss Is Nothing Then
'        MsgBox BName & " 不存在,立刻新建一个"
        Worksheets.Add
        ActiveSheet.Name = BName
        Sheets(BName).Select
        Range("A1").Select
    Else
'        MsgBox BName & "文件夹目录(勿删)表已存在"
    End If
End Sub


Sub 相应的表内更新图片清单() '子目录对应表里写入图片名
    Call 获取子目录内图片名 '========================================
    Call 判断是否需新建表 '========================================   
    For genmlwjj = 1 To 100
        If (Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1) = "") Then
            Exit For
        End If        
        lie = genmlwjj + 1
        BName = Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1).Value
        Sheets("文件夹目录(勿删)").Select
        Columns(lie).Select
        Selection.Copy
        Sheets(BName).Select
        Columns(2).Select
        ActiveSheet.Paste
    Next genmlwjj
End Sub


Sub 判断是否需新建表() '创建子目录工作表
    Dim Ws As Worksheet, BName As String
    On Error Resume Next   
    For genmlwjj = 1 To 999
        If (Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1) = "") Then
            Exit For
        End If        
        BName = Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1).Value        
        Set Ws = ActiveWorkbook.Sheets(BName)
        If Ws Is Nothing Then
'            MsgBox BName & " 表不存在,立刻新建一个"
            Sheets("文件夹目录(勿删)").Select
            Range("A1").Select
            Worksheets.Add
            ActiveSheet.Name = BName                       
        Else
'           MsgBox BName & " 表已存在"
        End If        
    Next genmlwjj   
End Sub



' --------------------------------------------------------------------------------------------------------------------------------------------------------
Sub 对所有表更新图片() '导入图片
    Call 相应的表内更新图片清单 '============================================
    For genmlwjj = 1 To 999
        If (Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1) = "") Then
            Exit For
        End If
        BName = Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1).Value
        Sheets(BName).Select               
    '    ActiveSheet.Shapes.SelectAll
    '    Selection.Delete
    '    Range("A1").Select
        Call 对单个表插入图片        
    Next genmlwjj
End Sub

Sub 对单个表插入图片()
    Dim i As Integer
    Dim FilPath As String
    Dim rng As Range
    Dim s As String   
    Sheets(BName).Cells(2, 3) = "中文"
    Sheets(BName).Cells(2, 4) = "翻译"
    Sheets(BName).Cells(2, 5) = "图片"   
    For i = 3 To 100
        If Sheets(BName).Cells(i, 2) = "" Then
            Exit For
        End If   
        FilPath = dizhi & "\" & BName & "\" & Sheets(BName).Cells(i, 2).Value        
        If Dir(FilPath) <> "" Then        
            Set rng = Sheets(BName).Cells(i, 5)
            With rng
                ML = .Left + 5
                MT = .Top + 5
                MW = .Width
                MH = .Height               
                mypic = FilPath               
                Call 获取图片尺寸               
                Sheets(BName).Select
                Rows(i).Select               
                MaxHeight = 390 '设置图片最大高度为390               
                If Picheight >= MaxHeight Then '对较大图片进行等比缩放
                    Picwidth = Picwidth / (Picheight / MaxHeight)
                    Picheight = MaxHeight
                    Selection.RowHeight = MaxHeight + 10 '调整行高
                    Sheets(BName).Cells(i, 1) = "原图太大被我缩小了" '加入备注
                Else
                    Selection.RowHeight = Picheight + 10 '调整行高
                End If
                MW = Picwidth '返回 图片 宽
                MH = Picheight '返回 图片 高               
                '插入图片
                ActiveSheet.Shapes.AddShape(msoShapeRectangle, ML, MT, MW, MH).Select
                Selection.ShapeRange.Fill.UserPicture FilPath
            End With
        Else
            s = s & Chr(10) & Sheets(BName).Cells(i, 2).Text
        End If
    Next
       Sheets(BName).Cells(1, 1).Select
    If s <> "" Then
        MsgBox s & Chr(10) & "没有照片!"
    End If
End Sub

'----------------------------------------------------------------------------------------------------------------------------------------------------------------
Sub 目录链接()
'清空=====================================
    Sheets("目录").Select
    Range("a1:b100").Select
    Selection.ClearContents   
'写入表名称和链接============================
h = 2 '开始的行
i = 1
For Each sh In Worksheets   
    Sheets("目录").Cells(i + h - 1, 1).Value = i '输出序号        
    Sheets("目录").Cells(i + h - 1, 2).Value = sh.Name '输出表名称   
    Sheets("目录").Cells(i + h - 1, 2).Select
    ActiveSheet.Hyperlinks.Add Anchor:=Selection, Address:="", SubAddress:="'" & sh.Name & "'!A1" '写入链接
    If i = 1 Then
        Sheets("目录").Cells(i + h - 1, 3).Value = "=HYPERLINK(" & Chr(34) & dizhi & Chr(34) & ")" '输出文件夹地址"
    Else
        Sheets("目录").Cells(i + h - 1, 3).Value = "=HYPERLINK(" & Chr(34) & dizhi & "\" & sh.Name & Chr(34) & ")" '输出文件夹地址"
    End If  
    i = i + 1   
Next sh
End Sub

Sub 文件链接()
dizhi = Sheets("目录").Cells(1, 10)
For i = 3 To 10
'    Sheets("目录").Cells(i, 3) = dizhi & "\" & Sheets("目录").Cells(i, 2)
    Sheets("目录").Hyperlinks.Add Anchor:=Cells(i, 3), Address:=dizhi, TextToDisplay:=rs.Fields(dizhi & "\" & Sheets("目录").Cells(i, 2)).Value
Next i
End Sub



'-------------------------------------------------------------------------------------------------------------------------------------------------
Sub 更新文档()
    Call 对所有表更新图片
    Call 目录链接
End Sub



'---------------------------------------------------------------------------------------------------------------------------------------------------
Sub 删除所有表里的图片()
    Call 相应的表内更新图片清单 '============================================
    For genmlwjj = 1 To 100
        If (Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1) = "") Then
            Exit For
        End If
        BName = Sheets("文件夹目录(勿删)").Cells(genmlwjj + 2, 1).Value
        Sheets(BName).Select '选表
        ActiveSheet.Shapes.SelectAll '选图片对象
        Selection.Delete
        Range("A1").Select        
    Next genmlwjj
End Sub



b.新建模块2,粘贴以下代码:

'------------------------------------------------------------------------------------------------------------------------------------------------------------
'***************************************************

'* 模 块 名:mdLSPicSize
'* 功能描述:读取图片尺寸信息(不加载图片,支持PNG)
'* 作    者:
'* 作者博客:
'* 日    期:2012-01-21 21:39
'* 版    本:V1.0.0
'***************************************************
'整行注释的为在读取图片尺寸时不需要的文件头信息
'BMP文件头
Private Type BitmapFileHeader
    bfType As Integer    '标识 0,1 两个字节为 42 4D 低位在前,即 19778
    bfReserved2 As Integer
    bfOffBits As Long
    bfReserved1 As Integer
    bfSize As Long
End Type
Private Type BitmapInfoHeader
    biSize As Long
    biWidth As Long    '宽度 18,19,20,21 四个字节,低位在前
    biHeight As Long    '高度 22,23,24,25 四个字节,低位在前
    '  biPlanes As Integer
    '  biBitCount As Integer
    '  biCompression As Long
    '  biSizeImage As Long
    '  biXPelsPerMeter As Long
    '  biYPelsPerMeter As Long
    '  biClrUsed As Long
    '  biClrImportant As Long
End Type
'JPEG(这个好麻烦)
Private Type LSJPEGHeader
    jSOI As Integer    '图像开始标识 0,1 两个字节为 FF D8 低位在前,即 -9985
    jAPP0 As Integer    'APP0块标识 2,3 两个字节为 FF E0
    jAPP0Length(1) As Byte   'APP0块标识后的长度,两个字节,高位在前
    '  jJFIFName As Long         'JFIF标识 49(J) 48(F) 44(I) 52(F)
    '  jJFIFVer1 As Byte         'JFIF版本
    '  jJFIFVer2 As Byte         'JFIF版本
    '  jJFIFVer3 As Byte         'JFIF版本
    '  jJFIFUnit As Byte
    '  jJFIFX As Integer
    '  jJFIFY As Integer
    '  jJFIFsX As Byte
    '  jJFIFsY As Byte
End Type
Private Type LSJPEGChunk
    jcType As Integer    '标识(按顺序):APPn(0,1~15)为 FF E1~FF EF; DQT为 FF DB(-9217)
    'SOFn(0~3)为 FF C0(-16129),FF C1(-15873),FF C2(-15617),FF C3(-15361)
    'DHT为 FF C4(-15105); 图像数据开始为 FF DA
    jcLength(1) As Byte    '标识后的长度,两个字节,高位在前
    '若标识为SOFn,则读取以下信息;否则按照长度跳过,读下一块
    jBlock As Byte    '数据采样块大小 08 or 0C or 10
    jHeight(1) As Byte    '高度两个字节,高位在前
    jWidth(1) As Byte    '宽度两个字节,高位在前
    '  jColorType As Byte        '颜色类型 03,后跟9字节,然后是DHT
End Type
'PNG文件头
Private Type LSPNGHeader
    pType As Long    '标识 0,1,2,3 四个字节为 89 50(P) 4E(N) 47(G) 低位在前,即 1196314761
    pType2 As Long    '标识 4,5,6,7 四个字节为 0D 0A 1A 0A
    pIHDRLength As Long    'IHDR块标识后的长度,疑似固定 00 0D,高位在前,即 13
    pIHDRName As Long    'IHDR块标识 49(I) 48(H) 44(D) 52(R)
    Pwidth(3) As Byte    '宽度 16,17,18,19 四个字节,高位在前
    Pheight(3) As Byte    '高度 20,21,22,23 四个字节,高位在前
    '  pBitDepth As Byte
    '  pColorType As Byte
    '  pCompress As Byte
    '  pFilter As Byte
    '  pInterlace As Byte
End Type
'GIF文件头(这个好简单)
Private Type LSGIFHeader
    gType1 As Long    '标识 0,1,2,3 四个字节为 47(G) 49(I) 46(F) 38(8) 低位在前,即 944130375
    gType2 As Integer    '版本 4,5 两个字节为 7a单幅静止图像9a若干幅图像形成连续动画
    gWidth As Integer    '宽度 6,7 两个字节,低位在前
    gHeight As Integer    '高度 8,9 两个字节,低位在前
End Type
Public Function PictureSize(ByVal picPath As String, ByRef Width As Long, ByRef Height As Long) As String
    Dim iFile As Integer
    Dim jpg As LSJPEGHeader
    Width = 0: Height = 0             '预输出:0 * 0
    If picPath = "" Then PictureSize = "null": Exit Function          '文件路径为空
    If Dir(picPath) = "" Then PictureSize = "not exist": Exit Function    '文件不存在
    PictureSize = "error"             '预定义:出错
    iFile = FreeFile()
    Open picPath For Binary Access Read As #iFile
    Get #iFile, , jpg
    If jpg.jSOI = -9985 Then
        Dim jpg2 As LSJPEGChunk, pass As Long
        pass = 5 + jpg.jAPP0Length(0) * 256 + jpg.jAPP0Length(1)      '高位在前的计算方法
        PictureSize = "JPEG error"    'JPEG分析出错
        Do
            Get #iFile, pass, jpg2
            If jpg2.jcType = -16129 Or jpg2.jcType = -15873 Or jpg2.jcType = -15617 Or jpg2.jcType = -15361 Then
                Width = jpg2.jWidth(0) * 256 + jpg2.jWidth(1)
                Height = jpg2.jHeight(0) * 256 + jpg2.jHeight(1)
                PictureSize = Width & "*" & Height
                'PictureSize = "JPEG"  'JPEG分析成功
                Stop
                Exit Do
            End If
            pass = pass + jpg2.jcLength(0) * 256 + jpg2.jcLength(1) + 2
        Loop While jpg2.jcType <> -15105    'And pass < LOF(iFile)
    ElseIf jpg.jSOI = 19778 Then
        Dim bmp As BitmapInfoHeader
        Get #iFile, 15, bmp
        Width = bmp.biWidth
        Height = bmp.biHeight
        PictureSize = Width & "*" & Height
        ' PictureSize = "BMP"           'BMP分析成功
    Else
        Dim png As LSPNGHeader
        Get #iFile, 1, png
        If png.pType = 1196314761 Then
            Width = png.Pwidth(0) * 16777216 + png.Pwidth(1) * 65536 + png.Pwidth(2) * 256 + png.Pwidth(3)
            Height = png.Pheight(0) * 16777216 + png.Pheight(1) * 65536 + png.Pheight(2) * 256 + png.Pheight(3)
            PictureSize = Width & "*" & Height
            'PictureSize = "PNG"       'PNG分析成功
        ElseIf png.pType = 944130375 Then
            Dim gif As LSGIFHeader
            Get #iFile, 1, gif
            Width = gif.gWidth
            Height = gif.gHeight
            PictureSize = Width & "*" & Height
            'PictureSize = "GIF"       'GIF分析成功
        Else
            PictureSize = "unknow"    '文件类型未知
        End If
    End If
    Close #iFile
End Function
'*************************以下是测试代码
Sub 获取图片尺寸()
    Dim w As Long, h As Long
    Dim f As String    '图片文件完成路径
    Dim t As String
    Dim Pwidth As Long, Pheight As Long
    Dim Psize As String
    f = mypic  '图片文件完成路径
    Psize = PictureSize(f, w, h)    '运行宏,w,h就是对应图片的width height  ,返回 width*height
    If Len(Psize) > 0 Then
        Pwidth = Val(Split(Psize, "*")(0))  '返回 图片 宽
        Pheight = Val(Split(Psize, "*")(1))    '返回 图片 高        
        Picwidth = Pwidth '赋值到
        Picheight = Pheight '赋值到        
    End If
End Sub





第三步:创建按钮
在“目录”工作表中创建2个按钮,分别指向宏“更新文档”、“删除所有表里的图片” 。


第四步:工具完成

导入后效果:






    欢迎有兴趣的朋友共同探讨!




转自 http://user.qzone.qq.com/1437900504/blog/1459218778


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-26 07:00

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表