我想使用 Apache POI 读取 PowerPoint POTX 文件,并在笔记本运行过程中填充模板,并将生成的 PPTX 文件写入 Azure Blob 存储。这是在 Microsoft 的 Fabric 产品中的 Spark 上执行的。 Fabric 允许将 Java 依赖项上传到环境,并且您可以创建多个环境。您可以选择运行笔记本时使用的环境。
我已经为 POI 5.2.3 创建了一个环境。我上传的库是
5.2.3 |
---|
commons-codec-1.15.jar |
commons-collections4-4.4.jar |
commons-compress-1.21.jar |
commons-io-2.11.0.jar |
commons-math3-3.6.1.jar |
curvesapi-1.07.jar |
log4j-api-2.18.0.jar |
poi-5.2.3.jar |
poi-ooxml-5.2.3.jar |
poi-ooxml-lite-5.2.3.jar |
SparseBitSet-1.2.jar |
xmlbeans-5.1.1.jar |
使用 5.2.3,笔记本运行没有错误,但输出不是有效的 PPTX 文件。
PowerPoint 发现幻灯片.pptx 中的内容存在问题。
PowerPoint 可以尝试修复演示文稿。 如果您信任此演示文稿的来源,请单击“修复”。
修复文件不起作用。如果我将文件扩展名更改为 .ppt PowerPoint 可以正常加载文件。
我创建了一个笔记本,采用 Apache POI 网站上 XLSF Cookbook 中的 从预定义的幻灯片布局创建新幻灯片 片段,将其改编为 Scala 并在演示文稿保存到文件的末尾添加了位。
import org.apache.poi.xslf.usermodel.{XMLSlideShow, XSLFSlide, SlideLayout}
import java.io.{FileInputStream,FileOutputStream}
import scala.jdk.CollectionConverters._
var ppt = new XMLSlideShow(new FileInputStream("/lakehouse/default/Files/template.potx"));
// first see what slide layouts are available :
println("Available slide layouts:");
for(master <- ppt.getSlideMasters().asScala){
for(layout <- master.getSlideLayouts()){
println(layout.getType());
}
}
// blank slide
var blankSlide = ppt.createSlide();
// there can be multiple masters each referencing a number of layouts
// for demonstration purposes we use the first (default) slide master
var defaultMaster = ppt.getSlideMasters().get(0);
// title slide
var titleLayout = defaultMaster.getLayout(SlideLayout.CUST);
// fill the placeholders
var slide1 = ppt.createSlide(titleLayout);
var title1 = slide1.getPlaceholder(0);
title1.setText("First Title");
// title and content
var titleBodyLayout = defaultMaster.getLayout(SlideLayout.CUST);
var slide2 = ppt.createSlide(titleBodyLayout);
var title2 = slide2.getPlaceholder(0);
title2.setText("Second Title");
var body2 = slide2.getPlaceholder(1);
body2.clearText(); // unset any existing text
body2.addNewTextParagraph().addNewTextRun().setText("First paragraph");
body2.addNewTextParagraph().addNewTextRun().setText("Second paragraph");
body2.addNewTextParagraph().addNewTextRun().setText("Third paragraph");
var outStream = new FileOutputStream("/lakehouse/default/Files/Output/slides.pptx")
ppt.write(outStream)
outStream.close()
我希望输出文件是 XML pptx 格式。我还需要做些什么来确保情况确实如此吗?
如果在从预定义幻灯片布局创建新幻灯片后将源 slideshow.pptx
保存为
*.pptx
,则从预定义幻灯片布局创建新幻灯片的代码将起作用。在不更改内容类型的情况下,无法使用
*.potx
作为源并另存为 *.pptx
。
在您的情况下,以
template.potx
开头并写入 slides.pptx
无法在不更改内容类型的情况下工作。如果您以 template.pptx
开头并写下 slides.pptx
,那么它就会起作用。同样,如果您以 template.potx
开头并写下 slides.potx
,
PowerPoint 模板文件
*.potx
和 PowerPoint 幻灯片文件 *.pptx
具有不同的内容类型。这些都存储在文件中。 *.potx
文件的内容为 txpe application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
。 *.pptx
文件的内容类型为 application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
。内容类型不匹配会导致使用 PowerPoint 打开文件时出错。
如果需要更改内容类型,则可能如下所示:
...
XMLSlideShow ppt = new XMLSlideShow(new FileInputStream("template.potx"));
...
ppt.getPackage().replaceContentType(
"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml",
"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml");
FileOutputStream out = new FileOutputStream("./slides.pptx");
...