解决方案

EXCEL自动插入图片(根据X列的文件名,在Y列插入相同文件名的JPG图片)

简单快速用法如下:

准备工作: 确保图片文件名(如 型号123.jpg)和 Excel 里的名字(型号123)一致。

贴代码:
在 Excel 中按 Alt + F11,点击菜单栏 插入 -> 模块,把代码粘贴进去。

运行:
在代码窗口内直接按 F5 键。

按弹窗提示输入 4 次:

① 选择 图片所在的文件夹。
② 输入 型号名字在哪一列(例如输入 A)。
③ 输入 图片要放在哪一列(例如输入 B)。
④ 输入 大小数值(建议输入 80)。
结果: 程序会自动把 B 列变成正方形格子,并把图片完美塞进去。

Sub BatchInsertImages_Square_Fixed()
    Dim ws As Worksheet
    Dim lastRow As Long, i As Long
    Dim picName As String, picPath As String, folderPath As String
    Dim shp As Shape ' 改用 Shape 对象
    Dim targetCell As Range
    Dim fileExtensions As Variant, ext As Variant
    Dim fileFound As Boolean
    
    ' 用户输入变量
    Dim nameColStr As String
    Dim imgColStr As String
    Dim sideLength As Double ' 边长(既是高度也是宽度)
    Dim fd As FileDialog
    
    ' ================= 1. 获取用户参数 =================
    
    ' 1.1 选择图片文件夹
    Set fd = Application.FileDialog(msoFileDialogFolderPicker)
    With fd
        .Title = "第一步:请选择包含图片的文件夹"
        If .Show = -1 Then
            folderPath = .SelectedItems(1) & "\"
        Else
            Exit Sub
        End If
    End With
    
    ' 1.2 输入文件名所在列
    nameColStr = InputBox("第二步:请输入【文件名】所在的列号(例如 A):", "参数设置", "A")
    If nameColStr = "" Then Exit Sub
    
    ' 1.3 输入图片插入列
    imgColStr = InputBox("第三步:请输入【图片】要插入的列号(例如 B):", "参数设置", "B")
    If imgColStr = "" Then Exit Sub
    
    ' 1.4 输入尺寸(边长)
    sideLength = Application.InputBox("第四步:请输入【图片边长/行高】" & vbCrLf & _
                                      "单元格将变为正方形以适应此大小。" & vbCrLf & _
                                      "(建议输入 60 - 80)", "参数设置", 80, Type:=1)
    If sideLength <= 0 Then Exit Sub

    ' ================= 2. 调整单元格为正方形 =================
    
    Set ws = ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, nameColStr).End(xlUp).Row
    fileExtensions = Array(".jpg", ".jpeg", ".png", ".bmp", ".gif")
    
    Application.ScreenUpdating = False
    
    ' 2.1 设置行高
    ws.Range(ws.Cells(2, nameColStr), ws.Cells(lastRow, nameColStr)).EntireRow.RowHeight = sideLength
    
    ' 2.2 设置列宽 (让列宽看起来跟行高一样宽)
    ' Excel的列宽单位很特殊,大约 1个列宽单位 ≈ 6个磅(Points)
    ' 这个公式可以让单元格看起来接近正方形
    ws.Columns(imgColStr).ColumnWidth = sideLength / 6
    
    ' ================= 3. 循环插入图片 =================
    
    For i = 2 To lastRow
        picName = Trim(ws.Cells(i, nameColStr).Value)
        Set targetCell = ws.Cells(i, imgColStr)
        
        If picName <> "" Then
            ' 清理旧图片 (Shape模式)
            Dim s As Shape
            For Each s In ws.Shapes
                If s.TopLeftCell.Address = targetCell.Address Then s.Delete
            Next s
            
            ' 寻找文件
            fileFound = False
            For Each ext In fileExtensions
                picPath = folderPath & picName & ext
                If Dir(picPath) <> "" Then
                    fileFound = True
                    Exit For
                End If
            Next ext
            
            If fileFound Then
                ' 使用 AddPicture 方法,这是防止变形的关键
                ' 参数说明: Filename, LinkToFile, SaveWithDocument, Left, Top, Width, Height
                ' 我们先插入,长宽设为 -1 (代表原始尺寸),然后再强制调整
                Set shp = ws.Shapes.AddPicture(picPath, msoFalse, msoTrue, _
                                               targetCell.Left, targetCell.Top, -1, -1)
                
                With shp
                    ' 1. 锁定纵横比 (防止意外拉伸)
                    .LockAspectRatio = msoTrue
                    
                    ' 2. 强制设置高度和宽度
                    ' 既然是方形图,我们把高度和宽度设为一样
                    ' 减去 4 是为了留出一点点边距,不压线
                    .Height = sideLength - 4
                    
                    ' 再次检查宽度,如果图片原图有微小误差,这里强制修正宽度,确保它是正方形
                    ' 如果你希望严格保持原图比例(即使原图不是正方形),请删除下面这一行
                    If .Width > (sideLength - 4) Then .Width = sideLength - 4
                    
                    ' 3. 居中定位
                    .Top = targetCell.Top + (targetCell.Height - .Height) / 2
                    .Left = targetCell.Left + (targetCell.Width - .Width) / 2
                    
                    ' 4. 设置属性:随单元格移动
                    .Placement = xlMoveAndSize
                End With
            Else
                targetCell.Value = "无图"
            End If
        End If
    Next i
    
    Application.ScreenUpdating = True
    MsgBox "处理完成!单元格已调整为方形。", vbInformation
End Sub

自动压缩图片

Sub BatchInsertImages_Square_Fixed_WithCompression()
    Dim ws As Worksheet
    Dim lastRow As Long, i As Long
    Dim picName As String, picPath As String, folderPath As String
    Dim shp As Shape
    Dim targetCell As Range
    Dim fileExtensions As Variant, ext As Variant
    Dim fileFound As Boolean
    
    ' 用户输入变量
    Dim nameColStr As String
    Dim imgColStr As String
    Dim sideLength As Double
    Dim fd As FileDialog
    
    ' WIA 图像处理对象声明
    Dim ImgFile As Object
    Dim ImgProcess As Object
    Dim tempImgPath As String
    Dim insertPath As String
    Dim maxResolution As Integer
    
    ' ================= 1. 获取用户参数 =================
    
    Set fd = Application.FileDialog(msoFileDialogFolderPicker)
    With fd
        .Title = "第一步:请选择包含图片的文件夹"
        If .Show = -1 Then
            folderPath = .SelectedItems(1) & "\"
        Else
            Exit Sub
        End If
    End With
    
    nameColStr = InputBox("第二步:请输入【文件名】所在的列号(例如 A):", "参数设置", "A")
    If nameColStr = "" Then Exit Sub
    
    imgColStr = InputBox("第三步:请输入【图片】要插入的列号(例如 B):", "参数设置", "B")
    If imgColStr = "" Then Exit Sub
    
    sideLength = Application.InputBox("第四步:请输入【图片边长/行高】" & vbCrLf & _
                                      "单元格将变为正方形以适应此大小。" & vbCrLf & _
                                      "(建议输入 60 - 80)", "参数设置", 80, Type:=1)
    If sideLength <= 0 Then Exit Sub

    ' ================= 2. 调整单元格为正方形 =================
    
    Set ws = ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, nameColStr).End(xlUp).Row
    fileExtensions = Array(".jpg", ".jpeg", ".png", ".bmp", ".gif")
    
    ' 设置图片最大像素尺寸。300像素足以在80边长的单元格中保持极度清晰,同时极大降低文件体积
    maxResolution = 300 
    
    Application.ScreenUpdating = False
    
    ws.Range(ws.Cells(2, nameColStr), ws.Cells(lastRow, nameColStr)).EntireRow.RowHeight = sideLength
    ws.Columns(imgColStr).ColumnWidth = sideLength / 6
    
    ' 创建 WIA 对象,用于压缩图片
    On Error Resume Next
    Set ImgFile = CreateObject("WIA.ImageFile")
    Set ImgProcess = CreateObject("WIA.ImageProcess")
    On Error GoTo 0
    
    ' ================= 3. 循环插入图片 =================
    
    For i = 2 To lastRow
        picName = Trim(ws.Cells(i, nameColStr).Value)
        Set targetCell = ws.Cells(i, imgColStr)
        
        If picName <> "" Then
            ' 清理旧图片
            Dim s As Shape
            For Each s In ws.Shapes
                If s.TopLeftCell.Address = targetCell.Address Then s.Delete
            Next s
            
            ' 寻找文件
            fileFound = False
            For Each ext In fileExtensions
                picPath = folderPath & picName & ext
                If Dir(picPath) <> "" Then
                    fileFound = True
                    Exit For
                End If
            Next ext
            
            If fileFound Then
                insertPath = picPath ' 默认使用原图路径
                
                ' ================= 核心:图片压缩逻辑 =================
                If Not ImgFile Is Nothing And Not ImgProcess Is Nothing Then
                    On Error Resume Next
                    ImgFile.LoadFile picPath
                    
                    ' 只有当原图尺寸大于设定的最大分辨率时才压缩
                    If ImgFile.Width > maxResolution Or ImgFile.Height > maxResolution Then
                        ImgProcess.Filters.Add ImgProcess.FilterInfos("Scale").FilterID
                        ImgProcess.Filters(1).Properties("MaximumWidth") = maxResolution
                        ImgProcess.Filters(1).Properties("MaximumHeight") = maxResolution
                        ImgProcess.Filters(1).Properties("PreserveAspectRatio") = True
                        
                        Set ImgFile = ImgProcess.Apply(ImgFile)
                        
                        ' 生成临时文件路径 (保持原扩展名)
                        tempImgPath = Environ("TEMP") & "\temp_excel_img" & ext
                        If Dir(tempImgPath) <> "" Then Kill tempImgPath
                        
                        ImgFile.SaveFile tempImgPath
                        
                        ' 如果成功保存了临时文件,则将插入路径更改为临时文件
                        If Err.Number = 0 Then
                            insertPath = tempImgPath
                        End If
                    End If
                    ' 清理 Filter,为下一张图做准备
                    Do While ImgProcess.Filters.Count > 0
                        ImgProcess.Filters.Remove 1
                    Loop
                    On Error GoTo 0
                End If
                ' =======================================================
                
                ' 插入图片 (使用压缩后的 insertPath)
                Set shp = ws.Shapes.AddPicture(insertPath, msoFalse, msoTrue, _
                                               targetCell.Left, targetCell.Top, -1, -1)
                
                With shp
                    .LockAspectRatio = msoTrue
                    .Height = sideLength - 4
                    If .Width > (sideLength - 4) Then .Width = sideLength - 4
                    .Top = targetCell.Top + (targetCell.Height - .Height) / 2
                    .Left = targetCell.Left + (targetCell.Width - .Width) / 2
                    .Placement = xlMoveAndSize
                End With
                
                ' 插入完成后,如果使用了临时文件,则将其删除
                If insertPath = tempImgPath Then
                    If Dir(tempImgPath) <> "" Then Kill tempImgPath
                End If
                
            Else
                targetCell.Value = "无图"
            End If
        End If
    Next i
    
    Application.ScreenUpdating = True
    MsgBox "处理完成!图片已压缩并插入。", vbInformation
End Sub

发表回复