Render Slide Presentasi sebagai Gambar SVG dalam JavaScript
Ikhtisar
SVG adalah format gambar berbasis XML yang dapat diskalakan dan bekerja dengan baik untuk penerbitan web, penampil slide, alur kerja aksesibilitas, dan pemrosesan otomatis pasca. Aspose.Slides untuk Node.js melalui Java mengekspor setiap slide ke file SVG terpisah dan memungkinkan Anda mengendalikan bagaimana teks, font, gambar, dan elemen SVG ditulis.
Gunakan SVGOptions ketika SVG yang diekspor harus kompak, dapat diprediksi di berbagai browser, atau siap untuk penggunaan interaktif.
Ekspor Slide sebagai SVG
Buat sebuah Presentation, pilih sebuah slide, dan tulis ke aliran dengan Slide.writeAsSvg. Contoh berikut mengekspor setiap slide dalam presentasi sebagai file SVG terpisah.
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();
}
Nama file menggunakan Slide.getSlideNumber bukan indeks perulangan. Anda juga dapat mengekspor sebuah bentuk individual dengan Shape.writeAsSvg ketika penampil slide atau halaman web hanya membutuhkan bentuk tersebut.
Konfigurasi Output SVG
SVGOptions mengendalikan rendering SVG. Untuk bingkai teks, SVGOptions.setUseFrameSize menyertakan bingkai teks dalam area rendering, dan SVGOptions.setUseFrameRotation menentukan apakah rotasi bingkai diterapkan. Atur SVGOptions.setDisableFontLigatures ke true ketika teks harus dirender tanpa 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();
}
Kontrol Pemotongan Ujung Garis pada Ujung Panah
SVG 1.1 tidak memiliki pengaturan inset penanda untuk menentukan di mana sebuah garis harus berhenti di bawah ujung panah. Secara default, Aspose.Slides memendekkan garis yang diekspor sehingga goresannya tidak menonjol melalui penanda. Panggil SVGOptions.setDisableLineEndCropping dengan true untuk menggambar goresan sampai ke titik akhir asli garis tersebut. Pengaturan ini hanya memengaruhi output SVG. Garis tetap mempertahankan posisi dan panjangnya pada slide.
Contoh ini menggambar ujung panah segitiga dan belah ketupat pada garis dengan lebar 2 dan 10 poin. Ia mengekspor slide yang sama dua kali, hanya mengubah opsi pemotongan.
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();
}
Perbandingan menunjukkan ujung panah segitiga pada garis 10 poin. Dengan pemotongan diaktifkan, ujungnya tajam. Dengan pemotongan dinonaktifkan, goresan menonjol melalui sisi miring penanda dan meninggalkan ujung datar.

Pada garis lain dari contoh, goresan yang menonjol kurang terlihat pada segitiga 2 poin. Belah ketupat yang terisi menutupi ujung goresan pada kedua lebar.
Kontrol Teks dan Font
Saat mengekspor slide ke SVG, Anda dapat mengendalikan apakah teks tetap sebagai teks atau diubah menjadi grafik vektor, dan bagaimana font eksternal disertakan atau direferensikan. Opsi-opsi berikut membantu Anda menyeimbangkan konsistensi visual, pemilihan teks, dan ketergantungan font dalam SVG yang diekspor.
Vektorkan Semua Teks
Atur SVGOptions.setVectorizeText ke true untuk menulis semua teks slide sebagai grafik vektor. Ini menghilangkan ketergantungan font dan membuat hasil visual lebih konsisten di berbagai browser, namun teks tidak lagi dapat dipilih atau dicari sebagai teks 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();
}
Pilih Cara Penanganan Font Eksternal
SVGOptions.setExternalFontsHandling menggunakan nilai SvgExternalFontsHandling untuk font yang dimuat secara eksternal. Pilih AddLinksToFontFiles untuk mereferensikan file font terpisah, Embed untuk menyertakan data font dalam SVG, atau Vectorize untuk merender hanya teks yang menggunakan font eksternal sebagai grafik. Verifikasi lisensi font sebelum menyematkan font.
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();
}
Kurangi Ukuran Gambar Tersemat
Gunakan SVGOptions.setPicturesCompression untuk mengurangi resolusi gambar yang tersemat, SVGOptions.setDeletePicturesCroppedAreas untuk menghilangkan area sumber yang dipotong, dan SVGOptions.setJpegQuality untuk mengontrol kualitas enkoding JPEG. Pengaturan ini mengurangi ukuran file dengan mengorbankan keakuratan gambar atau data gambar yang dipertahankan.
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();
}
Kontrol Resolusi Rasterisasi Metafile
SVGOptions.setMetafileRasterizationDpi menetapkan batas resolusi rendah untuk merasterkan metafile selama ekspor SVG. Gunakan untuk menyeimbangkan detail dan ukuran file ketika gambar EMF atau WMF dirasterkan. Ini tidak mendefinisikan DPI global untuk SVG atau memaksa setiap objek pada slide menjadi gambar raster.
Unduh metafile-rasterization.pptx, yang berisi gambar EMF dengan garis diagonal rapat. Contoh berikut mengekspor slide pertamanya pada tiga resolusi rasterisasi melalui Slide.writeAsSvg. Semua pengaturan ekspor lainnya tetap identik sehingga hasil dapat dibandingkan.
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();
}
Dalam output, EMF menjadi satu PNG tersemat di setiap SVG. Pengukuran berikut untuk presentasi yang disediakan; tidak merupakan rumus umum untuk mengonversi DPI ke dimensi piksel.
| Rasterisasi DPI Metafile | Dimensi PNG Tersemat | Ukuran file SVG (byte) |
|---|---|---|
| 72 | 1196 × 596 | 170,221 |
| 150 | 2492 × 1242 | 423,149 |
| 300 | 4983 × 2483 | 1,027,169 |
Perbandingan di bawah menunjukkan area yang sama dari raster tersemat pada ukuran tampilan yang diperbesar sama. Garis diagonal menunjukkan pixelasi yang terlihat pada 72 DPI dan tepi yang lebih halus pada resolusi lebih tinggi, sementara file SVG menjadi lebih besar. Meningkatkan nilai tidak selalu meningkatkan setiap detail atau mengubah setiap gambar yang diekspor.

SVGOptions.setPicturesCompression mengontrol pengurangan resolusi gambar dan dapat menutupi efek perubahan resolusi rasterisasi metafile. SVGOptions.setJpegQuality mengontrol kualitas enkoding JPEG, bukan resolusi rasterisasi metafile.
Tetapkan ID Stabil untuk Bentuk dan Teks
Berikan kontroler format ke SVGOptions.setShapeFormattingController untuk menetapkan SvgShape.setId bagi setiap bentuk SVG. Kontroler yang juga menangani rentang teks dapat menetapkan nilai SvgTSpan.setId pada elemen teks tspan.
Kontroler berikut menggunakan Shape.getOfficeInteropShapeId, yang stabil selama masa bentuk, dan penghitung berulang untuk rentang teksnya. Ini membuat ID yang dihasilkan cocok untuk pemrosesan lanjutan pada presentasi yang tidak diubah.
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();
}
Tambahkan Penangan Peristiwa SVG
Dalam kontroler format, panggil SvgShape.setEventHandler dengan nilai SvgEvent untuk menambahkan penangan peristiwa JavaScript ke bentuk yang diekspor. Tetapkan kontroler dengan SVGOptions.setShapeFormattingController dan definisikan fungsi JavaScript di halaman atau dokumen SVG yang menampung hasilnya.
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();
}
Halaman host dapat mendefinisikan fungsi JavaScript yang direferensikan oleh penangan. Penetapan ID dan penangan peristiwa memungkinkan penampil slide, peningkatan aksesibilitas, dan alur kerja SVG interaktif lainnya.
FAQ
Kapan saya harus menggunakan SVGOptions.setVectorizeText alih-alih SvgExternalFontsHandling.Vectorize?
Gunakan SVGOptions.setVectorizeText ketika semua teks harus independen dari font. Gunakan SvgExternalFontsHandling.Vectorize ketika hanya teks yang menggunakan font eksternal yang harus dikonversi menjadi grafik.
Apa cara terbaik untuk membuat SVG lebih kecil?
Mulailah dengan mengompresi gambar yang tersemat, menghapus area gambar yang dipotong, dan memilih file font yang ditautkan ketika lingkungan target dapat menyediakannya. Uji hasilnya karena resolusi gambar lebih rendah, kualitas JPEG lebih rendah, dan teks yang diverktorkan masing‑masing memiliki kompromi kualitas dan ukuran yang berbeda.
Apakah saya dapat memodifikasi elemen SVG yang diekspor setelah ekspor?
Ya. Tetapkan ID melalui kontroler format, lalu pilih elemen SVG yang sesuai dalam alat pemrosesan lanjutan Anda atau skrip peramban.