在Java中设置pptx主题

在Java中设置pptx主题,java,apache-poi,powerpoint,xslf,Java,Apache Poi,Powerpoint,Xslf,我正在尝试使用java以编程方式合并一些pptx文档。我基本上是用ApachePOI解决了这个问题,但是我试图合并的文档不起作用 经过大量的搜索和反复尝试,我发现这是因为pptx文档没有主题信息(即,如果我点击powerpoint并检查幻灯片主视图,它是空白的)。如果我转到设计功能区中的主题并选择“office主题”或其他主题,则保存。这些文件将很有魅力地合并在一起。否则,我会遇到以下错误: Exception in thread "main" java.lang.IllegalArgument

我正在尝试使用java以编程方式合并一些pptx文档。我基本上是用ApachePOI解决了这个问题,但是我试图合并的文档不起作用

经过大量的搜索和反复尝试,我发现这是因为pptx文档没有主题信息(即,如果我点击powerpoint并检查幻灯片主视图,它是空白的)。如果我转到设计功能区中的主题并选择“office主题”或其他主题,则保存。这些文件将很有魅力地合并在一起。否则,我会遇到以下错误:

Exception in thread "main" java.lang.IllegalArgumentException: Failed to fetch default style for otherStyle and level=0
    at org.apache.poi.xslf.usermodel.XSLFTextParagraph.getDefaultMasterStyle(XSLFTextParagraph.java:1005)
    at org.apache.poi.xslf.usermodel.XSLFTextParagraph.fetchParagraphProperty(XSLFTextParagraph.java:1029)
    at org.apache.poi.xslf.usermodel.XSLFTextParagraph.isBullet(XSLFTextParagraph.java:654)
    at org.apache.poi.xslf.usermodel.XSLFTextParagraph.copy(XSLFTextParagraph.java:1044)
    at org.apache.poi.xslf.usermodel.XSLFTextShape.copy(XSLFTextShape.java:631)
    at org.apache.poi.xslf.usermodel.XSLFSheet.appendContent(XSLFSheet.java:358)
    at com.apsiva.main.Snippet.main(Snippet.java:28)
以下是我运行的代码:

package com.apsiva.main;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.xslf.usermodel.SlideLayout;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFSlideLayout;

public class Snippet {
    /** Merge the pptx files in the array <decks> to the desired destination 
         * chosen in <outputPath> */
        public static void main(String[] args) {
            try {
                FileInputStream empty = new FileInputStream("C:/Users/Alex/workspace/OutputWorker/tmp/base2.pptx");
                XMLSlideShow pptx;

                pptx = new XMLSlideShow(empty);
                XSLFSlideLayout defaultLayout = pptx.getSlideMasters()[0].getLayout(SlideLayout.TITLE_AND_CONTENT);

                FileInputStream is = new FileInputStream("C:/Users/Alex/workspace/OutputWorker/tmp/noWork.pptx");
//              FileInputStream is = new FileInputStream("C:/Users/Alex/workspace/OutputWorker/tmp/works2.pptx");
                XMLSlideShow src = new XMLSlideShow(is);
                is.close();
                for (XSLFSlide srcSlide: src.getSlides()){
                    pptx.createSlide(defaultLayout).appendContent(srcSlide);
                }
                FileOutputStream out = new FileOutputStream("C:/POI-TEST-OUTPUT.pptx");
                pptx.write(out);
                out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
}
package com.apsiva.main;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入org.apache.poi.xslf.usermodel.SlideLayout;
导入org.apache.poi.xslf.usermodel.xmlsideshow;
导入org.apache.poi.xslf.usermodel.XSLFSlide;
导入org.apache.poi.xslf.usermodel.XSLFSlideLayout;
公共类代码段{
/**将阵列中的pptx文件合并到所需的目标
*选择*/
公共静态void main(字符串[]args){
试一试{
FileInputStream empty=新的FileInputStream(“C:/Users/Alex/workspace/OutputWorker/tmp/base2.pptx”);
XMLSlideShow pptx;
pptx=新的XMLSlideShow(空);
XSLFSlideLayout defaultLayout=pptx.getSlideMasters()[0].getLayout(SlideLayout.TITLE和内容);
FileInputStream is=newfileinputstream(“C:/Users/Alex/workspace/OutputWorker/tmp/noWork.pptx”);
//FileInputStream is=newfileinputstream(“C:/Users/Alex/workspace/OutputWorker/tmp/works2.pptx”);
XMLSlideShow src=新的XMLSlideShow(is);
is.close();
for(XSLFSlide srcSlide:src.getSlides()){
createSlide(defaultLayout).appendContent(srcside);
}
FileOutputStream out=新的FileOutputStream(“C:/POI-TEST-OUTPUT.pptx”);
pptx.写入(输出);
out.close();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
我想合并这些文件,我相信解决方案是通过编程将主题分配给这些文件。怎样才能做到呢


谢谢您的考虑

/ApachePOI/src/ooxml/java/org/apache/poi/xslf/usermodel/xsltextparagration.java

CTTextParagraphProperties getDefaultMasterStyle()


在某些情况下,当您生成了pptx文件(例如,JasperReport导出)时,可能会为不同的字段添加一些无效值。例如,行距(可以是百分比)和特殊字符,apache poi xslf不知道如何处理这些值。打开文件时,PowerPoint会自动将这些值调整为有效值。使用ApachePOI时,您必须单独标识这些字段并手动调整它们。 我有一个类似的问题,但行间距,并做了一个变通,通过设置每个段落的值如下:

List<XSLFShape> shapes = srcSlide.getShapes();                
for (XSLFShape xslfShape: shapes) {
    if (xslfShape instanceof XSLFTextShape){
    List<XSLFTextParagraph> textParagraphs = ((XSLFTextShape) xslfShape).getTextParagraphs();
        for (XSLFTextParagraph textParagraph: textParagraphs) {                            
            textParagraph.setLineSpacing(10d);
        }
    }
}
List shapes=srcSlide.getShapes();
for(XSLFShape XSLFShape:shapes){
if(xslfShape instanceof XSLFTextShape){
列出textPerpages=((xsltextShape)xslfShape).getTextPerpages();
对于(xslftexttraphy texttraphy:texttraphs){
text段落。设置行距(10d);
}
}
}
这很有魅力

更有效的方法是直接在XML对象上执行此操作:

 List<CTShape> ctShapes = srcSlide.getXmlObject().getCSld().getSpTree().getSpList();
    for (CTShape ctShape : ctShapes) {
        List<CTTextParagraph> ctTextParagraphs = ctShape.getTxBody().getPList();
        for (CTTextParagraph paragraph : ctTextParagraphs) {
            if (paragraph.getPPr().getLnSpc() != null) {
                paragraph.getPPr().unsetLnSpc();
            }
        }
    }
List ctShapes=srcSlide.getXmlObject().getCSld().getSpTree().getSpList();
用于(CTShape CTShape:ctShapes){
List cttextparges=ctShape.getTxBody().getPList();
对于(CTTEXT段落:CTTEXT段落){
如果(段落.getPPr().getLnSpc()!=null){
段落.getPPr().unsetLnSpc();
}
}
}
 List<CTShape> ctShapes = srcSlide.getXmlObject().getCSld().getSpTree().getSpList();
    for (CTShape ctShape : ctShapes) {
        List<CTTextParagraph> ctTextParagraphs = ctShape.getTxBody().getPList();
        for (CTTextParagraph paragraph : ctTextParagraphs) {
            if (paragraph.getPPr().getLnSpc() != null) {
                paragraph.getPPr().unsetLnSpc();
            }
        }
    }