在 Android 上將 PowerPoint 簡報轉換為 Markdown
概述
Aspose.Slides for Android via Java 能夠將 PPT 與 PPTX 簡報轉換為 Markdown,以用於文件編寫、靜態網站、內容遷移與版本控制的工作流程。您可以選擇 Markdown 的風格、控制投影片內容的呈現方式,並決定匯出影像的儲存位置以及產生的 Markdown 如何引用它們。
預設情況下,Markdown 匯出僅產生文字輸出。若要匯出視覺內容,請使用 MarkdownSaveOptions.setExportType 方法將匯出類型設定為 MarkdownExportType 列舉中的 Sequential 或 Visual 值。Sequential 會將投影片項目分別且依序渲染,而 Visual 則會將分組的項目保持在一起,以保留它們的視覺關係。TextOnly 值不會產生影像資源,因而在此模式下不會呼叫影像儲存回呼。
將簡報轉換為 Markdown
使用 Presentation 類別載入來源檔案,然後呼叫 Presentation.save 方法,傳入 SaveFormat 列舉中的 Md 值。
import com.aspose.slides.Presentation;
import com.aspose.slides.SaveFormat;
Presentation presentation = new Presentation("presentation.pptx");
try {
presentation.save("presentation.md", SaveFormat.Md);
} finally {
presentation.dispose();
}
選擇 Markdown 風格
MarkdownSaveOptions.setFlavor 方法可控制輸出所使用的 Markdown 規範。Flavor 列舉包含 CommonMark、GitHub Flavored Markdown 以及其他支援的變體。
以下範例將簡報匯出為 CommonMark:
import com.aspose.slides.Flavor;
import com.aspose.slides.MarkdownSaveOptions;
import com.aspose.slides.Presentation;
import com.aspose.slides.SaveFormat;
Presentation presentation = new Presentation("presentation.pptx");
try {
MarkdownSaveOptions options = new MarkdownSaveOptions();
options.setFlavor(Flavor.CommonMark);
presentation.save("presentation.md", SaveFormat.Md, options);
} finally {
presentation.dispose();
}
使用預設本機儲存行為匯出影像
MarkdownSaveOptions 類別提供兩個方法,用於設定本機儲存的影像:
- setBasePath 指定 Markdown 文件及其資源的基礎目錄。
- setImagesSaveFolderName 指定影像子目錄。其預設值為
Images。
以下範例會渲染視覺內容,將影像寫入 output/assets,並在 Markdown 文件中建立相對影像引用:
import com.aspose.slides.MarkdownExportType;
import com.aspose.slides.MarkdownSaveOptions;
import com.aspose.slides.Presentation;
import com.aspose.slides.SaveFormat;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Path outputDirectory = Paths.get("output");
Files.createDirectories(outputDirectory);
Presentation presentation = new Presentation("presentation.pptx");
try {
MarkdownSaveOptions options = new MarkdownSaveOptions();
options.setExportType(MarkdownExportType.Visual);
options.setBasePath(outputDirectory.toString());
options.setImagesSaveFolderName("assets");
Path markdownPath = outputDirectory.resolve("presentation.md");
presentation.save(markdownPath.toString(), SaveFormat.Md, options);
} finally {
presentation.dispose();
}
當自訂的影像儲存回呼傳回 false 時,此行為亦會作為備援使用。
自訂影像儲存與 Markdown 連結
使用 MarkdownSaveOptions.setImageSaving 方法註冊回呼,以處理 Markdown 匯出期間產生的非 SVG 位圖與中繼檔資源。其 MarkdownImageSavingHandler 回呼會收到 IImage 物件、其 ImageFormat 值,以及以單一元素 String[] 參數形式提供的產生之 Markdown 連結。請以給定的格式儲存或上傳影像,並將 link[0] 替換為必須寫入 Markdown 輸出的參照。
以 SVG 格式產生的資源會另外處理。請使用 MarkdownSaveOptions.setSvgImageSaving 方法註冊回呼。其 MarkdownSvgImageSavingHandler 回呼會收到 ISvgImage 物件以及單一元素 String[] link 參數。SVG 不具備 ImageFormat 參數;請改由 ISvgImage.getSvgData 方法取得其 XML 資料並寫入或上傳。視匯出模式與視覺分組情況而定,來源簡報中的 SVG 可能會在匯出時被點陣化或與其他內容合併;產生的非 SVG 資源將傳遞給影像儲存回呼。當每個匯出的視覺資源皆需要自訂處理時,請同時註冊這兩個回呼。
回呼的返回值決定由誰處理影像:
- 在回呼已儲存、上傳、轉換或以其他方式處理影像,並將有效值指派給
link[0]後,返回true。Aspose.Slides 會將該值寫入 Markdown 文件,且不執行預設的本機儲存。 - 返回
false,則讓 Aspose.Slides 依照 MarkdownSaveOptions.setBasePath 與 MarkdownSaveOptions.setImagesSaveFolderName 設定的值,將影像本機儲存並產生其連結。
重要
回呼若返回true,即代表它負責處理該影像。若返回 true 卻未指派有效且非空的連結,匯出將因 InvalidOperationException 而失敗。
將影像儲存至 CDN 原始目錄並使用外部 URL
以下範例將 cdn-origin/presentations/quarterly-report 視為已掛載或同步的 CDN 原始目錄。每個回呼會擷取產生的檔名,將影像儲存至該自訂目錄,並將產生的本機參照替換為公用 CDN URL。此範例本身不會執行網路上傳:該 URL 只有在目錄已掛載為 CDN 原始點或其檔案已發布至 CDN 後才會有效。若使用物件儲存,請以儲存 SDK 的上傳操作取代檔案系統寫入,並在上傳成功後才指派 link[0]。
import com.aspose.slides.MarkdownExportType;
import com.aspose.slides.MarkdownSaveOptions;
import com.aspose.slides.Presentation;
import com.aspose.slides.SaveFormat;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Function;
Path outputDirectory = Paths.get("output");
String publicBaseUrl = "https://cdn.example.com/presentations/quarterly-report";
Path storageDirectory = Paths.get("cdn-origin", "presentations", "quarterly-report");
Files.createDirectories(outputDirectory);
Files.createDirectories(storageDirectory);
Function<String, String> getFileNameFromLink = generatedLink -> {
String urlCompatibleLink = generatedLink.replace('\\', '/');
return urlCompatibleLink.substring(urlCompatibleLink.lastIndexOf('/') + 1);
};
Function<String, String> buildPublicUrl = fileName -> {
try {
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
return publicBaseUrl + "/" + encodedFileName;
} catch (UnsupportedEncodingException exception) {
System.err.println("Could not encode the image file name: " + exception.getMessage());
return null;
}
};
Presentation presentation = new Presentation("presentation.pptx");
try {
MarkdownSaveOptions options = new MarkdownSaveOptions();
options.setExportType(MarkdownExportType.Visual);
options.setBasePath(outputDirectory.toString());
options.setImagesSaveFolderName("fallback-images");
options.setImageSaving((image, format, link) -> {
if (image.getWidth() < 128 || image.getHeight() < 128) {
return false;
}
String fileName = getFileNameFromLink.apply(link[0]);
String publicUrl = buildPublicUrl.apply(fileName);
if (publicUrl == null) {
return false;
}
Path storagePath = storageDirectory.resolve(fileName);
image.save(storagePath.toString(), format);
link[0] = publicUrl;
return true;
});
options.setSvgImageSaving((svgImage, link) -> {
String fileName = getFileNameFromLink.apply(link[0]);
String publicUrl = buildPublicUrl.apply(fileName);
if (publicUrl == null) {
return false;
}
Path storagePath = storageDirectory.resolve(fileName);
try {
Files.write(storagePath, svgImage.getSvgData());
} catch (IOException exception) {
System.err.println("Could not save the SVG image: " + exception.getMessage());
return false;
}
link[0] = publicUrl;
return true;
});
Path markdownPath = outputDirectory.resolve("presentation.md");
presentation.save(markdownPath.toString(), SaveFormat.Md, options);
} finally {
presentation.dispose();
}
此位圖回呼會刻意對小於 128 × 128 像素的影像返回 false,因此 Aspose.Slides 會依預設行為將這些影像儲存至 output/fallback-images。較大的位圖與中繼檔資源,以及 SVG 資源,則交由自訂程式碼處理。例如,產生的本機參照 fallback-images/image1.png 會變成 https://cdn.example.com/presentations/quarterly-report/image1.png。回呼在寫入檔案時僅使用作業系統的路徑;寫入 Markdown 的連結則使用正斜線與 URL 編碼的檔名。建立相對連結時亦遵循相同規則:使用 /,而非平台特定的目錄分隔符。
常見問題
Can one handler process both raster images and SVG images?
否。請使用 MarkdownSaveOptions.setImageSaving 來處理匯出時產生的位圖與中繼檔資源,使用 MarkdownSaveOptions.setSvgImageSaving 來處理以 SVG 形式產生的資源。前者會提供 IImage 物件與 ImageFormat 值;後者會提供 ISvgImage 物件,其 SVG 資料可透過 ISvgImage.getSvgData 讀取。於匯出過程中被點陣化的來源 SVG 會改由影像儲存回呼處理。
What happens when an image-saving handler returns false?
Aspose.Slides 會使用預設的本機儲存行為。影像的儲存位置與產生的參照由 MarkdownSaveOptions.setBasePath 與 MarkdownSaveOptions.setImagesSaveFolderName 設定的值所控制。
Can a handler provide a URL without saving the image locally?
可以。回呼可以將影像上傳至物件儲存或傳遞給其他服務,將取得的 URL 指派給 link[0],並返回 true。回呼必須自行完成處理;返回 true 會阻止預設的本機儲存。
Why does Markdown export throw an InvalidOperationException from a handler?
當回呼返回 true 卻未提供有效的連結時,就會拋出此例外。請在返回 true 前指派應寫入 Markdown 的相對路徑或外部 URL。
Which path separator should image links use?
在 Markdown 連結與 URL 中請使用正斜線。Path.resolve 僅用於檔案系統路徑,Markdown 參照則需另行建構或正規化。
Are hyperlinks preserved during Markdown export?
會。文字 hyperlinks 會保留為標準的 Markdown 連結。投影片的 transitions 與 animations 則不會被轉換。
Can presentations be converted to Markdown in parallel?
可以同時處理多個不同的簡報檔案,但請勿在執行緒間共用同一個 Presentation 實例。請遵循 multithreading guidelines,為每個檔案使用獨立的實例。