package com.megatim.manuel.core.convert; import org.apache.poi.sl.usermodel.Placeholder; import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XSLFShape; import org.apache.poi.xslf.usermodel.XSLFSlide; import org.apache.poi.xslf.usermodel.XSLFTextShape; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; /** * PowerPoint .pptx (XSLF) -> HTML : chaque diapositive est rendue en image PNG (rendu fidèle), * et son titre devient une entrée de la table des matières. */ public class PptxConverter extends AbstractHtmlConverter { private static final double SCALE = 2.0; public PptxConverter(Path outputDir) { super(outputDir); } @Override public ConversionResult convert(Path source, int order) throws IOException { String safe = safeBase(source, order); String htmlName = safe + ".html"; List headings = new ArrayList<>(); List images = new ArrayList<>(); StringBuilder body = new StringBuilder(); try (FileInputStream fis = new FileInputStream(source.toFile()); XMLSlideShow ppt = new XMLSlideShow(fis)) { Dimension d = ppt.getPageSize(); int w = (int) Math.round(d.width * SCALE); int h = (int) Math.round(d.height * SCALE); int n = 0; for (XSLFSlide slide : ppt.getSlides()) { n++; String title = slideTitle(slide, n); BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g = img.createGraphics(); applyQualityHints(g); g.setColor(Color.WHITE); g.fillRect(0, 0, w, h); g.scale(SCALE, SCALE); try { slide.draw(g); } finally { g.dispose(); } String imgName = writeImagePng(safe, n, img); images.add(imgName); String anchor = safe + "_s" + n; headings.add(new Heading(title, 1, anchor)); body.append("

").append(esc(title)).append("

\n"); body.append("

\"").append(esc(title)).append("\"/

\n"); } } String docTitle = headings.isEmpty() ? stripExt(source.getFileName().toString()) : headings.get(0).text; writeHtml(htmlName, docTitle, body.toString()); return new ConversionResult(htmlName, docTitle, headings, images); } private String slideTitle(XSLFSlide slide, int n) { try { for (XSLFShape sh : slide.getShapes()) { if (sh instanceof XSLFTextShape) { XSLFTextShape ts = (XSLFTextShape) sh; Placeholder ph = ts.getPlaceholder(); if (ph == Placeholder.TITLE || ph == Placeholder.CENTERED_TITLE) { String t = ts.getText(); if (t != null && !t.isBlank()) return t.trim(); } } } } catch (Exception ignore) { /* pas de titre exploitable */ } return "Diapositive " + n; } }