如何在 Scala 中的 Microsoft Fabric Spark 上使用 Apache POI 从模板创建 PowerPoint 演示文稿?

问题描述 投票:0回答:1

我想使用 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 格式。我还需要做些什么来确保情况确实如此吗?

scala apache-poi powerpoint microsoft-fabric
1个回答
0
投票

如果在从预定义幻灯片布局创建新幻灯片后将源 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");
...
© www.soinside.com 2019 - 2024. All rights reserved.