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<Heading> headings = new ArrayList<>();
|
List<String> 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("<h1 id=\"").append(anchor).append("\">").append(esc(title)).append("</h1>\n");
|
body.append("<p class=\"slide\"><img src=\"").append(imgName)
|
.append("\" alt=\"").append(esc(title)).append("\"/></p>\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;
|
}
|
}
|