EXCEL编写一个VBA宏来实现下载图片并且重新命名功能

2024-07-11

因为Excel本身并不支持直接下载网络图片并重命名保存到本地的功能。不过,可以使用VBA宏,以下步骤来简化处理过程:

  1. 提取图片链接:首先,在Excel中使用公式或手动操作提取每条记录的图片链接。

  2. 使用VBA宏下载图片:您可以编写一个VBA宏来实现下载图片的功能。VBA宏可以访问网络,下载图片,并将其保存到本地磁盘。

  3. 重命名图片:在VBA宏中,您可以根据EID和图片序号来重命名图片。

以下是VBA宏代码,用于下载图片并根据EID和作品名称和序号重命名:

Sub DownloadImages()


    Dim ws As Worksheet

    Set ws = ThisWorkbook.Sheets("02024 爱立信摄影展_k0SjaQ ==") ' 请根据您的工作表名称(不是表格名字)修改


    Dim lastRow As Long

    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row ' 假设粉丝编号在A列


    Dim i As Long

    Dim EID As String

    Dim imageLinks As Variant

    Dim imgNumber As Integer

    Dim fileName As String

    Dim workName As String ' 新增变量以存储作品名称

    Dim folderPath As String

    folderPath = "E:\2024爱立信摄影展" ' 请根据需要修改保存路径

    

    ' 确保文件夹存在

    If Dir(folderPath, vbDirectory) = "" Then MkDir folderPath


    Dim WinHttpRequest As Object

    Set WinHttpRequest = CreateObject("WinHttp.WinHttpRequest.5.1")


    For i = 2 To lastRow

        EID = Trim(ws.Cells(i, "G").Value) ' 假设EID在G列

        imageLinks = Split(ws.Cells(i, "E").Value, "|") ' 假设图片链接在E列,使用"|"分割

        

        ' 提取作品名称,新变量workName

        workName = Trim(ws.Cells(i, "D").Value) ' 假设作品名称在D列

        

        ' 去除作品名称中的不允许字符

        workName = CleanFileName(workName)


        For imgNumber = 1 To UBound(imageLinks) + 1

            ' 根据EID和作品名称,设置文件名

            fileName = folderPath & "\" & EID & "-" & workName & "-" & imgNumber & ".jpg"

            

            ' 使用WinHttpRequest对象下载图片

            With WinHttpRequest

                .Open "GET", imageLinks(imgNumber - 1), False

                .SetTimeouts 5000, 5000, 5000, 5000

                .Send

                

                If .Status = 200 Then

                    Dim fileContent() As Byte

                    fileContent = .ResponseBody

                    

                    ' 尝试获取Content-Type头信息

                    Dim contentType As String

                    contentType = LCase(.GetResponseHeader("Content-Type"))

                    

                    ' 根据Content-Type设置文件扩展名

                    If InStr(1, contentType, "image/jpeg") > 0 Or _

                       InStr(1, contentType, "image/jpg") > 0 Then

                        fileName = Replace(fileName, ".jpg", ".jpg")

                    ElseIf InStr(1, contentType, "image/png") > 0 Then

                        fileName = Replace(fileName, ".jpg", ".png")

                    ElseIf InStr(1, contentType, "image/gif") > 0 Then

                        fileName = Replace(fileName, ".jpg", ".gif")

                    Else

                        MsgBox "未知的图片格式: " & contentType

                    End If

                    

                    ' 写入文件

                    Dim fileNum As Integer

                    fileNum = FreeFile

                    Open fileName For Binary Access Write As #fileNum

                        Put #fileNum, , fileContent

                    Close #fileNum

                Else

                    MsgBox "下载失败,状态码:" & .Status & ",URL:" & imageLinks(imgNumber - 1)

                End If

            End With

        Next imgNumber

    Next i

    

    MsgBox "所有图片已下载完毕。"

End Sub


Function CleanFileName(fileName As String) As String

    ' 替换文件名中的非法字符

    Dim illegalChars As Variant

    illegalChars = Array("\", "/", ":", "*", "?", """", "<", ">", "|", " ", "?")

    

    Dim newName As String

    newName = fileName

    Dim i As Integer

    For i = LBound(illegalChars) To UBound(illegalChars)

        newName = Replace(newName, illegalChars(i), "_") ' 使用下划线替代非法字符

    Next i

    

    CleanFileName = newName

End Function


1、在 CleanFileName 函数中新增了字符空格和“•”到 illegalChars 数组中。

使得任何包含非法字符的文件名将被正常处理,替换为下划线。你可以根据需要继续添加或修改非法字符列表。

2确保 fileName 在构建时不会遗漏路径分隔符 \。


以下是VBA宏代码,用于下载图片并根据EID和序号重命名:

Sub DownloadImages()

    Dim ws As Worksheet

    Set ws = ThisWorkbook.Sheets("02024 爱立信摄影展 == (1)") ' 请根据您的工作表名称修改

    

    Dim lastRow As Long

    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row ' 假设粉丝编号在A列

    

    Dim i As Long

    Dim EID As String

    Dim imageLinks As Variant

    Dim imgNumber As Integer

    Dim fileName As String

    Dim folderPath As String

    folderPath = "E:\"

    If Dir(folderPath, vbDirectory) = "" Then MkDir folderPath

    

    Dim WinHttpRequest As Object

    Set WinHttpRequest = CreateObject("WinHttp.WinHttpRequest.5.1")

    

    For i = 2 To lastRow

        EID = Trim(ws.Cells(i, "E").Value) ' 假设EID在E列

        imageLinks = Split(ws.Cells(i, "D").Value, "|") ' 假设图片链接在D列,使用"|"分割

        

        For imgNumber = 1 To UBound(imageLinks) + 1

            fileName = folderPath & EID & "-" & imgNumber & ".jpg" ' 默认使用.jpg格式

            

    ' 使用WinHttpRequest对象下载图片

            With WinHttpRequest

                .Open "GET", imageLinks(imgNumber - 1), False

                .SetTimeouts 5000, 5000, 5000, 5000

                .Send

                

                If .Status = 200 Then

                    Dim fileContent() As Byte

                    fileContent = .ResponseBody

                    

                    ' 尝试获取Content-Type头信息

                    Dim contentType As String

                    contentType = LCase(.GetResponseHeader("Content-Type"))

                    

                    ' 根据Content-Type设置文件扩展名

                    If InStr(1, contentType, "image/jpeg") > 0 Or _

                       InStr(1, contentType, "image/jpg") > 0 Then

                        fileName = Replace(fileName, ".jpg", ".jpg")

                    ElseIf InStr(1, contentType, "image/png") > 0 Then

                        fileName = Replace(fileName, ".jpg", ".png")

                    ElseIf InStr(1, contentType, "image/gif") > 0 Then

                        fileName = Replace(fileName, ".jpg", ".gif")

                    Else

                        MsgBox "未知的图片格式: " & contentType

                    End If

                    

                    ' 写入文件

                    Dim fileNum As Integer

                    fileNum = FreeFile

                    Open fileName For Binary Access Write As #fileNum

                        Put #fileNum, , fileContent

                    Close #fileNum

                Else

                    MsgBox "下载失败,状态码:" & .Status & ",URL:" & imageLinks(imgNumber - 1)

                End If

            End With

        Next imgNumber

    Next i

    

    MsgBox "所有图片已下载完毕。"

End Sub

  1. 在 CleanFileName 函数中新增了字符空格、中文字符“我”、中文字符“额”和“•”到 illegalChars 数组中。

  2. 使得任何包含非法字符的文件名将被正常处理,替换为下划线
  3. 确保 fileName 在构建时不会遗漏路径分隔符 \


这个VBA宏需要在Excel的VBA编辑器中运行。您可以通过以下步骤来使用它:

  1. 在Excel中,按下 Alt + F11 打开VBA编辑器。

  2. 插入一个新模块(在菜单中选择 Insert > Module)。

  3. 将上述代码复制并粘贴到新模块中。

  4. 修改代码中的工作表名称、列号和文件夹路径以匹配您的Excel文件。

  5. 运行宏(可以按 F5 键或在VBA编辑器中选择 Run > Run Sub/UserForm)。

由于VBA宏涉及到网络访问和文件操作,确保您的Excel设置允许运行宏,并且您有足够的权限来访问指定的文件夹。

请注意以下几点:

  • 确保工作表名称、列号和文件夹路径与您的Excel文件相匹配。

  • 这段代码使用了 MSXML2.XMLHTTP 对象来发送HTTP请求,这是较新版本的XMLHTTP对象,如果您的Excel版本不支持,您可能需要改回使用 Microsoft.XMLHTTP

  • 使用更现代的XMLHTTP库:使用 WinHttp.WinHttpRequest.5.1 来代替 MSXML2.XMLHTTP,这可能提供更好的兼容性和性能。

  • 异常处理:添加错误处理来捕获和处理下载过程中可能出现的异常。

  • HTTP请求超时:为HTTP请求添加超时设置,避免长时间等待响应。

  • 确保路径存在:在保存文件之前检查文件夹路径是否存在。

  • 代码中添加了检查,以确保不会尝试下载空链接,并且不会重复下载已存在的文件。

  • 代码中添加了创建文件夹的逻辑,如果目标文件夹不存在,会自动创建。

在运行宏之前,请确保您的宏安全设置允许运行宏,并且您已经启用了对 ActiveX 脚本和宏的访问。您可以在Excel的“文件” > “选项” > “信任中心” > “信任中心设置” > “宏设置”中调整这些选项。如果您不熟悉如何操作,可能需要寻求IT专业人员的帮助。

微信截图_20240711122303.png

微信图片_20240711105536.png

微信图片_20240711105545.png