Syl*_*rag 6 excel charts vba export
我正在尝试使用 VBA 以 SVG 格式导出 Excel 图表。
Set objChrt = ActiveChart.Parent
objChrt.Activate
Set curChart = objChrt.Chart
curChart.Export fileName:=fileName, FilterName:="SVG"
Run Code Online (Sandbox Code Playgroud)
如果我用“PNG”替换“SVG”,则导出完全按预期工作并生成有效的 PNG 文件。但是,“SVG”会生成一个空文件。(手动,有一个选项可以在 Excel 365 中另存为 SVG,因此存在导出过滤器)。
根据文档,Filtername 是“图形过滤器在注册表中出现的与语言无关的名称。”,但我在注册表中找不到类似的东西,无论哪种方式,都很难想象 SVG 过滤器名称被命名为“SVG”以外的任何名称。
有没有办法使用 VBA 以 SVG 格式导出图表?
注意:还有一个关于 Chart.export 生成空文件的问题,修复是ChartObject.Activate
在导出之前使用。这个问题是不同的,因为代码在“PNG”下正常工作,但在“SVG”下失败(所以这不是与激活或可见性相关的问题)。推荐的修复也不起作用。
将图表复制到剪贴板时,Excel 会添加许多不同的剪贴板格式。自2011 版( Application.Build >= 13426
) 起,现在包括“image/svg+xml”。
因此,我们所要做的就是在剪贴板上找到该格式并将其保存到文件中。事实证明这相当烦人。
Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr
Private Declare PtrSafe Function EnumClipboardFormats Lib "user32" (ByVal wFormat As Long) As Long
Private Declare PtrSafe Function GetClipboardFormatName Lib "user32" _
Alias "GetClipboardFormatNameW" _
(ByVal wFormat As Long, _
ByVal lpString As LongPtr, _
ByVal nMaxCount As Integer) As Integer
Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
Private Declare PtrSafe Function GlobalUnlock Lib "Kernel32" (ByVal hMem As LongPtr) As LongPtr
Private Declare PtrSafe Function GlobalLock Lib "Kernel32" (ByVal hMem As LongPtr) As LongPtr
Private Declare PtrSafe Function GlobalSize Lib "Kernel32" (ByVal hMem As LongPtr) As LongPtr
Private Declare PtrSafe Function CreateFile Lib "Kernel32" _
Alias "CreateFileA" (ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As LongPtr, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As LongPtr) As LongPtr
Private Declare PtrSafe Function WriteFile Lib "Kernel32" _
(ByVal hFile As LongPtr, _
ByVal lpBuffer As LongPtr, _
ByVal nNumberOfBytesToWrite As Long, _
ByRef lpNumberOfBytesWritten As Long, _
ByVal lpOverlapped As LongPtr) As Long
Private Declare PtrSafe Function CloseHandle Lib "Kernel32" (ByVal hObject As LongPtr) As Long
Sub SaveClipboard(formatName As String, filename As String)
Dim fmtName As String
Dim fmt As Long
Dim length As Long
Dim wrote As Long
Dim data As LongPtr
Dim fileHandle As LongPtr
Dim content As LongPtr
Dim ret As Long
If OpenClipboard(ActiveWindow.hwnd) = 0 Then
Exit Sub
End If
fmt = 0
Do
fmt = EnumClipboardFormats(fmt)
If fmt = 0 Then Exit Do
fmtName = String$(255, vbNullChar)
length = GetClipboardFormatName(fmt, StrPtr(fmtName), 255)
If length <> 0 And Left(fmtName, length) = formatName Then
data = GetClipboardData(fmt)
length = CLng(GlobalSize(data))
content = GlobalLock(data)
' use win32 api file handling to avoid copying buffers
fileHandle = CreateFile(filename, &H120089 Or &H120116, 0, 0, 2, 0, 0)
ret = WriteFile(fileHandle, content, length, wrote, 0)
CloseHandle fileHandle
GlobalUnlock data
Exit Do
End If
Loop
CloseClipboard
If fmt = 0 Then
MsgBox "Did not find clipboard format " & formatName
Exit Sub
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
然后只需复制图表并保存 svg;
shape.Copy
SaveClipboard "image/svg+xml", "C:\temp\output.svg"
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
762 次 |
最近记录: |