Rozwiązanie działające dla zmiany rozmiaru arkusza
Uwaga
Arkusze Excel osadzone jako obiekty OLE w prezentacji PowerPoint przy użyciu komponentów Aspose mogą nieoczekiwanie zmieniać rozmiar po pierwszej aktywacji. To zachowanie powoduje zauważalną różnicę wizualną między obiektem OLE przed i po aktywacji. Ten artykuł wyjaśnia problem i opisuje dwa sposoby jego rozwiązania.Tło
W artykule Zarządzanie OLE wyjaśniliśmy, jak dodać ramkę OLE do prezentacji PowerPoint przy użyciu Aspose.Slides for PHP via Java. Aby rozwiązać problem podglądu obiektu, przypisaliśmy obraz wybranego obszaru arkusza do ramki obiektu OLE. W wyjściowej prezentacji, po dwukrotnym kliknięciu ramki obiektu OLE wyświetlającej obraz arkusza, aktywowany jest skoroszyt Excel. Użytkownicy mogą wprowadzić dowolne zmiany w rzeczywistym skoroszycie Excel, a następnie powrócić do slajdu, klikając poza aktywowanym skoroszytem Excel. Rozmiar ramki obiektu OLE zmieni się, gdy użytkownik wróci do slajdu. Współczynnik zmiany rozmiaru będzie się różnił w zależności od rozmiaru ramki obiektu OLE i osadzonego skoroszytu Excel.
Przyczyna zmiany rozmiaru
Ponieważ skoroszyt Excel ma własny rozmiar okna, próbuje zachować swój pierwotny rozmiar przy pierwszej aktywacji. Z drugiej strony ramka obiektu OLE ma własny rozmiar. Według Microsoftu, gdy skoroszyt Excel jest aktywowany, Excel i PowerPoint negocjują rozmiar, aby zapewnić zachowanie prawidłowych proporcji jako części procesu osadzania. Zmiana rozmiaru zachodzi w oparciu o różnice pomiędzy rozmiarem okna Excel a rozmiarem i położeniem ramki obiektu OLE.
Rozwiązanie działające
Istnieją dwa możliwe rozwiązania, aby uniknąć efektu zmiany rozmiaru.
- Skaluj ramkę OLE w prezentacji PowerPoint, aby dopasować ją do całkowitej wysokości i szerokości wybranych wierszy i kolumn.
- Utrzymaj stały rozmiar ramki OLE i skaluj wybrane wiersze oraz kolumny, aby pasowały do niej.
Skalowanie rozmiaru ramki OLE
To podejście ustawia rozmiar ramki OLE tak, aby odpowiadał całkowitej wysokości i szerokości wybranych wierszy i kolumn w osadzonym arkuszu Excel.
Przykład ładuje istniejący skoroszyt Excel i wybiera pierwsze 10 wierszy oraz 13 kolumn pierwszego arkusza przy użyciu indeksów zerowych. WorksheetCollection::setOleSize definiuje wyświetlany zakres. Podgląd jest renderowany w 96 DPI, a jego wymiary w pikselach są konwertowane na punkty przy użyciu 72 punktów na cal. ShapeCollection::addOleObjectFrame osadza zmodyfikowany skoroszyt w ramce o tych wymiarach. Podgląd jest przypisany za pomocą OleObjectFrame::getSubstitutePictureFormat w celu zastąpienia tekstu zastępczego „EMBEDDED OLE OBJECT” w zapisanej prezentacji.
use aspose\cells\SaveFormat as CellsSaveFormat;
use aspose\cells\Workbook;
use aspose\slides\Images;
use aspose\slides\OleEmbeddedDataInfo;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
use Java as JavaObject;
$workbook = new Workbook("sample.xlsx");
try {
$worksheet = $workbook->getWorksheets()->get(0);
$startRow = 0;
$rowCount = 10;
$startColumn = 0;
$columnCount = 13;
$lastRow = $startRow + $rowCount - 1;
$lastColumn = $startColumn + $columnCount - 1;
$workbook->getWorksheets()->setOleSize($startRow, $lastRow, $startColumn, $lastColumn);
$cellRange = $worksheet->getCells()->createRange($startRow, $startColumn, $rowCount, $columnCount);
$imageResolution = 96;
$imageStream = CreateOleImage($cellRange, $imageResolution);
// Osadź zmodyfikowany skoroszyt i zachowaj dane binarne w tablicach bajtów Javy.
$workbookStream = new JavaObject("java.io.ByteArrayOutputStream");
$workbook->save($workbookStream, CellsSaveFormat::XLSX);
$workbookBytes = $workbookStream->toByteArray();
$image = Images::fromStream($imageStream);
try {
$frameWidth = java_values($image->getWidth()) * 72.0 / $imageResolution;
$frameHeight = java_values($image->getHeight()) * 72.0 / $imageResolution;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$dataInfo = new OleEmbeddedDataInfo($workbookBytes, "xlsx");
$oleFrame = $slide->getShapes()->addOleObjectFrame(10, 10, $frameWidth, $frameHeight, $dataInfo);
$previewImage = $presentation->getImages()->addImage($image);
$oleFrame->getSubstitutePictureFormat()->getPicture()->setImage($previewImage);
$oleFrame->setObjectIcon(false);
$presentation->save("output.pptx", SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
} finally {
$image->dispose();
$imageStream->close();
}
} finally {
$workbook->dispose();
}
Pomocniczy podgląd ustawia PageSetup::setPrintArea na wybrany zakres i usuwa marginesy, nagłówki oraz stopki. Z włączoną opcją ImageOrPrintOptions::setOnlyArea, SheetRender::toImage renderuje zakres jako obraz PNG. Pomocnik zwraca nowy strumień wejściowy zawierający obraz PNG, ustawiony na jego początek, gotowy do użycia w prezentacji.
use aspose\cells\ImageOrPrintOptions;
use aspose\cells\ImageType;
use aspose\cells\SheetRender;
use Java as JavaObject;
function CreateOleImage($cellRange, $imageResolution) {
$pageSetup = $cellRange->getWorksheet()->getPageSetup();
$pageSetup->setPrintArea($cellRange->getAddress());
$pageSetup->setLeftMargin(0);
$pageSetup->setRightMargin(0);
$pageSetup->setTopMargin(0);
$pageSetup->setBottomMargin(0);
$pageSetup->clearHeaderFooter();
$imageOptions = new ImageOrPrintOptions();
$imageOptions->setImageType(ImageType::PNG);
$imageOptions->setVerticalResolution($imageResolution);
$imageOptions->setHorizontalResolution($imageResolution);
$imageOptions->setOnePagePerSheet(true);
$imageOptions->setOnlyArea(true);
$worksheet = $cellRange->getWorksheet();
$sheetRender = new SheetRender($worksheet, $imageOptions);
$imageStream = new JavaObject("java.io.ByteArrayOutputStream");
$sheetRender->toImage(0, $imageStream);
$imageBytes = $imageStream->toByteArray();
return new JavaObject("java.io.ByteArrayInputStream", $imageBytes);
}
Skalowanie rozmiaru zakresu komórek
To podejście skaluje wysokości wybranych wierszy oraz szerokości wybranych kolumn, aby dopasować je do niestandardowego rozmiaru ramki OLE.
Przykład ładuje istniejący skoroszyt Excel i wybiera pierwsze 10 wierszy oraz 13 kolumn pierwszego arkusza przy użyciu indeksów zerowych. WorksheetCollection::setOleSize definiuje wyświetlany zakres, a poniższy pomocnik skaluje ten zakres, aby pasował do ramki o szerokości 400 punktów i wysokości 100 punktów. Po zapisaniu zmodyfikowanego skoroszytu do strumienia, ShapeCollection::addOleObjectFrame osadza go w określonym rozmiarze. Podgląd renderowany w 96 DPI jest przypisany za pomocą OleObjectFrame::getSubstitutePictureFormat, dzięki czemu zapisana prezentacja wyświetla wybrane komórki zamiast domyślnego elementu zastępczego.
use aspose\cells\SaveFormat as CellsSaveFormat;
use aspose\cells\Workbook;
use aspose\slides\Images;
use aspose\slides\OleEmbeddedDataInfo;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
use Java as JavaObject;
$workbook = new Workbook("sample.xlsx");
try {
$worksheet = $workbook->getWorksheets()->get(0);
$startRow = 0;
$rowCount = 10;
$startColumn = 0;
$columnCount = 13;
$lastRow = $startRow + $rowCount - 1;
$lastColumn = $startColumn + $columnCount - 1;
$workbook->getWorksheets()->setOleSize($startRow, $lastRow, $startColumn, $lastColumn);
$cellRange = $worksheet->getCells()->createRange($startRow, $startColumn, $rowCount, $columnCount);
$frameWidth = 400;
$frameHeight = 100;
ScaleCellRange($cellRange, $frameWidth, $frameHeight);
$imageResolution = 96;
$imageStream = CreateOleImage($cellRange, $imageResolution);
// Osadź zmodyfikowany skoroszyt i zachowaj dane binarne w tablicach bajtów Javy.
$workbookStream = new JavaObject("java.io.ByteArrayOutputStream");
$workbook->save($workbookStream, CellsSaveFormat::XLSX);
$workbookBytes = $workbookStream->toByteArray();
$image = Images::fromStream($imageStream);
try {
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$dataInfo = new OleEmbeddedDataInfo($workbookBytes, "xlsx");
$oleFrame = $slide->getShapes()->addOleObjectFrame(10, 10, $frameWidth, $frameHeight, $dataInfo);
$previewImage = $presentation->getImages()->addImage($image);
$oleFrame->getSubstitutePictureFormat()->getPicture()->setImage($previewImage);
$oleFrame->setObjectIcon(false);
$presentation->save("output.pptx", SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
} finally {
$image->dispose();
$imageStream->close();
}
} finally {
$workbook->dispose();
}
Pomocnik skalowania oblicza oddzielne współczynniki szerokości i wysokości dla wybranego zakresu, zachowując względne szerokości jego kolumn oraz względne wysokości jego wierszy. Przed zastosowaniem ich za pomocą Cells::setColumnWidthInch i Cells::setRowHeightInch, przelicza obliczone wymiary z punktów na cale. Wybrany zakres musi mieć niezerową szerokość i wysokość.
use aspose\cells\CellsUnitType;
// Szerokość i wysokość są oczekiwanymi wymiarami zakresu komórek w punktach.
function ScaleCellRange($cellRange, $width, $height) {
$rangeWidth = java_values($cellRange->getWidth());
$rangeHeight = java_values($cellRange->getHeight());
$cells = $cellRange->getWorksheet()->getCells();
$columnCount = java_values($cellRange->getColumnCount());
$rowCount = java_values($cellRange->getRowCount());
$firstColumn = java_values($cellRange->getFirstColumn());
$firstRow = java_values($cellRange->getFirstRow());
for ($i = 0; $i < $columnCount; $i++) {
$columnIndex = $firstColumn + $i;
$columnWidth = java_values($cells->getColumnWidth($columnIndex, false, CellsUnitType::POINT));
$newColumnWidth = $columnWidth * $width / $rangeWidth;
$widthInInches = $newColumnWidth / 72.0;
$cells->setColumnWidthInch($columnIndex, $widthInInches);
}
for ($i = 0; $i < $rowCount; $i++) {
$rowIndex = $firstRow + $i;
$rowHeight = java_values($cells->getRowHeight($rowIndex, false, CellsUnitType::POINT));
$newRowHeight = $rowHeight * $height / $rangeHeight;
$heightInInches = $newRowHeight / 72.0;
$cells->setRowHeightInch($rowIndex, $heightInInches);
}
}
Ten pomocnik podglądu renderuje zmieniony zakres przy użyciu SheetRender::toImage. Ogranicza PageSetup::setPrintArea do tego zakresu, usuwa marginesy, nagłówki i stopki oraz zwraca strumień PNG ustawiony na jego początek.
use aspose\cells\ImageOrPrintOptions;
use aspose\cells\ImageType;
use aspose\cells\SheetRender;
use Java as JavaObject;
function CreateOleImage($cellRange, $imageResolution) {
$pageSetup = $cellRange->getWorksheet()->getPageSetup();
$pageSetup->setPrintArea($cellRange->getAddress());
$pageSetup->setLeftMargin(0);
$pageSetup->setRightMargin(0);
$pageSetup->setTopMargin(0);
$pageSetup->setBottomMargin(0);
$pageSetup->clearHeaderFooter();
$imageOptions = new ImageOrPrintOptions();
$imageOptions->setImageType(ImageType::PNG);
$imageOptions->setVerticalResolution($imageResolution);
$imageOptions->setHorizontalResolution($imageResolution);
$imageOptions->setOnePagePerSheet(true);
$imageOptions->setOnlyArea(true);
$worksheet = $cellRange->getWorksheet();
$sheetRender = new SheetRender($worksheet, $imageOptions);
$imageStream = new JavaObject("java.io.ByteArrayOutputStream");
$sheetRender->toImage(0, $imageStream);
$imageBytes = $imageStream->toByteArray();
return new JavaObject("java.io.ByteArrayInputStream", $imageBytes);
}
Podsumowanie
Uwaga
Istnieją dwa podejścia do rozwiązania problemu zmiany rozmiaru arkusza. Wybierz podejście, które najlepiej odpowiada Twoim wymaganiom i przypadkowi użycia. Oba podejścia działają w ten sam sposób, niezależnie od tego, czy prezentacje są tworzone na podstawie szablonu, czy od podstaw. Dodatkowo w tym rozwiązaniu nie ma ograniczenia rozmiaru ramki obiektu OLE.FAQ
Dlaczego osadzony arkusz Excel zmienia rozmiar przy pierwszej aktywacji w PowerPoint?
Dzieje się tak, ponieważ Excel stara się zachować pierwotny rozmiar okna po aktywacji, podczas gdy ramka obiektu OLE w PowerPoint ma własne wymiary. PowerPoint i Excel negocjują rozmiar, aby utrzymać proporcje, co może powodować zmianę rozmiaru.
Czy można całkowicie zapobiec temu problemowi ze zmianą rozmiaru?
Tak. Skalując ramkę OLE, aby pasowała do rozmiaru zakresu komórek Excel, lub skalując zakres komórek, aby pasował do żądanego rozmiaru ramki OLE, można zapobiec niepożądanej zmianie rozmiaru.
Którą metodę skalowania powinienem użyć, skalowanie ramki OLE czy skalowanie zakresu komórek?
Wybierz skalowanie ramki OLE, jeśli chcesz zachować oryginalne rozmiary wierszy i kolumn Excel. Wybierz skalowanie zakresu komórek, jeśli potrzebujesz stałego rozmiaru ramki OLE w swojej prezentacji.
Czy te rozwiązania będą działać, jeśli moja prezentacja opiera się na szablonie?
Tak. Oba rozwiązania działają zarówno dla prezentacji tworzonych na podstawie szablonów, jak i od podstaw.
Czy istnieje limit rozmiaru ramki OLE przy użyciu tych metod?
Nie. Możesz ustawić ramkę obiektu OLE na dowolny rozmiar, pod warunkiem odpowiedniego ustawienia skali.
Czy istnieje sposób, aby uniknąć tekstu zastępczego „EMBEDDED OLE OBJECT” w PowerPoint?
Tak. Pobierając migawkę docelowego zakresu komórek Excel i ustawiając ją jako obraz zastępczy ramki OLE, możesz wyświetlić własny obraz podglądu zamiast domyślnego elementu zastępczego.
Powiązane artykuły
Tworzenie wykresu Excel i osadzanie go w prezentacji jako obiektu OLE
Automatyczna aktualizacja obiektów OLE przy użyciu dodatku MS PowerPoint