【问题标题】:Export pictures from excel file into jpg using VBA使用VBA将图片从excel文件导出为jpg
【发布时间】:2013-08-14 13:24:03
【问题描述】:

我有一个 Excel 文件,其中包含 B 列中的图片,我想将它们导出为 .jpg(或任何其他图片文件格式)的多个文件。文件名应从 A 列中的文本生成。我尝试了以下 VBA 宏:

Private Sub CommandButton1_Click()
Dim oTxt As Object
 For Each cell In Ark1.Range("A1:A" & Ark1.UsedRange.Rows.Count)
 ' you can change the sheet1 to your own choice
 saveText = cell.Text
 Open "H:\Webshop_Zpider\Strukturbildene\" & saveText & ".jpg" For Output As #1
 Print #1, cell.Offset(0, 1).text
 Close #1
 Next cell
End Sub

结果是它生成文件(jpg),没有任何内容。我认为Print #1, cell.Offset(0, 1).text. 是错误的。 不知道要改成什么cell.Offset(0, 1).pix

有人可以帮我吗?谢谢!

【问题讨论】:

  • 你可以使用this插件
  • 图片是如何存储的?如果它们在activex图像控件中,则只需一行代码即可保存图片;如果没有,您将需要更复杂的代码或建议的插件
  • 您好,我无法运行加载项(2007 版)。失败:“错误数量的参数和无效的属性分配”。克斯廷
  • 世界国旗图标,超压缩,.png 和 Base64:github.com/ashleedawg/flags

标签: image excel vba export


【解决方案1】:

如果我没记错的话,您需要使用工作表的“形状”属性。

每个 Shape 对象都有一个 TopLeftCell 和 BottomRightCell 属性来告诉您图像的位置。

这是我不久前使用的一段代码,大致适合您的需求。我不记得所有这些 ChartObjects 的具体细节,但这里是:

For Each oShape In ActiveSheet.Shapes
    strImageName = ActiveSheet.Cells(oShape.TopLeftCell.Row, 1).Value
    oShape.Select
    'Picture format initialization
    Selection.ShapeRange.PictureFormat.Contrast = 0.5: Selection.ShapeRange.PictureFormat.Brightness = 0.5: Selection.ShapeRange.PictureFormat.ColorType = msoPictureAutomatic: Selection.ShapeRange.PictureFormat.TransparentBackground = msoFalse: Selection.ShapeRange.Fill.Visible = msoFalse: Selection.ShapeRange.Line.Visible = msoFalse: Selection.ShapeRange.Rotation = 0#: Selection.ShapeRange.PictureFormat.CropLeft = 0#: Selection.ShapeRange.PictureFormat.CropRight = 0#: Selection.ShapeRange.PictureFormat.CropTop = 0#: Selection.ShapeRange.PictureFormat.CropBottom = 0#: Selection.ShapeRange.ScaleHeight 1#, msoTrue, msoScaleFromTopLeft: Selection.ShapeRange.ScaleWidth 1#, msoTrue, msoScaleFromTopLeft
    '/Picture format initialization
    Application.Selection.CopyPicture
    Set oDia = ActiveSheet.ChartObjects.Add(0, 0, oShape.Width, oShape.Height)
    Set oChartArea = oDia.Chart
    oDia.Activate
    With oChartArea
        .ChartArea.Select
        .Paste
        .Export ("H:\Webshop_Zpider\Strukturbildene\" & strImageName & ".jpg")
    End With
    oDia.Delete 'oChartArea.Delete
Next

【讨论】:

  • 效果很好! “图片格式初始化”似乎是您在用例中的要求,我只是将其注释掉。图表对象用作弥合剪贴板和文件系统之间差距的工具。
【解决方案2】:

这段代码:

Option Explicit

Sub ExportMyPicture()

     Dim MyChart As String, MyPicture As String
     Dim PicWidth As Long, PicHeight As Long

     Application.ScreenUpdating = False
     On Error GoTo Finish

     MyPicture = Selection.Name
     With Selection
           PicHeight = .ShapeRange.Height
           PicWidth = .ShapeRange.Width
     End With

     Charts.Add
     ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet1"
     Selection.Border.LineStyle = 0
     MyChart = Selection.Name & " " & Split(ActiveChart.Name, " ")(2)

     With ActiveSheet
           With .Shapes(MyChart)
                 .Width = PicWidth
                 .Height = PicHeight
           End With

           .Shapes(MyPicture).Copy

           With ActiveChart
                 .ChartArea.Select
                 .Paste
           End With

           .ChartObjects(1).Chart.Export Filename:="MyPic.jpg", FilterName:="jpg"
           .Shapes(MyChart).Cut
     End With

     Application.ScreenUpdating = True
     Exit Sub

Finish:
     MsgBox "You must select a picture"
End Sub

直接从here复制而来,非常适合我测试的案例。

【讨论】:

    【解决方案3】:

    '''设置要导出到文件夹的范围

    Workbooks("您的工作簿名称").Sheets("您的工作表名称").Select

    Dim rgExp As Range: Set rgExp = Range("A1:H31")
    ''' Copy range as picture onto Clipboard
    rgExp.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
    ''' Create an empty chart with exact size of range copied
    With ActiveSheet.ChartObjects.Add(Left:=rgExp.Left, Top:=rgExp.Top, _
    Width:=rgExp.Width, Height:=rgExp.Height)
    .Name = "ChartVolumeMetricsDevEXPORT"
    .Activate
    End With
    ''' Paste into chart area, export to file, delete chart.
    ActiveChart.Paste
    ActiveSheet.ChartObjects("ChartVolumeMetricsDevEXPORT").Chart.Export "C:\ExportmyChart.jpg"
    ActiveSheet.ChartObjects("ChartVolumeMetricsDevEXPORT").Delete
    

    【讨论】:

      【解决方案4】:
      Dim filepath as string
      Sheets("Sheet 1").ChartObjects("Chart 1").Chart.Export filepath & "Name.jpg"
      

      如果需要,将代码精简到绝对最小值。

      【讨论】:

        【解决方案5】:

        新版本的 excel 已经过时了旧答案。制作这个花了很长时间,但它做得很好。请注意,最大图像尺寸是有限的,纵横比也有一点偏差,因为我无法完美地优化整形数学。请注意,我已将其中一个工作表命名为 wsTMP,您可以将其替换为 Sheet1 等。将屏幕截图打印到目标路径大约需要 1 秒。

        Option Explicit
        
        Private Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
        
        Sub weGucciFam()
        
        Dim tmp As Variant, str As String, h As Double, w As Double
        
        Application.PrintCommunication = False
        Application.EnableEvents = False
        Application.Calculation = xlCalculationManual
        Application.ScreenUpdating = False
        If Application.StatusBar = False Then Application.StatusBar = "EVENTS DISABLED"
        
        keybd_event vbKeyMenu, 0, 0, 0 'these do just active window
        keybd_event vbKeySnapshot, 0, 0, 0
        keybd_event vbKeySnapshot, 0, 2, 0
        keybd_event vbKeyMenu, 0, 2, 0 'sendkeys alt+printscreen doesn't work
        wsTMP.Paste
        DoEvents
        Const dw As Double = 1186.56
        Const dh As Double = 755.28
        
        str = "C:\Users\YOURUSERNAMEHERE\Desktop\Screenshot.jpeg"
        w = wsTMP.Shapes(1).Width
        h = wsTMP.Shapes(1).Height
        
        Application.DisplayAlerts = False
        Set tmp = Charts.Add
        On Error Resume Next
        With tmp
            .PageSetup.PaperSize = xlPaper11x17
            .PageSetup.TopMargin = IIf(w > dw, dh - dw * h / w, dh - h) + 28
            .PageSetup.BottomMargin = 0
            .PageSetup.RightMargin = IIf(h > dh, dw - dh * w / h, dw - w) + 36
            .PageSetup.LeftMargin = 0
            .PageSetup.HeaderMargin = 0
            .PageSetup.FooterMargin = 0
            .SeriesCollection(1).Delete
            DoEvents
            .Paste
            DoEvents
            .Export Filename:=str, Filtername:="jpeg"
            .Delete
        End With
        On Error GoTo 0
        Do Until wsTMP.Shapes.Count < 1
            wsTMP.Shapes(1).Delete
        Loop
        
        Application.PrintCommunication = True
        Application.EnableEvents = True
        Application.Calculation = xlCalculationAutomatic
        Application.ScreenUpdating = True
        Application.StatusBar = False
        
        End Sub
        

        【讨论】:

          【解决方案6】:

          感谢您的想法!我利用上面的思路做了一个宏来做批量文件转换——将文件夹中一种格式的每个文件都转换成另一种格式。

          此代码需要包含名为“FilePath”(必须以“\”结尾)、“StartExt”(原始文件扩展名)和“EndExt”(所需文件扩展名)的单元格的工作表。警告:在替换具有相同名称和扩展名的现有文件之前,它不会要求确认。

          Private Sub CommandButton1_Click()
              Dim path As String
              Dim pathExt As String
              Dim file As String
              Dim oldExt As String
              Dim newExt As String
              Dim newFile As String
              Dim shp As Picture
              Dim chrt As ChartObject
              Dim chrtArea As Chart
          
              Application.ScreenUpdating = False
              Application.DisplayAlerts = False
          
              'Get settings entered by user
              path = Range("FilePath")
              oldExt = Range("StartExt")
              pathExt = path & "*." & oldExt
              newExt = Range("EndExt")
          
              file = Dir(pathExt)
          
              Do While Not file = "" 'cycle through all images in folder of selected format
                  Set shp = ActiveSheet.Pictures.Insert(path & file) 'Import image
                  newFile = Replace(file, "." & oldExt, "." & newExt) 'Determine new file name
                  Set chrt = ActiveSheet.ChartObjects.Add(0, 0, shp.Width, shp.Height) 'Create blank chart for embedding image
                  Set chrtArea = chrt.Chart
                  shp.CopyPicture 'Copy image to clipboard
                  With chrtArea 'Paste image to chart, then export
                      .ChartArea.Select
                      .Paste
                      .Export (path & newFile)
                  End With
                  chrt.Delete 'Delete chart
                  shp.Delete 'Delete imported image
          
                  file = Dir 'Advance to next file
              Loop
          
              Application.ScreenUpdating = True
              Application.DisplayAlerts = True
          
          
          End Sub
          

          【讨论】:

            【解决方案7】:

            这是另一种很酷的方法 - 使用接受命令行开关的外部查看器(在本例中为 IrfanView): * 我的循环基于 Michal Krzych 上面所写的内容。

            Sub ExportPicturesToFiles()
                Const saveSceenshotTo As String = "C:\temp\"
                Const pictureFormat As String = ".jpg"
            
                Dim pic As Shape
                Dim sFileName As String
                Dim i As Long
            
                i = 1
            
                For Each pic In ActiveSheet.Shapes
                    pic.Copy
                    sFileName = saveSceenshotTo & Range("A" & i).Text & pictureFormat
            
                    Call ExportPicWithIfran(sFileName)
            
                    i = i + 1
                Next
            End Sub
            
            Public Sub ExportPicWithIfran(sSaveAsPath As String)
                Const sIfranPath As String = "C:\Program Files\IrfanView\i_view32.exe"
                Dim sRunIfran As String
            
                sRunIfran = sIfranPath & " /clippaste /convert=" & _
                                        sSaveAsPath & " /killmesoftly"
            
                ' Shell is no good here. If you have more than 1 pic, it will
                ' mess things up (pics will over run other pics, becuase Shell does
                ' not make vba wait for the script to finish).
                ' Shell sRunIfran, vbHide
            
                ' Correct way (it will now wait for the batch to finish):
                call MyShell(sRunIfran )
            End Sub
            

            编辑:

              Private Sub MyShell(strShell As String)
              ' based on:
                ' http://stackoverflow.com/questions/15951837/excel-vba-wait-for-shell-command-to-complete
               ' by Nate Hekman
            
                Dim wsh As Object
                Dim waitOnReturn As Boolean:
                Dim windowStyle As VbAppWinStyle
            
                Set wsh = VBA.CreateObject("WScript.Shell")
                waitOnReturn = True
                windowStyle = vbHide
            
                wsh.Run strShell, windowStyle, waitOnReturn
            End Sub
            

            【讨论】:

              猜你喜欢
              • 2014-10-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-05-26
              • 1970-01-01
              • 2012-09-23
              • 2013-11-11
              • 1970-01-01
              相关资源
              最近更新 更多