Renderowanie slajdów prezentacji jako obrazy SVG w JavaScript
Przegląd
SVG jest skalowalnym formatem obrazu opartym na XML, który sprawdza się w publikowaniu w sieci, przeglądarkach slajdów, procesach dostępności i automatycznym przetwarzaniu poeksportowym. Aspose.Slides for Node.js via Java eksportuje każdy slajd do osobnego pliku SVG i pozwala kontrolować, w jaki sposób zapisywany jest tekst, czcionki, obrazy i elementy SVG.
Użyj SVGOptions, gdy eksportowany SVG musi być kompaktowy, przewidywalny w różnych przeglądarkach lub gotowy do interaktywnego użycia.
Eksport slajdu jako SVG
Utwórz Presentation, wybierz slajd i zapisz go do strumienia przy pomocy Slide.writeAsSvg. Poniższy przykład eksportuje każdy slajd prezentacji do osobnego pliku SVG.
const slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new slides.Presentation("presentation.pptx");
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const outputFileName = `slide-${slide.getSlideNumber()}.svg`;
const svgStream = java.newInstanceSync("java.io.FileOutputStream", outputFileName);
try {
slide.writeAsSvg(svgStream);
} finally {
svgStream.close();
}
}
} finally {
presentation.dispose();
}
Nazwa pliku używa Slide.getSlideNumber zamiast indeksu pętli. Możesz również wyeksportować pojedynczy kształt przy pomocy Shape.writeAsSvg, gdy przeglądarka slajdów lub strona internetowa potrzebuje jedynie tego kształtu.
Konfiguracja wyjścia SVG
SVGOptions steruje renderowaniem SVG. Dla ramek tekstowych SVGOptions.setUseFrameSize uwzględnia ramkę tekstu w obszarze renderowania, a SVGOptions.setUseFrameRotation określa, czy zastosować obrót ramki. Ustaw SVGOptions.setDisableFontLigatures na true, gdy tekst ma być renderowany bez ligatur.
const slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new slides.Presentation("presentation.pptx");
try {
const svgOptions = new slides.SVGOptions();
svgOptions.setDisableFontLigatures(true);
svgOptions.setUseFrameSize(true);
svgOptions.setUseFrameRotation(false);
const slide = presentation.getSlides().get_Item(0);
const svgStream = java.newInstanceSync(
"java.io.FileOutputStream",
"slide-with-custom-options.svg"
);
try {
slide.writeAsSvg(svgStream, svgOptions);
} finally {
svgStream.close();
}
} finally {
presentation.dispose();
}
Kontrola przycinania linii przy grotach strzałek
SVG 1.1 nie posiada ustawienia wcięcia znacznika określającego, gdzie linia ma się zatrzymać pod grotami strzałki. Domyślnie Aspose.Slides skraca wyeksportowaną linię, aby jej obrys nie wystawał poza znacznik. Wywołaj SVGOptions.setDisableLineEndCropping z wartością true, aby narysować obrys aż do pierwotnego końcowego punktu linii. To ustawienie wpływa wyłącznie na wyjście SVG. Pozycja i długość linii na slajdzie pozostają niezmienione.
Przykład rysuje trójkątne i rombowe groty na liniach o szerokości 2 i 10 punktów. Eksportuje ten sam slajd dwukrotnie, zmieniając jedynie opcję przycinania.
const slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const lineColor = java.newInstanceSync("java.awt.Color", 0, 0, 139);
let y = 40;
for (const style of [slides.LineArrowheadStyle.Triangle, slides.LineArrowheadStyle.Diamond]) {
for (const width of [2, 10]) {
const line = slide.getShapes().addAutoShape(slides.ShapeType.Line, 40, y, 200, 0);
const format = line.getLineFormat();
format.getFillFormat().setFillType(java.newByte(slides.FillType.Solid));
format.getFillFormat().getSolidFillColor().setColor(lineColor);
format.setWidth(width);
format.setEndArrowheadStyle(java.newByte(style));
y += 50;
}
}
const options = new slides.SVGOptions();
options.setDisableLineEndCropping(false);
const cropped = java.newInstanceSync("java.io.FileOutputStream", "cropped.svg");
try {
slide.writeAsSvg(cropped, options);
} finally {
cropped.close();
}
options.setDisableLineEndCropping(true);
const uncropped = java.newInstanceSync("java.io.FileOutputStream", "uncropped.svg");
try {
slide.writeAsSvg(uncropped, options);
} finally {
uncropped.close();
}
} finally {
presentation.dispose();
}
Porównanie pokazuje trójkątny grot na linii 10‑punktowej. Przy włączonym przycinaniu grot jest ostry. Przy wyłączonym przycinaniu obrys wystaje poza pochyłe boki znacznika, tworząc płaską końcówkę.

W pozostałych liniach z przykładu wystające obrysy są mniej widoczne przy trójkącie 2‑punktowym. Wypełniony romb zasłania koniec obrysu przy obu szerokościach.
Kontrola tekstu i czcionek
Podczas eksportowania slajdów do SVG możesz sterować, czy tekst pozostaje tekstem, czy zostaje przekonwertowany na grafikę wektorową, oraz w jaki sposób zewnętrzne czcionki są dołączane lub odwoływane. Poniższe opcje pomagają zrównoważyć spójność wizualną, możliwość zaznaczania tekstu oraz zależności czcionek w wyeksportowanym pliku SVG.
Wektoryzacja całego tekstu
Ustaw SVGOptions.setVectorizeText na true, aby zapisać cały tekst slajdu jako grafikę wektorową. Eliminuje to zależności od czcionek i sprawia, że rezultat jest bardziej jednorodny w różnych przeglądarkach, ale tekst nie jest już wybieralny ani przeszukiwalny jako tekst SVG.
const slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new slides.Presentation("presentation.pptx");
try {
const svgOptions = new slides.SVGOptions();
svgOptions.setVectorizeText(true);
const slide = presentation.getSlides().get_Item(0);
const svgStream = java.newInstanceSync(
"java.io.FileOutputStream",
"slide-with-vectorized-text.svg"
);
try {
slide.writeAsSvg(svgStream, svgOptions);
} finally {
svgStream.close();
}
} finally {
presentation.dispose();
}
Wybór sposobu obsługi zewnętrznych czcionek
SVGOptions.setExternalFontsHandling przyjmuje wartość SvgExternalFontsHandling określającą, jak traktować czcionki ładowane zewnętrznie. Wybierz AddLinksToFontFiles, aby odwoływać się do osobnych plików czcionek, Embed, aby wbudować dane czcionki w SVG, lub Vectorize, aby renderować jako grafikę tylko tekst korzystający z czcionek zewnętrznych. Przed wbudowaniem czcionek zweryfikuj ich licencje.
const slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new slides.Presentation("presentation.pptx");
try {
const slide = presentation.getSlides().get_Item(0);
const linkedFontsOptions = new slides.SVGOptions();
linkedFontsOptions.setExternalFontsHandling(
slides.SvgExternalFontsHandling.AddLinksToFontFiles
);
const linkedFontsStream = java.newInstanceSync(
"java.io.FileOutputStream",
"slide-with-font-links.svg"
);
try {
slide.writeAsSvg(linkedFontsStream, linkedFontsOptions);
} finally {
linkedFontsStream.close();
}
const embeddedFontsOptions = new slides.SVGOptions();
embeddedFontsOptions.setExternalFontsHandling(
slides.SvgExternalFontsHandling.Embed
);
const embeddedFontsStream = java.newInstanceSync(
"java.io.FileOutputStream",
"slide-with-embedded-fonts.svg"
);
try {
slide.writeAsSvg(embeddedFontsStream, embeddedFontsOptions);
} finally {
embeddedFontsStream.close();
}
const vectorizedExternalFontsOptions = new slides.SVGOptions();
vectorizedExternalFontsOptions.setExternalFontsHandling(
slides.SvgExternalFontsHandling.Vectorize
);
const vectorizedExternalFontsStream = java.newInstanceSync(
"java.io.FileOutputStream",
"slide-with-vectorized-external-fonts.svg"
);
try {
slide.writeAsSvg(vectorizedExternalFontsStream, vectorizedExternalFontsOptions);
} finally {
vectorizedExternalFontsStream.close();
}
} finally {
presentation.dispose();
}
Zmniejszanie rozmiaru osadzonych obrazów
Użyj SVGOptions.setPicturesCompression, aby obniżyć rozdzielczość osadzonych obrazów, SVGOptions.setDeletePicturesCroppedAreas, aby pominąć przycięte fragmenty źródłowe, oraz SVGOptions.setJpegQuality, aby kontrolować jakość kodowania JPEG. Ustawienia te zmniejszają rozmiar pliku kosztem jakości obrazu lub zachowanych danych obrazu.
const slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new slides.Presentation("presentation.pptx");
try {
const svgOptions = new slides.SVGOptions();
svgOptions.setPicturesCompression(slides.PicturesCompression.Dpi150);
svgOptions.setDeletePicturesCroppedAreas(true);
svgOptions.setJpegQuality(80);
const slide = presentation.getSlides().get_Item(0);
const svgStream = java.newInstanceSync("java.io.FileOutputStream", "compressed-slide.svg");
try {
slide.writeAsSvg(svgStream, svgOptions);
} finally {
svgStream.close();
}
} finally {
presentation.dispose();
}
Kontrola rozdzielczości rasteryzacji metafili
SVGOptions.setMetafileRasterizationDpi określa dolny limit rozdzielczości przy rasteryzacji metafili podczas eksportu SVG. Użyj go, aby wyważyć szczegółowość i rozmiar pliku przy rasteryzacji obrazu EMF lub WMF. Nie definiuje on globalnego DPI dla SVG ani nie zmusza wszystkich elementów slajdu do konwersji na obraz rastrowy.
Pobierz metafile-rasterization.pptx, który zawiera obraz EMF z ściśle rozmieszczonymi liniami ukośnymi. Poniższy przykład eksportuje jego pierwszy slajd w trzech rozdzielczościach rasteryzacji przy użyciu Slide.writeAsSvg. Wszystkie pozostałe ustawienia eksportu pozostają identyczne, aby wyniki można było porównać.
const slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new slides.Presentation("metafile-rasterization.pptx");
try {
for (const dpi of [72, 150, 300]) {
const svgOptions = new slides.SVGOptions();
svgOptions.setMetafileRasterizationDpi(dpi);
svgOptions.setPicturesCompression(slides.PicturesCompression.Dpi330);
svgOptions.setJpegQuality(90);
const outputFileName = `slide-${dpi}.svg`;
const svgStream = java.newInstanceSync("java.io.FileOutputStream", outputFileName);
try {
presentation.getSlides().get_Item(0).writeAsSvg(svgStream, svgOptions);
} finally {
svgStream.close();
}
}
} finally {
presentation.dispose();
}
W wyjściu EMF został zamieniony na jeden osadzony PNG w każdym SVG. Poniższe pomiary dotyczą dostarczonej prezentacji; nie są ogólną formułą konwersji DPI na wymiary pikseli.
| DPI rasteryzacji metafili | Wymiary osadzonego PNG | Rozmiar pliku SVG (bajty) |
|---|---|---|
| 72 | 1196 × 596 | 170,221 |
| 150 | 2492 × 1242 | 423,149 |
| 300 | 4983 × 2483 | 1,027,169 |
Porównanie poniżej pokazuje ten sam obszar osadzonego obrazu rastrowego przy tej samej powiększonej wielkości wyświetlania. Linie ukośne wykazują widoczną pikselację przy 72 DPI i wygładzone krawędzie przy wyższych rozdzielczościach, przy czym plik SVG rośnie. Zwiększenie wartości niekoniecznie poprawia każdy szczegół ani nie zmienia każdego wyeksportowanego obrazu.

SVGOptions.setPicturesCompression steruje redukcją rozdzielczości obrazu i może maskować wpływ zmiany rozdzielczości rasteryzacji metafili. SVGOptions.setJpegQuality kontroluje jakość kodowania JPEG, a nie rozdzielczość rasteryzacji metafili.
Przypisywanie stabilnych identyfikatorów do kształtów i tekstu
Przekaż kontroler formatowania do SVGOptions.setShapeFormattingController, aby ustawić SvgShape.setId dla każdego kształtu SVG. Kontroler obsługujący także fragmenty tekstu może ustawić wartości SvgTSpan.setId na elementach tspan.
Poniższy kontroler używa Shape.getOfficeInteropShapeId, który jest stabilny przez cały czas życia kształtu, oraz powtarzalnego licznika dla jego fragmentów tekstu. Dzięki temu wygenerowane identyfikatory nadają się do przetwarzania po zmianie prezentacji, o ile sama prezentacja nie uległa modyfikacji.
const slides = require("aspose.slides.via.java");
const java = require("java");
class StableSvgIdController {
constructor() {
this.currentShapeId = "";
this.textSpanIndex = 0;
}
formatShape(svgShape, shape) {
this.currentShapeId = `shape-${shape.getOfficeInteropShapeId()}`;
this.textSpanIndex = 0;
svgShape.setId(this.currentShapeId);
}
formatText(svgTSpan, portion, textFrame) {
const textSpanId = `${this.currentShapeId}-text-${this.textSpanIndex++}`;
svgTSpan.setId(textSpanId);
}
createProxy() {
const controller = this;
const interfaceName = "com.aspose.slides.ISvgShapeAndTextFormattingController";
const proxyMethods = {
formatShape(svgShape, shape) {
controller.formatShape(svgShape, shape);
},
formatText(svgTSpan, portion, textFrame) {
controller.formatText(svgTSpan, portion, textFrame);
}
};
return java.newProxy(interfaceName, proxyMethods);
}
}
const presentation = new slides.Presentation("presentation.pptx");
try {
const svgOptions = new slides.SVGOptions();
const stableSvgIdController = new StableSvgIdController();
const controllerProxy = stableSvgIdController.createProxy();
svgOptions.setShapeFormattingController(controllerProxy);
const slide = presentation.getSlides().get_Item(0);
const svgStream = java.newInstanceSync(
"java.io.FileOutputStream",
"slide-with-stable-ids.svg"
);
try {
slide.writeAsSvg(svgStream, svgOptions);
} finally {
svgStream.close();
}
} finally {
presentation.dispose();
}
Dodawanie obsługi zdarzeń SVG
W kontrolerze formatowania wywołaj SvgShape.setEventHandler z wartością SvgEvent, aby dodać obsługę zdarzenia JavaScript do wyeksportowanego kształtu. Przypisz kontroler za pomocą SVGOptions.setShapeFormattingController i zdefiniuj funkcję JavaScript w stronie lub dokumencie SVG, które hostują wynik.
const slides = require("aspose.slides.via.java");
const java = require("java");
class SvgEventController {
formatShape(svgShape, shape) {
if (shape.getName() === "ActionButton") {
svgShape.setId("action-button");
svgShape.setEventHandler(
slides.SvgEvent.OnClick,
"handleShapeClick(event)"
);
}
}
createProxy() {
const controller = this;
const interfaceName = "com.aspose.slides.ISvgShapeFormattingController";
const proxyMethods = {
formatShape(svgShape, shape) {
controller.formatShape(svgShape, shape);
}
};
return java.newProxy(interfaceName, proxyMethods);
}
}
const presentation = new slides.Presentation("presentation.pptx");
try {
const svgOptions = new slides.SVGOptions();
const svgEventController = new SvgEventController();
const controllerProxy = svgEventController.createProxy();
svgOptions.setShapeFormattingController(controllerProxy);
const slide = presentation.getSlides().get_Item(0);
const svgStream = java.newInstanceSync("java.io.FileOutputStream", "interactive-slide.svg");
try {
slide.writeAsSvg(svgStream, svgOptions);
} finally {
svgStream.close();
}
} finally {
presentation.dispose();
}
Strona hostująca może zdefiniować funkcję JavaScript odwołującą się do obsługi zdarzenia. Przypisywanie identyfikatorów i obsługi zdarzeń umożliwia przeglądarki slajdów, ulepszenia dostępności i inne interaktywne przepływy pracy z SVG.
FAQ
Kiedy powinienem używać SVGOptions.setVectorizeText zamiast SvgExternalFontsHandling.Vectorize?
Użyj SVGOptions.setVectorizeText, gdy cały tekst musi być niezależny od czcionek. Użyj SvgExternalFontsHandling.Vectorize, gdy tylko tekst korzystający z czcionek zewnętrznych powinien być zamieniony na grafikę.
Jaki jest najlepszy sposób na zmniejszenie rozmiaru SVG?
Zacznij od kompresji osadzonych obrazów, usuwania przyciętych obszarów obrazów oraz wybierania linków do plików czcionek, gdy docelowe środowisko może je serwować. Przetestuj wynik, ponieważ niższa rozdzielczość obrazu, niższa jakość JPEG i wektoryzowany tekst mają różne kompromisy jakości i rozmiaru.
Czy mogę modyfikować elementy SVG po eksporcie?
Tak. Przypisz identyfikatory poprzez kontroler formatowania, a następnie wybieraj pasujące elementy SVG w swoim narzędziu do przetwarzania post‑exportowego lub w skrypcie przeglądarki.