Рабочее решение для изменения размеров диаграмм в PPTX

Предыстория

В предыдущей статье мы объяснили, как создать диаграмму Excel с использованием Aspose.Cells для C++ и далее встроить эту диаграмму в презентацию PowerPoint с использованием Aspose.Slides для C++. Чтобы учесть проблему изменения объекта, мы назначили изображение диаграммы для OLE-объекта-рамки диаграммы. В выходной презентации, когда мы дважды щелкаем на OLE-рамку, показывающую изображение диаграммы, диаграмма Excel активируется. Конечные пользователи могут вносить любые желаемые изменения в фактическую рабочую книгу Excel, а затем вернуться к соответствующему слайду, щелкнув вне активной рабочей книги Excel. Размер OLE-рамки изменится, когда пользователь вернется к слайду. Фактор изменения размеров будет отличаться для различных размеров OLE-рамки и встроенной рабочей книги Excel.

Причина изменения размеров

Поскольку рабочая книга Excel имеет свой собственный размер окна, она пытается сохранить свой первоначальный размер во время первого активации. С другой стороны, OLE-рамка будет иметь свой собственный размер. Согласно данным Microsoft, при активации рабочей книги Excel Excel и PowerPoint согласовывают размер и обеспечивают его правильные пропорции в рамках операции встраивания. На основе различий в размере окон Excel и размерах / позиции OLE-рамки происходит изменение размеров.

Рабочее решение

Существуют два возможных сценария создания презентаций PowerPoint с использованием Aspose.Slides для C++.

Сценарий 1: Создать презентацию на основе существующего шаблона.

Сценарий 2: Создать презентацию с нуля.

Решение, которое мы предоставим здесь, будет действовать для обоих сценариев. Основой всех подходов к решению будет одно и то же: Размер окна встроенного OLE-объекта должен быть таким же, как и у OLE-рамки в слайде PowerPoint. Теперь мы обсудим два подхода к решению.

Первый подход

В этом подходе мы узнаем, как установить размер окна встроенной рабочей книги Excel, равный размеру OLE-рамки в слайде PowerPoint.

Сценарий 1

Допустим, мы определили шаблон и желаем создать презентации на основе этого шаблона. Предположим, что в шаблоне есть какая-то фигура на индексе 2, где мы хотим разместить OLE-рамку с встроенной рабочей книгой Excel. В этом сценарии размер OLE-рамки будет считаться предопределенным (это размер фигуры на индексе 2 в шаблоне). Все, что нам нужно сделать: установить размер окна рабочей книги, равный размеру фигуры. Следующий фрагмент кода будет служить этой цели:

System::SharedPtr<System::IO::MemoryStream> ToSlidesMemoryStream(intrusive_ptr<Aspose::Cells::Systems::IO::MemoryStream> inputStream)
{
    auto outputBuffer = System::MakeArray<uint8_t>(inputStream->GetLength(), inputStream->GetBuffer()->ArrayPoint());
    auto outputStream = System::MakeObject<System::IO::MemoryStream>(outputBuffer);

    return outputStream;
}
// определить размер диаграммы с окном 
chart->SetSizeWithWindow(true);

auto shape = slide->get_Shapes()->idx_get(2);

// установить ширину окна рабочей книги в дюймах (разделить на 72, так как PowerPoint использует 
// 72 пикселя / дюйм)
wb->GetISettings()->SetWindowWidthInch(shape->get_Width() / 72.f);

// установить высоту окна рабочей книги в дюймах
wb->GetISettings()->SetWindowHeightInch(shape->get_Height() / 72.f);

// Инициализировать MemoryStream
System::SharedPtr<System::IO::MemoryStream> ms = ToSlidesMemoryStream3(wb->SaveToStream());

System::SharedPtr<IOleEmbeddedDataInfo> dataInfo = System::MakeObject<OleEmbeddedDataInfo>(ms->ToArray(), u"xls");

// Создать OLE-рамку с встроенной Excel
System::SharedPtr<IOleObjectFrame> objFrame = slide->get_Shapes()->AddOleObjectFrame(
	shape->get_X(), 
	shape->get_Y(), 
	shape->get_Width(), 
	shape->get_Height(),
	dataInfo);

Сценарий 2

Допустим, мы хотим создать презентацию с нуля и желаем OLE-рамку любого размера с встроенной рабочей книгой Excel. В следующем фрагменте кода мы создали OLE-рамку высотой 4 дюйма и шириной 9,5 дюйма в слайде по оси x=0,5 дюйма и оси y=1 дюйм. Далее мы установили эквивалентный размер окна рабочей книги Excel, т.е.: высота 4 дюйма и ширина 9,5 дюйма.

// Наша желаемая высота
int32_t desiredHeight = 288; // 4 дюйма (4 * 72)

// Наша желаемая ширина
int32_t desiredWidth = 684; // 9,5 дюйма (9,5 * 72)

// определить размер диаграммы с окном 
chart->SetSizeWithWindow(true);

// установить ширину окна рабочей книги в дюймах
wb->GetISettings()->SetWindowWidthInch(desiredWidth / 72.f);

// установить высоту окна рабочей книги в дюймах
wb->GetISettings()->SetWindowHeightInch(desiredHeight / 72.f);

// Инициализировать MemoryStream
System::SharedPtr<System::IO::MemoryStream> ms = ToSlidesMemoryStream(wb->SaveToStream());

System::SharedPtr<IOleEmbeddedDataInfo> dataInfo = System::MakeObject<OleEmbeddedDataInfo>(ms->ToArray(), u"xls");

// Создать OLE-рамку с встроенной Excel
System::SharedPtr<IOleObjectFrame> objFrame = slide->get_Shapes()->AddOleObjectFrame(
	36.0f,
	72.0f, 
	desiredWidth, 
	desiredHeight,
	dataInfo);

Второй подход

В этом подходе мы узнаем, как установить размер диаграммы, находящейся в встроенной рабочей книге Excel, равным размеру OLE-рамки в слайде PowerPoint. Этот подход полезен, когда размер диаграммы заранее известен и никогда не изменится.

Сценарий 1

Допустим, мы определили шаблон и желаем создать презентации на основе этого шаблона. Предположим, что в шаблоне есть какая-то фигура на индексе 2, где мы хотим разместить OLE-рамку с встроенной рабочей книгой Excel. В этом сценарии размер OLE-рамки будет считаться предопределенным (это размер фигуры на индексе 2 в шаблоне). Все, что нам нужно сделать: установить размер диаграммы в рабочей книге, равный размеру фигуры. Следующий фрагмент кода будет служить этой цели:

// определить размер диаграммы без окна 
chart->SetSizeWithWindow(false);

auto shape = slide->get_Shapes()->idx_get(2);

// установить ширину диаграммы в пикселях (умножить на 96, так как Excel использует 96 пикселей на дюйм)    
chart->GetIChartObject()->SetWidth((int32_t)(shape->get_Width() / 72.f * 96.f));

// установить высоту диаграммы в пикселях
chart->GetIChartObject()->SetHeight((int32_t)(shape->get_Height() / 72.f) * 96.f);

// Определить размер печати диаграммы
chart->SetPrintSize(Aspose::Cells::PrintSizeType::PrintSizeType_Custom);

// Инициализировать MemoryStream
System::SharedPtr<System::IO::MemoryStream> ms = ToSlidesMemoryStream(wb->SaveToStream());

System::SharedPtr<IOleEmbeddedDataInfo> dataInfo = System::MakeObject<OleEmbeddedDataInfo>(ms->ToArray(), u"xls");

// Создать OLE-рамку с встроенной Excel
System::SharedPtr<IOleObjectFrame> objFrame = slide->get_Shapes()->AddOleObjectFrame(
	shape->get_X(), 
	shape->get_Y(), 
	shape->get_Width(),
	shape->get_Height(),
	dataInfo);

Сценарий 2

Допустим, мы хотим создать презентацию с нуля и желаем OLE-рамку любого размера с встроенной рабочей книгой Excel. В следующем фрагменте кода мы создали OLE-рамку высотой 4 дюйма и шириной 9,5 дюйма в слайде по оси x=0,5 дюйма и оси y=1 дюйм. Далее мы установили эквивалентный размер диаграммы, т.е.: высота 4 дюйма и ширина 9,5 дюйма.

// Наша желаемая высота
int32_t desiredHeight = 288; // 4 дюйма (4 * 576)

// Наша желаемая ширина
int32_t desiredWidth = 684; // 9,5 дюйма(9,5 * 576)

// определить размер диаграммы без окна 
chart->SetSizeWithWindow(false);

// установить ширину диаграммы в пикселях    
chart->GetIChartObject()->SetWidth((int32_t)((desiredWidth / 72.f) * 96.f));

// установить высоту диаграммы в пикселях    
chart->GetIChartObject()->SetHeight((int32_t)((desiredHeight / 72.f) * 96.f));

// Инициализировать MemoryStream
System::SharedPtr<System::IO::MemoryStream> ms = ToSlidesMemoryStream(wb->SaveToStream());

System::SharedPtr<IOleEmbeddedDataInfo> dataInfo = System::MakeObject<OleEmbeddedDataInfo>(ms->ToArray(), u"xls");

// Создать OLE-рамку с встроенной Excel
System::SharedPtr<IOleObjectFrame> objFrame = slide->get_Shapes()->AddOleObjectFrame(
	36.0f, 
	72.0f, 
	desiredWidth, 
	desiredHeight,
	dataInfo);

Заключение

Связанные разделы

Создание и встраивание диаграммы Excel в виде OLE-объекта в презентации