Уменьшить размер файла для диаграмм, вставленных из Excel в Word

Я создавал отчеты, копируя некоторые диаграммы и данные из документа Excel в документ Word. Я вставляю данные в элемент управления содержимым, поэтому использую ChartObject.CopyPicture в Excel и ContentControl.Range.Paste в словах. Это делается в цикле:

Set ws = ThisWorkbook.Worksheets("Charts")
With ws
For Each cc In wordDocument.ContentControls

    If cc.Range.InlineShapes.Count > 0 Then
        scaleHeight = cc.Range.InlineShapes(1).scaleHeight
        scaleWidth = cc.Range.InlineShapes(1).scaleWidth
        cc.Range.InlineShapes(1).Delete
        .ChartObjects(cc.Tag).CopyPicture Appearance:=xlScreen, Format:=xlPicture
        cc.Range.Paste
        cc.Range.InlineShapes(1).scaleHeight = scaleHeight
        cc.Range.InlineShapes(1).scaleWidth = scaleWidth
    ElseIf ...
Next cc
End With

При создании этих отчетов с помощью Office 2007 были получены файлы размером около 6 МБ, но при их создании (с использованием того же листа и документа) в Office 2010 размер файла был примерно в 10 раз больше.

После распаковки docx я обнаружил, что дополнительный размер исходит от файлов emf, которые соответствуют диаграммам, вставленным с помощью VBA. Если раньше они составляли от 360 до 900 Кбайт, то теперь они составляют 5-18 Мбайт. И графика заметно не лучше.

Более того, похоже, что это связано со стилем диаграммы. Я создал новую таблицу и вставил 7 точек данных и соответствующую двумерную круговую диаграмму. Со стилем по умолчанию он копируется как emf 79 КБ, а со стилем 26 копируется как emf 10 МБ. Когда я использовал Office 2007, диаграмма копировалась как emf 700 КБ. Это код:

Sub CopyAndPaste()
    ThisWorkbook.Worksheets("Charts").ChartObjects("Chart 1").CopyPicture Appearance:=xlScreen, Format:=xlPicture
    GetObject(, Class:="Word.Application").ActiveDocument.Range.Paste
End Sub

Я могу CopyPicture с форматом xlBitmap, и хотя он несколько меньше, он больше, чем ЭДС, созданный Office 2007, и заметно худшего качества. Есть ли другие варианты уменьшения размера файла? В идеале я хотел бы создать файл с тем же разрешением для диаграмм, что и в Office 2007. Есть ли способ, который использует только VBA (без изменения диаграмм в электронной таблице)? В любом случае я могу легко скопировать как объект, не связывая документы?


person Steve Clanton    schedule 22.05.2014    source источник
comment
В Excel 2010 внесены некоторые изменения в диаграммы: см. этот блог, хотя ни одна из них не выделяется как очевидная причина. Вы используете CopyPicture Appearance:=xlPrinter, поскольку это дает файлы большего размера, чем xlScreen? В противном случае не могли бы вы подробнее рассказать о диаграммах (какой тип, какое форматирование, сколько точек данных)?   -  person aucuparia    schedule 28.05.2014
comment
Как насчет того, чтобы экспортировать диаграмму в более эффективный формат (например, ActiveChart.Export "C:\My Charts\SpecialChart.png"), а затем импортировать .png в Word? Размер файла должен быть приемлемым.   -  person Rick supports Monica    schedule 28.05.2014
comment
Не могли бы вы добавить реальный код, который вы используете? Включаете ли вы ссылки на данные при вставке?   -  person Adach1979    schedule 28.05.2014
comment
Я не хочу, чтобы таблица и документ были связаны. При вставке нет ссылки, только файл emf в папке мультимедиа docx.   -  person Steve Clanton    schedule 28.05.2014
comment
Я использую xlScreen, и в графиках нет ничего особенного. Ни один из них не использует более двух десятков точек данных, а большинство - менее 15.   -  person Steve Clanton    schedule 29.05.2014
comment
Я думаю, это связано со стилем диаграммы, то есть стилем 26.   -  person Steve Clanton    schedule 29.05.2014
comment
Какой тип диаграммы? В моем тестировании размеры файлов были приемлемыми, за исключением диаграмм с изогнутыми 3D-объектами (из которых 3D-пузырь был наихудшим). Я предполагаю, что способ, которым Excel 2010 отображает их в метафайл, очень неэффективен по сравнению с 2007 годом.   -  person aucuparia    schedule 29.05.2014
comment
Кто-то еще с этой проблемой (решение не очень хорошее - скопируйте через PDF)   -  person aucuparia    schedule 29.05.2014
comment
Я создал новую таблицу и вставил 7 точек данных и соответствующую двумерную круговую диаграмму. Со стилем по умолчанию он копируется как emf 79 КБ, а со стилем 26 копируется как emf 10 МБ.   -  person Steve Clanton    schedule 29.05.2014
comment
Похоже, что причина увеличенного размера файла связана с изображением с высоким разрешением, сохраненным в дополнение к файлу emf: eknowinf.wordpress.com/2011/12/08/   -  person MP24    schedule 03.06.2014
comment
Вы пробовали поиграть с параметрами Размер и качество изображения в разделе Параметры Word ›Дополнительно?   -  person MP24    schedule 03.06.2014
comment
@ MP24 Спасибо за предложение. Я пробовал, и изменения вроде не меняют размер эдс. Я мог бы попробовать это в сочетании с импортом файла как png или bmp, а не вставкой. Однако я до некоторой степени убедился, что мне нужно будет создать объект диаграммы в словах в качестве окончательного решения.   -  person Steve Clanton    schedule 03.06.2014
comment
Другое предложение - использовать простые стили только, поскольку сложные стили будут создавать тысячи небольших объектов: answers.microsoft.com/en-us/office/forum/office_2010-excel/   -  person MP24    schedule 03.06.2014
comment
Не видел, чтобы это упоминалось в комментариях, и не уверен, повлияет ли это на размер экспортируемого изображения, но перед экспортом изображения диаграммы из Excel попробуйте запустить опцию Сжать изображения. Это можно сделать с помощью кода с помощью SendKeys или просто с минимальным взаимодействием с пользователем. Я использую нечто подобное, когда мое изображение помещается на лист Excel ... ActiveSheet.DrawingObjects.Select [NEWLINE] MsgBox "Dont forget to tick the Apply to Selected Pictures box", vbOKOnly + vbInformation [NEWLINE] Application.CommandBars.ExecuteMso "PicturesCompress"   -  person bmgh1985    schedule 06.06.2014
comment
Как насчет использования .PasteSpecial Link: = False, DataType: = wdPasteEnhancedMetafile вместо прямого .Paste?   -  person variant    schedule 10.06.2014


Ответы (3)


«Это старый код, сэр, но он проверяется».

Это старый вопрос, и у меня есть еще более старое (возможное) решение: вы можете сжать файлы .EMF как .EMZ, сжав их. Это уменьшит размер файла при сохранении качества изображения.

На VB6 я использовал zlib.dll и приведенный ниже код. Я переименовал имена функций на английский язык, но все комментарии оставил на португальском:

Option Explicit

' Declaração das interfaces com a ZLIB
Private Declare Function gzopen     Lib "zlib.dll" (ByVal file As String, ByVal mode As String) As Long
Private Declare Function gzwrite    Lib "zlib.dll" (ByVal file As Long, ByRef uncompr As Byte, ByVal uncomprLen As Long) As Long
Private Declare Function gzclose    Lib "zlib.dll" (ByVal file As Long) As Long
Private Declare Function Compress   Lib "zlib.dll" Alias "compress" (ByRef dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long) As Long
Private Declare Function Uncompress Lib "zlib.dll" Alias "uncompress" (ByRef dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long) As Long

' Ler o conteúdo de um arquivo
Public Function FileRead(ByVal strNomeArquivo As String) As Byte()

    Dim intHandle     As Integer
    Dim lngTamanho    As Long
    Dim bytConteudo() As Byte

    On Error GoTo FileReadError

    ' Abrir o documento indicado
    intHandle = FreeFile
    Open strNomeArquivo For Binary Access Read As intHandle

    ' Obter o tamanho do arquivo
    lngTamanho = LOF(intHandle)
    ReDim bytConteudo(lngTamanho)

    ' Obter o conteúdo e liberar o arquivo
    Get intHandle, , bytConteudo()
    Close intHandle

    FileRead = bytConteudo

    On Error GoTo 0
    Exit Function

FileReadError:

    objLogger.GravarEvento "modZLib.FileRead: " & Err.Description & " (" & Err.Number & " - " & Err.Source & ")", logTipoEvento.Erro

End Function

'Compactar um arquivo com o padrão gzip
Public Sub FileCompress(ByVal strArquivoOrigem As String, ByVal strArquivoDestino As String)

    Dim gzFile        As Long
    Dim bytConteudo() As Byte

    On Error GoTo FileCompressError

    ' Ler o conteúdo do arquivo
    bytConteudo = FileRead(strArquivoOrigem)

    ' Compactar o conteúdo
    gzFile = gzopen(strArquivoDestino, "wb")
    gzwrite gzFile, bytConteudo(0), UBound(bytConteudo)
    gzclose gzFile

    On Error GoTo 0
    Exit Sub

FileCompressError:

    objLogger.GravarEvento "modZLib.FileCompress:" & Err.Description & " (" & Err.Number & " - " & Err.Source & ")", logTipoEvento.Erro

End Sub
person Rubens Farias    schedule 24.04.2015
comment
Как бы я ни хотел, чтобы было что-то лучше, это лучше, чем все, что я нашел. Я считаю, что это лучшее, что можно сделать. Спасибо. - person Steve Clanton; 27.04.2015

Я уже сталкивался с чем-то подобным раньше

Вместо использования

Document.Range.Paste

Попробуйте использовать

Document.Range.PasteSpecial DataType:= wdPasteMetafilePicture

or

Document.Range.PasteSpecial DataType:= wdPasteShape

При этом диаграмма будет вставлена ​​как изображение или рисунок, а не как встроенный объект Excel.

Аналогично использованию "Специальная вставка ..." из меню.

Доступны другие типы данных

http://msdn.microsoft.com/en-us/library/office/aa220339(v=office.11).aspx

person Tom Page    schedule 22.08.2014

Возможно, это происходит из-за неправильного масштабирования файлов .emf. Использование PNG может решить проблему с размером (как указано в комментариях выше), но по-прежнему будет проблемой, потому что это не будут векторные изображения.

Если вы используете AddPicture для добавления изображений в свой файл, то на следующей странице показано решение, в котором вы можете изменить масштаб и уменьшить размер файла по умолчанию. Так что это может решить вашу проблему.

http://social.msdn.microsoft.com/Forums/en-US/f1c9c753-77fd-4c17-9ca8-02908debca5d/emf-file-added-using-the-addpicture-method-looks-bigger-in-excel-20072010-vs-excel-2003?forum=exceldev

person hnk    schedule 01.07.2014