Prezentációk exportálása XAML‑ba Java‑ban
Áttekintés
Ez a cikk bemutatja, hogyan lehet a PowerPoint‑prezentációkat XAML formátumba exportálni az Aspose.Slides használatával. Tartalmaz egy rövid bevezetést a XAML‑ba, megmutatja, hogyan menthető egy prezentáció XAML‑ba alapértelmezett beállításokkal, és bemutatja, hogyan testreszabható az export a XamlOptions, beleértve a rejtett diák exportálását is. A cikk néhány gyakori kérdésre is válaszol a tartalék betűtípusokkal, a XAML‑verem kompatibilitással és a rejtett diák exportálásának viselkedésével kapcsolatban.
A XAML‑ról
A XAML egy XML‑alapú jelölőnyelv, amelyet felhasználói felületek leírására használnak olyan keretrendszerekben, mint a WPF (Windows Presentation Foundation), az UWP (Universal Windows Platform) és a Xamarin.Forms.
A XAML‑fájlokkal vizuális tervezőben dolgozhatsz, vagy a jelölést közvetlenül írhatod és szerkesztheted.
Prezentációk exportálása XAML‑ba alapértelmezett beállításokkal
Az alábbi Java‑példa megmutatja, hogyan exportálható egy prezentáció XAML‑ba alapértelmezett beállításokkal:
import com.aspose.slides.*;
Presentation presentation = new Presentation("pres.pptx");
try {
XamlOptions xamlOptions = new XamlOptions();
presentation.save(xamlOptions);
} finally {
presentation.dispose();
}
Alapértelmezés szerint az exportált diákat egy pres almappába menti a folyamat aktuális munkakönyvtárában, amely egy üres útból kerül feloldásra a Paths.get segítségével. A mappa automatikusan létrejön, és a szükséges képek is oda kerülnek mentésre.
A kimeneti mappa neve a forrásfájl névéről származik kiterjesztés nélkül. A pres.pptx esetén a kimeneti fájlok neve pres/Slide_1.xaml, pres/Slide_2.xaml stb. Még ha abszolút útvonalat adsz meg a bemeneti prezentációhoz is, a kimeneti mappa az aktuális munkakönyvtárhoz relatív módon jön létre, nem a bemeneti fájl mellett.
Prezentációk exportálása XAML‑ba egyéni beállításokkal
Használd az IXamlOptions interfészt annak vezérlésére, hogyan exportálja az Aspose.Slides a prezentációt XAML‑ba.
A kimenet egyéni helyre mentéséhez valósítsd meg az IXamlOutputSaver interfészt, és add át az implementációdat a setOutputSaver metódusnak a XamlOptions‑on keresztül.
A rejtett diák XAML‑kimenetbe való belefoglalásához hívd meg a setExportHiddenSlides metódust true értékkel, ahogyan az alábbi Java‑példa mutatja:
import com.aspose.slides.*;
Presentation presentation = new Presentation("pres.pptx");
try {
XamlOptions xamlOptions = new XamlOptions();
xamlOptions.setExportHiddenSlides(true);
presentation.save(xamlOptions);
} finally {
presentation.dispose();
}
Minden generált XAML‑eszköz összegyűjtése
Egy XAML‑exportálás minden exportált diáról XAML dokumentumot, valamint külön képeket és segédforrásokat hozhat létre. Rendelj egy egyedi IXamlOutputSaver‑t a XamlOptions.setOutputSaver‑nek, hogy ezeket az eszközöket a alapértelmezett fájlrendszer‑mentő helyett kapd meg. Indítsd az exportálást a XAML‑specifikus Presentation.save metódussal, amely XAML‑beállításokat fogad.
A visszahívási életciklus megértése
Az exportáló külön meghívja a IXamlOutputSaver.save metódust minden generált eszközre:
pathazonosítja az eszközt, és tartalmazhat relatív almappákat. Őrizd meg ezt az információt, mert a XAML relatív útvonalakkal hivatkozhat erőforrásokra.dataaz eszköz bájtjait tartalmazza. A képeket és egyéb bináris erőforrásokat ne dekódold szövegként.- A mentő feladata, hogy a visszatérés előtt megtartsa vagy elmentse az adatot. A példák minden bájt‑tömböt alkalmazás‑tulajdonú memóriába másolnak.
- Az exportot csak akkor tekintsd sikeresnek, ha a prezentáció mentése visszatér, és minden visszahívás sikeresen befejeződik. Ne nyelj el tárolási hibákat, és ne indíts megfigyelés nélküli háttér‑írásokat. Ha a tartósítás később történik, az összesített sikert csak akkor jelentsd, ha az a lépés is sikeres.
A XamlOptions.setExportHiddenSlides ugyanúgy érvényes egy egyéni mentőre is. Az alapértelmezett érték, false, kizárja a rejtett diák XAML dokumentumait. true megadása belefoglalja őket és minden exporthoz szükséges erőforrást. Az erőforrás‑szám a prezentációtól függ; ne feltételezd, hogy diánként egy visszahívás vagy fix sorrend van.
Exportálás memóriába és az eszközök vizsgálata
Ez a teljes példa betölti a pres.pptx‑t, minden eszközt egy Map<String, byte[]>‑ba gyűjt, és kiírja a nevét, típusát és bájtszámát. Pontosan megőrzi a megadott neveket. Az ismétlődő nevek a gyűjteményt érvénytelennek jelzik a csendes felülírás helyett. A példa ezt ellenőrzi a használat előtt.
import com.aspose.slides.*;
import java.util.LinkedHashMap;
import java.util.Map;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
class MemoryXamlSaver implements IXamlOutputSaver {
final Map<String, byte[]> artifacts = new LinkedHashMap<>();
boolean valid = true;
@Override
public void save(String path, byte[] data) {
if (artifacts.containsKey(path)) {
valid = false;
System.err.println("Export rejected: duplicate artifact name: " + path);
return;
}
byte[] retainedData = data.clone();
artifacts.put(path, retainedData);
}
}
MemoryXamlSaver saver = new MemoryXamlSaver();
Presentation presentation = new Presentation("pres.pptx");
try {
XamlOptions options = new XamlOptions();
options.setOutputSaver(saver);
options.setExportHiddenSlides(true);
presentation.save(options);
} finally {
presentation.dispose();
}
if (!saver.valid) {
System.err.println("Export rejected: the artifact collection is invalid.");
return;
}
boolean inspectXamlText = false;
for (Map.Entry<String, byte[]> artifact : saver.artifacts.entrySet()) {
String name = artifact.getKey().toLowerCase(Locale.ROOT);
boolean isXaml = name.endsWith(".xaml");
boolean isImage = name.matches(".*\\.(png|jpg|jpeg|gif|bmp|tif|tiff|svg)$");
String kind = isXaml ? "slide XAML" : isImage ? "image" : "supporting resource";
System.out.println(artifact.getKey() + ": " + artifact.getValue().length + " bytes (" + kind + ")");
// Csak XAML-t dekódolj, és csak akkor, ha szöveges ellenőrzés szükséges.
if (isXaml && inspectXamlText) {
String markup = new String(artifact.getValue(), StandardCharsets.UTF_8);
System.out.println(markup);
}
}
A kiterjesztés‑ellenőrzések hasznosak a vizsgálathoz; tartsd meg az összes eszközt, beleértve az ismeretlen típusú erőforrásokat is. A bájtokat változtatás nélkül tárold vagy továbbítsd. Csak XAML‑szöveg feldolgozásához használd a String konstruktorát UTF‑8‑kal.
Gyűjtött eszközök csomagolása ZIP‑archívumban
Ez a független példa összegyűjti az exportot, ellenőrzi a neveket, és az eredeti bájtokat egy ZIP‑archívumba írja. Egy egyedi archívum‑név választja el a párhuzamos export‑feladatokat. A ZIP‑bejegyzések előre‑húzott perjeleket használnak, és megtartják a relatív almappákat. Nem biztonságos nevek vagy a normalizálás után ütköző nevek a teljes csomag írása előtt elutasításra kerülnek.
import com.aspose.slides.*;
import java.util.LinkedHashMap;
import java.util.Map;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
class MemoryXamlSaver implements IXamlOutputSaver {
final Map<String, byte[]> artifacts = new LinkedHashMap<>();
boolean valid = true;
@Override
public void save(String path, byte[] data) {
if (artifacts.containsKey(path)) {
valid = false;
System.err.println("Export rejected: duplicate artifact name: " + path);
return;
}
byte[] retainedData = data.clone();
artifacts.put(path, retainedData);
}
}
MemoryXamlSaver saver = new MemoryXamlSaver();
Presentation presentation = new Presentation("pres.pptx");
try {
XamlOptions options = new XamlOptions();
options.setOutputSaver(saver);
options.setExportHiddenSlides(false);
presentation.save(options);
} finally {
presentation.dispose();
}
if (!saver.valid) {
System.err.println("Export rejected: the artifact collection is invalid.");
return;
}
Map<String, byte[]> entries = new LinkedHashMap<>();
Set<String> entryNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
for (Map.Entry<String, byte[]> artifact : saver.artifacts.entrySet()) {
String entryName = artifact.getKey().replace('\\', '/');
String[] segments = entryName.split("/", -1);
boolean unsafeName = entryName.startsWith("/") || entryName.contains(":");
for (String segment : segments) {
unsafeName |= segment.trim().isEmpty() || segment.equals(".") || segment.equals("..");
}
if (unsafeName || !entryNames.add(entryName)) {
System.err.println("Export rejected: unsafe or duplicate artifact name: " + artifact.getKey());
return;
}
entries.put(entryName, artifact.getValue());
}
Path archivePath = Paths.get("xaml-" + UUID.randomUUID() + ".zip");
try {
OutputStream output = Files.newOutputStream(archivePath, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
try (OutputStream archiveOutput = output; ZipOutputStream archive = new ZipOutputStream(archiveOutput)) {
for (Map.Entry<String, byte[]> artifact : entries.entrySet()) {
ZipEntry entry = new ZipEntry(artifact.getKey());
archive.putNextEntry(entry);
archive.write(artifact.getValue());
archive.closeEntry();
}
}
// A ZIP könyvtár a siker jelentése előtt a lezárással lett befejezve.
System.out.println("Saved " + entries.size() + " artifacts to " + archivePath);
} catch (IOException exception) {
System.err.println("Archive persistence failed: " + exception.getMessage());
}
A példa a ZipOutputStream‑t használja egy helyi archívum írásához; maga az exportáló nem ír laza XAML‑ vagy képfájlokat. Távoli tároláshoz cseréld le az archívum‑írást a gyűjtött bájt‑tömbök feltöltésére. Használj export‑feladat‑azonosítót és a teljes relatív eszköz‑nevet blob‑kulcsként, vagy tárold a feladat‑azonosítót, a relatív nevet és a bináris adatot egy adatbázis‑sorban. A feladatot csak akkor tedd közzé, ha minden feltöltés befejeződött vagy a tranzakció elköteleződött. Ha a tartósítás meghiúsul, tisztítsd meg a részleges kimenetet.
Nagy prezentációk esetén egy egyéni mentő közvetlenül az alkalmazás‑tárolóba mentheti az egyes eszközöket, így elkerülve a teljes export másolatának memóriában tartását. Tartsd a visszahívásokat szinkronban az exportáló nézőpontjából: csak akkor térj vissza, ha a célpont elfogadta a bájtokat, és engedd, hogy a hibák eljussanak a hívóhoz.
Erőforrás‑nevek megőrzése és hivatkozások ellenőrzése
- Normalizáld az útvonal‑elválasztókat a cél igényei szerint, de tartsd meg a relatív almappákat. Ne csak a Path.getFileName‑t használd, kivéve ha minden generált név egyedi és a hivatkozások érvényesek.
- Alkalmazz cél‑specifikus név‑validálást. Laza fájlok írásakor vedd el a gyökér‑útvonalakat és a navigációs szegmenseket, oldd fel a célt a Path.toAbsolutePath‑val, és ellenőrizd, hogy az a tervezett export‑könyvtár alatt marad‑e, beleértve a könyvtár‑elválasztót a tartalmazási ellenőrzésben. Használj olyan alkalmazás‑vezérelt könyvtárat, amelynek nincsenek szimbolikus linkjei, amelyek átirányíthatják az írásokat.
- Minden export‑feladathoz használj külön mentőt és tárolási névtér‑prefixet. Detektáld az ütközéseket a szeparátor‑normalizálás után és a cél‑eset‑érzékenységi szabályok szerint.
- Közzététel előtt elemezd minden XAML‑dokumentumot XML‑ként, és vizsgáld meg a fájl‑alapú erőforrás‑hivatkozásokat, például a kép
SourcevagyImageSourceattribútumait. Oldd fel minden relatív URI‑t a tartalmazó XAML‑eszköz könyvtárához képest, normalizáld a kapott tárolási nevet, és ellenőrizd, hogy a megfelelő map‑kulcs, ZIP‑bejegyzés vagy tárolt objektum létezik‑e. Kezelj külön a külső URI‑kat és a XAML‑mark-up kifejezéseket a relatív fájlnevektől.
Például, ha a pres/Slide_1.xaml a images/image1.png‑re hivatkozik, akkor a tárolt erőforrásnak pres/images/image1.png‑ként kell elérhetőnek lennie. Ha csak image1.png marad, a kapcsolat megszakad. Objektumtárolás esetén tartsd meg ugyanazt a struktúrát a feladat‑előtag alatt, és tedd elérhetővé ezeket a URL‑eket a XAML‑fogyasztó számára. Nyisd meg újra a kész ZIP‑et a bejegyzés‑nevek és erőforrás‑bájtok ellenőrzéséhez, és tölts be reprezentatív diákat a cél‑XAML‑környezetben, hogy megerősítsd a képek helyes feloldását.
GYIK
Hogyan biztosítható, hogy a betűtípusok kiszámíthatóak legyenek, ha az eredeti betűtípus nem érhető el a gépen?
Hívd meg a setDefaultRegularFont metódust a XamlOptions-on – ez a fallback betűtípusként kerül használatra az export során, ha az eredeti hiányzik. Ez nem garantálja, hogy a generált XAML a fallback betűtípust hivatkozza, vagy hogy a betűtípus elérhető legyen a célgépen. Biztosítsd, hogy a XAML által hivatkozott betűtípusok jelen legyenek a megjelenítő környezetben.
Az exportált XAML csak WPF‑hez szánt, vagy más XAML‑veremekben is használható?
Az Aspose.Slides a WPF XAML‑t exportálja a nyilvános API‑ján keresztül. Más XAML‑veremekkel, például az UWP‑vel vagy a Xamarin.Forms‑szal való kompatibilitás nincs garantálva. Teszteld a generált jelölést a cél környezetben.
Támogatottak a rejtett diák, és hogyan lehet megakadályozni, hogy alapértelmezés szerint exportálásra kerüljenek?
Alapértelmezés szerint a rejtett diák nincsenek belefoglalva. Ezt a viselkedést a setExportHiddenSlides segítségével szabályozhatod a XamlOptions‑ban – tartsd letiltva, ha nincs szükséged a exportálásukra.