Export prezentací do HTML s externě odkazovanými obrázky
Přehled
Ve výchozím nastavení exportuje Aspose.Slides prezentaci do samostatného HTML souboru. Obrázky a další zdroje jsou zapisovány přímo do HTML, obvykle jako data Base64. To je pohodlné, když potřebujete jeden přenosný soubor, ale není to vždy nejlepší formát pro webové stránky, CMS nebo serverovou konverzní pipeline.
Použijte externě odkazované zdroje, pokud chcete:
- zmenšit velikost HTML dokumentu;
- cachovat obrázky, fonty, audio nebo video samostatně v prohlížeči nebo CDN;
- prozkoumat, nahradit, komprimovat nebo následně zpracovat vygenerované zdroje po exportu;
- udržet strukturu výstupu blíže tomu, co očekává webová aplikace.
Pro obecný průběh konverze HTML viz Convert PowerPoint Presentations to HTML. Tento článek se zaměřuje na část exportu týkající se propojování zdrojů.
Jak funguje export s odkazovanými zdroji
ILinkEmbedController umožňuje vaší aplikaci rozhodnout, zdroj po zdroji, zda exportér vloží data do HTML nebo je uloží externě a zapíše odkaz.
Rozhraní má tři metody:
ILinkEmbedController.getObjectStoringLocationrozhoduje, zda by měl být zdroj odkazován nebo vložen.ILinkEmbedController.getUrlvrací URL, která bude zapsána do vygenerovaného HTML nebo do jiného odkazovaného zdroje.ILinkEmbedController.saveExternalzapisuje data odkazovaného zdroje na disk nebo do jiného úložného cíle.
Cesta v souborovém systému a URL v prohlížeči jsou oddělené záležitosti. Například níže uvedený příklad zapisuje soubory zdrojů do html-output/assets na disku, zatímco HTML obsahuje relativní URL jako assets/resource-1.svg. Prohlížeč tato URL řeší relativně k souboru, který odkaz obsahuje. Proto odkaz z presentation.html na SVG soubor používá assets/resource-1.svg, zatímco odkaz z toho SVG souboru na obrázek uložený ve stejném adresáři assets používá resource-4.jpg.
Export HTML s odkazovanými zdroji
Následující příklad v Pythonu vytvoří výstupní adresář, uloží tam HTML soubor a uloží odkazované zdroje do podadresáře assets. Řadič propojává běžné obrázky, fonty, audio, video a CSS zdroje, pokud Aspose.Slides poskytuje nebo dokáže odvodit bezpečnou příponu souboru. Zdroje, které nejsou rozpoznány, zůstávají vložené.
import jpype
import asposeslides
from pathlib import Path
if not jpype.isJVMStarted():
jpype.startJVM()
from asposeslides.api import HtmlFormatter, HtmlOptions, LinkEmbedDecision, Presentation, SVGOptions, SaveFormat, SlideImageFormat
class ExternalResourceController:
EXTENSIONS_BY_CONTENT_TYPE = {
"image/jpeg": ".jpg",
"image/png": ".png",
"image/gif": ".gif",
"image/bmp": ".bmp",
"image/svg+xml": ".svg",
"image/tiff": ".tiff",
"image/x-emf": ".emf",
"image/x-wmf": ".wmf",
"font/woff": ".woff",
"font/woff2": ".woff2",
"font/ttf": ".ttf",
"application/font-woff": ".woff",
"application/vnd.ms-fontobject": ".eot",
"application/x-font-ttf": ".ttf",
"text/css": ".css",
"audio/mpeg": ".mp3",
"audio/mp4": ".m4a",
"audio/wav": ".wav",
"video/mp4": ".mp4",
"video/webm": ".webm",
}
def __init__(self, asset_directory, asset_url_prefix):
self.asset_directory = asset_directory
normalized_prefix = asset_url_prefix.replace("\\", "/") if asset_url_prefix else ""
self.asset_url_prefix = normalized_prefix.rstrip("/") + "/" if normalized_prefix else ""
self.file_names_by_resource_id = {}
def getObjectStoringLocation(self, resource_id, entity_data, semantic_name, content_type, recommended_extension):
extension = self.resolve_extension(content_type, recommended_extension)
if extension is None:
return LinkEmbedDecision.Embed
self.file_names_by_resource_id[resource_id] = f"resource-{resource_id}{extension}"
return LinkEmbedDecision.Link
def getUrl(self, resource_id, referrer):
file_name = self.file_names_by_resource_id.get(resource_id)
if file_name is None:
return None
if referrer in self.file_names_by_resource_id:
return file_name
return self.asset_url_prefix + file_name
def saveExternal(self, resource_id, entity_data):
file_name = self.file_names_by_resource_id.get(resource_id)
if file_name is None:
print(f"Resource {resource_id} was not registered for external storage.")
return
if entity_data is None or len(entity_data) == 0:
print(f"Resource {resource_id} contains no data and cannot be saved.")
return
try:
self.asset_directory.mkdir(parents=True, exist_ok=True)
file_path = self.asset_directory / file_name
resource_data = bytes(entity_data)
file_path.write_bytes(resource_data)
except OSError as error:
print(f"Failed to save external resource {resource_id}: {error}")
@classmethod
def resolve_extension(cls, content_type, recommended_extension):
content_type = str(content_type) if content_type is not None else ""
mapped_extension = cls.EXTENSIONS_BY_CONTENT_TYPE.get(content_type)
if mapped_extension is not None:
return mapped_extension
if not content_type.lower().startswith(("image/", "font/", "audio/", "video/")):
return None
if recommended_extension is None:
return None
extension_characters = str(recommended_extension).strip().lstrip(".")
if not extension_characters or not extension_characters.isalnum():
return None
return "." + extension_characters.lower()
input_file_path = Path("presentation.pptx")
output_directory = Path("html-output")
asset_directory_name = "assets"
asset_directory = output_directory / asset_directory_name
output_directory.mkdir(parents=True, exist_ok=True)
asset_directory.mkdir(parents=True, exist_ok=True)
asset_url_prefix = asset_directory_name + "/"
controller = ExternalResourceController(asset_directory, asset_url_prefix)
controller_proxy = jpype.JProxy("com.aspose.slides.ILinkEmbedController", inst=controller)
svg_options = SVGOptions(controller_proxy)
slide_image_format = SlideImageFormat.svg(svg_options)
html_options = HtmlOptions(controller_proxy)
html_formatter = HtmlFormatter.createDocumentFormatter("", False)
html_options.setHtmlFormatter(html_formatter)
html_options.setSlideImageFormat(slide_image_format)
presentation = Presentation(str(input_file_path))
try:
html_file_path = output_directory / "presentation.html"
presentation.save(str(html_file_path), SaveFormat.Html, html_options)
finally:
presentation.dispose()
Po exportu má výstupní složka tuto strukturu:
html-output/
presentation.html
assets/
resource-1.svg
resource-2.svg
resource-3.svg
resource-4.jpg
resource-5.png
Přesné soubory závisí na obsahu prezentace a nastaveních exportu. Například rastrové obrázky jsou běžně exportovány jako JPEG nebo PNG. Aspose.Slides může zvolit jiný obrazový kodek než ten použitý ve zdrojové prezentaci, pokud to vede k menšímu nebo vhodnějšímu souboru. Obrázky s průhledností jsou exportovány jako PNG.
Výběr URL pro nasazení
Ukázka používá relativní předponu URL: assets/. Pokud je presentation.html otevřen z html-output/presentation.html, prohlížeč načte html-output/assets/resource-1.svg.
Když jeden odkazovaný zdroj odkazuje na jiný odkazovaný zdroj, ukázka používá parametr referrer v ILinkEmbedController.getUrl a vrací pouze název souboru. Například pokud jsou resource-1.svg a resource-4.jpg oba ve složce assets, SVG soubor by měl odkazovat na resource-4.jpg, ne na assets/resource-4.jpg.
Použijte jinou předponu URL, pokud jsou soubory nasazeny jinde:
- Použijte
assets/, když je adresář s prostředky vedle HTML souboru. - Použijte
../assets/, když je adresář s prostředky o úroveň výš než HTML soubor. - Použijte
https://cdn.example.com/presentations/job-123/assets/, když jsou soubory nahrány na CDN nebo na statický souborový server.
URL vrácená metodou ILinkEmbedController.getUrl musí odpovídat konečné nasazené lokaci souboru zapsaného metodou ILinkEmbedController.saveExternal. V serverových aplikacích použijte jedinečný výstupní adresář nebo předponu objektového úložiště pro každou konverzní úlohu, aby nedošlo k přepsání souborů z jiného exportu.
Kdy místo toho vložit
Vložené Base64 HTML je stále užitečné, když výstup musí být jediný soubor, například e‑mailová příloha, offline náhled nebo dokument, který bude přesunut bez přidružené složky s prostředky. Odkazované zdroje jsou vhodnější, když bude HTML podávána webovou aplikací, uložena v CMS, optimalizována build pipeline nebo cachována prohlížeči nezávisle na HTML.
Často kladené otázky
Mohu externalizovat jen obrázky a nechat ostatní zdroje vložené?
Ano. V metodě ILinkEmbedController.getObjectStoringLocation vraťte LinkEmbedDecision.Link pouze pro typy obsahu, které chcete uložit jako samostatné soubory, a pro ostatní vraťte LinkEmbedDecision.Embed.
Proč se přípona exportovaného obrázku liší od původní prezentace?
Aspose.Slides může během HTML exportu překódovat rastrové obrázky, aby zlepšil velikost nebo kompatibilitu s prohlížeči. Například obrázek ze zdrojového souboru může být zapsán jako JPEG nebo PNG v závislosti na výsledném vykreslení.
Fungují relativní URL po přesunu HTML souboru?
Relativní URL fungují pouze při zachování stejné relativní struktury složek. Pokud HTML odkazuje na assets/resource-1.png, složka assets musí zůstat vedle HTML souboru, pokud nevytvoříte jinou předponu URL.
Měly by serverové aplikace znovu používat stejný výstupní adresář?
Ne. Použijte jedinečný výstupní adresář nebo předponu úložiště pro každou konverzní úlohu. To zabraňuje kolizím názvů souborů a přepisování zdrojů jedním exportem jiným exportem.