Please suggest the better way of exporting range of data from excel worksheets as image either in .jpeg or .png or in .gif.
-
2what version of Excel do you use, is it Excel 2007, Exxel 2010? Because in recent versions there is a feature **Copy...as Picture** which could probably be automated using VBA. – Our Man in Bananas Apr 22 '13 at 09:45
-
I'm using excel 2003. – Vishal I P Apr 22 '13 at 09:47
9 Answers
do you want to try the below code I found on the internet somewhere many moons ago and used.
It uses the Export function of the Chart object along with the CopyPicture method of the Range object.
References:
- MSDN - Export method as it applies to the Chart object. to save the clipboard as an Image
MSDN - CopyPicture method as it applies to the Range object to copy the range as a picture
dim sSheetName as string dim oRangeToCopy as range Dim oCht As Chart sSheetName ="Sheet1" ' worksheet to work on set oRangeToCopy =Range("B2:H8") ' range to be copied Worksheets(sSheetName).Range(oRangeToCopy).CopyPicture xlScreen, xlBitmap set oCht =charts.add with oCht .paste .Export FileName:="C:\SavedRange.jpg", Filtername:="JPG" end with

- 5,809
- 21
- 91
- 148
-
4didn work for me on this line: Worksheets(sSheetName).Range(oRangeToCopy).CopyPicture xlScreen, xlBitmap – juanora Mar 18 '15 at 14:16
-
Is there a way to improve the export image size? Default size is not providing much details of the chart. – Vivek Oct 29 '15 at 14:28
-
@Vivek: I can only suggest you take a look at the other answers - they may provide some help with that... – Our Man in Bananas Oct 30 '15 at 09:04
I've tried to improve this solution in several ways. Now resulting image has right proportions.
Set sheet = ActiveSheet
output = "D:\SavedRange4.png"
zoom_coef = 100 / sheet.Parent.Windows(1).Zoom
Set area = sheet.Range(sheet.PageSetup.PrintArea)
area.CopyPicture xlPrinter
Set chartobj = sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
chartobj.Chart.Export output, "png"
chartobj.Delete

- 2,093
- 3
- 28
- 48
-
1
-
-
I'm having the same issue. When I step through the code one line at a time, the image works fine, but if I just run it the image is created but appears blank. Also tried it with a time delay an that didn't help. @Winand – Joe K Sep 26 '21 at 21:20
-
@JoeK what if you delete the last two lines (.export and .delete)? Is the image blank? – Winand Sep 27 '21 at 07:53
Thanks everyone! I modified Winand's code slightly to export it to the user's desktop, no matter who is using the worksheet. I gave credit in the code to where I got the idea (thanks Kyle).
Sub ExportImage()
Dim sFilePath As String
Dim sView As String
'Captures current window view
sView = ActiveWindow.View
'Sets the current view to normal so there are no "Page X" overlays on the image
ActiveWindow.View = xlNormalView
'Temporarily disable screen updating
Application.ScreenUpdating = False
Set Sheet = ActiveSheet
'Set the file path to export the image to the user's desktop
'I have to give credit to Kyle for this solution, found it here:
'http://stackoverflow.com/questions/17551238/vba-how-to-save-excel-workbook-to-desktop-regardless-of-user
sFilePath = CreateObject("WScript.Shell").specialfolders("Desktop") & "\" & ActiveSheet.Name & ".png"
'Export print area as correctly scaled PNG image, courtasy of Winand
zoom_coef = 100 / Sheet.Parent.Windows(1).Zoom
Set area = Sheet.Range(Sheet.PageSetup.PrintArea)
area.CopyPicture xlPrinter
Set chartobj = Sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
chartobj.Chart.Export sFilePath, "png"
chartobj.Delete
'Returns to the previous view
ActiveWindow.View = sView
'Re-enables screen updating
Application.ScreenUpdating = True
'Tells the user where the image was saved
MsgBox ("Export completed! The file can be found here:" & Chr(10) & Chr(10) & sFilePath)
End Sub

- 627
- 6
- 9
Winand, Quality was also an issue for me so I did this:
For Each ws In ActiveWorkbook.Worksheets
If ws.PageSetup.PrintArea <> "" Then
'Reverse the effects of page zoom on the exported image
zoom_coef = 100 / ws.Parent.Windows(1).Zoom
areas = Split(ws.PageSetup.PrintArea, ",")
areaNo = 0
For Each a In areas
Set area = ws.Range(a)
' Change xlPrinter to xlScreen to see zooming white space
area.CopyPicture Appearance:=xlPrinter, Format:=xlPicture
Set chartobj = ws.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
'scale the image before export
ws.Shapes(chartobj.Index).ScaleHeight 3, msoFalse, msoScaleFromTopLeft
ws.Shapes(chartobj.Index).ScaleWidth 3, msoFalse, msoScaleFromTopLeft
chartobj.Chart.Export ws.Name & "-" & areaNo & ".png", "png"
chartobj.delete
areaNo = areaNo + 1
Next
End If
Next
See here:https://robp30.wordpress.com/2012/01/11/improving-the-quality-of-excel-image-export/

- 855
- 10
- 11
-
1i see what u did here.) You can achieve the same result by modifying the line "zoom_coef = ... * 3" – Winand Apr 16 '15 at 05:39
-
1
-
hmm, i checked with excel2013 before posting. Can u please pastebin the code that definitely gives u image with whitespace? (sometimes i want SO to be a forum.) – Winand Apr 16 '15 at 15:57
-
First of all I'm on 2010 and the question refers to 2003. xlScreen : will zoom, xlPrinter : will resize. My code I left out xlPrinter so it defaults to xlScreen. But your code is designed to counteract the effects of the adjustments to the screen Zoom in the bottom left of the screen. – MartinC Apr 17 '15 at 02:49
-
But if the zoom is at 100% it does as you say. We need to combine both zoom and scale to have quality in the export regardless of the zoom of the sheet. – MartinC Apr 17 '15 at 02:56
-
Why do we need xlScreen at all? It leaves filter buttons, default grid, etc. With xlPrinter we resize to compensate window zoom level and can add additional coef. (>1) to improve quality. Also the result looks the same as printed or exported to pdf. And no whitespace. – Winand Apr 17 '15 at 08:25
Solution without charts
Function SelectionToPicture(nome)
'save location ( change if you want )
FName = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\" & nome & ".jpg"
'copy selection and get size
Selection.CopyPicture xlScreen, xlBitmap
w = Selection.Width
h = Selection.Height
With ThisWorkbook.ActiveSheet
.Activate
Dim chtObj As ChartObject
Set chtObj = .ChartObjects.Add(100, 30, 400, 250)
chtObj.Name = "TemporaryPictureChart"
'resize obj to picture size
chtObj.Width = w
chtObj.Height = h
ActiveSheet.ChartObjects("TemporaryPictureChart").Activate
ActiveChart.Paste
ActiveChart.Export FileName:=FName, FilterName:="jpg"
chtObj.Delete
End With
End Function

- 91
- 1
- 4
If you add a Selection and saving to workbook path to Ryan Bradley code that will be more elastic:
Sub ExportImage()
Dim sheet, zoom_coef, area, chartobj
Dim sFilePath As String
Dim sView As String
'Captures current window view
sView = ActiveWindow.View
'Sets the current view to normal so there are no "Page X" overlays on the image
ActiveWindow.View = xlNormalView
'Temporarily disable screen updating
Application.ScreenUpdating = False
Set sheet = ActiveSheet
'Set the file path to export the image to the user's desktop
'I have to give credit to Kyle for this solution, found it here:
'http://stackoverflow.com/questions/17551238/vba-how-to-save-excel-workbook-to-desktop-regardless-of-user
'sFilePath = CreateObject("WScript.Shell").specialfolders("Desktop") & "\" & ActiveSheet.Name & ".png"
'##################
'Łukasz : Save to workbook directory
'Asking for filename insted of ActiveSheet.Name is also good idea, without file extension
dim FileID as string
FileID=inputbox("Type a file name","Filename...?",ActiveSheet.Name)
sFilePath = ThisWorkbook.Path & "\" & FileID & ".png"
'Łukasz:Change code to use Selection
'Simply select what you want to export and run the macro
'ActiveCell should be: Top Left
'it means select from top left corner to right bottom corner
Dim r As Long, c As Integer, ar As Long, ac As Integer
r = Selection.rows.Count
c = Selection.Columns.Count
ar = ActiveCell.Row
ac = ActiveCell.Column
ActiveSheet.PageSetup.PrintArea = Range(Cells(ar, ac), Cells(ar, ac)).Resize(r, c).Address
'Export print area as correctly scaled PNG image, courtasy of Winand
'Łukasz: zoom_coef can be constant = 0 to 5 can work too, but save is 0 to 4
zoom_coef = 5 '100 / sheet.Parent.Windows(1).Zoom
'#############
Set area = sheet.Range(sheet.PageSetup.PrintArea)
area.CopyPicture xlPrinter 'xlBitmap '
Set chartobj = sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
chartobj.Chart.Export sFilePath, "png"
chartobj.Delete
'Returns to the previous view
ActiveWindow.View = sView
'Re-enables screen updating
Application.ScreenUpdating = True
'Tells the user where the image was saved
MsgBox ("Export completed! The file can be found here: :" & Chr(10) & Chr(10) & sFilePath)
'Close
End Sub

- 17
- 2
This gives me the most reliable results:
Sub RangeToPicture()
Dim FileName As String: FileName = "C:\file.bmp"
Dim rPrt As Range: Set rPrt = ThisWorkbook.Sheets("Sheet1").Range("A1:C6")
'Add a Zoom to increase the resolution of the image.
ActiveWindow.Zoom = 300
Dim chtObj As ChartObject
rPrt.CopyPicture xlScreen, xlBitmap
Set chtObj = ActiveSheet.ChartObjects.Add(1, 1, rPrt.Width, rPrt.Height)
chtObj.Activate
ActiveChart.Paste
ActiveChart.Export FileName
chtObj.Delete
'Reset Zoom to innitial zoom of the image.
ActiveWindow.Zoom = 100
End Sub
Based on the link provided by Philip I got this to working
Worksheets("Final Analysis Sheet").Range("A4:G112").CopyPicture xlScreen, xlBitmap
Application.DisplayAlerts = False
Set oCht = Charts.Add
With oCht
.Paste
.Export Filename:="C:\FTPDailycheck\TodaysImages\SavedRange.jpg", Filtername:="JPG"
.Delete
End With

- 924
- 1
- 12
- 27
There's a more direct way to export a range image to a file, without the need to create a temporary chart. It makes use of PowerShell to save the clipboard as a .png file.
Copying the range to the clipboard as an image is straightforward, using the vba CopyPicture command, as shown in some of the other answers.
A PowerShell script to save the clipboard requires only two lines, as noted by thom schumacher in Save Image from clipboard using PowerShell.
VBA can launch a PowerShell script and wait for it to complete, as noted by Asam in Wait for shell command to complete.
Putting these ideas together, we get the following routine. I've tested this only under Windows 10 using the Office 2010 version of Excel. Note that there's an internal constant AidDebugging which can be set to True to provide additional feedback about the execution of the routine.
Option Explicit
' This routine copies the bitmap image of a range of cells to a .png file.
' Input arguments:
' RangeRef -- the range to be copied. This must be passed as a range object, not as the name
' or address of the range.
' Destination -- the name (including path if necessary) of the file to be created, ending in
' the extension ".png". It will be overwritten without warning if it exists.
' TempFile -- the name (including path if necessary) of a temporary script file which will be
' created and destroyed. If this is not supplied, file "RangeToPNG.ps1" will be
' created in the default folder. If AidDebugging is set to True, then this file
' will not be deleted, so it can be inspected for debugging.
' If the PowerShell script file cannot be launched, then this routine will display an error message.
' However, if the script can be launched but cannot create the resulting file, this script cannot
' detect that. To diagnose the problem, change AidDebugging from False to True and inspect the
' PowerShell output, which will remain in view until you close its window.
Public Sub RangeToPNG(RangeRef As Range, Destination As String, _
Optional TempFile As String = "RangeToPNG.ps1")
Dim WSH As Object
Dim PSCommand As String
Dim WindowStyle As Integer
Dim ErrorCode As Integer
Const WaitOnReturn = True
Const AidDebugging = False ' provide extra feedback about this routine's execution
' Create a little PowerShell script to save the clipboard as a .png file
' The script is based on a version found on September 13, 2020 at
' https://stackoverflow.com/questions/55215482/save-image-from-clipboard-using-powershell
Open TempFile For Output As #1
If (AidDebugging) Then ' output some extra feedback
Print #1, "Set-PSDebug -Trace 1" ' optional -- aids debugging
End If
Print #1, "$img = get-clipboard -format image"
Print #1, "$img.save(""" & Destination & """)"
If (AidDebugging) Then ' leave the PowerShell execution record on the screen for review
Print #1, "Read-Host -Prompt ""Press <Enter> to continue"" "
WindowStyle = 1 ' display window to aid debugging
Else
WindowStyle = 0 ' hide window
End If
Close #1
' Copy the desired range of cells to the clipboard as a bitmap image
RangeRef.CopyPicture xlScreen, xlBitmap
' Execute the PowerShell script
PSCommand = "POWERSHELL.exe -ExecutionPolicy Bypass -file """ & TempFile & """ "
Set WSH = VBA.CreateObject("WScript.Shell")
ErrorCode = WSH.Run(PSCommand, WindowStyle, WaitOnReturn)
If (ErrorCode <> 0) Then
MsgBox "The attempt to run a PowerShell script to save a range " & _
"as a .png file failed -- error code " & ErrorCode
End If
If (Not AidDebugging) Then
' Delete the script file, unless it might be useful for debugging
Kill TempFile
End If
End Sub
' Here's an example which tests the routine above.
Sub Test()
RangeToPNG Worksheets("Sheet1").Range("A1:F13"), "E:\Temp\ExportTest.png"
End Sub

- 109
- 1
- 5
-
Thank you for this. got it works with protected sheet while others cant. And the results for image high quality too. – amein Nov 06 '20 at 06:05
-
BTW, why does the script remove a little bit of left side portion from the saved image? Example like this: sheet view - https://i.imgur.com/HFrRxod.png. Saved image become: https://i.imgur.com/YWJFjGO.png. – amein Nov 06 '20 at 06:28
-
@amein -- I assume the answer to "why ...?" is "it's a Microsoft bug". I've noticed that too -- exterior cell borders are sometimes not included in the image. I work around it by adding very narrow, empty rows and columns around the target range and then outputting the slightly enlarged range, including the empty parts, as an image. That causes all of the interesting cell borders to become interior borders, so they're part of the final image. – Frogrammer-Analyst Nov 07 '20 at 17:07
-